V4L/DVB (12725): v4l: warn when desired devnodenr is in use & add _no_warn function
Hans Verkuil [Sun, 6 Sep 2009 10:54:00 +0000 (07:54 -0300)]
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: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Documentation/video4linux/v4l2-framework.txt
drivers/media/video/cx18/cx18-streams.c
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/v4l2-dev.c
include/media/v4l2-dev.h

index 38b3716..b806eda 100644 (file)
@@ -486,17 +486,27 @@ VFL_TYPE_RADIO: radioX for radio tuners
 VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use)
 
 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
-let the v4l2 framework pick the first free number. But if a driver creates
-many devices, then it can be useful to have different video devices in
-separate ranges. For example, video capture devices start at 0, video
-output devices start at 16.
-
+device node number used (i.e. the X in videoX). Normally you will pass -1
+to let the v4l2 framework pick the first free number. But sometimes users
+want to select a specific node number. It is common that drivers allow
+the user to select a specific device node number through a driver module
+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
 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
 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.
 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
index 6c988b9..7df513a 100644 (file)
@@ -245,7 +245,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
        video_set_drvdata(s->video_dev, s);
 
        /* 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) {
                CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
                        s->name, num);
index 2340003..67699e3 100644 (file)
@@ -261,7 +261,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
        video_set_drvdata(s->vdev, s);
 
        /* 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",
                                s->name, num);
                video_device_release(s->vdev);
index 4715f08..500cbe9 100644 (file)
@@ -382,6 +382,8 @@ static int get_index(struct video_device *vdev)
  *     @type: type of device to register
  *     @nr:   which device node number (0 == /dev/video0, 1 == /dev/video1, ...
  *             -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
  *     based on the requested type and registers the new device node with
@@ -401,7 +403,8 @@ static int get_index(struct video_device *vdev)
  *
  *     %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 ret;
@@ -547,6 +550,10 @@ int video_register_device(struct video_device *vdev, int type, int nr)
           reference to the device goes away. */
        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. */
        mutex_lock(&videodev_lock);
        video_device[vdev->minor] = vdev;
@@ -563,8 +570,19 @@ cleanup:
        vdev->minor = -1;
        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);
 
+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
  *     @vdev: the device to unregister
index 255f644..73c9867 100644 (file)
@@ -101,6 +101,10 @@ struct video_device
    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);
 
+/* 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
    vdev->minor < 0. */
 void video_unregister_device(struct video_device *vdev);