| 
				
			 | 
			
			
				
				@@ -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
			 | 
			
			
				
				 	} 
			 |