]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Veto the HP XhciDxe Driver
authorMichael Brown <mcb30@ipxe.org>
Mon, 30 Nov 2020 17:48:52 +0000 (17:48 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 30 Nov 2020 19:34:57 +0000 (19:34 +0000)
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>
src/interface/efi/efi_veto.c

index 1f7cc712e00e9ebf661badc63a89ac855156e072..ad501f26262fe2be3e0b0c1746ed55fee4cc6e97 100644 (file)
@@ -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,
+       },
 };
 
 /**