[PATCH] v4l: oopsfix for BTTV on badly behaved PCI chipsets
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>
Thu, 4 Aug 2005 19:53:30 +0000 (12:53 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 4 Aug 2005 20:00:54 +0000 (13:00 -0700)
no_overlay bttv parameter implemented to fix OOPS on some PCI chipsets
(like some VIA) with these behaviors:

1) If pci_quicks does identify the chip as having troubles to
   handle PCI2PCI transfers, no_overlay defaults to 1. The user may force
   it to 0, to reenable (not recommended).

2) For newer chipsets not blacklisted, no_overlay=1 is provided as a
   workaround until PCI chipset included on /drivers/pci/quirks.c

Thanks to Bodo Eggert <7eggert@gmx.de>

Signed-off-by: Michael Krufky <mkrufky@m1k.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Documentation/video4linux/bttv/Insmod-options
drivers/media/video/bttv-cards.c
drivers/media/video/bttv-driver.c

index 7bb5a50b07796f365007d86702e0bc0a56e7368b..fc94ff235ffac51f1f0079bbe673f47c3a460632 100644 (file)
@@ -44,6 +44,9 @@ bttv.o
                                push used by bttv.  bttv will disable overlay
                                by default on this hardware to avoid crashes.
                                With this insmod option you can override this.
+               no_overlay=1    Disable overlay. It should be used by broken
+                               hardware that doesn't support PCI2PCI direct
+                               transfers.
                automute=0/1    Automatically mutes the sound if there is
                                no TV signal, on by default.  You might try
                                to disable this if you have bad input signal
index 6c52fd0bb7df63ad644bfee1cd5b8e54149072d3..a97b9b958ed6d4ca3858519dec5750c6bc8198b0 100644 (file)
@@ -95,7 +95,7 @@ static int __devinit pvr_boot(struct bttv *btv);
 static unsigned int triton1=0;
 static unsigned int vsfx=0;
 static unsigned int latency = UNSET;
-static unsigned int no_overlay=-1;
+int no_overlay=-1;
 
 static unsigned int card[BTTV_MAX]   = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
 static unsigned int pll[BTTV_MAX]    = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
@@ -4296,9 +4296,11 @@ void __devinit bttv_check_chipset(void)
                printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
        if (pcipci_fail) {
                printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n");
-               if (UNSET == no_overlay) {
-                       printk(KERN_WARNING "bttv: going to disable overlay.\n");
+               if (!no_overlay) {
+                       printk(KERN_WARNING "bttv: overlay will be disabled.\n");
                        no_overlay = 1;
+               } else {
+                       printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n");
                }
        }
        if (UNSET != latency)
index 67f331eeeb19118319238b56daf40b9c7790cde5..eee9322ce21b06efb02a6bf51e2b662231983189 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-driver.c,v 1.45 2005/07/20 19:43:24 mkrufky Exp $
+    $Id: bttv-driver.c,v 1.52 2005/08/04 00:55:16 mchehab Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -80,6 +80,7 @@ static unsigned int irq_iswitch = 0;
 static unsigned int uv_ratio    = 50;
 static unsigned int full_luma_range = 0;
 static unsigned int coring      = 0;
+extern int no_overlay;
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int v4l2        = 1;
@@ -2151,6 +2152,10 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
                return 0;
        }
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                return setup_window(fh, btv, &f->fmt.win, 1);
        case V4L2_BUF_TYPE_VBI_CAPTURE:
                retval = bttv_switch_type(fh,f->type);
@@ -2224,9 +2229,11 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        /* others */
                        cap->type = VID_TYPE_CAPTURE|
                                VID_TYPE_TUNER|
-                               VID_TYPE_OVERLAY|
                                VID_TYPE_CLIPPING|
                                VID_TYPE_SCALES;
+                       if (no_overlay <= 0)
+                               cap->type |= VID_TYPE_OVERLAY;
+
                        cap->maxwidth  = bttv_tvnorms[btv->tvnorm].swidth;
                        cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
                        cap->minwidth  = 48;
@@ -2302,6 +2309,11 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                struct video_window *win = arg;
                struct v4l2_window w2;
 
+               if (no_overlay > 0) {
+                       printk ("VIDIOCSWIN: no_overlay\n");
+                       return -EINVAL;
+               }
+
                w2.field = V4L2_FIELD_ANY;
                w2.w.left    = win->x;
                w2.w.top     = win->y;
@@ -2577,10 +2589,12 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                cap->version = BTTV_VERSION_CODE;
                cap->capabilities =
                        V4L2_CAP_VIDEO_CAPTURE |
-                       V4L2_CAP_VIDEO_OVERLAY |
                        V4L2_CAP_VBI_CAPTURE |
                        V4L2_CAP_READWRITE |
                        V4L2_CAP_STREAMING;
+               if (no_overlay <= 0)
+                       cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
+
                if (bttv_tvcards[btv->c.type].tuner != UNSET &&
                    bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
                        cap->capabilities |= V4L2_CAP_TUNER;
@@ -3076,7 +3090,7 @@ static struct file_operations bttv_fops =
 static struct video_device bttv_video_template =
 {
        .name     = "UNSET",
-       .type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+       .type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
                    VID_TYPE_CLIPPING|VID_TYPE_SCALES,
        .hardware = VID_HARDWARE_BT848,
        .fops     = &bttv_fops,
@@ -3756,6 +3770,12 @@ static void bttv_unregister_video(struct bttv *btv)
 /* register video4linux devices */
 static int __devinit bttv_register_video(struct bttv *btv)
 {
+       if (no_overlay <= 0) {
+               bttv_video_template.type |= VID_TYPE_OVERLAY;
+       } else {
+               printk("bttv: Overlay support disabled.\n");
+       }
+
        /* video */
        btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
         if (NULL == btv->video_dev)