Skip to content

Commit

Permalink
[PATCH] pktcdvd: reusability of procfs functions
Browse files Browse the repository at this point in the history
This patch makes some of the procfs functions reusable (for
coming sysfs patch e.g.):
pkt_setup_dev()
pkt_remove_dev()
...

Signed-off-by: Thomas Maier <balagi@justmail.de>
Signed-off-by: Peter Osterlund <petero2@telia.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Thomas Maier authored and Linus Torvalds committed Dec 8, 2006
1 parent dae3c5a commit adb9250
Showing 1 changed file with 45 additions and 27 deletions.
72 changes: 45 additions & 27 deletions drivers/block/pktcdvd.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2000 Jens Axboe <axboe@suse.de>
* 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
* License. See linux/COPYING for more information.
Expand Down Expand Up @@ -2436,36 +2437,33 @@ static struct block_device_operations pktcdvd_ops = {
/*
* 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 ret = -ENOMEM;
struct pktcdvd_device *pd;
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++)
if (!pkt_devs[idx])
break;
if (idx == 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);
if (!pd)
return ret;
goto out_mutex;

pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
sizeof(struct pkt_rb_node));
if (!pd->rb_pool)
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_active_list);
spin_lock_init(&pd->cdrw.active_list_lock);
Expand All @@ -2476,11 +2474,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
init_waitqueue_head(&pd->wqueue);
pd->bio_queue = RB_ROOT;

disk = alloc_disk(1);
if (!disk)
goto out_mem;
pd->disk = disk;
disk->major = pktdev_major;
disk->first_minor = idx;
disk->fops = &pktcdvd_ops;
disk->flags = GENHD_FL_REMOVABLE;
sprintf(disk->disk_name, DRIVER_NAME"%d", idx);
strcpy(disk->disk_name, pd->name);
disk->private_data = pd;
disk->queue = blk_alloc_queue(GFP_KERNEL);
if (!disk->queue)
Expand All @@ -2492,8 +2494,12 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
goto out_new_dev;

add_disk(disk);

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;

out_new_dev:
Expand All @@ -2504,17 +2510,22 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
if (pd->rb_pool)
mempool_destroy(pd->rb_pool);
kfree(pd);
out_mutex:
mutex_unlock(&ctl_mutex);
printk(DRIVER_NAME": setup of pktcdvd device failed\n");
return ret;
}

/*
* 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;
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++) {
pd = pkt_devs[idx];
Expand All @@ -2523,12 +2534,14 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
}
if (idx == MAX_WRITERS) {
DPRINTK(DRIVER_NAME": dev not setup\n");
return -ENXIO;
ret = -ENXIO;
goto out;
}

if (pd->refcnt > 0)
return -EBUSY;

if (pd->refcnt > 0) {
ret = -EBUSY;
goto out;
}
if (!IS_ERR(pd->cdrw.thread))
kthread_stop(pd->cdrw.thread);

Expand All @@ -2547,12 +2560,19 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)

/* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE);
return 0;

out:
mutex_unlock(&ctl_mutex);
return ret;
}

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) {
ctrl_cmd->dev = new_encode_dev(pd->bdev->bd_dev);
ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev);
Expand All @@ -2561,13 +2581,16 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
ctrl_cmd->pkt_dev = 0;
}
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)
{
void __user *argp = (void __user *)arg;
struct pkt_ctrl_command ctrl_cmd;
int ret = 0;
dev_t pkt_dev = 0;

if (cmd != PACKET_CTRL_CMD)
return -ENOTTY;
Expand All @@ -2579,21 +2602,16 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
case PKT_CTRL_CMD_SETUP:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
ret = pkt_setup_dev(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev);
ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev);
break;
case PKT_CTRL_CMD_TEARDOWN:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
ret = pkt_remove_dev(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev));
break;
case PKT_CTRL_CMD_STATUS:
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
pkt_get_status(&ctrl_cmd);
mutex_unlock(&ctl_mutex);
break;
default:
return -ENOTTY;
Expand Down

0 comments on commit adb9250

Please sign in to comment.