[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:
parent
75eedfed3e
commit
4dcef52400
3 changed files with 32 additions and 7 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue