diff options
Diffstat (limited to 'drivers/mtd')
93 files changed, 2298 insertions, 1638 deletions
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 94539312995..7c057a05adb 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c @@ -26,19 +26,16 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/bootmem.h> -#include <linux/magic.h> #include <linux/module.h> +#include <uapi/linux/magic.h> + #define AR7_PARTS 4 #define ROOT_OFFSET 0xe0000 #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) -#ifndef SQUASHFS_MAGIC -#define SQUASHFS_MAGIC 0x73717368 -#endif - struct ar7_bin_rec { unsigned int checksum; unsigned int length; diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 63d2a64331f..6eeb84c81bc 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -37,8 +37,7 @@ #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ -#define BCM63XX_MIN_CFE_SIZE 0x10000 /* always at least 64KiB */ -#define BCM63XX_MIN_NVRAM_SIZE 0x10000 /* always at least 64KiB */ +#define BCM63XX_CFE_BLOCK_SIZE 0x10000 /* always at least 64KiB */ #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 @@ -79,7 +78,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, unsigned int rootfsaddr, kerneladdr, spareaddr; unsigned int rootfslen, kernellen, sparelen, totallen; unsigned int cfelen, nvramlen; - int namelen = 0; + unsigned int cfe_erasesize; int i; u32 computed_crc; bool rootfs_first = false; @@ -87,8 +86,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, if (bcm63xx_detect_cfe(master)) return -EINVAL; - cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE); - nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE); + cfe_erasesize = max_t(uint32_t, master->erasesize, + BCM63XX_CFE_BLOCK_SIZE); + + cfelen = cfe_erasesize; + nvramlen = cfe_erasesize; /* Allocate memory for buffer */ buf = vmalloc(sizeof(struct bcm_tag)); @@ -121,7 +123,6 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; spareaddr = roundup(totallen, master->erasesize) + cfelen; - sparelen = master->size - spareaddr - nvramlen; if (rootfsaddr < kerneladdr) { /* default Broadcom layout */ @@ -139,19 +140,15 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, rootfslen = 0; rootfsaddr = 0; spareaddr = cfelen; - sparelen = master->size - cfelen - nvramlen; } + sparelen = master->size - spareaddr - nvramlen; /* Determine number of partitions */ - namelen = 8; - if (rootfslen > 0) { + if (rootfslen > 0) nrparts++; - namelen += 6; - } - if (kernellen > 0) { + + if (kernellen > 0) nrparts++; - namelen += 6; - } /* Ask kernel for more memory */ parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); @@ -193,17 +190,16 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, parts[curpart].name = "nvram"; parts[curpart].offset = master->size - nvramlen; parts[curpart].size = nvramlen; + curpart++; /* Global partition "linux" to make easy firmware upgrade */ - curpart++; parts[curpart].name = "linux"; parts[curpart].offset = cfelen; parts[curpart].size = master->size - cfelen - nvramlen; for (i = 0; i < nrparts; i++) - pr_info("Partition %d is %s offset %lx and length %lx\n", i, - parts[i].name, (long unsigned int)(parts[i].offset), - (long unsigned int)(parts[i].size)); + pr_info("Partition %d is %s offset %llx and length %llx\n", i, + parts[i].name, parts[i].offset, parts[i].size); pr_info("Spare partition is offset %x and length %x\n", spareaddr, sparelen); diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 5ff5c4a1694..b86197286f2 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1536,8 +1536,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, UDELAY(map, chip, adr, 1); } - /* reset on all failures. */ - map_write( map, CMD(0xF0), chip->start ); + /* + * Recovery from write-buffer programming failures requires + * the write-to-buffer-reset sequence. Since the last part + * of the sequence also works as a normal reset, we can run + * the same commands regardless of why we are here. + * See e.g. + * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf + */ + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, + cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, + cfi->device_type, NULL); + cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, chip->start, map, cfi, + cfi->device_type, NULL); xip_enable(map, chip, adr); /* FIXME - should have reset delay before continuing */ diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index aed1b8a63c9..c533f27d863 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -56,8 +56,8 @@ /* special size referring to all the remaining space in a partition */ -#define SIZE_REMAINING UINT_MAX -#define OFFSET_CONTINUOUS UINT_MAX +#define SIZE_REMAINING ULLONG_MAX +#define OFFSET_CONTINUOUS ULLONG_MAX struct cmdline_mtd_partition { struct cmdline_mtd_partition *next; @@ -89,7 +89,7 @@ static struct mtd_partition * newpart(char *s, int extra_mem_size) { struct mtd_partition *parts; - unsigned long size, offset = OFFSET_CONTINUOUS; + unsigned long long size, offset = OFFSET_CONTINUOUS; char *name; int name_len; unsigned char *extra_mem; @@ -104,7 +104,8 @@ static struct mtd_partition * newpart(char *s, } else { size = memparse(s, &s); if (size < PAGE_SIZE) { - printk(KERN_ERR ERRP "partition size too small (%lx)\n", size); + printk(KERN_ERR ERRP "partition size too small (%llx)\n", + size); return ERR_PTR(-EINVAL); } } @@ -296,7 +297,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, struct mtd_part_parser_data *data) { - unsigned long offset; + unsigned long long offset; int i, err; struct cmdline_mtd_partition *part; const char *mtd_id = master->name; @@ -308,48 +309,52 @@ static int parse_cmdline_partitions(struct mtd_info *master, return err; } + /* + * Search for the partition definition matching master->name. + * If master->name is not set, stop at first partition definition. + */ for (part = partitions; part; part = part->next) { - if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) { - for (i = 0, offset = 0; i < part->num_parts; i++) { - if (part->parts[i].offset == OFFSET_CONTINUOUS) - part->parts[i].offset = offset; - else - offset = part->parts[i].offset; - - if (part->parts[i].size == SIZE_REMAINING) - part->parts[i].size = master->size - offset; - - if (part->parts[i].size == 0) { - printk(KERN_WARNING ERRP - "%s: skipping zero sized partition\n", - part->mtd_id); - part->num_parts--; - memmove(&part->parts[i], - &part->parts[i + 1], - sizeof(*part->parts) * (part->num_parts - i)); - continue; - } - - if (offset + part->parts[i].size > master->size) { - printk(KERN_WARNING ERRP - "%s: partitioning exceeds flash size, truncating\n", - part->mtd_id); - part->parts[i].size = master->size - offset; - } - offset += part->parts[i].size; - } - - *pparts = kmemdup(part->parts, - sizeof(*part->parts) * part->num_parts, - GFP_KERNEL); - if (!*pparts) - return -ENOMEM; - - return part->num_parts; + if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) + break; + } + + if (!part) + return 0; + + for (i = 0, offset = 0; i < part->num_parts; i++) { + if (part->parts[i].offset == OFFSET_CONTINUOUS) + part->parts[i].offset = offset; + else + offset = part->parts[i].offset; + + if (part->parts[i].size == SIZE_REMAINING) + part->parts[i].size = master->size - offset; + + if (part->parts[i].size == 0) { + printk(KERN_WARNING ERRP + "%s: skipping zero sized partition\n", + part->mtd_id); + part->num_parts--; + memmove(&part->parts[i], &part->parts[i + 1], + sizeof(*part->parts) * (part->num_parts - i)); + continue; } + + if (offset + part->parts[i].size > master->size) { + printk(KERN_WARNING ERRP + "%s: partitioning exceeds flash size, truncating\n", + part->mtd_id); + part->parts[i].size = master->size - offset; + } + offset += part->parts[i].size; } - return 0; + *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, + GFP_KERNEL); + if (!*pparts) + return -ENOMEM; + + return part->num_parts; } diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c index 2dc5a6f3fd5..4714584aa99 100644 --- a/drivers/mtd/devices/bcm47xxsflash.c +++ b/drivers/mtd/devices/bcm47xxsflash.c @@ -66,7 +66,7 @@ out: return err; } -static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) +static int bcm47xxsflash_remove(struct platform_device *pdev) { struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); @@ -77,7 +77,7 @@ static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) } static struct platform_driver bcma_sflash_driver = { - .remove = __devexit_p(bcm47xxsflash_remove), + .remove = bcm47xxsflash_remove, .driver = { .name = "bcma_sflash", .owner = THIS_MODULE, diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 681e2ee0f2d..e081bfeaaf7 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -62,6 +62,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) memset(page_address(page), 0xff, PAGE_SIZE); set_page_dirty(page); unlock_page(page); + balance_dirty_pages_ratelimited(mapping); break; } @@ -152,6 +153,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, memcpy(page_address(page) + offset, buf, cpylen); set_page_dirty(page); unlock_page(page); + balance_dirty_pages_ratelimited(mapping); } page_cache_release(page); @@ -433,7 +435,7 @@ static int __init block2mtd_init(void) } -static void __devexit block2mtd_exit(void) +static void block2mtd_exit(void) { struct list_head *pos, *next; diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index d34d83b8f9c..8510ccb9c6f 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1440,7 +1440,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, oobdelta = mtd->ecclayout->oobavail; break; default: - oobdelta = 0; + return -EINVAL; } if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) || (ofs % DOC_LAYOUT_PAGE_SIZE)) diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c index 706b847b46b..88b3fd3e18a 100644 --- a/drivers/mtd/devices/docprobe.c +++ b/drivers/mtd/devices/docprobe.c @@ -70,8 +70,6 @@ static unsigned long __initdata doc_locations[] = { 0xe0000, 0xe2000, 0xe4000, 0xe6000, 0xe8000, 0xea000, 0xec000, 0xee00 |