|
@@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
33
|
33
|
#include <ipxe/netdevice.h>
|
34
|
34
|
#include <ipxe/if_ether.h>
|
35
|
35
|
#include <ipxe/ethernet.h>
|
|
36
|
+#include <ipxe/pci.h>
|
36
|
37
|
#include <ipxe/profile.h>
|
37
|
38
|
#include <undi.h>
|
38
|
39
|
#include <undinet.h>
|
|
@@ -807,6 +808,10 @@ struct undinet_irq_broken {
|
807
|
808
|
uint16_t pci_vendor;
|
808
|
809
|
/** PCI device ID */
|
809
|
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,10 +827,10 @@ struct undinet_irq_broken {
|
822
|
827
|
*/
|
823
|
828
|
static const struct undinet_irq_broken undinet_irq_broken_list[] = {
|
824
|
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
|
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,14 +841,30 @@ static const struct undinet_irq_broken undinet_irq_broken_list[] = {
|
836
|
841
|
*/
|
837
|
842
|
static int undinet_irq_is_broken ( struct device_description *desc ) {
|
838
|
843
|
const struct undinet_irq_broken *broken;
|
|
844
|
+ struct pci_device pci;
|
|
845
|
+ uint16_t subsys_vendor;
|
|
846
|
+ uint16_t subsys;
|
839
|
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
|
859
|
for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
|
842
|
860
|
sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
|
843
|
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
|
868
|
return 1;
|
848
|
869
|
}
|
849
|
870
|
}
|