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:181
#define EINFO_ENOTSUP
Definition errno.h:591

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;
138
139 /* Skip non-interface descriptors */
140 if ( interface->header.type != USB_INTERFACE_DESCRIPTOR )
141 continue;
142
143 /* Iterate over all endpoint descriptors looking for a match */
144 for_each_interface_descriptor ( endpoint, config, interface ) {
145
146 /* Skip non-endpoint descriptors */
147 if ( endpoint->header.type != USB_ENDPOINT_DESCRIPTOR )
148 continue;
149
150 /* Check endpoint address */
151 if ( endpoint->endpoint != ep->address )
152 continue;
153
154 /* Check interface belongs to this function */
156
157 /* Skip non-matching functions */
158 if ( func->interface[0] != usbio->first )
159 continue;
160
161 /* Iterate over all interfaces for a match */
162 for ( i = 0 ; i < func->desc.count ; i++ ) {
163 if ( interface->interface ==
164 func->interface[i] )
165 return interface->interface;
166 }
167 }
168 }
169 }
170
171 DBGC ( usbio, "USBIO %s cannot find interface for %s",
173 return -ENOENT;
174}
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
#define DBGC(...)
Definition compiler.h:505
#define ENOENT
No such file or directory.
Definition errno.h:515
#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 for_each_interface_descriptor(desc, config, interface)
Iterate over all configuration descriptors within an interface descriptor.
Definition usb.h:394
#define for_each_config_descriptor(desc, config)
Iterate over all configuration descriptors.
Definition usb.h:386
#define USB_EP0_ADDRESS
Control endpoint address.
Definition usb.h:501
#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
uint8_t type
Descriptor type.
Definition usb.h:177
A USB device.
Definition usb.h:723
struct list_head functions
List of functions.
Definition usb.h:737
struct usb_endpoint * ep[32]
Endpoint list.
Definition usb.h:745
A USB endpoint descriptor.
Definition usb.h:264
uint8_t endpoint
Endpoint address.
Definition usb.h:268
struct usb_descriptor_header header
Descriptor header.
Definition usb.h:266
struct usb_device * usb
USB device.
Definition usb.h:406
unsigned int address
Endpoint address.
Definition usb.h:408
unsigned int count
Number of interfaces.
Definition usb.h:665
A USB function.
Definition usb.h:674
struct usb_device * usb
USB device.
Definition usb.h:678
struct usb_function_descriptor desc
Function descriptor.
Definition usb.h:680
uint8_t interface[0]
List of interface numbers.
Definition usb.h:697
struct list_head list
List of functions within this USB device.
Definition usb.h:684
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:221

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_endpoint_descriptor::header, usb_function::interface, usb_function::list, list_for_each_entry, usb_descriptor_header::type, 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 183 of file usbio.c.

183 {
184 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
185 EFI_HANDLE handle = usbio->handle;
186 struct usbio_interface *intf = &usbio->interface[interface];
189 USB_DEVICE_PATH *usbpath;
190 EFI_STATUS efirc;
191 int rc;
192
193 /* Sanity check */
194 assert ( interface < usbio->config->interfaces );
195
196 /* If interface is already open, just increment the usage count */
197 if ( intf->count ) {
198 intf->count++;
199 return 0;
200 }
201
202 /* Construct device path for this interface */
203 path = usbio->path;
204 usbpath = usbio->usbpath;
205 usbpath->InterfaceNumber = interface;
206 end = efi_path_end ( path );
207
208 /* Locate handle for this endpoint's interface */
209 if ( ( efirc = bs->LocateDevicePath ( &efi_usb_io_protocol_guid, &path,
210 &intf->handle ) ) != 0 ) {
211 rc = -EEFI ( efirc );
212 DBGC ( usbio, "USBIO %s could not locate ",
214 DBGC ( usbio, "%s: %s\n",
215 efi_devpath_text ( usbio->path ), strerror ( rc ) );
216 return rc;
217 }
218
219 /* Check that expected path was located */
220 if ( path != end ) {
221 DBGC ( usbio, "USBIO %s located incomplete ",
223 DBGC ( usbio, "%s\n", efi_handle_name ( intf->handle ) );
224 return -EXDEV;
225 }
226
227 /* Open USB I/O protocol on this handle */
228 if ( ( rc = efi_open_by_driver ( intf->handle,
230 &intf->io ) ) != 0 ) {
231 DBGC ( usbio, "USBIO %s cannot open ",
233 DBGC ( usbio, "%s: %s\n",
234 efi_handle_name ( intf->handle ), strerror ( rc ) );
235 DBGC_EFI_OPENERS ( usbio, intf->handle,
237 return rc;
238 }
239
240 /* Increment usage count */
241 intf->count++;
242
243 return 0;
244}
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:50
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:429
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition efi_path.c:163
#define EXDEV
Improper link.
Definition errno.h:685
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition efi.h:474
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
#define DBGC_EFI_OPENERS(...)
Definition efi.h:345
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:1931
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition UefiSpec.h:1972
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition DevicePath.h:46
UINT8 InterfaceNumber
USB Interface Number.
Definition DevicePath.h:431
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 252 of file usbio.c.

252 {
253 struct usbio_interface *intf = &usbio->interface[interface];
254
255 /* Sanity checks */
256 assert ( interface < usbio->config->interfaces );
257 assert ( intf->count > 0 );
258
259 /* Decrement usage count */
260 intf->count--;
261
262 /* Do nothing if interface is still in use */
263 if ( intf->count )
264 return;
265
266 /* Close USB I/O protocol */
268}
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 283 of file usbio.c.

283 {
284
285 /* Nothing to do */
286 return 0;
287}

References __unused.

◆ usbio_control_close()

void usbio_control_close ( struct usbio_endpoint *endpoint __unused)
static

Close control endpoint.

Parameters
endpointEndpoint

Definition at line 294 of file usbio.c.

294 {
295
296 /* Nothing to do */
297}

References __unused.

◆ usbio_control_poll()

void usbio_control_poll ( struct usbio_endpoint * endpoint)
static

Poll control endpoint.

Parameters
endpointEndpoint

Definition at line 304 of file usbio.c.

304 {
305 struct usbio_device *usbio = endpoint->usbio;
306 struct usb_endpoint *ep = endpoint->ep;
307 EFI_HANDLE handle = usbio->handle;
309 union {
310 struct usb_setup_packet setup;
312 } *msg;
314 struct io_buffer *iobuf;
315 unsigned int index;
316 unsigned int flags;
317 unsigned int recipient;
318 unsigned int interface;
320 void *data;
321 size_t len;
323 EFI_STATUS efirc;
324 int rc;
325
326 /* Do nothing if ring is empty */
327 if ( endpoint->cons == endpoint->prod )
328 return;
329
330 /* Consume next transfer */
331 index = ( endpoint->cons++ % USBIO_RING_COUNT );
332 iobuf = endpoint->iobuf[index];
333 flags = endpoint->flags[index];
334
335 /* Sanity check */
336 if ( ! ( flags & USBIO_MESSAGE ) ) {
337 DBGC ( usbio, "USBIO %s %s non-message transfer\n",
339 rc = -ENOTSUP;
340 goto err_not_message;
341 }
342
343 /* Construct transfer */
344 msg = iob_push ( iobuf, sizeof ( *msg ) );
345 iob_pull ( iobuf, sizeof ( *msg ) );
346 request = le16_to_cpu ( msg->setup.request );
347 len = iob_len ( iobuf );
348 if ( len ) {
349 data = iobuf->data;
350 direction = ( ( request & USB_DIR_IN ) ?
352 } else {
353 data = NULL;
355 }
356
357 /* Determine interface for this transfer */
358 recipient = ( request & USB_RECIP_MASK );
359 if ( recipient == USB_RECIP_INTERFACE ) {
360 /* Recipient is an interface: use interface number directly */
361 interface = le16_to_cpu ( msg->setup.index );
362 } else {
363 /* Route all other requests through the first interface */
364 interface = 0;
365 }
366
367 /* Open interface */
368 if ( ( rc = usbio_open ( usbio, interface ) ) != 0 )
369 goto err_open;
370 io = usbio->interface[interface].io;
371
372 /* Due to the design of EFI_USB_IO_PROTOCOL, attempting to set
373 * the configuration to a non-default value is basically a
374 * self-destruct button.
375 */
376 if ( ( request == USB_SET_CONFIGURATION ) &&
377 ( le16_to_cpu ( msg->setup.value ) != usbio->config->config ) ) {
379 DBGC ( usbio, "USBIO %s cannot change configuration: %s\n",
381 goto err_moronic_specification;
382 }
383
384 /* Submit transfer */
385 if ( ( efirc = io->UsbControlTransfer ( io, &msg->efi, direction, 0,
386 data, len, &status ) ) != 0 ) {
387 rc = -EEFI ( efirc );
388 DBGC ( usbio, "USBIO %s %s could not submit control transfer ",
390 DBGC ( usbio, "via %s: %s (status %04x)\n",
392 strerror ( rc ), status );
393 goto err_transfer;
394 }
395
396 /* Close interface */
397 usbio_close ( usbio, interface );
398
399 /* Complete transfer */
400 usb_complete ( ep, iobuf );
401
402 return;
403
404 err_transfer:
405 err_moronic_specification:
406 usbio_close ( usbio, interface );
407 err_open:
408 err_not_message:
409 usb_complete_err ( ep, iobuf, rc );
410}
unsigned int UINT32
4-byte unsigned value.
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
EFI_USB_DATA_DIRECTION
USB data transfer direction.
Definition UsbIo.h:47
@ EfiUsbNoData
Definition UsbIo.h:50
@ EfiUsbDataIn
Definition UsbIo.h:48
@ EfiUsbDataOut
Definition UsbIo.h:49
struct _EFI_USB_IO_PROTOCOL EFI_USB_IO_PROTOCOL
Definition UsbIo.h:29
USB_DEVICE_REQUEST EFI_USB_DEVICE_REQUEST
Definition UsbIo.h:38
unsigned short uint16_t
Definition stdint.h:11
long index
Definition bigint.h:65
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:590
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:1087
#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:89
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
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:483
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
A USB endpoint.
Definition usb.h:404
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:587
static void usbio_close(struct usbio_device *usbio, unsigned int interface)
Close USB I/O interface.
Definition usbio.c:252
static int usbio_open(struct usbio_device *usbio, unsigned int interface)
Open USB I/O interface.
Definition usbio.c:183
#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 432 of file usbio.c.

432 {
433
434 /* Nothing to do */
435 return 0;
436}

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 443 of file usbio.c.

443 {
444
445 /* Nothing to do */
446}

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 453 of file usbio.c.

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

525 {
526
527 /* Nothing to do */
528 return 0;
529}

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 536 of file usbio.c.

536 {
537
538 /* Nothing to do */
539}

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 546 of file usbio.c.

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

655 {
656 struct usbio_interrupt_ring *intr = context;
657 struct usbio_endpoint *endpoint = intr->endpoint;
658 struct usbio_device *usbio = endpoint->usbio;
659 struct usb_endpoint *ep = endpoint->ep;
660 EFI_HANDLE handle = usbio->handle;
661 unsigned int fill;
662 unsigned int index;
663
664 /* Sanity check */
666
667 /* Do nothing if ring is empty */
668 fill = ( intr->prod - intr->cons );
669 if ( fill >= USBIO_INTR_COUNT ) {
670 DBGC ( usbio, "USBIO %s %s dropped interrupt completion\n",
672 return 0;
673 }
674
675 /* Do nothing if transfer was unsuccessful */
676 if ( status != 0 ) {
677 DBGC ( usbio, "USBIO %s %s interrupt completion status %04x\n",
679 status );
680 return 0; /* Unclear what failure actually means here */
681 }
682
683 /* Copy data to buffer and increment producer counter */
684 index = ( intr->prod % USBIO_INTR_COUNT );
685 memcpy ( intr->data[index], data, len );
686 intr->len[index] = len;
687 intr->prod++;
688
689 return 0;
690}
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 698 of file usbio.c.

698 {
699 struct usbio_device *usbio = endpoint->usbio;
701 struct usb_endpoint *ep = endpoint->ep;
702 EFI_USB_IO_PROTOCOL *io = endpoint->io;
703 EFI_HANDLE handle = usbio->handle;
704 unsigned int interval;
705 unsigned int i;
706 void *data;
707 EFI_STATUS efirc;
708 int rc;
709
710 /* Allocate interrupt ring buffer */
711 intr = zalloc ( sizeof ( *intr ) + ( USBIO_INTR_COUNT * ep->mtu ) );
712 if ( ! intr ) {
713 rc = -ENOMEM;
714 goto err_alloc;
715 }
716 endpoint->intr = intr;
717 intr->endpoint = endpoint;
718 data = ( ( ( void * ) intr ) + sizeof ( *intr ) );
719 for ( i = 0 ; i < USBIO_INTR_COUNT ; i++ ) {
720 intr->data[i] = data;
721 data += ep->mtu;
722 }
723
724 /* Determine polling interval */
725 interval = ( ep->interval >> 3 /* microframes -> milliseconds */ );
726 if ( ! interval )
727 interval = 1; /* May not be zero */
728
729 /* Add to periodic schedule */
730 if ( ( efirc = io->UsbAsyncInterruptTransfer ( io, ep->address, TRUE,
731 interval, ep->mtu,
733 intr ) ) != 0 ) {
734 rc = -EEFI ( efirc );
735 DBGC ( usbio, "USBIO %s %s could not schedule interrupt "
736 "transfer: %s\n", efi_handle_name ( handle ),
737 usb_endpoint_name ( ep ), strerror ( rc ) );
738 goto err_schedule;
739 }
740
741 return 0;
742
743 io->UsbAsyncInterruptTransfer ( io, ep->address, FALSE, 0, 0,
744 NULL, NULL );
745 err_schedule:
746 free ( intr );
747 err_alloc:
748 return rc;
749}
#define ENOMEM
Not enough space.
Definition errno.h:535
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER UsbAsyncInterruptTransfer
Definition UsbIo.h:485
size_t mtu
Maximum transfer size.
Definition usb.h:412
unsigned int interval
Interval (in microframes)
Definition usb.h:416
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:653

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 756 of file usbio.c.

756 {
757 struct usb_endpoint *ep = endpoint->ep;
758 EFI_USB_IO_PROTOCOL *io = endpoint->io;
759
760 /* Remove from periodic schedule */
761 io->UsbAsyncInterruptTransfer ( io, ep->address, FALSE, 0, 0,
762 NULL, NULL );
763
764 /* Free interrupt ring buffer */
765 free ( endpoint->intr );
766}

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 773 of file usbio.c.

773 {
775 struct usb_endpoint *ep = endpoint->ep;
776 struct io_buffer *iobuf;
777 unsigned int index;
778 unsigned int intr_index;
779 size_t len;
780
781 /* Do nothing if ring is empty */
782 if ( endpoint->cons == endpoint->prod )
783 return;
784
785 /* Do nothing if interrupt ring is empty */
786 if ( intr->cons == intr->prod )
787 return;
788
789 /* Consume next transfer */
790 index = ( endpoint->cons++ % USBIO_RING_COUNT );
791 iobuf = endpoint->iobuf[index];
792
793 /* Populate I/O buffer */
794 intr_index = ( intr->cons++ % USBIO_INTR_COUNT );
795 len = intr->len[intr_index];
796 assert ( len <= iob_len ( iobuf ) );
797 iob_put ( iobuf, ( len - iob_len ( iobuf ) ) );
798 memcpy ( iobuf->data, intr->data[intr_index], len );
799
800 /* Complete transfer */
801 usb_complete ( ep, iobuf );
802}
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 824 of file usbio.c.

824 {
825 struct usb_bus *bus = ep->usb->port->hub->bus;
826 struct usbio_device *usbio = usb_bus_get_hostdata ( bus );
827 struct usbio_endpoint *endpoint;
829 unsigned int attr = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
830 int interface;
831 int rc;
832
833 /* Allocate and initialise structure */
834 endpoint = zalloc ( sizeof ( *endpoint ) );
835 if ( ! endpoint ) {
836 rc = -ENOMEM;
837 goto err_alloc;
838 }
839 usb_endpoint_set_hostdata ( ep, endpoint );
840 endpoint->usbio = usbio;
841 endpoint->ep = ep;
842
843 /* Identify endpoint operations */
845 endpoint->op = &usbio_control_operations;
846 } else if ( attr == USB_ENDPOINT_ATTR_BULK ) {
847 endpoint->op = ( ( ep->address & USB_DIR_IN ) ?
850 } else if ( attr == USB_ENDPOINT_ATTR_INTERRUPT ) {
851 endpoint->op = &usbio_interrupt_operations;
852 } else {
853 rc = -ENOTSUP;
854 goto err_operations;
855 }
856
857 /* Identify interface for this endpoint */
858 interface = usbio_interface ( usbio, ep );
859 if ( interface < 0 ) {
860 rc = interface;
861 goto err_interface;
862 }
863 endpoint->interface = interface;
864
865 /* Open interface */
866 if ( ( rc = usbio_open ( usbio, interface ) ) != 0 )
867 goto err_open_interface;
868 endpoint->handle = usbio->interface[interface].handle;
869 endpoint->io = usbio->interface[interface].io;
870 DBGC ( usbio, "USBIO %s %s using ",
872 DBGC ( usbio, "%s\n", efi_handle_name ( endpoint->handle ) );
873
874 /* Open endpoint */
875 if ( ( rc = endpoint->op->open ( endpoint ) ) != 0 )
876 goto err_open_endpoint;
877
878 /* Add to list of endpoints */
879 list_add_tail ( &endpoint->list, &usbio->endpoints );
880
881 return 0;
882
883 list_del ( &endpoint->list );
884 endpoint->op->close ( endpoint );
885 err_open_endpoint:
886 usbio_close ( usbio, interface );
887 err_open_interface:
888 err_interface:
889 err_operations:
890 free ( endpoint );
891 err_alloc:
892 return rc;
893}
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:576
#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:1062
#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:966
struct usb_port * port
USB port.
Definition usb.h:727
unsigned int attributes
Attributes.
Definition usb.h:410
struct usb_bus * bus
USB bus.
Definition usb.h:845
struct usb_hub * hub
USB hub.
Definition usb.h:815
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:413
static struct usbio_operations usbio_interrupt_operations
Interrupt endpoint operations.
Definition usbio.c:805
static struct usbio_operations usbio_bulk_in_operations
Bulk endpoint operations.
Definition usbio.c:506
static struct usbio_operations usbio_bulk_out_operations
Bulk endpoint operations.
Definition usbio.c:607

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 900 of file usbio.c.

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

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 932 of file usbio.c.

932 {
933
934 /* Nothing to do */
935 return 0;
936}

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 944 of file usbio.c.

944 {
945
946 /* Nothing to do */
947 return 0;
948}

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 958 of file usbio.c.

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

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 989 of file usbio.c.

990 {
991 struct usb_setup_packet *setup;
992
993 /* Adjust I/O buffer to start of data payload */
994 assert ( iob_len ( iobuf ) >= sizeof ( *setup ) );
995 iob_pull ( iobuf, sizeof ( *setup ) );
996
997 /* Enqueue transfer */
998 return usbio_endpoint_enqueue ( ep, iobuf, USBIO_MESSAGE );
999}
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:958

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 1009 of file usbio.c.

1010 {
1011
1012 /* Enqueue transfer */
1013 return usbio_endpoint_enqueue ( ep, iobuf, ( zlp ? USBIO_ZLEN : 0 ) );
1014}

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 1021 of file usbio.c.

1021 {
1022
1023 /* Do nothing if shutdown is in progress */
1025 return;
1026
1027 /* Poll endpoint */
1028 endpoint->op->poll ( endpoint );
1029}
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 1044 of file usbio.c.

1044 {
1045 struct usbio_device *usbio =
1046 usb_bus_get_hostdata ( usb->port->hub->bus );
1047
1048 usb_set_hostdata ( usb, usbio );
1049 return 0;
1050}
static void usb_set_hostdata(struct usb_device *usb, void *priv)
Set USB device host controller private data.
Definition usb.h:784

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 1057 of file usbio.c.

1057 {
1058
1059 /* Nothing to do */
1060}

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 1068 of file usbio.c.

1068 {
1069
1070 /* Nothing to do */
1071 return 0;
1072}

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 1087 of file usbio.c.

1087 {
1088
1089 /* Disallow non-root hubs */
1090 if ( hub->usb )
1091 return -ENOTSUP;
1092
1093 /* Nothing to do */
1094 return 0;
1095}
struct usb_device * usb
Underlying USB device, if any.
Definition usb.h:847

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 1102 of file usbio.c.

1102 {
1103
1104 /* Nothing to do */
1105}

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 1120 of file usbio.c.

1120 {
1121
1122 /* Nothing to do */
1123 return 0;
1124}

References __unused.

◆ usbio_root_close()

void usbio_root_close ( struct usb_hub *hub __unused)
static

Close root hub.

Parameters
hubUSB hub

Definition at line 1131 of file usbio.c.

1131 {
1132
1133 /* Nothing to do */
1134}

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 1143 of file usbio.c.

1144 {
1145
1146 /* Nothing to do */
1147 return 0;
1148}

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 1157 of file usbio.c.

1158 {
1159
1160 /* Nothing to do */
1161 return 0;
1162}

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 1171 of file usbio.c.

1172 {
1173
1174 /* Not actually exposed via EFI_USB_IO_PROTOCOL */
1175 port->speed = USB_SPEED_HIGH;
1176 return 0;
1177}
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 1187 of file usbio.c.

1189 {
1190
1191 /* Should never be called; this is a root hub */
1192 return -ENOTSUP;
1193}

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 1208 of file usbio.c.

1208 {
1209
1210 /* Nothing to do */
1211 return 0;
1212}

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 1219 of file usbio.c.

1219 {
1220
1221 /* Nothing to do */
1222}

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 1229 of file usbio.c.

1229 {
1230 struct usbio_device *usbio = usb_bus_get_hostdata ( bus );
1231 struct usbio_endpoint *endpoint;
1232
1233 /* Poll all endpoints. We trust that completion handlers are
1234 * minimal and will not do anything that could plausibly
1235 * affect the endpoint list itself.
1236 */
1237 list_for_each_entry ( endpoint, &usbio->endpoints, list )
1238 usbio_endpoint_poll ( endpoint );
1239}
static void usbio_endpoint_poll(struct usbio_endpoint *endpoint)
Poll for completions.
Definition usbio.c:1021

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 1288 of file usbio.c.

1288 {
1292 struct usb_driver *driver;
1293 struct usb_device_id *id;
1295 EFI_STATUS efirc;
1296 int rc;
1297
1298 /* Get protocol */
1300 &io ) ) != 0 ) {
1301 DBGCP ( handle, "USB %s is not a USB device\n",
1302 efi_handle_name ( handle ) );
1303 return rc;
1304 }
1305
1306 /* Get device descriptor */
1307 if ( ( efirc = io->UsbGetDeviceDescriptor ( io, &device ) ) != 0 ) {
1308 rc = -EEFI ( efirc );
1309 DBGC ( handle, "USB %s could not get device descriptor: "
1310 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1311 return rc;
1312 }
1313 memset ( &desc, 0, sizeof ( desc ) );
1314 desc.vendor = device.IdVendor;
1315 desc.product = device.IdProduct;
1316
1317 /* Get interface descriptor */
1318 if ( ( efirc = io->UsbGetInterfaceDescriptor ( io, &interface ) ) != 0){
1319 rc = -EEFI ( efirc );
1320 DBGC ( handle, "USB %s could not get interface descriptor: "
1321 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1322 return rc;
1323 }
1324 desc.class.class.class = interface.InterfaceClass;
1325 desc.class.class.subclass = interface.InterfaceSubClass;
1326 desc.class.class.protocol = interface.InterfaceProtocol;
1327
1328 /* Look for a driver for this interface */
1329 driver = usb_find_driver ( &desc, &id );
1330 if ( ! driver )
1331 return -ENOTSUP;
1332
1333 return 0;
1334}
USB_DEVICE_DESCRIPTOR EFI_USB_DEVICE_DESCRIPTOR
Definition UsbIo.h:39
USB_INTERFACE_DESCRIPTOR EFI_USB_INTERFACE_DESCRIPTOR
Definition UsbIo.h:41
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:539
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:444
void * memset(void *dest, int character, size_t len) __nonnull
EFI_USB_IO_GET_INTERFACE_DESCRIPTOR UsbGetInterfaceDescriptor
Definition UsbIo.h:495
EFI_USB_IO_GET_DEVICE_DESCRIPTOR UsbGetDeviceDescriptor
Definition UsbIo.h:493
A hardware device.
Definition device.h:77
A USB device ID.
Definition usb.h:1361
A USB driver.
Definition usb.h:1419
A USB function descriptor.
Definition usb.h:657
struct usb_driver * usb_find_driver(struct usb_function_descriptor *desc, struct usb_device_id **id)
Find USB device driver.
Definition usb.c:1167

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 1342 of file usbio.c.

1342 {
1343 EFI_HANDLE handle = usbio->handle;
1344 EFI_USB_IO_PROTOCOL *io = usbio->io;
1347 union {
1348 struct usb_setup_packet setup;
1350 } msg;
1351 UINT32 status;
1352 size_t len;
1353 unsigned int count;
1354 unsigned int value;
1355 unsigned int i;
1356 EFI_STATUS efirc;
1357 int rc;
1358
1359 /* Get device descriptor */
1360 if ( ( efirc = io->UsbGetDeviceDescriptor ( io, &device ) ) != 0 ) {
1361 rc = -EEFI ( efirc );
1362 DBGC ( usbio, "USB %s could not get device descriptor: "
1363 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1364 goto err_get_device_descriptor;
1365 }
1366 count = device.NumConfigurations;
1367
1368 /* Get current partial configuration descriptor */
1369 if ( ( efirc = io->UsbGetConfigDescriptor ( io, &partial ) ) != 0 ) {
1370 rc = -EEFI ( efirc );
1371 DBGC ( usbio, "USB %s could not get partial configuration "
1372 "descriptor: %s\n", efi_handle_name ( handle ),
1373 strerror ( rc ) );
1374 goto err_get_configuration_descriptor;
1375 }
1376 len = le16_to_cpu ( partial.TotalLength );
1377
1378 /* Allocate configuration descriptor */
1379 usbio->config = malloc ( len );
1380 if ( ! usbio->config ) {
1381 rc = -ENOMEM;
1382 goto err_alloc;
1383 }
1384
1385 /* There is, naturally, no way to retrieve the entire device
1386 * configuration descriptor via EFI_USB_IO_PROTOCOL. Worse,
1387 * there is no way to even retrieve the index of the current
1388 * configuration descriptor. We have to iterate over all
1389 * possible configuration descriptors looking for the
1390 * descriptor that matches the current configuration value.
1391 */
1392 for ( i = 0 ; i < count ; i++ ) {
1393
1394 /* Construct request */
1395 msg.setup.request = cpu_to_le16 ( USB_GET_DESCRIPTOR );
1396 value = ( ( USB_CONFIGURATION_DESCRIPTOR << 8 ) | i );
1397 msg.setup.value = cpu_to_le16 ( value );
1398 msg.setup.index = 0;
1399 msg.setup.len = cpu_to_le16 ( len );
1400
1401 /* Get full configuration descriptor */
1402 if ( ( efirc = io->UsbControlTransfer ( io, &msg.efi,
1403 EfiUsbDataIn, 0,
1404 usbio->config, len,
1405 &status ) ) != 0 ) {
1406 rc = -EEFI ( efirc );
1407 DBGC ( usbio, "USB %s could not get configuration %d "
1408 "descriptor: %s\n", efi_handle_name ( handle ),
1409 i, strerror ( rc ) );
1410 goto err_control_transfer;
1411 }
1412
1413 /* Ignore unless this is the current configuration */
1414 if ( usbio->config->config != partial.ConfigurationValue )
1415 continue;
1416
1417 /* Check length */
1418 if ( le16_to_cpu ( usbio->config->len ) != len ) {
1419 DBGC ( usbio, "USB %s configuration descriptor length "
1420 "mismatch\n", efi_handle_name ( handle ) );
1421 rc = -EINVAL;
1422 goto err_len;
1423 }
1424
1425 return 0;
1426 }
1427
1428 /* No match found */
1429 DBGC ( usbio, "USB %s could not find current configuration "
1430 "descriptor\n", efi_handle_name ( handle ) );
1431 rc = -ENOENT;
1432
1433 err_len:
1434 err_control_transfer:
1435 free ( usbio->config );
1436 err_alloc:
1437 err_get_configuration_descriptor:
1438 err_get_device_descriptor:
1439 return rc;
1440}
USB_CONFIG_DESCRIPTOR EFI_USB_CONFIG_DESCRIPTOR
Definition UsbIo.h:40
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:429
#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:621
UINT8 ConfigurationValue
Definition Usb.h:133
UINT16 TotalLength
Definition Usb.h:131
EFI_USB_IO_GET_CONFIG_DESCRIPTOR UsbGetConfigDescriptor
Definition UsbIo.h:494
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 1448 of file usbio.c.

1448 {
1449 EFI_HANDLE handle = usbio->handle;
1452 USB_DEVICE_PATH *usbpath;
1453 size_t len;
1454 int rc;
1455
1456 /* Open device path protocol */
1458 &path ) ) != 0 ) {
1459 DBGC ( usbio, "USBIO %s cannot open device path protocol: "
1460 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1461 return rc;
1462 }
1463
1464 /* Locate end of device path and sanity check */
1465 len = efi_path_len ( path );
1466 if ( len < sizeof ( *usbpath ) ) {
1467 DBGC ( usbio, "USBIO %s underlength device path\n",
1468 efi_handle_name ( handle ) );
1469 return -EINVAL;
1470 }
1471 usbpath = ( ( ( void * ) path ) + len - sizeof ( *usbpath ) );
1472 if ( ! ( ( usbpath->Header.Type == MESSAGING_DEVICE_PATH ) &&
1473 ( usbpath->Header.SubType == MSG_USB_DP ) ) ) {
1474 DBGC ( usbio, "USBIO %s not a USB device path: ",
1475 efi_handle_name ( handle ) );
1476 DBGC ( usbio, "%s\n", efi_devpath_text ( path ) );
1477 return -EINVAL;
1478 }
1479
1480 /* Allocate copy of device path */
1481 usbio->path = malloc ( len + sizeof ( *end ) );
1482 if ( ! usbio->path )
1483 return -ENOMEM;
1484 memcpy ( usbio->path, path, ( len + sizeof ( *end ) ) );
1485 usbio->usbpath = ( ( ( void * ) usbio->path ) + len -
1486 sizeof ( *usbpath ) );
1487
1488 return 0;
1489}
#define MSG_USB_DP
USB Device Path SubType.
Definition DevicePath.h:421
#define MESSAGING_DEVICE_PATH
Messaging Device Paths.
Definition DevicePath.h:324
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:169
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition efi_path.c:174
UINT8 Type
0x01 Hardware Device Path.
Definition DevicePath.h:47
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:54
EFI_DEVICE_PATH_PROTOCOL Header
Definition DevicePath.h:423

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 1497 of file usbio.c.

1497 {
1498 EFI_HANDLE handle = usbio->handle;
1499 EFI_USB_IO_PROTOCOL *io = usbio->io;
1501 unsigned int first;
1502 unsigned int count;
1503 EFI_STATUS efirc;
1504 int rc;
1505
1506 /* Get interface descriptor */
1507 if ( ( efirc = io->UsbGetInterfaceDescriptor ( io, &interface ) ) != 0){
1508 rc = -EEFI ( efirc );
1509 DBGC ( usbio, "USB %s could not get interface descriptor: "
1510 "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1511 goto err_get_interface_descriptor;
1512 }
1513
1514 /* Record first interface number */
1515 first = interface.InterfaceNumber;
1516 count = usbio->config->interfaces;
1517 assert ( first < count );
1518 usbio->first = first;
1519
1520 /* Allocate interface list */
1521 usbio->interface = zalloc ( count * sizeof ( usbio->interface[0] ) );
1522 if ( ! usbio->interface ) {
1523 rc = -ENOMEM;
1524 goto err_alloc;
1525 }
1526
1527 /* Use already-opened protocol for control transfers and for
1528 * the first interface.
1529 */
1530 usbio->interface[0].handle = handle;
1531 usbio->interface[0].io = io;
1532 usbio->interface[0].count = 1;
1533 usbio->interface[first].handle = handle;
1534 usbio->interface[first].io = io;
1535 usbio->interface[first].count = 1;
1536
1537 return 0;
1538
1539 free ( usbio->interface );
1540 err_alloc:
1541 err_get_interface_descriptor:
1542 return rc;
1543}
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 1551 of file usbio.c.

1551 {
1553 int rc;
1554
1555 /* Exclude existing USB I/O protocol drivers */
1556 if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
1557 DBGC ( device, "USBIO %s could not exclude drivers: %s\n",
1558 efi_handle_name ( device ), strerror ( rc ) );
1559 return rc;
1560 }
1561
1562 return 0;
1563}
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 1571 of file usbio.c.

1571 {
1572 EFI_HANDLE handle = efidev->device;
1573 struct usbio_device *usbio;
1574 struct usb_port *port;
1575 int rc;
1576
1577 /* Allocate and initialise structure */
1578 usbio = zalloc ( sizeof ( *usbio ) );
1579 if ( ! usbio ) {
1580 rc = -ENOMEM;
1581 goto err_alloc;
1582 }
1583 efidev_set_drvdata ( efidev, usbio );
1584 usbio->handle = handle;
1585 INIT_LIST_HEAD ( &usbio->endpoints );
1586
1587 /* Open USB I/O protocol */
1589 &usbio->io ) ) != 0 ) {
1590 DBGC ( usbio, "USBIO %s cannot open USB I/O protocol: %s\n",
1591 efi_handle_name ( handle ), strerror ( rc ) );
1593 goto err_open_usbio;
1594 }
1595
1596 /* Describe generic device */
1597 efi_device_info ( handle, "USB", &usbio->dev );
1598 usbio->dev.parent = &efidev->dev;
1599 list_add ( &usbio->dev.siblings, &efidev->dev.children );
1600 INIT_LIST_HEAD ( &usbio->dev.children );
1601
1602 /* Fetch configuration descriptor */
1603 if ( ( rc = usbio_config ( usbio ) ) != 0 )
1604 goto err_config;
1605
1606 /* Construct device path */
1607 if ( ( rc = usbio_path ( usbio ) ) != 0 )
1608 goto err_path;
1609
1610 /* Construct interface list */
1611 if ( ( rc = usbio_interfaces ( usbio ) ) != 0 )
1612 goto err_interfaces;
1613
1614 /* Allocate USB bus */
1615 usbio->bus = alloc_usb_bus ( &usbio->dev, 1 /* single "port" */,
1617 if ( ! usbio->bus ) {
1618 rc = -ENOMEM;
1619 goto err_alloc_bus;
1620 }
1621 usb_bus_set_hostdata ( usbio->bus, usbio );
1622 usb_hub_set_drvdata ( usbio->bus->hub, usbio );
1623
1624 /* Set port protocol */
1625 port = usb_port ( usbio->bus->hub, 1 );
1626 port->protocol = USB_PROTO_2_0;
1627
1628 /* Register USB bus */
1629 if ( ( rc = register_usb_bus ( usbio->bus ) ) != 0 )
1630 goto err_register;
1631
1632 return 0;
1633
1634 unregister_usb_bus ( usbio->bus );
1635 err_register:
1636 free_usb_bus ( usbio->bus );
1637 err_alloc_bus:
1638 free ( usbio->interface );
1639 err_interfaces:
1640 free ( usbio->path );
1641 err_path:
1642 free ( usbio->config );
1643 err_config:
1644 list_del ( &usbio->dev.siblings );
1646 err_open_usbio:
1647 free ( usbio );
1648 err_alloc:
1649 return rc;
1650}
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:960
static void usb_hub_set_drvdata(struct usb_hub *hub, void *priv)
Set USB hub driver private data.
Definition usb.h:937
static void usb_bus_set_hostdata(struct usb_bus *bus, void *priv)
Set USB bus host controller private data.
Definition usb.h:1051
#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:995
A USB port.
Definition usb.h:813
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:2171
int register_usb_bus(struct usb_bus *bus)
Register USB bus.
Definition usb.c:2131
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:2095
void free_usb_bus(struct usb_bus *bus)
Free USB bus.
Definition usb.c:2195
static int usbio_path(struct usbio_device *usbio)
Construct device path for opening other interfaces.
Definition usbio.c:1448
static int usbio_config(struct usbio_device *usbio)
Fetch configuration descriptor.
Definition usbio.c:1342
static int usbio_interfaces(struct usbio_device *usbio)
Construct interface list.
Definition usbio.c:1497
#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 1657 of file usbio.c.

1657 {
1658 EFI_HANDLE handle = efidev->device;
1659 struct usbio_device *usbio = efidev_get_drvdata ( efidev );
1660
1661 unregister_usb_bus ( usbio->bus );
1662 free_usb_bus ( usbio->bus );
1663 free ( usbio->interface );
1664 free ( usbio->path );
1665 free ( usbio->config );
1666 list_del ( &usbio->dev.siblings );
1668 free ( usbio );
1669}
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:294
static int usbio_control_open(struct usbio_endpoint *endpoint __unused)
Open control endpoint.
Definition usbio.c:283
static void usbio_control_poll(struct usbio_endpoint *endpoint)
Poll control endpoint.
Definition usbio.c:304

Control endpoint operations.

Definition at line 413 of file usbio.c.

413 {
414 .open = usbio_control_open,
415 .close = usbio_control_close,
416 .poll = usbio_control_poll,
417};

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:453
static void usbio_bulk_in_close(struct usbio_endpoint *endpoint __unused)
Close bulk IN endpoint.
Definition usbio.c:443
static int usbio_bulk_in_open(struct usbio_endpoint *endpoint __unused)
Open bulk IN endpoint.
Definition usbio.c:432

Bulk endpoint operations.

Definition at line 506 of file usbio.c.

506 {
507 .open = usbio_bulk_in_open,
508 .close = usbio_bulk_in_close,
509 .poll = usbio_bulk_in_poll,
510};

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:536
static int usbio_bulk_out_open(struct usbio_endpoint *endpoint __unused)
Open bulk OUT endpoint.
Definition usbio.c:525
static void usbio_bulk_out_poll(struct usbio_endpoint *endpoint)
Poll bulk OUT endpoint.
Definition usbio.c:546

Bulk endpoint operations.

Definition at line 607 of file usbio.c.

607 {
608 .open = usbio_bulk_out_open,
609 .close = usbio_bulk_out_close,
610 .poll = usbio_bulk_out_poll,
611};

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:756
static int usbio_interrupt_open(struct usbio_endpoint *endpoint)
Open interrupt endpoint.
Definition usbio.c:698
static void usbio_interrupt_poll(struct usbio_endpoint *endpoint)
Poll interrupt endpoint.
Definition usbio.c:773

Interrupt endpoint operations.

Definition at line 805 of file usbio.c.

805 {
806 .open = usbio_interrupt_open,
807 .close = usbio_interrupt_close,
808 .poll = usbio_interrupt_poll,
809};

Referenced by usbio_endpoint_open().

◆ usbio_operations

struct usb_host_operations usbio_operations
static

USB I/O host controller driver operations.

Definition at line 1249 of file usbio.c.

1249 {
1250 .endpoint = {
1251 .open = usbio_endpoint_open,
1252 .close = usbio_endpoint_close,
1253 .reset = usbio_endpoint_reset,
1254 .mtu = usbio_endpoint_mtu,
1255 .message = usbio_endpoint_message,
1256 .stream = usbio_endpoint_stream,
1257 },
1258 .device = {
1259 .open = usbio_device_open,
1260 .close = usbio_device_close,
1261 .address = usbio_device_address,
1262 },
1263 .bus = {
1264 .open = usbio_bus_open,
1265 .close = usbio_bus_close,
1266 .poll = usbio_bus_poll,
1267 },
1268 .hub = {
1269 .open = usbio_hub_open,
1270 .close = usbio_hub_close,
1271 },
1272 .root = {
1273 .open = usbio_root_open,
1274 .close = usbio_root_close,
1275 .enable = usbio_root_enable,
1276 .disable = usbio_root_disable,
1277 .speed = usbio_root_speed,
1278 .clear_tt = usbio_root_clear_tt,
1279 },
1280};
static int usbio_device_address(struct usb_device *usb __unused)
Assign device address.
Definition usbio.c:1068
static int usbio_endpoint_open(struct usb_endpoint *ep)
Open endpoint.
Definition usbio.c:824
static int usbio_endpoint_message(struct usb_endpoint *ep, struct io_buffer *iobuf)
Enqueue message transfer.
Definition usbio.c:989
static int usbio_root_disable(struct usb_hub *hub __unused, struct usb_port *port __unused)
Disable port.
Definition usbio.c:1157
static int usbio_endpoint_mtu(struct usb_endpoint *ep __unused)
Update MTU.
Definition usbio.c:944
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:1187
static void usbio_root_close(struct usb_hub *hub __unused)
Close root hub.
Definition usbio.c:1131
static int usbio_bus_open(struct usb_bus *bus __unused)
Open USB bus.
Definition usbio.c:1208
static int usbio_device_open(struct usb_device *usb)
Open device.
Definition usbio.c:1044
static int usbio_hub_open(struct usb_hub *hub)
Open hub.
Definition usbio.c:1087
static void usbio_bus_close(struct usb_bus *bus __unused)
Close USB bus.
Definition usbio.c:1219
static int usbio_root_open(struct usb_hub *hub __unused)
Open root hub.
Definition usbio.c:1120
static int usbio_root_enable(struct usb_hub *hub __unused, struct usb_port *port __unused)
Enable port.
Definition usbio.c:1143
static int usbio_endpoint_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int zlp)
Enqueue stream transfer.
Definition usbio.c:1009
static int usbio_root_speed(struct usb_hub *hub __unused, struct usb_port *port)
Update root hub port speed.
Definition usbio.c:1171
static void usbio_bus_poll(struct usb_bus *bus)
Poll USB bus.
Definition usbio.c:1229
static void usbio_hub_close(struct usb_hub *hub __unused)
Close hub.
Definition usbio.c:1102
static int usbio_endpoint_reset(struct usb_endpoint *ep __unused)
Reset endpoint.
Definition usbio.c:932
static void usbio_device_close(struct usb_device *usb __unused)
Close device.
Definition usbio.c:1057
static void usbio_endpoint_close(struct usb_endpoint *ep)
Close endpoint.
Definition usbio.c:900