* [PATCH 1/5] efi: usb: add header for usb-efi
2026-08-12 16:36 [PATCH 0/5] Add support for USB-EFI devices in EFI Playload Fabian Pflug
@ 2026-08-12 16:36 ` Fabian Pflug
2026-08-12 16:36 ` [PATCH 2/5] usb: core: make usb_set_maxpacket_ep public Fabian Pflug
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Fabian Pflug @ 2026-08-12 16:36 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Fabian Pflug
Convert the spec in [1] to a header, that is useable for barebox.
The async headers are not defined, since it is currently not planned to
support async in addition to sync.
[1] https://uefi.org/specs/UEFI/2.11/17_Protocols_USB_Support.html
Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
include/efi/protocol/usb.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/include/efi/protocol/usb.h b/include/efi/protocol/usb.h
new file mode 100644
index 0000000000..7d30fbbcaa
--- /dev/null
+++ b/include/efi/protocol/usb.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __EFI_PROTOCOL_USB_H_
+#define __EFI_PROTOCOL_USB_H_
+
+#include <efi/types.h>
+#include <linux/usb/usb.h>
+
+enum efi_usb_data_direction {
+ EFI_USB_DATA_IN,
+ EFI_USB_DATA_OUT,
+ EFI_USB_NO_DATA
+};
+
+//
+// Error code for USB Transfer Results
+//
+#define EFI_USB_NOERROR 0x0000
+#define EFI_USB_ERR_NOTEXECUTE 0x0001
+#define EFI_USB_ERR_STALL 0x0002
+#define EFI_USB_ERR_BUFFER 0x0004
+#define EFI_USB_ERR_BABBLE 0x0008
+#define EFI_USB_ERR_NAK 0x0010
+#define EFI_USB_ERR_CRC 0x0020
+#define EFI_USB_ERR_TIMEOUT 0x0040
+#define EFI_USB_ERR_BITSTUFF 0x0080
+#define EFI_USB_ERR_SYSTEM 0x0100
+
+struct efi_usb_io_protocol {
+ efi_status_t(EFIAPI *control_transfer)(
+ struct efi_usb_io_protocol *this, struct devrequest *request,
+ enum efi_usb_data_direction direction, u32 timeout, void *data,
+ efi_uintn_t length, u32 *status);
+ efi_status_t(EFIAPI *bulk_transfer)(struct efi_usb_io_protocol *this,
+ u8 device_endpoint, void *data,
+ efi_uintn_t *length,
+ efi_uintn_t timeout, u32 *status);
+ void *usb_io_async_interrupt_transfer;
+ efi_status_t(EFIAPI *sync_interrupt_transfer)(
+ struct efi_usb_io_protocol *this, u8 device_endpoint,
+ void *data, efi_uintn_t *length, efi_uintn_t timeout,
+ u32 *status);
+ void *efi_usb_io_isochronous_transfer;
+ void *efi_usb_io_async_isochronous_transfer;
+ efi_status_t(EFIAPI *get_device_descriptor)(
+ struct efi_usb_io_protocol *this,
+ struct usb_device_descriptor *desc);
+ efi_status_t(EFIAPI *get_config_descriptor)(
+ struct efi_usb_io_protocol *this,
+ struct usb_config_descriptor *desc);
+ efi_status_t(EFIAPI *get_interface_descriptor)(
+ struct efi_usb_io_protocol *this,
+ struct usb_interface_descriptor *desc);
+ efi_status_t(EFIAPI *get_endpoint_descriptor)(
+ struct efi_usb_io_protocol *this, u8 index,
+ struct usb_endpoint_descriptor *desc);
+ efi_status_t(EFIAPI *get_string_descriptor)(
+ struct efi_usb_io_protocol *this, u16 lang_id, u8 string_id,
+ char **desc);
+ efi_status_t(EFIAPI *get_supported_languages)(
+ struct efi_usb_io_protocol *this, u16 **lang_id_table,
+ u16 *table_size);
+ efi_status_t(EFIAPI *port_reset)(struct efi_usb_io_protocol *this);
+};
+
+#endif
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 2/5] usb: core: make usb_set_maxpacket_ep public
2026-08-12 16:36 [PATCH 0/5] Add support for USB-EFI devices in EFI Playload Fabian Pflug
2026-08-12 16:36 ` [PATCH 1/5] efi: usb: add header for usb-efi Fabian Pflug
@ 2026-08-12 16:36 ` Fabian Pflug
2026-08-12 16:36 ` [PATCH 3/5] drivers: usb: host: efi: add efi io driver Fabian Pflug
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Fabian Pflug @ 2026-08-12 16:36 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Fabian Pflug
The function will be used by the efi usb driver to set the maxpackets
per endpoint.
Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
drivers/usb/core/usb.c | 12 ++----------
drivers/usb/core/usb.h | 2 ++
2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index ae87137447..ce10b71f40 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -127,16 +127,8 @@ static int usb_set_configuration(struct usb_device *dev, int configuration)
return res;
}
-/* The routine usb_set_maxpacket_ep() is extracted from the loop of routine
- * usb_set_maxpacket(), because the optimizer of GCC 4.x chokes on this routine
- * when it is inlined in 1 single routine. What happens is that the register r3
- * is used as loop-count 'i', but gets overwritten later on.
- * This is clearly a compiler bug, but it is easier to workaround it here than
- * to update the compiler (Occurs with at least several GCC 4.{1,2},x
- * CodeSourcery compilers like e.g. 2007q3, 2008q1, 2008q3 lite editions on ARM)
- */
-static void noinline
-usb_set_maxpacket_ep(struct usb_device *dev, struct usb_endpoint_descriptor *ep)
+void usb_set_maxpacket_ep(struct usb_device *dev,
+ struct usb_endpoint_descriptor *ep)
{
int b;
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 0d4f80c21d..b503e5b4a8 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -6,5 +6,7 @@ struct usb_device *usb_alloc_new_device(void);
void usb_free_device(struct usb_device *dev);
int usb_new_device(struct usb_device *dev);
void usb_remove_device(struct usb_device *dev);
+void usb_set_maxpacket_ep(struct usb_device *dev,
+ struct usb_endpoint_descriptor *ep);
#endif /* __CORE_USB_H */
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 3/5] drivers: usb: host: efi: add efi io driver
2026-08-12 16:36 [PATCH 0/5] Add support for USB-EFI devices in EFI Playload Fabian Pflug
2026-08-12 16:36 ` [PATCH 1/5] efi: usb: add header for usb-efi Fabian Pflug
2026-08-12 16:36 ` [PATCH 2/5] usb: core: make usb_set_maxpacket_ep public Fabian Pflug
@ 2026-08-12 16:36 ` Fabian Pflug
2026-08-12 16:36 ` [PATCH 4/5] efi: guid: add guid for usb host controller 2 Fabian Pflug
2026-08-12 16:36 ` [PATCH 5/5] test: x86: add test for uefi usb io Fabian Pflug
4 siblings, 0 replies; 6+ messages in thread
From: Fabian Pflug @ 2026-08-12 16:36 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Fabian Pflug
The driver is based on [1] with one "host" controller per device.
The host controller will hopefully not have any sub-devices and only
have the one root device, which functions as the only device needed and
registered for.
[1] https://uefi.org/specs/UEFI/2.11/17_Protocols_USB_Support.html#usb-driver-model
Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
drivers/usb/host/Kconfig | 11 ++
drivers/usb/host/Makefile | 1 +
drivers/usb/host/efi-io-protocol.c | 316 +++++++++++++++++++++++++++++++++++++
efi/guid.c | 1 +
include/efi/guid.h | 1 +
5 files changed, 330 insertions(+)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 58f276cdb4..66e320d163 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -22,6 +22,17 @@ config USB_EHCI_ZYNQ
help
Enable support for Zynq on-chip EHCI USB controller
+config USB_EFI_IO_PROTOCOL
+ bool "EFI USB I/O Protocol"
+ depends on EFI_PAYLOAD
+ depends on USB_HOST
+ help
+ Enable support for usb devices, initialized by the UEFI BIOS.
+ Use this with caution, as devices may afterwards have multiple drivers.
+ For example can a USB-Stick be treated as an IO Blockdevice by UEFI and
+ have a driver for it, but can also be initiated as a USB-Storage device,
+ which could lead to errors in handling the USB-Device.
+
config USB_OHCI
bool "OHCI driver"
depends on !MMU && HAS_DMA
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index cbddfbe923..4f77680fc7 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
obj-$(CONFIG_USB_OHCI) += ohci-hcd.o
obj-$(CONFIG_USB_OHCI_AT91) += ohci-at91.o
obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
+obj-$(CONFIG_USB_EFI_IO_PROTOCOL) += efi-io-protocol.o
diff --git a/drivers/usb/host/efi-io-protocol.c b/drivers/usb/host/efi-io-protocol.c
new file mode 100644
index 0000000000..bd35628f59
--- /dev/null
+++ b/drivers/usb/host/efi-io-protocol.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <efi/payload.h>
+#include <efi/payload/init.h>
+#include <efi/payload/driver.h>
+#include <efi/protocol/usb.h>
+#include <efi/error.h>
+
+#include "../core/usb.h"
+
+struct efi_usb_io_priv {
+ struct efi_usb_io_protocol *protocol;
+ struct device *dev;
+ struct usb_host host;
+};
+
+#define usb_dev_to_efi_priv(ptr) \
+ container_of(ptr->host, struct efi_usb_io_priv, host)
+
+static int efi_usb_error_check(efi_status_t efiret, int status)
+{
+ if (efiret == EFI_DEVICE_ERROR) {
+ if (status & EFI_USB_ERR_TIMEOUT)
+ return -ETIMEDOUT;
+ if (status & EFI_USB_ERR_STALL)
+ return -ETIMEDOUT;
+ if (status & EFI_USB_ERR_NAK)
+ return -EPROTO;
+ if (status & EFI_USB_ERR_BUFFER)
+ return -EINVAL;
+ if (status & EFI_USB_ERR_NOTEXECUTE)
+ return -EIO;
+ if (status & EFI_USB_ERR_BABBLE)
+ return -EIO;
+ if (status & EFI_USB_ERR_CRC)
+ return -EIO;
+ if (status & EFI_USB_ERR_BITSTUFF)
+ return -EIO;
+ if (status & EFI_USB_ERR_SYSTEM)
+ return -EIO;
+ }
+
+ if (EFI_ERROR(efiret))
+ return -efi_errno(efiret);
+
+ return 0;
+}
+
+static int efi_usb_control_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length,
+ struct devrequest *setup, int timeout)
+{
+ struct efi_usb_io_priv *priv = usb_dev_to_efi_priv(dev);
+ enum efi_usb_data_direction direction;
+ efi_status_t efiret;
+ efi_uintn_t efi_timeout = timeout;
+ u32 status;
+
+ if (usb_pipein(pipe))
+ direction = EFI_USB_DATA_IN;
+ else
+ direction = EFI_USB_DATA_OUT;
+ if (length == 0)
+ direction = EFI_USB_NO_DATA;
+
+ efiret = priv->protocol->control_transfer(priv->protocol, setup,
+ direction, efi_timeout,
+ buffer, length, &status);
+
+ dev->status = status; // dev-status is a long, status is u32
+ dev->act_len = length;
+
+ return efi_usb_error_check(efiret, status);
+}
+
+static int efi_usb_bulk_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length, int timeout)
+{
+ struct efi_usb_io_priv *priv = usb_dev_to_efi_priv(dev);
+ efi_uintn_t efi_length = length;
+ efi_status_t efiret;
+ u32 status;
+
+ u8 epnum = usb_pipeendpoint(pipe) | (usb_pipein(pipe) << 7);
+
+ efiret = priv->protocol->bulk_transfer(priv->protocol, epnum, buffer,
+ &efi_length, timeout, &status);
+
+ dev->status = status;
+ dev->act_len = efi_length;
+
+ return efi_usb_error_check(efiret, status);
+}
+
+static int efi_usb_int_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length,
+ int __always_unused interval)
+{
+ struct efi_usb_io_priv *priv = usb_dev_to_efi_priv(dev);
+ efi_status_t efiret;
+ u32 status;
+ efi_uintn_t efi_length = length;
+
+ u8 epnum = usb_pipeendpoint(pipe) | (usb_pipein(pipe) << 7);
+
+ efiret = priv->protocol->sync_interrupt_transfer(
+ priv->protocol, epnum, buffer, &efi_length, 100, &status);
+
+ dev->status = status;
+ dev->act_len = efi_length;
+
+ return efi_usb_error_check(efiret, status);
+}
+
+static int efi_get_usb_string(struct efi_usb_io_protocol *protocol, u16 lang_id,
+ int index, char *buf, size_t size)
+{
+ char *efi_name;
+ efi_status_t efiret;
+ unsigned int u, idx;
+
+ memset(buf, 0, size);
+
+ if (!index)
+ return 0;
+
+ efiret = protocol->get_string_descriptor(protocol, lang_id, index,
+ &efi_name);
+ if (EFI_ERROR(efiret))
+ return -efi_errno(efiret);
+
+ size--; /* leave room for trailing NULL char in output buffer */
+ for (idx = 0, u = 2;; u += 2) {
+ if (idx >= size)
+ break;
+ if (efi_name[u + 1]) /* high byte */
+ buf[idx++] = '?'; /* non-ASCII character */
+ else if (efi_name[u])
+ buf[idx++] = efi_name[u];
+ else
+ break;
+ }
+ buf[idx] = 0;
+
+ return 0;
+}
+
+static int create_usb_device(struct efi_usb_io_priv *priv)
+{
+ struct usb_host *host = &priv->host;
+ struct usb_device *dev;
+ efi_status_t efiret;
+ struct usb_interface *interface;
+ int err;
+ u16 *lang_ids;
+ u16 num_langs;
+
+ dev = usb_alloc_new_device();
+ dev->host = host;
+
+ dev_set_name(&dev->dev, "usb%d", dev->host->busnum);
+ dev->dev.id = DEVICE_ID_SINGLE;
+
+ efiret = priv->protocol->get_device_descriptor(priv->protocol,
+ dev->descriptor);
+ if (EFI_ERROR(efiret)) {
+ err = -efi_errno(efiret);
+ goto out_err;
+ }
+
+ switch (dev->descriptor->bMaxPacketSize0) {
+ case 8:
+ dev->maxpacketsize = PACKET_SIZE_8;
+ break;
+ case 16:
+ dev->maxpacketsize = PACKET_SIZE_16;
+ break;
+ case 32:
+ dev->maxpacketsize = PACKET_SIZE_32;
+ break;
+ case 64:
+ dev->maxpacketsize = PACKET_SIZE_64;
+ break;
+ }
+
+ // There is only the possibility to access the current active configuration
+ // and not set the configuration.
+ // https://uefi.org/specs/UEFI/2.11/17_Protocols_USB_Support.html#efi-usb-io-protocol-usbgetconfigdescriptor
+ efiret = priv->protocol->get_config_descriptor(priv->protocol,
+ &dev->config.desc);
+ if (EFI_ERROR(efiret)) {
+ err = -efi_errno(efiret);
+ goto out_err;
+ }
+
+ // UEFI has by definition only one interface per config
+ // https://uefi.org/specs/UEFI/2.11/17_Protocols_USB_Support.html#efi-usb-io-protocol-usbgetinterfacedescriptor
+ dev->config.no_of_if = 1;
+ interface = &dev->config.interface[0];
+
+ efiret = priv->protocol->get_interface_descriptor(priv->protocol,
+ &interface->desc);
+ if (EFI_ERROR(efiret)) {
+ err = -efi_errno(efiret);
+ goto out_err;
+ }
+
+ interface->no_of_ep = interface->desc.bNumEndpoints;
+
+ if (interface->no_of_ep > USB_MAXENDPOINTS) {
+ err = -EPROTO;
+ goto out_err;
+ }
+
+ for (int i = 0; i < interface->no_of_ep; i++) {
+ efiret = priv->protocol->get_endpoint_descriptor(
+ priv->protocol, i, &interface->ep_desc[i]);
+ if (EFI_ERROR(efiret))
+ return -efi_errno(efiret);
+ usb_set_maxpacket_ep(dev, &interface->ep_desc[i]);
+ }
+
+ efiret = priv->protocol->get_supported_languages(priv->protocol,
+ &lang_ids, &num_langs);
+ if (EFI_ERROR(efiret)) {
+ err = -efi_errno(efiret);
+ goto out_err;
+ }
+
+ num_langs = num_langs / sizeof(u16);
+ if (num_langs == 0) {
+ err = -EPROTO;
+ goto out_err;
+ }
+
+ dev->string_langid = lang_ids[0];
+ dev->have_langid = num_langs;
+
+ dev_info(&dev->dev, "new device: Mfr=%d, Product=%d, SerialNumber=%d\n",
+ dev->descriptor->iManufacturer, dev->descriptor->iProduct,
+ dev->descriptor->iSerialNumber);
+
+ err = efi_get_usb_string(priv->protocol, dev->string_langid,
+ dev->descriptor->iManufacturer, dev->mf,
+ sizeof(dev->mf));
+ if (err)
+ goto out_err;
+ err = efi_get_usb_string(priv->protocol, dev->string_langid,
+ dev->descriptor->iProduct, dev->prod,
+ sizeof(dev->prod));
+ if (err)
+ goto out_err;
+ err = efi_get_usb_string(priv->protocol, dev->string_langid,
+ dev->descriptor->iSerialNumber, dev->serial,
+ sizeof(dev->serial));
+ if (err)
+ goto out_err;
+
+ dev_info(&dev->dev, "Bus %03d Device %03d: ID %04x:%04x %s\n",
+ dev->host->busnum, dev->devnum, dev->descriptor->idVendor,
+ dev->descriptor->idProduct, dev->prod);
+
+ err = register_device(&dev->dev);
+ if (err) {
+ dev_err(&dev->dev, "Failed to register device: %pe\n",
+ ERR_PTR(err));
+ goto out_err;
+ }
+
+ // register as root device for host
+ host->root_dev = dev;
+
+ return 0;
+
+out_err:
+ dev_err(&dev->dev, "Failed to create UEFI-USB-IO device: %pe\n",
+ ERR_PTR(err));
+ usb_free_device(dev);
+ return err;
+}
+
+static int efi_usb_io_probe(struct efi_device *efidev)
+{
+ struct device *dev = &efidev->dev;
+ struct efi_usb_io_priv *priv;
+ struct usb_host *host;
+
+ priv = xzalloc(sizeof(*priv));
+
+ BS->handle_protocol(efidev->handle, &efi_usb_io_protocol_guid,
+ (void **)&priv->protocol);
+ if (!priv->protocol)
+ return -ENODEV;
+
+ dev->priv = priv;
+ priv->dev = dev;
+
+ // EFI has one device per probe, which now needs its own host controller,
+ // since there is no shared host controller resource.
+
+ host = &priv->host;
+ host->submit_int_msg = efi_usb_int_msg;
+ host->submit_control_msg = efi_usb_control_msg;
+ host->submit_bulk_msg = efi_usb_bulk_msg;
+ usb_register_host(host);
+
+ return create_usb_device(priv);
+}
+
+static struct efi_driver efi_usb_io_driver = {
+ .driver = {
+ .name = "efi-usb-io-protocol",
+ },
+ .probe = efi_usb_io_probe,
+ .guid = EFI_USB_IO_PROTOCOL_GUID,
+};
+device_efi_driver(efi_usb_io_driver);
diff --git a/efi/guid.c b/efi/guid.c
index 8853829d21..f438783fc1 100644
--- a/efi/guid.c
+++ b/efi/guid.c
@@ -15,6 +15,7 @@ efi_guid_t efi_null_guid = EFI_NULL_GUID;
efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
const efi_guid_t efi_guid_image_security_database = EFI_IMAGE_SECURITY_DATABASE_GUID;
efi_guid_t efi_block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
+efi_guid_t efi_usb_io_protocol_guid = EFI_USB_IO_PROTOCOL_GUID;
efi_guid_t efi_rng_protocol_guid = EFI_RNG_PROTOCOL_GUID;
efi_guid_t efi_barebox_vendor_guid = EFI_BAREBOX_VENDOR_GUID;
efi_guid_t efi_file_store_vars_guid = EFI_FILE_STORE_VARS_GUID;
diff --git a/include/efi/guid.h b/include/efi/guid.h
index 202300c74a..7d75842b04 100644
--- a/include/efi/guid.h
+++ b/include/efi/guid.h
@@ -27,6 +27,7 @@ extern efi_guid_t efi_null_guid;
extern efi_guid_t efi_global_variable_guid;
extern const efi_guid_t efi_guid_image_security_database;
extern efi_guid_t efi_block_io_protocol_guid;
+extern efi_guid_t efi_usb_io_protocol_guid;
extern efi_guid_t efi_rng_protocol_guid;
extern efi_guid_t efi_barebox_vendor_guid;
extern efi_guid_t efi_file_store_vars_guid;
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 4/5] efi: guid: add guid for usb host controller 2
2026-08-12 16:36 [PATCH 0/5] Add support for USB-EFI devices in EFI Playload Fabian Pflug
` (2 preceding siblings ...)
2026-08-12 16:36 ` [PATCH 3/5] drivers: usb: host: efi: add efi io driver Fabian Pflug
@ 2026-08-12 16:36 ` Fabian Pflug
2026-08-12 16:36 ` [PATCH 5/5] test: x86: add test for uefi usb io Fabian Pflug
4 siblings, 0 replies; 6+ messages in thread
From: Fabian Pflug @ 2026-08-12 16:36 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Fabian Pflug
Taken from https://uefi.org/specs/UEFI/2.11/17_Protocols_USB_Support.html#usb2-host-controller-protocol
Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
efi/guid.c | 1 +
include/efi/guid.h | 3 +++
2 files changed, 4 insertions(+)
diff --git a/efi/guid.c b/efi/guid.c
index f438783fc1..568e1daa7d 100644
--- a/efi/guid.c
+++ b/efi/guid.c
@@ -100,6 +100,7 @@ const char *efi_guid_string(const efi_guid_t *g)
EFI_GUID_STRING(EFI_UGA_IO_PROTOCOL_GUID, "UGA Protocol", "EFI 1.1 UGA Protocol");
EFI_GUID_STRING(EFI_PCI_IO_PROTOCOL_GUID, "PCI IO Protocol", "EFI 1.1 PCI IO Protocol");
EFI_GUID_STRING(EFI_USB_IO_PROTOCOL_GUID, "USB IO Protocol", "EFI 1.0 USB IO Protocol");
+ EFI_GUID_STRING(EFI_USB2_HC_PROTOCOL_GUID, "USB HC2 Protocol", "EFI 1.0 USB Host Protocol");
EFI_GUID_STRING(EFI_FILE_INFO_GUID, "File Info", "EFI File Info");
EFI_GUID_STRING(EFI_FILE_SYSTEM_INFO_GUID, "Filesystem Info", "EFI FileSystem Info");
EFI_GUID_STRING(EFI_FILE_SYSTEM_VOLUME_LABEL_ID, "Filesystem Volume Label ID", "EFI FileSystem Volume Label ID");
diff --git a/include/efi/guid.h b/include/efi/guid.h
index 7d75842b04..3e8cff0373 100644
--- a/include/efi/guid.h
+++ b/include/efi/guid.h
@@ -121,6 +121,9 @@ extern const efi_guid_t efi_debug_image_info_table_guid;
#define EFI_USB_IO_PROTOCOL_GUID \
EFI_GUID(0x2B2F68D6, 0x0CD2, 0x44cf, 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75)
+#define EFI_USB2_HC_PROTOCOL_GUID \
+ EFI_GUID(0x3e745226, 0x9818, 0x45b6, 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc)
+
#define EFI_FILE_INFO_GUID \
EFI_GUID( 0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 5/5] test: x86: add test for uefi usb io
2026-08-12 16:36 [PATCH 0/5] Add support for USB-EFI devices in EFI Playload Fabian Pflug
` (3 preceding siblings ...)
2026-08-12 16:36 ` [PATCH 4/5] efi: guid: add guid for usb host controller 2 Fabian Pflug
@ 2026-08-12 16:36 ` Fabian Pflug
4 siblings, 0 replies; 6+ messages in thread
From: Fabian Pflug @ 2026-08-12 16:36 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Fabian Pflug
Check, that the EFI-USB-IO controller will create a USB Network device
in barebox. The device has currently no driver, but is available
nevertheless.
Signed-off-by: Fabian Pflug <f.pflug@pengutronix.de>
---
drivers/usb/host/efi-io-protocol.c | 15 ++++++++++++---
test/x86/pc@efi_defconfig.yaml | 9 ++++++++-
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/efi-io-protocol.c b/drivers/usb/host/efi-io-protocol.c
index bd35628f59..5c6abe5114 100644
--- a/drivers/usb/host/efi-io-protocol.c
+++ b/drivers/usb/host/efi-io-protocol.c
@@ -144,6 +144,16 @@ static int efi_get_usb_string(struct efi_usb_io_protocol *protocol, u16 lang_id,
return 0;
}
+static void print_usb_device_info(struct device *dev)
+{
+ struct usb_device *usb_dev = container_of(dev, struct usb_device, dev);
+
+ dev_info(dev, "Bus %03d Device %03d: ID %04x:%04x %s\n",
+ usb_dev->host->busnum, usb_dev->devnum,
+ usb_dev->descriptor->idVendor, usb_dev->descriptor->idProduct,
+ usb_dev->prod);
+}
+
static int create_usb_device(struct efi_usb_io_priv *priv)
{
struct usb_host *host = &priv->host;
@@ -255,9 +265,8 @@ static int create_usb_device(struct efi_usb_io_priv *priv)
if (err)
goto out_err;
- dev_info(&dev->dev, "Bus %03d Device %03d: ID %04x:%04x %s\n",
- dev->host->busnum, dev->devnum, dev->descriptor->idVendor,
- dev->descriptor->idProduct, dev->prod);
+ print_usb_device_info(&dev->dev);
+ devinfo_add(&dev->dev, print_usb_device_info);
err = register_device(&dev->dev);
if (err) {
diff --git a/test/x86/pc@efi_defconfig.yaml b/test/x86/pc@efi_defconfig.yaml
index 2c077d5509..0e77d5a0eb 100644
--- a/test/x86/pc@efi_defconfig.yaml
+++ b/test/x86/pc@efi_defconfig.yaml
@@ -8,7 +8,11 @@ targets:
memory: 1024M
kernel: barebox.efi
display: qemu-default
- extra_args: '-bios OVMF.fd'
+ extra_args: >
+ -bios OVMF.fd
+ -device qemu-xhci,id=xhci
+ -device usb-net,netdev=usb0,bus=xhci.0
+ -netdev user,id=usb0
BareboxDriver:
prompt: 'barebox@[^:]+:[^ ]+ '
bootstring: 'commandline:'
@@ -16,6 +20,7 @@ targets:
features:
- pci
devices:
+ usb1: 'usb1: Bus 001 Device 000: ID 0525:a4a2 NDIS/QEMU USB Network Device'
fb0: 'Type: primary'
fbconsole0: 'Parent: fb0'
wdog0: 'Parent: efi-wdt'
@@ -25,6 +30,8 @@ targets:
acpi-APIC0: 'Signature: APIC (Multiple APIC Description Table)'
runner:
kconfig_add:
+ - CONFIG_USB_HOST=y
+ - CONFIG_USB_EFI_IO_PROTOCOL=y
- CONFIG_DRIVER_SERIAL_NS16550=y
- CONFIG_CONSOLE_ACTIVATE_FIRST=y # avoid duplicate output
images:
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread