V4L/DVB (10641): v4l2-dev: remove limit of 32 devices per driver in get_index()
authorHans Verkuil <hverkuil@xs4all.nl>
Sat, 14 Feb 2009 14:31:01 +0000 (11:31 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 30 Mar 2009 15:42:50 +0000 (12:42 -0300)
get_index() had a limitation of 32 devices per driver. This was
unnecessarily strict and has been replaced with the maximum number
of devices. That should really satisfy anyone!

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/v4l2-dev.c

index 13f87c22e78dce1721bb10c464409786df685c2c..922b39e79b8e0876db5863ea3a21b4a064b94b62 100644 (file)
@@ -288,37 +288,38 @@ static const struct file_operations v4l2_fops = {
  */
 static int get_index(struct video_device *vdev, int num)
 {
-       u32 used = 0;
-       const int max_index = sizeof(used) * 8 - 1;
+       /* This can be static since this function is called with the global
+          videodev_lock held. */
+       static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
        int i;
 
-       /* Currently a single v4l driver instance cannot create more than
-          32 devices.
-          Increase to u64 or an array of u32 if more are needed. */
-       if (num > max_index) {
+       if (num >= VIDEO_NUM_DEVICES) {
                printk(KERN_ERR "videodev: %s num is too large\n", __func__);
                return -EINVAL;
        }
 
-       /* Some drivers do not set the parent. In that case always return 0. */
+       /* Some drivers do not set the parent. In that case always return
+          num or 0. */
        if (vdev->parent == NULL)
-               return 0;
+               return num >= 0 ? num : 0;
+
+       bitmap_zero(used, VIDEO_NUM_DEVICES);
 
        for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
                if (video_device[i] != NULL &&
                    video_device[i]->parent == vdev->parent) {
-                       used |= 1 << video_device[i]->index;
+                       set_bit(video_device[i]->index, used);
                }
        }
 
        if (num >= 0) {
-               if (used & (1 << num))
+               if (test_bit(num, used))
                        return -ENFILE;
                return num;
        }
 
-       i = ffz(used);
-       return i > max_index ? -ENFILE : i;
+       i = find_first_zero_bit(used, VIDEO_NUM_DEVICES);
+       return i == VIDEO_NUM_DEVICES ? -ENFILE : i;
 }
 
 int video_register_device(struct video_device *vdev, int type, int nr)