From b6e2ea03b031b6366d2cc3b69d19508763ea1f8a Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 30 Nov 2020 17:48:52 +0000 Subject: [PATCH] [efi] Veto the HP XhciDxe Driver The HP XhciDxe driver (observed on an HP EliteBook 840 G6) does not respond correctly to driver disconnection, and will leave the PciIo protocol instance opened with BY_DRIVER attributes even after returning successfully from its Stop() method. This prevents iPXE from subsequently connecting to the PCI device handle. Veto this driver if the iPXE build includes a native xHCI driver. Signed-off-by: Michael Brown --- src/interface/efi/efi_veto.c | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/interface/efi/efi_veto.c b/src/interface/efi/efi_veto.c index 1f7cc712e..ad501f262 100644 --- a/src/interface/efi/efi_veto.c +++ b/src/interface/efi/efi_veto.c @@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include #include #include @@ -391,12 +392,57 @@ efi_veto_dell_ip4config ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused, return 1; } +/** + * Veto HP XhciDxe driver + * + * @v binding Driver binding protocol + * @v loaded Loaded image protocol + * @v wtf Component name protocol, if present + * @v manufacturer Manufacturer name, if present + * @v name Driver name, if present + * @ret vetoed Driver is to be vetoed + */ +static int +efi_veto_hp_xhci ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused, + EFI_LOADED_IMAGE_PROTOCOL *loaded __unused, + EFI_COMPONENT_NAME_PROTOCOL *wtf __unused, + const char *manufacturer, const CHAR16 *name ) { + static const CHAR16 xhci[] = L"Usb Xhci Driver"; + static const char *hp = "HP"; + struct pci_driver *driver; + + /* Check manufacturer and driver name */ + if ( ! manufacturer ) + return 0; + if ( ! name ) + return 0; + if ( strcmp ( manufacturer, hp ) != 0 ) + return 0; + if ( memcmp ( name, xhci, sizeof ( xhci ) ) != 0 ) + return 0; + + /* Veto driver only if we have our own xHCI driver */ + for_each_table_entry ( driver, PCI_DRIVERS ) { + if ( driver->class.class == + PCI_CLASS ( PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB, + PCI_CLASS_SERIAL_USB_XHCI ) ) { + return 1; + } + } + + return 0; +} + /** Driver vetoes */ static struct efi_veto efi_vetoes[] = { { .name = "Dell Ip4Config", .veto = efi_veto_dell_ip4config, }, + { + .name = "HP Xhci", + .veto = efi_veto_hp_xhci, + }, }; /** -- 2.47.2