mtd/drivers/mtd mtdblock_ro.c,1.15,1.16
David Woodhouse
dwmw2 at infradead.org
Sun May 18 15:15:33 EDT 2003
Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv8624
Modified Files:
mtdblock_ro.c
Log Message:
Simple mtdblock_ro driver to use new blk core
Index: mtdblock_ro.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtdblock_ro.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- mtdblock_ro.c 24 Jan 2003 13:15:19 -0000 1.15
+++ mtdblock_ro.c 18 May 2003 19:15:30 -0000 1.16
@@ -1,308 +1,86 @@
/*
* $Id$
*
- * Read-only version of the mtdblock device, without the
- * read/erase/modify/writeback stuff
+ * (C) 2003 David Woodhouse <dwmw2 at infradead.org>
+ *
+ * Simple read-only (writable only for RAM) mtdblock driver
*/
-#ifdef MTDBLOCK_DEBUG
-#define DEBUGLVL debug
-#endif
-
-
-#include <linux/module.h>
-#include <linux/types.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"
-#define DEVICE_REQUEST mtdblock_request
-#define DEVICE_NR(device) (device)
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-#define DEVICE_NO_RANDOM
-#include <linux/blk.h>
-
-#if LINUX_VERSION_CODE < 0x20300
-#define RQFUNC_ARG void
-#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
-#else
-#define RQFUNC_ARG request_queue_t *q
-#endif
-
-#ifdef MTDBLOCK_DEBUG
-static int debug = MTDBLOCK_DEBUG;
-MODULE_PARM(debug, "i");
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
-#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
-#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
-#else
-#define BLK_INC_USE_COUNT do {} while(0)
-#define BLK_DEC_USE_COUNT do {} while(0)
-#endif
+#include <linux/mtd/blktrans.h>
-/* this lock is used just in kernels >= 2.5.x */
-static spinlock_t mtdblock_ro_lock;
-
-static int mtd_sizes[MAX_MTD_DEVICES];
-
-static int mtdblock_open(struct inode *inode, struct file *file)
+static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buf)
{
- struct mtd_info *mtd = NULL;
-
- int dev;
-
- DEBUG(1,"mtdblock_open\n");
-
- if (inode == 0)
- return -EINVAL;
-
- dev = minor(inode->i_rdev);
-
- mtd = get_mtd_device(NULL, dev);
- if (!mtd)
- return -EINVAL;
- if (MTD_ABSENT == mtd->type) {
- put_mtd_device(mtd);
- return -EINVAL;
- }
-
- BLK_INC_USE_COUNT;
-
- mtd_sizes[dev] = mtd->size>>9;
-
- DEBUG(1, "ok\n");
+ size_t retlen;
+ if (dev->mtd->read(dev->mtd, (block * 512), 512, &retlen, buf))
+ return 1;
return 0;
}
-static release_t mtdblock_release(struct inode *inode, struct file *file)
+static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buf)
{
- int dev;
- struct mtd_info *mtd;
-
- DEBUG(1, "mtdblock_release\n");
+ size_t retlen;
- if (inode == NULL)
- release_return(-ENODEV);
-
- dev = minor(inode->i_rdev);
- mtd = __get_mtd_device(NULL, dev);
-
- if (!mtd) {
- printk(KERN_WARNING "MTD device is absent on mtd_release!\n");
- BLK_DEC_USE_COUNT;
- release_return(-ENODEV);
- }
-
- if (mtd->sync)
- mtd->sync(mtd);
+ if (dev->mtd->write(dev->mtd, (block * 512), 512, &retlen, buf))
+ return 1;
+ return 0;
+}
- put_mtd_device(mtd);
+static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
+{
+ struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- DEBUG(1, "ok\n");
+ if (!dev)
+ return;
- BLK_DEC_USE_COUNT;
- release_return(0);
-}
+ memset(dev, 0, sizeof(*dev));
+ dev->mtd = mtd;
+ dev->devnum = mtd->index;
+ dev->blksize = 512;
+ dev->size = mtd->size >> 9;
+ dev->tr = tr;
+ if ((mtd->flags & (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) !=
+ (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE))
+ dev->readonly = 1;
-static void mtdblock_request(RQFUNC_ARG)
-{
- struct request *current_request;
- unsigned int res = 0;
- struct mtd_info *mtd;
-
- while (1)
- {
- /* Grab the Request and unlink it from the request list, INIT_REQUEST
- will execute a return if we are done. */
- INIT_REQUEST;
- current_request = CURRENT;
-
- if (minor(current_request->rq_dev) >= MAX_MTD_DEVICES)
- {
- printk("mtd: Unsupported device!\n");
- end_request(0);
- continue;
- }
-
- // Grab our MTD structure
-
- mtd = __get_mtd_device(NULL,minor(current_request->rq_dev));
- if (!mtd) {
- printk("MTD device %d doesn't appear to exist any more\n",
- kdev_t_to_nr(CURRENT_DEV));
- end_request(0);
- }
-
- if (current_request->sector << 9 > mtd->size ||
- (current_request->sector + current_request->current_nr_sectors) << 9 > mtd->size)
- {
- printk("mtd: Attempt to read past end of device!\n");
- printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size,
- current_request->sector, current_request->current_nr_sectors);
- end_request(0);
- continue;
- }
-
- /* Remove the request we are handling from the request list so nobody messes
- with it */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- /* Now drop the lock that the ll_rw_blk functions grabbed for us
- and process the request. This is necessary due to the extreme time
- we spend processing it. */
- spin_unlock_irq(QUEUE_LOCK(QUEUE));
-#endif
-
- // Handle the request
- switch (rq_data_dir(current_request))
- {
- size_t retlen;
-
- case READ:
- if (MTD_READ(mtd,current_request->sector<<9,
- current_request->current_nr_sectors << 9,
- &retlen, current_request->buffer) == 0)
- res = 1;
- else
- res = 0;
- break;
-
- case WRITE:
-
- /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector,
- current_request->current_nr_sectors);
- */
-
- // Read only device
- if ((mtd->flags & MTD_CAP_RAM) == 0)
- {
- res = 0;
- break;
- }
-
- // Do the write
- if (MTD_WRITE(mtd,current_request->sector<<9,
- current_request->current_nr_sectors << 9,
- &retlen, current_request->buffer) == 0)
- res = 1;
- else
- res = 0;
- break;
-
- // Shouldn't happen
- default:
- printk("mtd: unknown request\n");
- break;
- }
-
- // Grab the lock and re-thread the item onto the linked list
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- spin_lock_irq(QUEUE_LOCK(QUEUE));
-#endif
- end_request(res);
- }
+ add_mtd_blktrans_dev(dev);
}
-
-
-static int mtdblock_ioctl(struct inode * inode, struct file * file,
- unsigned int cmd, unsigned long arg)
+static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
{
- struct mtd_info *mtd;
-
- mtd = __get_mtd_device(NULL, minor(inode->i_rdev));
-
- if (!mtd) return -EINVAL;
-
- switch (cmd) {
- case BLKGETSIZE: /* Return device size */
- return put_user((mtd->size >> 9), (unsigned long *) arg);
-
-#ifdef BLKGETSIZE64
- case BLKGETSIZE64:
- return put_user((u64)mtd->size, (u64 *)arg);
-#endif
-
- case BLKFLSBUF:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
-#endif
- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- if (mtd->sync)
- mtd->sync(mtd);
- return 0;
-
- default:
- return -ENOTTY;
- }
+ del_mtd_blktrans_dev(dev);
+ kfree(dev);
}
-#if LINUX_VERSION_CODE < 0x20326
-static struct file_operations mtd_fops =
-{
- open: mtdblock_open,
- ioctl: mtdblock_ioctl,
- release: mtdblock_release,
- read: block_read,
- write: block_write
-};
-#else
-static struct block_device_operations mtd_fops =
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
- owner: THIS_MODULE,
-#endif
- open: mtdblock_open,
- release: mtdblock_release,
- ioctl: mtdblock_ioctl
+struct mtd_blktrans_ops mtdblock_tr = {
+ .name = "mtdblock",
+ .major = 31,
+ .part_bits = 2,
+ .readsect = mtdblock_readsect,
+ .writesect = mtdblock_writesect,
+ .add_mtd = mtdblock_add_mtd,
+ .remove_dev = mtdblock_remove_dev,
+ .owner = THIS_MODULE,
};
-#endif
-int __init init_mtdblock(void)
+static int __init mtdblock_init(void)
{
- int i;
-
- /* this lock is used just in kernels >= 2.5.x */
- spin_lock_init(&mtdblock_ro_lock);
-
- if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
- MTD_BLOCK_MAJOR);
- return -EAGAIN;
- }
-
- /* We fill it in at open() time. */
- for (i=0; i< MAX_MTD_DEVICES; i++) {
- mtd_sizes[i] = 0;
- }
-
- /* Allow the block size to default to BLOCK_SIZE. */
- blksize_size[MAJOR_NR] = NULL;
- blk_size[MAJOR_NR] = mtd_sizes;
-
- BLK_INIT_QUEUE(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request, &mtdblock_ro_lock);
- return 0;
+ return register_mtd_blktrans(&mtdblock_tr);
}
-static void __exit cleanup_mtdblock(void)
+static void __exit mtdblock_exit(void)
{
- unregister_blkdev(MAJOR_NR,DEVICE_NAME);
- blk_size[MAJOR_NR] = NULL;
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ deregister_mtd_blktrans(&mtdblock_tr);
}
-module_init(init_mtdblock);
-module_exit(cleanup_mtdblock);
-
+module_init(mtdblock_init);
+module_exit(mtdblock_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Erwin Authried <eauth at softsys.co.at> et al.");
+MODULE_AUTHOR("David Woodhouse <dwmw2 at infradead.org>");
MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices");
-
More information about the linux-mtd-cvs
mailing list