Subject: [PATCH] Adds kernel parameter to ignore pci devices

Hello,

Some time ago, I went to freenode IRC trying to solve a hardware
imcompatible problem in Linux. I have an old computer
(k6-200Mhz/chipset sis) and a USB 1.x and 2.0 expansion PCI Card
(LG/chipset sis). Usb 1.x works fine but if usb 2.0 (ehci) is set up,
the system freezes. This happens in Linux and win98. In windows I
managed to solve this simply disabling the device. But in Linux, I
can't do that, just disabling all pci with pci=off. I tried reserve=
stuff with no luck. As the help from the friends in IRC wasn't enough,
I decided to do it my self.

This is my first patch and so must have lots of problems. I think
I must also write a description for
Documentation/kernel-parameters.txt. I'm not sure about the "flag" in
dev struct to tell that it is to be ignored. Null can't be used as the
multifunction is detected by the current device. So, I assumed that
devices with bus==null are ignored. The only alternative that I though
to not use this hack is spliting and join some other functions.
Please, feed back me. BTW, this patch really solved my problem. lspci
doesn't show the device and so all the OS. Just scanpci was able to
list the ignored device.

Please, CC to my personal email as I'm not in kernel mail list.

Luiz Andelo Daros de Luca,


This patchs adds ignore_pci= parameter to disable a pci device as
windows control panel does. This solves some hardware incompatibily in
old computers that freezes the kernel just after the device gets
configured by pci driver.

Signed-off-by: Luiz Angelo Daros de Luca <[email protected]>

---
--- linux-2.6.16.13-4/drivers/pci/probe.c.orig 2006-09-19
19:07:39.000000000 -0300
+++ linux-2.6.16.13-4/drivers/pci/probe.c 2006-09-19 19:09:21.000000000 -0300
@@ -753,6 +753,94 @@ static void pci_release_bus_bridge_dev(s
}

/*
+ * Max ignored devices
+ */
+#define MAX_IGNORED_DEVICES 10
+/*
+ * Vector with device/vendor numbers as (device<<16|vendor)
+ */
+static u32 ignore_device[MAX_IGNORED_DEVICES+1];
+
+/*
+ * Loops ignore_device checking if vendor_device matches one of the
+ * ignore_device[] elements.
+ */
+static inline u8 device_shouldbe_ignored(u32 vendor_device) {
+ u32 *device_ignored = ignore_device; //read static
+ u32 cur_ignored_device;
+
+ while ((cur_ignored_device=device_ignored[0])) {
+ if (vendor_device==cur_ignored_device)
+ return 1;
+ device_ignored++;
+ }
+ return 0;
+}
+
+/*
+ * Reads the kernel parameter ignore_device= and save
+ * the values in vector ignore_device
+ */
+static int __init ignore_device_setup (char *str)
+{
+ static int ignore_device_ptr;//=0
+ int id=0;
+
+ int vendor=0;
+ int device=0;
+
+ while (str && str[0]) {
+ /* Interpret first parameter as number */
+ if (!get_option (&str, &id)) {
+ printk(KERN_WARNING
+ "Warning: ignore_device parameter '%s' should be a number\n",
+ str);
+ return 0;
+ }
+
+ if (!vendor) {
+ vendor=id;
+ /* Check for device syntax */
+ if (str[0]==':') {
+ str++;
+ continue;
+ } else
+ break;
+ } else {
+ device=id;
+ /* Check for next entry */
+ if (str[0] == ',')
+ str++;
+ }
+
+ if (ignore_device_ptr < MAX_IGNORED_DEVICES) {
+ /* Save the ignored device information */
+ ignore_device[ignore_device_ptr++]=device<<16 | vendor;
+ /* Warns it */
+ printk(KERN_WARNING "Device %04X:%04X will be ignored\n",
+ vendor, device);
+ /* Reset vendor and device */
+ vendor=0;
+ device=0;
+ } else {
+ printk(KERN_WARNING
+ "Too many ignored devices. %04X:%04X will NOT be ignored\n",
+ vendor, device);
+ return 0;
+ }
+ }
+
+ if (vendor) {
+ printk(KERN_WARNING
+ "IGNORE_DEVICE: Invalid vendor:device parameter. Ignoring %d\n",
+ vendor);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
* Read the config data for a PCI device, sanity-check it
* and fill in the dev structure...
*/
@@ -805,6 +893,17 @@ pci_scan_device(struct pci_bus *bus, int
dev->multifunction = !!(hdr_type & 0x80);
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
+ /* Mark as ignored(dev->bus=NULL) and return. Do not allow any
+ further setups as some broken devices freezes the computer here.
+ It must return a dev to keep pci_scan_slot scanning for other
+ devices (dev->multifunction). */
+ if (device_shouldbe_ignored(l)) {
+ printk(KERN_WARNING
+ "PCI_IGNORE: Device %04X:%04X ignored as requested\n",
+ dev->vendor,dev->device);
+ dev->bus=NULL;
+ return dev;
+ }
dev->cfg_size = pci_cfg_space_size(dev);

/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
@@ -849,8 +948,11 @@ pci_scan_single_device(struct pci_bus *b
if (!dev)
return NULL;

- pci_device_add(dev, bus);
- pci_scan_msi_device(dev);
+ /* Devices with dev->bus==NULL where set to be ignored by pci_scan_device. */
+ if (dev->bus) {
+ pci_device_add(dev, bus);
+ pci_scan_msi_device(dev);
+ }

return dev;
}
@@ -1036,6 +1138,8 @@ struct pci_bus * __devinit pci_scan_bus_
}
EXPORT_SYMBOL(pci_scan_bus_parented);

+__setup("ignore_device=", ignore_device_setup);
+
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_do_scan_bus);


2006-09-19 23:37:15

by Alan

[permalink] [raw]
Subject: Re: [PATCH] Adds kernel parameter to ignore pci devices

Not sure its the way I'd approach it - in your specific case it should
be easier to just not compile in EHCI (USB 2.0) support.


2006-09-20 06:37:13

by Jarek Poplawski

[permalink] [raw]
Subject: Re: [PATCH] Adds kernel parameter to ignore pci devices

On 20-09-2006 02:01, Alan Cox wrote:
> Not sure its the way I'd approach it - in your specific case it should
> be easier to just not compile in EHCI (USB 2.0) support.

I'd dare to vote for this idea: it's good for testing
and very practical eg. for comparing performance of similar
devices like network or sound cards. Besides: ehci could
work for other devices.

Best regards,

Jarek P.

2006-09-20 10:14:51

by Alan

[permalink] [raw]
Subject: Re: [PATCH] Adds kernel parameter to ignore pci devices

Ar Mer, 2006-09-20 am 08:41 +0200, ysgrifennodd Jarek Poplawski:
> On 20-09-2006 02:01, Alan Cox wrote:
> > Not sure its the way I'd approach it - in your specific case it should
> > be easier to just not compile in EHCI (USB 2.0) support.
>
> I'd dare to vote for this idea: it's good for testing
> and very practical eg. for comparing performance of similar
> devices like network or sound cards. Besides: ehci could
> work for other devices.

In which case you'd need to specify the device to ignore by its PCI bus
address so could ignore one device but not another of the same type. Eg
pci=ignore=0:4.5


2006-09-20 11:21:57

by Jarek Poplawski

[permalink] [raw]
Subject: Re: [PATCH] Adds kernel parameter to ignore pci devices

On Wed, Sep 20, 2006 at 11:38:53AM +0100, Alan Cox wrote:
> Ar Mer, 2006-09-20 am 08:41 +0200, ysgrifennodd Jarek Poplawski:
> > On 20-09-2006 02:01, Alan Cox wrote:
> > > Not sure its the way I'd approach it - in your specific case it should
> > > be easier to just not compile in EHCI (USB 2.0) support.
> >
> > I'd dare to vote for this idea: it's good for testing
> > and very practical eg. for comparing performance of similar
> > devices like network or sound cards. Besides: ehci could
> > work for other devices.
>
> In which case you'd need to specify the device to ignore by its PCI bus
> address so could ignore one device but not another of the same type. Eg
> pci=ignore=0:4.5

If I correctly understand this as a doubt I mean doing this in grub
or lilo as boot variants.

Jarek P.

Subject: Re: [PATCH] Adds kernel parameter to ignore pci devices

Allan, disabling EHCI in kernel won't solve it cause the kernel
freezes when linux is setting up pci. This is before any device
specific driver and it is done even without any driver for that
device.

I was going to implement a way to ignore using bus+board+function but
not at this time. BTW, are the parameters name, format and debug
messages adequated to kernel's principels?


2006/9/20, Jarek Poplawski <[email protected]>:
> On Wed, Sep 20, 2006 at 11:38:53AM +0100, Alan Cox wrote:
> > Ar Mer, 2006-09-20 am 08:41 +0200, ysgrifennodd Jarek Poplawski:
> > > On 20-09-2006 02:01, Alan Cox wrote:
> > > > Not sure its the way I'd approach it - in your specific case it should
> > > > be easier to just not compile in EHCI (USB 2.0) support.
> > >
> > > I'd dare to vote for this idea: it's good for testing
> > > and very practical eg. for comparing performance of similar
> > > devices like network or sound cards. Besides: ehci could
> > > work for other devices.
> >
> > In which case you'd need to specify the device to ignore by its PCI bus
> > address so could ignore one device but not another of the same type. Eg
> > pci=ignore=0:4.5
>
> If I correctly understand this as a doubt I mean doing this in grub
> or lilo as boot variants.
>
> Jarek P.
>


--
Luiz Angelo Daros de Luca
[email protected]
ICQ: 19290419

I Know, "Where you wanted to go today",
but I decided to stop here instead!
MS Windows

2006-09-20 17:03:57

by Alan

[permalink] [raw]
Subject: Re: [PATCH] Adds kernel parameter to ignore pci devices

Ar Mer, 2006-09-20 am 13:51 -0300, ysgrifennodd Luiz Angelo Daros de
Luca:
> Allan, disabling EHCI in kernel won't solve it cause the kernel
> freezes when linux is setting up pci. This is before any device
> specific driver and it is done even without any driver for that
> device.
>
> I was going to implement a way to ignore using bus+board+function but
> not at this time. BTW, are the parameters name, format and debug
> messages adequated to kernel's principels?

I think so yes. The actual names used are a minor detail to worry about
once the code is working, neat and being submitted.

Alan