diff options
Diffstat (limited to 'drivers/mtd')
40 files changed, 212 insertions, 1069 deletions
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index 0f6bb2e625d8..a7ec5954caf5 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -200,27 +200,6 @@ config MTD_CFI_AMDSTD provides support for one of those command sets, used on chips including the AMD Am29LV320. -config MTD_CFI_AMDSTD_RETRY - int "Retry failed commands (erase/program)" - depends on MTD_CFI_AMDSTD - default "0" - help - Some chips, when attached to a shared bus, don't properly filter - bus traffic that is destined to other devices. This broken - behavior causes erase and program sequences to be aborted when - the sequences are mixed with traffic for other devices. - - SST49LF040 (and related) chips are know to be broken. - -config MTD_CFI_AMDSTD_RETRY_MAX - int "Max retries of failed commands (erase/program)" - depends on MTD_CFI_AMDSTD_RETRY - default "0" - help - If you have an SST49LF040 (or related chip) then this value should - be set to at least 1. This can also be adjusted at driver load - time with the retry_cmd_max module parameter. - config MTD_CFI_STAA tristate "Support for ST (Advanced Architecture) flash chips" depends on MTD_GEN_PROBE diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c index fdb91b6f1d97..57115618c496 100644 --- a/drivers/mtd/chips/amd_flash.c +++ b/drivers/mtd/chips/amd_flash.c @@ -664,7 +664,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) printk("%s: Probing for AMD compatible flash...\n", map->name); if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table, - sizeof(table)/sizeof(table[0]))) + ARRAY_SIZE(table))) == -1) { printk(KERN_WARNING "%s: Found no AMD compatible device at location zero\n", @@ -696,7 +696,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) base += (1 << temp.chipshift)) { int numchips = temp.numchips; table_pos[numchips] = probe_new_chip(mtd, base, chips, - &temp, table, sizeof(table)/sizeof(table[0])); + &temp, table, ARRAY_SIZE(table)); } mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index edb306c03c0a..517ea33e7260 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -34,6 +34,7 @@ #define MANUFACTURER_MACRONIX 0x00C2 #define MANUFACTURER_NEC 0x0010 #define MANUFACTURER_PMC 0x009D +#define MANUFACTURER_SHARP 0x00b0 #define MANUFACTURER_SST 0x00BF #define MANUFACTURER_ST 0x0020 #define MANUFACTURER_TOSHIBA 0x0098 @@ -124,6 +125,9 @@ #define PM49FL004 0x006E #define PM49FL008 0x006A +/* Sharp */ +#define LH28F640BF 0x00b0 + /* ST - www.st.com */ #define M29W800DT 0x00D7 #define M29W800DB 0x005B @@ -1267,6 +1271,19 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO( 0x01000, 256 ) } + }, { + .mfr_id = MANUFACTURER_SHARP, + .dev_id = LH28F640BF, + .name = "LH28F640BF", + .uaddr = { + [0] = MTD_UADDR_UNNECESSARY, /* x8 */ + }, + .DevSize = SIZE_4MiB, + .CmdSet = P_ID_INTEL_STD, + .NumEraseRegions= 1, + .regions = { + ERASEINFO(0x40000,16), + } }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39LF512, @@ -2035,7 +2052,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, DEBUG(MTD_DEBUG_LEVEL3, "Search for id:(%02x %02x) interleave(%d) type(%d)\n", cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); - for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { + for (i = 0; i < ARRAY_SIZE(jedec_table); i++) { if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c index 36f61a6a766e..3cc0b23c5865 100644 --- a/drivers/mtd/chips/sharp.c +++ b/drivers/mtd/chips/sharp.c @@ -64,7 +64,7 @@ #undef AUTOUNLOCK /* automatically unlocks blocks before erasing */ -struct mtd_info *sharp_probe(struct map_info *); +static struct mtd_info *sharp_probe(struct map_info *); static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd); @@ -96,7 +96,6 @@ struct sharp_info{ struct flchip chips[1]; }; -struct mtd_info *sharp_probe(struct map_info *map); static void sharp_destroy(struct mtd_info *mtd); static struct mtd_chip_driver sharp_chipdrv = { @@ -107,7 +106,7 @@ static struct mtd_chip_driver sharp_chipdrv = { }; -struct mtd_info *sharp_probe(struct map_info *map) +static struct mtd_info *sharp_probe(struct map_info *map) { struct mtd_info *mtd = NULL; struct sharp_info *sharp = NULL; @@ -581,7 +580,7 @@ static void sharp_destroy(struct mtd_info *mtd) } -int __init sharp_probe_init(void) +static int __init sharp_probe_init(void) { printk("MTD Sharp chip driver <ds@lineo.com>\n"); diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 6b8bb2e4dcfd..a7a7bfe33879 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -42,7 +42,8 @@ /* special size referring to all the remaining space in a partition */ -#define SIZE_REMAINING 0xffffffff +#define SIZE_REMAINING UINT_MAX +#define OFFSET_CONTINUOUS UINT_MAX struct cmdline_mtd_partition { struct cmdline_mtd_partition *next; @@ -75,7 +76,7 @@ static struct mtd_partition * newpart(char *s, { struct mtd_partition *parts; unsigned long size; - unsigned long offset = 0; + unsigned long offset = OFFSET_CONTINUOUS; char *name; int name_len; unsigned char *extra_mem; @@ -314,7 +315,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, { for(i = 0, offset = 0; i < part->num_parts; i++) { - if (!part->parts[i].offset) + if (part->parts[i].offset == OFFSET_CONTINUOUS) part->parts[i].offset = offset; else offset = part->parts[i].offset; diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index dd628cb51e31..7fac438b5c32 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -129,8 +129,8 @@ config MTDRAM_ABS_POS allocating space from Linux's available memory. Otherwise, leave this set to zero. Most people will want to leave this as zero. -config MTD_BLKMTD - tristate "MTD emulation using block device" +config MTD_BLOCK2MTD + tristate "MTD using block device" depends on MTD help This driver allows a block device to appear as an MTD. It would @@ -141,15 +141,6 @@ config MTD_BLKMTD Testing MTD users (eg JFFS2) on large media and media that might be removed during a write (using the floppy drive). -config MTD_BLOCK2MTD - tristate "MTD using block device (rewrite)" - depends on MTD && EXPERIMENTAL - help - This driver is basically the same at MTD_BLKMTD above, but - experienced some interface changes plus serious speedups. In - the long term, it should replace MTD_BLKMTD. Right now, you - shouldn't entrust important data to it yet. - comment "Disk-On-Chip Device Drivers" config MTD_DOC2000 diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 7c5ed2178380..b6573670316f 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_MTD_PMC551) += pmc551.o obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o obj-$(CONFIG_MTD_MTDRAM) += mtdram.o obj-$(CONFIG_MTD_LART) += lart.o -obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c deleted file mode 100644 index 04f864d238db..000000000000 --- a/drivers/mtd/devices/blkmtd.c +++ /dev/null @@ -1,820 +0,0 @@ -/* - * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $ - * - * blkmtd.c - use a block device as a fake MTD - * - * Author: Simon Evans <spse@secret.org.uk> - * - * Copyright (C) 2001,2002 Simon Evans - * - * Licence: GPL - * - * How it works: - * The driver uses raw/io to read/write the device and the page - * cache to cache access. Writes update the page cache with the - * new data and mark it dirty and add the page into a BIO which - * is then written out. - * - * It can be loaded Read-Only to prevent erases and writes to the - * medium. - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/blkdev.h> -#include <linux/bio.h> -#include <linux/pagemap.h> -#include <linux/list.h> -#include <linux/init.h> -#include <linux/mtd/mtd.h> - - -#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) -#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "blkmtd: " format "\n" , ## arg) -#define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg) - - -/* Default erase size in K, always make it a multiple of PAGE_SIZE */ -#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ -#define VERSION "$Revision: 1.27 $" - -/* Info for the block device */ -struct blkmtd_dev { - struct list_head list; - struct block_device *blkdev; - struct mtd_info mtd_info; - struct semaphore wrbuf_mutex; -}; - - -/* Static info about the MTD, used in cleanup_module */ -static LIST_HEAD(blkmtd_device_list); - - -static void blkmtd_sync(struct mtd_info *mtd); - -#define MAX_DEVICES 4 - -/* Module parameters passed by insmod/modprobe */ -static char *device[MAX_DEVICES]; /* the block device to use */ -static int erasesz[MAX_DEVICES]; /* optional default erase size */ -static int ro[MAX_DEVICES]; /* optional read only flag */ -static int sync; - - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>"); -MODULE_DESCRIPTION("Emulate an MTD using a block device"); -module_param_array(device, charp, NULL, 0); -MODULE_PARM_DESC(device, "block device to use"); -module_param_array(erasesz, int, NULL, 0); -MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB."); -module_param_array(ro, bool, NULL, 0); -MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors"); -module_param(sync, bool, 0); -MODULE_PARM_DESC(sync, "1=Synchronous writes"); - - -/* completion handler for BIO reads */ -static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error) -{ - if (bio->bi_size) - return 1; - - complete((struct completion*)bio->bi_private); - return 0; -} - - -/* completion handler for BIO writes */ -static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error) -{ - const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; - - if (bio->bi_size) - return 1; - - if(!uptodate) - err("bi_write_complete: not uptodate\n"); - - do { - struct page *page = bvec->bv_page; - DEBUG(3, "Cleaning up page %ld\n", page->index); - if (--bvec >= bio->bi_io_vec) - prefetchw(&bvec->bv_page->flags); - - if (uptodate) { - SetPageUptodate(page); - } else { - ClearPageUptodate(page); - SetPageError(page); - } - clear_page_dirty(page); - unlock_page(page); - page_cache_release(page); - } while (bvec >= bio->bi_io_vec); - - complete((struct completion*)bio->bi_private); - return 0; -} - - -/* read one page from the block device */ -static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page) -{ - struct bio *bio; - struct completion event; - int err = -ENOMEM; - - if(PageUptodate(page)) { - DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index); - unlock_page(page); - return 0; - } - - ClearPageUptodate(page); - ClearPageError(page); - - bio = bio_alloc(GFP_KERNEL, 1); - if(bio) { - init_completion(&event); - bio->bi_bdev = dev->blkdev; - bio->bi_sector = page->index << (PAGE_SHIFT-9); - bio->bi_private = &event; - bio->bi_end_io = bi_read_complete; - if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) { - submit_bio(READ_SYNC, bio); - wait_for_completion(&event); - err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; - bio_put(bio); - } - } - - if(err) - SetPageError(page); - else - SetPageUptodate(page); - flush_dcache_page(page); - unlock_page(page); - return err; -} - - -/* write out the current BIO and wait for it to finish */ -static int blkmtd_write_out(struct bio *bio) -{ - struct completion event; - int err; - - if(!bio->bi_vcnt) { - bio_put(bio); - return 0; - } - - init_completion(&event); - bio->bi_private = &event; - bio->bi_end_io = bi_write_complete; - submit_bio(WRITE_SYNC, bio); - wait_for_completion(&event); - DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt); - err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; - bio_put(bio); - return err; -} - - -/** - * blkmtd_add_page - add a page to the current BIO - * @bio: bio to add to (NULL to alloc initial bio) - * @blkdev: block device - * @page: page to add - * @pagecnt: pages left to add - * - * Adds a page to the current bio, allocating it if necessary. If it cannot be - * added, the current bio is written out and a new one is allocated. Returns - * the new bio to add or NULL on error - */ -static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev, - struct page *page, int pagecnt) -{ - - retry: - if(!bio) { - bio = bio_alloc(GFP_KERNEL, pagecnt); - if(!bio) - return NULL; - bio->bi_sector = page->index << (PAGE_SHIFT-9); - bio->bi_bdev = blkdev; - } - - if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { - blkmtd_write_out(bio); - bio = NULL; - goto retry; - } - return bio; -} - - -/** - * write_pages - write block of data to device via the page cache - * @dev: device to write to - * @buf: data source or NULL if erase (output is set to 0xff) - * @to: offset into output device - * @len: amount to data to write - * @retlen: amount of data written - * - * Grab pages from the page cache and fill them with the source data. - * Non page aligned start and end result in a readin of the page and - * part of the page being modified. Pages are added to the bio and then written - * out. - */ -static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, - size_t len, size_t *retlen) -{ - int pagenr, offset; - size_t start_len = 0, end_len; - int pagecnt = 0; - int err = 0; - struct bio *bio = NULL; - size_t thislen = 0; - - pagenr = to >> PAGE_SHIFT; - offset = to & ~PAGE_MASK; - - DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %zd pagenr = %d offset = %d\n", - buf, (long)to, len, pagenr, offset); - - /* see if we have to do a partial write at the start */ - if(offset) { - start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len; - len -= start_len; - } - - /* calculate the length of the other two regions */ - end_len = len & ~PAGE_MASK; - len -= end_len; - - if(start_len) - pagecnt++; - - if(len) - pagecnt += len >> PAGE_SHIFT; - - if(end_len) - pagecnt++; - - down(&dev->wrbuf_mutex); - - DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", - start_len, len, end_len, pagecnt); - - if(start_len) { - /* do partial start region */ - struct page *page; - - DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %zd offset = %d\n", - pagenr, start_len, offset); - - BUG_ON(!buf); - page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); - lock_page(page); - if(PageDirty(page)) { - err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", - to, start_len, len, end_len, pagenr); - BUG(); - } - memcpy(page_address(page)+offset, buf, start_len); - set_page_dirty(page); - SetPageUptodate(page); - buf += start_len; - thislen = start_len; - bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); - if(!bio) { - err = -ENOMEM; - err("bio_add_page failed\n"); - goto write_err; - } - pagecnt--; - pagenr++; - } - - /* Now do the main loop to a page aligned, n page sized output */ - if(len) { - int pagesc = len >> PAGE_SHIFT; - DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n", - pagenr, pagesc); - while(pagesc) { - struct page *page; - - /* see if page is in the page cache */ - DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr); - page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr); - if(PageDirty(page)) { - BUG(); - } - if(!page) { - warn("write: cannot grab cache page %d", pagenr); - err = -ENOMEM; - goto write_err; - } - if(!buf) { - memset(page_address(page), 0xff, PAGE_SIZE); - } else { - memcpy(page_address(page), buf, PAGE_SIZE); - buf += PAGE_SIZE; - } - bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); - if(!bio) { - err = -ENOMEM; - err("bio_add_page failed\n"); - goto write_err; - } - pagenr++; - pagecnt--; - set_page_dirty(page); - SetPageUptodate(page); - pagesc--; - thislen += PAGE_SIZE; - } - } - - if(end_len) { - /* do the third region */ - struct page *page; - DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %zd\n", - pagenr, end_len); - BUG_ON(!buf); - page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); - lock_page(page); - if(PageDirty(page)) { - err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", - to, start_len, len, end_len, pagenr); - BUG(); - } - memcpy(page_address(page), buf, end_len); - set_page_dirty(page); - SetPageUptodate(page); - DEBUG(3, "blkmtd: write: writing out partial end\n"); - thislen += end_len; - bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); - if(!bio) { - err = -ENOMEM; - err("bio_add_page failed\n"); - goto write_err; - } - pagenr++; - } - - DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt); - write_err: - if(bio) - blkmtd_write_out(bio); - - DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); - up(&dev->wrbuf_mutex); - - if(retlen) - *retlen = thislen; - return err; -} - - -/* erase a specified part of the device */ -static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr) -{ - struct blkmtd_dev *dev = mtd->priv; - struct mtd_erase_region_info *einfo = mtd->eraseregions; - int numregions = mtd->numeraseregions; - size_t from; - u_long len; - int err = -EIO; - size_t retlen; - - instr->state = MTD_ERASING; - from = instr->addr; - len = instr->len; - - /* check erase region has valid start and length */ - DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%zx len = 0x%lx\n", - mtd->name+9, from, len); - while(numregions) { - DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n", - einfo->offset, einfo->erasesize, einfo->numblocks); - if(from >= einfo->offset - && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) { - if(len == einfo->erasesize - && ( (from - einfo->offset) % einfo->erasesize == 0)) - break; - } - numregions--; - einfo++; - } - - if(!numregions) { - /* Not a valid erase block */ - err("erase: invalid erase request 0x%lX @ 0x%08zX", len, from); - instr->state = MTD_ERASE_FAILED; - err = -EIO; - } - - if(instr->state != MTD_ERASE_FAILED) { - /* do the erase */ - DEBUG(3, "Doing erase from = %zd len = %ld\n", from, len); - err = write_pages(dev, NULL, from, len, &retlen); - if(err || retlen != len) { - err("erase failed err = %d", err); - instr->state = MTD_ERASE_FAILED; - } else { - instr->state = MTD_ERASE_DONE; - } - } - - DEBUG(3, "blkmtd: erase: checking callback\n"); - mtd_erase_callback(instr); - DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err); - return err; -} - - -/* read a range of the data via the page cache */ -static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) -{ - struct blkmtd_dev *dev = mtd->priv; - int err = 0; - int offset; - int pagenr, pages; - size_t thislen = 0; - - DEBUG(2, "blkmtd: read: dev = `%s' from = %lld len = %zd buf = %p\n", - mtd->name+9, from, len, buf); - - if(from > mtd->size) - return -EINVAL; - if(from + len > mtd->size) - len = mtd->size - from; - - pagenr = from >> PAGE_SHIFT; - offset = from - (pagenr << PAGE_SHIFT); - - pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT; - DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n", - pagenr, offset, pages); - - while(pages) { - struct page *page; - int cpylen; - - DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr); - page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); - if(IS_ERR(page)) { - err = -EIO; - goto readerr; - } - - cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE; - if(offset+cpylen > PAGE_SIZE) - cpylen = PAGE_SIZE-offset; - - memcpy(buf + thislen, page_address(page) + offset, cpylen); - offset = 0; - len -= cpylen; - thislen += cpylen; - pagenr++; - pages--; - if(!PageDirty(page)) - page_cache_release(page); - } - - readerr: - if(retlen) - *retlen = thislen; - DEBUG(2, "blkmtd: end read: retlen = %zd, err = %d\n", thislen, err); - return err; -} - - -/* write data to the underlying device */ -static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) -{ - struct blkmtd_dev *dev = mtd->priv; - int err; - - if(!len) - return 0; - - DEBUG(2, "blkmtd: write: dev = `%s' to = %lld len = %zd buf = %p\n", - mtd->name+9, to, len, buf); - - if(to >= mtd->size) { - return -ENOSPC; - } - - if(to + len > mtd->size) { - len = mtd->size - to; - } - - err = write_pages(dev, buf, to, len, retlen); - if(err > 0) - err = 0; - DEBUG(2, "blkmtd: write: end, err = %d\n", err); - return err; -} - - -/* sync the device - wait until the write queue is empty */ -static void blkmtd_sync(struct mtd_info *mtd) -{ - /* Currently all writes are synchronous */ -} - - -static void free_device(struct blkmtd_dev *dev) -{ - DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); - if(dev) { - kfree(dev->mtd_info.eraseregions); - kfree(dev->mtd_info.name); - if(dev->blkdev) { - invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); - close_bdev_excl(dev->blkdev); - } - kfree(dev); - } -} - - -/* For a given size and initial erase size, calculate the number - * and size of each erase region. Goes round the loop twice, - * once to find out how many regions, then allocates space, - * then round the loop again to fill it in. - */ -static struct mtd_erase_region_info *calc_erase_regions( - size_t erase_size, size_t total_size, int *regions) -{ - struct mtd_erase_region_info *info = NULL; - - DEBUG(2, "calc_erase_regions, es = %zd size = %zd regions = %d\n", - erase_size, total_size, *regions); - /* Make any user specified erasesize be a power of 2 - and at least PAGE_SIZE */ - if(erase_size) { - int es = erase_size; - erase_size = 1; - while(es != 1) { - es >>= 1; - erase_size <<= 1; - } - if(erase_size < PAGE_SIZE) - erase_size = PAGE_SIZE; - } else { - erase_size = CONFIG_MTD_BLKDEV_ERASESIZE; - } - - *regions = 0; - - do { - int tot_size = total_size; - int er_size = erase_size; - int count = 0, offset = 0, regcnt = 0; - - while(tot_size) { - count = tot_size / er_size; - if(count) { - tot_size = tot_size % er_size; - if(info) { - DEBUG(2, "adding to erase info off=%d er=%d cnt=%d\n", - offset, er_size, count); - (info+regcnt)->offset = offset; - (info+regcnt)->erasesize = er_size; - (info+regcnt)->numblocks = count; - (*regions)++; - } - regcnt++; - offset += (count * er_size); - } - while(er_size > tot_size) - er_size >>= 1; - } - if(info == NULL) { - info = kmalloc(regcnt * sizeof(struct mtd_erase_region_info), GFP_KERNEL); - if(!info) - break; - } - } while(!(*regions)); - DEBUG(2, "calc_erase_regions done, es = %zd size = %zd regions = %d\n", - erase_size, total_size, *regions); - return info; -} - - -extern dev_t __init name_to_dev_t(const char *line); - -static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) -{ - struct block_device *bdev; - int mode; - struct blkmtd_dev *dev; - - if(!devname) - return NULL; - - /* Get a handle on the device */ - - -#ifdef MODULE - mode = (readonly) ? O_RDONLY : O_RDWR; - bdev = open_bdev_excl(devname, mode, NULL); -#else - mode = (readonly) ? FMODE_READ : FMODE_WRITE; - bdev = open_by_devnum(name_to_dev_t(devname), mode); -#endif - if(IS_ERR(bdev)) { - err("error: cannot open device %s", devname); - DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev)); - return NULL; - } - - DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n", - MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); - - if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { - err("attempting to use an MTD device as a block device"); - blkdev_put(bdev); - return NULL; - } - - dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL); - if(dev == NULL) { - blkdev_put(bdev); - return NULL; - } - - memset(dev, 0, sizeof(struct blkmtd_dev)); - dev->blkdev = bdev; - if(!readonly) { - init_MUTEX(&dev->wrbuf_mutex); - } - - dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; - - /* Setup the MTD structure */ - /* make the name contain the block device in */ - dev->mtd_info.name = kmalloc(sizeof("blkmtd: ") + strlen(devname), GFP_KERNEL); - if(dev->mtd_info.name == NULL) - goto devinit_err; - - sprintf(dev->mtd_info.name, "blkmtd: %s", devname); - dev->mtd_info.eraseregions = calc_erase_regions(erase_size, dev->mtd_info.size, - &dev->mtd_info.numeraseregions); - if(dev->mtd_info.eraseregions == NULL) - goto devinit_err; - - dev->mtd_info.erasesize = dev->mtd_info.eraseregions->erasesize; - DEBUG(1, "blkmtd: init: found %d erase regions\n", - dev->mtd_info.numeraseregions); - - if(readonly) { - dev->mtd_info.type = MTD_ROM; - dev->mtd_info.flags = MTD_CAP_ROM; - } else { - dev->mtd_info.type = MTD_RAM; - dev->mtd_info.flags = MTD_CAP_RAM; - dev->mtd_info.erase = blkmtd_erase; - dev->mtd_info.write = blkmtd_write; - dev->mtd_info.writev = default_mtd_writev; - dev->mtd_info.sync = blkmtd_sync; - } - dev->mtd_info.read = blkmtd_read; - dev->mtd_info.readv = default_mtd_readv; - dev->mtd_info.priv = dev; - dev->mtd_info.owner = THIS_MODULE; - - list_add(&dev->list, &blkmtd_device_list); - if (add_mtd_device(&dev->mtd_info)) { - /* Device didnt get added, so free the entry */ - list_del(&dev->list); - goto devinit_err; - } else { - info("mtd%d: [%s] erase_size = %dKiB %s", - dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "), - dev->mtd_info.erasesize >> 10, - readonly ? "(read-only)" : ""); - } - - return dev; - - devinit_err: - free_device(dev); - return NULL; -} - - -/* Cleanup and exit - sync the device and kill of the kernel thread */ -static void __devexit cleanup_blkmtd(void) -{ - struct list_head *temp1, *temp2; - - /* Remove the MTD devices */ - list_for_each_safe(temp1, temp2, &blkmtd_device_list) { - struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev, - list); - blkmtd_sync(&dev->mtd_info); - del_mtd_device(&dev->mtd_info); - info("mtd%d: [%s] removed", dev->mtd_info.index, - dev->mtd_info.name + strlen("blkmtd: ")); - list_del(&dev->list); - free_device(dev); - } -} - -#ifndef MODULE - -/* Handle kernel boot params */ - - -static int __init param_blkmtd_device(char *str) -{ - int i; - - for(i = 0; i < MAX_DEVICES; i++) { - device[i] = str; - DEBUG(2, "blkmtd: device setup: %d = %s\n", i, device[i]); - strsep(&str, ","); - } - return 1; -} - - -static int __init param_blkmtd_erasesz(char *str) -{ - int i; - for(i = 0; i < MAX_DEVICES; i++) { - char *val = strsep(&str, ","); - if(val) - erasesz[i] = simple_strtoul(val, NULL, 0); - DEBUG(2, "blkmtd: erasesz setup: %d = %d\n", i, erasesz[i]); - } - - return 1; -} - - -static int __init param_blkmtd_ro(char *str) -{ - int i; - for(i = 0; i < MAX_DEVICES; i++) { - char *val = strsep(&str, ","); - if(val) - ro[i] = simple_strtoul(val, NULL, 0); - DEBUG(2, "blkmtd: ro setup: %d = %d\n", i, ro[i]); - } - - return 1; -} - - -static int __init param_blkmtd_sync(char *str) -{ - if(str[0] == '1') - sync = 1; - return 1; -} - -__setup("blkmtd_device=", param_blkmtd_device); -__setup("blkmtd_erasesz=", param_blkmtd_erasesz); -__setup("blkmtd_ro=", param_blkmtd_ro); -__setup("blkmtd_sync=", param_blkmtd_sync); - -#endif - - -/* Startup */ -static int __init init_blkmtd(void) -{ - int i; - - info("version " VERSION); - /* Check args - device[0] is the bare minimum*/ - if(!device[0]) { - err("error: missing `device' name\n"); - return -EINVAL; - } - - for(i = 0; i < MAX_DEVICES; i++) - add_device(device[i], ro[i], erasesz[i] << 10); - - if(list_empty(&blkmtd_device_list)) - return -EINVAL; - - return 0; -} - -module_init(init_blkmtd); -module_exit(cleanup_blkmtd); diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 7ff403b2a0a0..4160b8334c53 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/mtd/mtd.h> #include <linux/buffer_head.h> +#include <linux/mutex.h> #define VERSION "$Revision: 1.30 $" @@ -31,7 +32,7 @@ struct block2mtd_dev { struct list_head list; struct block_device *blkdev; struct mtd_info mtd; - struct semaphore write_mutex; + struct mutex write_mutex; }; @@ -134,9 +135,9 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr) int err; instr->state = MTD_ERASING; - down(&dev->write_mutex); + mutex_lock(&dev->write_mutex); err = _block2mtd_erase(dev, from, len); - up(&dev->write_mutex); + mutex_unlock(&dev->write_mutex); if (err) { ERROR("erase failed err = %d", err); instr->state = MTD_ERASE_FAILED; @@ -249,9 +250,9 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (to + len > mtd->size) len = mtd->size - to; - down(&dev->write_mutex); + mutex_lock(&dev->write_mutex); err = _block2mtd_write(dev, buf, to, len, retlen); - up(&dev->write_mutex); + mutex_unlock(&dev->write_mutex); if (err > 0) err = 0; return err; @@ -310,7 +311,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) goto devinit_err; } - init_MUTEX(&dev->write_mutex); + mutex_init(&dev->write_mutex); /* Setup the MTD structure */ /* make the name contain the block device in */ diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index e4345cf744a2..23e7a5c7d2c1 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -20,6 +20,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/bitops.h> +#include <linux/mutex.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> @@ -605,7 +606,7 @@ static void DoC2k_init(struct mtd_info *mtd) this->curfloor = -1; this->curchip = -1; - init_MUTEX(&this->lock); + mutex_init(&this->lock); /* Ident all the chips present. */ DoC_ScanChips(this, maxchips); @@ -645,7 +646,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, if (from >= this->totlen) return -EINVAL; - down(&this->lock); + mutex_lock(&this->lock); *retlen = 0; while (left) { @@ -774,7 +775,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, buf += len; } - up(&this->lock); + mutex_unlock(&this->lock); return ret; } @@ -803,7 +804,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, if (to >= this->totlen) return -EINVAL; - down(&this->lock); + mutex_lock(&this->lock); *retlen = 0; while (left) { @@ -873,7 +874,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - up(&this->lock); + mutex_unlock(&this->lock); return -EIO; } @@ -935,7 +936,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - up(&this->lock); + mutex_unlock(&this->lock); return -EIO; } @@ -956,7 +957,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); if (ret) { - up(&this->lock); + mutex_unlock(&this->lock); return ret; } } @@ -966,7 +967,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, buf += len; } - up(&this->lock); + mutex_unlock(&this->lock); return 0; } @@ -975,13 +976,13 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, u_char *eccbuf, struct nand_oobinfo *oobsel) { static char static_buf[512]; - static DECLARE_MUTEX(writev_buf_sem); + static DEFINE_MUTEX(writev_buf_mutex); size_t totretlen = 0; size_t thisvecofs = 0; int ret= 0; - down(&writev_buf_sem); + mutex_lock(&writev_buf_mutex); while(count) { size_t thislen, thisretlen; @@ -1024,7 +1025,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, to += thislen; } - up(&writev_buf_sem); + mutex_unlock(&writev_buf_mutex); *retlen = totretlen; return ret; } @@ -1037,7 +1038,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, int len256 = 0, ret; struct Nand *mychip; - down(&this->lock); + mutex_lock(&this->lock); mychip = &this->chips[ofs >> this->chipshift]; @@ -1083,7 +1084,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ret = DoC_WaitReady(this); - up(&this->lock); + mutex_unlock(&this->lock); return ret; } @@ -1197,10 +1198,10 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, struct DiskOnChip *this = mtd->priv; int ret; - down(&this->lock); + mutex_lock(&this->lock); ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf); - up(&this->lock); + mutex_unlock(&this->lock); return ret; } @@ -1214,10 +1215,10 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) struct Nand *mychip; int status; - down(&this->lock); + mutex_lock(&this->lock); if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) { - up(&this->lock); + mutex_unlock(&this->lock); return -EINVAL; } @@ -1265,7 +1266,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) callback: mtd_erase_callback(instr); - up(&this->lock); + mutex_unlock(&this->lock); return 0; } diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 1e876fcb0408..29b0ddaa324e 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -581,8 +581,6 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen /***************************************************************************************************/ -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) - static struct mtd_info mtd; static struct mtd_erase_region_info erase_regions[] = { @@ -640,7 +638,7 @@ int __init lart_flash_init (void) mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; - mtd.numeraseregions = NB_OF (erase_regions); + mtd.numeraseregions = ARRAY_SIZE(erase_regions); mtd.eraseregions = erase_regions; mtd.erase = flash_erase; mtd.read = flash_read; @@ -670,9 +668,9 @@ int __init lart_flash_init (void) result,mtd.eraseregions[result].numblocks); #ifdef HAVE_PARTITIONS - printk ("\npartitions = %d\n",NB_OF (lart_partitions)); + printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); - for (result = 0; result < NB_OF (lart_partitions); result++) + for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) printk (KERN_DEBUG "\n\n" "lart_partitions[%d].name = %s\n" @@ -687,7 +685,7 @@ int __init lart_flash_init (void) #ifndef HAVE_PARTITIONS result = add_mtd_device (&mtd); #else - result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions)); + result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions)); #endif return (result); diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index d5f24089be71..04e65d5dae00 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -186,7 +186,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) struct m25p *flash = mtd_to_m25p(mtd); u32 addr,len; - DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", + DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n", flash->spi->dev.bus_id, __FUNCTION__, "at", (u32)instr->addr, instr->len); diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 0ff2e4378244..485f663493d2 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c @@ -308,7 +308,7 @@ static int __init ms02nv_init(void) break; } - for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++) + for (i = 0; i < ARRAY_SIZE(ms02nv_addrs); i++) if (!ms02nv_init_one(ms02nv_addrs[i] << stride)) count++; diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index 8a544890173d..a3b92479719d 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c @@ -47,9 +47,6 @@ */ #define MAX_LOOPS 10000 -extern void INFTL_dumptables(struct INFTLrecord *inftl); -extern void INFTL_dumpVUchains(struct INFTLrecord *inftl); - static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { struct INFTLrecord *inftl; @@ -132,7 +129,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) return; } #ifdef PSYCHO_DEBUG - printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); + printk(KERN_INFO "INFTL: Found new inftl%c\n", inftl->mbd.devnum + 'a'); #endif return; } @@ -885,8 +882,6 @@ static struct mtd_blktrans_ops inftl_tr = { .owner = THIS_MODULE, }; -extern char inftlmountrev[]; - static int __init init_inftl(void) { printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c index a57791a6ce40..b933a2a27b18 100644 --- a/drivers/mtd/maps/alchemy-flash.c +++ b/drivers/mtd/maps/alchemy-flash.c @@ -126,8 +126,6 @@ static struct mtd_partition alchemy_partitions[] = { } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - static struct mtd_info *mymtd; int __init alchemy_mtd_init(void) @@ -154,7 +152,7 @@ int __init alchemy_mtd_init(void) * Static partition definition selection */ parts = alchemy_partitions; - nb_parts = NB_OF(alchemy_partitions); + nb_parts = ARRAY_SIZE(alchemy_partitions); alchemy_map.size = window_size; /* diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c index 6a8c0415bde8..fd0f0d3187de 100644 --- a/drivers/mtd/maps/cfi_flagadm.c +++ b/drivers/mtd/maps/cfi_flagadm.c @@ -86,7 +86,7 @@ struct mtd_partition flagadm_parts[] = { } }; -#define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition)) +#define PARTITION_COUNT ARRAY_SIZE(flagadm_parts) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c index 49d90542fc75..652813cd6c2d 100644 --- a/drivers/mtd/maps/dbox2-flash.c +++ b/drivers/mtd/maps/dbox2-flash.c @@ -57,7 +57,7 @@ static struct mtd_partition partition_info[]= { } }; -#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) #define WINDOW_ADDR 0x10000000 #define WINDOW_SIZE 0x800000 diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c index efb221692641..c299d10b33e6 100644 --- a/drivers/mtd/maps/dilnetpc.c +++ b/drivers/mtd/maps/dilnetpc.c @@ -300,7 +300,7 @@ static struct mtd_partition partition_info[]= }, }; -#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) static struct mtd_info *mymtd; static struct mtd_info *lowlvl_parts[NUM_PARTITIONS]; @@ -345,7 +345,7 @@ static struct mtd_partition higlvl_partition_info[]= }, }; -#define NUM_HIGHLVL_PARTITIONS (sizeof(higlvl_partition_info)/sizeof(partition_info[0])) +#define NUM_HIGHLVL_PARTITIONS ARRAY_SIZE(higlvl_partition_info) static int dnp_adnp_probe(void) diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c index b993ac01a9a5..2bb3c0f0f970 100644 --- a/drivers/mtd/maps/dmv182.c +++ b/drivers/mtd/maps/dmv182.c @@ -99,7 +99,7 @@ static struct mtd_info *this_mtd; static int __init init_svme182(void) { struct mtd_partition *partitions; - int num_parts = sizeof(svme182_partitions) / sizeof(struct mtd_partition); + int num_parts = ARRAY_SIZE(svme182_partitions); partitions = svme182_partitions; diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 319094821101..0667101ccbe1 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c @@ -59,7 +59,7 @@ static struct mtd_partition h720x_partitions[] = { } }; -#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0])) +#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions) static int nr_mtd_parts; static struct mtd_partition *mtd_parts; diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c index 33060a315722..ed215470158b 100644 --- a/drivers/mtd/maps/netsc520.c +++ b/drivers/mtd/maps/netsc520.c @@ -76,7 +76,7 @@ static struct mtd_partition partition_info[]={ .size = 0x80000 }, }; -#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) #define WINDOW_SIZE 0x00100000 #define WINDOW_ADDR 0x00200000 @@ -88,7 +88,7 @@ static struct map_info netsc520_map = { .phys = WINDOW_ADDR, }; -#define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) +#define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c index 632eb2aa968f..54a3102ab19a 100644 --- a/drivers/mtd/maps/nettel.c +++ b/drivers/mtd/maps/nettel.c @@ -128,8 +128,7 @@ static struct mtd_partition nettel_amd_partitions[] = { } }; -#define NUM_AMD_PARTITIONS \ - (sizeof(nettel_amd_partitions)/sizeof(nettel_amd_partitions[0])) +#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions) /****************************************************************************/ diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c index c223514ca2eb..a21fcd195ab4 100644 --- a/drivers/mtd/maps/ocotea.c +++ b/drivers/mtd/maps/ocotea.c @@ -58,8 +58,6 @@ static struct mtd_partition ocotea_large_partitions[] = { } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - int __init init_ocotea(void) { u8 fpga0_reg; @@ -97,7 +95,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_small_partitions, - NB_OF(ocotea_small_partitions)); + ARRAY_SIZE(ocotea_small_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; @@ -118,7 +116,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_large_partitions, - NB_OF(ocotea_large_partitions)); + ARRAY_SIZE(ocotea_large_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index 21822c2edbe4..d2ab1bae9c34 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c @@ -334,9 +334,6 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; release: - if (mtd) - map_destroy(mtd); - if (map) { map->exit(dev, map); kfree(map); diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index f988c817e196..d27f4129afd3 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -54,7 +54,7 @@ static const int debug = 0; #define MAX_PCMCIA_ADDR 0x4000000 struct pcmciamtd_dev { - dev_link_t link; /* PCMCIA link */ + struct pcmcia_device *p_dev; dev_node_t node; /* device node */ caddr_t win_base; /* ioremapped address of PCMCIA window */ unsigned int win_size; /* size of window */ @@ -111,8 +111,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) memreq_t mrq; int ret; - if(!(dev->link.state & DEV_PRESENT)) { - DEBUG(1, "device removed state = 0x%4.4X", dev->link.state); + if (!pcmcia_dev_present(dev->p_dev)) { + DEBUG(1, "device removed"); return 0; } @@ -122,7 +122,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) dev->offset, mrq.CardOffset); mrq.Page = 0; if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { - cs_error(dev->link.handle, MapMemPage, ret); + cs_error(dev->p_dev, MapMemPage, ret); return NULL; } dev->offset = mrq.CardOffset; @@ -238,7 +238,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v /* read/write{8,16} copy_{from,to} routines with direct access */ -#define DEV_REMOVED(x) (!(*(u_int *)x->map_priv_1 & DEV_PRESENT)) +#define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev))) static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) { @@ -319,7 +319,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f static void pcmciamtd_set_vpp(struct map_info *map, int on) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; - dev_link_t *link = &dev->link; + struct pcmcia_device *link = dev->p_dev; modconf_t mod; int ret; @@ -328,9 +328,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0; DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); - ret = pcmcia_modify_configuration(link->handle, &mod); + ret = pcmcia_modify_configuration(link, &mod); if(ret != CS_SUCCESS) { - cs_error(link->handle, ModifyConfiguration, ret); + cs_error(link, ModifyConfiguration, ret); } } @@ -340,7 +340,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) * still open, this will be postponed until it is closed. */ -static void pcmciamtd_release(dev_link_t *link) +static void pcmciamtd_release(struct pcmcia_device *link) { struct pcmciamtd_dev *dev = link->priv; @@ -353,12 +353,11 @@ static void pcmciamtd_release(dev_link_t *link) } pcmcia_release_window(link->win); } - pcmcia_release_configuration(link->handle); - link->state &= ~DEV_CONFIG; + pcmcia_disable_device(link); } -static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_name) +static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) { int rc; tuple_t tuple; @@ -371,16 +370,16 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_ tuple.TupleOffset = 0; tuple.DesiredTuple = RETURN_FIRST_TUPLE; - rc = pcmcia_get_first_tuple(link->handle, &tuple); + rc = pcmcia_get_first_tuple(link, &tuple); while(rc == CS_SUCCESS) { - rc = pcmcia_get_tuple_data(link->handle, &tuple); + rc = pcmcia_get_tuple_data(link, &tuple); if(rc != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, rc); + cs_error(link, GetTupleData, rc); break; } - rc = pcmcia_parse_tuple(link->handle, &tuple, &parse); + rc = pcmcia_parse_tuple(link, &tuple, &parse); if(rc != CS_SUCCESS) { - cs_error(link->handle, ParseTuple, rc); + cs_error(link, ParseTuple, rc); break; } @@ -451,7 +450,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_ DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); } - rc = pcmcia_get_next_tuple(link->handle, &tuple); + rc = pcmcia_get_next_tuple(link, &tuple); } if(!dev->pcmcia_map.size) dev->pcmcia_map.size = MAX_PCMCIA_ADDR; @@ -488,7 +487,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_ #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static void pcmciamtd_config(dev_link_t *link) +static int pcmciamtd_config(struct pcmcia_device *link) { struct pcmciamtd_dev *dev = link->priv; struct mtd_info *mtd = NULL; @@ -504,13 +503,10 @@ static void pcmciamtd_config(dev_link_t *link) DEBUG(3, "link=0x%p", link); - /* Configure card */ - link->state |= DEV_CONFIG; - DEBUG(2, "Validating CIS"); - ret = pcmcia_validate_cis(link->handle, &cisinfo); + ret = pcmcia_validate_cis(link, &cisinfo); if(ret != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, ret); + cs_error(link, GetTupleData, ret); } else { DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains); } @@ -538,7 +534,7 @@ static void pcmciamtd_config(dev_link_t *link) req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; req.Base = 0; req.AccessSpeed = mem_speed; - link->win = (window_handle_t)link->handle; + link->win = (window_handle_t)link; req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR; dev->win_size = 0; @@ -546,7 +542,7 @@ static void pcmciamtd_config(dev_link_t *link) int ret; DEBUG(2, "requesting window with size = %dKiB memspeed = %d", req.Size >> 10, req.AccessSpeed); - ret = pcmcia_request_window(&link->handle, &req, &link->win); + ret = pcmcia_request_window(&link, &req, &link->win); DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); if(ret) { req.Size >>= 1; @@ -562,19 +558,19 @@ static void pcmciamtd_config(dev_link_t *link) if(!dev->win_size) { err("Cant allocate memory window"); pcmciamtd_release(link); - return; + return -ENODEV; } DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); + CS_CHECK(GetStatus, pcmcia_get_status(link, &status)); DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", status.CardState, (unsigned long)link->win); dev->win_base = ioremap(req.Base, req.Size); if(!dev->win_base) { err("ioremap(%lu, %u) failed", req.Base, req.Size); pcmciamtd_release(link); - return; + return -ENODEV; } DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", dev, req.Base, dev->win_base, req.Size); @@ -584,17 +580,14 @@ static void pcmciamtd_config(dev_link_t *link) dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; DEBUG(2, "Getting configuration"); - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t)); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t)); DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); dev->vpp = (vpp) ? vpp : t.Vpp1; link->conf.Attributes = 0; - link->conf.Vcc = t.Vcc; if(setvpp == 2) { - link->conf.Vpp1 = dev->vpp; - link->conf.Vpp2 = dev->vpp; + link->conf.Vpp = dev->vpp; } else { - link->conf.Vpp1 = 0; - link->conf.Vpp2 = 0; + link->conf.Vpp = 0; } link->conf.IntType = INT_MEMORY; @@ -606,9 +599,10 @@ static void pcmciamtd_config(dev_link_t *link) link->conf.ConfigIndex = 0; link->conf.Present = t.Present; DEBUG(2, "Setting Configuration"); - ret = pcmcia_request_configuration(link->handle, &link->conf); + ret = pcmcia_request_configuration(link, &link->conf); if(ret != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, ret); + cs_error(link, RequestConfiguration, ret); + return -ENODEV; } if(mem_type == 1) { @@ -616,7 +610,7 @@ static void pcmciamtd_config(dev_link_t *link) } else if(mem_type == 2) { mtd = do_map_probe("map_rom", &dev->pcmcia_map); } else { - for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { + for(i = 0; i < ARRAY_SIZE(probes); i++) { DEBUG(1, "Trying %s", probes[i]); mtd = do_map_probe(probes[i], &dev->pcmcia_map); if(mtd) @@ -629,7 +623,7 @@ static void pcmciamtd_config(dev_link_t *link) if(!mtd) { DEBUG(1, "Cant find an MTD"); pcmciamtd_release(link); - return; + return -ENODEV; } dev->mtd_info = mtd; @@ -654,7 +648,6 @@ static void pcmciamtd_config(dev_link_t *link) use the faster non-remapping read/write functions */ if(mtd->size <= dev->win_size) { DEBUG(1, "Using non remapping memory functions"); - dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state); dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base; if (dev->pcmcia_map.bankwidth == 1) { dev->pcmcia_map.read = pcmcia_read8; @@ -672,19 +665,18 @@ static void pcmciamtd_config(dev_link_t *link) dev->mtd_info = NULL; err("Couldnt register MTD device"); pcmciamtd_release(link); - return; + return -ENODEV; } snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); info("mtd%d: %s", mtd->index, mtd->name); - link->state &= ~DEV_CONFIG_PENDING; - link->dev = &dev->node; - return; + link->dev_node = &dev->node; + return 0; cs_failed: - cs_error(link->handle, last_fn, last_ret); + cs_error(link, last_fn, last_ret); err("CS Error, exiting"); pcmciamtd_release(link); - return; + return -ENODEV; } @@ -713,21 +705,18 @@ static int pcmciamtd_resume(struct pcmcia_device *dev) * when the device is released. */ -static void pcmciamtd_detach(struct pcmcia_device *p_dev) +static void pcmciamtd_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); + struct pcmciamtd_dev *dev = link->priv; DEBUG(3, "link=0x%p", link); - if(link->state & DEV_CONFIG) { - struct pcmciamtd_dev *dev = link->priv; - if(dev->mtd_info) { - del_mtd_device(dev->mtd_info); - info("mtd%d: Removed", dev->mtd_info->index); - } - - pcmciamtd_release(link); + if(dev->mtd_info) { + del_mtd_device(dev->mtd_info); + info("mtd%d: Removed", dev->mtd_info->index); } + + pcmciamtd_release(link); } @@ -736,10 +725,9 @@ static void pcmciamtd_detach(struct pcmcia_device *p_dev) * with Card Services. */ -static int pcmciamtd_attach(struct pcmcia_device *p_dev) +static int pcmciamtd_probe(struct pcmcia_device *link) { struct pcmciamtd_dev *dev; - dev_link_t *link; /* Create new memory card device */ dev = kmalloc(sizeof(*dev), GFP_KERNEL); @@ -747,20 +735,13 @@ static int pcmciamtd_attach(struct pcmcia_device *p_dev) DEBUG(1, "dev=0x%p", dev); memset(dev, 0, sizeof(*dev)); - link = &dev->link; + dev->p_dev = link; link->priv = dev; link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY; - link->next = NULL; - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - pcmciamtd_config(link); - - return 0; + return pcmciamtd_config(link); } static struct pcmcia_device_id pcmciamtd_ids[] = { @@ -794,7 +775,7 @@ static struct pcmcia_driver pcmciamtd_driver = { .drv = { .name = "pcmciamtd" }, - .probe = pcmciamtd_attach, + .probe = pcmciamtd_probe, .remove = pcmciamtd_detach, .owner = THIS_MODULE, .id_table = pcmciamtd_ids, diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c index 5b76ed886185..50b14033613f 100644 --- a/drivers/mtd/maps/redwood.c +++ b/drivers/mtd/maps/redwood.c @@ -121,8 +121,7 @@ struct map_info redwood_flash_map = { }; -#define NUM_REDWOOD_FLASH_PARTITIONS \ - (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0])) +#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions) static struct mtd_info *redwood_mtd; diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c index 225cdd9ba5b2..350286dc1d2e 100644 --- a/drivers/mtd/maps/sbc8240.c +++ b/drivers/mtd/maps/sbc8240.c @@ -66,7 +66,7 @@ static struct map_info sbc8240_map[2] = { } }; -#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info)) +#define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map) /* * The following defines the partition layout of SBC8240 boards. @@ -125,8 +125,6 @@ static struct mtd_partition sbc8240_fs_partitions [] = { } }; -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) - /* trivial struct to describe partition information */ struct mtd_part_def { @@ -190,10 +188,10 @@ int __init init_sbc8240_mtd (void) #ifdef CONFIG_MTD_PARTITIONS sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions; sbc8240_part_banks[0].type = "static image"; - sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions); + sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions); sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions; sbc8240_part_banks[1].type = "static file system"; - sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions); + sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions); for (i = 0; i < NUM_FLASH_BANKS; i++) { diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index ed92afadd8a9..e8c130e1efd3 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c @@ -107,7 +107,7 @@ static struct map_info sc520cdp_map[] = { }, }; -#define NUM_FLASH_BANKS (sizeof(sc520cdp_map)/sizeof(struct map_info)) +#define NUM_FLASH_BANKS ARRAY_SIZE(sc520cdp_map) static struct mtd_info *mymtd[NUM_FLASH_BANKS]; static struct mtd_info *merged_mtd; diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index 2c91dff8bb60..28b8a571a91a 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c @@ -70,7 +70,7 @@ static struct mtd_partition partition_info[] = { .size = 0x80000 }, }; -#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) +#define NUM_PARTITIONS ARRAY_SIZE(partition_info) #endif diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c index 999f4bb3d845..12fe53c0d2fc 100644 --- a/drivers/mtd/maps/sharpsl-flash.c +++ b/drivers/mtd/maps/sharpsl-flash.c @@ -49,8 +49,6 @@ static struct mtd_partition sharpsl_partitions[1] = { } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - int __init init_sharpsl(void) { struct mtd_partition *parts; @@ -92,7 +90,7 @@ int __init init_sharpsl(void) } parts = sharpsl_partitions; - nb_parts = NB_OF(sharpsl_partitions); + nb_parts = ARRAY_SIZE(sharpsl_partitions); printk(KERN_NOTICE "Using %s partision definition\n", part_type); add_mtd_partitions(mymtd, parts, nb_parts); diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c index 4b372bcb17f1..a7422c200567 100644 --- a/drivers/mtd/maps/ts5500_flash.c +++ b/drivers/mtd/maps/ts5500_flash.c @@ -64,7 +64,7 @@ static struct mtd_partition ts5500_partitions[] = { } }; -#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) +#define NUM_PARTITIONS ARRAY_SIZE(ts5500_partitions) static struct mtd_info *mymtd; diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index 79d92808b766..f7264dc2ac9b 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c @@ -37,7 +37,7 @@ struct mtd_partition uclinux_romfs[] = { { .name = "ROMfs" } }; -#define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) +#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs) /****************************************************************************/ diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c index e0063941c0df..b3e487395435 100644 --- a/drivers/mtd/maps/vmax301.c +++ b/drivers/mtd/maps/vmax301.c @@ -182,7 +182,7 @@ int __init init_vmax301(void) } } - if (!vmax_mtd[1] && !vmax_mtd[2]) { + if (!vmax_mtd[0] && !vmax_mtd[1]) { iounmap((void *)iomapadr); return -ENXIO; } diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 840dd66ce2dc..458d3c8ae1ee 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -19,12 +19,12 @@ #include <linux/spinlock.h> #include <linux/hdreg.h> #include <linux/init.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> #include <asm/uaccess.h> static LIST_HEAD(blktrans_majors); -extern struct semaphore mtd_table_mutex; +extern struct mutex mtd_table_mutex; extern struct mtd_info *mtd_table[]; struct mtd_blkcore_priv { @@ -122,9 +122,9 @@ static int mtd_blktrans_thread(void *arg) spin_unlock_irq(rq->queue_lock); - down(&dev->sem); + mutex_lock(&dev->lock); res = do_blktrans_request(tr, dev, req); - up(&dev->sem); + mutex_unlock(&dev->lock); spin_lock_irq(rq->queue_lock); @@ -235,8 +235,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int last_devnum = -1; struct gendisk *gd; - if (!down_trylock(&mtd_table_mutex)) { - up(&mtd_table_mutex); + if (!!mutex_trylock(&mtd_table_mutex)) { + mutex_unlock(&mtd_table_mutex); BUG(); } @@ -267,7 +267,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) return -EBUSY; } - init_MUTEX(&new->sem); + mutex_init(&new->lock); list_add_tail(&new->list, &tr->devs); added: if (!tr->writesect) @@ -313,8 +313,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) { - if (!down_trylock(&mtd_table_mutex)) { - up(&mtd_table_mutex); + if (!!mutex_trylock(&mtd_table_mutex)) { + mutex_unlock(&mtd_table_mutex); BUG(); } @@ -378,14 +378,14 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); ret = register_blkdev(tr->major, tr->name); if (ret) { printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", tr->name, tr->major, ret); kfree(tr->blkcore_priv); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } spin_lock_init(&tr->blkcore_priv->queue_lock); @@ -396,7 +396,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) if (!tr->blkcore_priv->rq) { unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return -ENOMEM; } @@ -407,7 +407,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } @@ -419,7 +419,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) tr->add_mtd(tr, mtd_table[i]); } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return 0; } @@ -428,7 +428,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) { struct list_head *this, *next; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); /* Clean up the kernel thread */ tr->blkcore_priv->exiting = 1; @@ -446,7 +446,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); kfree(tr->blkcore_priv); diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index e84756644fd1..2cef280e388c 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -19,11 +19,13 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/blktrans.h> +#include <linux/mutex.h> + static struct mtdblk_dev { struct mtd_info *mtd; int count; - struct semaphore cache_sem; + struct mutex cache_mutex; unsigned char *cache_data; unsigned long cache_offset; unsigned int cache_size; @@ -284,7 +286,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd) mtdblk->count = 1; mtdblk->mtd = mtd; - init_MUTEX (&mtdblk->cache_sem); + mutex_init(&mtdblk->cache_mutex); mtdblk->cache_state = STATE_EMPTY; if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && mtdblk->mtd->erasesize) { @@ -306,9 +308,9 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd) DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); - down(&mtdblk->cache_sem); + mutex_lock(&mtdblk->cache_mutex); write_cached_data(mtdblk); - up(&mtdblk->cache_sem); + mutex_unlock(&mtdblk->cache_mutex); if (!--mtdblk->count) { /* It was the last usage. Free the device */ @@ -327,9 +329,9 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev) { struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; - down(&mtdblk->cache_sem); + mutex_lock(&mtdblk->cache_mutex); write_cached_data(mtdblk); - up(&mtdblk->cache_sem); + mutex_unlock(&mtdblk->cache_mutex); if (mtdblk->mtd->sync) mtdblk->mtd->sync(mtdblk->mtd); diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index dade02ab0687..9905870f56e5 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -19,15 +19,13 @@ #include <linux/ioctl.h> #include <linux/init.h> #include <linux/mtd/compatmac.h> -#ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> -#endif #include <linux/mtd/mtd.h> /* These are exported solely for the purpose of mtd_blkdevs.c. You should not use them for _anything_ else */ -DECLARE_MUTEX(mtd_table_mutex); +DEFINE_MUTEX(mtd_table_mutex); struct mtd_info *mtd_table[MAX_MTD_DEVICES]; EXPORT_SYMBOL_GPL(mtd_table_mutex); @@ -49,7 +47,7 @@ int add_mtd_device(struct mtd_info *mtd) { int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); for (i=0; i < MAX_MTD_DEVICES; i++) if (!mtd_table[i]) { @@ -67,7 +65,7 @@ int add_mtd_device(struct mtd_info *mtd) not->add(mtd); } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); /* We _know_ we aren't being removed, because our caller is still holding us here. So none of this try_ nonsense, and no bitching about it @@ -76,7 +74,7 @@ int add_mtd_device(struct mtd_info *mtd) return 0; } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return 1; } @@ -94,7 +92,7 @@ int del_mtd_device (struct mtd_info *mtd) { int ret; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); if (mtd_table[mtd->index] != mtd) { ret = -ENODEV; @@ -118,7 +116,7 @@ int del_mtd_device (struct mtd_info *mtd) ret = 0; } - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } @@ -135,7 +133,7 @@ void register_mtd_user (struct mtd_notifier *new) { int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); list_add(&new->list, &mtd_notifiers); @@ -145,7 +143,7 @@ void register_mtd_user (struct mtd_notifier *new) if (mtd_table[i]) new->add(mtd_table[i]); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); } /** @@ -162,7 +160,7 @@ int unregister_mtd_user (struct mtd_notifier *old) { int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); module_put(THIS_MODULE); @@ -171,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old) old->remove(mtd_table[i]); list_del(&old->list); - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return 0; } @@ -193,7 +191,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) struct mtd_info *ret = NULL; int i; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); if (num == -1) { for (i=0; i< MAX_MTD_DEVICES; i++) @@ -211,7 +209,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) if (ret) ret->usecount++; - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); return ret; } @@ -219,9 +217,9 @@ void put_mtd_device(struct mtd_info *mtd) { int c; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); c = --mtd->usecount; - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); BUG_ON(c < 0); module_put(mtd->owner); @@ -296,10 +294,11 @@ EXPORT_SYMBOL(unregister_mtd_user); EXPORT_SYMBOL(default_mtd_writev); EXPORT_SYMBOL(default_mtd_readv); +#ifdef CONFIG_PROC_FS + /*====================================================================*/ /* Support for /proc/mtd */ -#ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_mtd; static inline int mtd_proc_info (char *buf, int i) @@ -319,7 +318,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, int len, l, i; off_t begin = 0; - down(&mtd_table_mutex); + mutex_lock(&mtd_table_mutex); len = sprintf(page, "dev: size erasesize name\n"); for (i=0; i< MAX_MTD_DEVICES; i++) { @@ -337,38 +336,34 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, *eof = 1; done: - up(&mtd_table_mutex); + mutex_unlock(&mtd_table_mutex); if (off >= len+begin) return 0; *start = page + (off-begin); return ((count < begin+len-off) ? count : begin+len-off); } -#endif /* CONFIG_PROC_FS */ - /*====================================================================*/ /* Init code */ static int __init init_mtd(void) { -#ifdef CONFIG_PROC_FS if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) proc_mtd->read_proc = mtd_read_proc; -#endif return 0; } static void __exit cleanup_mtd(void) { -#ifdef CONFIG_PROC_FS if (proc_mtd) remove_proc_entry( "mtd", NULL); -#endif } module_init(init_mtd); module_exit(cleanup_mtd); +#endif /* CONFIG_PROC_FS */ + MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 1fc4c134d939..cfe288a6e853 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -178,17 +178,16 @@ config MTD_NAND_DISKONCHIP_BBTWRITE Even if you leave this disabled, you can enable BBT writes at module load time (assuming you build diskonchip as a module) with the module parameter "inftl_bbt_write=1". - - config MTD_NAND_SHARPSL - bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" - depends on MTD_NAND && ARCH_PXA - - config MTD_NAND_NANDSIM - bool "Support for NAND Flash Simulator" - depends on MTD_NAND && MTD_PARTITIONS +config MTD_NAND_SHARPSL + tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" + depends on MTD_NAND && ARCH_PXA + +config MTD_NAND_NANDSIM + tristate "Support for NAND Flash Simulator" + depends on MTD_NAND && MTD_PARTITIONS help The simulator may simulate verious NAND flash chips for the MTD nand layer. - + endmenu diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 201e1362da14..bde3550910a2 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -55,8 +55,6 @@ static const struct mtd_partition partition_info[] = { .size = MTDPART_SIZ_FULL } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - /** * au_read_byte - read one byte from the chip @@ -462,7 +460,7 @@ int __init au1xxx_nand_init (void) } /* Register the partitions */ - add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info)); + add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info)); return 0; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5d222460b42a..95e96fa1fceb 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -80,6 +80,7 @@ #include <linux/mtd/compatmac.h> #include <linux/interrupt.h> #include <linux/bitops.h> +#include <linux/leds.h> #include <asm/io.h> #ifdef CONFIG_MTD_PARTITIONS @@ -515,6 +516,8 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i return nand_isbad_bbt (mtd, ofs, allowbbt); } +DEFINE_LED_TRIGGER(nand_led_trigger); + /* * Wait for the ready pin, after a command * The timeout is catched later. @@ -524,12 +527,14 @@ static void nand_wait_ready(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; unsigned long timeo = jiffies + 2; + led_trigger_event(nand_led_trigger, LED_FULL); /* wait until command is processed or timeout occures */ do { if (this->dev_ready(mtd)) - return; + break; touch_softlockup_watchdog(); } while (time_before(jiffies, timeo)); + led_trigger_event(nand_led_trigger, LED_OFF); } /** @@ -817,6 +822,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) else timeo += (HZ * 20) / 1000; + led_trigger_event(nand_led_trigger, LED_FULL); + /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ ndelay (100); @@ -840,6 +847,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) } cond_resched(); } + led_trigger_event(nand_led_trigger, LED_OFF); + status = (int) this->read_byte(mtd); return status; } @@ -2724,6 +2733,21 @@ void nand_release (struct mtd_info *mtd) EXPORT_SYMBOL_GPL (nand_scan); EXPORT_SYMBOL_GPL (nand_release); + +static int __init nand_base_init(void) +{ + led_trigger_register_simple("nand-disk", &nand_led_trigger); + return 0; +} + +static void __exit nand_base_exit(void) +{ + led_trigger_unregister_simple(nand_led_trigger); +} + +module_init(nand_base_init); +module_exit(nand_base_exit); + MODULE_LICENSE ("GPL"); MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); MODULE_DESCRIPTION ("Generic NAND flash driver code"); diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 8815c8dbef2d..c077d2ec9cdd 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -85,10 +85,6 @@ static int parse_redboot_partitions(struct mtd_info *master, numslots = (master->erasesize / sizeof(struct fis_image_desc)); for (i = 0; i < numslots; i++) { - if (buf[i].name[0] == 0xff) { - i = numslots; - break; - } if (!memcmp(buf[i].name, "FIS directory", 14)) { /* This is apparently the FIS directory entry for the * FIS directory itself. The FIS directory size is @@ -128,7 +124,7 @@ static int parse_redboot_partitions(struct mtd_info *master, struct fis_list *new_fl, **prev; if (buf[i].name[0] == 0xff) - break; + continue; if (!redboot_checksum(&buf[i])) break; |