summaryrefslogtreecommitdiff
path: root/drivers/media/video
diff options
context:
space:
mode:
authorBrandon Philips <brandon@ifup.org>2008-06-25 05:58:25 +0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 14:28:39 +0400
commit8373a3e512c8ea8e93981d42b0d1efb252be17fa (patch)
treebef7482f3f00d40b675072a33f5728e03e07aa42 /drivers/media/video
parent2bc93aa304f10bf94c377a487b09df75eaf88ab6 (diff)
downloadlinux-8373a3e512c8ea8e93981d42b0d1efb252be17fa.tar.xz
V4L/DVB (8389): videodev: simplify get_index()
Use Hans Verkuil's suggested method of implementing get_index which doesn't depend on class_for_each_device and instead uses the video_device array. This simplifies the code and reduces its memory footprint. Signed-off-by: Brandon Philips <bphilips@suse.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/videodev.c65
1 files changed, 17 insertions, 48 deletions
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index c24d91897099..bf12b5f850e2 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -2011,25 +2011,8 @@ out:
}
EXPORT_SYMBOL(video_ioctl2);
-struct index_info {
- struct device *dev;
- unsigned int used[VIDEO_NUM_DEVICES];
-};
-
-static int __fill_index_info(struct device *cd, void *data)
-{
- struct index_info *info = data;
- struct video_device *vfd = container_of(cd, struct video_device,
- class_dev);
-
- if (info->dev == vfd->dev)
- info->used[vfd->index] = 1;
-
- return 0;
-}
-
/**
- * assign_index - assign stream number based on parent device
+ * get_index - assign stream number based on parent device
* @vdev: video_device to assign index number to, vdev->dev should be assigned
* @num: -1 if auto assign, requested number otherwise
*
@@ -2039,44 +2022,30 @@ static int __fill_index_info(struct device *cd, void *data)
*/
static int get_index(struct video_device *vdev, int num)
{
- struct index_info *info;
+ u32 used = 0;
int i;
- int ret = 0;
- if (num >= VIDEO_NUM_DEVICES)
+ if (num >= 32) {
+ printk(KERN_ERR "videodev: %s num is too large\n", __func__);
return -EINVAL;
-
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->dev = vdev->dev;
-
- ret = class_for_each_device(&video_class, info,
- __fill_index_info);
-
- if (ret < 0)
- goto out;
-
- if (num >= 0) {
- if (!info->used[num])
- ret = num;
- else
- ret = -ENFILE;
-
- goto out;
}
for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
- if (info->used[i])
- continue;
- ret = i;
- goto out;
+ if (video_device[i] != NULL &&
+ video_device[i] != vdev &&
+ video_device[i]->dev == vdev->dev) {
+ used |= 1 << video_device[i]->index;
+ }
}
-out:
- kfree(info);
- return ret;
+ if (num >= 0) {
+ if (used & (1 << num))
+ return -ENFILE;
+ return num;
+ }
+
+ i = ffz(used);
+ return i >= 32 ? -ENFILE : i;
}
static const struct file_operations video_fops;