lkml.org 
[lkml]   [2003]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[RFC/PATCH] 2/2 v4l: sysfs'ify bttv driver
  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;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 13:47    [W:0.110 / U:0.012 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site