Commit adb9250a authored by Thomas Maier's avatar Thomas Maier Committed by Linus Torvalds

[PATCH] pktcdvd: reusability of procfs functions

This patch makes some of the procfs functions reusable (for
coming sysfs patch e.g.):
pkt_setup_dev()
pkt_remove_dev()
...
Signed-off-by: default avatarThomas Maier <balagi@justmail.de>
Signed-off-by: default avatarPeter Osterlund <petero2@telia.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dae3c5a0
/* /*
* Copyright (C) 2000 Jens Axboe <axboe@suse.de> * Copyright (C) 2000 Jens Axboe <axboe@suse.de>
* Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com> * Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com>
* Copyright (C) 2006 Thomas Maier <balagi@justmail.de>
* *
* May be copied or modified under the terms of the GNU General Public * May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information. * License. See linux/COPYING for more information.
...@@ -2436,36 +2437,33 @@ static struct block_device_operations pktcdvd_ops = { ...@@ -2436,36 +2437,33 @@ static struct block_device_operations pktcdvd_ops = {
/* /*
* Set up mapping from pktcdvd device to CD-ROM device. * Set up mapping from pktcdvd device to CD-ROM device.
*/ */
static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
{ {
int idx; int idx;
int ret = -ENOMEM; int ret = -ENOMEM;
struct pktcdvd_device *pd; struct pktcdvd_device *pd;
struct gendisk *disk; struct gendisk *disk;
dev_t dev = new_decode_dev(ctrl_cmd->dev);
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
for (idx = 0; idx < MAX_WRITERS; idx++) for (idx = 0; idx < MAX_WRITERS; idx++)
if (!pkt_devs[idx]) if (!pkt_devs[idx])
break; break;
if (idx == MAX_WRITERS) { if (idx == MAX_WRITERS) {
printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS); printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS);
return -EBUSY; ret = -EBUSY;
goto out_mutex;
} }
pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL); pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
if (!pd) if (!pd)
return ret; goto out_mutex;
pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE, pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
sizeof(struct pkt_rb_node)); sizeof(struct pkt_rb_node));
if (!pd->rb_pool) if (!pd->rb_pool)
goto out_mem; goto out_mem;
disk = alloc_disk(1);
if (!disk)
goto out_mem;
pd->disk = disk;
INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
INIT_LIST_HEAD(&pd->cdrw.pkt_active_list); INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
spin_lock_init(&pd->cdrw.active_list_lock); spin_lock_init(&pd->cdrw.active_list_lock);
...@@ -2476,11 +2474,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) ...@@ -2476,11 +2474,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
init_waitqueue_head(&pd->wqueue); init_waitqueue_head(&pd->wqueue);
pd->bio_queue = RB_ROOT; pd->bio_queue = RB_ROOT;
disk = alloc_disk(1);
if (!disk)
goto out_mem;
pd->disk = disk;
disk->major = pktdev_major; disk->major = pktdev_major;
disk->first_minor = idx; disk->first_minor = idx;
disk->fops = &pktcdvd_ops; disk->fops = &pktcdvd_ops;
disk->flags = GENHD_FL_REMOVABLE; disk->flags = GENHD_FL_REMOVABLE;
sprintf(disk->disk_name, DRIVER_NAME"%d", idx); strcpy(disk->disk_name, pd->name);
disk->private_data = pd; disk->private_data = pd;
disk->queue = blk_alloc_queue(GFP_KERNEL); disk->queue = blk_alloc_queue(GFP_KERNEL);
if (!disk->queue) if (!disk->queue)
...@@ -2492,8 +2494,12 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) ...@@ -2492,8 +2494,12 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
goto out_new_dev; goto out_new_dev;
add_disk(disk); add_disk(disk);
pkt_devs[idx] = pd; pkt_devs[idx] = pd;
ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev); if (pkt_dev)
*pkt_dev = pd->pkt_dev;
mutex_unlock(&ctl_mutex);
return 0; return 0;
out_new_dev: out_new_dev:
...@@ -2504,17 +2510,22 @@ out_mem: ...@@ -2504,17 +2510,22 @@ out_mem:
if (pd->rb_pool) if (pd->rb_pool)
mempool_destroy(pd->rb_pool); mempool_destroy(pd->rb_pool);
kfree(pd); kfree(pd);
out_mutex:
mutex_unlock(&ctl_mutex);
printk(DRIVER_NAME": setup of pktcdvd device failed\n");
return ret; return ret;
} }
/* /*
* Tear down mapping from pktcdvd device to CD-ROM device. * Tear down mapping from pktcdvd device to CD-ROM device.
*/ */
static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) static int pkt_remove_dev(dev_t pkt_dev)
{ {
struct pktcdvd_device *pd; struct pktcdvd_device *pd;
int idx; int idx;
dev_t pkt_dev = new_decode_dev(ctrl_cmd->pkt_dev); int ret = 0;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
for (idx = 0; idx < MAX_WRITERS; idx++) { for (idx = 0; idx < MAX_WRITERS; idx++) {
pd = pkt_devs[idx]; pd = pkt_devs[idx];
...@@ -2523,12 +2534,14 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) ...@@ -2523,12 +2534,14 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
} }
if (idx == MAX_WRITERS) { if (idx == MAX_WRITERS) {
DPRINTK(DRIVER_NAME": dev not setup\n"); DPRINTK(DRIVER_NAME": dev not setup\n");
return -ENXIO; ret = -ENXIO;
goto out;
} }
if (pd->refcnt > 0) if (pd->refcnt > 0) {
return -EBUSY; ret = -EBUSY;
goto out;
}
if (!IS_ERR(pd->cdrw.thread)) if (!IS_ERR(pd->cdrw.thread))
kthread_stop(pd->cdrw.thread); kthread_stop(pd->cdrw.thread);
...@@ -2547,12 +2560,19 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) ...@@ -2547,12 +2560,19 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
/* This is safe: open() is still holding a reference. */ /* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE); module_put(THIS_MODULE);
return 0;
out:
mutex_unlock(&ctl_mutex);
return ret;
} }
static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
{ {
struct pktcdvd_device *pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index); struct pktcdvd_device *pd;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index);
if (pd) { if (pd) {
ctrl_cmd->dev = new_encode_dev(pd->bdev->bd_dev); ctrl_cmd->dev = new_encode_dev(pd->bdev->bd_dev);
ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev); ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev);
...@@ -2561,6 +2581,8 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) ...@@ -2561,6 +2581,8 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
ctrl_cmd->pkt_dev = 0; ctrl_cmd->pkt_dev = 0;
} }
ctrl_cmd->num_devices = MAX_WRITERS; ctrl_cmd->num_devices = MAX_WRITERS;
mutex_unlock(&ctl_mutex);
} }
static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
...@@ -2568,6 +2590,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -2568,6 +2590,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
struct pkt_ctrl_command ctrl_cmd; struct pkt_ctrl_command ctrl_cmd;
int ret = 0; int ret = 0;
dev_t pkt_dev = 0;
if (cmd != PACKET_CTRL_CMD) if (cmd != PACKET_CTRL_CMD)
return -ENOTTY; return -ENOTTY;
...@@ -2579,21 +2602,16 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -2579,21 +2602,16 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
case PKT_CTRL_CMD_SETUP: case PKT_CTRL_CMD_SETUP:
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev);
ret = pkt_setup_dev(&ctrl_cmd); ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev);
mutex_unlock(&ctl_mutex);
break; break;
case PKT_CTRL_CMD_TEARDOWN: case PKT_CTRL_CMD_TEARDOWN:
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev));
ret = pkt_remove_dev(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
break; break;
case PKT_CTRL_CMD_STATUS: case PKT_CTRL_CMD_STATUS:
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
pkt_get_status(&ctrl_cmd); pkt_get_status(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
break; break;
default: default:
return -ENOTTY; return -ENOTTY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment