Browse Source

[undi] Include subsystem IDs in broken interrupt device check

Allow the subsystem IDs to be used when checking for PXE stacks with
broken interrupt support.

Suggested-by: Levi Hsieh <Levi.Hsieh@dell.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
d6f02c72c9
1 changed files with 27 additions and 6 deletions
  1. 27
    6
      src/arch/x86/drivers/net/undinet.c

+ 27
- 6
src/arch/x86/drivers/net/undinet.c View File

33
 #include <ipxe/netdevice.h>
33
 #include <ipxe/netdevice.h>
34
 #include <ipxe/if_ether.h>
34
 #include <ipxe/if_ether.h>
35
 #include <ipxe/ethernet.h>
35
 #include <ipxe/ethernet.h>
36
+#include <ipxe/pci.h>
36
 #include <ipxe/profile.h>
37
 #include <ipxe/profile.h>
37
 #include <undi.h>
38
 #include <undi.h>
38
 #include <undinet.h>
39
 #include <undinet.h>
807
 	uint16_t pci_vendor;
808
 	uint16_t pci_vendor;
808
 	/** PCI device ID */
809
 	/** PCI device ID */
809
 	uint16_t pci_device;
810
 	uint16_t pci_device;
811
+	/** PCI subsystem vendor ID */
812
+	uint16_t pci_subsys_vendor;
813
+	/** PCI subsystem ID */
814
+	uint16_t pci_subsys;
810
 };
815
 };
811
 
816
 
812
 /**
817
 /**
822
  */
827
  */
823
 static const struct undinet_irq_broken undinet_irq_broken_list[] = {
828
 static const struct undinet_irq_broken undinet_irq_broken_list[] = {
824
 	/* HP XX70x laptops */
829
 	/* HP XX70x laptops */
825
-	{ .pci_vendor = 0x8086, .pci_device = 0x1502 },
826
-	{ .pci_vendor = 0x8086, .pci_device = 0x1503 },
830
+	{ 0x8086, 0x1502, PCI_ANY_ID, PCI_ANY_ID },
831
+	{ 0x8086, 0x1503, PCI_ANY_ID, PCI_ANY_ID },
827
 	/* HP 745 G3 laptop */
832
 	/* HP 745 G3 laptop */
828
-	{ .pci_vendor = 0x14e4, .pci_device = 0x1687 },
833
+	{ 0x14e4, 0x1687, PCI_ANY_ID, PCI_ANY_ID },
829
 };
834
 };
830
 
835
 
831
 /**
836
 /**
836
  */
841
  */
837
 static int undinet_irq_is_broken ( struct device_description *desc ) {
842
 static int undinet_irq_is_broken ( struct device_description *desc ) {
838
 	const struct undinet_irq_broken *broken;
843
 	const struct undinet_irq_broken *broken;
844
+	struct pci_device pci;
845
+	uint16_t subsys_vendor;
846
+	uint16_t subsys;
839
 	unsigned int i;
847
 	unsigned int i;
840
 
848
 
849
+	/* Ignore non-PCI devices */
850
+	if ( desc->bus_type != BUS_TYPE_PCI )
851
+		return 0;
852
+
853
+	/* Read subsystem IDs */
854
+	pci_init ( &pci, desc->location );
855
+	pci_read_config_word ( &pci, PCI_SUBSYSTEM_VENDOR_ID, &subsys_vendor );
856
+	pci_read_config_word ( &pci, PCI_SUBSYSTEM_ID, &subsys );
857
+
858
+	/* Check for a match against the broken device list */
841
 	for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
859
 	for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
842
 			    sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
860
 			    sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
843
 		broken = &undinet_irq_broken_list[i];
861
 		broken = &undinet_irq_broken_list[i];
844
-		if ( ( desc->bus_type == BUS_TYPE_PCI ) &&
845
-		     ( desc->vendor == broken->pci_vendor ) &&
846
-		     ( desc->device == broken->pci_device ) ) {
862
+		if ( ( broken->pci_vendor == desc->vendor ) &&
863
+		     ( broken->pci_device == desc->device ) &&
864
+		     ( ( broken->pci_subsys_vendor == subsys_vendor ) ||
865
+		       ( broken->pci_subsys_vendor == PCI_ANY_ID ) ) &&
866
+		     ( ( broken->pci_subsys == subsys ) ||
867
+		       ( broken->pci_subsys == PCI_ANY_ID ) ) ) {
847
 			return 1;
868
 			return 1;
848
 		}
869
 		}
849
 	}
870
 	}

Loading…
Cancel
Save