aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2013-09-23 17:28:26 -0400
committerMatt Fleming <matt.fleming@intel.com>2013-09-30 12:13:13 +0100
commitde01ebe9760456a1df02b0c1e096a1c6e9d7d714 (patch)
tree6370d23e3beef86e91cdacc1e6c247bed2808acc
parentac223941475118b1e819fe260c348559e6e81994 (diff)
downloadsyslinux-de01ebe9760456a1df02b0c1e096a1c6e9d7d714.tar.gz
syslinux-de01ebe9760456a1df02b0c1e096a1c6e9d7d714.tar.xz
syslinux-de01ebe9760456a1df02b0c1e096a1c6e9d7d714.zip
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@gmail.com>
-rw-r--r--core/fs/pxe/isr.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index af2edd3e..d0a0bf90 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)