iPXE
efi_usb.c File Reference

EFI USB I/O PROTOCOL. More...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_null.h>
#include <ipxe/efi/efi_usb.h>
#include <ipxe/usb.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static const char * efi_usb_direction_name (EFI_USB_DATA_DIRECTION direction)
 Transcribe data direction (for debugging)
static VOID EFIAPI efi_usb_timer (EFI_EVENT event __unused, VOID *context)
 Poll USB bus (from endpoint event timer)
static int efi_usb_mtu (struct efi_usb_interface *usbintf, unsigned int endpoint)
 Get endpoint MTU.
static int efi_usb_is_open (struct efi_usb_interface *usbintf, unsigned int endpoint)
 Check if endpoint is open.
static int efi_usb_open (struct efi_usb_interface *usbintf, unsigned int endpoint, unsigned int attributes, unsigned int interval, struct usb_endpoint_driver_operations *driver)
 Open endpoint.
static void efi_usb_close (struct efi_usb_endpoint *usbep)
 Close endpoint.
static void efi_usb_close_all (struct efi_usb_interface *usbintf)
 Close all endpoints.
static void efi_usb_free_all (struct efi_usb_interface *usbintf)
 Free all endpoints.
static void efi_usb_sync_complete (struct usb_endpoint *ep, struct io_buffer *iobuf __unused, int rc)
 Complete synchronous transfer.
static int efi_usb_sync_transfer (struct efi_usb_interface *usbintf, unsigned int endpoint, unsigned int attributes, unsigned int timeout, void *data, size_t *len)
 Perform synchronous transfer.
static void efi_usb_async_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete asynchronous transfer.
static int efi_usb_async_start (struct efi_usb_interface *usbintf, unsigned int endpoint, unsigned int interval, size_t len, EFI_ASYNC_USB_TRANSFER_CALLBACK callback, void *context)
 Start asynchronous transfer.
static void efi_usb_async_stop (struct efi_usb_interface *usbintf, unsigned int endpoint)
 Stop asynchronous transfer.
static EFI_STATUS EFIAPI efi_usb_control_transfer (EFI_USB_IO_PROTOCOL *usbio, EFI_USB_DEVICE_REQUEST *packet, EFI_USB_DATA_DIRECTION direction, UINT32 timeout, VOID *data, UINTN len, UINT32 *status)
 Perform control transfer.
static EFI_STATUS EFIAPI efi_usb_bulk_transfer (EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN *len, UINTN timeout, UINT32 *status)
 Perform bulk transfer.
static EFI_STATUS EFIAPI efi_usb_sync_interrupt_transfer (EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN *len, UINTN timeout, UINT32 *status)
 Perform synchronous interrupt transfer.
static EFI_STATUS EFIAPI efi_usb_async_interrupt_transfer (EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, BOOLEAN start, UINTN interval, UINTN len, EFI_ASYNC_USB_TRANSFER_CALLBACK callback, VOID *context)
 Perform asynchronous interrupt transfer.
static EFI_STATUS EFIAPI efi_usb_isochronous_transfer (EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN len, UINT32 *status)
 Perform synchronous isochronous transfer.
static EFI_STATUS EFIAPI efi_usb_async_isochronous_transfer (EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN len, EFI_ASYNC_USB_TRANSFER_CALLBACK callback, VOID *context)
 Perform asynchronous isochronous transfers.
static EFI_STATUS EFIAPI efi_usb_get_device_descriptor (EFI_USB_IO_PROTOCOL *usbio, EFI_USB_DEVICE_DESCRIPTOR *efidesc)
 Get device descriptor.
static EFI_STATUS EFIAPI efi_usb_get_config_descriptor (EFI_USB_IO_PROTOCOL *usbio, EFI_USB_CONFIG_DESCRIPTOR *efidesc)
 Get configuration descriptor.
static EFI_STATUS EFIAPI efi_usb_get_interface_descriptor (EFI_USB_IO_PROTOCOL *usbio, EFI_USB_INTERFACE_DESCRIPTOR *efidesc)
 Get interface descriptor.
static EFI_STATUS EFIAPI efi_usb_get_endpoint_descriptor (EFI_USB_IO_PROTOCOL *usbio, UINT8 index, EFI_USB_ENDPOINT_DESCRIPTOR *efidesc)
 Get endpoint descriptor.
static EFI_STATUS EFIAPI efi_usb_get_string_descriptor (EFI_USB_IO_PROTOCOL *usbio, UINT16 language, UINT8 index, CHAR16 **string)
 Get string descriptor.
static EFI_STATUS EFIAPI efi_usb_get_supported_languages (EFI_USB_IO_PROTOCOL *usbio, UINT16 **languages, UINT16 *len)
 Get supported languages.
static EFI_STATUS EFIAPI efi_usb_port_reset (EFI_USB_IO_PROTOCOL *usbio)
 Reset port.
static int efi_usb_install (struct efi_usb_device *usbdev, unsigned int interface)
 Install interface.
static void efi_usb_uninstall (struct efi_usb_interface *usbintf)
 Uninstall interface.
static void efi_usb_uninstall_all (struct efi_usb_device *efiusb)
 Uninstall all interfaces.
static int efi_usb_probe (struct usb_function *func, struct usb_configuration_descriptor *config)
 Probe device.
static void efi_usb_remove (struct usb_function *func)
 Remove device.

Variables

static struct usb_endpoint_driver_operations efi_usb_sync_driver
 Synchronous endpoint operations.
static struct usb_endpoint_driver_operations efi_usb_async_driver
 Asynchronous endpoint operations.
static EFI_USB_IO_PROTOCOL efi_usb_io_protocol
 USB I/O protocol.
static struct usb_device_id efi_usb_ids []
 USB I/O protocol device IDs.
struct usb_driver usbio_driver __usb_fallback_driver
 USB I/O protocol driver.

Detailed Description

EFI USB I/O PROTOCOL.

Definition in file efi_usb.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ efi_usb_direction_name()

const char * efi_usb_direction_name ( EFI_USB_DATA_DIRECTION direction)
static

Transcribe data direction (for debugging)

Parameters
directionData direction
Return values
textTranscribed data direction

Definition at line 52 of file efi_usb.c.

52 {
53
54 switch ( direction ) {
55 case EfiUsbDataIn: return "in";
56 case EfiUsbDataOut: return "out";
57 case EfiUsbNoData: return "none";
58 default: return "<UNKNOWN>";
59 }
60}
@ EfiUsbNoData
Definition UsbIo.h:50
@ EfiUsbDataIn
Definition UsbIo.h:48
@ EfiUsbDataOut
Definition UsbIo.h:49
uint8_t direction
Direction.
Definition ena.h:3

References direction, EfiUsbDataIn, EfiUsbDataOut, and EfiUsbNoData.

Referenced by efi_usb_control_transfer().

◆ efi_usb_timer()

VOID EFIAPI efi_usb_timer ( EFI_EVENT event __unused,
VOID * context )
static

Poll USB bus (from endpoint event timer)

Parameters
eventEFI event
contextEFI USB endpoint

Definition at line 75 of file efi_usb.c.

76 {
77 struct efi_usb_endpoint *usbep = context;
78 struct usb_function *func = usbep->usbintf->usbdev->func;
79
80 /* Poll bus */
81 usb_poll ( func->usb->port->hub->bus );
82
83 /* Refill endpoint */
84 if ( usbep->ep.open )
85 usb_refill ( &usbep->ep );
86}
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition usb.h:1072
struct usb_function * func
The underlying USB function.
Definition efi_usb.h:24
An EFI USB device endpoint.
Definition efi_usb.h:60
struct efi_usb_interface * usbintf
EFI USB device interface.
Definition efi_usb.h:62
void * context
Asynchronous callback context.
Definition efi_usb.h:74
struct usb_endpoint ep
USB endpoint.
Definition efi_usb.h:64
struct efi_usb_device * usbdev
Containing USB device.
Definition efi_usb.h:40
struct usb_port * port
USB port.
Definition usb.h:727
int open
Endpoint is open.
Definition usb.h:419
A USB function.
Definition usb.h:674
struct usb_device * usb
USB device.
Definition usb.h:678
struct usb_bus * bus
USB bus.
Definition usb.h:845
struct usb_hub * hub
USB hub.
Definition usb.h:815
int usb_refill(struct usb_endpoint *ep)
Refill endpoint.
Definition usb.c:711

References __unused, usb_hub::bus, efi_usb_endpoint::context, EFI_EVENT, EFIAPI, efi_usb_endpoint::ep, efi_usb_device::func, usb_port::hub, usb_endpoint::open, usb_device::port, usb_function::usb, usb_poll(), usb_refill(), efi_usb_interface::usbdev, efi_usb_endpoint::usbintf, and VOID.

Referenced by efi_usb_open().

◆ efi_usb_mtu()

int efi_usb_mtu ( struct efi_usb_interface * usbintf,
unsigned int endpoint )
static

Get endpoint MTU.

Parameters
usbintfEFI USB interface
endpointEndpoint address
Return values
mtuEndpoint MTU, or negative error

Definition at line 95 of file efi_usb.c.

96 {
97 struct efi_usb_device *usbdev = usbintf->usbdev;
100
101 /* Locate cached interface descriptor */
102 interface = usb_interface_descriptor ( usbdev->config,
103 usbintf->interface,
104 usbintf->alternate );
105 if ( ! interface ) {
106 DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
107 usbintf->name, usbintf->alternate );
108 return -ENOENT;
109 }
110
111 /* Locate and copy cached endpoint descriptor */
113 if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
114 ( desc->endpoint == endpoint ) )
115 return USB_ENDPOINT_MTU ( le16_to_cpu ( desc->sizes ) );
116 }
117
118 DBGC ( usbdev, "USBDEV %s alt %d ep %02x has no descriptor\n",
119 usbintf->name, usbintf->alternate, endpoint );
120 return -ENOENT;
121}
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define DBGC(...)
Definition compiler.h:505
#define ENOENT
No such file or directory.
Definition errno.h:515
struct ib_cm_path alternate
Alternate path.
Definition ib_mad.h:31
#define le16_to_cpu(value)
Definition byteswap.h:113
#define USB_ENDPOINT_DESCRIPTOR
A USB endpoint descriptor.
Definition usb.h:278
#define for_each_interface_descriptor(desc, config, interface)
Iterate over all configuration descriptors within an interface descriptor.
Definition usb.h:394
#define USB_ENDPOINT_MTU(sizes)
USB endpoint MTU.
Definition usb.h:308
An EFI USB device.
Definition efi_usb.h:20
struct usb_configuration_descriptor * config
Configuration descriptor.
Definition efi_usb.h:26
unsigned int alternate
Alternate setting.
Definition efi_usb.h:47
char name[32]
Name.
Definition efi_usb.h:38
An object interface.
Definition interface.h:125
A USB endpoint descriptor.
Definition usb.h:264
A USB interface descriptor.
Definition usb.h:245

References alternate, efi_usb_interface::alternate, efi_usb_device::config, DBGC, desc, ENOENT, for_each_interface_descriptor, le16_to_cpu, efi_usb_interface::name, USB_ENDPOINT_DESCRIPTOR, USB_ENDPOINT_MTU, and efi_usb_interface::usbdev.

Referenced by efi_usb_open().

◆ efi_usb_is_open()

int efi_usb_is_open ( struct efi_usb_interface * usbintf,
unsigned int endpoint )
static

Check if endpoint is open.

Parameters
usbintfEFI USB interface
endpointEndpoint address
Return values
is_openEndpoint is open

Definition at line 130 of file efi_usb.c.

131 {
132 unsigned int index = USB_ENDPOINT_IDX ( endpoint );
133 struct efi_usb_endpoint *usbep = usbintf->endpoint[index];
134
135 return ( usbep && usbep->ep.open );
136}
long index
Definition bigint.h:65
#define USB_ENDPOINT_IDX(address)
Construct endpoint index from endpoint address.
Definition usb.h:528
struct efi_usb_endpoint * endpoint[32]
Opened endpoints.
Definition efi_usb.h:56

References efi_usb_interface::endpoint, efi_usb_endpoint::ep, index, usb_endpoint::open, USB_ENDPOINT_IDX, and efi_usb_endpoint::usbintf.

Referenced by efi_usb_async_start(), efi_usb_async_stop(), and efi_usb_sync_transfer().

◆ efi_usb_open()

int efi_usb_open ( struct efi_usb_interface * usbintf,
unsigned int endpoint,
unsigned int attributes,
unsigned int interval,
struct usb_endpoint_driver_operations * driver )
static

Open endpoint.

Parameters
usbintfEFI USB interface
endpointEndpoint address
attributesEndpoint attributes
intervalInterval (in milliseconds)
driverDriver operations
Return values
rcReturn status code

Definition at line 148 of file efi_usb.c.

151 {
152 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
153 struct efi_usb_device *usbdev = usbintf->usbdev;
154 struct efi_usb_endpoint *usbep;
155 unsigned int index = USB_ENDPOINT_IDX ( endpoint );
156 int mtu;
157 EFI_STATUS efirc;
158 int rc;
159
160 /* Allocate structure, if needed. Once allocated, we leave
161 * the endpoint structure in place until the device is
162 * removed, to work around external UEFI code that closes the
163 * endpoint at illegal times.
164 */
165 usbep = usbintf->endpoint[index];
166 if ( ! usbep ) {
167 usbep = zalloc ( sizeof ( *usbep ) );
168 if ( ! usbep ) {
169 rc = -ENOMEM;
170 goto err_alloc;
171 }
172 usbep->usbintf = usbintf;
173 usbintf->endpoint[index] = usbep;
174 }
175
176 /* Get endpoint MTU */
177 mtu = efi_usb_mtu ( usbintf, endpoint );
178 if ( mtu < 0 ) {
179 rc = mtu;
180 goto err_mtu;
181 }
182
183 /* Allocate and initialise structure */
184 usb_endpoint_init ( &usbep->ep, usbdev->func->usb, driver );
185 usb_endpoint_describe ( &usbep->ep, endpoint, attributes, mtu, 0,
186 ( interval << 3 /* microframes */ ) );
187
188 /* Open endpoint */
189 if ( ( rc = usb_endpoint_open ( &usbep->ep ) ) != 0 ) {
190 DBGC ( usbdev, "USBDEV %s %s could not open: %s\n",
191 usbintf->name, usb_endpoint_name ( &usbep->ep ),
192 strerror ( rc ) );
193 goto err_open;
194 }
195 DBGC ( usbdev, "USBDEV %s %s opened\n",
196 usbintf->name, usb_endpoint_name ( &usbep->ep ) );
197
198 /* Create event */
199 if ( ( efirc = bs->CreateEvent ( ( EVT_TIMER | EVT_NOTIFY_SIGNAL ),
201 &usbep->event ) ) != 0 ) {
202 rc = -EEFI ( efirc );
203 DBGC ( usbdev, "USBDEV %s %s could not create event: %s\n",
204 usbintf->name, usb_endpoint_name ( &usbep->ep ),
205 strerror ( rc ) );
206 goto err_event;
207 }
208
209 return 0;
210
211 bs->CloseEvent ( usbep->event );
212 err_event:
213 usb_endpoint_close ( &usbep->ep );
214 err_open:
215 err_mtu:
216 err_alloc:
217 return rc;
218}
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
#define TPL_CALLBACK
Definition UefiSpec.h:649
#define EVT_TIMER
Definition UefiSpec.h:451
#define EVT_NOTIFY_SIGNAL
Definition UefiSpec.h:454
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
static VOID EFIAPI efi_usb_timer(EFI_EVENT event __unused, VOID *context)
Poll USB bus (from endpoint event timer)
Definition efi_usb.c:75
static int efi_usb_mtu(struct efi_usb_interface *usbintf, unsigned int endpoint)
Get endpoint MTU.
Definition efi_usb.c:95
uint32_t mtu
Maximum MTU.
Definition ena.h:17
#define ENOMEM
Not enough space.
Definition errno.h:535
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
EFI_SYSTEM_TABLE * efi_systab
static void usb_endpoint_init(struct usb_endpoint *ep, struct usb_device *usb, struct usb_endpoint_driver_operations *driver)
Initialise USB endpoint.
Definition usb.h:540
static void usb_endpoint_describe(struct usb_endpoint *ep, unsigned int address, unsigned int attributes, size_t mtu, unsigned int burst, unsigned int interval)
Describe USB endpoint.
Definition usb.h:558
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_CREATE_EVENT CreateEvent
Definition UefiSpec.h:1955
EFI_CLOSE_EVENT CloseEvent
Definition UefiSpec.h:1959
EFI_EVENT event
Asynchronous timer event.
Definition efi_usb.h:70
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
Definition usb.c:294
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
Definition usb.c:400
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging)
Definition usb.c:221

References EFI_BOOT_SERVICES::CloseEvent, EFI_BOOT_SERVICES::CreateEvent, DBGC, EEFI, efi_systab, efi_usb_mtu(), efi_usb_timer(), efi_usb_interface::endpoint, ENOMEM, efi_usb_endpoint::ep, efi_usb_endpoint::event, EVT_NOTIFY_SIGNAL, EVT_TIMER, efi_usb_device::func, index, mtu, efi_usb_interface::name, rc, strerror(), TPL_CALLBACK, usb_function::usb, usb_endpoint_close(), usb_endpoint_describe(), USB_ENDPOINT_IDX, usb_endpoint_init(), usb_endpoint_name(), usb_endpoint_open(), efi_usb_interface::usbdev, efi_usb_endpoint::usbintf, and zalloc().

Referenced by efi_usb_async_start(), and efi_usb_sync_transfer().

◆ efi_usb_close()

void efi_usb_close ( struct efi_usb_endpoint * usbep)
static

Close endpoint.

Parameters
usbepEFI USB endpoint

Definition at line 225 of file efi_usb.c.

225 {
226 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
227 struct efi_usb_interface *usbintf = usbep->usbintf;
228 struct efi_usb_device *usbdev = usbintf->usbdev;
229 unsigned int index = USB_ENDPOINT_IDX ( usbep->ep.address );
230
231 /* Sanity check */
232 assert ( usbintf->endpoint[index] == usbep );
233
234 /* Cancel timer (if applicable) and close event */
235 bs->SetTimer ( usbep->event, TimerCancel, 0 );
236 bs->CloseEvent ( usbep->event );
237
238 /* Close endpoint */
239 usb_endpoint_close ( &usbep->ep );
240 DBGC ( usbdev, "USBDEV %s %s closed\n",
241 usbintf->name, usb_endpoint_name ( &usbep->ep ) );
242}
@ TimerCancel
An event's timer settings is to be cancelled and not trigger time is to be set/.
Definition UefiSpec.h:544
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
EFI_SET_TIMER SetTimer
Definition UefiSpec.h:1956
An EFI USB device interface.
Definition efi_usb.h:36
unsigned int address
Endpoint address.
Definition usb.h:408

References usb_endpoint::address, assert, EFI_BOOT_SERVICES::CloseEvent, DBGC, efi_systab, efi_usb_interface::endpoint, efi_usb_endpoint::ep, efi_usb_endpoint::event, index, efi_usb_interface::name, EFI_BOOT_SERVICES::SetTimer, TimerCancel, usb_endpoint_close(), USB_ENDPOINT_IDX, usb_endpoint_name(), efi_usb_interface::usbdev, and efi_usb_endpoint::usbintf.

Referenced by efi_usb_async_start(), efi_usb_close_all(), and efi_usb_sync_transfer().

◆ efi_usb_close_all()

void efi_usb_close_all ( struct efi_usb_interface * usbintf)
static

Close all endpoints.

Parameters
usbintfEFI USB interface

Definition at line 249 of file efi_usb.c.

249 {
250 struct efi_usb_endpoint *usbep;
251 unsigned int i;
252
253 for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
254 sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
255 usbep = usbintf->endpoint[i];
256 if ( usbep && usbep->ep.open )
257 efi_usb_close ( usbep );
258 }
259}
static void efi_usb_close(struct efi_usb_endpoint *usbep)
Close endpoint.
Definition efi_usb.c:225

References efi_usb_close(), efi_usb_interface::endpoint, efi_usb_endpoint::ep, usb_endpoint::open, and efi_usb_endpoint::usbintf.

Referenced by efi_usb_control_transfer(), efi_usb_install(), and efi_usb_uninstall().

◆ efi_usb_free_all()

void efi_usb_free_all ( struct efi_usb_interface * usbintf)
static

Free all endpoints.

Parameters
usbintfEFI USB interface

Definition at line 266 of file efi_usb.c.

266 {
267 struct efi_usb_endpoint *usbep;
268 unsigned int i;
269
270 for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
271 sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
272 usbep = usbintf->endpoint[i];
273 if ( usbep ) {
274 assert ( ! usbep->ep.open );
275 free ( usbep );
276 usbintf->endpoint[i] = NULL;
277 }
278 }
279}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55

References assert, efi_usb_interface::endpoint, efi_usb_endpoint::ep, free, NULL, usb_endpoint::open, and efi_usb_endpoint::usbintf.

Referenced by efi_usb_install(), and efi_usb_uninstall().

◆ efi_usb_sync_complete()

void efi_usb_sync_complete ( struct usb_endpoint * ep,
struct io_buffer *iobuf __unused,
int rc )
static

Complete synchronous transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 288 of file efi_usb.c.

289 {
290 struct efi_usb_endpoint *usbep =
291 container_of ( ep, struct efi_usb_endpoint, ep );
292
293 /* Record completion status */
294 usbep->rc = rc;
295}
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
int rc
Most recent synchronous completion status.
Definition efi_usb.h:67

References __unused, container_of, efi_usb_endpoint::ep, efi_usb_endpoint::rc, and rc.

◆ efi_usb_sync_transfer()

int efi_usb_sync_transfer ( struct efi_usb_interface * usbintf,
unsigned int endpoint,
unsigned int attributes,
unsigned int timeout,
void * data,
size_t * len )
static

Perform synchronous transfer.

Parameters
usbintfUSB endpoint
endpointEndpoint address
attributesEndpoint attributes
timeoutTimeout (in milliseconds)
dataData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 313 of file efi_usb.c.

317 {
318 struct efi_usb_device *usbdev = usbintf->usbdev;
319 struct efi_usb_endpoint *usbep;
320 struct io_buffer *iobuf;
321 unsigned int index = USB_ENDPOINT_IDX ( endpoint );
322 unsigned int i;
323 int rc;
324
325 /* Open endpoint, if applicable */
326 if ( ( ! efi_usb_is_open ( usbintf, endpoint ) ) &&
327 ( ( rc = efi_usb_open ( usbintf, endpoint, attributes, 0,
328 &efi_usb_sync_driver ) ) != 0 ) ) {
329 goto err_open;
330 }
331 usbep = usbintf->endpoint[index];
332
333 /* Allocate and construct I/O buffer */
334 iobuf = alloc_iob ( *len );
335 if ( ! iobuf ) {
336 rc = -ENOMEM;
337 goto err_alloc;
338 }
339 iob_put ( iobuf, *len );
340 if ( ! ( endpoint & USB_ENDPOINT_IN ) )
341 memcpy ( iobuf->data, data, *len );
342
343 /* Initialise completion status */
344 usbep->rc = -EINPROGRESS;
345
346 /* Enqueue transfer */
347 if ( ( rc = usb_stream ( &usbep->ep, iobuf, 0 ) ) != 0 ) {
348 DBGC ( usbdev, "USBDEV %s %s could not enqueue: %s\n",
349 usbintf->name, usb_endpoint_name ( &usbep->ep ),
350 strerror ( rc ) );
351 goto err_stream;
352 }
353
354 /* Wait for completion */
355 rc = -ETIMEDOUT;
356 for ( i = 0 ; ( ( timeout == 0 ) || ( i < timeout ) ) ; i++ ) {
357
358 /* Poll bus */
359 usb_poll ( usbdev->func->usb->port->hub->bus );
360
361 /* Check for completion */
362 if ( usbep->rc != -EINPROGRESS ) {
363 rc = usbep->rc;
364 break;
365 }
366
367 /* Delay */
368 mdelay ( 1 );
369 }
370
371 /* Check for errors */
372 if ( rc != 0 ) {
373 DBGC ( usbdev, "USBDEV %s %s failed: %s\n", usbintf->name,
374 usb_endpoint_name ( &usbep->ep ), strerror ( rc ) );
375 goto err_completion;
376 }
377
378 /* Copy completion to data buffer, if applicable */
379 assert ( iob_len ( iobuf ) <= *len );
380 if ( endpoint & USB_ENDPOINT_IN )
381 memcpy ( data, iobuf->data, iob_len ( iobuf ) );
382 *len = iob_len ( iobuf );
383
384 /* Free I/O buffer */
385 free_iob ( iobuf );
386
387 /* Leave endpoint open */
388 return 0;
389
390 err_completion:
391 err_stream:
392 free_iob ( iobuf );
393 err_alloc:
394 efi_usb_close ( usbep );
395 err_open:
396 return EFIRC ( rc );
397}
void timeout(int)
ring len
Length.
Definition dwmac.h:226
static int efi_usb_open(struct efi_usb_interface *usbintf, unsigned int endpoint, unsigned int attributes, unsigned int interval, struct usb_endpoint_driver_operations *driver)
Open endpoint.
Definition efi_usb.c:148
static int efi_usb_is_open(struct efi_usb_interface *usbintf, unsigned int endpoint)
Check if endpoint is open.
Definition efi_usb.c:130
static struct usb_endpoint_driver_operations efi_usb_sync_driver
Synchronous endpoint operations.
Definition efi_usb.c:298
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define EINPROGRESS
Operation in progress.
Definition errno.h:419
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:167
#define USB_ENDPOINT_IN
Endpoint direction is in.
Definition usb.h:525
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition usb.c:546

References alloc_iob(), assert, usb_hub::bus, data, io_buffer::data, DBGC, efi_usb_close(), efi_usb_is_open(), efi_usb_open(), efi_usb_sync_driver, EFIRC, EINPROGRESS, efi_usb_interface::endpoint, ENOMEM, efi_usb_endpoint::ep, ETIMEDOUT, free_iob(), efi_usb_device::func, usb_port::hub, index, iob_len(), iob_put, len, mdelay(), memcpy(), efi_usb_interface::name, usb_device::port, efi_usb_endpoint::rc, rc, strerror(), timeout(), usb_function::usb, USB_ENDPOINT_IDX, USB_ENDPOINT_IN, usb_endpoint_name(), usb_poll(), usb_stream(), and efi_usb_interface::usbdev.

Referenced by efi_usb_bulk_transfer(), and efi_usb_sync_interrupt_transfer().

◆ efi_usb_async_complete()

void efi_usb_async_complete ( struct usb_endpoint * ep,
struct io_buffer * iobuf,
int rc )
static

Complete asynchronous transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 406 of file efi_usb.c.

407 {
408 struct efi_usb_endpoint *usbep =
409 container_of ( ep, struct efi_usb_endpoint, ep );
411
412 /* Ignore packets cancelled when the endpoint closes */
413 if ( ! ep->open )
414 goto drop;
415
416 /* Construct status */
417 status = ( ( rc == 0 ) ? 0 : EFI_USB_ERR_SYSTEM );
418
419 /* Report completion, if applicable */
420 if ( usbep->callback ) {
421 usbep->callback ( iobuf->data, iob_len ( iobuf ),
422 usbep->context, status );
423 }
424
425 drop:
426 /* Recycle or free I/O buffer */
427 if ( usbep->ep.open ) {
428 usb_recycle ( &usbep->ep, iobuf );
429 } else {
430 free_iob ( iobuf );
431 }
432}
unsigned int UINT32
4-byte unsigned value.
#define EFI_USB_ERR_SYSTEM
Definition UsbIo.h:65
uint8_t status
Status.
Definition ena.h:5
static void usb_recycle(struct usb_endpoint *ep, struct io_buffer *iobuf)
Recycle I/O buffer.
Definition usb.h:633
EFI_ASYNC_USB_TRANSFER_CALLBACK callback
Asynchronous callback handler.
Definition efi_usb.h:72

References efi_usb_endpoint::callback, container_of, efi_usb_endpoint::context, io_buffer::data, EFI_USB_ERR_SYSTEM, efi_usb_endpoint::ep, free_iob(), iob_len(), usb_endpoint::open, rc, status, and usb_recycle().

◆ efi_usb_async_start()

int efi_usb_async_start ( struct efi_usb_interface * usbintf,
unsigned int endpoint,
unsigned int interval,
size_t len,
EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
void * context )
static

Start asynchronous transfer.

Parameters
usbintfEFI USB interface
endpointEndpoint address
intervalInterval (in milliseconds)
lenTransfer length
callbackCallback function
contextContext for callback function
Return values
rcReturn status code

Definition at line 450 of file efi_usb.c.

454 {
455 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
456 struct efi_usb_device *usbdev = usbintf->usbdev;
457 struct efi_usb_endpoint *usbep;
458 unsigned int index = USB_ENDPOINT_IDX ( endpoint );
459 EFI_STATUS efirc;
460 int rc;
461
462 /* Close endpoint, if applicable */
463 if ( efi_usb_is_open ( usbintf, endpoint ) )
465
466 /* Open endpoint */
467 if ( ( rc = efi_usb_open ( usbintf, endpoint,
469 &efi_usb_async_driver ) ) != 0 )
470 goto err_open;
471 usbep = usbintf->endpoint[index];
472
473 /* Record callback parameters */
474 usbep->callback = callback;
475 usbep->context = context;
476
477 /* Prefill endpoint */
478 usb_refill_init ( &usbep->ep, 0, len, EFI_USB_ASYNC_FILL );
479 if ( ( rc = usb_prefill ( &usbep->ep ) ) != 0 ) {
480 DBGC ( usbdev, "USBDEV %s %s could not prefill: %s\n",
481 usbintf->name, usb_endpoint_name ( &usbep->ep ),
482 strerror ( rc ) );
483 goto err_prefill;
484 }
485
486 /* Start timer */
487 if ( ( efirc = bs->SetTimer ( usbep->event, TimerPeriodic,
488 ( interval * 10000 ) ) ) != 0 ) {
489 rc = -EEFI ( efirc );
490 DBGC ( usbdev, "USBDEV %s %s could not set timer: %s\n",
491 usbintf->name, usb_endpoint_name ( &usbep->ep ),
492 strerror ( rc ) );
493 goto err_timer;
494 }
495
496 return 0;
497
498 bs->SetTimer ( usbep->event, TimerCancel, 0 );
499 err_timer:
500 err_prefill:
501 usbep->callback = NULL;
502 usbep->context = NULL;
503 efi_usb_close ( usbep );
504 err_open:
505 return rc;
506}
@ TimerPeriodic
An event is to be signaled periodically at a specified interval from the current time.
Definition UefiSpec.h:548
static struct usb_endpoint_driver_operations efi_usb_async_driver
Asynchronous endpoint operations.
Definition efi_usb.c:435
#define EFI_USB_ASYNC_FILL
Asynchronous transfer fill level.
Definition efi_usb.h:81
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition usb.h:617
#define USB_ENDPOINT_ATTR_INTERRUPT
Interrupt endpoint transfer type.
Definition usb.h:293
int usb_prefill(struct usb_endpoint *ep)
Prefill endpoint recycled buffer list.
Definition usb.c:620

References efi_usb_endpoint::callback, efi_usb_endpoint::context, DBGC, EEFI, efi_systab, efi_usb_async_driver, EFI_USB_ASYNC_FILL, efi_usb_close(), efi_usb_is_open(), efi_usb_open(), efi_usb_interface::endpoint, efi_usb_endpoint::ep, efi_usb_endpoint::event, index, len, efi_usb_interface::name, NULL, rc, EFI_BOOT_SERVICES::SetTimer, strerror(), TimerCancel, TimerPeriodic, USB_ENDPOINT_ATTR_INTERRUPT, USB_ENDPOINT_IDX, usb_endpoint_name(), usb_prefill(), usb_refill_init(), efi_usb_interface::usbdev, and efi_usb_endpoint::usbintf.

Referenced by efi_usb_async_interrupt_transfer().

◆ efi_usb_async_stop()

void efi_usb_async_stop ( struct efi_usb_interface * usbintf,
unsigned int endpoint )
static

Stop asynchronous transfer.

Parameters
usbintfEFI USB interface
endpointEndpoint address

Definition at line 514 of file efi_usb.c.

515 {
516 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
517 struct efi_usb_endpoint *usbep;
518 unsigned int index = USB_ENDPOINT_IDX ( endpoint );
519
520 /* Do nothing if endpoint is already closed */
521 if ( ! efi_usb_is_open ( usbintf, endpoint ) )
522 return;
523 usbep = usbintf->endpoint[index];
524
525 /* Stop timer */
526 bs->SetTimer ( usbep->event, TimerCancel, 0 );
527
528 /* Clear callback parameters */
529 usbep->callback = NULL;
530 usbep->context = NULL;
531}

References efi_usb_endpoint::callback, efi_usb_endpoint::context, efi_systab, efi_usb_is_open(), efi_usb_interface::endpoint, efi_usb_endpoint::event, index, NULL, EFI_BOOT_SERVICES::SetTimer, TimerCancel, USB_ENDPOINT_IDX, and efi_usb_endpoint::usbintf.

Referenced by efi_usb_async_interrupt_transfer().

◆ efi_usb_control_transfer()

EFI_STATUS EFIAPI efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL * usbio,
EFI_USB_DEVICE_REQUEST * packet,
EFI_USB_DATA_DIRECTION direction,
UINT32 timeout,
VOID * data,
UINTN len,
UINT32 * status )
static

Perform control transfer.

Parameters
usbioUSB I/O protocol
packetSetup packet
directionData direction
timeoutTimeout (in milliseconds)
dataData buffer
lenLength of data
Return values
statusTransfer status
efircEFI status code

Definition at line 553 of file efi_usb.c.

557 {
558 struct efi_usb_interface *usbintf =
560 struct efi_usb_device *usbdev = usbintf->usbdev;
561 unsigned int request = ( packet->RequestType |
562 USB_REQUEST_TYPE ( packet->Request ) );
563 unsigned int value = le16_to_cpu ( packet->Value );
564 unsigned int index = le16_to_cpu ( packet->Index );
565 struct efi_saved_tpl tpl;
566 int rc;
567
568 DBGC2 ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %s %dms "
569 "%p+%zx\n", usbintf->name, request, value, index,
570 le16_to_cpu ( packet->Length ),
572 ( ( size_t ) len ) );
573
574 /* Raise TPL */
575 efi_raise_tpl ( &tpl );
576
577 /* Clear status */
578 *status = 0;
579
580 /* Block attempts to change the device configuration, since
581 * this is logically impossible to do given the constraints of
582 * the EFI_USB_IO_PROTOCOL design.
583 */
584 if ( ( request == USB_SET_CONFIGURATION ) &&
585 ( value != usbdev->config->config ) ) {
586 DBGC ( usbdev, "USBDEV %s cannot set configuration %d: not "
587 "logically possible\n", usbintf->name, index );
588 rc = -ENOTSUP;
589 goto err_change_config;
590 }
591
592 /* If we are selecting a new alternate setting then close all
593 * open endpoints.
594 */
595 if ( ( request == USB_SET_INTERFACE ) &&
596 ( value != usbintf->alternate ) )
597 efi_usb_close_all ( usbintf );
598
599 /* Issue control transfer */
600 if ( ( rc = usb_control ( usbdev->func->usb, request, value, index,
601 data, len ) ) != 0 ) {
602 DBGC ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %p+%zx "
603 "failed: %s\n", usbintf->name, request, value, index,
604 le16_to_cpu ( packet->Length ), data, ( ( size_t ) len ),
605 strerror ( rc ) );
607 goto err_control;
608 }
609
610 /* Update alternate setting, if applicable */
611 if ( request == USB_SET_INTERFACE ) {
612 usbintf->alternate = value;
613 DBGC ( usbdev, "USBDEV %s alt %d selected\n",
614 usbintf->name, usbintf->alternate );
615 }
616
617 err_control:
618 err_change_config:
619 efi_restore_tpl ( &tpl );
620 return EFIRC ( rc );
621}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition efi_init.c:383
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition efi_init.c:399
static const char * efi_usb_direction_name(EFI_USB_DATA_DIRECTION direction)
Transcribe data direction (for debugging)
Definition efi_usb.c:52
static void efi_usb_close_all(struct efi_usb_interface *usbintf)
Close all endpoints.
Definition efi_usb.c:249
#define DBGC2(...)
Definition compiler.h:522
#define ENOTSUP
Operation not supported.
Definition errno.h:590
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
#define USB_REQUEST_TYPE(type)
Construct USB request type.
Definition usb.h:122
#define USB_SET_INTERFACE
Set interface.
Definition usb.h:153
#define USB_SET_CONFIGURATION
Set configuration.
Definition usb.h:146
UINT16 Length
Definition Usb.h:100
UINT8 Request
Definition Usb.h:97
UINT16 Value
Definition Usb.h:98
UINT8 RequestType
Definition Usb.h:96
UINT16 Index
Definition Usb.h:99
An EFI saved task priority level.
Definition efi.h:80
EFI_USB_IO_PROTOCOL usbio
USB I/O protocol.
Definition efi_usb.h:51
uint8_t config
Configuration value.
Definition usb.h:218
int usb_control(struct usb_device *usb, unsigned int request, unsigned int value, unsigned int index, void *data, size_t len)
Issue USB control transaction.
Definition usb.c:784

References efi_usb_interface::alternate, efi_usb_device::config, usb_configuration_descriptor::config, container_of, data, DBGC, DBGC2, direction, efi_raise_tpl(), efi_restore_tpl(), efi_usb_close_all(), efi_usb_direction_name(), EFI_USB_ERR_SYSTEM, EFIRC, ENOTSUP, efi_usb_device::func, USB_DEVICE_REQUEST::Index, index, le16_to_cpu, len, USB_DEVICE_REQUEST::Length, efi_usb_interface::name, rc, USB_DEVICE_REQUEST::Request, request, USB_DEVICE_REQUEST::RequestType, status, strerror(), timeout(), usb_function::usb, usb_control(), USB_REQUEST_TYPE, USB_SET_CONFIGURATION, USB_SET_INTERFACE, efi_usb_interface::usbdev, efi_usb_interface::usbio, USB_DEVICE_REQUEST::Value, value, and VOID.

◆ efi_usb_bulk_transfer()

EFI_STATUS EFIAPI efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL * usbio,
UINT8 endpoint,
VOID * data,
UINTN * len,
UINTN timeout,
UINT32 * status )
static

Perform bulk transfer.

Parameters
usbioUSB I/O protocol
endpointEndpoint address
dataData buffer
lenLength of data
timeoutTimeout (in milliseconds)
Return values
statusTransfer status
efircEFI status code

Definition at line 635 of file efi_usb.c.

636 {
637 struct efi_usb_interface *usbintf =
639 struct efi_usb_device *usbdev = usbintf->usbdev;
640 size_t actual = *len;
641 struct efi_saved_tpl tpl;
642 int rc;
643
644 DBGC2 ( usbdev, "USBDEV %s bulk %s %p+%zx %dms\n", usbintf->name,
645 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
646 ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
647
648 /* Raise TPL */
649 efi_raise_tpl ( &tpl );
650
651 /* Clear status */
652 *status = 0;
653
654 /* Perform synchronous transfer */
655 if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
657 data, &actual ) ) != 0 ) {
658 /* Assume that any error represents a timeout */
660 goto err_transfer;
661 }
662
663 err_transfer:
664 efi_restore_tpl ( &tpl );
665 return EFIRC ( rc );
666}
#define EFI_USB_ERR_TIMEOUT
Definition UsbIo.h:63
static int efi_usb_sync_transfer(struct efi_usb_interface *usbintf, unsigned int endpoint, unsigned int attributes, unsigned int timeout, void *data, size_t *len)
Perform synchronous transfer.
Definition efi_usb.c:313
#define USB_ENDPOINT_ATTR_BULK
Bulk endpoint transfer type.
Definition usb.h:290

References container_of, data, DBGC2, efi_raise_tpl(), efi_restore_tpl(), EFI_USB_ERR_TIMEOUT, efi_usb_sync_transfer(), EFIRC, len, efi_usb_interface::name, rc, status, timeout(), USB_ENDPOINT_ATTR_BULK, USB_ENDPOINT_IN, efi_usb_interface::usbdev, efi_usb_interface::usbio, and VOID.

◆ efi_usb_sync_interrupt_transfer()

EFI_STATUS EFIAPI efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL * usbio,
UINT8 endpoint,
VOID * data,
UINTN * len,
UINTN timeout,
UINT32 * status )
static

Perform synchronous interrupt transfer.

Parameters
usbioUSB I/O protocol
endpointEndpoint address
dataData buffer
lenLength of data
timeoutTimeout (in milliseconds)
Return values
statusTransfer status
efircEFI status code

Definition at line 680 of file efi_usb.c.

682 {
683 struct efi_usb_interface *usbintf =
685 struct efi_usb_device *usbdev = usbintf->usbdev;
686 size_t actual = *len;
687 struct efi_saved_tpl tpl;
688 int rc;
689
690 DBGC2 ( usbdev, "USBDEV %s sync intr %s %p+%zx %dms\n", usbintf->name,
691 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
692 ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
693
694 /* Raise TPL */
695 efi_raise_tpl ( &tpl );
696
697 /* Clear status */
698 *status = 0;
699
700 /* Perform synchronous transfer */
701 if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
703 timeout, data, &actual ) ) != 0 ) {
704 /* Assume that any error represents a timeout */
706 goto err_transfer;
707 }
708
709 err_transfer:
710 efi_restore_tpl ( &tpl );
711 return EFIRC ( rc );
712}

References container_of, data, DBGC2, efi_raise_tpl(), efi_restore_tpl(), EFI_USB_ERR_TIMEOUT, efi_usb_sync_transfer(), EFIRC, len, efi_usb_interface::name, rc, status, timeout(), USB_ENDPOINT_ATTR_INTERRUPT, USB_ENDPOINT_IN, efi_usb_interface::usbdev, efi_usb_interface::usbio, and VOID.

◆ efi_usb_async_interrupt_transfer()

EFI_STATUS EFIAPI efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL * usbio,
UINT8 endpoint,
BOOLEAN start,
UINTN interval,
UINTN len,
EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
VOID * context )
static

Perform asynchronous interrupt transfer.

Parameters
usbioUSB I/O protocol
endpointEndpoint address
startStart (rather than stop) transfer
intervalPolling interval (in milliseconds)
lenData length
callbackCallback function
contextContext for callback function
Return values
efircEFI status code

Definition at line 727 of file efi_usb.c.

730 {
731 struct efi_usb_interface *usbintf =
733 struct efi_usb_device *usbdev = usbintf->usbdev;
734 struct efi_saved_tpl tpl;
735 int rc;
736
737 DBGC2 ( usbdev, "USBDEV %s async intr %s len %#zx int %d %p/%p\n",
738 usbintf->name,
739 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ),
740 ( ( size_t ) len ), ( ( unsigned int ) interval ),
741 callback, context );
742
743 /* Raise TPL */
744 efi_raise_tpl ( &tpl );
745
746 /* Start/stop transfer as applicable */
747 if ( start ) {
748
749 /* Start new transfer */
750 if ( ( rc = efi_usb_async_start ( usbintf, endpoint, interval,
751 len, callback,
752 context ) ) != 0 )
753 goto err_start;
754
755 } else {
756
757 /* Stop transfer */
758 efi_usb_async_stop ( usbintf, endpoint );
759
760 /* Success */
761 rc = 0;
762
763 }
764
765 err_start:
766 efi_restore_tpl ( &tpl );
767 return EFIRC ( rc );
768}
static int efi_usb_async_start(struct efi_usb_interface *usbintf, unsigned int endpoint, unsigned int interval, size_t len, EFI_ASYNC_USB_TRANSFER_CALLBACK callback, void *context)
Start asynchronous transfer.
Definition efi_usb.c:450
static void efi_usb_async_stop(struct efi_usb_interface *usbintf, unsigned int endpoint)
Stop asynchronous transfer.
Definition efi_usb.c:514
uint32_t start
Starting offset.
Definition netvsc.h:1

References container_of, DBGC2, efi_raise_tpl(), efi_restore_tpl(), efi_usb_async_start(), efi_usb_async_stop(), EFIRC, len, efi_usb_interface::name, rc, start, USB_ENDPOINT_IN, efi_usb_interface::usbdev, efi_usb_interface::usbio, and VOID.

◆ efi_usb_isochronous_transfer()

EFI_STATUS EFIAPI efi_usb_isochronous_transfer ( EFI_USB_IO_PROTOCOL * usbio,
UINT8 endpoint,
VOID * data,
UINTN len,
UINT32 * status )
static

Perform synchronous isochronous transfer.

Parameters
usbioUSB I/O protocol
endpointEndpoint address
dataData buffer
lenLength of data
Return values
statusTransfer status
efircEFI status code

Definition at line 781 of file efi_usb.c.

782 {
783 struct efi_usb_interface *usbintf =
785 struct efi_usb_device *usbdev = usbintf->usbdev;
786
787 DBGC2 ( usbdev, "USBDEV %s sync iso %s %p+%zx\n", usbintf->name,
788 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
789 ( ( size_t ) len ) );
790
791 /* Clear status */
792 *status = 0;
793
794 /* Not supported */
795 return EFI_UNSUPPORTED;
796}
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.

References container_of, data, DBGC2, EFI_UNSUPPORTED, len, efi_usb_interface::name, status, USB_ENDPOINT_IN, efi_usb_interface::usbdev, efi_usb_interface::usbio, and VOID.

◆ efi_usb_async_isochronous_transfer()

EFI_STATUS EFIAPI efi_usb_async_isochronous_transfer ( EFI_USB_IO_PROTOCOL * usbio,
UINT8 endpoint,
VOID * data,
UINTN len,
EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
VOID * context )
static

Perform asynchronous isochronous transfers.

Parameters
usbioUSB I/O protocol
endpointEndpoint address
dataData buffer
lenLength of data
callbackCallback function
contextContext for callback function
Return values
statusTransfer status
efircEFI status code

Definition at line 811 of file efi_usb.c.

814 {
815 struct efi_usb_interface *usbintf =
817 struct efi_usb_device *usbdev = usbintf->usbdev;
818
819 DBGC2 ( usbdev, "USBDEV %s async iso %s %p+%zx %p/%p\n", usbintf->name,
820 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
821 ( ( size_t ) len ), callback, context );
822
823 /* Not supported */
824 return EFI_UNSUPPORTED;
825}

References container_of, data, DBGC2, EFI_UNSUPPORTED, len, efi_usb_interface::name, USB_ENDPOINT_IN, efi_usb_interface::usbdev, efi_usb_interface::usbio, and VOID.

◆ efi_usb_get_device_descriptor()

EFI_STATUS EFIAPI efi_usb_get_device_descriptor ( EFI_USB_IO_PROTOCOL * usbio,
EFI_USB_DEVICE_DESCRIPTOR * efidesc )
static

Get device descriptor.

Parameters
usbioUSB I/O protocol
Return values
efidescEFI device descriptor
efircEFI status code

Definition at line 835 of file efi_usb.c.

836 {
837 struct efi_usb_interface *usbintf =
839 struct efi_usb_device *usbdev = usbintf->usbdev;
840
841 DBGC2 ( usbdev, "USBDEV %s get device descriptor\n", usbintf->name );
842
843 /* Copy cached device descriptor */
844 memcpy ( efidesc, &usbdev->func->usb->device, sizeof ( *efidesc ) );
845
846 return 0;
847}
struct usb_device_descriptor device
Device descriptor.
Definition usb.h:735

References container_of, DBGC2, usb_device::device, efi_usb_device::func, memcpy(), efi_usb_interface::name, usb_function::usb, efi_usb_interface::usbdev, and efi_usb_interface::usbio.

◆ efi_usb_get_config_descriptor()

EFI_STATUS EFIAPI efi_usb_get_config_descriptor ( EFI_USB_IO_PROTOCOL * usbio,
EFI_USB_CONFIG_DESCRIPTOR * efidesc )
static

Get configuration descriptor.

Parameters
usbioUSB I/O protocol
Return values
efidescEFI interface descriptor
efircEFI status code

Definition at line 857 of file efi_usb.c.

858 {
859 struct efi_usb_interface *usbintf =
861 struct efi_usb_device *usbdev = usbintf->usbdev;
862
863 DBGC2 ( usbdev, "USBDEV %s get configuration descriptor\n",
864 usbintf->name );
865
866 /* Copy cached configuration descriptor */
867 memcpy ( efidesc, usbdev->config, sizeof ( *efidesc ) );
868
869 return 0;
870}

References efi_usb_device::config, container_of, DBGC2, memcpy(), efi_usb_interface::name, efi_usb_interface::usbdev, and efi_usb_interface::usbio.

◆ efi_usb_get_interface_descriptor()

EFI_STATUS EFIAPI efi_usb_get_interface_descriptor ( EFI_USB_IO_PROTOCOL * usbio,
EFI_USB_INTERFACE_DESCRIPTOR * efidesc )
static

Get interface descriptor.

Parameters
usbioUSB I/O protocol
Return values
efidescEFI interface descriptor
efircEFI status code

Definition at line 880 of file efi_usb.c.

881 {
882 struct efi_usb_interface *usbintf =
884 struct efi_usb_device *usbdev = usbintf->usbdev;
886
887 DBGC2 ( usbdev, "USBDEV %s get interface descriptor\n", usbintf->name );
888
889 /* Locate cached interface descriptor */
890 desc = usb_interface_descriptor ( usbdev->config, usbintf->interface,
891 usbintf->alternate );
892 if ( ! desc ) {
893 DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
894 usbintf->name, usbintf->alternate );
895 return -ENOENT;
896 }
897
898 /* Copy cached interface descriptor */
899 memcpy ( efidesc, desc, sizeof ( *efidesc ) );
900
901 return 0;
902}
unsigned int interface
Interface number.
Definition efi_usb.h:45
struct usb_interface_descriptor * usb_interface_descriptor(struct usb_configuration_descriptor *config, unsigned int interface, unsigned int alternate)
Locate USB interface descriptor.
Definition usb.c:144

References efi_usb_interface::alternate, efi_usb_device::config, container_of, DBGC, DBGC2, desc, ENOENT, efi_usb_interface::interface, memcpy(), efi_usb_interface::name, usb_interface_descriptor(), efi_usb_interface::usbdev, and efi_usb_interface::usbio.

◆ efi_usb_get_endpoint_descriptor()

EFI_STATUS EFIAPI efi_usb_get_endpoint_descriptor ( EFI_USB_IO_PROTOCOL * usbio,
UINT8 index,
EFI_USB_ENDPOINT_DESCRIPTOR * efidesc )
static

Get endpoint descriptor.

Parameters
usbioUSB I/O protocol
addressEndpoint index
Return values
efidescEFI interface descriptor
efircEFI status code

Definition at line 913 of file efi_usb.c.

914 {
915 struct efi_usb_interface *usbintf =
917 struct efi_usb_device *usbdev = usbintf->usbdev;
920
921 DBGC2 ( usbdev, "USBDEV %s get endpoint %d descriptor\n",
922 usbintf->name, index );
923
924 /* Locate cached interface descriptor */
925 interface = usb_interface_descriptor ( usbdev->config,
926 usbintf->interface,
927 usbintf->alternate );
928 if ( ! interface ) {
929 DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
930 usbintf->name, usbintf->alternate );
931 return -ENOENT;
932 }
933
934 /* Locate and copy cached endpoint descriptor */
936 if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
937 ( index-- == 0 ) ) {
938 memcpy ( efidesc, desc, sizeof ( *efidesc ) );
939 return 0;
940 }
941 }
942 return -ENOENT;
943}

References alternate, efi_usb_interface::alternate, efi_usb_device::config, container_of, DBGC, DBGC2, desc, ENOENT, for_each_interface_descriptor, index, memcpy(), efi_usb_interface::name, USB_ENDPOINT_DESCRIPTOR, efi_usb_interface::usbdev, and efi_usb_interface::usbio.

◆ efi_usb_get_string_descriptor()

EFI_STATUS EFIAPI efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL * usbio,
UINT16 language,
UINT8 index,
CHAR16 ** string )
static

Get string descriptor.

Parameters
usbioUSB I/O protocol
languageLanguage ID
indexString index
Return values
stringString
efircEFI status code

Definition at line 955 of file efi_usb.c.

956 {
957 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
958 struct efi_usb_interface *usbintf =
960 struct efi_usb_device *usbdev = usbintf->usbdev;
962 struct efi_saved_tpl tpl;
963 VOID *buffer;
964 size_t len;
965 EFI_STATUS efirc;
966 int rc;
967
968 DBGC2 ( usbdev, "USBDEV %s get string %d:%d descriptor\n",
969 usbintf->name, language, index );
970
971 /* Raise TPL */
972 efi_raise_tpl ( &tpl );
973
974 /* Read descriptor header */
975 if ( ( rc = usb_get_descriptor ( usbdev->func->usb, 0,
977 language, &header,
978 sizeof ( header ) ) ) != 0 ) {
979 DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
980 "descriptor header: %s\n", usbintf->name, language,
981 index, strerror ( rc ) );
982 goto err_get_header;
983 }
984 len = header.len;
985 if ( len < sizeof ( header ) ) {
986 DBGC ( usbdev, "USBDEV %s underlength string %d:%d\n",
987 usbintf->name, language, index );
988 rc = -EINVAL;
989 goto err_len;
990 }
991
992 /* Allocate buffer */
993 if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
994 &buffer ) ) != 0 ) {
995 rc = -EEFI ( efirc );
996 goto err_alloc;
997 }
998
999 /* Read whole descriptor */
1000 if ( ( rc = usb_get_descriptor ( usbdev->func->usb, 0,
1002 language, buffer, len ) ) != 0 ) {
1003 DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
1004 "descriptor: %s\n", usbintf->name, language,
1005 index, strerror ( rc ) );
1006 goto err_get_descriptor;
1007 }
1008
1009 /* Shuffle down and terminate string */
1010 memmove ( buffer, ( buffer + sizeof ( header ) ),
1011 ( len - sizeof ( header ) ) );
1012 memset ( ( buffer + len - sizeof ( header ) ), 0, sizeof ( **string ) );
1013
1014 /* Restore TPL */
1015 efi_restore_tpl ( &tpl );
1016
1017 /* Return allocated string */
1018 *string = buffer;
1019 return 0;
1020
1021 err_get_descriptor:
1022 bs->FreePool ( buffer );
1023 err_alloc:
1024 err_len:
1025 err_get_header:
1026 efi_restore_tpl ( &tpl );
1027 return EFIRC ( rc );
1028}
#define VOID
Undeclared type.
Definition Base.h:272
@ EfiBootServicesData
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
struct ena_llq_option header
Header locations.
Definition ena.h:5
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define EINVAL
Invalid argument.
Definition errno.h:429
#define USB_STRING_DESCRIPTOR
A USB string descriptor.
Definition usb.h:239
static int usb_get_descriptor(struct usb_device *usb, unsigned int type, unsigned int desc, unsigned int index, unsigned int language, struct usb_descriptor_header *data, size_t len)
Get USB descriptor.
Definition usb.h:1177
void * memset(void *dest, int character, size_t len) __nonnull
void * memmove(void *dest, const void *src, size_t len) __nonnull
EFI_FREE_POOL FreePool
Definition UefiSpec.h:1950
EFI_ALLOCATE_POOL AllocatePool
Definition UefiSpec.h:1949
A USB descriptor header.
Definition usb.h:173

References EFI_BOOT_SERVICES::AllocatePool, buffer, container_of, DBGC, DBGC2, EEFI, efi_raise_tpl(), efi_restore_tpl(), efi_systab, EfiBootServicesData, EFIRC, EINVAL, EFI_BOOT_SERVICES::FreePool, efi_usb_device::func, header, index, len, memmove(), memset(), efi_usb_interface::name, rc, strerror(), usb_function::usb, usb_get_descriptor(), USB_STRING_DESCRIPTOR, efi_usb_interface::usbdev, efi_usb_interface::usbio, and VOID.

◆ efi_usb_get_supported_languages()

EFI_STATUS EFIAPI efi_usb_get_supported_languages ( EFI_USB_IO_PROTOCOL * usbio,
UINT16 ** languages,
UINT16 * len )
static

Get supported languages.

Parameters
usbioUSB I/O protocol
Return values
languagesLanguage ID table
lenLength of language ID table
efircEFI status code

Definition at line 1039 of file efi_usb.c.

1040 {
1041 struct efi_usb_interface *usbintf =
1043 struct efi_usb_device *usbdev = usbintf->usbdev;
1044
1045 DBGC2 ( usbdev, "USBDEV %s get supported languages\n", usbintf->name );
1046
1047 /* Return cached supported languages */
1048 *languages = usbdev->lang;
1049 *len = usbdev->lang_len;
1050
1051 return 0;
1052}
size_t lang_len
Length of supported languages.
Definition efi_usb.h:30
uint16_t * lang
Supported languages.
Definition efi_usb.h:28

References container_of, DBGC2, efi_usb_device::lang, efi_usb_device::lang_len, len, efi_usb_interface::name, efi_usb_interface::usbdev, and efi_usb_interface::usbio.

◆ efi_usb_port_reset()

EFI_STATUS EFIAPI efi_usb_port_reset ( EFI_USB_IO_PROTOCOL * usbio)
static

Reset port.

Parameters
usbioUSB I/O protocol
Return values
efircEFI status code

Definition at line 1061 of file efi_usb.c.

1061 {
1062 struct efi_usb_interface *usbintf =
1064 struct efi_usb_device *usbdev = usbintf->usbdev;
1065
1066 DBGC2 ( usbdev, "USBDEV %s reset port\n", usbintf->name );
1067
1068 /* This is logically impossible to do, since resetting the
1069 * port may destroy state belonging to other
1070 * EFI_USB_IO_PROTOCOL instances belonging to the same USB
1071 * device. (This is yet another artifact of the incredibly
1072 * poor design of the EFI_USB_IO_PROTOCOL.)
1073 */
1074 return EFI_INVALID_PARAMETER;
1075}
#define EFI_INVALID_PARAMETER
Enumeration of EFI_STATUS.

References container_of, DBGC2, EFI_INVALID_PARAMETER, efi_usb_interface::name, efi_usb_interface::usbdev, and efi_usb_interface::usbio.

◆ efi_usb_install()

int efi_usb_install ( struct efi_usb_device * usbdev,
unsigned int interface )
static

Install interface.

Parameters
usbdevEFI USB device
interfaceInterface number
Return values
rcReturn status code

Definition at line 1108 of file efi_usb.c.

1109 {
1110 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1111 struct usb_function *func = usbdev->func;
1112 struct efi_usb_interface *usbintf;
1113 int leak = 0;
1114 EFI_STATUS efirc;
1115 int rc;
1116
1117 /* Allocate and initialise structure */
1118 usbintf = zalloc ( sizeof ( *usbintf ) );
1119 if ( ! usbintf ) {
1120 rc = -ENOMEM;
1121 goto err_alloc;
1122 }
1123 snprintf ( usbintf->name, sizeof ( usbintf->name ), "%s[%d]",
1124 usbdev->name, interface );
1125 usbintf->usbdev = usbdev;
1126 usbintf->interface = interface;
1127 memcpy ( &usbintf->usbio, &efi_usb_io_protocol,
1128 sizeof ( usbintf->usbio ) );
1129
1130 /* Construct device path */
1131 usbintf->path = efi_usb_path ( func );
1132 if ( ! usbintf->path ) {
1133 rc = -ENODEV;
1134 goto err_path;
1135 }
1136
1137 /* Add to list of interfaces */
1138 list_add_tail ( &usbintf->list, &usbdev->interfaces );
1139
1140 /* Install protocols */
1141 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1142 &usbintf->handle,
1143 &efi_usb_io_protocol_guid, &usbintf->usbio,
1145 NULL ) ) != 0 ) {
1146 rc = -EEFI ( efirc );
1147 DBGC ( usbdev, "USBDEV %s could not install protocols: %s\n",
1148 usbintf->name, strerror ( rc ) );
1149 goto err_install_protocol;
1150 }
1151
1152 DBGC ( usbdev, "USBDEV %s installed as %s\n",
1153 usbintf->name, efi_handle_name ( usbintf->handle ) );
1154 return 0;
1155
1156 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1157 usbintf->handle,
1158 &efi_usb_io_protocol_guid, &usbintf->usbio,
1160 NULL ) ) != 0 ) {
1161 DBGC ( usbdev, "USBDEV %s could not uninstall: %s\n",
1162 usbintf->name, strerror ( -EEFI ( efirc ) ) );
1163 leak = 1;
1164 }
1165 efi_nullify_usbio ( &usbintf->usbio );
1166 err_install_protocol:
1167 efi_usb_close_all ( usbintf );
1168 efi_usb_free_all ( usbintf );
1169 list_del ( &usbintf->list );
1170 if ( ! leak )
1171 free ( usbintf->path );
1172 err_path:
1173 if ( ! leak )
1174 free ( usbintf );
1175 err_alloc:
1176 if ( leak ) {
1177 DBGC ( usbdev, "USBDEV %s nullified and leaked\n",
1178 usbintf->name );
1179 }
1180 return rc;
1181}
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:169
EFI_GUID efi_usb_io_protocol_guid
USB I/O protocol GUID.
Definition efi_guid.c:429
void efi_nullify_usbio(EFI_USB_IO_PROTOCOL *usbio)
Nullify USB I/O protocol.
Definition efi_null.c:712
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
Definition efi_path.c:697
static EFI_USB_IO_PROTOCOL efi_usb_io_protocol
USB I/O protocol.
Definition efi_usb.c:1078
static void efi_usb_free_all(struct efi_usb_interface *usbintf)
Free all endpoints.
Definition efi_usb.c:266
#define ENODEV
No such device.
Definition errno.h:510
#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
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
struct list_head interfaces
List of interfaces.
Definition efi_usb.h:32
const char * name
Name.
Definition efi_usb.h:22
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition efi_usb.h:53
EFI_HANDLE handle
EFI handle.
Definition efi_usb.h:49
struct list_head list
List of interfaces.
Definition efi_usb.h:42
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References DBGC, EEFI, efi_device_path_protocol_guid, efi_handle_name(), efi_nullify_usbio(), efi_systab, efi_usb_close_all(), efi_usb_free_all(), efi_usb_io_protocol, efi_usb_io_protocol_guid, efi_usb_path(), ENODEV, ENOMEM, free, efi_usb_device::func, efi_usb_interface::handle, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, efi_usb_interface::interface, efi_usb_device::interfaces, efi_usb_interface::list, list_add_tail, list_del, memcpy(), efi_usb_device::name, efi_usb_interface::name, NULL, efi_usb_interface::path, rc, snprintf(), strerror(), EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, efi_usb_interface::usbdev, efi_usb_interface::usbio, and zalloc().

Referenced by efi_usb_probe().

◆ efi_usb_uninstall()

void efi_usb_uninstall ( struct efi_usb_interface * usbintf)
static

Uninstall interface.

Parameters
usbintfEFI USB interface

Definition at line 1188 of file efi_usb.c.

1188 {
1189 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1190 struct efi_usb_device *usbdev = usbintf->usbdev;
1191 int leak = efi_shutdown_in_progress;
1192 EFI_STATUS efirc;
1193
1194 DBGC ( usbdev, "USBDEV %s uninstalling %s\n",
1195 usbintf->name, efi_handle_name ( usbintf->handle ) );
1196
1197 /* Disconnect controllers. This should not be necessary, but
1198 * seems to be required on some platforms to avoid failures
1199 * when uninstalling protocols.
1200 */
1202 efi_disconnect ( usbintf->handle, NULL );
1203
1204 /* Uninstall protocols */
1205 if ( ( ! efi_shutdown_in_progress ) &&
1206 ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1207 usbintf->handle,
1208 &efi_usb_io_protocol_guid, &usbintf->usbio,
1210 NULL ) ) != 0 ) ) {
1211 DBGC ( usbdev, "USBDEV %s could not uninstall: %s\n",
1212 usbintf->name, strerror ( -EEFI ( efirc ) ) );
1213 leak = 1;
1214 }
1215 efi_nullify_usbio ( &usbintf->usbio );
1216
1217 /* Close and free all endpoints */
1218 efi_usb_close_all ( usbintf );
1219 efi_usb_free_all ( usbintf );
1220
1221 /* Remove from list of interfaces */
1222 list_del ( &usbintf->list );
1223
1224 /* Free device path */
1225 if ( ! leak )
1226 free ( usbintf->path );
1227
1228 /* Free interface */
1229 if ( ! leak )
1230 free ( usbintf );
1231
1232 /* Report leakage, if applicable */
1233 if ( leak && ( ! efi_shutdown_in_progress ) ) {
1234 DBGC ( usbdev, "USBDEV %s nullified and leaked\n",
1235 usbintf->name );
1236 }
1237}
int efi_disconnect(EFI_HANDLE device, EFI_HANDLE driver)
Disconnect UEFI driver(s)
Definition efi_connect.c:90
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60

References DBGC, EEFI, efi_device_path_protocol_guid, efi_disconnect(), efi_handle_name(), efi_nullify_usbio(), efi_shutdown_in_progress, efi_systab, efi_usb_close_all(), efi_usb_free_all(), efi_usb_io_protocol_guid, free, efi_usb_interface::handle, efi_usb_interface::list, list_del, efi_usb_interface::name, NULL, efi_usb_interface::path, strerror(), EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, efi_usb_interface::usbdev, and efi_usb_interface::usbio.

Referenced by efi_usb_uninstall_all().

◆ efi_usb_uninstall_all()

void efi_usb_uninstall_all ( struct efi_usb_device * efiusb)
static

Uninstall all interfaces.

Parameters
usbdevEFI USB device

Definition at line 1244 of file efi_usb.c.

1244 {
1245 struct efi_usb_interface *usbintf;
1246
1247 /* Uninstall all interfaces */
1248 while ( ( usbintf = list_first_entry ( &efiusb->interfaces,
1249 struct efi_usb_interface,
1250 list ) ) ) {
1251 efi_usb_uninstall ( usbintf );
1252 }
1253}
static void efi_usb_uninstall(struct efi_usb_interface *usbintf)
Uninstall interface.
Definition efi_usb.c:1188
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334

References efi_usb_uninstall(), efi_usb_device::interfaces, efi_usb_interface::list, and list_first_entry.

Referenced by efi_usb_probe(), and efi_usb_remove().

◆ efi_usb_probe()

int efi_usb_probe ( struct usb_function * func,
struct usb_configuration_descriptor * config )
static

Probe device.

Parameters
funcUSB function
configConfiguration descriptor
Return values
rcReturn status code

Definition at line 1262 of file efi_usb.c.

1263 {
1264 struct usb_device *usb = func->usb;
1265 struct efi_usb_device *usbdev;
1266 struct efi_usb_interface *usbintf;
1268 struct usb_descriptor_header *lang;
1269 size_t config_len;
1270 size_t lang_len;
1271 unsigned int i;
1272 int rc;
1273
1274 /* Get configuration length */
1275 config_len = le16_to_cpu ( config->len );
1276
1277 /* Get supported languages descriptor header */
1278 if ( ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
1279 &header, sizeof ( header ) ) ) != 0 ) {
1280 /* Assume no strings are present */
1281 header.len = 0;
1282 }
1283 lang_len = ( ( header.len >= sizeof ( header ) ) ?
1284 ( header.len - sizeof ( header ) ) : 0 );
1285
1286 /* Allocate and initialise structure */
1287 usbdev = zalloc ( sizeof ( *usbdev ) + config_len +
1288 sizeof ( *lang ) + lang_len );
1289 if ( ! usbdev ) {
1290 rc = -ENOMEM;
1291 goto err_alloc;
1292 }
1293 usb_func_set_drvdata ( func, usbdev );
1294 usbdev->name = func->name;
1295 usbdev->func = func;
1296 usbdev->config = ( ( ( void * ) usbdev ) + sizeof ( *usbdev ) );
1297 memcpy ( usbdev->config, config, config_len );
1298 lang = ( ( ( void * ) usbdev->config ) + config_len );
1299 usbdev->lang = ( ( ( void * ) lang ) + sizeof ( *lang ) );
1300 usbdev->lang_len = lang_len;
1301 INIT_LIST_HEAD ( &usbdev->interfaces );
1302
1303 /* Get supported languages descriptor, if applicable */
1304 if ( lang_len &&
1306 0, 0, lang, header.len ) ) != 0 ) ) {
1307 DBGC ( usbdev, "USBDEV %s could not get supported languages: "
1308 "%s\n", usbdev->name, strerror ( rc ) );
1309 goto err_get_languages;
1310 }
1311
1312 /* Install interfaces */
1313 for ( i = 0 ; i < func->desc.count ; i++ ) {
1314 if ( ( rc = efi_usb_install ( usbdev,
1315 func->interface[i] ) ) != 0 )
1316 goto err_install;
1317 }
1318
1319 /* Connect any external drivers */
1320 list_for_each_entry ( usbintf, &usbdev->interfaces, list )
1321 efi_connect ( usbintf->handle, NULL );
1322
1323 return 0;
1324
1325 err_install:
1326 efi_usb_uninstall_all ( usbdev );
1327 assert ( list_empty ( &usbdev->interfaces ) );
1328 err_get_languages:
1329 free ( usbdev );
1330 err_alloc:
1331 return rc;
1332}
int efi_connect(EFI_HANDLE device, EFI_HANDLE driver)
Connect UEFI driver(s)
Definition efi_connect.c:58
static void efi_usb_uninstall_all(struct efi_usb_device *efiusb)
Uninstall all interfaces.
Definition efi_usb.c:1244
static int efi_usb_install(struct efi_usb_device *usbdev, unsigned int interface)
Install interface.
Definition efi_usb.c:1108
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition usb.h:707
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
uint16_t len
Total length.
Definition usb.h:214
A USB device.
Definition usb.h:723
unsigned int count
Number of interfaces.
Definition usb.h:665
struct usb_function_descriptor desc
Function descriptor.
Definition usb.h:680
uint8_t interface[0]
List of interface numbers.
Definition usb.h:697
const char * name
Name.
Definition usb.h:676

References assert, efi_usb_device::config, usb_function_descriptor::count, DBGC, usb_function::desc, efi_connect(), efi_usb_install(), efi_usb_uninstall_all(), ENOMEM, free, efi_usb_device::func, efi_usb_interface::handle, header, INIT_LIST_HEAD, usb_function::interface, efi_usb_device::interfaces, efi_usb_device::lang, efi_usb_device::lang_len, le16_to_cpu, usb_configuration_descriptor::len, list_empty, list_for_each_entry, memcpy(), efi_usb_device::name, usb_function::name, NULL, rc, strerror(), usb_function::usb, usb_func_set_drvdata(), usb_get_descriptor(), USB_STRING_DESCRIPTOR, and zalloc().

◆ efi_usb_remove()

void efi_usb_remove ( struct usb_function * func)
static

Remove device.

Parameters
funcUSB function

Definition at line 1339 of file efi_usb.c.

1339 {
1340 struct efi_usb_device *usbdev = usb_func_get_drvdata ( func );
1341
1342 /* Uninstall all interfaces */
1343 efi_usb_uninstall_all ( usbdev );
1344 assert ( list_empty ( &usbdev->interfaces ) );
1345
1346 /* Free device */
1347 free ( usbdev );
1348}
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:718

References assert, efi_usb_uninstall_all(), free, efi_usb_device::func, efi_usb_device::interfaces, list_empty, and usb_func_get_drvdata().

Variable Documentation

◆ efi_usb_sync_driver

struct usb_endpoint_driver_operations efi_usb_sync_driver
static
Initial value:
= {
.complete = efi_usb_sync_complete,
}
static void efi_usb_sync_complete(struct usb_endpoint *ep, struct io_buffer *iobuf __unused, int rc)
Complete synchronous transfer.
Definition efi_usb.c:288

Synchronous endpoint operations.

Definition at line 298 of file efi_usb.c.

298 {
299 .complete = efi_usb_sync_complete,
300};

Referenced by efi_usb_sync_transfer().

◆ efi_usb_async_driver

struct usb_endpoint_driver_operations efi_usb_async_driver
static
Initial value:
= {
}
static void efi_usb_async_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete asynchronous transfer.
Definition efi_usb.c:406

Asynchronous endpoint operations.

Definition at line 435 of file efi_usb.c.

435 {
436 .complete = efi_usb_async_complete,
437};

Referenced by efi_usb_async_start().

◆ efi_usb_io_protocol

EFI_USB_IO_PROTOCOL efi_usb_io_protocol
static
Initial value:
= {
.UsbControlTransfer = efi_usb_control_transfer,
.UsbBulkTransfer = efi_usb_bulk_transfer,
.UsbAsyncInterruptTransfer = efi_usb_async_interrupt_transfer,
.UsbSyncInterruptTransfer = efi_usb_sync_interrupt_transfer,
.UsbIsochronousTransfer = efi_usb_isochronous_transfer,
.UsbAsyncIsochronousTransfer = efi_usb_async_isochronous_transfer,
.UsbGetDeviceDescriptor = efi_usb_get_device_descriptor,
.UsbGetConfigDescriptor = efi_usb_get_config_descriptor,
.UsbGetInterfaceDescriptor = efi_usb_get_interface_descriptor,
.UsbGetEndpointDescriptor = efi_usb_get_endpoint_descriptor,
.UsbGetStringDescriptor = efi_usb_get_string_descriptor,
.UsbGetSupportedLanguages = efi_usb_get_supported_languages,
.UsbPortReset = efi_usb_port_reset,
}
static EFI_STATUS EFIAPI efi_usb_get_device_descriptor(EFI_USB_IO_PROTOCOL *usbio, EFI_USB_DEVICE_DESCRIPTOR *efidesc)
Get device descriptor.
Definition efi_usb.c:835
static EFI_STATUS EFIAPI efi_usb_sync_interrupt_transfer(EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN *len, UINTN timeout, UINT32 *status)
Perform synchronous interrupt transfer.
Definition efi_usb.c:680
static EFI_STATUS EFIAPI efi_usb_async_isochronous_transfer(EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN len, EFI_ASYNC_USB_TRANSFER_CALLBACK callback, VOID *context)
Perform asynchronous isochronous transfers.
Definition efi_usb.c:811
static EFI_STATUS EFIAPI efi_usb_isochronous_transfer(EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN len, UINT32 *status)
Perform synchronous isochronous transfer.
Definition efi_usb.c:781
static EFI_STATUS EFIAPI efi_usb_port_reset(EFI_USB_IO_PROTOCOL *usbio)
Reset port.
Definition efi_usb.c:1061
static EFI_STATUS EFIAPI efi_usb_get_string_descriptor(EFI_USB_IO_PROTOCOL *usbio, UINT16 language, UINT8 index, CHAR16 **string)
Get string descriptor.
Definition efi_usb.c:955
static EFI_STATUS EFIAPI efi_usb_get_endpoint_descriptor(EFI_USB_IO_PROTOCOL *usbio, UINT8 index, EFI_USB_ENDPOINT_DESCRIPTOR *efidesc)
Get endpoint descriptor.
Definition efi_usb.c:913
static EFI_STATUS EFIAPI efi_usb_get_supported_languages(EFI_USB_IO_PROTOCOL *usbio, UINT16 **languages, UINT16 *len)
Get supported languages.
Definition efi_usb.c:1039
static EFI_STATUS EFIAPI efi_usb_bulk_transfer(EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data, UINTN *len, UINTN timeout, UINT32 *status)
Perform bulk transfer.
Definition efi_usb.c:635
static EFI_STATUS EFIAPI efi_usb_get_interface_descriptor(EFI_USB_IO_PROTOCOL *usbio, EFI_USB_INTERFACE_DESCRIPTOR *efidesc)
Get interface descriptor.
Definition efi_usb.c:880
static EFI_STATUS EFIAPI efi_usb_get_config_descriptor(EFI_USB_IO_PROTOCOL *usbio, EFI_USB_CONFIG_DESCRIPTOR *efidesc)
Get configuration descriptor.
Definition efi_usb.c:857
static EFI_STATUS EFIAPI efi_usb_control_transfer(EFI_USB_IO_PROTOCOL *usbio, EFI_USB_DEVICE_REQUEST *packet, EFI_USB_DATA_DIRECTION direction, UINT32 timeout, VOID *data, UINTN len, UINT32 *status)
Perform control transfer.
Definition efi_usb.c:553
static EFI_STATUS EFIAPI efi_usb_async_interrupt_transfer(EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, BOOLEAN start, UINTN interval, UINTN len, EFI_ASYNC_USB_TRANSFER_CALLBACK callback, VOID *context)
Perform asynchronous interrupt transfer.
Definition efi_usb.c:727

USB I/O protocol.

Definition at line 1078 of file efi_usb.c.

1078 {
1079 .UsbControlTransfer = efi_usb_control_transfer,
1080 .UsbBulkTransfer = efi_usb_bulk_transfer,
1081 .UsbAsyncInterruptTransfer = efi_usb_async_interrupt_transfer,
1082 .UsbSyncInterruptTransfer = efi_usb_sync_interrupt_transfer,
1083 .UsbIsochronousTransfer = efi_usb_isochronous_transfer,
1084 .UsbAsyncIsochronousTransfer = efi_usb_async_isochronous_transfer,
1085 .UsbGetDeviceDescriptor = efi_usb_get_device_descriptor,
1086 .UsbGetConfigDescriptor = efi_usb_get_config_descriptor,
1087 .UsbGetInterfaceDescriptor = efi_usb_get_interface_descriptor,
1088 .UsbGetEndpointDescriptor = efi_usb_get_endpoint_descriptor,
1089 .UsbGetStringDescriptor = efi_usb_get_string_descriptor,
1090 .UsbGetSupportedLanguages = efi_usb_get_supported_languages,
1091 .UsbPortReset = efi_usb_port_reset,
1092};

Referenced by efi_usb_install().

◆ efi_usb_ids

struct usb_device_id efi_usb_ids[]
static
Initial value:
= {
USB_ID ( 0xffff, 0xffff, "usbio", "USB passthrough", 0 ),
}
#define USB_ID(_vendor, _product, _name, _description, _data)
Definition usb.h:1373

USB I/O protocol device IDs.

Definition at line 1351 of file efi_usb.c.

1351 {
1352 USB_ID ( 0xffff, 0xffff, "usbio", "USB passthrough", 0 ),
1353};

◆ __usb_fallback_driver

struct usb_driver usbio_driver __usb_fallback_driver
Initial value:
= {
.ids = efi_usb_ids,
.id_count = ( sizeof ( efi_usb_ids ) / sizeof ( efi_usb_ids[0] ) ),
.probe = efi_usb_probe,
.remove = efi_usb_remove,
}
static int efi_usb_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition efi_usb.c:1262
static struct usb_device_id efi_usb_ids[]
USB I/O protocol device IDs.
Definition efi_usb.c:1351
static void efi_usb_remove(struct usb_function *func)
Remove device.
Definition efi_usb.c:1339
#define USB_ANY_ID
Match-anything ID.
Definition usb.h:1385
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1401
@ USB_SCORE_FALLBACK
Fallback driver (has no effect on overall score)
Definition usb.h:1461

USB I/O protocol driver.

Definition at line 1356 of file efi_usb.c.

1356 {
1357 .ids = efi_usb_ids,
1358 .id_count = ( sizeof ( efi_usb_ids ) / sizeof ( efi_usb_ids[0] ) ),
1360 .score = USB_SCORE_FALLBACK,
1361 .probe = efi_usb_probe,
1362 .remove = efi_usb_remove,
1363};