This patch converts ov511 to dynamically allocate struct video_device, using the new interfaces in videodev.[ch]. This is required to safely support sysfs without races.

Please apply.

--
Mark McClelland
[EMAIL PROTECTED]

===================================================================


[EMAIL PROTECTED], 2003-08-13 06:50:45-07:00, [EMAIL PROTECTED]
  ov511: convert struct video_device to dynamic allocation


 ov511.c |   59 +++++++++++++++++++++++++++++++-----------------------
 ov511.h |    4 ---
 2 files changed, 35 insertions, 28 deletions


# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.5 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.2254  -> 1.2255 
#       drivers/usb/media/ov511.h       1.20    -> 1.21   
#       drivers/usb/media/ov511.c       1.56    -> 1.57   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/08/13      [EMAIL PROTECTED]       1.2255
# ov511: convert struct video_device to dynamic allocation
# --------------------------------------------
#
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c Wed Aug 13 06:54:22 2003
+++ b/drivers/usb/media/ov511.c Wed Aug 13 06:54:22 2003
@@ -45,6 +45,7 @@
 #include <asm/semaphore.h>
 #include <asm/processor.h>
 #include <linux/mm.h>
+#include <linux/device.h>
 
 #if defined (__i386__)
        #include <asm/cpufeature.h>
@@ -4042,7 +4043,7 @@
 ov51x_v4l1_open(struct inode *inode, struct file *file)
 {
        struct video_device *vdev = video_devdata(file);
-       struct usb_ov511 *ov = vdev->priv;
+       struct usb_ov511 *ov = video_get_drvdata(vdev);
        int err, i;
 
        PDEBUG(4, "opening");
@@ -4099,7 +4100,7 @@
 ov51x_v4l1_close(struct inode *inode, struct file *file)
 {
        struct video_device *vdev = file->private_data;
-       struct usb_ov511 *ov = vdev->priv;
+       struct usb_ov511 *ov = video_get_drvdata(vdev);
 
        PDEBUG(4, "ov511_close");
 
@@ -4141,7 +4142,7 @@
                          unsigned int cmd, void *arg)
 {
        struct video_device *vdev = file->private_data;
-       struct usb_ov511 *ov = vdev->priv;
+       struct usb_ov511 *ov = video_get_drvdata(vdev);
        PDEBUG(5, "IOCtl: 0x%X", cmd);
 
        if (!ov->dev)
@@ -4542,7 +4543,7 @@
 
                memset(vu, 0, sizeof(struct video_unit));
 
-               vu->video = ov->vdev.minor;
+               vu->video = ov->vdev->minor;
                vu->vbi = VIDEO_NO_UNIT;
                vu->radio = VIDEO_NO_UNIT;
                vu->audio = VIDEO_NO_UNIT;
@@ -4581,7 +4582,7 @@
                 unsigned int cmd, unsigned long arg)
 {
        struct video_device *vdev = file->private_data;
-       struct usb_ov511 *ov = vdev->priv;
+       struct usb_ov511 *ov = video_get_drvdata(vdev);
        int rc;
 
        if (down_interruptible(&ov->lock))
@@ -4599,7 +4600,7 @@
        struct video_device *vdev = file->private_data;
        int noblock = file->f_flags&O_NONBLOCK;
        unsigned long count = cnt;
-       struct usb_ov511 *ov = vdev->priv;
+       struct usb_ov511 *ov = video_get_drvdata(vdev);
        int i, rc = 0, frmx = -1;
        struct ov511_frame *frame;
 
@@ -4753,7 +4754,7 @@
        struct video_device *vdev = file->private_data;
        unsigned long start = vma->vm_start;
        unsigned long size  = vma->vm_end - vma->vm_start;
-       struct usb_ov511 *ov = vdev->priv;
+       struct usb_ov511 *ov = video_get_drvdata(vdev);
        unsigned long page, pos;
 
        if (ov->dev == NULL)
@@ -4805,6 +4806,8 @@
        .type =         VID_TYPE_CAPTURE,
        .hardware =     VID_HARDWARE_OV511,
        .fops =         &ov511_fops,
+       .release =      video_device_release,
+       .minor =        -1,
 };
 
 /****************************************************************************
@@ -5688,7 +5691,6 @@
        struct usb_interface_descriptor *idesc;
        struct usb_ov511 *ov;
        int i;
-       int registered = 0;
 
        PDEBUG(1, "probing for device...");
 
@@ -5748,7 +5750,7 @@
                break;
        default:
                err("Unknown product ID 0x%04x", dev->descriptor.idProduct);
-               goto error_dealloc;
+               goto error;
        }
 
        info("USB %s video device found", symbolic(brglist, ov->bridge));
@@ -5765,7 +5767,7 @@
 
        if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) {
                err("usb_make_path error");
-               goto error_dealloc;
+               goto error;
        }
 
        /* Allocate control transfer buffer. */
@@ -5807,36 +5809,46 @@
        }
 #endif
 
-       memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template));
-       ov->vdev.priv = ov;
+       ov->vdev = video_device_alloc();
+       if (!ov->vdev)
+               goto error;
+
+       memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev));
+       ov->vdev->dev = &dev->dev;
+       video_set_drvdata(ov->vdev, ov);
 
        for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
                /* Minor 0 cannot be specified; assume user wants autodetect */
                if (unit_video[i] == 0)
                        break;
 
-               if (video_register_device(&ov->vdev, VFL_TYPE_GRABBER,
+               if (video_register_device(ov->vdev, VFL_TYPE_GRABBER,
                        unit_video[i]) >= 0) {
-                       registered = 1;
                        break;
                }
        }
 
        /* Use the next available one */
-       if (!registered &&
-           video_register_device(&ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
+       if ((ov->vdev->minor == -1) &&
+           video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
                err("video_register_device failed");
                goto error;
        }
 
        info("Device at %s registered to minor %d", ov->usb_path,
-            ov->vdev.minor);
-
+            ov->vdev->minor);
 
-       usb_set_intfdata (intf, ov);
+       usb_set_intfdata(intf, ov);
        return 0;
 
 error:
+       if (ov->vdev) {
+               if (-1 == ov->vdev->minor)
+                       video_device_release(ov->vdev);
+               else
+                       video_unregister_device(ov->vdev);
+               ov->vdev = NULL;
+       }
 
        if (ov->cbuf) {
                down(&ov->cbuf_lock);
@@ -5845,7 +5857,6 @@
                up(&ov->cbuf_lock);
        }
 
-error_dealloc:
        if (ov) {
                kfree(ov);
                ov = NULL;
@@ -5859,7 +5870,7 @@
 static void
 ov51x_disconnect(struct usb_interface *intf)
 {
-       struct usb_ov511 *ov = usb_get_intfdata (intf);
+       struct usb_ov511 *ov = usb_get_intfdata(intf);
        int n;
 
        PDEBUG(3, "");
@@ -5869,9 +5880,8 @@
        if (!ov)
                return;
 
-       video_unregister_device(&ov->vdev);
-       if (ov->user)
-               PDEBUG(3, "Device open...deferring video_unregister_device");
+       if (ov->vdev)
+               video_unregister_device(ov->vdev);
 
        for (n = 0; n < OV511_NUMFRAMES; n++)
                ov->frame[n].grabstate = FRAME_ERROR;
@@ -5886,7 +5896,6 @@
 
        ov->streaming = 0;
        ov51x_unlink_isoc(ov);
-
 
        ov->dev = NULL;
 
diff -Nru a/drivers/usb/media/ov511.h b/drivers/usb/media/ov511.h
--- a/drivers/usb/media/ov511.h Wed Aug 13 06:54:22 2003
+++ b/drivers/usb/media/ov511.h Wed Aug 13 06:54:22 2003
@@ -407,9 +407,7 @@
 };
 
 struct usb_ov511 {
-       struct video_device vdev;
-
-       /* Device structure */
+       struct video_device *vdev;
        struct usb_device *dev;
 
        int customid;

Reply via email to