2002-09-10 14:00:18

by Gerd Knorr

[permalink] [raw]
Subject: ignore pci devices?

Hi,

I have a small problem: Some vendor has built a PCI board which
(ab-)uses the bt848/878 chip in creative ways to do some DMA. It is
*not* a video card, thus letting the bttv driver control the card isn't
very useful and causes trouble. The card has no PCI Subsystem ID, so I
can't identify and blacklist it easily. Thus I need some way to allow
the users to tell bttv (or the kernel) to ignore that particular PCI
card.

Is there already something generic for this? Some kernel parameter
which makes pci_module_init() skip a given PCI device for example?

Another way to fix this I'm thinking about is to add a insmod option
along the lines "ignore=<bus>,<slot>" to bttv. Comments? Better idea?

Gerd

--
You can't please everybody. And usually if you _try_ to please
everybody, the end result is one big mess.
-- Linus Torvalds, 2002-04-20


2002-09-10 14:19:27

by Alan

[permalink] [raw]
Subject: Re: ignore pci devices?

On Tue, 2002-09-10 at 14:47, Gerd Knorr wrote:
> I have a small problem: Some vendor has built a PCI board which
> (ab-)uses the bt848/878 chip in creative ways to do some DMA. It is
> *not* a video card, thus letting the bttv driver control the card isn't
> very useful and causes trouble. The card has no PCI Subsystem ID, so I
> can't identify and blacklist it easily. Thus I need some way to allow
> the users to tell bttv (or the kernel) to ignore that particular PCI
> card.

Doh.. If the vendor isnt setting subsystem ids then its not valid
hardware for windows nowdays. Obvious question - what else is on that
board that might let you do the idents. We already find the USB on the
NSC SuperIO by peeking at the next device along and checking if its the
SuperIO functions 8)

2002-09-10 16:25:40

by Martin Mares

[permalink] [raw]
Subject: Re: ignore pci devices?

Hi!

> I have a small problem: Some vendor has built a PCI board which
> (ab-)uses the bt848/878 chip in creative ways to do some DMA. It is
> *not* a video card, thus letting the bttv driver control the card isn't
> very useful and causes trouble. The card has no PCI Subsystem ID, so I
> can't identify and blacklist it easily. Thus I need some way to allow
> the users to tell bttv (or the kernel) to ignore that particular PCI
> card.
>
> Is there already something generic for this? Some kernel parameter
> which makes pci_module_init() skip a given PCI device for example?

What about writing a "driver" which will just bind to a given
PCI device, so that the other drivers will see it's already handled?

Have a nice fortnight
--
Martin `MJ' Mares <[email protected]> http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
For every complex problem, there's a solution that is simple, neat and wrong.

2002-09-10 18:34:58

by Alan

[permalink] [raw]
Subject: Re: ignore pci devices?

On Tue, 2002-09-10 at 17:30, Martin Mares wrote:
> > Is there already something generic for this? Some kernel parameter
> > which makes pci_module_init() skip a given PCI device for example?
>
> What about writing a "driver" which will just bind to a given
> PCI device, so that the other drivers will see it's already handled?

pci_driver has no implicit ordering.

2002-09-10 18:36:56

by Martin Mares

[permalink] [raw]
Subject: Re: ignore pci devices?

> pci_driver has no implicit ordering.

Agreed, but I meant inserting it as a module before the other
modules.

Have a nice fortnight
--
Martin `MJ' Mares <[email protected]> http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Current root password is "p3s5vwF50". Keep secret.

2002-09-10 20:07:21

by Alan

[permalink] [raw]
Subject: Re: ignore pci devices?

On Tue, 2002-09-10 at 19:41, Martin Mares wrote:
> > pci_driver has no implicit ordering.
>
> Agreed, but I meant inserting it as a module before the other
> modules.

Which breaks the moment it meets a hotplug system

2002-09-11 10:45:23

by Gerd Knorr

[permalink] [raw]
Subject: Re: ignore pci devices?

> > can't identify and blacklist it easily. Thus I need some way to allow
> > the users to tell bttv (or the kernel) to ignore that particular PCI
> > card.
>
> Doh.. If the vendor isnt setting subsystem ids then its not valid
> hardware for windows nowdays. Obvious question - what else is on that
> board that might let you do the idents.

Well, at least nothing in PCI space. It looks just like a random,
cheap bt878 card.

> We already find the USB on the NSC SuperIO by peeking at the next
> device along and checking if its the SuperIO functions 8)

It is a PCI card you can plug into some slot, not a motherboard ...

Gerd

--
You can't please everybody. And usually if you _try_ to please
everybody, the end result is one big mess.
-- Linus Torvalds, 2002-04-20

2002-09-11 11:40:47

by Alan

[permalink] [raw]
Subject: Re: ignore pci devices?

On Wed, 2002-09-11 at 11:51, Gerd Knorr wrote:
> Well, at least nothing in PCI space. It looks just like a random,
> cheap bt878 card.

Arggh read the email properly this time 8)

If its a BT878 on a board then assuming we can't tell the difference I
guess it doesn't work mixed with tv cards. Does it work in windows
paired with a real video capture card by some cheapo cardmaker that also
doesn't set the ssid ?

2002-09-11 11:39:13

by Alan

[permalink] [raw]
Subject: Re: ignore pci devices?

On Wed, 2002-09-11 at 11:51, Gerd Knorr wrote:
> > We already find the USB on the NSC SuperIO by peeking at the next
> > device along and checking if its the SuperIO functions 8)
>
> It is a PCI card you can plug into some slot, not a motherboard ...

Yes but what other PCI devices are on that card ?

2002-09-11 12:20:29

by Gerd Knorr

[permalink] [raw]
Subject: Re: ignore pci devices?

On Tue, Sep 10, 2002 at 09:15:12PM +0100, Alan Cox wrote:
> On Tue, 2002-09-10 at 19:41, Martin Mares wrote:
> > > pci_driver has no implicit ordering.
> >
> > Agreed, but I meant inserting it as a module before the other
> > modules.
>
> Which breaks the moment it meets a hotplug system

Neverless this works fine in the non-hotplugging modular driver case,
i.e. it can be used to fix that particular bt878 card issue. Might also
be useful for testing ressource allocation error paths of PCI drivers.

Gerd

==============================[ cut here ]==============================
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/kernel.h>

MODULE_DESCRIPTION("reserve pci card ressources to make device drivers *not* touch the card");
MODULE_AUTHOR("Gerd Knorr");
MODULE_LICENSE("GPL");

static char *ignore = "none";
MODULE_PARM(ignore,"s");
static int bus = -1, slot = -1,function = -1;

static void remove(struct pci_dev *dev)
{
int i;

printk("reserve: remove device %02x:%02x.%x\n",
dev->bus->number,PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
for (i = 0;; i++) {
if (0 == pci_resource_start(dev,i))
break;
if (pci_resource_start(dev,i) < 0x10000) {
release_region(pci_resource_start(dev,i),
pci_resource_len(dev,i));
} else {
release_mem_region(pci_resource_start(dev,i),
pci_resource_len(dev,i));
}
}
return;
}

static int __devinit probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct resource *res;
int i;

if (bus != dev->bus->number ||
slot != PCI_SLOT(dev->devfn) ||
function != PCI_FUNC(dev->devfn))
return -EBUSY;

printk("reserve: probe device %02x:%02x.%x\n",
dev->bus->number,PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
for (i = 0;; i++) {
if (0 == pci_resource_start(dev,i))
break;
if (pci_resource_start(dev,i) < 0x10000) {
res = request_region(pci_resource_start(dev,i),
pci_resource_len(dev,i),
"reserve");
printk("reserve: ... io at %lx size %lx [%s]\n",
pci_resource_start(dev,i),
pci_resource_len(dev,i),
res ? "ok" : "failed");
if (!res)
goto busy;
} else {
res = request_mem_region(pci_resource_start(dev,i),
pci_resource_len(dev,i),
"reserve");
printk("reserve: ... mem at %lx size %lx [%s]\n",
pci_resource_start(dev,i),
pci_resource_len(dev,i),
res ? "ok" : "failed");
if (!res)
goto busy;
}
}
return 0;

busy:
i--;
while (i >= 0) {
if (pci_resource_start(dev,i) < 0x10000) {
release_region(pci_resource_start(dev,i),
pci_resource_len(dev,i));
} else {
release_mem_region(pci_resource_start(dev,i),
pci_resource_len(dev,i));
}
}
return -EBUSY;
}

static struct pci_device_id pci_tbl[] __devinitdata = {
{
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ /* end of list */}
};

MODULE_DEVICE_TABLE(pci, pci_tbl);

static struct pci_driver pci_driver = {
name: "reserve",
id_table: pci_tbl,
probe: probe,
remove: remove,
};

static int do_init(void)
{
if (3 == sscanf(ignore,"%x:%x.%x",&bus,&slot,&function)) {
/* nothing */;
} else if (2 == sscanf(ignore,"%x.%x",&slot,&function)) {
bus = 0;
} else if (2 == sscanf(ignore,"%x:%x",&bus,&slot)) {
function = 0;
} else if (1 == sscanf(ignore,"%x",&slot)) {
bus = 0;
function = 0;
} else {
printk("reserve: can't parse ignore=<device> insmod option\n");
return -EINVAL;
}
printk("reserve: ignore=\"%s\" -> using device %02x:%02x.%x\n",
ignore,bus,slot,function);
return pci_module_init(&pci_driver);
}

static void do_fini(void)
{
pci_unregister_driver(&pci_driver);
}

module_init(do_init);
module_exit(do_fini);

/*
* Local variables:
* c-basic-offset: 8
* End:
*/

2002-09-11 12:29:53

by Alan

[permalink] [raw]
Subject: Re: ignore pci devices?

On Wed, 2002-09-11 at 13:20, Gerd Knorr wrote:
> Neverless this works fine in the non-hotplugging modular driver case,
> i.e. it can be used to fix that particular bt878 card issue. Might also
> be useful for testing ressource allocation error paths of PCI drivers.

Up until 2.4.20pre6 they are broken in the PCI core. IDE found that one
out.


The reserve module is an interesting approach though. I had been
pondering doing a rename module for some similar purposes but completely
missed that one.

BTW we have pci_request_resource stuff that would shrink your module a
fair bit

2002-09-11 12:50:24

by Gerd Knorr

[permalink] [raw]
Subject: Re: ignore pci devices?

On Wed, Sep 11, 2002 at 12:48:58PM +0100, Alan Cox wrote:
> On Wed, 2002-09-11 at 11:51, Gerd Knorr wrote:
> > Well, at least nothing in PCI space. It looks just like a random,
> > cheap bt878 card.
>
> Arggh read the email properly this time 8)
>
> If its a BT878 on a board then assuming we can't tell the difference I
> guess it doesn't work mixed with tv cards. Does it work in windows
> paired with a real video capture card by some cheapo cardmaker that also
> doesn't set the ssid ?

Don't know, Cc:'ed the owner of the card. Currently it is paired with
another bt878 grabber card which has a PCI Subsystem ID.

The windows driver's I've seen so far do check the ssid, althrough some
handle it better than others: The (old) Hauppauge drivers I have become
greatly confused if they find a card with a unknown ssid. Maybe that is
fixed by now. The Terratec Windows drivers just pick the card they know
about and ignore the other one as they should. Don't know what the
generic/reference/cheapo-card drivers do.

The problem bttv has here is that it can't simply ignore cards without
ssid because that would break all the crap^Wcheap boards out there ...

Gerd

--
You can't please everybody. And usually if you _try_ to please
everybody, the end result is one big mess.
-- Linus Torvalds, 2002-04-20

2002-09-11 15:50:33

by Gerd Knorr

[permalink] [raw]
Subject: Re: ignore pci devices?

On Wed, Sep 11, 2002 at 01:38:00PM +0100, Alan Cox wrote:
>
> Up until 2.4.20pre6 they are broken in the PCI core. IDE found that one
> out.
>
> The reserve module is an interesting approach though. I had been
> pondering doing a rename module for some similar purposes but completely
> missed that one.
>
> BTW we have pci_request_resource stuff that would shrink your module a
> fair bit

guess you mean pci_assign_resource()? Played with that one, now my
/proc/iomem file looks *ahem* intresting. Is this the bug mentioned
above?

Gerd

==============================[ cut here ]==============================
Script started on Wed Sep 11 17:33:33 2002
bogomips kraxel ~/kernel/bttv-0.7.97/driver# lspci -vs a.0
00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 11)
Subsystem: TERRATEC Electronic GmbH: Unknown device 1135
Flags: bus master, medium devsel, latency 32, IRQ 5
Memory at ce000000 (32-bit, prefetchable) [size=4K]
Capabilities: <available only to root>

bogomips kraxel ~/kernel/bttv-0.7.97/driver# insmod ./pci-reserve.o ignore=0a.0
bogomips kraxel ~/kernel/bttv-0.7.97/driver# dmesg | tail
lp0: using parport0 (polling).
nfs warning: mount version older than kernel
/dev/vmnet: open called by PID 1250 (vmnet-netifup)
/dev/vmnet: port on hub 8 successfully opened
/dev/vmnet: open called by PID 1267 (vmnet-dhcpd)
/dev/vmnet: port on hub 8 successfully opened
vmnet8: no IPv6 routers present
reserve: ignore="0a.0" -> using device 00:0a.0
reserve: probe device 00:0a.0
reserve: ... ressource at 40000000 size 1000 [ok]
bogomips kraxel ~/kernel/bttv-0.7.97/driver# cat /proc/iomem
00000000-0009efff : System RAM
0009f000-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000c7fff : Video ROM
000c8000-000cb7ff : Extension ROM
000f0000-000fffff : System ROM
00100000-3fffbfff : System RAM
00100000-001ecc3c : Kernel code
001ecc3d-0024aa5f : Kernel data
3fffc000-3fffefff : ACPI Tables
3ffff000-3fffffff : ACPI Non-volatile Storage
40000000-40000fff : Brooktree Corporation Bt878 Video Capture
ca000000-ca0000ff : LSI Logic / Symbios Logic (formerly NCR) 53c810
ca800000-ca8003ff : Philips Semiconductors SAA7134 (#2)
cb000000-cb0000ff : Lite-On Communications Inc LNE100TX
cb000000-cb0000ff : tulip
cb800000-cb8003ff : Philips Semiconductors SAA7134
cc000000-cd6fffff : PCI Bus #01
cc000000-cc7fffff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : matroxfb MMIO
cd800000-cd800fff : Brooktree Corporation Bt878 Audio Capture
40000000-40000fff : Brooktree Corporation Bt878 Video Capture
ca000000-ca0000ff : LSI Logic / Symbios Logic (formerly NCR) 53c810
ca800000-ca8003ff : Philips Semiconductors SAA7134 (#2)
cb000000-cb0000ff : Lite-On Communications Inc LNE100TX
cb000000-cb0000ff : tulip
cb800000-cb8003ff : Philips Semiconductors SAA7134
cc000000-cd6fffff : PCI Bus #01
cc000000-cc7fffff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : matroxfb MMIO
cd800000-cd800fff : Brooktree Corporation Bt878 Audio Capture
40000000-40000fff : Brooktree Corporation Bt878 Video Capture
ca000000-ca0000ff : LSI Logic / Symbios Logic (formerly NCR) 53c810
ca800000-ca8003ff : Philips Semiconductors SAA7134 (#2)
cb000000-cb0000ff : Lite-On Communications Inc LNE100TX
cb000000-cb0000ff : tulip
cb800000-cb8003ff : Philips Semiconductors SAA7134
cc000000-cd6fffff : PCI Bus #01
cc000000-cc7fffff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : matroxfb MMIO
cd800000-cd800fff : Brooktree Corporation Bt878 Audio Capture
40000000-40000fff : Brooktree Corporation Bt878 Video Capture
ca000000-ca0000ff : LSI Logic / Symbios Logic (formerly NCR) 53c810
ca800000-ca8003ff : Philips Semiconductors SAA7134 (#2)
cb000000-cb0000ff : Lite-On Communications Inc LNE100TX
cb000000-cb0000ff : tulip
cb800000-cb8003ff : Philips Semiconductors SAA7134
cc000000-cd6fffff : PCI Bus #01
cc000000-cc7fffff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : matroxfb MMIO
cd800000-cd800fff : Brooktree Corporation Bt878 Audio Capture
40000000-40000fff : Brooktree Corporation Bt878 Video Capture
ca000000-ca0000ff : LSI Logic / Symbios Logic (formerly NCR) 53c810
ca800000-ca8003ff : Philips Semiconductors SAA7134 (#2)
cb000000-cb0000ff : Lite-On Communications Inc LNE100TX
cb000000-cb0000ff : tulip
cb800000-cb8003ff : Philips Semiconductors SAA7134
cc000000-cd6fffff : PCI Bus #01
cc000000-cc7fffff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : matroxfb MMIO
cd800000-cd800fff : Brooktree Corporation Bt878 Audio Capture
40000000-40000fff : Brooktree Corporation Bt878 Video Capture
ca000000-ca0000ff : LSI Logic / Symbios Logic (formerly NCR) 53c810
ca800000-ca8003ff : Philips Semiconductors SAA7134 (#2)
cb000000-cb0000ff : Lite-On Communications Inc LNE100TX
cb000000-cb0000ff : tulip
cb800000-cb8003ff : Philips Semiconductors SAA7134
cc000000-cd6fffff : PCI Bus #01
cc000000-cc7fffff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : Matrox Graphics, Inc. MGA G200 AGP
cc800000-cc803fff : matroxfb MMIO
cd800000-cd800fff : Brooktree Corporation Bt878 Audio Capture
40000000-40000fff : Brooktree Corporation Bt878 Video Capture
ca000000-ca0000ff : LSI Logic / Symbios Logic (formerly NCR) 53c810
ca800000-ca8003ff : Philips Semiconductors SAA7134 (#2)
cb000000-cb0000ff : Lite-On Communications Inc LNE100TX
cb000000-cb0000ff : tulip
bogomips kraxel ~/kernel/bttv-0.7.97/driver#

Script done on Wed Sep 11 17:34:56 2002
==============================[ cut here ]==============================
/*
* pci-reserve.c -- reserve pci device resources to make device \
* drivers *not* touch the card
*
* (c) 2002 Gerd Knorr <[email protected]>
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/kernel.h>

MODULE_DESCRIPTION("reserve pci device resources to make device drivers *not* touch the card");
MODULE_AUTHOR("Gerd Knorr");
MODULE_LICENSE("GPL");

static char *ignore = "none";
static int bus = -1, slot = -1,function = -1;
MODULE_PARM(ignore,"s");

#ifndef MODULE
static int __init setup(char *str) { ignore = str; return 0; }
__setup("pci-reserve.ignore=", setup);
#endif

static int __devinit probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
int i,rc;

if (bus != dev->bus->number ||
slot != PCI_SLOT(dev->devfn) ||
function != PCI_FUNC(dev->devfn))
return -EBUSY;

printk("reserve: probe device %02x:%02x.%x\n",
dev->bus->number,PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
for (i = 0;; i++) {
if (0 == pci_resource_start(dev,i))
break;
rc = pci_assign_resource(dev,i);
printk("reserve: ... ressource at %lx size %lx [%s]\n",
pci_resource_start(dev,i),
pci_resource_len(dev,i),
rc ? "failed" : "ok");
if (rc)
return -EBUSY;
}
return 0;
}

static struct pci_device_id pci_tbl[] __devinitdata = {
{
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ /* end of list */}
};

MODULE_DEVICE_TABLE(pci, pci_tbl);

static struct pci_driver pci_driver = {
.name = "reserve",
.id_table = pci_tbl,
.probe = probe,
};

static int parse(char *id, int *b, int *s, int *f)
{
if (3 == sscanf(id,"%x:%x.%x",b,s,f)) {
/* nothing */;
} else if (2 == sscanf(id,"%x.%x",s,f)) {
*b = 0;
} else if (2 == sscanf(id,"%x:%x",b,s)) {
*f= 0;
} else if (1 == sscanf(id,"%x",s)) {
*b = 0; *f= 0;
} else {
printk("reserve: can't parse \"%s\"\n",id);
return -1;
}
return 0;
}

static int do_init(void)
{
if (parse(ignore,&bus,&slot,&function) < 0)
return -EINVAL;
printk("reserve: ignore=\"%s\" -> using device %02x:%02x.%x\n",
ignore,bus,slot,function);
return pci_module_init(&pci_driver);
}

static void do_fini(void)
{
pci_unregister_driver(&pci_driver);
}

module_init(do_init);
module_exit(do_fini);

/*
* Local variables:
* c-basic-offset: 8
* End:
*/

2002-09-11 16:17:19

by Alan

[permalink] [raw]
Subject: Re: ignore pci devices?

On Wed, 2002-09-11 at 16:37, Gerd Knorr wrote:
> guess you mean pci_assign_resource()? Played with that one, now my
> /proc/iomem file looks *ahem* intresting. Is this the bug mentioned
> above?

Well I've not seen it appear that way but I guess it could do - the old
code on finding a clash when reserving PCI resources (and you'll tickle
that anyway with pci_module_init and two candidate drivers) freed
resources it never allocated.

I'd have expected lots of printks first