This patch fixes a memory corruption that occurred in the
qcom-nandc driver since it was converted to nand_scan().
On boot, an affected device will panic from a NPE at a weird place:
| Unable to handle kernel NULL pointer dereference at virtual address 0
| pgd = (ptrval)
| [00000000] *pgd=00000000
| Internal error: Oops: 80000005 [#1] SMP ARM
| CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.9 #0
| Hardware name: Generic DT based system
| PC is at (null)
| LR is at nand_block_isbad+0x90/0xa4
| pc : [<00000000>] lr : [<c0592240>] psr: 80000013
| sp : cf839d40 ip : 00000000 fp : cfae9e20
| r10: cf815810 r9 : 00000000 r8 : 00000000
| r7 : 00000000 r6 : 00000000 r5 : 00000001 r4 : cf815810
| r3 : 00000000 r2 : cfae9810 r1 : ffffffff r0 : cf815810
| Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
| Control: 10c5387d Table: 8020406a DAC: 00000051
| Process swapper/0 (pid: 1, stack limit = 0x(ptrval))
| [<c0592240>] (nand_block_isbad) from [<c0580a94>]
| [<c0580a94>] (allocate_partition) from [<c05811e4>]
| [<c05811e4>] (add_mtd_partitions) from [<c0581164>]
| [<c0581164>] (parse_mtd_partitions) from [<c057def4>]
| [<c057def4>] (mtd_device_parse_register) from [<c059d274>]
| [<c059d274>] (qcom_nandc_probe) from [<c0567f00>]
The problem is that the nand_scan()'s qcom_nand_attach_chip callback
is updating the nandc->max_cwperpage from 1 to 4. This causes the
sg_init_table of clear_bam_transaction() in the driver's
qcom_nandc_block_bad() to memset much more than what was initially
allocated by alloc_bam_transaction().
This patch restores the old behavior by reallocating the shared bam
transaction alloc_bam_transaction() after the chip was identified,
but before mtd_device_parse_register() (which is an alias for
mtd_device_register() - see panic) gets called. This fixes the
corruption and the driver is working again.
Cc: stable@vger.kernel.org
Fixes: 6a3cec64f1 ("mtd: rawnand: qcom: convert driver to nand_scan()")
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Boris Brezillon <bbrezillon@kernel.org>
- Parse the 4BAIT SFDP section
- Add a bunch of SPI NOR entries to the flash_info table
- Add the concept of SFDP fixups and use it to fix a bug on MX25L25635F
- A bunch of minor cleanups/comestic changes
-----BEGIN PGP SIGNATURE-----
iQJQBAABCgA6FiEEKmCqpbOU668PNA69Ze02AX4ItwAFAlwVQUYcHGJvcmlzLmJy
ZXppbGxvbkBib290bGluLmNvbQAKCRBl7TYBfgi3ACIYD/sG0+vRIKK8+NgNUHYy
nzKICKvdnBrm2RWi+6va5n2pYggyNy1VhWEjmqWLupjxn7NGkjZiBilhfj8Iv6YN
HScNy7FLHM6pxTKpsZKQLLGKvaUXODgvZwiw3L6T5T3JaJ5nlpE5g8jQy8sCzfjK
pwKdrOw17caZgoY0bMe2ppCObIDLd+mY+WSHbo6tb4/fohpTX1l9QZYHjfgHU9vP
CG0z3sU0JCNGXsbQMngfeuyXFjJ4OKdnklbVTeZl673AYtQMBhQEIGNVkVefuBP3
p8hU0CWRn0Yikc1HGTENvYCnQ7ju3z+16rnLxy3A5CPHhCDrTgUmM8HabYbh+0Si
0Y1wXpEOZ0OZQ7uMs2Q8SK0GLyxqdxkE0ibHgb7K/aLb+yg8oB7DB4Uenb06CiaQ
KAZWGgWZlSondX+/GI7YcQozslFFCfixAw6H0kCpQW0/2piXNqsN5BOROEqjueXW
xeMG0DNnzrQ6/vB9ukLESSB/YvVwfUvt6GSjqMSDdXwx6zyKSvHJ+chCxlK46+Hm
zIVcvNT3mpwcuVnQOZZeCaiIrDUAySEq/8Ztp9O5/CfkzdQyMWxDPoY9A0HjL2p3
FmRN7aAB9jJcdHc2tLwcKPRepjliIUMLf0NXdTSizzQz8WJqULZRBN0VWW4sCbLc
+tTisYjX8fYUz9+kHUcQ4XY16g==
=JXhP
-----END PGP SIGNATURE-----
Merge tag 'spi-nor/for-4.21' of git://git.infradead.org/linux-mtd into mtd/next
Core changes:
- Parse the 4BAIT SFDP section
- Add a bunch of SPI NOR entries to the flash_info table
- Add the concept of SFDP fixups and use it to fix a bug on MX25L25635F
- A bunch of minor cleanups/comestic changes
Now that the CS line to be selected is passed to ->exec_op() and
stored in chip->cur_cs and after patching all drivers implementing
->exec_op() to stop implementing this method, we can deprecate it by
moving it to the nand_legacy structure.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Tested-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
PAGE_READ is used by RISC-V arch code included through mm headers,
and it makes sense to bring in a prefix on these in the driver.
drivers/mtd/nand/raw/qcom_nandc.c:153: warning: "PAGE_READ" redefined
#define PAGE_READ 0x2
In file included from include/linux/memremap.h:7,
from include/linux/mm.h:27,
from include/linux/scatterlist.h:8,
from include/linux/dma-mapping.h:11,
from drivers/mtd/nand/raw/qcom_nandc.c:17:
arch/riscv/include/asm/pgtable.h:48: note: this is the location of the previous definition
Caught by riscv allmodconfig.
Signed-off-by: Olof Johansson <olof@lixom.net>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Those hooks should be replaced by a proper ->exec_op() implementation.
Move them to the nand_legacy struct to make it clear.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Those hooks have been overloaded by some drivers for bad reasons:
either the driver was not fitting in the NAND framework and should
have been an MTD driver (docg4), or it was not properly implementing
the OOB read/write request or had a weird layout where BBM are trashed.
In any case, we should discourage people from overloading those
methods and encourage them to fix their driver instead.
Move the ->block_{bad,markbad}() hooks to the nand_legacy struct to
make it clear.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Those hooks have been replaced by ->exec_op(). Move them to the
nand_legacy struct.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
All those hooks have been replaced by ->exec_op(). Move them to the
nand_legacy struct.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers and
hooks to take a nand_chip object instead of an mtd_info one or
remove the mtd_info object when both are passed.
Let's tackle the chip->cmdfunc() hook.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers and
hooks to take a nand_chip object instead of an mtd_info one or
remove the mtd_info object when both are passed.
Let's tackle all chip->block_xxx() hooks at once.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers and
hooks to take a nand_chip object instead of an mtd_info one or
remove the mtd_info object when both are passed.
Let's tackle the chip->select_chip() hook.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers and
hooks to take a nand_chip object instead of an mtd_info one or
remove the mtd_info object when both are passed.
Let's tackle all chip->write_xxx() hooks at once.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers and
hooks to take a nand_chip object instead of an mtd_info one or
remove the mtd_info object when both are passed.
Let's tackle all chip->read_xxx() hooks at once.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers and
hooks to take a nand_chip object instead of an mtd_info one or
remove the mtd_info object when both are passed.
Let's tackle all ecc->write_xxx() hooks at once.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers and
hooks to take a nand_chip object instead of an mtd_info one or
remove the mtd_info object when both are passed.
Let's tackle all ecc->read_xxx() hooks at once.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Acked-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers to
take a nand_chip object instead of an mtd_info one.
Now is nand_release()'s turn.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Let's make the raw NAND API consistent by patching all helpers to take
a nand_chip object instead of an mtd_info one.
We start with nand_scan().
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
A recent commit removed the incorrect use of phys_to_dma from this
driver, but failed to remove the dma-direct.h include, so do that
now.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Two helpers have been added to the core to do all kind of controller
side configuration/initialization between the detection phase and the
final NAND scan. Implement these hooks so that we can convert the driver
to just use nand_scan() instead of the nand_scan_ident() +
nand_scan_tail() pair.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
In the raw NAND core, a NAND chip is described by a nand_chip structure,
while a NAND controller is described with a nand_hw_control structure
which is not very meaningful.
Rename this structure nand_controller.
As the structure gets renamed, it is logical to also rename the core
function initializing it from nand_hw_control_init() to
nand_controller_init().
Lastly, the 'hwcontrol' entry of the nand_chip structure is not
meaningful neither while it has the role of fallback when no controller
structure is provided by the driver (the controller driver is dumb and
can only control a single chip). Thus, it is renamed dummy_controller.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Acked-by: Boris Brezillon <boris.brezillon@bootlin.com>
Compile-testing this driver on x86 caused a link error:
ERROR: "__phys_to_dma" [drivers/mtd/nand/raw/qcom_nandc.ko] undefined!
The problem here is that the driver attempts to convert the physical
address into the DMA controller as a dma_addr_t and calls phys_to_dma()
to do the conversion.
The correct way to do the conversion is using the dma mapping interfaces.
Fixes: c76b78d8ec ("mtd: nand: Qualcomm NAND controller driver")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
NAND parts can have bitflips in an erased page due to the
process technology used. In this case, QCOM NAND controller
is not able to identify that page as an erased page.
Currently the driver calls nand_check_erased_ecc_chunk() for
identifying the erased pages but this won’t work always since the
checking is being with ECC engine returned data. In case of
bitflips, the ECC engine tries to correct the data and then it
generates the uncorrectable error. Now, this data is not equal to
original raw data. For erased CW identification, the raw data
should be read again from NAND device and this
nand_check_erased_ecc_chunk function() should be called for raw
data only.
Now following logic is being added to identify the erased
codeword bitflips.
1. In most of the cases, not all the codewords will have bitflips
and only single CW will have bitflips. So, there is no need to
read the complete raw page data. The NAND raw read can be
scheduled for any CW in page. The NAND controller works on CW
basis and it will update the status register after each CW read.
Maintain the bitmask for the CW which generated the uncorrectable
error.
2. Do raw read for all the CW's which generated the uncorrectable
error.
3. Both DATA and OOB need to be checked for number of 0. The
top-level API can be called with only data buf or OOB buf so use
chip->databuf if data buf is null and chip->oob_poi if
OOB buf is null for copying the raw bytes temporarily.
4. For each CW, check the number of 0 in cw_data and usable
oob bytes, The bbm and spare (unused) bytes bit flip won’t
affect the ECC so don’t check the number of bitflips in this area.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Make separate function to perform raw read for one codeword and
call this function multiple times for each codeword in case of
raw page read. This separate function will help in subsequent
patches related with erased codeword bitflip detection.
It will decrease throughput for raw page read. Raw page read
is used for debug purpose so it won't affect normal flash
operations.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Currently there is no error checking for raw read. For raw
reads, there won’t be any ECC failure but the operational
failures are possible, so schedule the NAND_FLASH_STATUS read
after each codeword.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Fix value returned by ->read_page_raw() to be the
actual operation status, instead of always 0.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
QCOM NAND controller layout protects available OOB data bytes with
ECC also so when ecc->write_oob() is being called then it
can't update just OOB bytes. Currently, it first reads the last
codeword which includes old OOB bytes. Then it updates the old OOB
bytes with new ones and then again writes the codeword back.
The reading codeword is unnecessary since user is responsible to
have these bytes cleared to 0xFF.
This patch removes the read part and updates the OOB bytes with
data area padded with OxFF.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
read_page and read_oob both calls the read_page_ecc function.
The QCOM NAND controller protect the OOB available bytes with
ECC so read errors should be checked for read_oob also.
This patch moves the error checking code inside read_page_ecc
so caller does not have to check explicitly for read errors.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
parse_read_errors can be called with only oob_buf in which case
data_buf will be NULL. If data_buf is NULL, then don’t
treat this page as completely erased in case of ECC uncorrectable
error for RS ECC. For BCH ECC, the controller itself tells
regarding erased page in status register.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Following is the flow in the HW if controller tries to read erased
page:
1. First ECC uncorrectable error will be generated from ECC engine
since ECC engine first calculates the ECC with all 0xff and match
the calculated ECC with ECC code in OOB (which is again all 0xff).
2. After getting ECC error, erased CW detection logic will be
applied which is different for BCH and RS ECC
a. For BCH, HW checks if all the bytes in page are 0xff and then
it updates the status in separate register
NAND_ERASED_CW_DETECT_STATUS.
b. For RS ECC, the HW reports the same error when reading an
erased CW, but it notifies that it is an erased CW by
placing special characters at certain offsets in the
buffer.
So the erased CW detect status should be checked only if ECC engine
generated the uncorrectable error.
Currently for all other operational errors also (like TIMEOUT, MPU
errors, etc.), the erased CW detect logic is being applied so fix this
and return EIO for other operational errors.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
The BAM has 3 channels - tx, rx and command. command channel
is used for register read/writes, tx channel for data writes
and rx channel for data reads. Currently, the driver assumes the
transfer completion once it gets all the command descriptors
completed. Sometimes, there is race condition between data channel
(tx/rx) and command channel completion. In these cases,
the data present in buffer is not valid during small window
between command descriptor completion and data descriptor
completion.
This patch generates NAND transfer completion when both
(Data and Command) DMA channels have completed all its DMA
descriptors. It assigns completion callback in last
DMA descriptors of that channel and wait for completion.
Fixes: 8d6b6d7e13 ("mtd: nand: qcom: support for command descriptor formation")
Cc: stable@vger.kernel.org
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Currently the driver uses the ECC strength specified in DT.
The QPIC/EBI2 NAND supports 4 or 8-bit ECC correction. The same
kind of board can have different NAND parts so use the ECC
strength from device parameters if it is not specified in DT.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
QCOM NAND controller supports only one step size (512) so
nand-ecc-step-size DT property is redundant. This property
can be removed and ecc step size can be assigned with 512 value.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
SET/GET FEATURES are flagged ONFI-compliant because of their name. This
is not accurate as non-ONFI NAND chips support it and use it.
Rename the hooks and helpers to remove the "onfi" prefix.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
As part of the process of sharing more code between different NAND
based devices, we need to move all raw NAND related code to the raw/
subdirectory.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>