mirror of https://github.com/ipxe/ipxe.git
[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>pull/72/merge
parent
2eef77ecc0
commit
d6f02c72c9
|
@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
#include <ipxe/netdevice.h>
|
#include <ipxe/netdevice.h>
|
||||||
#include <ipxe/if_ether.h>
|
#include <ipxe/if_ether.h>
|
||||||
#include <ipxe/ethernet.h>
|
#include <ipxe/ethernet.h>
|
||||||
|
#include <ipxe/pci.h>
|
||||||
#include <ipxe/profile.h>
|
#include <ipxe/profile.h>
|
||||||
#include <undi.h>
|
#include <undi.h>
|
||||||
#include <undinet.h>
|
#include <undinet.h>
|
||||||
|
@ -807,6 +808,10 @@ struct undinet_irq_broken {
|
||||||
uint16_t pci_vendor;
|
uint16_t pci_vendor;
|
||||||
/** PCI device ID */
|
/** PCI device ID */
|
||||||
uint16_t pci_device;
|
uint16_t pci_device;
|
||||||
|
/** PCI subsystem vendor ID */
|
||||||
|
uint16_t pci_subsys_vendor;
|
||||||
|
/** PCI subsystem ID */
|
||||||
|
uint16_t pci_subsys;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -822,10 +827,10 @@ struct undinet_irq_broken {
|
||||||
*/
|
*/
|
||||||
static const struct undinet_irq_broken undinet_irq_broken_list[] = {
|
static const struct undinet_irq_broken undinet_irq_broken_list[] = {
|
||||||
/* HP XX70x laptops */
|
/* HP XX70x laptops */
|
||||||
{ .pci_vendor = 0x8086, .pci_device = 0x1502 },
|
{ 0x8086, 0x1502, PCI_ANY_ID, PCI_ANY_ID },
|
||||||
{ .pci_vendor = 0x8086, .pci_device = 0x1503 },
|
{ 0x8086, 0x1503, PCI_ANY_ID, PCI_ANY_ID },
|
||||||
/* HP 745 G3 laptop */
|
/* HP 745 G3 laptop */
|
||||||
{ .pci_vendor = 0x14e4, .pci_device = 0x1687 },
|
{ 0x14e4, 0x1687, PCI_ANY_ID, PCI_ANY_ID },
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -836,14 +841,30 @@ static const struct undinet_irq_broken undinet_irq_broken_list[] = {
|
||||||
*/
|
*/
|
||||||
static int undinet_irq_is_broken ( struct device_description *desc ) {
|
static int undinet_irq_is_broken ( struct device_description *desc ) {
|
||||||
const struct undinet_irq_broken *broken;
|
const struct undinet_irq_broken *broken;
|
||||||
|
struct pci_device pci;
|
||||||
|
uint16_t subsys_vendor;
|
||||||
|
uint16_t subsys;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
/* Ignore non-PCI devices */
|
||||||
|
if ( desc->bus_type != BUS_TYPE_PCI )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Read subsystem IDs */
|
||||||
|
pci_init ( &pci, desc->location );
|
||||||
|
pci_read_config_word ( &pci, PCI_SUBSYSTEM_VENDOR_ID, &subsys_vendor );
|
||||||
|
pci_read_config_word ( &pci, PCI_SUBSYSTEM_ID, &subsys );
|
||||||
|
|
||||||
|
/* Check for a match against the broken device list */
|
||||||
for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
|
for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
|
||||||
sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
|
sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
|
||||||
broken = &undinet_irq_broken_list[i];
|
broken = &undinet_irq_broken_list[i];
|
||||||
if ( ( desc->bus_type == BUS_TYPE_PCI ) &&
|
if ( ( broken->pci_vendor == desc->vendor ) &&
|
||||||
( desc->vendor == broken->pci_vendor ) &&
|
( broken->pci_device == desc->device ) &&
|
||||||
( desc->device == broken->pci_device ) ) {
|
( ( broken->pci_subsys_vendor == subsys_vendor ) ||
|
||||||
|
( broken->pci_subsys_vendor == PCI_ANY_ID ) ) &&
|
||||||
|
( ( broken->pci_subsys == subsys ) ||
|
||||||
|
( broken->pci_subsys == PCI_ANY_ID ) ) ) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue