Hi,

This patch adapts the bttv driver to the recent videodev changes.
struct video_device is now dynamically allocated and freed on
->release() to fix sysfs race.  Also adds a private sysfs driver
attribute file.

  Gerd

==============================[ cut here ]==============================
diff -u linux-2.6.0-test1/drivers/media/video/bttv-cards.c 
linux/drivers/media/video/bttv-cards.c
--- linux-2.6.0-test1/drivers/media/video/bttv-cards.c  2003-07-21 11:49:42.000000000 
+0200
+++ linux/drivers/media/video/bttv-cards.c      2003-07-21 11:49:43.000000000 +0200
@@ -1851,12 +1851,8 @@
                btv->type=card[btv->nr];
        
        /* print which card config we are using */
-       sprintf(btv->video_dev.name,"BT%d%s(%.23s)",
-               btv->id,
-               (btv->id==848 && btv->revision==0x12) ? "A" : "",
-               bttv_tvcards[btv->type].name);
        printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->nr,
-              btv->video_dev.name,btv->type,
+              bttv_tvcards[btv->type].name, btv->type,
               card[btv->nr] < bttv_num_tvcards
               ? "insmod option" : "autodetected");
 
diff -u linux-2.6.0-test1/drivers/media/video/bttv-driver.c 
linux/drivers/media/video/bttv-driver.c
--- linux-2.6.0-test1/drivers/media/video/bttv-driver.c 2003-07-21 11:49:42.000000000 
+0200
+++ linux/drivers/media/video/bttv-driver.c     2003-07-21 17:08:32.183882024 +0200
@@ -32,6 +32,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
+#include <linux/device.h>
 
 #include <asm/io.h>
 #include <asm/byteorder.h>
@@ -123,6 +124,17 @@
 #endif
 
 /* ----------------------------------------------------------------------- */
+/* sysfs                                                                   */
+
+static ssize_t show_card(struct class_device *cd, char *buf)
+{
+       struct video_device *vfd = to_video_device(cd);
+       struct bttv *btv = dev_get_drvdata(vfd->dev);
+       return sprintf(buf, "%d\n", btv ? btv->type : UNSET);
+}
+static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
+
+/* ----------------------------------------------------------------------- */
 /* static data                                                             */
 
 /* special timing tables from conexant... */
@@ -2039,7 +2051,7 @@
                 struct video_capability *cap = arg;
 
                memset(cap,0,sizeof(*cap));
-                strcpy(cap->name,btv->video_dev.name);
+                strcpy(cap->name,btv->video_dev->name);
                if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
                        /* vbi */
                        cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
@@ -2390,7 +2402,7 @@
                if (0 == v4l2)
                        return -EINVAL;
                 strcpy(cap->driver,"bttv");
-                strlcpy(cap->card,btv->video_dev.name,sizeof(cap->card));
+                strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
                sprintf(cap->bus_info,"PCI:%s",btv->dev->slot_name);
                cap->version = BTTV_VERSION_CODE;
                cap->capabilities =
@@ -2767,12 +2779,12 @@
        dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
 
        for (i = 0; i < bttv_num; i++) {
-               if (bttvs[i].video_dev.minor == minor) {
+               if (bttvs[i].video_dev->minor == minor) {
                        btv = &bttvs[i];
                        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                        break;
                }
-               if (bttvs[i].vbi_dev.minor == minor) {
+               if (bttvs[i].vbi_dev->minor == minor) {
                        btv = &bttvs[i];
                        type = V4L2_BUF_TYPE_VBI_CAPTURE;
                        break;
@@ -2873,8 +2885,8 @@
 static struct video_device bttv_video_template =
 {
        .name     = "UNSET",
-       type:     VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
-                 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
+       .type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+                   VID_TYPE_CLIPPING|VID_TYPE_SCALES,
        .hardware = VID_HARDWARE_BT848,
        .fops     = &bttv_fops,
        .minor    = -1,
@@ -2902,7 +2914,7 @@
        dprintk("bttv: open minor=%d\n",minor);
 
        for (i = 0; i < bttv_num; i++) {
-               if (bttvs[i].radio_dev.minor == minor) {
+               if (bttvs[i].radio_dev->minor == minor) {
                        btv = &bttvs[i];
                        break;
                }
@@ -2947,7 +2959,7 @@
                 struct video_capability *cap = arg;
 
                memset(cap,0,sizeof(*cap));
-                strcpy(cap->name,btv->radio_dev.name);
+                strcpy(cap->name,btv->radio_dev->name);
                 cap->type = VID_TYPE_TUNER;
                cap->channels = 1;
                cap->audios = 1;
@@ -3337,30 +3349,83 @@
 /* ----------------------------------------------------------------------- */
 /* initialitation                                                          */
 
+static struct video_device *vdev_init(struct bttv *btv,
+                                     struct video_device *template,
+                                     char *type)
+{
+       struct video_device *vfd;
+
+       vfd = video_device_alloc();
+       if (NULL == vfd)
+               return NULL;
+       *vfd = *template;
+       vfd->minor   = -1;
+       vfd->release = video_device_release;
+       vfd->dev     = &btv->dev->dev;
+       snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
+                btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
+                type, bttv_tvcards[btv->type].name);
+       return vfd;
+}
+
 /* register video4linux devices */
 static int __devinit bttv_register_video(struct bttv *btv)
 {
-        if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
-                return -1;
+       /* video */
+       btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
+        if (NULL == btv->video_dev)
+               goto err;
+       if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
+               goto err;
        printk(KERN_INFO "bttv%d: registered device video%d\n",
-              btv->nr,btv->video_dev.minor & 0x1f);
+              btv->nr,btv->video_dev->minor & 0x1f);
+       video_device_create_file(btv->video_dev, &class_device_attr_card);
 
-        if(video_register_device(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) {
-                video_unregister_device(&btv->video_dev);
-                return -1;
-        }
+       /* vbi */
+       btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
+        if (NULL == btv->vbi_dev)
+               goto err;
+        if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
+               goto err;
        printk(KERN_INFO "bttv%d: registered device vbi%d\n",
-              btv->nr,btv->vbi_dev.minor & 0x1f);
+              btv->nr,btv->vbi_dev->minor & 0x1f);
 
         if (!btv->has_radio)
                return 0;
-       if (video_register_device(&btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) {
-               video_unregister_device(&btv->vbi_dev);
-               video_unregister_device(&btv->video_dev);
-               return -1;
-        }
+       /* radio */
+       btv->radio_dev = vdev_init(btv, &radio_template, "radio");
+        if (NULL == btv->radio_dev)
+               goto err;
+       if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
+               goto err;
        printk(KERN_INFO "bttv%d: registered device radio%d\n",
-              btv->nr,btv->radio_dev.minor & 0x1f);
+              btv->nr,btv->radio_dev->minor & 0x1f);
+
+       /* all done */
+       return 0;
+
+ err:
+       if (btv->video_dev) {
+               if (-1 != btv->video_dev->minor)
+                       video_unregister_device(btv->video_dev);
+               else
+                       video_device_release(btv->video_dev);
+               btv->video_dev = NULL;
+       }
+       if (btv->vbi_dev) {
+               if (-1 != btv->vbi_dev->minor)
+                       video_unregister_device(btv->vbi_dev);
+               else
+                       video_device_release(btv->vbi_dev);
+               btv->vbi_dev = NULL;
+       }
+       if (btv->radio_dev) {
+               if (-1 != btv->radio_dev->minor)
+                       video_unregister_device(btv->radio_dev);
+               else
+                       video_device_release(btv->radio_dev);
+               btv->radio_dev = NULL;
+       }
         return 0;
 }
 
@@ -3408,16 +3473,6 @@
         btv->i2c_rc = -1;
         btv->tuner_type  = UNSET;
         btv->pinnacle_id = UNSET;
-
-       memcpy(&btv->video_dev, &bttv_video_template, sizeof(bttv_video_template));
-       memcpy(&btv->radio_dev, &radio_template,      sizeof(radio_template));
-       memcpy(&btv->vbi_dev,   &bttv_vbi_template,   sizeof(bttv_vbi_template));
-        btv->video_dev.minor = -1;
-       btv->video_dev.priv = btv;
-        btv->radio_dev.minor = -1;
-       btv->radio_dev.priv = btv;
-        btv->vbi_dev.minor = -1;
-       btv->vbi_dev.priv = btv;
        btv->has_radio=radio[btv->nr];
        
        /* pci stuff (init, get irq/mmip, ... */
@@ -3576,12 +3631,18 @@
                i2c_bit_del_bus(&btv->i2c_adap);
 
        /* unregister video4linux */
-        if (btv->video_dev.minor!=-1)
-                video_unregister_device(&btv->video_dev);
-        if (btv->radio_dev.minor!=-1)
-                video_unregister_device(&btv->radio_dev);
-       if (btv->vbi_dev.minor!=-1)
-                video_unregister_device(&btv->vbi_dev);
+        if (btv->video_dev) {
+                video_unregister_device(btv->video_dev);
+               btv->video_dev = NULL;
+       }
+        if (btv->radio_dev) {
+                video_unregister_device(btv->radio_dev);
+               btv->radio_dev = NULL;
+       }
+       if (btv->vbi_dev) {
+                video_unregister_device(btv->vbi_dev);
+               btv->vbi_dev = NULL;
+       }
 
        /* free allocated memory */
        btcx_riscmem_free(btv->dev,&btv->main);
diff -u linux-2.6.0-test1/drivers/media/video/bttvp.h linux/drivers/media/video/bttvp.h
--- linux-2.6.0-test1/drivers/media/video/bttvp.h       2003-07-21 11:49:42.000000000 
+0200
+++ linux/drivers/media/video/bttvp.h   2003-07-21 11:49:43.000000000 +0200
@@ -276,9 +276,9 @@
        int                        i2c_state, i2c_rc;
 
        /* video4linux (1) */
-       struct video_device video_dev;
-       struct video_device radio_dev;
-       struct video_device vbi_dev;
+       struct video_device *video_dev;
+       struct video_device *radio_dev;
+       struct video_device *vbi_dev;
 
        /* locking */
        spinlock_t s_lock;


--
video4linux-list mailing list
Unsubscribe mailto:[EMAIL PROTECTED]
https://www.redhat.com/mailman/listinfo/video4linux-list

Reply via email to