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