aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-dev.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-02-14 11:31:01 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 12:42:50 -0300
commit775a05dd547747cdcc079e03f4e89c7475caa735 (patch)
tree7a741f8c312e92184d4d424d67a71d5a6de1ccd9 /drivers/media/video/v4l2-dev.c
parent27d35fc3fb06284edec8a3c9f6872a1ce7405a48 (diff)
downloadkernel_samsung_smdk4412-775a05dd547747cdcc079e03f4e89c7475caa735.zip
kernel_samsung_smdk4412-775a05dd547747cdcc079e03f4e89c7475caa735.tar.gz
kernel_samsung_smdk4412-775a05dd547747cdcc079e03f4e89c7475caa735.tar.bz2
V4L/DVB (10641): v4l2-dev: remove limit of 32 devices per driver in get_index()
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>
Diffstat (limited to 'drivers/media/video/v4l2-dev.c')
-rw-r--r--drivers/media/video/v4l2-dev.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 13f87c2..922b39e 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -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)