Re: PCI scan problems in 2.2.16

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jul 20, 2000 at 10:45:42AM -0400, Dennis wrote:
> Ah, finally some useful info!
> 
> >I have patch for 2.4.x which adds 'pciorder=' option to kernel, so
> >I can swap my two bttv interfaces with 'pciorder=0:0b.0,0:0a.0' or
> >'pciorder=0:0a.0,0:0b.0'. 
> >
> >b) or you can order only devices  driven by one driver and ordering 
> >between different drivers is derived from link order (this one is ACPI 
> >compatible, but you cannot swap 3Com with Tulip...) (2.2.x can support 
> >only this way; some non-hotplug drivers does not support this and always
> >search for devices in chip type order, not in bus order).
> 
> Im running 2.2.16, and 2.4 is not an option. You say your patch is for 2.4,
> so what needs to be done to get the eepro100 driver to scan in the desired
> way with 2 of the same cards? Im not concerned about different drivers at
> this point.

Patch below does reordering. Unfortunately, eepro100 driver uses chip-type
based ordering and not slot based, so if on-board chip type differs from
plugged-in chip type, you are out of bussiness... In eepro100_init there
is 

   for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
      ...
         if (pcibios_find_device(pci_tbl[chip_idx].vendor_id, ....) {
             pdev = pci_find_slot(pci_bus, pci_device_fn);
             ... /* work with pdev */
         }
   }

You must rewrite it in form:

   for (pdev = pci_devices; pdev; pdev = pdev->next) {
       for (chip_idx = 0; pci_tbl[chip_idx].name; chip_idx++) {
           if (pdev->vendor == pci_tbl[chip_idx].vendor_id &&
               pdev->device == pci_tbl[chip_idx].device_id) {
                  ... /* work with pdev */
           }
       }
   }

so that bus ordering really matters. This change is not part of patch,
as I cannot test such change myself. Patch applies cleanly to 2.2.17-pre13.

[for networking driver you may want to use 2.4.0 driver + kcompat24 module,
this combination will work correctly with pciorder patch]

--------- 8< ---------
diff -urdN linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- linux/drivers/pci/pci.c	Wed Jun  7 21:26:43 2000
+++ linux/drivers/pci/pci.c	Thu Jul 20 16:15:46 2000
@@ -43,6 +43,20 @@
 	return dev;
 }
 
+static struct pci_dev *
+pci_find_slot_and_remove(unsigned int bus, unsigned int devfn)
+{
+	struct pci_dev *dev;
+	struct pci_dev **last;
+	
+	for(last = &pci_devices; (dev = *last) != NULL; last = &dev->next) {
+		if (dev->bus->number == bus && dev->devfn == devfn) {
+			*last = dev->next;
+			return dev;
+		}
+	}
+	return NULL;
+}
 
 struct pci_dev *
 pci_find_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
@@ -57,6 +71,10 @@
 }
 
 
+#define PCIORDER_MAX_SLOTS	16
+static u32 pciorder_array[PCIORDER_MAX_SLOTS];
+static u32 *pciorder_used = pciorder_array;
+
 struct pci_dev *
 pci_find_class(unsigned int class, struct pci_dev *from)
 {
@@ -436,6 +454,28 @@
 	return b;
 }
 
+__initfunc(static void pciorder_sort(void))
+{
+	struct pci_dev *dev;
+	u32 *pciorder;
+	struct pci_dev *sorted_devices;
+	struct pci_dev **last_dev = &sorted_devices;
+
+	DBG(KERN_DEBUG "PCI: Sorting device list...\n");
+	for (pciorder = pciorder_array; pciorder < pciorder_used; pciorder++) {
+		dev = pci_find_slot_and_remove(*pciorder >> 16, *pciorder & 0xFFFF);
+		if (dev) {
+			*last_dev = dev;
+			last_dev = &dev->next;
+		} else {
+			DBG(KERN_DEBUG "PCI device at %X:%02X.%X was not found\n", 
+				*pciorder >> 16, (*pciorder >> 3) & 0x1FFF, *pciorder & 7);
+		}
+	}
+	*last_dev = pci_devices;
+	pci_devices = sorted_devices;
+}
+
 __initfunc(void pci_init(void))
 {
 	pcibios_init();
@@ -457,6 +497,8 @@
 	pci_quirks_init();
 #endif
 
+	pciorder_sort();
+
 #ifdef CONFIG_PROC_FS
 	pci_proc_init();
 #endif
@@ -475,4 +517,28 @@
 		}
 		str = k;
 	}
+}
+
+__initfunc(void pciorder_setup(char *str, int *ints))
+{
+	u32 bus;
+	u32 node;
+	
+	do {
+		bus = simple_strtoul(str, &str, 16);
+		if (*str != ':') {
+			printk(KERN_INFO "Missing : in pciorder=\n");
+			return;
+		}
+		node = simple_strtoul(str + 1, &str, 16);
+		if (*str == '.') {
+			u32 fn;
+		
+			fn = simple_strtoul(str + 1, &str, 16);
+			node = (node << 3) | fn;
+		}
+		*pciorder_used++ = (bus << 16) | node;
+		DBG(KERN_DEBUG "pciorder=%X:%02X.%X\n", bus, node >> 3, node & 7);
+	} while (*str++ == ',' && pciorder_used < pciorder_array + PCIORDER_MAX_SLOTS);
+	return;
 }
diff -urdN linux/include/linux/pci.h linux/include/linux/pci.h
--- linux/include/linux/pci.h	Wed Jul 19 21:37:01 2000
+++ linux/include/linux/pci.h	Thu Jul 20 15:56:46 2000
@@ -1334,6 +1334,7 @@
 
 void pci_init(void);
 void pci_setup(char *str, int *ints);
+void pciorder_setup(char *str, int *ints);
 void pci_quirks_init(void);
 unsigned int pci_scan_bus(struct pci_bus *bus);
 struct pci_bus *pci_scan_peer_bridge(int bus);
diff -urdN linux/init/main.c linux/init/main.c
--- linux/init/main.c	Wed Jul 19 21:37:01 2000
+++ linux/init/main.c	Thu Jul 20 15:54:18 2000
@@ -1062,6 +1062,7 @@
 #endif
 #ifdef CONFIG_PCI
 	{ "pci=", pci_setup },
+	{ "pciorder=", pciorder_setup },
 #endif
 #ifdef CONFIG_PARIDE_PD
 	{ "pd.", pd_setup },
---------- 8< -----------

With options 'pciorder=1:0,0:0c.1,0:0b.1,0:0b.0' I get following /proc/pci.
And bttv and scsi drivers correctly swapped video0/video1 and sda/sdb...
						Best regards,
							Petr Vandrovec
							vandrove@vc.cvut.cz

PCI devices found:
  Bus  1, device   0, function  0:
    VGA compatible controller: Matrox Matrox G400 (rev 4).
      Medium devsel.  Fast back-to-back capable.  IRQ 16.  Master Capable.  Latency=64.  Min Gnt=16.Max Lat=32.
      Prefetchable 32 bit memory at 0xe8000000 [0xe8000008].
      Non-prefetchable 32 bit memory at 0xe4000000 [0xe4000000].
      Non-prefetchable 32 bit memory at 0xe5000000 [0xe5000000].
  Bus  0, device  12, function  1:
    SCSI storage controller: Adaptec AIC-7895U (rev 4).
      Medium devsel.  Fast back-to-back capable.  IRQ 16.  Master Capable.  Latency=64.  Min Gnt=8.Max Lat=8.
      I/O at 0xc000 [0xc001].
      Non-prefetchable 32 bit memory at 0xec005000 [0xec005000].
  Bus  0, device  11, function  1:
    Multimedia controller: Brooktree Bt878 (rev 2).
      Medium devsel.  Fast back-to-back capable.  IRQ 19.  Master Capable.  Latency=64.  Min Gnt=4.Max Lat=255.
      Prefetchable 32 bit memory at 0xec002000 [0xec002008].
  Bus  0, device  11, function  0:
    Multimedia video controller: Brooktree Bt878 2nd Contr. (?) (rev 2).
      Medium devsel.  Fast back-to-back capable.  IRQ 19.  Master Capable.  Latency=64.  Min Gnt=16.Max Lat=40.
      Prefetchable 32 bit memory at 0xec001000 [0xec001008].
  Bus  0, device   0, function  0:
    Host bridge: Intel 440BX - 82443BX Host (rev 2).
      Medium devsel.  Master Capable.  Latency=64.  
      Prefetchable 32 bit memory at 0xe0000000 [0xe0000008].
  Bus  0, device   1, function  0:
    PCI bridge: Intel 440BX - 82443BX AGP (rev 2).
      Medium devsel.  Master Capable.  Latency=64.  Min Gnt=136.
  Bus  0, device   7, function  0:
    ISA bridge: Intel 82371AB PIIX4 ISA (rev 2).
      Medium devsel.  Fast back-to-back capable.  Master Capable.  No bursts.  
  Bus  0, device   7, function  1:
    IDE interface: Intel 82371AB PIIX4 IDE (rev 1).
      Medium devsel.  Fast back-to-back capable.  Master Capable.  Latency=64.  
      I/O at 0xf000 [0xf001].
  Bus  0, device   7, function  2:
    USB Controller: Intel 82371AB PIIX4 USB (rev 1).
      Medium devsel.  Fast back-to-back capable.  IRQ 10.  Master Capable.  Latency=64.  
      I/O at 0xa000 [0xa001].
  Bus  0, device   7, function  3:
    Bridge: Intel 82371AB PIIX4 ACPI (rev 2).
      Medium devsel.  Fast back-to-back capable.  
  Bus  0, device   8, function  0:
    Multimedia audio controller: Unknown vendor Unknown device (rev 0).
      Vendor id=125d. Device id=1969.
      Medium devsel.  Fast back-to-back capable.  IRQ 16.  Master Capable.  Latency=64.  Min Gnt=2.Max Lat=24.
      I/O at 0xa400 [0xa401].
      I/O at 0xa800 [0xa801].
      I/O at 0xac00 [0xac01].
      I/O at 0xb000 [0xb001].
      I/O at 0xb400 [0xb401].
  Bus  0, device   9, function  0:
    Ethernet controller: DEC DC21142 (rev 48).
      Medium devsel.  Fast back-to-back capable.  IRQ 17.  Master Capable.  Latency=64.  Min Gnt=20.Max Lat=40.
      I/O at 0xb800 [0xb801].
      Non-prefetchable 32 bit memory at 0xec004000 [0xec004000].
  Bus  0, device  10, function  0:
    Multimedia video controller: Brooktree Bt848 (rev 18).
      Medium devsel.  Fast back-to-back capable.  IRQ 18.  Master Capable.  Latency=64.  Min Gnt=16.Max Lat=40.
      Prefetchable 32 bit memory at 0xec000000 [0xec000008].
  Bus  0, device  12, function  0:
    SCSI storage controller: Adaptec AIC-7895U (rev 4).
      Medium devsel.  Fast back-to-back capable.  IRQ 16.  Master Capable.  Latency=64.  Min Gnt=8.Max Lat=8.
      I/O at 0xbc00 [0xbc01].
      Non-prefetchable 32 bit memory at 0xec003000 [0xec003000].
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.rutgers.edu


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux