aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-02-14 09:31:01 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:50 -0400
commit775a05dd547747cdcc079e03f4e89c7475caa735 (patch)
tree7a741f8c312e92184d4d424d67a71d5a6de1ccd9 /drivers/media
parent27d35fc3fb06284edec8a3c9f6872a1ce7405a48 (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.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 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 */
289static int get_index(struct video_device *vdev, int num) 289static 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
324int video_register_device(struct video_device *vdev, int type, int nr) 325int video_register_device(struct video_device *vdev, int type, int nr)