Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+45 −27
Original line number Diff line number Diff line
/*
 * 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.
@@ -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);
@@ -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)
@@ -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:
@@ -2504,17 +2510,22 @@ out_mem:
	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];
@@ -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);

@@ -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);
@@ -2561,6 +2581,8 @@ 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)
@@ -2568,6 +2590,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
	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;
@@ -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;