summary refs log tree commit diff
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-09-03 17:11:53 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-09-03 18:37:12 -0300
commit980d4f17345fe420fda2a84cd4a28d5d41d73cef (patch)
tree23a7abc26273cf6021f5e82b52e1d06f6d0b47f4 /drivers/media/video/vivi.c
parentf3b9f50ef771670b5d94c568241d6766691c6c18 (diff)
downloadlinux-980d4f17345fe420fda2a84cd4a28d5d41d73cef.tar.gz
V4L/DVB (8751): vivi: Fix some issues at vivi register routine
This patch fixes several small issues at vivi register routines:

1) minor and n_devs should be unsigned;
2) n_devs = 0 were not properly handled;
3) if n_devs specify a high number, the driver would just roll back and
won't register any device. The proper behaviour is to keep all succeded
devices registered;
4) both n_devs and minor were using 0 as permissions. Better to have
them with 0444.

With the current patch, if n_devs specify a very large value, it will
register all possible devices. For example, on a machine without any
other V4L drivers loaded, with this patch, we will have something like:

vivi: V4L2 device registered as /dev/video0
vivi: V4L2 device registered as /dev/video1
vivi: V4L2 device registered as /dev/video2
	...
vivi: V4L2 device registered as /dev/video31
video_register_device_index: get_index failed
Video Technology Magazine Virtual Video Capture Board ver 0.5.0 successfully loaded.

5) The number of allocated devices on success is now kept at n_devs:

$ cat /sys/module/vivi/parameters/n_devs
32

Thanks to Henne <henne@nachtwindheim.de> for pointing that there were
some issues at vivi.

Cc: Henne <henne@nachtwindheim.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r--drivers/media/video/vivi.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 3518af071a2e..f55d77db1558 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1104,19 +1104,29 @@ static struct video_device vivi_template = {
 	Initialization and module stuff
    ------------------------------------------------------------------*/
 
+/* This routine allocates from 1 to n_devs virtual drivers.
+
+   The real maximum number of virtual drivers will depend on how many drivers
+   will succeed. This is limited to the maximum number of devices that
+   videodev supports. Since there are 64 minors for video grabbers, this is
+   currently the theoretical maximum limit. However, a further limit does
+   exist at videodev that forbids any driver to register more than 32 video
+   grabbers.
+ */
 static int __init vivi_init(void)
 {
 	int ret = -ENOMEM, i;
 	struct vivi_dev *dev;
 	struct video_device *vfd;
 
+	if (n_devs <= 0)
+		n_devs = 1;
+
 	for (i = 0; i < n_devs; i++) {
 		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-		if (NULL == dev)
+		if (!dev)
 			break;
 
-		list_add_tail(&dev->vivi_devlist, &vivi_devlist);
-
 		/* init video dma queues */
 		INIT_LIST_HEAD(&dev->vidq.active);
 		init_waitqueue_head(&dev->vidq.wq);
@@ -1126,14 +1136,27 @@ static int __init vivi_init(void)
 		mutex_init(&dev->mutex);
 
 		vfd = video_device_alloc();
-		if (NULL == vfd)
+		if (!vfd) {
+			kfree(dev);
 			break;
+		}
 
 		*vfd = vivi_template;
 
 		ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
-		if (ret < 0)
+		if (ret < 0) {
+			video_device_release(vfd);
+			kfree(dev);
+
+			/* If some registers succeeded, keep driver */
+			if (i)
+				ret = 0;
+
 			break;
+		}
+
+		/* Now that everything is fine, let's add it to device list */
+		list_add_tail(&dev->vivi_devlist, &vivi_devlist);
 
 		snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
 			 vivi_template.name, vfd->minor);
@@ -1149,11 +1172,16 @@ static int __init vivi_init(void)
 	if (ret < 0) {
 		vivi_release();
 		printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
-	} else
+	} else {
 		printk(KERN_INFO "Video Technology Magazine Virtual Video "
 			"Capture Board ver %u.%u.%u successfully loaded.\n",
 			(VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
 			VIVI_VERSION & 0xFF);
+
+		/* n_devs will reflect the actual number of allocated devices */
+		n_devs = i;
+	}
+
 	return ret;
 }
 
@@ -1169,10 +1197,10 @@ MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
 MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
 MODULE_LICENSE("Dual BSD/GPL");
 
-module_param(video_nr, int, 0);
+module_param(video_nr, uint, 0444);
 MODULE_PARM_DESC(video_nr, "video iminor start number");
 
-module_param(n_devs, int, 0);
+module_param(n_devs, uint, 0444);
 MODULE_PARM_DESC(n_devs, "number of video devices to create");
 
 module_param_named(debug, vivi_template.debug, int, 0444);