[PATCH] v4l: oopsfix for BTTV on badly behaved PCI chipsets

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>
This commit is contained in:
Mauro Carvalho Chehab 2005-08-04 12:53:30 -07:00 committed by Linus Torvalds
parent 75eedfed3e
commit 4dcef52400
3 changed files with 32 additions and 7 deletions

View file

@ -44,6 +44,9 @@ bttv.o
push used by bttv. bttv will disable overlay push used by bttv. bttv will disable overlay
by default on this hardware to avoid crashes. by default on this hardware to avoid crashes.
With this insmod option you can override this. 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 automute=0/1 Automatically mutes the sound if there is
no TV signal, on by default. You might try no TV signal, on by default. You might try
to disable this if you have bad input signal to disable this if you have bad input signal

View file

@ -95,7 +95,7 @@ static int __devinit pvr_boot(struct bttv *btv);
static unsigned int triton1=0; static unsigned int triton1=0;
static unsigned int vsfx=0; static unsigned int vsfx=0;
static unsigned int latency = UNSET; 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 card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int pll[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"); printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
if (pcipci_fail) { if (pcipci_fail) {
printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n"); printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n");
if (UNSET == no_overlay) { if (!no_overlay) {
printk(KERN_WARNING "bttv: going to disable overlay.\n"); printk(KERN_WARNING "bttv: overlay will be disabled.\n");
no_overlay = 1; no_overlay = 1;
} else {
printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n");
} }
} }
if (UNSET != latency) if (UNSET != latency)

View 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 bttv - Bt848 frame grabber driver
@ -80,6 +80,7 @@ static unsigned int irq_iswitch = 0;
static unsigned int uv_ratio = 50; static unsigned int uv_ratio = 50;
static unsigned int full_luma_range = 0; static unsigned int full_luma_range = 0;
static unsigned int coring = 0; static unsigned int coring = 0;
extern int no_overlay;
/* API features (turn on/off stuff for testing) */ /* API features (turn on/off stuff for testing) */
static unsigned int v4l2 = 1; static unsigned int v4l2 = 1;
@ -2151,6 +2152,10 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
return 0; return 0;
} }
case V4L2_BUF_TYPE_VIDEO_OVERLAY: 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); return setup_window(fh, btv, &f->fmt.win, 1);
case V4L2_BUF_TYPE_VBI_CAPTURE: case V4L2_BUF_TYPE_VBI_CAPTURE:
retval = bttv_switch_type(fh,f->type); retval = bttv_switch_type(fh,f->type);
@ -2224,9 +2229,11 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
/* others */ /* others */
cap->type = VID_TYPE_CAPTURE| cap->type = VID_TYPE_CAPTURE|
VID_TYPE_TUNER| VID_TYPE_TUNER|
VID_TYPE_OVERLAY|
VID_TYPE_CLIPPING| VID_TYPE_CLIPPING|
VID_TYPE_SCALES; VID_TYPE_SCALES;
if (no_overlay <= 0)
cap->type |= VID_TYPE_OVERLAY;
cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth; cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight; cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
cap->minwidth = 48; cap->minwidth = 48;
@ -2302,6 +2309,11 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
struct video_window *win = arg; struct video_window *win = arg;
struct v4l2_window w2; struct v4l2_window w2;
if (no_overlay > 0) {
printk ("VIDIOCSWIN: no_overlay\n");
return -EINVAL;
}
w2.field = V4L2_FIELD_ANY; w2.field = V4L2_FIELD_ANY;
w2.w.left = win->x; w2.w.left = win->x;
w2.w.top = win->y; 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->version = BTTV_VERSION_CODE;
cap->capabilities = cap->capabilities =
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_VIDEO_OVERLAY |
V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VBI_CAPTURE |
V4L2_CAP_READWRITE | V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING; V4L2_CAP_STREAMING;
if (no_overlay <= 0)
cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
if (bttv_tvcards[btv->c.type].tuner != UNSET && if (bttv_tvcards[btv->c.type].tuner != UNSET &&
bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT) bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER; cap->capabilities |= V4L2_CAP_TUNER;
@ -3076,7 +3090,7 @@ static struct file_operations bttv_fops =
static struct video_device bttv_video_template = static struct video_device bttv_video_template =
{ {
.name = "UNSET", .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, VID_TYPE_CLIPPING|VID_TYPE_SCALES,
.hardware = VID_HARDWARE_BT848, .hardware = VID_HARDWARE_BT848,
.fops = &bttv_fops, .fops = &bttv_fops,
@ -3756,6 +3770,12 @@ static void bttv_unregister_video(struct bttv *btv)
/* register video4linux devices */ /* register video4linux devices */
static int __devinit bttv_register_video(struct bttv *btv) 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 */ /* video */
btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
if (NULL == btv->video_dev) if (NULL == btv->video_dev)