From 6f5afaed58a7d560fb7ba4a028662de22011a7a7 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Fri, 28 Mar 2008 14:15:47 -0700 Subject: mtd: nand: add out label in rfc_from4 This has been forgotten in commit f5bbdacc419 ("[MTD] NAND Modularize read function") and nobody compiled the driver. Signed-off-by: Sebastian Siewior Cc: Thomas Gleixner Cc: David Woodhouse Cc: Joern Engel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/nand/rtc_from4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 9189ec8f243e..0f6ac250f434 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c @@ -460,7 +460,7 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, er_stat |= 1 << 1; kfree(buf); } - +out: rtn = status; if (er_stat == 0) { /* if ECC is available */ rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */ -- cgit v1.2.3-59-g8ed1b From 4a5691c0f7b65b7aa9d237e55f05e691352caac7 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 28 Mar 2008 14:16:09 -0700 Subject: mtd: maps/physmap: fix oops in suspend/resume/shutdown ops # reboot ... [ 42.351266] Flash device refused suspend due to active operation (state 0) [ 42.358195] Unable to handle kernel NULL pointer dereference at virtual address 00000078 [ 42.360060] pgd = c7d9c000 [ 42.362769] [00000078] *pgd=a7d8d031, *pte=00000000, *ppte=00000000 [ 42.372902] Internal error: Oops: 17 [#1] [ 42.376911] Modules linked in: [ 42.379980] CPU: 0 Not tainted (2.6.25-rc2-10642-ge8f2594-dirty #73) [ 42.380000] PC is at physmap_flash_shutdown+0x28/0x54 ... [ 42.380000] Backtrace: [ 42.380000] [] (physmap_flash_shutdown+0x0/0x54) from [] (platform_drv_shutdown+0x20/0x24) [ 42.380000] r5:28121969 r4:c0229e08 [ 42.380000] [] (platform_drv_shutdown+0x0/0x24) from [] (device_shutdown+0x60/0x88) [ 42.380000] [] (device_shutdown+0x0/0x88) from [] (kernel_restart_prepare+0x2c/0x3c) [ 42.380000] r4:00000000 [ 42.380000] [] (kernel_restart_prepare+0x0/0x3c) from [] (kernel_restart+0x14/0x48) [ 42.380000] [] (kernel_restart+0x0/0x48) from [] (sys_reboot+0xe8/0x1f8) [ 42.380000] r4:01234567 [ 42.380000] [] (sys_reboot+0x0/0x1f8) from [] (ret_fast_syscall+0x0/0x2c) [ 42.380000] r7:00000058 r6:00000004 r5:00000001 r4:00000000 [ 42.380000] Code: 0a000009 e7953004 e1a00003 e1a0e00f (e593f078) [ 42.650051] ---[ end trace 6d6c26a0fc3141de ]--- Segmentation fault INIT: no more processes left in this runlevel While looping for mtd[i]s, we should stop at the mtd[i] == NULL. This patch also removes unnecessary "if (info)" checks: suspend/resume/shutdown ops are executed only if probe() is succeeded, so info is guaranteed to be !NULL. Signed-off-by: Anton Vorontsov Cc: David Brownell Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/maps/physmap.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index f00e04efbe28..bc4649a17b9d 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -202,9 +202,8 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state int ret = 0; int i; - if (info) - for (i = 0; i < MAX_RESOURCES; i++) - ret |= info->mtd[i]->suspend(info->mtd[i]); + for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) + ret |= info->mtd[i]->suspend(info->mtd[i]); return ret; } @@ -214,9 +213,9 @@ static int physmap_flash_resume(struct platform_device *dev) struct physmap_flash_info *info = platform_get_drvdata(dev); int i; - if (info) - for (i = 0; i < MAX_RESOURCES; i++) - info->mtd[i]->resume(info->mtd[i]); + for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) + info->mtd[i]->resume(info->mtd[i]); + return 0; } @@ -225,8 +224,8 @@ static void physmap_flash_shutdown(struct platform_device *dev) struct physmap_flash_info *info = platform_get_drvdata(dev); int i; - for (i = 0; i < MAX_RESOURCES; i++) - if (info && info->mtd[i]->suspend(info->mtd[i]) == 0) + for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) + if (info->mtd[i]->suspend(info->mtd[i]) == 0) info->mtd[i]->resume(info->mtd[i]); } #else -- cgit v1.2.3-59-g8ed1b From fb6d080c6f75dfd7e23d5a3575334785aa8738eb Mon Sep 17 00:00:00 2001 From: Alexey Korolev Date: Fri, 4 Apr 2008 14:30:01 -0700 Subject: mtd: fix broken state in CFI driver caused by FL_SHUTDOWN THe CFI driver in 2.6.24 kernel is broken. Not so intensive read/write operations cause incomplete writes which lead to kernel panics in JFFS2. We investigated the issue - it is caused by bug in FL_SHUTDOWN parsing code. Sometimes chip returns -EIO as if it is in FL_SHUTDOWN state when it should wait in FL_PONT (error in order of conditions). The following patch fixes the bug in state parsing code of CFI. Also I've added comments to notify developers if they want to add new case in future. Signed-off-by: Alexey Korolev Reviewed-by: Joern Engel Cc: David Woodhouse Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/chips/cfi_cmdset_0001.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 47794d23a42e..0080452531d6 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -718,7 +718,7 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long /* Someone else might have been playing with it. */ return -EAGAIN; } - + /* Fall through */ case FL_READY: case FL_CFI_QUERY: case FL_JEDEC_QUERY: @@ -778,14 +778,14 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long chip->state = FL_READY; return 0; + case FL_SHUTDOWN: + /* The machine is rebooting now,so no one can get chip anymore */ + return -EIO; case FL_POINT: /* Only if there's no operation suspended... */ if (mode == FL_READY && chip->oldstate == FL_READY) return 0; - - case FL_SHUTDOWN: - /* The machine is rebooting now,so no one can get chip anymore */ - return -EIO; + /* Fall through */ default: sleep: set_current_state(TASK_UNINTERRUPTIBLE); -- cgit v1.2.3-59-g8ed1b From f8e30e447c692aaa728c65930ebc0146f65e1e7b Mon Sep 17 00:00:00 2001 From: Dmitry Adamushko Date: Tue, 8 Apr 2008 17:41:59 -0700 Subject: mtd/chips: add missing set_current_state() to cfi_{amdstd,staa}_sync() cfi_amdstd_sync() and cfi_staa_sync() call schedule() without changing task's state appropriately. In case of e.g. chip->state == FL_ERASING, cfi_*_sync() will be busy-looping either redundantly for a fixed interval of time (for SCHED_NORMAL tasks) or possibly endlessly (for RT tasks and UP). Signed-off-by: Dmitry Adamushko Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/chips/cfi_cmdset_0002.c | 1 + drivers/mtd/chips/cfi_cmdset_0020.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index d072e87ce4e2..458d477614d6 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1763,6 +1763,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd) default: /* Not an idle state */ + set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); spin_unlock(chip->mutex); diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index b344ff858b2d..492e2ab27420 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -1015,6 +1015,7 @@ static void cfi_staa_sync (struct mtd_info *mtd) default: /* Not an idle state */ + set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&chip->wq, &wait); spin_unlock_bh(chip->mutex); -- cgit v1.2.3-59-g8ed1b