aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2020-11-30 17:48:52 +0000
committerMichael Brown <mcb30@ipxe.org>2020-11-30 19:34:57 +0000
commitb6e2ea03b031b6366d2cc3b69d19508763ea1f8a (patch)
treeaab66769ba0d20fba0c25083e6afb030230491da
parent63625b43e9009833183f1921ed3753ba35d9261f (diff)
downloadipxe-b6e2ea03b031b6366d2cc3b69d19508763ea1f8a.zip
ipxe-b6e2ea03b031b6366d2cc3b69d19508763ea1f8a.tar.gz
ipxe-b6e2ea03b031b6366d2cc3b69d19508763ea1f8a.tar.bz2
[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 <mcb30@ipxe.org>
-rw-r--r--src/interface/efi/efi_veto.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/interface/efi/efi_veto.c b/src/interface/efi/efi_veto.c
index 1f7cc71..ad501f2 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 <string.h>
#include <errno.h>
#include <ipxe/settings.h>
+#include <ipxe/pci.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/DriverBinding.h>
#include <ipxe/efi/Protocol/LoadedImage.h>
@@ -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,
+ },
};
/**