[syslinux:elflink] PXE ISR: Force polling on select hardware WORKAROUND

syslinux-bot for Gene Cumm gene.cumm at gmail.com
Mon Sep 30 04:18:16 PDT 2013


Commit-ID:  de01ebe9760456a1df02b0c1e096a1c6e9d7d714
Gitweb:     http://www.syslinux.org/commit/de01ebe9760456a1df02b0c1e096a1c6e9d7d714
Author:     Gene Cumm <gene.cumm at gmail.com>
AuthorDate: Mon, 23 Sep 2013 17:28:26 -0400
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Mon, 30 Sep 2013 12:13:13 +0100

PXE ISR: Force polling on select hardware WORKAROUND

By OUI == 00:23:ae and flags == 0xdc1b, detect select hardware.

On select platforms (Dell OptiPlex 760, Dell OptiPlex 960; perhaps
more), the interrupt appears to go "deaf" after a few seconds.  By
matching MAC OUI and flags value, force polling on these select
platforms.  I'm not sure if there's any better data available that
shallow in the core.  I believe PCI IDs can be fetched with functions
from other libraries and the UUID and DMI data (the most likely to be
useful is SYSPRODUCT) is available in ldlinux.c32.

Commit message expanded with Matt Fleming's assistance

Signed-off-by: Gene Cumm <gene.cumm at gmail.com>

---
 core/fs/pxe/isr.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index af2edd3..d0a0bf9 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -18,6 +18,14 @@ static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
 static DECLARE_INIT_SEMAPHORE(pxe_poll_thread_sem, 0);
 static struct thread *pxe_thread, *poll_thread;
 
+#ifndef PXE_POLL_FORCE
+#  define PXE_POLL_FORCE 0
+#endif
+
+#ifndef PXE_POLL_BY_MODEL
+#  define PXE_POLL_BY_MODEL 1
+#endif
+
 /*
  * Note: this *must* be called with interrupts enabled.
  */
@@ -251,8 +259,20 @@ void pxe_start_isr(void)
     poll_thread = start_thread("pxe poll", 4096, POLL_THREAD_PRIORITY,
 			       pxe_poll_thread, NULL);
 
-    if (!irq ||	!(pxe_undi_iface.ServiceFlags & PXE_UNDI_IFACE_FLAG_IRQ))
+    if (!irq ||	!(pxe_undi_iface.ServiceFlags & PXE_UNDI_IFACE_FLAG_IRQ)) {
 	asm volatile("orb $1,%0" : "+m" (pxe_need_poll));
+	dprintf("pxe_start_isr: forcing pxe_need_poll\n");
+    } else if (PXE_POLL_BY_MODEL) {
+	dprintf("pxe_start_isr: trying poll by model\n");
+	int hwad = ((int)MAC[0] << 16) + ((int)MAC[1] << 8) + MAC[2];
+	dprintf("pxe_start_isr: got %06x %04x\n", hwad, pxe_undi_iface.ServiceFlags);
+	if (hwad == 0x000023ae) {
+	    if (pxe_undi_iface.ServiceFlags == 0xdc1b) {
+		asm volatile("orb $1,%0" : "+m" (pxe_need_poll));
+		dprintf("pxe_start_isr: forcing pxe_need_poll by model\n");
+	    }
+	}
+    }
 }
 
 int reset_pxe(void)


More information about the Syslinux-commits mailing list