aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2013-03-05 14:22:53 +0000
committerMichael Brown <mcb30@ipxe.org>2013-03-05 14:22:53 +0000
commit9373ca8ea2928097e41da1888280a435b54ff1e0 (patch)
tree62c8f1f4d6f2b1f7b279d4250e2120021fd8e3c0 /src/arch
parente27803e40f9134ca7c05c7bf94f3ccd9bbb8edb4 (diff)
downloadipxe-9373ca8ea2928097e41da1888280a435b54ff1e0.zip
ipxe-9373ca8ea2928097e41da1888280a435b54ff1e0.tar.gz
ipxe-9373ca8ea2928097e41da1888280a435b54ff1e0.tar.bz2
[undi] Work around specific devices with known broken interrupt behaviour
Some PXE stacks are known to claim that IRQs are supported, but then never generate interrupts. No satisfactory solution has been found to this problem; the workaround is to add the PCI vendor and device IDs to a list of devices which will be treated as simply not supporting interrupts. This is something of a hack, since it will generate false positives for identical devices with a working PXE stack (e.g. those that have been reflashed with iPXE), but it's an improvement on the current situation. Reported-by: Richard Moore <rich@richud.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/i386/drivers/net/undinet.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/arch/i386/drivers/net/undinet.c b/src/arch/i386/drivers/net/undinet.c
index 6205c80..e956b98 100644
--- a/src/arch/i386/drivers/net/undinet.c
+++ b/src/arch/i386/drivers/net/undinet.c
@@ -531,6 +531,53 @@ static struct net_device_operations undinet_operations = {
.irq = undinet_irq,
};
+/** A device with broken support for generating interrupts */
+struct undinet_irq_broken {
+ /** PCI vendor ID */
+ uint16_t pci_vendor;
+ /** PCI device ID */
+ uint16_t pci_device;
+};
+
+/**
+ * List of devices with broken support for generating interrupts
+ *
+ * Some PXE stacks are known to claim that IRQs are supported, but
+ * then never generate interrupts. No satisfactory solution has been
+ * found to this problem; the workaround is to add the PCI vendor and
+ * device IDs to this list. This is something of a hack, since it
+ * will generate false positives for identical devices with a working
+ * PXE stack (e.g. those that have been reflashed with iPXE), but it's
+ * an improvement on the current situation.
+ */
+static const struct undinet_irq_broken undinet_irq_broken_list[] = {
+ /* HP XX70x laptops */
+ { .pci_vendor = 0x8086, .pci_device = 0x1502 },
+ { .pci_vendor = 0x8086, .pci_device = 0x1503 },
+};
+
+/**
+ * Check for devices with broken support for generating interrupts
+ *
+ * @v undi UNDI device
+ * @ret irq_is_broken Interrupt support is broken; no interrupts are generated
+ */
+static int undinet_irq_is_broken ( struct undi_device *undi ) {
+ const struct undinet_irq_broken *broken;
+ unsigned int i;
+
+ for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
+ sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
+ broken = &undinet_irq_broken_list[i];
+ if ( ( undi->dev.desc.bus_type == BUS_TYPE_PCI ) &&
+ ( undi->dev.desc.vendor == broken->pci_vendor ) &&
+ ( undi->dev.desc.device == broken->pci_device ) ) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
/**
* Probe UNDI device
*
@@ -647,6 +694,11 @@ int undinet_probe ( struct undi_device *undi ) {
undinic );
undinic->hacks |= UNDI_HACK_EB54;
}
+ if ( undinet_irq_is_broken ( undi ) ) {
+ DBGC ( undinic, "UNDINIC %p forcing polling mode due to "
+ "broken interrupts\n", undinic );
+ undinic->irq_supported = 0;
+ }
/* Register network device */
if ( ( rc = register_netdev ( netdev ) ) != 0 )