From efba2e313ea1b1bd69a7c4659263becf43bb1adc Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Fri, 11 Feb 2011 13:00:37 +0300 Subject: mtd: jedec_probe: Change variable name from cfi_p to cfi In the following commit, we'll need to use the CMD() macro in order to fix the initialisation of the sector_erase_cmd field. That requires the local variable to be called 'cfi', so change it first in a simple patch. Signed-off-by: Antony Pavlov Acked-by: Guillaume LECERF Signed-off-by: David Woodhouse CC: stable@kernel.org --- drivers/mtd/chips/jedec_probe.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index d72a5fb2d041..7bedbb96604d 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -1935,14 +1935,14 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi) } -static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) +static int cfi_jedec_setup(struct cfi_private *cfi, int index) { int i,num_erase_regions; uint8_t uaddr; - if (! (jedec_table[index].devtypes & p_cfi->device_type)) { + if (!(jedec_table[index].devtypes & cfi->device_type)) { DEBUG(MTD_DEBUG_LEVEL1, "Rejecting potential %s with incompatible %d-bit device type\n", - jedec_table[index].name, 4 * (1<device_type)); + jedec_table[index].name, 4 * (1<device_type)); return 0; } @@ -1950,27 +1950,27 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) num_erase_regions = jedec_table[index].nr_regions; - p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); - if (!p_cfi->cfiq) { + cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); + if (!cfi->cfiq) { //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); return 0; } - memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); + memset(cfi->cfiq, 0, sizeof(struct cfi_ident)); - p_cfi->cfiq->P_ID = jedec_table[index].cmd_set; - p_cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions; - p_cfi->cfiq->DevSize = jedec_table[index].dev_size; - p_cfi->cfi_mode = CFI_MODE_JEDEC; + cfi->cfiq->P_ID = jedec_table[index].cmd_set; + cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions; + cfi->cfiq->DevSize = jedec_table[index].dev_size; + cfi->cfi_mode = CFI_MODE_JEDEC; for (i=0; icfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; + cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; } - p_cfi->cmdset_priv = NULL; + cfi->cmdset_priv = NULL; /* This may be redundant for some cases, but it doesn't hurt */ - p_cfi->mfr = jedec_table[index].mfr_id; - p_cfi->id = jedec_table[index].dev_id; + cfi->mfr = jedec_table[index].mfr_id; + cfi->id = jedec_table[index].dev_id; uaddr = jedec_table[index].uaddr; @@ -1978,8 +1978,8 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) our brains explode when we see the datasheets talking about address lines numbered from A-1 to A18. The CFI table has unlock addresses in device-words according to the mode the device is connected in */ - p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 / p_cfi->device_type; - p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 / p_cfi->device_type; + cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 / cfi->device_type; + cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 / cfi->device_type; return 1; /* ok */ } -- cgit v1.2.3 From ceabebb2bd2672f709e4454e16bc6042732e2dfe Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Fri, 11 Feb 2011 13:00:37 +0300 Subject: mtd: jedec_probe: initialise make sector erase command variable In the commit 08968041bef437ec363623cd3218c2b083537ada (mtd: cfi_cmdset_0002: make sector erase command variable) introdused a field sector_erase_cmd. In the same commit initialisation of cfi->sector_erase_cmd made in cfi_chip_setup() (file drivers/mtd/chips/cfi_probe.c), so the CFI chip has no problem: ... cfi->cfi_mode = CFI_MODE_CFI; cfi->sector_erase_cmd = CMD(0x30); ... But for the JEDEC chips this initialisation is not carried out, so the JEDEC chips have sector_erase_cmd == 0. This patch adds the missing initialisation. Signed-off-by: Antony Pavlov Acked-by: Guillaume LECERF Signed-off-by: David Woodhouse CC: stable@kernel.org --- drivers/mtd/chips/jedec_probe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 7bedbb96604d..4e1be51cc122 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -1935,7 +1935,7 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi) } -static int cfi_jedec_setup(struct cfi_private *cfi, int index) +static int cfi_jedec_setup(struct map_info *map, struct cfi_private *cfi, int index) { int i,num_erase_regions; uint8_t uaddr; @@ -1962,6 +1962,7 @@ static int cfi_jedec_setup(struct cfi_private *cfi, int index) cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions; cfi->cfiq->DevSize = jedec_table[index].dev_size; cfi->cfi_mode = CFI_MODE_JEDEC; + cfi->sector_erase_cmd = CMD(0x30); for (i=0; icfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; @@ -2175,7 +2176,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", __func__, cfi->mfr, cfi->id, cfi->addr_unlock1, cfi->addr_unlock2 ); - if (!cfi_jedec_setup(cfi, i)) + if (!cfi_jedec_setup(map, cfi, i)) return 0; goto ok_out; } -- cgit v1.2.3 From ecf3fde07c8dcb92a1bf3fbdfe70905d85cd00e1 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Mon, 7 Feb 2011 17:07:11 +0100 Subject: mtd: fix race in cfi_cmdset_0001 driver As inval_cache_and_wait_for_operation() drop and reclaim the lock to invalidate the cache, some other thread may suspend the operation before reaching the for(;;) loop. Therefore the loop must start with checking the chip->state before reading status from the chip. Signed-off-by: Joakim Tjernlund Acked-by: Michael Cashwell Acked-by: Stefan Bigler Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/chips/cfi_cmdset_0001.c | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index a8c3e1c9b02a..4aaa88f8ab5f 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1230,10 +1230,32 @@ static int inval_cache_and_wait_for_operation( sleep_time = chip_op_time / 2; for (;;) { + if (chip->state != chip_state) { + /* Someone's suspended the operation: sleep */ + DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + mutex_unlock(&chip->mutex); + schedule(); + remove_wait_queue(&chip->wq, &wait); + mutex_lock(&chip->mutex); + continue; + } + status = map_read(map, cmd_adr); if (map_word_andequal(map, status, status_OK, status_OK)) break; + if (chip->erase_suspended && chip_state == FL_ERASING) { + /* Erase suspend occured while sleep: reset timeout */ + timeo = reset_timeo; + chip->erase_suspended = 0; + } + if (chip->write_suspended && chip_state == FL_WRITING) { + /* Write suspend occured while sleep: reset timeout */ + timeo = reset_timeo; + chip->write_suspended = 0; + } if (!timeo) { map_write(map, CMD(0x70), cmd_adr); chip->state = FL_STATUS; @@ -1257,27 +1279,6 @@ static int inval_cache_and_wait_for_operation( timeo--; } mutex_lock(&chip->mutex); - - while (chip->state != chip_state) { - /* Someone's suspended the operation: sleep */ - DECLARE_WAITQUEUE(wait, current); - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); - mutex_unlock(&chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - mutex_lock(&chip->mutex); - } - if (chip->erase_suspended && chip_state == FL_ERASING) { - /* Erase suspend occured while sleep: reset timeout */ - timeo = reset_timeo; - chip->erase_suspended = 0; - } - if (chip->write_suspended && chip_state == FL_WRITING) { - /* Write suspend occured while sleep: reset timeout */ - timeo = reset_timeo; - chip->write_suspended = 0; - } } /* Done and happy. */ -- cgit v1.2.3 From 82013d988fc03a1b908b2b0360a1e34f6152fda6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 8 Jan 2011 15:24:37 +0100 Subject: mtd: amd76xrom: fix oops at boot when resources are not available For some unknown reasons resources needed by amd76xrom driver can be unavailable. And instead of returning an error, the driver keeps going and crash the kernel. This patch fixes the problem by making the driver return -EBUSY if the resources are not available. Commit messages tweaked by Artem. Reported-by: Russell Whitaker Signed-off-by: Stanislaw Gruszka Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/maps/amd76xrom.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 77d64ce19e9f..92de7e3a49a5 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c @@ -151,6 +151,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, printk(KERN_ERR MOD_NAME " %s(): Unable to register resource %pR - kernel bug?\n", __func__, &window->rsrc); + return -EBUSY; } -- cgit v1.2.3 From bd637f6f22235b4613f9ab6555e8088a455c1ed4 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Sun, 9 Jan 2011 01:25:06 +0200 Subject: mtd: mtd_blkdevs: fix double free on error path This one liner patch fixes double free that will occur if add_mtd_blktrans_dev fails. On failure it frees the input argument, but all its users also free it on error which is natural thing to do. Thus don't free it. All credit for finding that bug belongs to reporters of the bug in the android bugzilla http://code.google.com/p/android/issues/detail?id=13761 Commit message tweaked by Artem. Signed-off-by: Maxim Levitsky Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/mtd_blkdevs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index cb20c67995d8..e0a2373bf0e2 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -413,7 +413,6 @@ error3: error2: list_del(&new->list); error1: - kfree(new); return ret; } -- cgit v1.2.3 From c804c733846572ca85c2bba60c7fe6fa024dff18 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 7 Mar 2011 11:04:24 +0800 Subject: mtd: add "platform:" prefix for platform modalias Since 43cc71eed1250755986da4c0f9898f9a635cb3bf (platform: prefix MODALIAS with "platform:"), the platform modalias is prefixed with "platform:". Signed-off-by: Axel Lin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/nand/omap2.c | 2 +- drivers/mtd/onenand/generic.c | 2 +- drivers/mtd/onenand/omap2.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 15682ec8530e..28af71c61834 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -968,6 +968,6 @@ static void __exit omap_nand_exit(void) module_init(omap_nand_init); module_exit(omap_nand_exit); -MODULE_ALIAS(DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Glue layer for NAND flash on TI OMAP boards"); diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index e78914938c5c..ac08750748a3 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c @@ -131,7 +131,7 @@ static struct platform_driver generic_onenand_driver = { .remove = __devexit_p(generic_onenand_remove), }; -MODULE_ALIAS(DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); static int __init generic_onenand_init(void) { diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index ac31f461cc1c..c849cacf4b2f 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -860,7 +860,7 @@ static void __exit omap2_onenand_exit(void) module_init(omap2_onenand_init); module_exit(omap2_onenand_exit); -MODULE_ALIAS(DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jarkko Lavinen "); MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP2 / OMAP3"); -- cgit v1.2.3