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