diff options
author | Gene Cumm <gene.cumm@gmail.com> | 2013-09-23 17:28:26 -0400 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-09-30 12:13:13 +0100 |
commit | de01ebe9760456a1df02b0c1e096a1c6e9d7d714 (patch) | |
tree | 6370d23e3beef86e91cdacc1e6c247bed2808acc /core | |
parent | ac223941475118b1e819fe260c348559e6e81994 (diff) | |
download | syslinux-de01ebe9760456a1df02b0c1e096a1c6e9d7d714.tar.gz |
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>
Diffstat (limited to 'core')
-rw-r--r-- | core/fs/pxe/isr.c | 22 |
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) |