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
[EMAIL PROTECTED]
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].
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]