patch-2.4.11-dontuse linux/drivers/mtd/mtdblock.c
Next file: linux/drivers/mtd/mtdblock_ro.c
Previous file: linux/drivers/mtd/maps/vmax301.c
Back to the patch index
Back to the overall index
- Lines: 211
- Date:
Thu Oct 4 15:14:59 2001
- Orig file:
v2.4.10/linux/drivers/mtd/mtdblock.c
- Orig date:
Sun Sep 23 11:40:58 2001
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
@@ -1,7 +1,7 @@
/*
* Direct MTD block device access
*
- * $Id: mtdblock.c,v 1.38 2000/11/27 08:50:22 dwmw2 Exp $
+ * $Id: mtdblock.c,v 1.47 2001/10/02 15:05:11 dwmw2 Exp $
*
* 02-nov-2000 Nicolas Pitre Added read-modify-write with cache
*/
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
+#include <linux/mtd/compatmac.h>
#define MAJOR_NR MTD_BLOCK_MAJOR
#define DEVICE_NAME "mtdblock"
@@ -158,13 +159,16 @@
int len, const char *buf)
{
struct mtd_info *mtd = mtdblk->mtd;
- unsigned int sect_size = mtd->erasesize;
+ unsigned int sect_size = mtdblk->cache_size;
size_t retlen;
int ret;
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
mtd->name, pos, len);
+ if (!sect_size)
+ return MTD_WRITE (mtd, pos, len, &retlen, buf);
+
while (len > 0) {
unsigned long sect_start = (pos/sect_size)*sect_size;
unsigned int offset = pos - sect_start;
@@ -224,13 +228,16 @@
int len, char *buf)
{
struct mtd_info *mtd = mtdblk->mtd;
- unsigned int sect_size = mtd->erasesize;
+ unsigned int sect_size = mtdblk->cache_size;
size_t retlen;
int ret;
DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
mtd->name, pos, len);
+ if (!sect_size)
+ return MTD_READ (mtd, pos, len, &retlen, buf);
+
while (len > 0) {
unsigned long sect_start = (pos/sect_size)*sect_size;
unsigned int offset = pos - sect_start;
@@ -268,6 +275,7 @@
static int mtdblock_open(struct inode *inode, struct file *file)
{
struct mtdblk_dev *mtdblk;
+ struct mtd_info *mtd;
int dev;
DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
@@ -278,6 +286,14 @@
dev = MINOR(inode->i_rdev);
if (dev >= MAX_MTD_DEVICES)
return -EINVAL;
+
+ mtd = get_mtd_device(NULL, dev);
+ if (!mtd)
+ return -ENODEV;
+ if (MTD_ABSENT == mtd->type) {
+ put_mtd_device(mtd);
+ return -ENODEV;
+ }
MOD_INC_USE_COUNT;
@@ -299,28 +315,26 @@
mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
if (!mtdblk) {
+ put_mtd_device(mtd);
MOD_DEC_USE_COUNT;
return -ENOMEM;
}
memset(mtdblk, 0, sizeof(*mtdblk));
mtdblk->count = 1;
- mtdblk->mtd = get_mtd_device(NULL, dev);
-
- if (!mtdblk->mtd) {
- kfree(mtdblk);
- MOD_DEC_USE_COUNT;
- return -ENODEV;
- }
+ mtdblk->mtd = mtd;
init_MUTEX (&mtdblk->cache_sem);
mtdblk->cache_state = STATE_EMPTY;
- mtdblk->cache_size = mtdblk->mtd->erasesize;
- mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
- if (!mtdblk->cache_data) {
- put_mtd_device(mtdblk->mtd);
- kfree(mtdblk);
- MOD_DEC_USE_COUNT;
- return -ENOMEM;
+ if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
+ mtdblk->mtd->erasesize) {
+ mtdblk->cache_size = mtdblk->mtd->erasesize;
+ mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
+ if (!mtdblk->cache_data) {
+ put_mtd_device(mtdblk->mtd);
+ kfree(mtdblk);
+ MOD_DEC_USE_COUNT;
+ return -ENOMEM;
+ }
}
/* OK, we've created a new one. Add it to the list. */
@@ -339,7 +353,8 @@
mtdblks[dev] = mtdblk;
mtd_sizes[dev] = mtdblk->mtd->size/1024;
- mtd_blksizes[dev] = mtdblk->mtd->erasesize;
+ if (mtdblk->mtd->erasesize)
+ mtd_blksizes[dev] = mtdblk->mtd->erasesize;
if (mtd_blksizes[dev] > PAGE_SIZE)
mtd_blksizes[dev] = PAGE_SIZE;
set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
@@ -359,7 +374,7 @@
if (inode == NULL)
release_return(-ENODEV);
-
+
invalidate_device(inode->i_rdev, 1);
dev = MINOR(inode->i_rdev);
@@ -454,13 +469,8 @@
}
static volatile int leaving = 0;
-#if LINUX_VERSION_CODE > 0x020300
static DECLARE_MUTEX_LOCKED(thread_sem);
static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
-#else
-static struct semaphore thread_sem = MUTEX_LOCKED;
-DECLARE_WAIT_QUEUE_HEAD(thr_wq);
-#endif
int mtdblock_thread(void *dummy)
{
@@ -578,7 +588,7 @@
{
char name[8];
- if (!mtd)
+ if (!mtd || mtd->type == MTD_ABSENT)
return;
sprintf(name, "%d", mtd->index);
@@ -590,18 +600,13 @@
static void mtd_notify_remove(struct mtd_info* mtd)
{
- if (!mtd)
+ if (!mtd || mtd->type == MTD_ABSENT)
return;
devfs_unregister(devfs_rw_handle[mtd->index]);
}
#endif
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_mtdblock init_module
-#define cleanup_mtdblock cleanup_module
-#endif
-
int __init init_mtdblock(void)
{
int i;
@@ -635,11 +640,7 @@
blksize_size[MAJOR_NR] = mtd_blksizes;
blk_size[MAJOR_NR] = mtd_sizes;
-#if LINUX_VERSION_CODE < 0x20320
- blk_dev[MAJOR_NR].request_fn = mtdblock_request;
-#else
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
-#endif
kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
return 0;
}
@@ -656,14 +657,15 @@
#else
unregister_blkdev(MAJOR_NR,DEVICE_NAME);
#endif
-#if LINUX_VERSION_CODE < 0x20320
- blk_dev[MAJOR_NR].request_fn = NULL;
-#else
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-#endif
blksize_size[MAJOR_NR] = NULL;
blk_size[MAJOR_NR] = NULL;
}
module_init(init_mtdblock);
module_exit(cleanup_mtdblock);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org> et al.");
+MODULE_DESCRIPTION("Caching read/erase/writeback block device emulation access to MTD devices");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)