summaryrefslogtreecommitdiffstats
path: root/src/drivers/usb/usbio.h
diff options
context:
space:
mode:
authorMichael Brown2015-09-04 03:26:01 +0200
committerMichael Brown2015-09-07 02:38:40 +0200
commit15a8800a984239553cbbb6629e076e98a3be7537 (patch)
tree87c62eac43dc8f06224e128625d157e5cdf94fc9 /src/drivers/usb/usbio.h
parent[efi] Allow efidev_parent() to traverse multiple device generations (diff)
downloadipxe-15a8800a984239553cbbb6629e076e98a3be7537.tar.gz
ipxe-15a8800a984239553cbbb6629e076e98a3be7537.tar.xz
ipxe-15a8800a984239553cbbb6629e076e98a3be7537.zip
[efi] Add a USB host controller driver based on EFI_USB_IO_PROTOCOL
Allow iPXE to coexist with other USB device drivers, by attaching to the EFI_USB_IO_PROTOCOL instances provided by the UEFI platform firmware. The EFI_USB_IO_PROTOCOL is an unsurprisingly badly designed abstraction of a USB device. The poor design choices intrinsic in the UEFI specification prevent efficient operation as a network device, with the result that devices operated using the EFI_USB_IO_PROTOCOL operate approximately two orders of magnitude slower than devices operated using our native EHCI or xHCI host controller drivers. Since the performance is so abysmally slow, and since the underlying problems are due to fundamental architectural mistakes in the UEFI specification, support for the EFI_USB_IO_PROTOCOL host controller driver is left as disabled by default. Users are advised to use the native iPXE host controller drivers instead. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/usb/usbio.h')
-rw-r--r--src/drivers/usb/usbio.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/drivers/usb/usbio.h b/src/drivers/usb/usbio.h
new file mode 100644
index 00000000..1d02876f
--- /dev/null
+++ b/src/drivers/usb/usbio.h
@@ -0,0 +1,153 @@
+#ifndef _USBIO_H
+#define _USBIO_H
+
+/** @file
+ *
+ * EFI_USB_IO_PROTOCOL pseudo Host Controller Interface driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/list.h>
+#include <ipxe/device.h>
+#include <ipxe/efi/efi.h>
+#include <ipxe/efi/Protocol/UsbIo.h>
+#include <ipxe/efi/Protocol/DevicePath.h>
+#include <ipxe/usb.h>
+
+/** USB I/O maximum transfer size
+ *
+ * The API provides no way to discover the maximum transfer size.
+ * Assume the 16kB supported by EHCI.
+ */
+#define USBIO_MTU 16384
+
+/** USB I/O interrupt ring buffer size
+ *
+ * This is a policy decision.
+ */
+#define USBIO_INTR_COUNT 4
+
+/** A USB interrupt ring buffer */
+struct usbio_interrupt_ring {
+ /** USB I/O endpoint */
+ struct usbio_endpoint *endpoint;
+ /** Producer counter */
+ unsigned int prod;
+ /** Consumer counter */
+ unsigned int cons;
+ /** Data buffers */
+ void *data[USBIO_INTR_COUNT];
+ /** Lengths */
+ size_t len[USBIO_INTR_COUNT];
+};
+
+/** USB I/O ring buffer size
+ *
+ * This is a policy decision.
+ */
+#define USBIO_RING_COUNT 64
+
+/** A USB I/O endpoint */
+struct usbio_endpoint {
+ /** USB I/O device */
+ struct usbio_device *usbio;
+ /** USB endpoint */
+ struct usb_endpoint *ep;
+ /** List of endpoints */
+ struct list_head list;
+ /** USB I/O endpoint operations */
+ struct usbio_operations *op;
+
+ /** Containing interface number */
+ unsigned int interface;
+ /** EFI handle */
+ EFI_HANDLE handle;
+ /** USB I/O protocol */
+ EFI_USB_IO_PROTOCOL *io;
+
+ /** Producer counter */
+ unsigned int prod;
+ /** Consumer counter */
+ unsigned int cons;
+ /** I/O buffers */
+ struct io_buffer *iobuf[USBIO_RING_COUNT];
+ /** Flags */
+ uint8_t flags[USBIO_RING_COUNT];
+
+ /** Interrupt ring buffer (if applicable) */
+ struct usbio_interrupt_ring *intr;
+};
+
+/** USB I/O transfer flags */
+enum usbio_flags {
+ /** This is a message transfer */
+ USBIO_MESSAGE = 0x01,
+ /** This transfer requires zero-length packet termination */
+ USBIO_ZLEN = 0x02,
+};
+
+/** USB I/O endpoint operations */
+struct usbio_operations {
+ /** Open endpoint
+ *
+ * @v endpoint Endpoint
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct usbio_endpoint *endpoint );
+ /** Close endpoint
+ *
+ * @v endpoint Endpoint
+ */
+ void ( * close ) ( struct usbio_endpoint *endpoint );
+ /** Poll endpoint
+ *
+ * @v endpoint Endpoint
+ */
+ void ( * poll ) ( struct usbio_endpoint *endpoint );
+};
+
+/** A USB I/O protocol interface */
+struct usbio_interface {
+ /** EFI device handle */
+ EFI_HANDLE handle;
+ /** USB I/O protocol */
+ EFI_USB_IO_PROTOCOL *io;
+ /** Usage count */
+ unsigned int count;
+};
+
+/** A USB I/O protocol device
+ *
+ * We model each externally-provided USB I/O protocol device as a host
+ * controller containing a root hub with a single port.
+ */
+struct usbio_device {
+ /** EFI device handle */
+ EFI_HANDLE handle;
+ /** USB I/O protocol */
+ EFI_USB_IO_PROTOCOL *io;
+ /** Generic device */
+ struct device dev;
+
+ /** Configuration descriptor */
+ struct usb_configuration_descriptor *config;
+
+ /** Device path */
+ EFI_DEVICE_PATH_PROTOCOL *path;
+ /** Final component of USB device path */
+ USB_DEVICE_PATH *usbpath;
+
+ /** First interface number */
+ uint8_t first;
+ /** USB I/O protocol interfaces */
+ struct usbio_interface *interface;
+
+ /** USB bus */
+ struct usb_bus *bus;
+ /** List of endpoints */
+ struct list_head endpoints;
+};
+
+#endif /* _USBIO_H */