mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
mtd: cfi_cmdset_0002: cap the write-buffer chunk at 256 bytes on an x8 device
The Write to Buffer command takes the number of words to program minus
one, and do_write_buffer() sends that count as a single bus word:
map_write(map, CMD(words - 1), cmd_adr);
CMD() replicates the value into every device lane, so each device reads
the count off its own data lines - eight of them on an x8 part. A count
that does not fit in eight bits is truncated there, which limits one
Write to Buffer to 256 words on an x8 device, however large a buffer the
chip advertises in its CFI query.
The M29EW on a Cavium Octeon CN6335 board (an x16 part strapped to x8)
advertises MaxBufWriteSize = 512 bytes, so cfi_amdstd_write_buffers()
split the data into 512-byte chunks and do_write_buffer() sent a count of
511. The chip saw 511 & 0xff = 255, expected 256 bytes, and aborted the
program when the 257th arrived. Chunks below 256 bytes - the leading
partial chunk of a write - completed normally, so only the full-size ones
failed:
MTD do_write_buffer_wait(): software timeout, address:0x03278bff.
jffs2: Write of 4164 bytes at 0x02c789b4 failed. returned -5, retlen 68
jffs2: No space for garbage collection. Aborting GC thread
Clamp MaxBufWriteSize for x8 devices in the write-buffer fixup, and
recompute mtd->writebufsize, which cfi_cmdset_0002_setup() derives from
MaxBufWriteSize before the fixups run.
The clamp deliberately keys off the device width rather than the part,
even though the driver already recognises this one in is_m29ew(): the
ceiling comes from the width of a device's data bus, not from the chip,
so any x8 device advertising a larger buffer is told a count it cannot
receive. The M29EW is only where it was found.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Orgad Shaneh <orgads@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
parent
3be16e5d49
commit
cfc5ebc954
|
|
@ -283,6 +283,21 @@ static void fixup_use_write_buffers(struct mtd_info *mtd)
|
|||
pr_debug("Using buffer write method\n");
|
||||
mtd->_write = cfi_amdstd_write_buffers;
|
||||
}
|
||||
|
||||
/*
|
||||
* The word count of the Write to Buffer command is a single bus
|
||||
* word per device, so an x8 device can be told to program at most
|
||||
* 256 bytes however large a buffer it advertises - including when
|
||||
* several of them are interleaved on a wider bus, where CMD()
|
||||
* replicates the count into each device's lane and it is truncated
|
||||
* there.
|
||||
*/
|
||||
if (cfi->device_type == CFI_DEVICETYPE_X8 &&
|
||||
cfi->cfiq->MaxBufWriteSize > 8) {
|
||||
cfi->cfiq->MaxBufWriteSize = 8;
|
||||
mtd->writebufsize = cfi_interleave(cfi) <<
|
||||
cfi->cfiq->MaxBufWriteSize;
|
||||
}
|
||||
}
|
||||
#endif /* !FORCE_WORD_WRITE */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user