Netboot Mailing List (by thread)

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

Fw: [PATCH] Kludge for Intel's PXE scan order



  I forward this message to netboot, since the master code is in
Etherboot. Please tell us how you feel...


(Warning: This patch is ugly.  But the issue it addresses is important.)

Many of the systems with which we will be using GRUB have multiple
Ethernet adapters.  As it happens, all of them are Intel EEPro100s
with Intel's PXE BIOS for netbooting.  Unfortunately, PXE insists on
always preferring the LOM (LAN On Motherboard), if any; it is
unable/unwilling to detect which adapter is actually connected.  Even
worse, Intel's LOMs almost always show up *last* in a PCI scan, so
GRUB never uses it.

The upshot of this is that, on a multi-adapter system, PXE insists on
loading from the motherboard port, while GRUB insists on using the
non-motherboard port.  So you can't netboot without two cables.

The below patch is the workaround I will use unless/until a better
solution is found.  It makes a special case of Intel adapters and
diskless booting; in that case, it effectively reverses the scan.

A much better solution, IMO, would be to give GRUB the ability to send
DHCP requests out on *all* adapters *simultaneously*.  The Linux
kernel does this for its boot-time DHCP support, and it's a wonderful
way to prevent headaches for users.

PS: The variable "pci_ioaddr" in pci.c seemed unused, so I removed it.


2000-06-08  Chip Salzenberg  <chip@valinux.com>

	Adjust scan order for Intel adapters under diskless boot.
	* netboot/pci.h (eth_pci_prefer_last): Declare new variable.
	* netboot/pci.c (eth_pci_prefer_last): Define it, default -1.
	(scan_bus): Compare it to each adapter's vendor; if it matches,
	then keep scanning, so the last one found will be used.
	Also tweak debugging messages.
	(pci_ioaddr): Eliminate unused variable.
	* stage2/common.c (setup_diskless_environment): Set
	eth_pci_prefer_last to PCI_VENDOR_ID_INTEL.

Index: netboot/pci.h
diff -u -2 -r1.6 pci.h
--- netboot/pci.h	2000/05/17 13:55:18	1.6
+++ netboot/pci.h	2000/06/09 01:55:48
@@ -146,4 +146,6 @@
 };
 
+extern unsigned short eth_pci_prefer_last;
+
 extern void	eth_pci_init(struct pci_device *);
 

Index: netboot/pci.c
diff -u -2 -r1.5 pci.c
--- netboot/pci.c	2000/05/31 02:15:13	1.5
+++ netboot/pci.c	2000/06/09 01:55:48
@@ -23,6 +23,7 @@
 
 /*#define	DEBUG	1*/
-static unsigned int pci_ioaddr = 0;
 
+unsigned short eth_pci_prefer_last = 0xFFFF; /* no such vendor */
+
 #ifdef	CONFIG_PCI_DIRECT
 #define  PCIBIOS_SUCCESSFUL                0x00
@@ -406,5 +407,4 @@
 	int i, reg;
 
-	pci_ioaddr = 0;
 	buses=1;
 	for (bus = 0; bus < buses; ++bus) {
@@ -430,5 +430,5 @@
 
 #if	DEBUG
-			printf("bus %x, function %x, vendor %x, device %x\n",
+			printf("bus %x, func %x: vendor %x, device %x\n",
 				bus, devfn, vendor, device);
 #endif
@@ -437,4 +437,8 @@
 				    || device != pcidev[i].dev_id)
 					continue;
+#if	DEBUG
+				printf("bus %x, func %x: '%s'\n",
+				       bus, devfn, pcidev[i].name);
+#endif
 				for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
 					pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
@@ -453,13 +457,18 @@
 						pcidev[i].name, ioaddr, romaddr);
 					/* Take the first one or the one that matches in boot ROM address */
-					if (pci_ioaddr == 0 || romaddr == ((unsigned long) rom.rom_segment << 4)) {
-						pcidev[i].membase = membase;
-						pcidev[i].ioaddr = ioaddr;
-						pcidev[i].devfn = devfn;
+					pcidev[i].membase = membase;
+					pcidev[i].ioaddr = ioaddr;
+					pcidev[i].devfn = devfn;
+
+					/* Should we prefer the last eth? */
+					if (vendor == eth_pci_prefer_last)
+						goto next_devfn;
 
-						return;
-					}
+					/* No, first one is good enough */
+					return;
 				}
 			}
+
+	    next_devfn: ;
 		}
 	}

Index: stage2/common.c
diff -u -2 -r1.12 common.c
--- stage2/common.c	2000/05/29 16:11:08	1.12
+++ stage2/common.c	2000/06/09 01:55:48
@@ -24,4 +24,5 @@
 #ifdef SUPPORT_DISKLESS
 # include <etherboot.h>
+# include <pci.h>
 #endif
 
@@ -136,4 +137,12 @@
 setup_diskless_environment (void)
 {
+  /*
+   * Intel's PXE prefers the LOM (LAN on motherboard).
+   * If we booted with PXE, then that must be the one connected.
+   * As it happens, the LOM always shows up last in sequence.
+   * So preferring the last Intel adapter found is a good strategy.
+   */
+  eth_pci_prefer_last = PCI_VENDOR_ID_INTEL;
+
   /* For now, there is no difference between BOOTP and DHCP in GRUB.  */
   if (! bootp ())

-- 
Chip Salzenberg              - a.k.a. -              <chip@valinux.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
    but he stepped in a wormhole and had to go in early."  // MST3K





For requests or suggestions regarding this mailing list archive please write to netboot@gkminix.han.de.