mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
mtd: rawnand: serialize lock/unlock against other NAND operations
nand_lock() and nand_unlock() call into chip->ops.lock_area/unlock_area
without holding the NAND device lock. On controllers that implement
SET_FEATURES via multiple low-level PIO commands, these can race with
concurrent UBI/UBIFS background erase/write operations that hold the
device lock, resulting in cmd_pending conflicts on the NAND controller.
Add nand_get_device()/nand_release_device() around the lock/unlock
operations to serialize them against all other NAND controller access.
Fixes: 92270086b7 ("mtd: rawnand: Add support for manufacturer specific lock/unlock operation")
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
Reviewed-by: William Zhang <william.zhang@broadcom.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
committed by
Miquel Raynal
parent
073b2db724
commit
bab2bc6e85
@@ -4737,11 +4737,16 @@ static void nand_shutdown(struct mtd_info *mtd)
|
||||
static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
int ret;
|
||||
|
||||
if (!chip->ops.lock_area)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return chip->ops.lock_area(chip, ofs, len);
|
||||
nand_get_device(chip);
|
||||
ret = chip->ops.lock_area(chip, ofs, len);
|
||||
nand_release_device(chip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4753,11 +4758,16 @@ static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
static int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
int ret;
|
||||
|
||||
if (!chip->ops.unlock_area)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return chip->ops.unlock_area(chip, ofs, len);
|
||||
nand_get_device(chip);
|
||||
ret = chip->ops.unlock_area(chip, ofs, len);
|
||||
nand_release_device(chip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set default functions */
|
||||
|
||||
Reference in New Issue
Block a user