diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 07:12:00 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 07:12:00 -0300 |
commit | 8cd12cf4483a6c0b0fd1d221d8c6ebd02236f077 (patch) | |
tree | 207ec9be4aae5bf5216dcad124e411fbb554231a /linux/drivers/media/video/videodev.c | |
parent | f1c16914fc0f794e9febebc7a345fd5c86ebdbd4 (diff) | |
parent | 2e87dc4bc0ada9acabcc0d704444e8f361490624 (diff) | |
download | mediapointer-dvb-s2-8cd12cf4483a6c0b0fd1d221d8c6ebd02236f077.tar.gz mediapointer-dvb-s2-8cd12cf4483a6c0b0fd1d221d8c6ebd02236f077.tar.bz2 |
merge: http://www.linuxtv.org/hg/~hverkuil/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Fixed a small merge conflicts at:
merging linux/drivers/media/video/cx18/cx18-cards.h
warning: conflicts during merge.
merging linux/drivers/media/video/cx18/cx18-cards.h failed!
Basically, two new structures were added bellow the same place
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/videodev.c')
-rw-r--r-- | linux/drivers/media/video/videodev.c | 98 |
1 files changed, 96 insertions, 2 deletions
diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index aa75288ce..da78f4578 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -375,6 +375,14 @@ EXPORT_SYMBOL(v4l_printk_ioctl); * sysfs stuff */ +static ssize_t show_index(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct video_device *vfd = container_of(cd, struct video_device, + class_dev); + return sprintf(buf, "%i\n", vfd->index); +} + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) static ssize_t show_name(struct class_device *cd, char *buf) #else @@ -433,6 +441,7 @@ static void video_release(struct device *cd) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) static struct device_attribute video_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(index, S_IRUGO, show_index, NULL), __ATTR_NULL }; #endif @@ -1938,8 +1947,82 @@ 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 + * @vdev: video_device to assign index number to, vdev->dev should be assigned + * @num: -1 if auto assign, requested number otherwise + * + * + * returns -ENFILE if num is already in use, a free index number if + * successful. + */ +static int get_index(struct video_device *vdev, int num) +{ + struct index_info *info; + int i; + int ret = 0; + + if (num >= VIDEO_NUM_DEVICES) + 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; + } + +out: + kfree(info); + return ret; +} + static const struct file_operations video_fops; +int video_register_device(struct video_device *vfd, int type, int nr) +{ + return video_register_device_index(vfd, type, nr, -1); +} +EXPORT_SYMBOL(video_register_device); + /** * video_register_device - register video4linux devices * @vfd: video device structure we want to register @@ -1965,7 +2048,8 @@ static const struct file_operations video_fops; * %VFL_TYPE_RADIO - A radio card */ -int video_register_device(struct video_device *vfd, int type, int nr) +int video_register_device_index(struct video_device *vfd, int type, int nr, + int index) { int i=0; int base; @@ -2022,6 +2106,16 @@ int video_register_device(struct video_device *vfd, int type, int nr) } video_device[i]=vfd; vfd->minor=i; + + ret = get_index(vfd, index); + if (ret < 0) { + printk(KERN_ERR "%s: get_index failed\n", + __func__); + goto fail_minor; + } + + vfd->index = ret; + mutex_unlock(&videodev_lock); mutex_init(&vfd->lock); @@ -2084,7 +2178,7 @@ fail_minor: mutex_unlock(&videodev_lock); return ret; } -EXPORT_SYMBOL(video_register_device); +EXPORT_SYMBOL(video_register_device_index); /** * video_unregister_device - unregister a video4linux device |