mirror of https://gitee.com/openkylin/linux.git
69c7f4618c
Any write with either dd or flashcp to a device driven by the
spear_smi.c driver will pass through the spear_smi_cpy_toio()
function. This function will get called for chunks of up to 256 bytes.
If the amount of data is smaller, we may have a problem if the data
length is not 4-byte aligned. In this situation, the kernel panics
during the memcpy:
# dd if=/dev/urandom bs=1001 count=1 of=/dev/mtd6
spear_smi_cpy_toio [620] dest c9070000, src c7be8800, len 256
spear_smi_cpy_toio [620] dest c9070100, src c7be8900, len 256
spear_smi_cpy_toio [620] dest c9070200, src c7be8a00, len 256
spear_smi_cpy_toio [620] dest c9070300, src c7be8b00, len 233
Unhandled fault: external abort on non-linefetch (0x808) at 0xc90703e8
[...]
PC is at memcpy+0xcc/0x330
The above error occurs because the implementation of memcpy_toio()
tries to optimize the number of I/O by writing 4 bytes at a time as
much as possible, until there are less than 4 bytes left and then
switches to word or byte writes.
Unfortunately, the specification states about the Write Burst mode:
"the next AHB Write request should point to the next
incremented address and should have the same size (byte,
half-word or word)"
This means ARM architecture implementation of memcpy_toio() cannot
reliably be used blindly here. Workaround this situation by update the
write path to stick to byte access when the burst length is not
multiple of 4.
Fixes:
|
||
---|---|---|
.. | ||
Kconfig | ||
Makefile | ||
bcm47xxsflash.c | ||
bcm47xxsflash.h | ||
block2mtd.c | ||
docg3.c | ||
docg3.h | ||
lart.c | ||
mchp23k256.c | ||
ms02-nv.c | ||
ms02-nv.h | ||
mtd_dataflash.c | ||
mtdram.c | ||
phram.c | ||
pmc551.c | ||
powernv_flash.c | ||
serial_flash_cmds.h | ||
slram.c | ||
spear_smi.c | ||
sst25l.c | ||
st_spi_fsm.c |