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:
Orgad Shaneh 2026-09-16 16:27:31 +00:00 committed by Miquel Raynal
parent 3be16e5d49
commit cfc5ebc954

View File

@ -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 */