aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2013-09-23 17:28:26 -0400
committerGene Cumm <gene.cumm@gmail.com>2013-09-23 17:28:26 -0400
commit2fe3a7bdd20d6fada21bd455a902c2b02f46a02d (patch)
tree9ebf56aa6d6591fc3a280459d2f2795fc8649366
parentac223941475118b1e819fe260c348559e6e81994 (diff)
downloadsyslinux-2fe3a7bdd20d6fada21bd455a902c2b02f46a02d.tar.gz
syslinux-2fe3a7bdd20d6fada21bd455a902c2b02f46a02d.tar.xz
syslinux-2fe3a7bdd20d6fada21bd455a902c2b02f46a02d.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.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index af2edd3e..bc8a6c30 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.
*/
@@ -253,6 +261,18 @@ void pxe_start_isr(void)
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)