diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-02-14 09:31:01 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:50 -0400 |
commit | 775a05dd547747cdcc079e03f4e89c7475caa735 (patch) | |
tree | 7a741f8c312e92184d4d424d67a71d5a6de1ccd9 /drivers/media | |
parent | 27d35fc3fb06284edec8a3c9f6872a1ce7405a48 (diff) |
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')
-rw-r--r-- | drivers/media/video/v4l2-dev.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 13f87c22e78d..922b39e79b8e 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 = { | |||
288 | */ | 288 | */ |
289 | static int get_index(struct video_device *vdev, int num) | 289 | static int get_index(struct video_device *vdev, int num) |
290 | { | 290 | { |
291 | u32 used = 0; | 291 | /* This can be static since this function is called with the global |
292 | const int max_index = sizeof(used) * 8 - 1; | 292 | videodev_lock held. */ |
293 | static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES); | ||
293 | int i; | 294 | int i; |
294 | 295 | ||
295 | /* Currently a single v4l driver instance cannot create more than | 296 | if (num >= VIDEO_NUM_DEVICES) { |
296 | 32 devices. | ||
297 | Increase to u64 or an array of u32 if more are needed. */ | ||
298 | if (num > max_index) { | ||
299 | printk(KERN_ERR "videodev: %s num is too large\n", __func__); | 297 | printk(KERN_ERR "videodev: %s num is too large\n", __func__); |
300 | return -EINVAL; | 298 | return -EINVAL; |
301 | } | 299 | } |
302 | 300 | ||
303 | /* Some drivers do not set the parent. In that case always return 0. */ | 301 | /* Some drivers do not set the parent. In that case always return |
302 | num or 0. */ | ||
304 | if (vdev->parent == NULL) | 303 | if (vdev->parent == NULL) |
305 | return 0; | 304 | return num >= 0 ? num : 0; |
305 | |||
306 | bitmap_zero(used, VIDEO_NUM_DEVICES); | ||
306 | 307 | ||
307 | for (i = 0; i < VIDEO_NUM_DEVICES; i++) { | 308 | for (i = 0; i < VIDEO_NUM_DEVICES; i++) { |
308 | if (video_device[i] != NULL && | 309 | if (video_device[i] != NULL && |
309 | video_device[i]->parent == vdev->parent) { | 310 | video_device[i]->parent == vdev->parent) { |
310 | used |= 1 << video_device[i]->index; | 311 | set_bit(video_device[i]->index, used); |
311 | } | 312 | } |
312 | } | 313 | } |
313 | 314 | ||
314 | if (num >= 0) { | 315 | if (num >= 0) { |
315 | if (used & (1 << num)) | 316 | if (test_bit(num, used)) |
316 | return -ENFILE; | 317 | return -ENFILE; |
317 | return num; | 318 | return num; |
318 | } | 319 | } |
319 | 320 | ||
320 | i = ffz(used); | 321 | i = find_first_zero_bit(used, VIDEO_NUM_DEVICES); |
321 | return i > max_index ? -ENFILE : i; | 322 | return i == VIDEO_NUM_DEVICES ? -ENFILE : i; |
322 | } | 323 | } |
323 | 324 | ||
324 | int video_register_device(struct video_device *vdev, int type, int nr) | 325 | int video_register_device(struct video_device *vdev, int type, int nr) |