iPXE
usbio.c File Reference

EFI_USB_IO_PROTOCOL pseudo Host Controller Interface driver. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/Protocol/UsbIo.h>
#include <ipxe/usb.h>
#include "usbio.h"

Go to the source code of this file.

Macros

#define ENOTSUP_MORONIC_SPECIFICATION   __einfo_error ( EINFO_ENOTSUP_MORONIC_SPECIFICATION )
#define EINFO_ENOTSUP_MORONIC_SPECIFICATION

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int usbio_interface (struct usbio_device *usbio, struct usb_endpoint *ep)
 Determine endpoint interface number.
static int usbio_open (struct usbio_device *usbio, unsigned int interface)
 Open USB I/O interface.
static void usbio_close (struct usbio_device *usbio, unsigned int interface)
 Close USB I/O interface.
static int usbio_control_open (struct usbio_endpoint *endpoint __unused)
 Open control endpoint.
static void usbio_control_close (struct usbio_endpoint *endpoint __unused)
 Close control endpoint.
static void usbio_control_poll (struct usbio_endpoint *endpoint)
 Poll control endpoint.
static int usbio_bulk_in_open (struct usbio_endpoint *endpoint __unused)
 Open bulk IN endpoint.
static void usbio_bulk_in_close (struct usbio_endpoint *endpoint __unused)
 Close bulk IN endpoint.
static void usbio_bulk_in_poll (struct usbio_endpoint *endpoint)
 Poll bulk IN endpoint.
static int usbio_bulk_out_open (struct usbio_endpoint *endpoint __unused)
 Open bulk OUT endpoint.
static void usbio_bulk_out_close (struct usbio_endpoint *endpoint __unused)
 Close bulk OUT endpoint.
static void usbio_bulk_out_poll (struct usbio_endpoint *endpoint)
 Poll bulk OUT endpoint.
static EFI_STATUS EFIAPI usbio_interrupt_callback (VOID *data, UINTN len, VOID *context, UINT32 status)
 Interrupt endpoint callback.
static int usbio_interrupt_open (struct usbio_endpoint *endpoint)
 Open interrupt endpoint.
static void usbio_interrupt_close (struct usbio_endpoint *endpoint)
 Close interrupt endpoint.
static void usbio_interrupt_poll (struct usbio_endpoint *endpoint)
 Poll interrupt endpoint.
static int usbio_endpoint_open (struct usb_endpoint *ep)
 Open endpoint.
static void usbio_endpoint_close (struct usb_endpoint *ep)
 Close endpoint.
static int usbio_endpoint_reset (struct usb_endpoint *ep __unused)
 Reset endpoint.
static int usbio_endpoint_mtu (struct usb_endpoint *ep __unused)
 Update MTU.
static int usbio_endpoint_enqueue (struct usb_endpoint *ep, struct io_buffer *iobuf, unsigned int flags)
 Enqueue transfer.
static int usbio_endpoint_message (struct usb_endpoint *ep, struct io_buffer *iobuf)
 Enqueue message transfer.
static int usbio_endpoint_stream (struct usb_endpoint *ep, struct io_buffer *iobuf, int zlp)
 Enqueue stream transfer.
static void usbio_endpoint_poll (struct usbio_endpoint *endpoint)
 Poll for completions.
static int usbio_device_open (struct usb_device *usb)
 Open device.
static void usbio_device_close (struct usb_device *usb __unused)
 Close device.
static int usbio_device_address (struct usb_device *usb __unused)
 Assign device address.
static int usbio_hub_open (struct usb_hub *hub)
 Open hub.
static void usbio_hub_close (struct usb_hub *hub __unused)
 Close hub.
static int usbio_root_open (struct usb_hub *hub __unused)
 Open root hub.
static void usbio_root_close (struct usb_hub *hub __unused)
 Close root hub.
static int usbio_root_enable (struct usb_hub *hub __unused, struct usb_port *port __unused)
 Enable port.
static int usbio_root_disable (struct usb_hub *hub __unused, struct usb_port *port __unused)
 Disable port.
static int usbio_root_speed (struct usb_hub *hub __unused, struct usb_port *port)
 Update root hub port speed.
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_bus_open (struct usb_bus *bus __unused)
 Open USB bus.
static void usbio_bus_close (struct usb_bus *bus __unused)
 Close USB bus.
static void usbio_bus_poll (struct usb_bus *bus)
 Poll USB bus.
static int usbio_supported (EFI_HANDLE handle)
 Check to see if driver supports a device.
static int usbio_config (struct usbio_device *usbio)
 Fetch configuration descriptor.
static int usbio_path (struct usbio_device *usbio)
 Construct device path for opening other interfaces.
static int usbio_interfaces (struct usbio_device *usbio)
 Construct interface list.
static int usbio_exclude (EFI_HANDLE device)
 Exclude existing drivers.
static int usbio_start (struct efi_device *efidev)
 Attach driver to device.
static void usbio_stop (struct efi_device *efidev)
 Detach driver from device.
struct efi_driver usbio_driver __efi_driver (EFI_DRIVER_HARDWARE)
 EFI USB I/O driver.

Variables

static struct usbio_operations usbio_control_operations
 Control endpoint operations.
static struct usbio_operations usbio_bulk_in_operations
 Bulk endpoint operations.
static struct usbio_operations usbio_bulk_out_operations
 Bulk endpoint operations.
static struct usbio_operations usbio_interrupt_operations
 Interrupt endpoint operations.
static struct usb_host_operations usbio_operations
 USB I/O host controller driver operations.

Detailed Description

EFI_USB_IO_PROTOCOL pseudo Host Controller Interface driver.

The EFI_USB_IO_PROTOCOL is an almost unbelievably poorly designed abstraction of a USB device. It would be just about forgivable for an API to support only synchronous operation for bulk OUT endpoints. It is imbecilic to support only synchronous operation for bulk IN endpoints. This apparently intern-designed API throttles a typical NIC down to 1.5% of its maximum throughput. That isn't a typo. It really is that slow.

We can't even work around this stupidity by talking to the host controller abstraction directly, because an identical limitation exists in the EFI_USB2_HC_PROTOCOL.

Unless you derive therapeutic value from watching download progress indicators lethargically creep through every single integer from 0 to 100, you should use iPXE's native USB host controller drivers instead. (Or just upgrade from UEFI to "legacy" BIOS, which will produce a similar speed increase.)

For added excitement, the EFI_USB_IO_PROTOCOL makes the (demonstrably incorrect) assumption that a USB driver needs to attach to exactly one interface within a USB device, and provides a helper method to retrieve "the" interface descriptor. Since pretty much every USB network device requires binding to a pair of control+data interfaces, this aspect of EFI_USB_IO_PROTOCOL is of no use to us.

We have our own existing code for reading USB descriptors, so we don't actually care that the UsbGetInterfaceDescriptor() method provided by EFI_USB_IO_PROTOCOL is useless for network devices. We can read the descriptors ourselves (via UsbControlTransfer()) and get all of the information we need this way. We can even work around the fact that EFI_USB_IO_PROTOCOL provides separate handles for each of the two interfaces comprising our network device.

However, if we discover that we need to select an alternative device configuration (e.g. for devices exposing both RNDIS and ECM), then all hell breaks loose. EFI_USB_IO_PROTOCOL starts to panic because its cached interface and endpoint descriptors will no longer be valid. As mentioned above, the cached descriptors are useless for network devices anyway so we really don't care about this, but EFI_USB_IO_PROTOCOL certainly cares. It prints out a manic warning message containing no fewer than six exclamation marks and then literally commits seppuku in the middle of the UsbControlTransfer() method by attempting to uninstall itself. Quite how the caller is supposed to react when asked to stop using the EFI_USB_IO_PROTOCOL instance while in the middle of an uninterruptible call to said instance is left as an exercise for the interested reader.

There is no sensible way to work around this, so we just preemptively fail if asked to change the device configuration, on the basis that reporting a sarcastic error message is often preferable to jumping through a NULL pointer and crashing the system.

Definition in file usbio.c.

Macro Definition Documentation

◆ ENOTSUP_MORONIC_SPECIFICATION

#define ENOTSUP_MORONIC_SPECIFICATION   __einfo_error ( EINFO_ENOTSUP_MORONIC_SPECIFICATION )

Definition at line 101 of file usbio.c.

101#define ENOTSUP_MORONIC_SPECIFICATION \
102 __einfo_error ( EINFO_ENOTSUP_MORONIC_SPECIFICATION )

Referenced by usbio_control_poll().

◆ EINFO_ENOTSUP_MORONIC_SPECIFICATION

#define EINFO_ENOTSUP_MORONIC_SPECIFICATION
Value:
"EFI_USB_IO_PROTOCOL was designed by morons" )
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition errno.h:224
#define EINFO_ENOTSUP
Definition errno.h:634

Definition at line 103 of file usbio.c.

103#define EINFO_ENOTSUP_MORONIC_SPECIFICATION \
104 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, \
105 "EFI_USB_IO_PROTOCOL was designed by morons" )

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ usbio_interface()

int usbio_interface ( struct usbio_device * usbio,
struct usb_endpoint * ep )
static

Determine endpoint interface number.

Parameters
usbioUSB I/O device
epUSB Endpoint
Return values
interfaceInterface number, or negative error

Definition at line 121 of file usbio.c.

122 {
123 EFI_HANDLE handle = usbio->handle;
124 struct usb_device *usb = ep->usb;
128 struct usb_function *func;
129 unsigned int i;
130
131 /* The control endpoint is not part of a described interface */
132 if ( ep->address == USB_EP0_ADDRESS )
133 return 0;
134
135 /* Iterate over all interface descriptors looking for a match */
136 config = usbio->config;
139
140 /* Iterate over all endpoint descriptors looking for a match */
141 for_each_interface_descriptor ( endpoint, config, interface,
143
144 /* Check endpoint address */
145 if ( endpoint->endpoint != ep->address )
146 continue;
147
148 /* Check interface belongs to this function */
150
151 /* Skip non-matching functions */
152 if ( func->interface[0] != usbio->first )
153 continue;
154
155 /* Iterate over all interfaces for a match */
156 for ( i = 0 ; i < func->desc.count ; i++ ) {
157 if ( interface->interface ==
158 func->interface[i] )
159 return interface->interface;
160 }
161 }
162 }
163 }
164
165 DBGC ( usbio, "USBIO %s cannot find interface for %s",
167 return -ENOENT;
168}
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
#define DBGC(...)
Definition compiler.h:530
#define ENOENT
No such file or directory.
Definition errno.h:558
#define EFI_HANDLE
Definition efi.h:53
uint16_t handle
Handle.
Definition smbios.h:5
#define USB_ENDPOINT_DESCRIPTOR
A USB endpoint descriptor.
Definition usb.h:278
#define USB_INTERFACE_DESCRIPTOR
A USB interface descriptor.
Definition usb.h:261
#define USB_EP0_ADDRESS
Control endpoint address.
Definition usb.h:511
#define for_each_interface_descriptor(desc, config, interface, typeval)
Iterate over all configuration descriptors within an interface descriptor.
Definition usb.h:399
#define for_each_config_descriptor(desc, config, typeval)
Iterate over all configuration descriptors.
Definition usb.h:386
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
An object interface.
Definition interface.h:125
A USB configuration descriptor.
Definition usb.h:210
uint8_t config
Configuration value.
Definition usb.h:218
A USB device.
Definition usb.h:733
struct list_head functions
List of functions.
Definition usb.h:747
struct usb_endpoint * ep[32]
Endpoint list.
Definition usb.h:755
A USB endpoint descriptor.
Definition usb.h:264
uint8_t endpoint
Endpoint address.
Definition usb.h:268
struct usb_device * usb
USB device.
Definition usb.h:416
unsigned int address
Endpoint address.
Definition usb.h:418
unsigned int count
Number of interfaces.
Definition usb.h:675
A USB function.
Definition usb.h:684
struct usb_device * usb
USB device.
Definition usb.h:688
struct usb_function_descriptor desc
Function descriptor.
Definition usb.h:690
uint8_t interface[0]
List of interface numbers.
Definition usb.h:707
struct list_head list
List of functions within this USB device.
Definition usb.h:694
A USB interface descriptor.
Definition usb.h:245
uint8_t first
First interface number.
Definition usbio.h:143
EFI_HANDLE handle
EFI device handle.
Definition usbio.h:128
struct usb_configuration_descriptor * config
Configuration descriptor.
Definition usbio.h:135
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging).
Definition usb.c:220

References usb_endpoint::address, usb_configuration_descriptor::config, usbio_device::config, usb_function_descriptor::count, DBGC, usb_function::desc, EFI_HANDLE, efi_handle_name(), usb_endpoint_descriptor::endpoint, ENOENT, usb_device::ep, usbio_device::first, for_each_config_descriptor, for_each_interface_descriptor, usb_device::functions, handle, usbio_device::handle, usb_function::interface, usb_function::list, list_for_each_entry, usb_endpoint::usb, usb_function::usb, USB_ENDPOINT_DESCRIPTOR, usb_endpoint_name(), USB_EP0_ADDRESS, and USB_INTERFACE_DESCRIPTOR.

◆ usbio_open()

int usbio_open ( struct usbio_device * usbio,
unsigned int interface )
static

Open USB I/O interface.

Parameters
usbioUSB I/O device
interfaceInterface number
Return values
rcReturn status code

Definition at line 177 of file usbio.c.

177 {
178 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
179 EFI_HANDLE handle = usbio->handle;
180 struct usbio_interface *intf = &usbio->interface[interface];
183 USB_DEVICE_PATH *usbpath;
184 EFI_STATUS efirc;
185 int rc;
186
187 /* Sanity check */
188 assert ( interface < usbio->config->interfaces );
189
190 /* If interface is already open, just increment the usage count */
191 if ( intf->count ) {
192 intf->count++;
193 return 0;
194 }
195
196 /* Construct device path for this interface */
197 path = usbio->path;
198 usbpath = usbio->usbpath;
199 usbpath->InterfaceNumber = interface;
200 end = efi_path_end ( path );
201
202 /* Locate handle for this endpoint's interface */
203 if ( ( efirc = bs->LocateDevicePath ( &efi_usb_io_protocol_guid, &path,
204 &intf->handle ) ) != 0 ) {
205 rc = -EEFI ( efirc );
206 DBGC ( usbio, "USBIO %s could not locate ",
208 DBGC ( usbio, "%s: %s\n",
209 efi_devpath_text ( usbio->path ), strerror ( rc ) );
210 return rc;
211 }
212
213 /* Check that expected path was located */
214 if ( path != end ) {
215 DBGC ( usbio, "USBIO %s located incomplete ",
217 DBGC ( usbio, "%s\n", efi_handle_name ( intf->handle ) );
218 return -EXDEV;
219 }
220
221 /* Open USB I/O protocol on this handle */
222 if ( ( rc = efi_open_by_driver ( intf->handle,
224 &intf->io ) ) != 0 ) {
225 DBGC ( usbio, "USBIO %s cannot open ",
227 DBGC ( usbio, "%s: %s\n",
228 efi_handle_name ( intf->handle ), strerror ( rc ) );
229 DBGC_EFI_OPENERS ( usbio, intf->handle,
231 return rc;
232 }
233
234 /* Increment usage count */
235 intf->count++;
236
237 return 0;
238}
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition efi_debug.c:247
EFI_GUID efi_usb_io_protocol_guid
USB I/O protocol GUID.
Definition efi_guid.c:434
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition efi_path.c:167
#define EXDEV
Improper link.
Definition errno.h:728
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition efi.h:483
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:181
#define DBGC_EFI_OPENERS(...)
Definition efi.h:352
EFI_SYSTEM_TABLE * efi_systab
uint32_t end
Ending offset.
Definition netvsc.h:7
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI Boot Services Table.
Definition UefiSpec.h:1930
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition UefiSpec.h:1971
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition DevicePath.h:45
UINT8 InterfaceNumber
USB Interface Number.
Definition DevicePath.h:430
struct usbio_interface * interface
USB I/O protocol interfaces.
Definition usbio.h:145
USB_DEVICE_PATH * usbpath
Final component of USB device path.
Definition usbio.h:140
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition usbio.h:138
A USB I/O protocol interface.
Definition usbio.h:112
unsigned int count
Usage count.
Definition usbio.h:118
EFI_USB_IO_PROTOCOL * io
USB I/O protocol.
Definition usbio.h:116
EFI_HANDLE handle
EFI device handle.
Definition usbio.h:114

References assert, usbio_interface::count, DBGC, DBGC_EFI_OPENERS, EEFI, efi_devpath_text(), EFI_HANDLE, efi_handle_name(), efi_open_by_driver, efi_path_end(), efi_systab, efi_usb_io_protocol_guid, end, EXDEV, handle, usbio_device::handle, usbio_interface::handle, usbio_device::interface, USB_DEVICE_PATH::InterfaceNumber, usbio_interface::io, EFI_BOOT_SERVICES::LocateDevicePath, usbio_device::path, rc, strerror(), and usbio_device::usbpath.

Referenced by usbio_control_poll(), and usbio_endpoint_open().

◆ usbio_close()

void usbio_close ( struct usbio_device * usbio,
unsigned int interface )
static

Close USB I/O interface.

Parameters
usbioUSB I/O device
interfaceInterface number

Definition at line 246 of file usbio.c.

246 {
247 struct usbio_interface *intf = &usbio->interface[interface];
248
249 /* Sanity checks */
250 assert ( interface < usbio->config->interfaces );
251 assert ( intf->count > 0 );
252
253 /* Decrement usage count */
254 intf->count--;
255
256 /* Do nothing if interface is still in use */
257 if ( intf->count )
258 return;
259
260 /* Close USB I/O protocol */
262}
void efi_close_by_driver(EFI_HANDLE handle, EFI_GUID *protocol)
Close protocol opened for persistent use by a driver.
Definition efi_open.c:279

References assert, usbio_interface::count, efi_close_by_driver(), efi_usb_io_protocol_guid, usbio_interface::handle, and usbio_device::interface.

Referenced by usbio_control_poll(), usbio_endpoint_close(), and usbio_endpoint_open().

◆ usbio_control_open()

int usbio_control_open ( struct usbio_endpoint *endpoint __unused)
static

Open control endpoint.

Parameters
endpointEndpoint
Return values
rcReturn status code

Definition at line 277 of file usbio.c.

277 {
278
279 /* Nothing to do */
280 return 0;
281}

References __unused.

◆ usbio_control_close()

void usbio_control_close ( struct usbio_endpoint *endpoint __unused)
static

Close control endpoint.

Parameters
endpointEndpoint

Definition at line 288 of file usbio.c.

288 {
289
290 /* Nothing to do */
291}

References __unused.

◆ usbio_control_poll()

void usbio_control_poll ( struct usbio_endpoint * endpoint)
static

Poll control endpoint.

Parameters
endpointEndpoint

Definition at line 298 of file usbio.c.

298 {
299 struct usbio_device *usbio = endpoint->usbio;
300 struct usb_endpoint *ep = endpoint->ep;
301 EFI_HANDLE handle = usbio->handle;
303 union {
304 struct usb_setup_packet setup;
306 } *msg;
308 struct io_buffer *iobuf;
309 unsigned int index;
310 unsigned int flags;
311 unsigned int recipient;
312 unsigned int interface;
314 void *data;
315 size_t len;
317 EFI_STATUS efirc;
318 int rc;
319
320 /* Do nothing if ring is empty */
321 if ( endpoint->cons == endpoint->prod )
322 return;
323
324 /* Consume next transfer */
325 index = ( endpoint->cons++ % USBIO_RING_COUNT );
326 iobuf = endpoint->iobuf[index];
327 flags = endpoint->flags[index];
328
329 /* Sanity check */
330 if ( ! ( flags & USBIO_MESSAGE ) ) {
331 DBGC ( usbio, "USBIO %s %s non-message transfer\n",
333 rc = -ENOTSUP;
334 goto err_not_message;
335 }
336
337 /* Construct transfer */
338 msg = iob_push ( iobuf, sizeof ( *msg ) );
339 iob_pull ( iobuf, sizeof ( *msg ) );
340 request = le16_to_cpu ( msg->setup.request );
341 len = iob_len ( iobuf );
342 if ( len ) {
343 data = iobuf->data;
344 direction = ( ( request & USB_DIR_IN ) ?
346 } else {
347 data = NULL;
349 }
350
351 /* Determine interface for this transfer */
352 recipient = ( request & USB_RECIP_MASK );
353 if ( recipient == USB_RECIP_INTERFACE ) {
354 /* Recipient is an interface: use interface number directly */
355 interface = le16_to_cpu ( msg->setup.index );
356 } else {
357 /* Route all other requests through the first interface */
358 interface = 0;
359 }
360
361 /* Open interface */
362 if ( ( rc = usbio_open ( usbio, interface ) ) != 0 )
363 goto err_open;
364 io = usbio->interface[interface].io;
365
366 /* Due to the design of EFI_USB_IO_PROTOCOL, attempting to set
367 * the configuration to a non-default value is basically a
368 * self-destruct button.
369 */
370 if ( ( request == USB_SET_CONFIGURATION ) &&
371 ( le16_to_cpu ( msg->setup.value ) != usbio->config->config ) ) {
373 DBGC ( usbio, "USBIO %s cannot change configuration: %s\n",
375 goto err_moronic_specification;
376 }
377
378 /* Submit transfer */
379 if ( ( efirc = io->UsbControlTransfer ( io, &msg->efi, direction, 0,
380 data, len, &status ) ) != 0 ) {
381 rc = -EEFI ( efirc );
382 DBGC ( usbio, "USBIO %s %s could not submit control transfer ",
384 DBGC ( usbio, "via %s: %s (status %04x)\n",
386 strerror ( rc ), status );
387 goto err_transfer;
388 }
389
390 /* Close interface */
391 usbio_close ( usbio, interface );
392
393 /* Complete transfer */
394 usb_complete ( ep, iobuf );
395
396 return;
397
398 err_transfer:
399 err_moronic_specification:
400 usbio_close ( usbio, interface );
401 err_open:
402 err_not_message:
403 usb_complete_err ( ep, iobuf, rc );
404}
unsigned int UINT32
4-byte unsigned value.
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
EFI_USB_DATA_DIRECTION
USB data transfer direction.
Definition UsbIo.h:46
@ EfiUsbNoData
Definition UsbIo.h:49
@ EfiUsbDataIn
Definition UsbIo.h:47
@ EfiUsbDataOut
Definition UsbIo.h:48
struct _EFI_USB_IO_PROTOCOL EFI_USB_IO_PROTOCOL
Definition UsbIo.h:28
USB_DEVICE_REQUEST EFI_USB_DEVICE_REQUEST
Definition UsbIo.h:37
unsigned short uint16_t
Definition stdint.h:11
long index
Definition bigint.h:30
ring len
Length.
Definition dwmac.h:226
uint8_t direction
Direction.
Definition ena.h:3
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t flags
Flags.
Definition ena.h:7
uint8_t status
Status.
Definition ena.h:5
#define ENOTSUP
Operation not supported.
Definition errno.h:633
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
#define le16_to_cpu(value)
Definition byteswap.h:113
#define USB_DIR_IN
Data transfer is from device to host.
Definition usb.h:98
static void usb_complete(struct usb_endpoint *ep, struct io_buffer *iobuf)
Complete transfer (without error).
Definition usb.h:1097
#define USB_RECIP_MASK
Request recipient mask.
Definition usb.h:110
#define USB_SET_CONFIGURATION
Set configuration.
Definition usb.h:146
#define USB_RECIP_INTERFACE
Request recipient is an interface.
Definition usb.h:116
#define iob_push(iobuf, len)
Definition iobuf.h:149
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_pull(iobuf, len)
Definition iobuf.h:167
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition message.c:62
EFI_USB_IO_CONTROL_TRANSFER UsbControlTransfer
Definition UsbIo.h:482
A persistent I/O buffer.
Definition iobuf.h:98
void * data
Start of data.
Definition iobuf.h:113
A USB endpoint.
Definition usb.h:414
A USB I/O protocol device.
Definition usbio.h:126
unsigned int cons
Consumer counter.
Definition usbio.h:73
struct usb_endpoint * ep
USB endpoint.
Definition usbio.h:57
struct io_buffer * iobuf[USBIO_RING_COUNT]
I/O buffers.
Definition usbio.h:75
struct usbio_device * usbio
USB I/O device.
Definition usbio.h:55
unsigned int prod
Producer counter.
Definition usbio.h:71
uint8_t flags[USBIO_RING_COUNT]
Flags.
Definition usbio.h:77
void usb_complete_err(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer (possibly with error).
Definition usb.c:586
static void usbio_close(struct usbio_device *usbio, unsigned int interface)
Close USB I/O interface.
Definition usbio.c:246
static int usbio_open(struct usbio_device *usbio, unsigned int interface)
Open USB I/O interface.
Definition usbio.c:177
#define ENOTSUP_MORONIC_SPECIFICATION
Definition usbio.c:101
@ USBIO_MESSAGE
This is a message transfer.
Definition usbio.h:86
#define USBIO_RING_COUNT
USB I/O ring buffer size.
Definition usbio.h:50

References usb_configuration_descriptor::config, usbio_device::config, usbio_endpoint::cons, data, io_buffer::data, DBGC, direction, EEFI, EFI_HANDLE, efi_handle_name(), EfiUsbDataIn, EfiUsbDataOut, EfiUsbNoData, ENOTSUP, ENOTSUP_MORONIC_SPECIFICATION, usbio_endpoint::ep, flags, usbio_endpoint::flags, handle, usbio_device::handle, usbio_interface::handle, index, usbio_device::interface, usbio_interface::io, iob_len(), iob_pull, iob_push, usbio_endpoint::iobuf, le16_to_cpu, len, msg(), NULL, usbio_endpoint::prod, rc, request, status, strerror(), usb_complete(), usb_complete_err(), USB_DIR_IN, usb_endpoint_name(), USB_RECIP_INTERFACE, USB_RECIP_MASK, USB_SET_CONFIGURATION, _EFI_USB_IO_PROTOCOL::UsbControlTransfer, usbio_endpoint::usbio, usbio_close(), USBIO_MESSAGE, usbio_open(), and USBIO_RING_COUNT.

◆ usbio_bulk_in_open()

int usbio_bulk_in_open ( struct usbio_endpoint *endpoint __unused)
static

Open bulk IN endpoint.

Parameters
endpointEndpoint
Return values
rcReturn status code

Definition at line 426 of file usbio.c.

426 {
427
428 /* Nothing to do */
429 return 0;
430}

References __unused.

◆ usbio_bulk_in_close()

void usbio_bulk_in_close ( struct usbio_endpoint *endpoint __unused)
static

Close bulk IN endpoint.

Parameters
endpointEndpoint

Definition at line 437 of file usbio.c.

437 {
438
439 /* Nothing to do */
440}

References __unused.

◆ usbio_bulk_in_poll()

void usbio_bulk_in_poll ( struct usbio_endpoint * endpoint)
static

Poll bulk IN endpoint.

Parameters
endpointEndpoint

Definition at line 447 of file usbio.c.

447 {
448 struct usbio_device *usbio = endpoint->usbio;
449 struct usb_endpoint *ep = endpoint->ep;
450 EFI_USB_IO_PROTOCOL *io = endpoint->io;
451 EFI_HANDLE handle = usbio->handle;
452 struct io_buffer *iobuf;
453 unsigned int index;
454 UINTN len;
456 EFI_STATUS efirc;
457 int rc;
458
459 /* Do nothing if ring is empty */
460 if ( endpoint->cons == endpoint->prod )
461 return;
462
463 /* Attempt (but do not yet consume) next transfer */
464 index = ( endpoint->cons % USBIO_RING_COUNT );
465 iobuf = endpoint->iobuf[index];
466
467 /* Construct transfer */
468 len = iob_len ( iobuf );
469
470 /* Upon being turned on, the EFI_USB_IO_PROTOCOL did nothing
471 * for several minutes before firing a small ARP packet a few
472 * millimetres into the ether.
473 */
474 efirc = io->UsbBulkTransfer ( io, ep->address, iobuf->data,
475 &len, 1, &status );
476 if ( efirc == EFI_TIMEOUT )
477 return;
478
479 /* Consume transfer */
480 endpoint->cons++;
481
482 /* Check for failure */
483 if ( efirc != 0 ) {
484 rc = -EEFI ( efirc );
485 DBGC2 ( usbio, "USBIO %s %s could not submit bulk IN transfer: "
486 "%s (status %04x)\n", efi_handle_name ( handle ),
487 usb_endpoint_name ( ep ), strerror ( rc ), status );
488 usb_complete_err ( ep, iobuf, rc );
489 return;
490 }
491
492 /* Update length */
493 iob_put ( iobuf, ( len - iob_len ( iobuf ) ) );
494
495 /* Complete transfer */
496 usb_complete ( ep, iobuf );
497}
UINT64 UINTN
Unsigned value of native width.
#define EFI_TIMEOUT
Enumeration of EFI_STATUS.
#define DBGC2(...)
Definition compiler.h:547
#define iob_put(iobuf, len)
Definition iobuf.h:185
EFI_USB_IO_BULK_TRANSFER UsbBulkTransfer
Definition UsbIo.h:483
EFI_USB_IO_PROTOCOL * io
USB I/O protocol.
Definition usbio.h:68

References usb_endpoint::address, usbio_endpoint::cons, io_buffer::data, DBGC2, EEFI, EFI_HANDLE, efi_handle_name(), EFI_TIMEOUT, usbio_endpoint::ep, handle, usbio_device::handle, index, usbio_endpoint::io, iob_len(), iob_put, usbio_endpoint::iobuf, len, usbio_endpoint::prod, rc, status, strerror(), usb_complete(), usb_complete_err(), usb_endpoint_name(), _EFI_USB_IO_PROTOCOL::UsbBulkTransfer, usbio_endpoint::usbio, and USBIO_RING_COUNT.

◆ usbio_bulk_out_open()

int usbio_bulk_out_open ( struct usbio_endpoint *endpoint __unused)
static

Open bulk OUT endpoint.

Parameters
endpointEndpoint
Return values
rcReturn status code

Definition at line 519 of file usbio.c.

519 {
520
521 /* Nothing to do */
522 return 0;
523}

References __unused.

◆ usbio_bulk_out_close()

void usbio_bulk_out_close ( struct usbio_endpoint *endpoint __unused)
static

Close bulk OUT endpoint.

Parameters
endpointEndpoint

Definition at line 530 of file usbio.c.

530 {
531
532 /* Nothing to do */
533}

References __unused.

◆ usbio_bulk_out_poll()

void usbio_bulk_out_poll ( struct usbio_endpoint * endpoint)
static

Poll bulk OUT endpoint.

Parameters
endpointEndpoint

Definition at line 540 of file usbio.c.

540 {
541 struct usbio_device *usbio = endpoint->usbio;
542 struct usb_endpoint *ep = endpoint->ep;
543 EFI_USB_IO_PROTOCOL *io = endpoint->io;
544 EFI_HANDLE handle = usbio->handle;
545 struct io_buffer *iobuf;
546 unsigned int index;
547 unsigned int flags;
548 UINTN len;
550 EFI_STATUS efirc;
551 int rc;
552
553 /* Do nothing if ring is empty */
554 if ( endpoint->cons == endpoint->prod )
555 return;
556
557 /* Consume next transfer */
558 index = ( endpoint->cons++ % USBIO_RING_COUNT );
559 iobuf = endpoint->iobuf[index];
560 flags = endpoint->flags[index];
561
562 /* Construct transfer */
563 len = iob_len ( iobuf );
564
565 /* Submit transfer */
566 if ( ( efirc = io->UsbBulkTransfer ( io, ep->address, iobuf->data,
567 &len, 0, &status ) ) != 0 ) {
568 rc = -EEFI ( efirc );
569 DBGC ( usbio, "USBIO %s %s could not submit bulk OUT transfer: "
570 "%s (status %04x)\n", efi_handle_name ( handle ),
571 usb_endpoint_name ( ep ), strerror ( rc ), status );
572 goto err;
573 }
574
575 /* Update length */
576 iob_put ( iobuf, ( len - iob_len ( iobuf ) ) );
577
578 /* Submit zero-length transfer if required */
579 len = 0;
580 if ( ( flags & USBIO_ZLEN ) &&
581 ( efirc = io->UsbBulkTransfer ( io, ep->address, NULL, &len, 0,
582 &status ) ) != 0 ) {
583 rc = -EEFI ( efirc );
584 DBGC ( usbio, "USBIO %s %s could not submit zero-length "
585 "transfer: %s (status %04x)\n",
587 strerror ( rc ), status );
588 goto err;
589 }
590
591 /* Complete transfer */
592 usb_complete ( ep, iobuf );
593
594 return;
595
596 err:
597 usb_complete_err ( ep, iobuf, rc );
598}
@ USBIO_ZLEN
This transfer requires zero-length packet termination.
Definition usbio.h:88

References usb_endpoint::address, usbio_endpoint::cons, io_buffer::data, DBGC, EEFI, EFI_HANDLE, efi_handle_name(), usbio_endpoint::ep, flags, usbio_endpoint::flags, handle, usbio_device::handle, index, usbio_endpoint::io, iob_len(), iob_put, usbio_endpoint::iobuf, len, NULL, usbio_endpoint::prod, rc, status, strerror(), usb_complete(), usb_complete_err(), usb_endpoint_name(), _EFI_USB_IO_PROTOCOL::UsbBulkTransfer, usbio_endpoint::usbio, USBIO_RING_COUNT, and USBIO_ZLEN.

◆ usbio_interrupt_callback()

EFI_STATUS EFIAPI usbio_interrupt_callback ( VOID * data,
UINTN len,
VOID * context,
UINT32 status )
static

Interrupt endpoint callback.

Parameters
dataReceived data
lenLength of received data
contextCallback context
statusTransfer status
Return values
efircEFI status code

Definition at line 647 of file usbio.c.

649 {
650 struct usbio_interrupt_ring *intr = context;
651 struct usbio_endpoint *endpoint = intr->endpoint;
652 struct usbio_device *usbio = endpoint->usbio;
653 struct usb_endpoint *ep = endpoint->ep;
654 EFI_HANDLE handle = usbio->handle;
655 unsigned int fill;
656 unsigned int index;
657
658 /* Sanity check */
660
661 /* Do nothing if ring is empty */
662 fill = ( intr->prod - intr->cons );
663 if ( fill >= USBIO_INTR_COUNT ) {
664 DBGC ( usbio, "USBIO %s %s dropped interrupt completion\n",
666 return 0;
667 }
668
669 /* Do nothing if transfer was unsuccessful */
670 if ( status != 0 ) {
671 DBGC ( usbio, "USBIO %s %s interrupt completion status %04x\n",
673 status );
674 return 0; /* Unclear what failure actually means here */
675 }
676
677 /* Copy data to buffer and increment producer counter */
678 index = ( intr->prod % USBIO_INTR_COUNT );
679 memcpy ( intr->data[index], data, len );
680 intr->len[index] = len;
681 intr->prod++;
682
683 return 0;
684}
static int fill
Definition string.h:209
uint32_t mtu
Maximum MTU.
Definition ena.h:17
uint8_t intr
Interrupts enabled.
Definition ena.h:3
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A USB I/O endpoint.
Definition usbio.h:53
A USB interrupt ring buffer.
Definition usbio.h:33
#define USBIO_INTR_COUNT
USB I/O interrupt ring buffer size.
Definition usbio.h:30

References assert, data, DBGC, EFI_HANDLE, efi_handle_name(), EFIAPI, usbio_endpoint::ep, fill, handle, usbio_device::handle, index, intr, len, memcpy(), mtu, status, usb_endpoint_name(), usbio_endpoint::usbio, USBIO_INTR_COUNT, and VOID.

Referenced by usbio_interrupt_open().

◆ usbio_interrupt_open()

int usbio_interrupt_open ( struct usbio_endpoint * endpoint)
static

Open interrupt endpoint.

Parameters
endpointEndpoint
Return values
rcReturn status code

Definition at line 692 of file usbio.c.

692 {
693 struct usbio_device *usbio = endpoint->usbio;
695 struct usb_endpoint *ep = endpoint->ep;
696 EFI_USB_IO_PROTOCOL *io = endpoint->io;
697 EFI_HANDLE handle = usbio->handle;
698 unsigned int interval;
699 unsigned int i;
700 void *data;
701 EFI_STATUS efirc;
702 int rc;
703
704 /* Allocate interrupt ring buffer */
705 intr = zalloc ( sizeof ( *intr ) + ( USBIO_INTR_COUNT * ep->mtu ) );
706 if ( ! intr ) {
707 rc = -ENOMEM;
708 goto err_alloc;
709 }
710 endpoint->intr = intr;
711 intr->endpoint = endpoint;
712 data = ( ( ( void * ) intr ) + sizeof ( *intr ) );
713 for ( i = 0 ; i < USBIO_INTR_COUNT ; i++ ) {
714 intr->data[i] = data;
715 data += ep->mtu;
716 }
717
718 /* Determine polling interval */
719 interval = ( ep->interval >> 3 /* microframes -> milliseconds */ );
720 if ( ! interval )
721 interval = 1; /* May not be zero */
722
723 /* Add to periodic schedule */
724 if ( ( efirc = io->UsbAsyncInterruptTransfer ( io, ep->address, TRUE,
725 interval, ep->mtu,
727 intr ) ) != 0 ) {
728 rc = -EEFI ( efirc );
729 DBGC ( usbio, "USBIO %s %s could not schedule interrupt "
730 "transfer: %s\n", efi_handle_name ( handle ),
731 usb_endpoint_name ( ep ), strerror ( rc ) );
732 goto err_schedule;
733 }
734
735 return 0;
736
737 io->UsbAsyncInterruptTransfer ( io, ep->address, FALSE, 0, 0,
738 NULL, NULL );
739 err_schedule:
740 free ( intr );
741 err_alloc:
742 return rc;
743}
#define ENOMEM
Not enough space.
Definition errno.h:578
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER UsbAsyncInterruptTransfer
Definition UsbIo.h:484
size_t mtu
Maximum transfer size.
Definition usb.h:422
unsigned int interval
Interval (in microframes).
Definition usb.h:426
struct usbio_interrupt_ring * intr
Interrupt ring buffer (if applicable).
Definition usbio.h:80
#define TRUE
Definition tlan.h:46
#define FALSE
Definition tlan.h:45
static EFI_STATUS EFIAPI usbio_interrupt_callback(VOID *data, UINTN len, VOID *context, UINT32 status)
Interrupt endpoint callback.
Definition usbio.c:647

References usb_endpoint::address, data, DBGC, EEFI, EFI_HANDLE, efi_handle_name(), ENOMEM, usbio_endpoint::ep, FALSE, free, handle, usbio_device::handle, usb_endpoint::interval, intr, usbio_endpoint::intr, usbio_endpoint::io, usb_endpoint::mtu, NULL, rc, strerror(), TRUE, usb_endpoint_name(), _EFI_USB_IO_PROTOCOL::UsbAsyncInterruptTransfer, usbio_endpoint::usbio, usbio_interrupt_callback(), USBIO_INTR_COUNT, and zalloc().

◆ usbio_interrupt_close()

void usbio_interrupt_close ( struct usbio_endpoint * endpoint)
static

Close interrupt endpoint.

Parameters
endpointEndpoint

Definition at line 750 of file usbio.c.

750 {
751 struct usb_endpoint *ep = endpoint->ep;
752 EFI_USB_IO_PROTOCOL *io = endpoint->io;
753
754 /* Remove from periodic schedule */
755 io->UsbAsyncInterruptTransfer ( io, ep->address, FALSE, 0, 0,
756 NULL, NULL );
757
758 /* Free interrupt ring buffer */
759 free ( endpoint->intr );
760}

References usb_endpoint::address, usbio_endpoint::ep, FALSE, free, usbio_endpoint::intr, usbio_endpoint::io, NULL, and _EFI_USB_IO_PROTOCOL::UsbAsyncInterruptTransfer.

◆ usbio_interrupt_poll()

void usbio_interrupt_poll ( struct usbio_endpoint * endpoint)
static

Poll interrupt endpoint.

Parameters
endpointEndpoint

Definition at line 767 of file usbio.c.

767 {
769 struct usb_endpoint *ep = endpoint->ep;
770 struct io_buffer *iobuf;
771 unsigned int index;
772 unsigned int intr_index;
773 size_t len;
774
775 /* Do nothing if ring is empty */
776 if ( endpoint->cons == endpoint->prod )
777 return;
778
779 /* Do nothing if interrupt ring is empty */
780 if ( intr->cons == intr->prod )
781 return;
782
783 /* Consume next transfer */
784 index = ( endpoint->cons++ % USBIO_RING_COUNT );
785 iobuf = endpoint->iobuf[index];
786
787 /* Populate I/O buffer */
788 intr_index = ( intr->cons++ % USBIO_INTR_COUNT );
789 len = intr->len[intr_index];
790 assert ( len <= iob_len ( iobuf ) );
791 iob_put ( iobuf, ( len - iob_len ( iobuf ) ) );
792 memcpy ( iobuf->data, intr->data[intr_index], len );
793
794 /* Complete transfer */
795 usb_complete ( ep, iobuf );
796}
struct usbio_endpoint * endpoint
USB I/O endpoint.
Definition usbio.h:35

References assert, usbio_endpoint::cons, io_buffer::data, usbio_interrupt_ring::endpoint, usbio_endpoint::ep, index, intr, usbio_endpoint::intr, iob_len(), iob_put, usbio_endpoint::iobuf, len, memcpy(), usbio_endpoint::prod, usb_complete(), USBIO_INTR_COUNT, and USBIO_RING_COUNT.

◆ usbio_endpoint_open()

int usbio_endpoint_open ( struct usb_endpoint * ep)
static

Open endpoint.

Parameters
epUSB endpoint
Return values
rcReturn status code

Definition at line 818 of file usbio.c.

818 {
819 struct usb_bus *bus = ep->usb->port->hub->bus;
820 struct usbio_device *usbio = usb_bus_get_hostdata ( bus );
821 struct usbio_endpoint *endpoint;
823 unsigned int attr = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
824 int interface;
825 int rc;
826
827 /* Allocate and initialise structure */
828 endpoint = zalloc ( sizeof ( *endpoint ) );
829 if ( ! endpoint ) {
830 rc = -ENOMEM;
831 goto err_alloc;
832 }
833 usb_endpoint_set_hostdata ( ep, endpoint );
834 endpoint->usbio = usbio;
835 endpoint->ep = ep;
836
837 /* Identify endpoint operations */
839 endpoint->op = &usbio_control_operations;
840 } else if ( attr == USB_ENDPOINT_ATTR_BULK ) {
841 endpoint->op = ( ( ep->address & USB_DIR_IN ) ?
844 } else if ( attr == USB_ENDPOINT_ATTR_INTERRUPT ) {
845 endpoint->op = &usbio_interrupt_operations;
846 } else {
847 rc = -ENOTSUP;
848 goto err_operations;
849 }
850
851 /* Identify interface for this endpoint */
852 interface = usbio_interface ( usbio, ep );
853 if ( interface < 0 ) {
854 rc = interface;
855 goto err_interface;
856 }
857 endpoint->interface = interface;
858
859 /* Open interface */
860 if ( ( rc = usbio_open ( usbio, interface ) ) != 0 )
861 goto err_open_interface;
862 endpoint->handle = usbio->interface[interface].handle;
863 endpoint->io = usbio->interface[interface].io;
864 DBGC ( usbio, "USBIO %s %s using ",
866 DBGC ( usbio, "%s\n", efi_handle_name ( endpoint->handle ) );
867
868 /* Open endpoint */
869 if ( ( rc = endpoint->op->open ( endpoint ) ) != 0 )
870 goto err_open_endpoint;
871
872 /* Add to list of endpoints */
873 list_add_tail ( &endpoint->list, &usbio->endpoints );
874
875 return 0;
876
877 list_del ( &endpoint->list );
878 endpoint->op->close ( endpoint );
879 err_open_endpoint:
880 usbio_close ( usbio, interface );
881 err_open_interface:
882 err_interface:
883 err_operations:
884 free ( endpoint );
885 err_alloc:
886 return rc;
887}
uint8_t bus
Bus.
Definition edd.h:1
#define USB_ENDPOINT_ATTR_BULK
Bulk endpoint transfer type.
Definition usb.h:290
static void usb_endpoint_set_hostdata(struct usb_endpoint *ep, void *priv)
Set USB endpoint host controller private data.
Definition usb.h:586
#define USB_ENDPOINT_ATTR_INTERRUPT
Interrupt endpoint transfer type.
Definition usb.h:293
static void * usb_bus_get_hostdata(struct usb_bus *bus)
Get USB bus host controller private data.
Definition usb.h:1072
#define USB_ENDPOINT_ATTR_TYPE_MASK
Endpoint attribute transfer type mask.
Definition usb.h:281
#define USB_ENDPOINT_ATTR_CONTROL
Control endpoint transfer type.
Definition usb.h:287
uint8_t attr
Type and attributes.
Definition librm.h:7
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
A USB bus.
Definition usb.h:976
struct usb_port * port
USB port.
Definition usb.h:737
unsigned int attributes
Attributes.
Definition usb.h:420
struct usb_bus * bus
USB bus.
Definition usb.h:855
struct usb_hub * hub
USB hub.
Definition usb.h:825
struct list_head endpoints
List of endpoints.
Definition usbio.h:150
EFI_HANDLE handle
EFI handle.
Definition usbio.h:66
struct usbio_operations * op
USB I/O endpoint operations.
Definition usbio.h:61
unsigned int interface
Containing interface number.
Definition usbio.h:64
struct list_head list
List of endpoints.
Definition usbio.h:59
void(* close)(struct usbio_endpoint *endpoint)
Close endpoint.
Definition usbio.h:103
int(* open)(struct usbio_endpoint *endpoint)
Open endpoint.
Definition usbio.h:98
static struct usbio_operations usbio_control_operations
Control endpoint operations.
Definition usbio.c:407
static struct usbio_operations usbio_interrupt_operations
Interrupt endpoint operations.
Definition usbio.c:799
static struct usbio_operations usbio_bulk_in_operations
Bulk endpoint operations.
Definition usbio.c:500
static struct usbio_operations usbio_bulk_out_operations
Bulk endpoint operations.
Definition usbio.c:601

References usb_endpoint::address, attr, usb_endpoint::attributes, bus, usb_hub::bus, usbio_operations::close, DBGC, EFI_HANDLE, efi_handle_name(), usbio_device::endpoints, ENOMEM, ENOTSUP, usbio_endpoint::ep, free, handle, usbio_device::handle, usbio_endpoint::handle, usbio_interface::handle, usb_port::hub, usbio_device::interface, usbio_endpoint::interface, usbio_endpoint::io, usbio_interface::io, usbio_endpoint::list, list_add_tail, list_del, usbio_endpoint::op, usbio_operations::open, usb_device::port, rc, usb_endpoint::usb, usb_bus_get_hostdata(), USB_DIR_IN, USB_ENDPOINT_ATTR_BULK, USB_ENDPOINT_ATTR_CONTROL, USB_ENDPOINT_ATTR_INTERRUPT, USB_ENDPOINT_ATTR_TYPE_MASK, usb_endpoint_name(), usb_endpoint_set_hostdata(), usbio_endpoint::usbio, usbio_bulk_in_operations, usbio_bulk_out_operations, usbio_close(), usbio_control_operations, usbio_interrupt_operations, usbio_open(), and zalloc().

◆ usbio_endpoint_close()

void usbio_endpoint_close ( struct usb_endpoint * ep)
static

Close endpoint.

Parameters
epUSB endpoint

Definition at line 894 of file usbio.c.

894 {
895 struct usbio_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
896 struct usbio_device *usbio = endpoint->usbio;
897 struct io_buffer *iobuf;
898 unsigned int index;
899
900 /* Remove from list of endpoints */
901 list_del ( &endpoint->list );
902
903 /* Close endpoint */
904 endpoint->op->close ( endpoint );
905
906 /* Close interface */
907 usbio_close ( usbio, endpoint->interface );
908
909 /* Cancel any incomplete transfers */
910 while ( endpoint->cons != endpoint->prod ) {
911 index = ( endpoint->cons++ % USBIO_RING_COUNT );
912 iobuf = endpoint->iobuf[index];
913 usb_complete_err ( ep, iobuf, -ECANCELED );
914 }
915
916 /* Free endpoint */
917 free ( endpoint );
918}
#define ECANCELED
Operation canceled.
Definition errno.h:387
static void * usb_endpoint_get_hostdata(struct usb_endpoint *ep)
Get USB endpoint host controller private data.
Definition usb.h:597

References usbio_operations::close, usbio_endpoint::cons, ECANCELED, usbio_endpoint::ep, free, index, usbio_endpoint::interface, usbio_endpoint::iobuf, usbio_endpoint::list, list_del, usbio_endpoint::op, usbio_endpoint::prod, usb_complete_err(), usb_endpoint_get_hostdata(), usbio_endpoint::usbio, usbio_close(), and USBIO_RING_COUNT.

◆ usbio_endpoint_reset()

int usbio_endpoint_reset ( struct usb_endpoint *ep __unused)
static

Reset endpoint.

Parameters
epUSB endpoint
Return values
rcReturn status code

Definition at line 926 of file usbio.c.

926 {
927
928 /* Nothing to do */
929 return 0;
930}

References __unused.

◆ usbio_endpoint_mtu()

int usbio_endpoint_mtu ( struct usb_endpoint *ep __unused)
static

Update MTU.

Parameters
epUSB endpoint
Return values
rcReturn status code

Definition at line 938 of file usbio.c.

938 {
939
940 /* Nothing to do */
941 return 0;
942}

References __unused.

◆ usbio_endpoint_enqueue()

int usbio_endpoint_enqueue ( struct usb_endpoint * ep,
struct io_buffer * iobuf,
unsigned int flags )
static

Enqueue transfer.

Parameters
epUSB endpoint
iobufI/O buffer
flagsTransfer flags
Return values
rcReturn status code

Definition at line 952 of file usbio.c.

954 {
955 struct usbio_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
956 unsigned int fill;
957 unsigned int index;
958
959 /* Fail if shutdown is in progress */
961 return -ECANCELED;
962
963 /* Fail if transfer ring is full */
964 fill = ( endpoint->prod - endpoint->cons );
965 if ( fill >= USBIO_RING_COUNT )
966 return -ENOBUFS;
967
968 /* Add to ring */
969 index = ( endpoint->prod++ % USBIO_RING_COUNT );
970 endpoint->iobuf[index] = iobuf;
971 endpoint->flags[index] = flags;
972
973 return 0;
974}
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60
#define ENOBUFS
No buffer space available.
Definition errno.h:542

References usbio_endpoint::cons, ECANCELED, efi_shutdown_in_progress, ENOBUFS, usbio_endpoint::ep, fill, flags, usbio_endpoint::flags, index, usbio_endpoint::iobuf, usbio_endpoint::prod, usb_endpoint_get_hostdata(), and USBIO_RING_COUNT.

Referenced by usbio_endpoint_message(), and usbio_endpoint_stream().

◆ usbio_endpoint_message()

int usbio_endpoint_message ( struct usb_endpoint * ep,
struct io_buffer * iobuf )
static

Enqueue message transfer.

Parameters
epUSB endpoint
iobufI/O buffer
Return values
rcReturn status code

Definition at line 983 of file usbio.c.

984 {
985 struct usb_setup_packet *setup;
986
987 /* Adjust I/O buffer to start of data payload */
988 assert ( iob_len ( iobuf ) >= sizeof ( *setup ) );
989 iob_pull ( iobuf, sizeof ( *setup ) );
990
991 /* Enqueue transfer */
992 return usbio_endpoint_enqueue ( ep, iobuf, USBIO_MESSAGE );
993}
A USB setup data packet.
Definition usb.h:83
static int usbio_endpoint_enqueue(struct usb_endpoint *ep, struct io_buffer *iobuf, unsigned int flags)
Enqueue transfer.
Definition usbio.c:952

References assert, iob_len(), iob_pull, usbio_endpoint_enqueue(), and USBIO_MESSAGE.

◆ usbio_endpoint_stream()

int usbio_endpoint_stream ( struct usb_endpoint * ep,
struct io_buffer * iobuf,
int zlp )
static

Enqueue stream transfer.

Parameters
epUSB endpoint
iobufI/O buffer
zlpAppend a zero-length packet
Return values
rcReturn status code

Definition at line 1003 of file usbio.c.

1004 {
1005
1006 /* Enqueue transfer */
1007 return usbio_endpoint_enqueue ( ep, iobuf, ( zlp ? USBIO_ZLEN : 0 ) );
1008}

References usbio_endpoint_enqueue(), and USBIO_ZLEN.

◆ usbio_endpoint_poll()

void usbio_endpoint_poll ( struct usbio_endpoint * endpoint)
static

Poll for completions.

Parameters
endpointEndpoint

Definition at line 1015 of file usbio.c.

1015 {
1016
1017 /* Do nothing if shutdown is in progress */
1019 return;
1020
1021 /* Poll endpoint */
1022 endpoint->op->poll ( endpoint );
1023}
void(* poll)(struct usbio_endpoint *endpoint)
Poll endpoint.
Definition usbio.h:108

References efi_shutdown_in_progress, usbio_endpoint::op, and usbio_operations::poll.

Referenced by usbio_bus_poll().

◆ usbio_device_open()

int usbio_device_open ( struct usb_device * usb)
static

Open device.

Parameters
usbUSB device
Return values
rcReturn status code

Definition at line 1038 of file usbio.c.

1038 {
1039 struct usbio_device *usbio =
1040 usb_bus_get_hostdata ( usb->port->hub->bus );
1041
1042 usb_set_hostdata ( usb, usbio );
1043 return 0;
1044}
static void usb_set_hostdata(struct usb_device *usb, void *priv)
Set USB device host controller private data.
Definition usb.h:794

References usb_hub::bus, usb_port::hub, usb_device::port, usb_bus_get_hostdata(), and usb_set_hostdata().

◆ usbio_device_close()

void usbio_device_close ( struct usb_device *usb __unused)
static

Close device.

Parameters
usbUSB device

Definition at line 1051 of file usbio.c.

1051 {
1052
1053 /* Nothing to do */
1054}

References __unused.

◆ usbio_device_address()

int usbio_device_address ( struct usb_device *usb __unused)
static

Assign device address.

Parameters
usbUSB device
Return values
rcReturn status code

Definition at line 1062 of file usbio.c.

1062 {
1063
1064 /* Nothing to do */
1065 return 0;
1066}

References __unused.

◆ usbio_hub_open()

int usbio_hub_open ( struct usb_hub * hub)
static

Open hub.

Parameters
hubUSB hub
Return values
rcReturn status code

Definition at line 1081 of file usbio.c.

1081 {
1082
1083 /* Disallow non-root hubs */
1084 if ( hub->usb )
1085 return -ENOTSUP;
1086
1087 /* Nothing to do */
1088 return 0;
1089}
struct usb_device * usb
Underlying USB device, if any.
Definition usb.h:857

References ENOTSUP, and usb_hub::usb.

◆ usbio_hub_close()

void usbio_hub_close ( struct usb_hub *hub __unused)
static

Close hub.

Parameters
hubUSB hub

Definition at line 1096 of file usbio.c.

1096 {
1097
1098 /* Nothing to do */
1099}

References __unused.

◆ usbio_root_open()

int usbio_root_open ( struct usb_hub *hub __unused)
static

Open root hub.

Parameters
hubUSB hub
Return values
rcReturn status code

Definition at line 1114 of file usbio.c.

1114 {
1115
1116 /* Nothing to do */
1117 return 0;
1118}

References __unused.

◆ usbio_root_close()

void usbio_root_close ( struct usb_hub *hub __unused)
static

Close root hub.

Parameters
hubUSB hub

Definition at line 1125 of file usbio.c.

1125 {
1126
1127 /* Nothing to do */
1128}

References __unused.

◆ usbio_root_enable()

int usbio_root_enable ( struct usb_hub *hub __unused,
struct usb_port *port __unused )
static

Enable port.

Parameters
hubUSB hub
portUSB port
Return values
rcReturn status code

Definition at line 1137 of file usbio.c.

1138 {
1139
1140 /* Nothing to do */
1141 return 0;
1142}

References __unused, and port.

◆ usbio_root_disable()

int usbio_root_disable ( struct usb_hub *hub __unused,
struct usb_port *port __unused )
static

Disable port.

Parameters
hubUSB hub
portUSB port
Return values
rcReturn status code

Definition at line 1151 of file usbio.c.

1152 {
1153
1154 /* Nothing to do */
1155 return 0;
1156}

References __unused, and port.

◆ usbio_root_speed()

int usbio_root_speed ( struct usb_hub *hub __unused,
struct usb_port * port )
static

Update root hub port speed.

Parameters
hubUSB hub
portUSB port
Return values
rcReturn status code

Definition at line 1165 of file usbio.c.

1166 {
1167
1168 /* Not actually exposed via EFI_USB_IO_PROTOCOL */
1169 port->speed = USB_SPEED_HIGH;
1170 return 0;
1171}
u8 port
Port number.
Definition CIB_PRM.h:3
@ USB_SPEED_HIGH
High speed (480Mbps).
Definition usb.h:53

References __unused, port, and USB_SPEED_HIGH.

◆ usbio_root_clear_tt()

int usbio_root_clear_tt ( struct usb_hub *hub __unused,
struct usb_port *port __unused,
struct usb_endpoint *ep __unused )
static

Clear transaction translator buffer.

Parameters
hubUSB hub
portUSB port
epUSB endpoint
Return values
rcReturn status code

Definition at line 1181 of file usbio.c.

1183 {
1184
1185 /* Should never be called; this is a root hub */
1186 return -ENOTSUP;
1187}

References __unused, ENOTSUP, and port.

◆ usbio_bus_open()

int usbio_bus_open ( struct usb_bus *bus __unused)
static

Open USB bus.

Parameters
busUSB bus
Return values
rcReturn status code

Definition at line 1202 of file usbio.c.

1202 {
1203
1204 /* Nothing to do */
1205 return 0;
1206}

References __unused, and bus.

◆ usbio_bus_close()

void usbio_bus_close ( struct usb_bus *bus __unused)
static

Close USB bus.

Parameters
busUSB bus

Definition at line 1213 of file usbio.c.

1213 {
1214
1215 /* Nothing to do */
1216}

References __unused, and bus.

◆ usbio_bus_poll()

void usbio_bus_poll ( struct usb_bus * bus)
static

Poll USB bus.

Parameters
busUSB bus

Definition at line 1223 of file usbio.c.

1223 {
1224 struct usbio_device *usbio = usb_bus_get_hostdata ( bus );
1225 struct usbio_endpoint *endpoint;
1226
1227 /* Poll all endpoints. We trust that completion handlers are
1228 * minimal and will not do anything that could plausibly
1229 * affect the endpoint list itself.
1230 */
1231 list_for_each_entry ( endpoint, &usbio->endpoints, list )
1232 usbio_endpoint_poll ( endpoint );
1233}
static void usbio_endpoint_poll(struct usbio_endpoint *endpoint)
Poll for completions.
Definition usbio.c:1015

References bus, usbio_device::endpoints, usbio_endpoint::list, list_for_each_entry, usb_bus_get_hostdata(), usbio_endpoint::usbio, and usbio_endpoint_poll().

◆ usbio_supported()

int usbio_supported ( EFI_HANDLE handle)
static

Check to see if driver supports a device.

Parameters
handleEFI device handle
Return values
rcReturn status code

Definition at line 1282 of file usbio.c.

1282 {
1286 struct usb_driver *driver;
1287 struct usb_device_id *id;
1289 EFI_STATUS efirc;
1290 int rc;
1291
1292 /* Get protocol */
1294 &io ) ) != 0 ) {
1295 DBGCP ( handle, "USB %s is not a USB device\n",
1296 efi_handle_name ( handle ) );
1297 return rc;
1298 }
1299
1300 /* Get device descriptor */
1301 if ( ( efirc = io->UsbGetDeviceDescriptor ( io, &device ) ) != 0 ) {
1302 rc = -EEFI ( efirc );
1303 DBGC ( handle, "USB %s could not get device descriptor: "
1304 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1305 return rc;
1306 }
1307 memset ( &desc, 0, sizeof ( desc ) );
1308 desc.vendor = device.IdVendor;
1309 desc.product = device.IdProduct;
1310
1311 /* Get interface descriptor */
1312 if ( ( efirc = io->UsbGetInterfaceDescriptor ( io, &interface ) ) != 0){
1313 rc = -EEFI ( efirc );
1314 DBGC ( handle, "USB %s could not get interface descriptor: "
1315 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1316 return rc;
1317 }
1318 desc.class.class.class = interface.InterfaceClass;
1319 desc.class.class.subclass = interface.InterfaceSubClass;
1320 desc.class.class.protocol = interface.InterfaceProtocol;
1321
1322 /* Look for a driver for this interface */
1323 driver = usb_find_driver ( &desc, &id );
1324 if ( ! driver )
1325 return -ENOTSUP;
1326
1327 return 0;
1328}
USB_DEVICE_DESCRIPTOR EFI_USB_DEVICE_DESCRIPTOR
Definition UsbIo.h:38
USB_INTERFACE_DESCRIPTOR EFI_USB_INTERFACE_DESCRIPTOR
Definition UsbIo.h:40
uint8_t id
Request identifier.
Definition ena.h:1
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define DBGCP(...)
Definition compiler.h:564
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:453
void * memset(void *dest, int character, size_t len) __nonnull
EFI_USB_IO_GET_INTERFACE_DESCRIPTOR UsbGetInterfaceDescriptor
Definition UsbIo.h:494
EFI_USB_IO_GET_DEVICE_DESCRIPTOR UsbGetDeviceDescriptor
Definition UsbIo.h:492
A hardware device.
Definition device.h:77
A USB device ID.
Definition usb.h:1371
A USB driver.
Definition usb.h:1429
A USB function descriptor.
Definition usb.h:667
struct usb_driver * usb_find_driver(struct usb_function_descriptor *desc, struct usb_device_id **id)
Find USB device driver.
Definition usb.c:1166

References DBGC, DBGCP, desc, EEFI, EFI_HANDLE, efi_handle_name(), efi_open, efi_usb_io_protocol_guid, ENOTSUP, handle, id, memset(), rc, strerror(), usb_find_driver(), _EFI_USB_IO_PROTOCOL::UsbGetDeviceDescriptor, and _EFI_USB_IO_PROTOCOL::UsbGetInterfaceDescriptor.

Referenced by __efi_driver().

◆ usbio_config()

int usbio_config ( struct usbio_device * usbio)
static

Fetch configuration descriptor.

Parameters
usbioUSB I/O device
Return values
rcReturn status code

Definition at line 1336 of file usbio.c.

1336 {
1337 EFI_HANDLE handle = usbio->handle;
1338 EFI_USB_IO_PROTOCOL *io = usbio->io;
1341 union {
1342 struct usb_setup_packet setup;
1344 } msg;
1345 UINT32 status;
1346 size_t len;
1347 unsigned int count;
1348 unsigned int value;
1349 unsigned int i;
1350 EFI_STATUS efirc;
1351 int rc;
1352
1353 /* Get device descriptor */
1354 if ( ( efirc = io->UsbGetDeviceDescriptor ( io, &device ) ) != 0 ) {
1355 rc = -EEFI ( efirc );
1356 DBGC ( usbio, "USB %s could not get device descriptor: "
1357 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1358 goto err_get_device_descriptor;
1359 }
1360 count = device.NumConfigurations;
1361
1362 /* Get current partial configuration descriptor */
1363 if ( ( efirc = io->UsbGetConfigDescriptor ( io, &partial ) ) != 0 ) {
1364 rc = -EEFI ( efirc );
1365 DBGC ( usbio, "USB %s could not get partial configuration "
1366 "descriptor: %s\n", efi_handle_name ( handle ),
1367 strerror ( rc ) );
1368 goto err_get_configuration_descriptor;
1369 }
1370 len = le16_to_cpu ( partial.TotalLength );
1371
1372 /* Allocate configuration descriptor */
1373 usbio->config = malloc ( len );
1374 if ( ! usbio->config ) {
1375 rc = -ENOMEM;
1376 goto err_alloc;
1377 }
1378
1379 /* There is, naturally, no way to retrieve the entire device
1380 * configuration descriptor via EFI_USB_IO_PROTOCOL. Worse,
1381 * there is no way to even retrieve the index of the current
1382 * configuration descriptor. We have to iterate over all
1383 * possible configuration descriptors looking for the
1384 * descriptor that matches the current configuration value.
1385 */
1386 for ( i = 0 ; i < count ; i++ ) {
1387
1388 /* Construct request */
1389 msg.setup.request = cpu_to_le16 ( USB_GET_DESCRIPTOR );
1390 value = ( ( USB_CONFIGURATION_DESCRIPTOR << 8 ) | i );
1391 msg.setup.value = cpu_to_le16 ( value );
1392 msg.setup.index = 0;
1393 msg.setup.len = cpu_to_le16 ( len );
1394
1395 /* Get full configuration descriptor */
1396 if ( ( efirc = io->UsbControlTransfer ( io, &msg.efi,
1397 EfiUsbDataIn, 0,
1398 usbio->config, len,
1399 &status ) ) != 0 ) {
1400 rc = -EEFI ( efirc );
1401 DBGC ( usbio, "USB %s could not get configuration %d "
1402 "descriptor: %s\n", efi_handle_name ( handle ),
1403 i, strerror ( rc ) );
1404 goto err_control_transfer;
1405 }
1406
1407 /* Ignore unless this is the current configuration */
1408 if ( usbio->config->config != partial.ConfigurationValue )
1409 continue;
1410
1411 /* Check length */
1412 if ( le16_to_cpu ( usbio->config->len ) != len ) {
1413 DBGC ( usbio, "USB %s configuration descriptor length "
1414 "mismatch\n", efi_handle_name ( handle ) );
1415 rc = -EINVAL;
1416 goto err_len;
1417 }
1418
1419 return 0;
1420 }
1421
1422 /* No match found */
1423 DBGC ( usbio, "USB %s could not find current configuration "
1424 "descriptor\n", efi_handle_name ( handle ) );
1425 rc = -ENOENT;
1426
1427 err_len:
1428 err_control_transfer:
1429 free ( usbio->config );
1430 err_alloc:
1431 err_get_configuration_descriptor:
1432 err_get_device_descriptor:
1433 return rc;
1434}
USB_CONFIG_DESCRIPTOR EFI_USB_CONFIG_DESCRIPTOR
Definition UsbIo.h:39
pseudo_bit_t value[0x00020]
Definition arbel.h:2
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define EINVAL
Invalid argument.
Definition errno.h:472
#define cpu_to_le16(value)
Definition byteswap.h:107
#define USB_CONFIGURATION_DESCRIPTOR
A USB configuration descriptor.
Definition usb.h:228
#define USB_GET_DESCRIPTOR
Get descriptor.
Definition usb.h:137
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677
UINT8 ConfigurationValue
Definition Usb.h:132
UINT16 TotalLength
Definition Usb.h:130
EFI_USB_IO_GET_CONFIG_DESCRIPTOR UsbGetConfigDescriptor
Definition UsbIo.h:493
uint16_t len
Total length.
Definition usb.h:214
EFI_USB_IO_PROTOCOL * io
USB I/O protocol.
Definition usbio.h:130

References usb_configuration_descriptor::config, usbio_device::config, USB_CONFIG_DESCRIPTOR::ConfigurationValue, count, cpu_to_le16, DBGC, EEFI, EFI_HANDLE, efi_handle_name(), EfiUsbDataIn, EINVAL, ENOENT, ENOMEM, free, handle, usbio_device::handle, usbio_device::io, le16_to_cpu, len, usb_configuration_descriptor::len, malloc(), msg(), rc, status, strerror(), USB_CONFIG_DESCRIPTOR::TotalLength, USB_CONFIGURATION_DESCRIPTOR, USB_GET_DESCRIPTOR, _EFI_USB_IO_PROTOCOL::UsbControlTransfer, _EFI_USB_IO_PROTOCOL::UsbGetConfigDescriptor, _EFI_USB_IO_PROTOCOL::UsbGetDeviceDescriptor, and value.

Referenced by usbio_start().

◆ usbio_path()

int usbio_path ( struct usbio_device * usbio)
static

Construct device path for opening other interfaces.

Parameters
usbioUSB I/O device
Return values
rcReturn status code

Definition at line 1442 of file usbio.c.

1442 {
1443 EFI_HANDLE handle = usbio->handle;
1446 USB_DEVICE_PATH *usbpath;
1447 size_t len;
1448 int rc;
1449
1450 /* Open device path protocol */
1452 &path ) ) != 0 ) {
1453 DBGC ( usbio, "USBIO %s cannot open device path protocol: "
1454 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1455 return rc;
1456 }
1457
1458 /* Locate end of device path and sanity check */
1459 len = efi_path_len ( path );
1460 if ( len < sizeof ( *usbpath ) ) {
1461 DBGC ( usbio, "USBIO %s underlength device path\n",
1462 efi_handle_name ( handle ) );
1463 return -EINVAL;
1464 }
1465 usbpath = ( ( ( void * ) path ) + len - sizeof ( *usbpath ) );
1466 if ( ! ( ( usbpath->Header.Type == MESSAGING_DEVICE_PATH ) &&
1467 ( usbpath->Header.SubType == MSG_USB_DP ) ) ) {
1468 DBGC ( usbio, "USBIO %s not a USB device path: ",
1469 efi_handle_name ( handle ) );
1470 DBGC ( usbio, "%s\n", efi_devpath_text ( path ) );
1471 return -EINVAL;
1472 }
1473
1474 /* Allocate copy of device path */
1475 usbio->path = malloc ( len + sizeof ( *end ) );
1476 if ( ! usbio->path )
1477 return -ENOMEM;
1478 memcpy ( usbio->path, path, ( len + sizeof ( *end ) ) );
1479 usbio->usbpath = ( ( ( void * ) usbio->path ) + len -
1480 sizeof ( *usbpath ) );
1481
1482 return 0;
1483}
#define MSG_USB_DP
USB Device Path SubType.
Definition DevicePath.h:420
#define MESSAGING_DEVICE_PATH
Messaging Device Paths.
Definition DevicePath.h:323
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:170
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator).
Definition efi_path.c:178
UINT8 Type
0x01 Hardware Device Path.
Definition DevicePath.h:46
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition DevicePath.h:53
EFI_DEVICE_PATH_PROTOCOL Header
Definition DevicePath.h:422

References DBGC, efi_device_path_protocol_guid, efi_devpath_text(), EFI_HANDLE, efi_handle_name(), efi_open, efi_path_len(), EINVAL, end, ENOMEM, handle, usbio_device::handle, USB_DEVICE_PATH::Header, len, malloc(), memcpy(), MESSAGING_DEVICE_PATH, MSG_USB_DP, usbio_device::path, rc, strerror(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, and usbio_device::usbpath.

Referenced by usbio_start().

◆ usbio_interfaces()

int usbio_interfaces ( struct usbio_device * usbio)
static

Construct interface list.

Parameters
usbioUSB I/O device
Return values
rcReturn status code

Definition at line 1491 of file usbio.c.

1491 {
1492 EFI_HANDLE handle = usbio->handle;
1493 EFI_USB_IO_PROTOCOL *io = usbio->io;
1495 unsigned int first;
1496 unsigned int count;
1497 EFI_STATUS efirc;
1498 int rc;
1499
1500 /* Get interface descriptor */
1501 if ( ( efirc = io->UsbGetInterfaceDescriptor ( io, &interface ) ) != 0){
1502 rc = -EEFI ( efirc );
1503 DBGC ( usbio, "USB %s could not get interface descriptor: "
1504 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1505 goto err_get_interface_descriptor;
1506 }
1507
1508 /* Record first interface number */
1509 first = interface.InterfaceNumber;
1510 count = usbio->config->interfaces;
1511 assert ( first < count );
1512 usbio->first = first;
1513
1514 /* Allocate interface list */
1515 usbio->interface = zalloc ( count * sizeof ( usbio->interface[0] ) );
1516 if ( ! usbio->interface ) {
1517 rc = -ENOMEM;
1518 goto err_alloc;
1519 }
1520
1521 /* Use already-opened protocol for control transfers and for
1522 * the first interface.
1523 */
1524 usbio->interface[0].handle = handle;
1525 usbio->interface[0].io = io;
1526 usbio->interface[0].count = 1;
1527 usbio->interface[first].handle = handle;
1528 usbio->interface[first].io = io;
1529 usbio->interface[first].count = 1;
1530
1531 return 0;
1532
1533 free ( usbio->interface );
1534 err_alloc:
1535 err_get_interface_descriptor:
1536 return rc;
1537}
uint32_t first
First block in range.
Definition pccrr.h:1
uint8_t interfaces
Number of interfaces.
Definition usb.h:216

References assert, usbio_device::config, count, usbio_interface::count, DBGC, EEFI, EFI_HANDLE, efi_handle_name(), ENOMEM, first, usbio_device::first, free, handle, usbio_device::handle, usbio_interface::handle, usbio_device::interface, usb_configuration_descriptor::interfaces, usbio_device::io, usbio_interface::io, rc, strerror(), _EFI_USB_IO_PROTOCOL::UsbGetInterfaceDescriptor, and zalloc().

Referenced by usbio_start().

◆ usbio_exclude()

int usbio_exclude ( EFI_HANDLE device)
static

Exclude existing drivers.

Parameters
deviceEFI device handle
Return values
rcReturn status code

Definition at line 1545 of file usbio.c.

1545 {
1547 int rc;
1548
1549 /* Exclude existing USB I/O protocol drivers */
1550 if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
1551 DBGC ( device, "USBIO %s could not exclude drivers: %s\n",
1552 efi_handle_name ( device ), strerror ( rc ) );
1553 return rc;
1554 }
1555
1556 return 0;
1557}
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
int efi_driver_exclude(EFI_HANDLE device, EFI_GUID *protocol)
Try to disconnect an existing EFI driver.
Definition efi_driver.c:438
uint16_t protocol
Protocol ID.
Definition stp.h:7

References DBGC, efi_driver_exclude(), EFI_HANDLE, efi_handle_name(), efi_usb_io_protocol_guid, protocol, rc, and strerror().

Referenced by __efi_driver().

◆ usbio_start()

int usbio_start ( struct efi_device * efidev)
static

Attach driver to device.

Parameters
efidevEFI device
Return values
rcReturn status code

Definition at line 1565 of file usbio.c.

1565 {
1566 EFI_HANDLE handle = efidev->device;
1567 struct usbio_device *usbio;
1568 struct usb_port *port;
1569 int rc;
1570
1571 /* Allocate and initialise structure */
1572 usbio = zalloc ( sizeof ( *usbio ) );
1573 if ( ! usbio ) {
1574 rc = -ENOMEM;
1575 goto err_alloc;
1576 }
1577 efidev_set_drvdata ( efidev, usbio );
1578 usbio->handle = handle;
1579 INIT_LIST_HEAD ( &usbio->endpoints );
1580
1581 /* Open USB I/O protocol */
1583 &usbio->io ) ) != 0 ) {
1584 DBGC ( usbio, "USBIO %s cannot open USB I/O protocol: %s\n",
1585 efi_handle_name ( handle ), strerror ( rc ) );
1587 goto err_open_usbio;
1588 }
1589
1590 /* Describe generic device */
1591 efi_device_info ( handle, "USB", &usbio->dev );
1592 usbio->dev.parent = &efidev->dev;
1593 list_add ( &usbio->dev.siblings, &efidev->dev.children );
1594 INIT_LIST_HEAD ( &usbio->dev.children );
1595
1596 /* Fetch configuration descriptor */
1597 if ( ( rc = usbio_config ( usbio ) ) != 0 )
1598 goto err_config;
1599
1600 /* Construct device path */
1601 if ( ( rc = usbio_path ( usbio ) ) != 0 )
1602 goto err_path;
1603
1604 /* Construct interface list */
1605 if ( ( rc = usbio_interfaces ( usbio ) ) != 0 )
1606 goto err_interfaces;
1607
1608 /* Allocate USB bus */
1609 usbio->bus = alloc_usb_bus ( &usbio->dev, 1 /* single "port" */,
1611 if ( ! usbio->bus ) {
1612 rc = -ENOMEM;
1613 goto err_alloc_bus;
1614 }
1615 usb_bus_set_hostdata ( usbio->bus, usbio );
1616 usb_hub_set_drvdata ( usbio->bus->hub, usbio );
1617
1618 /* Set port protocol */
1619 port = usb_port ( usbio->bus->hub, 1 );
1620 port->protocol = USB_PROTO_2_0;
1621
1622 /* Register USB bus */
1623 if ( ( rc = register_usb_bus ( usbio->bus ) ) != 0 )
1624 goto err_register;
1625
1626 return 0;
1627
1628 unregister_usb_bus ( usbio->bus );
1629 err_register:
1630 free_usb_bus ( usbio->bus );
1631 err_alloc_bus:
1632 free ( usbio->interface );
1633 err_interfaces:
1634 free ( usbio->path );
1635 err_path:
1636 free ( usbio->config );
1637 err_config:
1638 list_del ( &usbio->dev.siblings );
1640 err_open_usbio:
1641 free ( usbio );
1642 err_alloc:
1643 return rc;
1644}
static void efidev_set_drvdata(struct efi_device *efidev, void *priv)
Set EFI driver-private data.
Definition efi_driver.h:87
void efi_device_info(EFI_HANDLE device, const char *prefix, struct device *dev)
Get underlying device information.
Definition efi_utils.c:189
@ USB_PROTO_2_0
USB 2.0.
Definition usb.h:23
static struct usb_port * usb_port(struct usb_hub *hub, unsigned int address)
Get USB port.
Definition usb.h:970
static void usb_hub_set_drvdata(struct usb_hub *hub, void *priv)
Set USB hub driver private data.
Definition usb.h:947
static void usb_bus_set_hostdata(struct usb_bus *bus, void *priv)
Set USB bus host controller private data.
Definition usb.h:1061
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
struct device * parent
Bus device.
Definition device.h:89
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
EFI_HANDLE device
EFI device handle.
Definition efi_driver.h:22
struct device dev
Generic device.
Definition efi_driver.h:20
struct usb_hub * hub
Root hub.
Definition usb.h:1005
A USB port.
Definition usb.h:823
struct usb_bus * bus
USB bus.
Definition usbio.h:148
struct device dev
Generic device.
Definition usbio.h:132
USB I/O endpoint operations.
Definition usbio.h:92
void unregister_usb_bus(struct usb_bus *bus)
Unregister USB bus.
Definition usb.c:2170
int register_usb_bus(struct usb_bus *bus)
Register USB bus.
Definition usb.c:2130
struct usb_bus * alloc_usb_bus(struct device *dev, unsigned int ports, size_t mtu, struct usb_host_operations *op)
Allocate USB bus.
Definition usb.c:2094
void free_usb_bus(struct usb_bus *bus)
Free USB bus.
Definition usb.c:2194
static int usbio_path(struct usbio_device *usbio)
Construct device path for opening other interfaces.
Definition usbio.c:1442
static int usbio_config(struct usbio_device *usbio)
Fetch configuration descriptor.
Definition usbio.c:1336
static int usbio_interfaces(struct usbio_device *usbio)
Construct interface list.
Definition usbio.c:1491
#define USBIO_MTU
USB I/O maximum transfer size.
Definition usbio.h:24

References alloc_usb_bus(), usbio_device::bus, device::children, usbio_device::config, DBGC, DBGC_EFI_OPENERS, efi_device::dev, usbio_device::dev, efi_device::device, efi_close_by_driver(), efi_device_info(), EFI_HANDLE, efi_handle_name(), efi_open_by_driver, efi_usb_io_protocol_guid, efidev_set_drvdata(), usbio_device::endpoints, ENOMEM, free, free_usb_bus(), handle, usbio_device::handle, usb_bus::hub, INIT_LIST_HEAD, usbio_device::interface, usbio_device::io, list_add, list_del, device::parent, usbio_device::path, port, rc, register_usb_bus(), device::siblings, strerror(), unregister_usb_bus(), usb_bus_set_hostdata(), usb_hub_set_drvdata(), usb_port(), USB_PROTO_2_0, usbio_config(), usbio_interfaces(), USBIO_MTU, usbio_path(), and zalloc().

Referenced by __efi_driver().

◆ usbio_stop()

void usbio_stop ( struct efi_device * efidev)
static

Detach driver from device.

Parameters
efidevEFI device

Definition at line 1651 of file usbio.c.

1651 {
1652 EFI_HANDLE handle = efidev->device;
1653 struct usbio_device *usbio = efidev_get_drvdata ( efidev );
1654
1655 unregister_usb_bus ( usbio->bus );
1656 free_usb_bus ( usbio->bus );
1657 free ( usbio->interface );
1658 free ( usbio->path );
1659 free ( usbio->config );
1660 list_del ( &usbio->dev.siblings );
1662 free ( usbio );
1663}
static void * efidev_get_drvdata(struct efi_device *efidev)
Get EFI driver-private data.
Definition efi_driver.h:98

References usbio_device::bus, usbio_device::config, usbio_device::dev, efi_device::device, efi_close_by_driver(), EFI_HANDLE, efi_usb_io_protocol_guid, efidev_get_drvdata(), free, free_usb_bus(), handle, usbio_device::interface, list_del, usbio_device::path, device::siblings, and unregister_usb_bus().

Referenced by __efi_driver().

◆ __efi_driver()

struct efi_driver usbio_driver __efi_driver ( EFI_DRIVER_HARDWARE )

Variable Documentation

◆ usbio_control_operations

struct usbio_operations usbio_control_operations
static
Initial value:
= {
}
static void usbio_control_close(struct usbio_endpoint *endpoint __unused)
Close control endpoint.
Definition usbio.c:288
static int usbio_control_open(struct usbio_endpoint *endpoint __unused)
Open control endpoint.
Definition usbio.c:277
static void usbio_control_poll(struct usbio_endpoint *endpoint)
Poll control endpoint.
Definition usbio.c:298

Control endpoint operations.

Definition at line 407 of file usbio.c.

407 {
408 .open = usbio_control_open,
409 .close = usbio_control_close,
410 .poll = usbio_control_poll,
411};

Referenced by usbio_endpoint_open().

◆ usbio_bulk_in_operations

struct usbio_operations usbio_bulk_in_operations
static
Initial value:
= {
}
static void usbio_bulk_in_poll(struct usbio_endpoint *endpoint)
Poll bulk IN endpoint.
Definition usbio.c:447
static void usbio_bulk_in_close(struct usbio_endpoint *endpoint __unused)
Close bulk IN endpoint.
Definition usbio.c:437
static int usbio_bulk_in_open(struct usbio_endpoint *endpoint __unused)
Open bulk IN endpoint.
Definition usbio.c:426

Bulk endpoint operations.

Definition at line 500 of file usbio.c.

500 {
501 .open = usbio_bulk_in_open,
502 .close = usbio_bulk_in_close,
503 .poll = usbio_bulk_in_poll,
504};

Referenced by usbio_endpoint_open().

◆ usbio_bulk_out_operations

struct usbio_operations usbio_bulk_out_operations
static
Initial value:
= {
}
static void usbio_bulk_out_close(struct usbio_endpoint *endpoint __unused)
Close bulk OUT endpoint.
Definition usbio.c:530
static int usbio_bulk_out_open(struct usbio_endpoint *endpoint __unused)
Open bulk OUT endpoint.
Definition usbio.c:519
static void usbio_bulk_out_poll(struct usbio_endpoint *endpoint)
Poll bulk OUT endpoint.
Definition usbio.c:540

Bulk endpoint operations.

Definition at line 601 of file usbio.c.

601 {
602 .open = usbio_bulk_out_open,
603 .close = usbio_bulk_out_close,
604 .poll = usbio_bulk_out_poll,
605};

Referenced by usbio_endpoint_open().

◆ usbio_interrupt_operations

struct usbio_operations usbio_interrupt_operations
static
Initial value:
= {
}
static void usbio_interrupt_close(struct usbio_endpoint *endpoint)
Close interrupt endpoint.
Definition usbio.c:750
static int usbio_interrupt_open(struct usbio_endpoint *endpoint)
Open interrupt endpoint.
Definition usbio.c:692
static void usbio_interrupt_poll(struct usbio_endpoint *endpoint)
Poll interrupt endpoint.
Definition usbio.c:767

Interrupt endpoint operations.

Definition at line 799 of file usbio.c.

799 {
800 .open = usbio_interrupt_open,
801 .close = usbio_interrupt_close,
802 .poll = usbio_interrupt_poll,
803};

Referenced by usbio_endpoint_open().

◆ usbio_operations

struct usb_host_operations usbio_operations
static

USB I/O host controller driver operations.

Definition at line 1243 of file usbio.c.

1243 {
1244 .endpoint = {
1245 .open = usbio_endpoint_open,
1246 .close = usbio_endpoint_close,
1247 .reset = usbio_endpoint_reset,
1248 .mtu = usbio_endpoint_mtu,
1249 .message = usbio_endpoint_message,
1250 .stream = usbio_endpoint_stream,
1251 },
1252 .device = {
1253 .open = usbio_device_open,
1254 .close = usbio_device_close,
1255 .address = usbio_device_address,
1256 },
1257 .bus = {
1258 .open = usbio_bus_open,
1259 .close = usbio_bus_close,
1260 .poll = usbio_bus_poll,
1261 },
1262 .hub = {
1263 .open = usbio_hub_open,
1264 .close = usbio_hub_close,
1265 },
1266 .root = {
1267 .open = usbio_root_open,
1268 .close = usbio_root_close,
1269 .enable = usbio_root_enable,
1270 .disable = usbio_root_disable,
1271 .speed = usbio_root_speed,
1272 .clear_tt = usbio_root_clear_tt,
1273 },
1274};
static int usbio_device_address(struct usb_device *usb __unused)
Assign device address.
Definition usbio.c:1062
static int usbio_endpoint_open(struct usb_endpoint *ep)
Open endpoint.
Definition usbio.c:818
static int usbio_endpoint_message(struct usb_endpoint *ep, struct io_buffer *iobuf)
Enqueue message transfer.
Definition usbio.c:983
static int usbio_root_disable(struct usb_hub *hub __unused, struct usb_port *port __unused)
Disable port.
Definition usbio.c:1151
static int usbio_endpoint_mtu(struct usb_endpoint *ep __unused)
Update MTU.
Definition usbio.c:938
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.
Definition usbio.c:1181
static void usbio_root_close(struct usb_hub *hub __unused)
Close root hub.
Definition usbio.c:1125
static int usbio_bus_open(struct usb_bus *bus __unused)
Open USB bus.
Definition usbio.c:1202
static int usbio_device_open(struct usb_device *usb)
Open device.
Definition usbio.c:1038
static int usbio_hub_open(struct usb_hub *hub)
Open hub.
Definition usbio.c:1081
static void usbio_bus_close(struct usb_bus *bus __unused)
Close USB bus.
Definition usbio.c:1213
static int usbio_root_open(struct usb_hub *hub __unused)
Open root hub.
Definition usbio.c:1114
static int usbio_root_enable(struct usb_hub *hub __unused, struct usb_port *port __unused)
Enable port.
Definition usbio.c:1137
static int usbio_endpoint_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int zlp)
Enqueue stream transfer.
Definition usbio.c:1003
static int usbio_root_speed(struct usb_hub *hub __unused, struct usb_port *port)
Update root hub port speed.
Definition usbio.c:1165
static void usbio_bus_poll(struct usb_bus *bus)
Poll USB bus.
Definition usbio.c:1223
static void usbio_hub_close(struct usb_hub *hub __unused)
Close hub.
Definition usbio.c:1096
static int usbio_endpoint_reset(struct usb_endpoint *ep __unused)
Reset endpoint.
Definition usbio.c:926
static void usbio_device_close(struct usb_device *usb __unused)
Close device.
Definition usbio.c:1051
static void usbio_endpoint_close(struct usb_endpoint *ep)
Close endpoint.
Definition usbio.c:894