/*
- * $Id: blkmtd-25.c,v 1.5 2003/07/16 06:48:27 spse Exp $
+ * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $
*
* blkmtd.c - use a block device as a fake MTD
*
/* 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.5 $"
+#define VERSION "$Revision: 1.27 $"
/* Info for the block device */
struct blkmtd_dev {
#define MAX_DEVICES 4
/* Module parameters passed by insmod/modprobe */
-char *device[MAX_DEVICES]; /* the block device to use */
-int erasesz[MAX_DEVICES]; /* optional default erase size */
-int ro[MAX_DEVICES]; /* optional read only flag */
-int sync;
+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_PARM(device, "1-4s");
+module_param_array(device, charp, NULL, 0);
MODULE_PARM_DESC(device, "block device to use");
-MODULE_PARM(erasesz, "1-4i");
+module_param_array(erasesz, int, NULL, 0);
MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB.");
-MODULE_PARM(ro, "1-4i");
+module_param_array(ro, bool, NULL, 0);
MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors");
-MODULE_PARM(sync, "i");
+module_param(sync, bool, 0);
MODULE_PARM_DESC(sync, "1=Synchronous writes");
ClearPageUptodate(page);
SetPageError(page);
}
- ClearPageDirty(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;
}
unlock_page(page);
return 0;
}
-
+
ClearPageUptodate(page);
ClearPageError(page);
pagenr = to >> PAGE_SHIFT;
offset = to & ~PAGE_MASK;
- DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %d pagenr = %d offset = %d\n",
+ 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 */
down(&dev->wrbuf_mutex);
- DEBUG(3, "blkmtd: write: start_len = %d len = %d end_len = %d pagecnt = %d\n",
+ 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 = %d offset = %d\n",
+ 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 = %d len = %d end_len = %d pagenr = %d\n",
+ 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);
- SetPageDirty(page);
+ set_page_dirty(page);
SetPageUptodate(page);
buf += start_len;
thislen = start_len;
}
pagenr++;
pagecnt--;
- SetPageDirty(page);
+ 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 = %d\n",
+ 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 = %d len = %d end_len = %d pagenr = %d\n",
+ 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);
- SetPageDirty(page);
+ set_page_dirty(page);
SetPageUptodate(page);
DEBUG(3, "blkmtd: write: writing out partial end\n");
thislen += end_len;
if(bio)
blkmtd_write_out(bio);
- DEBUG(2, "blkmtd: write: end, retlen = %d, err = %d\n", *retlen, err);
+ DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err);
up(&dev->wrbuf_mutex);
if(retlen)
size_t from;
u_long len;
int err = -EIO;
- int retlen;
+ 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%x len = 0x%lx\n",
+ 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",
if(!numregions) {
/* Not a valid erase block */
- err("erase: invalid erase request 0x%lX @ 0x%08X", len, from);
+ 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 = %d len = %ld\n", from, len);
+ 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);
}
DEBUG(3, "blkmtd: erase: checking callback\n");
- if (instr->callback) {
- (*(instr->callback))(instr);
- }
+ mtd_erase_callback(instr);
DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err);
return err;
}
int pagenr, pages;
size_t thislen = 0;
- DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %p\n",
- mtd->name+9, (long int)from, len, buf);
+ 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;
readerr:
if(retlen)
*retlen = thislen;
- DEBUG(2, "blkmtd: end read: retlen = %d, err = %d\n", thislen, err);
+ DEBUG(2, "blkmtd: end read: retlen = %zd, err = %d\n", thislen, err);
return err;
}
if(!len)
return 0;
- DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %p\n",
- mtd->name+9, (long int)to, len, buf);
+ 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;
{
DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
if(dev) {
- if(dev->mtd_info.eraseregions)
- kfree(dev->mtd_info.eraseregions);
- if(dev->mtd_info.name)
- kfree(dev->mtd_info.name);
-
+ 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);
{
struct mtd_erase_region_info *info = NULL;
- DEBUG(2, "calc_erase_regions, es = %d size = %d regions = %d\n",
+ 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 */
break;
}
} while(!(*regions));
- DEBUG(2, "calc_erase_regions done, es = %d size = %d regions = %d\n",
+ DEBUG(2, "calc_erase_regions done, es = %zd size = %zd regions = %d\n",
erase_size, total_size, *regions);
return info;
}
memset(dev, 0, sizeof(struct blkmtd_dev));
dev->blkdev = bdev;
- atomic_set(&(dev->blkdev->bd_inode->i_mapping->truncate_count), 0);
if(!readonly) {
init_MUTEX(&dev->wrbuf_mutex);
}
dev->mtd_info.erasesize >> 10,
readonly ? "(read-only)" : "");
}
-
+
return dev;
devinit_err: