From: Adrian M. <zx8...@us...> - 2002-09-15 22:49:30
|
Update of /cvsroot/linuxdc/linux-sh-dc/fs In directory usw-pr-cvs1:/tmp/cvs-serv16853/fs Modified Files: vmuflash-fs.c Log Message: vmu flash fs code cleaned and improved Index: vmuflash-fs.c =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmuflash-fs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- vmuflash-fs.c 14 Sep 2002 23:50:32 -0000 1.1 +++ vmuflash-fs.c 15 Sep 2002 22:49:27 -0000 1.2 @@ -12,8 +12,9 @@ * General Public Licence * http://www.gnu.org * - * Much of this driver is based + * Much of this driver is modelled * on existing mtd block drivers. + * Particularly the mtdblock driver... * All copyrights acknowledged. * * @@ -37,19 +38,19 @@ #define DEVICE_NAME "vmufs" #define DEVICE_NR(device) (device) #define MAJOR_NR MTD_BLOCK_MAJOR - -#include <linux/blk.h> +#define DEVICE_NO_RANDOM +#include <linux/blk.h> #ifdef CONFIG_DEVFS_FS #include <linux/devfs_fs_kernel.h> -static void vmufs_notify_add(struct mtd_info* mtd); -static void vmufs_notify_remove(struct mtd_info* mtd); +static void vmufs_notify_add(struct mtd_info *mtd); +static void vmufs_notify_remove(struct mtd_info *mtd); static struct mtd_notifier notifier = { - vmufs_notify_add, - vmufs_notify_remove, - NULL + vmufs_notify_add, + vmufs_notify_remove, + NULL }; static devfs_handle_t devfs_dir_handle = NULL; static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES]; @@ -60,10 +61,10 @@ static int vmublksize_size[MAX_MTD_DEVICES]; static struct vmublk_dev { - struct mtd_info *mtd; /* Locked */ + struct mtd_info *mtd; /* Locked */ int count; - + } *vmublks[MAX_MTD_DEVICES]; @@ -75,26 +76,27 @@ /* Notification that a new device has been added. Create the devfs entry for * it. */ -static void vmufs_notify_add(struct mtd_info* mtd) +static void vmufs_notify_add(struct mtd_info *mtd) { - char name[8]; + char name[8]; - if (!mtd || mtd->type == MTD_ABSENT) - return; + if (!mtd || mtd->type == MTD_ABSENT) + return; - sprintf(name, "%d", mtd->index); - devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name, - DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index, - S_IFBLK | S_IRUGO | S_IWUGO, - &vmufs_bdops, NULL); + sprintf(name, "%d", mtd->index); + devfs_rw_handle[mtd->index] = + devfs_register(devfs_dir_handle, name, DEVFS_FL_DEFAULT, + MTD_BLOCK_MAJOR, mtd->index, + S_IFBLK | S_IRUGO | S_IWUGO, &vmufs_bdops, + NULL); } -static void vmufs_notify_remove(struct mtd_info* mtd) +static void vmufs_notify_remove(struct mtd_info *mtd) { - if (!mtd || mtd->type == MTD_ABSENT) - return; + if (!mtd || mtd->type == MTD_ABSENT) + return; - devfs_unregister(devfs_rw_handle[mtd->index]); + devfs_unregister(devfs_rw_handle[mtd->index]); } #endif @@ -108,11 +110,11 @@ struct mtd_info *mtd; int dev; - DEBUG(MTD_DEBUG_LEVEL1,"vmuflash_fs_open\n"); - + DEBUG(MTD_DEBUG_LEVEL1, "vmuflash_fs_open\n"); + if (!inode) return -EINVAL; - + dev = MINOR(inode->i_rdev); if (dev >= MAX_MTD_DEVICES) return -EINVAL; @@ -124,7 +126,7 @@ put_mtd_device(mtd); return -ENODEV; } - + spin_lock(&vmublks_lock); /* If it's already open.... */ @@ -133,12 +135,12 @@ spin_unlock(&vmublks_lock); return 0; } - + /* OK, it's not open. Try to find it */ /* First we have to drop the lock, because we have to to things which might sleep. - */ + */ spin_unlock(&vmublks_lock); vmublk = kmalloc(sizeof(struct vmublk_dev), GFP_KERNEL); @@ -159,15 +161,16 @@ vmublks[dev] = vmublk; - vmublk_size[dev] = vmublk->mtd->size/1024; + vmublk_size[dev] = vmublk->mtd->size / 1024; if (vmublk->mtd->erasesize) vmublksize_size[dev] = vmublk->mtd->erasesize; if (vmublksize_size[dev] > PAGE_SIZE) vmublksize_size[dev] = PAGE_SIZE; - set_device_ro (inode->i_rdev, !(vmublk->mtd->flags & MTD_WRITEABLE)); - + set_device_ro(inode->i_rdev, + !(vmublk->mtd->flags & MTD_WRITEABLE)); + spin_unlock(&vmublks_lock); - + DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); return 0; @@ -179,15 +182,43 @@ { - return 1; + return 1; } -int vmufs_ioctl(struct inode *inode, struct file *filp, unsigned int command, unsigned long argument) +int vmufs_ioctl(struct inode *inode, struct file *filp, + unsigned int command, unsigned long argument) { + struct vmublk_dev *vmublk; + + vmublk = vmublks[MINOR(inode->i_rdev)]; + + if (!vmublk) + BUG(); + + switch (command) { + case BLKGETSIZE: /* Return device size */ + return put_user((vmublk->mtd->size >> 9), + (unsigned long *) argument); + case BLKGETSIZE64: + return put_user((u64) vmublk->mtd->size, (u64 *) argument); + + case BLKFLSBUF: + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + fsync_dev(inode->i_rdev); + invalidate_buffers(inode->i_rdev); + + if (vmublk->mtd->sync) + vmublk->mtd->sync(vmublk->mtd); + return 0; + + default: + return -EINVAL; + } - return 1; } @@ -196,7 +227,7 @@ - return 1; + return 1; } @@ -205,84 +236,95 @@ - return 1; + return 1; } static int get_vmu_device(const struct request *req) { - int devno; - devno = MINOR(req->rq_dev); - /* Is there an mtd device for this? */ - struct mtd_info *mtd = get_mtd_device(NULL, devno); - if (!mtd){ - static int count = 0; - if (count++ < 45) /* TO DO: Lower this for production driver */ - printk(KERN_WARNING "vmufs: requested an unknown device: %i\n", devno); - return -1; - } - put_mtd_device(mtd); - return devno; + int devno; + devno = MINOR(req->rq_dev); + /* Is there an mtd device for this? */ + struct mtd_info *mtd = get_mtd_device(NULL, devno); + if (!mtd) { + static int count = 0; + if (count++ < 45) /* TO DO: Lower this for production driver */ + printk(KERN_WARNING + "vmufs: requested an unknown device: %i\n", + devno); + return -1; + } + put_mtd_device(mtd); + return devno; } static int vmufs_transfer(int devno, const struct request *req) { - struct mtd_info *mtd = get_mtd_device(NULL, devno); - - int size, retsize, retvalue = 1; - u8 *ptr = NULL; - size = req->current_nr_sectors * mtd->erasesize; + struct mtd_info *mtd = get_mtd_device(NULL, devno); + spin_unlock_irq(&io_request_lock); + int size, retsize, retvalue = 1; + u8 *ptr = NULL; + size = req->current_nr_sectors * mtd->erasesize; - switch(req->cmd){ - case READ: - ptr = kmalloc(size, GFP_KERNEL); - if (((mtd->read)(mtd, req->sector * mtd->erasesize, size, &retsize, ptr)) < 0){ - /* Failed */ - retvalue = -1; - static int count = 0; - if (count++ < 45) /* TO DO: Lower this for production driver */ - printk(KERN_WARNING "vmufs: failed on read\n"); - break; - } + switch (req->cmd) { + case READ: + ptr = kmalloc(size, GFP_KERNEL); + if (((mtd->read) (mtd, req->sector * mtd->erasesize, size, + &retsize, ptr)) < 0) { + /* Failed */ + retvalue = -1; + static int count = 0; + if (count++ < 45) /* TO DO: Lower this for production driver */ + printk(KERN_WARNING + "vmufs: failed on read\n"); + break; + } - memcpy(req->buffer, ptr, retsize); + memcpy(req->buffer, ptr, retsize); - break; - case WRITE: - ptr = kmalloc(size, GFP_KERNEL); - memcpy(ptr, req->buffer, size); - if (((mtd->write)(mtd, req->sector * mtd->erasesize, size, &retsize, ptr)) < 0){ - /* Failed */ - retvalue = -1; - static int count = 0; - if (count++ < 45) /* TO DO: Lower this for production driver */ - printk(KERN_WARNING "vmufs: failed on write\n"); - break; - } - default: - retvalue = 0; - } - if (ptr) kfree(ptr); - put_mtd_device(mtd); - return retvalue; + break; + case WRITE: + ptr = kmalloc(size, GFP_KERNEL); + memcpy(ptr, req->buffer, size); + if (((mtd->write) (mtd, req->sector * mtd->erasesize, size, + &retsize, ptr)) < 0) { + /* Failed */ + retvalue = -1; + static int count = 0; + if (count++ < 45) /* TO DO: Lower this for production driver */ + printk(KERN_WARNING + "vmufs: failed on write\n"); + break; + } + default: + retvalue = 0; + } + if (ptr) + kfree(ptr); + put_mtd_device(mtd); + spin_lock_irq(&io_request_lock); + return retvalue; } -void vmufs_request(request_queue_t *q) +void vmufs_request(request_queue_t * q) { - int device, status; + int device, status; - while (1){ - INIT_REQUEST; - /* Check we have a real device */ - device = get_vmu_device(CURRENT); - if (device < 0){ - end_request(0); - continue; - } - status = vmufs_transfer(device, CURRENT); - printk("request %p: cmd %i sec %li (nr. %li)\n", CURRENT, CURRENT->cmd, CURRENT->sector, CURRENT->current_nr_sectors); - end_request(1); - } + while (1) { + INIT_REQUEST; + + /* Check we have a real device */ + device = get_vmu_device(CURRENT); + if (device < 0) { + end_request(0); + continue; + } + status = vmufs_transfer(device, CURRENT); + printk("request %p: cmd %i sec %li (nr. %li)\n", CURRENT, + CURRENT->cmd, CURRENT->sector, + CURRENT->current_nr_sectors); + end_request(1); + } } @@ -290,56 +332,57 @@ int __init init_vmufs(void) { - int i; + int i; - spin_lock_init(&vmufs_lock); + spin_lock_init(&vmufs_lock); #ifdef CONFIG_DEVFS_FS - if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &vmufs_bdops)) - { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_BLOCK_MAJOR); - return -EAGAIN; - } + if (devfs_register_blkdev + (MTD_BLOCK_MAJOR, DEVICE_NAME, &vmufs_bdops)) { + printk(KERN_NOTICE + "Can't allocate major number %d for Memory Technology Devices.\n", + MTD_BLOCK_MAJOR); + return -EAGAIN; + } - devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL); - register_mtd_user(¬ifier); + devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL); + register_mtd_user(¬ifier); #else - if (register_blkdev(MAJOR_NR,DEVICE_NAME,&vmufs_bdops)) { - printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", - MTD_BLOCK_MAJOR); - return -EAGAIN; - } - + if (register_blkdev(MAJOR_NR, DEVICE_NAME, &vmufs_bdops)) { + printk(KERN_NOTICE + "Can't allocate major number %d for Memory Technology Devices.\n", + MTD_BLOCK_MAJOR); + return -EAGAIN; + } #endif - /* We fill it in at open() time. */ - for (i=0; i< MAX_MTD_DEVICES; i++) { - vmublk_size[i] = 0; - vmublksize_size[i] = 0; /* Not fixed (in theory) for DC vmu flash */ - } + /* We fill it in at open() time. */ + for (i = 0; i < MAX_MTD_DEVICES; i++) { + vmublk_size[i] = 0; + vmublksize_size[i] = 0; /* Not fixed (in theory) for DC vmu flash */ + } /* init_waitqueue_head(&vmufs_wq); */ - blksize_size[MAJOR_NR] = vmublksize_size; - blk_size[MAJOR_NR] = vmublk_size; + blksize_size[MAJOR_NR] = vmublksize_size; + blk_size[MAJOR_NR] = vmublk_size; - blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &vmufs_request); - /*kernel_thread (vmufs_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND); */ /* Do I need this? */ - return 0; + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &vmufs_request); +/*kernel_thread (vmufs_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND); *//* Do I need this? */ + return 0; } static void __exit exit_vmufs(void) { - /* leaving = 1; - wake_up(&thr_wq); - down(&thread_sem); */ + /* leaving = 1; + wake_up(&thr_wq); + down(&thread_sem); */ #ifdef CONFIG_DEVFS_FS unregister_mtd_user(¬ifier); devfs_unregister(devfs_dir_handle); devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME); #else - unregister_blkdev(MAJOR_NR,DEVICE_NAME); + unregister_blkdev(MAJOR_NR, DEVICE_NAME); #endif blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blksize_size[MAJOR_NR] = NULL; @@ -349,11 +392,11 @@ static struct block_device_operations vmufs_bdops = { - open: vmufs_open, - release: vmufs_release, - ioctl: vmufs_ioctl, - check_media_change: vmufs_check_change, - revalidate: vmufs_revalidate, + open:vmufs_open, + release:vmufs_release, + ioctl:vmufs_ioctl, + check_media_change:vmufs_check_change, + revalidate:vmufs_revalidate, }; |