101#define ENOTSUP_MORONIC_SPECIFICATION \
102 __einfo_error ( EINFO_ENOTSUP_MORONIC_SPECIFICATION )
103#define EINFO_ENOTSUP_MORONIC_SPECIFICATION \
104 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, \
105 "EFI_USB_IO_PROTOCOL was designed by morons" )
162 for ( i = 0 ; i < func->
desc.
count ; i++ ) {
171 DBGC ( usbio,
"USBIO %s cannot find interface for %s",
194 assert ( interface < usbio->config->interfaces );
210 &intf->
handle ) ) != 0 ) {
212 DBGC ( usbio,
"USBIO %s could not locate ",
214 DBGC ( usbio,
"%s: %s\n",
221 DBGC ( usbio,
"USBIO %s located incomplete ",
230 &intf->
io ) ) != 0 ) {
231 DBGC ( usbio,
"USBIO %s cannot open ",
233 DBGC ( usbio,
"%s: %s\n",
256 assert ( interface < usbio->config->interfaces );
317 unsigned int recipient;
327 if ( endpoint->
cons == endpoint->
prod )
337 DBGC ( usbio,
"USBIO %s %s non-message transfer\n",
340 goto err_not_message;
379 DBGC ( usbio,
"USBIO %s cannot change configuration: %s\n",
381 goto err_moronic_specification;
388 DBGC ( usbio,
"USBIO %s %s could not submit control transfer ",
390 DBGC ( usbio,
"via %s: %s (status %04x)\n",
405 err_moronic_specification:
466 if ( endpoint->
cons == endpoint->
prod )
491 DBGC2 ( usbio,
"USBIO %s %s could not submit bulk IN transfer: "
560 if ( endpoint->
cons == endpoint->
prod )
575 DBGC ( usbio,
"USBIO %s %s could not submit bulk OUT transfer: "
590 DBGC ( usbio,
"USBIO %s %s could not submit zero-length "
591 "transfer: %s (status %04x)\n",
670 DBGC ( usbio,
"USBIO %s %s dropped interrupt completion\n",
677 DBGC ( usbio,
"USBIO %s %s interrupt completion status %04x\n",
717 intr->endpoint = endpoint;
735 DBGC ( usbio,
"USBIO %s %s could not schedule interrupt "
778 unsigned int intr_index;
782 if ( endpoint->
cons == endpoint->
prod )
834 endpoint =
zalloc (
sizeof ( *endpoint ) );
867 goto err_open_interface;
870 DBGC ( usbio,
"USBIO %s %s using ",
875 if ( (
rc = endpoint->
op->
open ( endpoint ) ) != 0 )
876 goto err_open_endpoint;
884 endpoint->
op->
close ( endpoint );
910 endpoint->
op->
close ( endpoint );
916 while ( endpoint->
cons != endpoint->
prod ) {
960 unsigned int flags ) {
995 iob_pull ( iobuf,
sizeof ( *setup ) );
1028 endpoint->
op->
poll ( endpoint );
1309 DBGC (
handle,
"USB %s could not get device descriptor: "
1320 DBGC (
handle,
"USB %s could not get interface descriptor: "
1362 DBGC ( usbio,
"USB %s could not get device descriptor: "
1364 goto err_get_device_descriptor;
1371 DBGC ( usbio,
"USB %s could not get partial configuration "
1374 goto err_get_configuration_descriptor;
1392 for ( i = 0 ; i <
count ; i++ ) {
1398 msg.setup.index = 0;
1407 DBGC ( usbio,
"USB %s could not get configuration %d "
1410 goto err_control_transfer;
1419 DBGC ( usbio,
"USB %s configuration descriptor length "
1429 DBGC ( usbio,
"USB %s could not find current configuration "
1434 err_control_transfer:
1437 err_get_configuration_descriptor:
1438 err_get_device_descriptor:
1459 DBGC ( usbio,
"USBIO %s cannot open device path protocol: "
1466 if (
len <
sizeof ( *usbpath ) ) {
1467 DBGC ( usbio,
"USBIO %s underlength device path\n",
1471 usbpath = ( ( (
void * ) path ) +
len -
sizeof ( *usbpath ) );
1474 DBGC ( usbio,
"USBIO %s not a USB device path: ",
1482 if ( ! usbio->
path )
1486 sizeof ( *usbpath ) );
1509 DBGC ( usbio,
"USB %s could not get interface descriptor: "
1511 goto err_get_interface_descriptor;
1541 err_get_interface_descriptor:
1557 DBGC (
device,
"USBIO %s could not exclude drivers: %s\n",
1578 usbio =
zalloc (
sizeof ( *usbio ) );
1589 &usbio->
io ) ) != 0 ) {
1590 DBGC ( usbio,
"USBIO %s cannot open USB I/O protocol: %s\n",
1593 goto err_open_usbio;
1612 goto err_interfaces;
1617 if ( ! usbio->
bus ) {
UINT64 UINTN
Unsigned value of native width.
unsigned int UINT32
4-byte unsigned value.
#define NULL
NULL pointer (VOID *)
#define VOID
Undeclared type.
#define MSG_USB_DP
USB Device Path SubType.
#define MESSAGING_DEVICE_PATH
Messaging Device Paths.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
#define EFI_TIMEOUT
Enumeration of EFI_STATUS.
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
EFI Usb I/O Protocol as defined in UEFI specification.
USB_DEVICE_DESCRIPTOR EFI_USB_DEVICE_DESCRIPTOR
EFI_USB_DATA_DIRECTION
USB data transfer direction.
struct _EFI_USB_IO_PROTOCOL EFI_USB_IO_PROTOCOL
USB_CONFIG_DESCRIPTOR EFI_USB_CONFIG_DESCRIPTOR
USB_INTERFACE_DESCRIPTOR EFI_USB_INTERFACE_DESCRIPTOR
USB_DEVICE_REQUEST EFI_USB_DEVICE_REQUEST
struct arbelprm_rc_send_wqe rc
pseudo_bit_t value[0x00020]
#define assert(condition)
Assert a condition at run-time.
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
int efi_driver_exclude(EFI_HANDLE device, EFI_GUID *protocol)
Try to disconnect an existing EFI driver.
#define EFI_DRIVER_HARDWARE
Hardware drivers.
#define __efi_driver(order)
Declare an EFI driver.
static void * efidev_get_drvdata(struct efi_device *efidev)
Get EFI driver-private data.
static void efidev_set_drvdata(struct efi_device *efidev, void *priv)
Set EFI driver-private data.
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
EFI_GUID efi_usb_io_protocol_guid
USB I/O protocol GUID.
int efi_shutdown_in_progress
EFI shutdown is in progress.
void efi_close_by_driver(EFI_HANDLE handle, EFI_GUID *protocol)
Close protocol opened for persistent use by a driver.
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
void efi_device_info(EFI_HANDLE device, const char *prefix, struct device *dev)
Get underlying device information.
uint8_t direction
Direction.
uint8_t id
Request identifier.
uint8_t data[48]
Additional event data.
struct ena_llq_option desc
Descriptor counts.
uint8_t intr
Interrupts enabled.
#define __unused
Declare a variable or data structure as unused.
static unsigned int count
Number of entries.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
#define ENOENT
No such file or directory.
#define EINVAL
Invalid argument.
#define EXDEV
Improper link.
#define ENOMEM
Not enough space.
#define ENOTSUP
Operation not supported.
#define ECANCELED
Operation canceled.
#define ENOBUFS
No buffer space available.
u8 request[0]
List of IEs requested.
#define le16_to_cpu(value)
#define cpu_to_le16(value)
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
#define DBGC_EFI_OPENERS(...)
EFI_SYSTEM_TABLE * efi_systab
Universal Serial Bus (USB)
#define USB_ENDPOINT_DESCRIPTOR
A USB endpoint descriptor.
#define USB_ENDPOINT_ATTR_BULK
Bulk endpoint transfer type.
#define USB_INTERFACE_DESCRIPTOR
A USB interface descriptor.
#define USB_CONFIGURATION_DESCRIPTOR
A USB configuration descriptor.
#define USB_DIR_IN
Data transfer is from device to host.
static struct usb_port * usb_port(struct usb_hub *hub, unsigned int address)
Get USB port.
#define for_each_interface_descriptor(desc, config, interface)
Iterate over all configuration descriptors within an interface descriptor.
static void * usb_endpoint_get_hostdata(struct usb_endpoint *ep)
Get USB endpoint host controller private data.
static void usb_complete(struct usb_endpoint *ep, struct io_buffer *iobuf)
Complete transfer (without error)
#define for_each_config_descriptor(desc, config)
Iterate over all configuration descriptors.
static void usb_endpoint_set_hostdata(struct usb_endpoint *ep, void *priv)
Set USB endpoint host controller private data.
#define USB_ENDPOINT_ATTR_INTERRUPT
Interrupt endpoint transfer type.
static void * usb_bus_get_hostdata(struct usb_bus *bus)
Get USB bus host controller private data.
#define USB_ENDPOINT_ATTR_TYPE_MASK
Endpoint attribute transfer type mask.
@ USB_SPEED_HIGH
High speed (480Mbps)
#define USB_ENDPOINT_ATTR_CONTROL
Control endpoint transfer type.
#define USB_GET_DESCRIPTOR
Get descriptor.
#define USB_RECIP_MASK
Request recipient mask.
static void usb_set_hostdata(struct usb_device *usb, void *priv)
Set USB device host controller private data.
#define USB_EP0_ADDRESS
Control endpoint address.
static void usb_hub_set_drvdata(struct usb_hub *hub, void *priv)
Set USB hub driver private data.
#define USB_SET_CONFIGURATION
Set configuration.
static void usb_bus_set_hostdata(struct usb_bus *bus, void *priv)
Set USB bus host controller private data.
#define USB_RECIP_INTERFACE
Request recipient is an interface.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
#define iob_push(iobuf, len)
#define iob_put(iobuf, len)
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define iob_pull(iobuf, len)
uint8_t attr
Type and attributes.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
#define list_del(list)
Delete an entry from a list.
#define INIT_LIST_HEAD(list)
Initialise a list head.
#define list_add(new, head)
Add a new entry to the head of a list.
void * zalloc(size_t size)
Allocate cleared memory.
void * malloc(size_t size)
Allocate memory.
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
uint32_t end
Ending offset.
uint32_t first
First block in range.
static void(* free)(struct refcnt *refcnt))
uint16_t protocol
Protocol ID.
char * strerror(int errno)
Retrieve string representation of error number.
EFI_LOCATE_DEVICE_PATH LocateDevicePath
This protocol can be used on any device handle to obtain generic path/location information concerning...
UINT8 Type
0x01 Hardware Device Path.
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
UINT8 InterfaceNumber
USB Interface Number.
EFI_DEVICE_PATH_PROTOCOL Header
EFI_USB_IO_GET_CONFIG_DESCRIPTOR UsbGetConfigDescriptor
EFI_USB_IO_GET_INTERFACE_DESCRIPTOR UsbGetInterfaceDescriptor
EFI_USB_IO_CONTROL_TRANSFER UsbControlTransfer
EFI_USB_IO_BULK_TRANSFER UsbBulkTransfer
EFI_USB_IO_GET_DEVICE_DESCRIPTOR UsbGetDeviceDescriptor
EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER UsbAsyncInterruptTransfer
struct device * parent
Bus device.
struct list_head children
Devices attached to this device.
struct list_head siblings
Devices on the same bus.
EFI_HANDLE device
EFI device handle.
struct device dev
Generic device.
void * data
Start of data.
struct usb_hub * hub
Root hub.
A USB configuration descriptor.
uint8_t config
Configuration value.
uint8_t interfaces
Number of interfaces.
uint16_t len
Total length.
struct usb_port * port
USB port.
struct list_head functions
List of functions.
struct usb_endpoint * ep[32]
Endpoint list.
A USB endpoint descriptor.
uint8_t endpoint
Endpoint address.
struct usb_descriptor_header header
Descriptor header.
size_t mtu
Maximum transfer size.
struct usb_device * usb
USB device.
unsigned int attributes
Attributes.
unsigned int interval
Interval (in microframes)
unsigned int address
Endpoint address.
A USB function descriptor.
unsigned int count
Number of interfaces.
struct usb_device * usb
USB device.
struct usb_function_descriptor desc
Function descriptor.
uint8_t interface[0]
List of interface numbers.
struct list_head list
List of functions within this USB device.
USB host controller operations.
struct usb_bus * bus
USB bus.
struct usb_device * usb
Underlying USB device, if any.
A USB interface descriptor.
struct usb_hub * hub
USB hub.
A USB I/O protocol device.
uint8_t first
First interface number.
struct list_head endpoints
List of endpoints.
struct usb_bus * bus
USB bus.
struct usbio_interface * interface
USB I/O protocol interfaces.
struct device dev
Generic device.
EFI_HANDLE handle
EFI device handle.
USB_DEVICE_PATH * usbpath
Final component of USB device path.
struct usb_configuration_descriptor * config
Configuration descriptor.
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
EFI_USB_IO_PROTOCOL * io
USB I/O protocol.
EFI_USB_IO_PROTOCOL * io
USB I/O protocol.
EFI_HANDLE handle
EFI handle.
struct usbio_interrupt_ring * intr
Interrupt ring buffer (if applicable)
unsigned int cons
Consumer counter.
struct usb_endpoint * ep
USB endpoint.
struct io_buffer * iobuf[USBIO_RING_COUNT]
I/O buffers.
struct usbio_operations * op
USB I/O endpoint operations.
struct usbio_device * usbio
USB I/O device.
unsigned int interface
Containing interface number.
struct list_head list
List of endpoints.
unsigned int prod
Producer counter.
uint8_t flags[USBIO_RING_COUNT]
Flags.
A USB I/O protocol interface.
unsigned int count
Usage count.
EFI_USB_IO_PROTOCOL * io
USB I/O protocol.
EFI_HANDLE handle
EFI device handle.
A USB interrupt ring buffer.
struct usbio_endpoint * endpoint
USB I/O endpoint.
USB I/O endpoint operations.
void(* close)(struct usbio_endpoint *endpoint)
Close endpoint.
int(* open)(struct usbio_endpoint *endpoint)
Open endpoint.
void(* poll)(struct usbio_endpoint *endpoint)
Poll endpoint.
struct usb_driver * usb_find_driver(struct usb_function_descriptor *desc, struct usb_device_id **id)
Find USB device driver.
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging)
void unregister_usb_bus(struct usb_bus *bus)
Unregister USB bus.
int register_usb_bus(struct usb_bus *bus)
Register USB bus.
struct usb_bus * alloc_usb_bus(struct device *dev, unsigned int ports, size_t mtu, struct usb_host_operations *op)
Allocate USB bus.
void free_usb_bus(struct usb_bus *bus)
Free USB bus.
void usb_complete_err(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer (possibly with error)
static int usbio_path(struct usbio_device *usbio)
Construct device path for opening other interfaces.
static int usbio_device_address(struct usb_device *usb __unused)
Assign device address.
static int usbio_endpoint_open(struct usb_endpoint *ep)
Open endpoint.
static int usbio_supported(EFI_HANDLE handle)
Check to see if driver supports a device.
static int usbio_exclude(EFI_HANDLE device)
Exclude existing drivers.
static int usbio_endpoint_message(struct usb_endpoint *ep, struct io_buffer *iobuf)
Enqueue message transfer.
static int usbio_root_disable(struct usb_hub *hub __unused, struct usb_port *port __unused)
Disable port.
static void usbio_bulk_in_poll(struct usbio_endpoint *endpoint)
Poll bulk IN endpoint.
static void usbio_control_close(struct usbio_endpoint *endpoint __unused)
Close control endpoint.
static EFI_STATUS EFIAPI usbio_interrupt_callback(VOID *data, UINTN len, VOID *context, UINT32 status)
Interrupt endpoint callback.
static void usbio_interrupt_close(struct usbio_endpoint *endpoint)
Close interrupt endpoint.
static int usbio_endpoint_mtu(struct usb_endpoint *ep __unused)
Update MTU.
static int usbio_root_clear_tt(struct usb_hub *hub __unused, struct usb_port *port __unused, struct usb_endpoint *ep __unused)
Clear transaction translator buffer.
static int usbio_interrupt_open(struct usbio_endpoint *endpoint)
Open interrupt endpoint.
static int usbio_endpoint_enqueue(struct usb_endpoint *ep, struct io_buffer *iobuf, unsigned int flags)
Enqueue transfer.
static void usbio_root_close(struct usb_hub *hub __unused)
Close root hub.
static void usbio_close(struct usbio_device *usbio, unsigned int interface)
Close USB I/O interface.
static int usbio_interface(struct usbio_device *usbio, struct usb_endpoint *ep)
Determine endpoint interface number.
static int usbio_bus_open(struct usb_bus *bus __unused)
Open USB bus.
static void usbio_bulk_in_close(struct usbio_endpoint *endpoint __unused)
Close bulk IN endpoint.
static struct usbio_operations usbio_control_operations
Control endpoint operations.
static int usbio_device_open(struct usb_device *usb)
Open device.
static struct usbio_operations usbio_interrupt_operations
Interrupt endpoint operations.
static struct usbio_operations usbio_bulk_in_operations
Bulk endpoint operations.
static int usbio_bulk_in_open(struct usbio_endpoint *endpoint __unused)
Open bulk IN endpoint.
static int usbio_hub_open(struct usb_hub *hub)
Open hub.
static void usbio_bus_close(struct usb_bus *bus __unused)
Close USB bus.
static int usbio_root_open(struct usb_hub *hub __unused)
Open root hub.
static int usbio_start(struct efi_device *efidev)
Attach driver to device.
static int usbio_config(struct usbio_device *usbio)
Fetch configuration descriptor.
static int usbio_root_enable(struct usb_hub *hub __unused, struct usb_port *port __unused)
Enable port.
static int usbio_interfaces(struct usbio_device *usbio)
Construct interface list.
static void usbio_endpoint_poll(struct usbio_endpoint *endpoint)
Poll for completions.
static int usbio_endpoint_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int zlp)
Enqueue stream transfer.
static void usbio_interrupt_poll(struct usbio_endpoint *endpoint)
Poll interrupt endpoint.
static int usbio_root_speed(struct usb_hub *hub __unused, struct usb_port *port)
Update root hub port speed.
static int usbio_open(struct usbio_device *usbio, unsigned int interface)
Open USB I/O interface.
static void usbio_bus_poll(struct usb_bus *bus)
Poll USB bus.
static void usbio_hub_close(struct usb_hub *hub __unused)
Close hub.
static int usbio_endpoint_reset(struct usb_endpoint *ep __unused)
Reset endpoint.
static struct usbio_operations usbio_bulk_out_operations
Bulk endpoint operations.
static int usbio_control_open(struct usbio_endpoint *endpoint __unused)
Open control endpoint.
static void usbio_control_poll(struct usbio_endpoint *endpoint)
Poll control endpoint.
static void usbio_bulk_out_close(struct usbio_endpoint *endpoint __unused)
Close bulk OUT endpoint.
static void usbio_stop(struct efi_device *efidev)
Detach driver from device.
static int usbio_bulk_out_open(struct usbio_endpoint *endpoint __unused)
Open bulk OUT endpoint.
static void usbio_device_close(struct usb_device *usb __unused)
Close device.
#define ENOTSUP_MORONIC_SPECIFICATION
static void usbio_bulk_out_poll(struct usbio_endpoint *endpoint)
Poll bulk OUT endpoint.
static void usbio_endpoint_close(struct usb_endpoint *ep)
Close endpoint.
EFI_USB_IO_PROTOCOL pseudo Host Controller Interface driver.
@ USBIO_MESSAGE
This is a message transfer.
@ USBIO_ZLEN
This transfer requires zero-length packet termination.
#define USBIO_RING_COUNT
USB I/O ring buffer size.
#define USBIO_MTU
USB I/O maximum transfer size.
#define USBIO_INTR_COUNT
USB I/O interrupt ring buffer size.