Commit 6b5270d2 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

V4L/DVB (12725): v4l: warn when desired devnodenr is in use & add _no_warn function

Warn when the desired device node number is already in use, except when
the new video_register_device_no_warn function is called since in some
use-cases that warning is not relevant.
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5062cb70
...@@ -486,17 +486,27 @@ VFL_TYPE_RADIO: radioX for radio tuners ...@@ -486,17 +486,27 @@ VFL_TYPE_RADIO: radioX for radio tuners
VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use) VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use)
The last argument gives you a certain amount of control over the device The last argument gives you a certain amount of control over the device
device node number used (i.e. the X in videoX). Normally you will pass -1 to device node number used (i.e. the X in videoX). Normally you will pass -1
let the v4l2 framework pick the first free number. But if a driver creates to let the v4l2 framework pick the first free number. But sometimes users
many devices, then it can be useful to have different video devices in want to select a specific node number. It is common that drivers allow
separate ranges. For example, video capture devices start at 0, video the user to select a specific device node number through a driver module
output devices start at 16. option. That number is then passed to this function and video_register_device
will attempt to select that device node number. If that number was already
in use, then the next free device node number will be selected and it
will send a warning to the kernel log.
Another use-case is if a driver creates many devices. In that case it can
be useful to place different video devices in separate ranges. For example,
video capture devices start at 0, video output devices start at 16.
So you can use the last argument to specify a minimum device node number So you can use the last argument to specify a minimum device node number
and the v4l2 framework will try to pick the first free number that is equal and the v4l2 framework will try to pick the first free number that is equal
or higher to what you passed. If that fails, then it will just pick the or higher to what you passed. If that fails, then it will just pick the
first free number. first free number.
Since in this case you do not care about a warning about not being able
to select the specified device node number, you can call the function
video_register_device_no_warn() instead.
Whenever a device node is created some attributes are also created for you. Whenever a device node is created some attributes are also created for you.
If you look in /sys/class/video4linux you see the devices. Go into e.g. If you look in /sys/class/video4linux you see the devices. Go into e.g.
video0 and you will see 'name' and 'index' attributes. The 'name' attribute video0 and you will see 'name' and 'index' attributes. The 'name' attribute
......
...@@ -245,7 +245,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) ...@@ -245,7 +245,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
video_set_drvdata(s->video_dev, s); video_set_drvdata(s->video_dev, s);
/* Register device. First try the desired minor, then any free one. */ /* Register device. First try the desired minor, then any free one. */
ret = video_register_device(s->video_dev, vfl_type, num); ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
if (ret < 0) { if (ret < 0) {
CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
s->name, num); s->name, num);
......
...@@ -261,7 +261,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) ...@@ -261,7 +261,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
video_set_drvdata(s->vdev, s); video_set_drvdata(s->vdev, s);
/* Register device. First try the desired minor, then any free one. */ /* Register device. First try the desired minor, then any free one. */
if (video_register_device(s->vdev, vfl_type, num)) { if (video_register_device_no_warn(s->vdev, vfl_type, num)) {
IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
s->name, num); s->name, num);
video_device_release(s->vdev); video_device_release(s->vdev);
......
...@@ -382,6 +382,8 @@ static int get_index(struct video_device *vdev) ...@@ -382,6 +382,8 @@ static int get_index(struct video_device *vdev)
* @type: type of device to register * @type: type of device to register
* @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ... * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ...
* -1 == first free) * -1 == first free)
* @warn_if_nr_in_use: warn if the desired device node number
* was already in use and another number was chosen instead.
* *
* The registration code assigns minor numbers and device node numbers * The registration code assigns minor numbers and device node numbers
* based on the requested type and registers the new device node with * based on the requested type and registers the new device node with
...@@ -401,7 +403,8 @@ static int get_index(struct video_device *vdev) ...@@ -401,7 +403,8 @@ static int get_index(struct video_device *vdev)
* *
* %VFL_TYPE_RADIO - A radio card * %VFL_TYPE_RADIO - A radio card
*/ */
int video_register_device(struct video_device *vdev, int type, int nr) static int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use)
{ {
int i = 0; int i = 0;
int ret; int ret;
...@@ -547,6 +550,10 @@ int video_register_device(struct video_device *vdev, int type, int nr) ...@@ -547,6 +550,10 @@ int video_register_device(struct video_device *vdev, int type, int nr)
reference to the device goes away. */ reference to the device goes away. */
vdev->dev.release = v4l2_device_release; vdev->dev.release = v4l2_device_release;
if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
printk(KERN_WARNING "%s: requested %s%d, got %s%d\n",
__func__, name_base, nr, name_base, vdev->num);
/* Part 5: Activate this minor. The char device can now be used. */ /* Part 5: Activate this minor. The char device can now be used. */
mutex_lock(&videodev_lock); mutex_lock(&videodev_lock);
video_device[vdev->minor] = vdev; video_device[vdev->minor] = vdev;
...@@ -563,8 +570,19 @@ int video_register_device(struct video_device *vdev, int type, int nr) ...@@ -563,8 +570,19 @@ int video_register_device(struct video_device *vdev, int type, int nr)
vdev->minor = -1; vdev->minor = -1;
return ret; return ret;
} }
int video_register_device(struct video_device *vdev, int type, int nr)
{
return __video_register_device(vdev, type, nr, 1);
}
EXPORT_SYMBOL(video_register_device); EXPORT_SYMBOL(video_register_device);
int video_register_device_no_warn(struct video_device *vdev, int type, int nr)
{
return __video_register_device(vdev, type, nr, 0);
}
EXPORT_SYMBOL(video_register_device_no_warn);
/** /**
* video_unregister_device - unregister a video4linux device * video_unregister_device - unregister a video4linux device
* @vdev: the device to unregister * @vdev: the device to unregister
......
...@@ -101,6 +101,10 @@ struct video_device ...@@ -101,6 +101,10 @@ struct video_device
Also note that vdev->minor is set to -1 if the registration failed. */ Also note that vdev->minor is set to -1 if the registration failed. */
int __must_check video_register_device(struct video_device *vdev, int type, int nr); int __must_check video_register_device(struct video_device *vdev, int type, int nr);
/* Same as video_register_device, but no warning is issued if the desired
device node number was already in use. */
int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr);
/* Unregister video devices. Will do nothing if vdev == NULL or /* Unregister video devices. Will do nothing if vdev == NULL or
vdev->minor < 0. */ vdev->minor < 0. */
void video_unregister_device(struct video_device *vdev); void video_unregister_device(struct video_device *vdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment