iPXE
efi_usb.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include <unistd.h>
31#include <errno.h>
32#include <assert.h>
33#include <ipxe/efi/efi.h>
34#include <ipxe/efi/efi_path.h>
35#include <ipxe/efi/efi_driver.h>
36#include <ipxe/efi/efi_null.h>
37#include <ipxe/efi/efi_usb.h>
38#include <ipxe/usb.h>
39
40/** @file
41 *
42 * EFI USB I/O PROTOCOL
43 *
44 */
45
46/**
47 * Transcribe data direction (for debugging)
48 *
49 * @v direction Data direction
50 * @ret text Transcribed data direction
51 */
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}
61
62/******************************************************************************
63 *
64 * Endpoints
65 *
66 ******************************************************************************
67 */
68
69/**
70 * Poll USB bus (from endpoint event timer)
71 *
72 * @v event EFI event
73 * @v context EFI USB endpoint
74 */
76 VOID *context ) {
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}
87
88/**
89 * Get endpoint MTU
90 *
91 * @v usbintf EFI USB interface
92 * @v endpoint Endpoint address
93 * @ret mtu Endpoint MTU, or negative error
94 */
95static int efi_usb_mtu ( struct efi_usb_interface *usbintf,
96 unsigned int endpoint ) {
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}
122
123/**
124 * Check if endpoint is open
125 *
126 * @v usbintf EFI USB interface
127 * @v endpoint Endpoint address
128 * @ret is_open Endpoint is open
129 */
130static int efi_usb_is_open ( struct efi_usb_interface *usbintf,
131 unsigned int endpoint ) {
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}
137
138/**
139 * Open endpoint
140 *
141 * @v usbintf EFI USB interface
142 * @v endpoint Endpoint address
143 * @v attributes Endpoint attributes
144 * @v interval Interval (in milliseconds)
145 * @v driver Driver operations
146 * @ret rc Return status code
147 */
149 unsigned int endpoint, unsigned int attributes,
150 unsigned int interval,
151 struct usb_endpoint_driver_operations *driver ) {
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}
219
220/**
221 * Close endpoint
222 *
223 * @v usbep EFI USB endpoint
224 */
225static void efi_usb_close ( struct efi_usb_endpoint *usbep ) {
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}
243
244/**
245 * Close all endpoints
246 *
247 * @v usbintf EFI USB interface
248 */
249static void efi_usb_close_all ( struct efi_usb_interface *usbintf ) {
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}
260
261/**
262 * Free all endpoints
263 *
264 * @v usbintf EFI USB interface
265 */
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}
280
281/**
282 * Complete synchronous transfer
283 *
284 * @v ep USB endpoint
285 * @v iobuf I/O buffer
286 * @v rc Completion status code
287 */
289 struct io_buffer *iobuf __unused, int rc ) {
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}
296
297/** Synchronous endpoint operations */
301
302/**
303 * Perform synchronous transfer
304 *
305 * @v usbintf USB endpoint
306 * @v endpoint Endpoint address
307 * @v attributes Endpoint attributes
308 * @v timeout Timeout (in milliseconds)
309 * @v data Data buffer
310 * @v len Length of data buffer
311 * @ret rc Return status code
312 */
313static int efi_usb_sync_transfer ( struct efi_usb_interface *usbintf,
314 unsigned int endpoint,
315 unsigned int attributes,
316 unsigned int timeout,
317 void *data, size_t *len ) {
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}
398
399/**
400 * Complete asynchronous transfer
401 *
402 * @v ep USB endpoint
403 * @v iobuf I/O buffer
404 * @v rc Completion status code
405 */
406static void efi_usb_async_complete ( struct usb_endpoint *ep,
407 struct io_buffer *iobuf, int rc ) {
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}
433
434/** Asynchronous endpoint operations */
438
439/**
440 * Start asynchronous transfer
441 *
442 * @v usbintf EFI USB interface
443 * @v endpoint Endpoint address
444 * @v interval Interval (in milliseconds)
445 * @v len Transfer length
446 * @v callback Callback function
447 * @v context Context for callback function
448 * @ret rc Return status code
449 */
450static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
451 unsigned int endpoint, unsigned int interval,
452 size_t len,
454 void *context ) {
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}
507
508/**
509 * Stop asynchronous transfer
510 *
511 * @v usbintf EFI USB interface
512 * @v endpoint Endpoint address
513 */
515 unsigned int endpoint ) {
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}
532
533/******************************************************************************
534 *
535 * USB I/O protocol
536 *
537 ******************************************************************************
538 */
539
540/**
541 * Perform control transfer
542 *
543 * @v usbio USB I/O protocol
544 * @v packet Setup packet
545 * @v direction Data direction
546 * @v timeout Timeout (in milliseconds)
547 * @v data Data buffer
548 * @v len Length of data
549 * @ret status Transfer status
550 * @ret efirc EFI status code
551 */
552static EFI_STATUS EFIAPI
557 UINT32 *status ) {
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}
622
623/**
624 * Perform bulk transfer
625 *
626 * @v usbio USB I/O protocol
627 * @v endpoint Endpoint address
628 * @v data Data buffer
629 * @v len Length of data
630 * @v timeout Timeout (in milliseconds)
631 * @ret status Transfer status
632 * @ret efirc EFI status code
633 */
634static EFI_STATUS EFIAPI
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}
667
668/**
669 * Perform synchronous interrupt transfer
670 *
671 * @v usbio USB I/O protocol
672 * @v endpoint Endpoint address
673 * @v data Data buffer
674 * @v len Length of data
675 * @v timeout Timeout (in milliseconds)
676 * @ret status Transfer status
677 * @ret efirc EFI status code
678 */
679static EFI_STATUS EFIAPI
682 UINT32 *status ) {
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}
713
714/**
715 * Perform asynchronous interrupt transfer
716 *
717 * @v usbio USB I/O protocol
718 * @v endpoint Endpoint address
719 * @v start Start (rather than stop) transfer
720 * @v interval Polling interval (in milliseconds)
721 * @v len Data length
722 * @v callback Callback function
723 * @v context Context for callback function
724 * @ret efirc EFI status code
725 */
726static EFI_STATUS EFIAPI
728 BOOLEAN start, UINTN interval, UINTN len,
730 VOID *context ) {
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}
769
770/**
771 * Perform synchronous isochronous transfer
772 *
773 * @v usbio USB I/O protocol
774 * @v endpoint Endpoint address
775 * @v data Data buffer
776 * @v len Length of data
777 * @ret status Transfer status
778 * @ret efirc EFI status code
779 */
780static EFI_STATUS EFIAPI
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}
797
798/**
799 * Perform asynchronous isochronous transfers
800 *
801 * @v usbio USB I/O protocol
802 * @v endpoint Endpoint address
803 * @v data Data buffer
804 * @v len Length of data
805 * @v callback Callback function
806 * @v context Context for callback function
807 * @ret status Transfer status
808 * @ret efirc EFI status code
809 */
810static EFI_STATUS EFIAPI
812 VOID *data, UINTN len,
814 VOID *context ) {
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}
826
827/**
828 * Get device descriptor
829 *
830 * @v usbio USB I/O protocol
831 * @ret efidesc EFI device descriptor
832 * @ret efirc EFI status code
833 */
834static EFI_STATUS EFIAPI
836 EFI_USB_DEVICE_DESCRIPTOR *efidesc ) {
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}
848
849/**
850 * Get configuration descriptor
851 *
852 * @v usbio USB I/O protocol
853 * @ret efidesc EFI interface descriptor
854 * @ret efirc EFI status code
855 */
856static EFI_STATUS EFIAPI
858 EFI_USB_CONFIG_DESCRIPTOR *efidesc ) {
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}
871
872/**
873 * Get interface descriptor
874 *
875 * @v usbio USB I/O protocol
876 * @ret efidesc EFI interface descriptor
877 * @ret efirc EFI status code
878 */
879static EFI_STATUS EFIAPI
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}
903
904/**
905 * Get endpoint descriptor
906 *
907 * @v usbio USB I/O protocol
908 * @v address Endpoint index
909 * @ret efidesc EFI interface descriptor
910 * @ret efirc EFI status code
911 */
912static EFI_STATUS EFIAPI
914 EFI_USB_ENDPOINT_DESCRIPTOR *efidesc ) {
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}
944
945/**
946 * Get string descriptor
947 *
948 * @v usbio USB I/O protocol
949 * @v language Language ID
950 * @v index String index
951 * @ret string String
952 * @ret efirc EFI status code
953 */
954static EFI_STATUS EFIAPI
956 UINT8 index, CHAR16 **string ) {
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}
1029
1030/**
1031 * Get supported languages
1032 *
1033 * @v usbio USB I/O protocol
1034 * @ret languages Language ID table
1035 * @ret len Length of language ID table
1036 * @ret efirc EFI status code
1037 */
1038static EFI_STATUS EFIAPI
1040 UINT16 **languages, UINT16 *len ) {
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}
1053
1054/**
1055 * Reset port
1056 *
1057 * @v usbio USB I/O protocol
1058 * @ret efirc EFI status code
1059 */
1060static EFI_STATUS EFIAPI
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}
1076
1077/** USB I/O protocol */
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};
1093
1094/******************************************************************************
1095 *
1096 * USB driver
1097 *
1098 ******************************************************************************
1099 */
1100
1101/**
1102 * Install interface
1103 *
1104 * @v usbdev EFI USB device
1105 * @v interface Interface number
1106 * @ret rc Return status code
1107 */
1108static int efi_usb_install ( struct efi_usb_device *usbdev,
1109 unsigned int interface ) {
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}
1182
1183/**
1184 * Uninstall interface
1185 *
1186 * @v usbintf EFI USB interface
1187 */
1188static void efi_usb_uninstall ( struct efi_usb_interface *usbintf ) {
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}
1238
1239/**
1240 * Uninstall all interfaces
1241 *
1242 * @v usbdev EFI USB device
1243 */
1244static void efi_usb_uninstall_all ( struct efi_usb_device *efiusb ) {
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}
1254
1255/**
1256 * Probe device
1257 *
1258 * @v func USB function
1259 * @v config Configuration descriptor
1260 * @ret rc Return status code
1261 */
1262static int efi_usb_probe ( struct usb_function *func,
1263 struct usb_configuration_descriptor *config ) {
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}
1333
1334/**
1335 * Remove device
1336 *
1337 * @v func USB function
1338 */
1339static void efi_usb_remove ( struct usb_function *func ) {
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}
1349
1350/** USB I/O protocol device IDs */
1351static struct usb_device_id efi_usb_ids[] = {
1352 USB_ID ( 0xffff, 0xffff, "usbio", "USB passthrough", 0 ),
1353};
1354
1355/** USB I/O protocol driver */
1356struct usb_driver usbio_driver __usb_fallback_driver = {
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};
unsigned short UINT16
2-byte unsigned value.
unsigned char BOOLEAN
Logical Boolean.
UINT64 UINTN
Unsigned value of native width.
unsigned short CHAR16
2-byte Character.
#define EFIAPI
unsigned char UINT8
1-byte unsigned value.
unsigned int UINT32
4-byte unsigned value.
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define VOID
Undeclared type.
Definition Base.h:272
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
#define EFI_INVALID_PARAMETER
Enumeration of EFI_STATUS.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
@ EfiBootServicesData
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
#define TPL_CALLBACK
Definition UefiSpec.h:649
@ TimerCancel
An event's timer settings is to be cancelled and not trigger time is to be set/.
Definition UefiSpec.h:544
@ TimerPeriodic
An event is to be signaled periodically at a specified interval from the current time.
Definition UefiSpec.h:548
#define EVT_TIMER
Definition UefiSpec.h:451
#define EVT_NOTIFY_SIGNAL
Definition UefiSpec.h:454
USB_DEVICE_DESCRIPTOR EFI_USB_DEVICE_DESCRIPTOR
Definition UsbIo.h:39
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
#define EFI_USB_ERR_TIMEOUT
Definition UsbIo.h:63
USB_CONFIG_DESCRIPTOR EFI_USB_CONFIG_DESCRIPTOR
Definition UsbIo.h:40
USB_INTERFACE_DESCRIPTOR EFI_USB_INTERFACE_DESCRIPTOR
Definition UsbIo.h:41
USB_DEVICE_REQUEST EFI_USB_DEVICE_REQUEST
Definition UsbIo.h:38
EFI_STATUS(EFIAPI * EFI_ASYNC_USB_TRANSFER_CALLBACK)(IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Status)
Async USB transfer callback routine.
Definition UsbIo.h:83
#define EFI_USB_ERR_SYSTEM
Definition UsbIo.h:65
USB_ENDPOINT_DESCRIPTOR EFI_USB_ENDPOINT_DESCRIPTOR
Definition UsbIo.h:42
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
pseudo_bit_t value[0x00020]
Definition arbel.h:2
long index
Definition bigint.h:65
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
void timeout(int)
ring len
Length.
Definition dwmac.h:226
int efi_disconnect(EFI_HANDLE device, EFI_HANDLE driver)
Disconnect UEFI driver(s)
Definition efi_connect.c:90
int efi_connect(EFI_HANDLE device, EFI_HANDLE driver)
Connect UEFI driver(s)
Definition efi_connect.c:58
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
EFI driver interface.
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_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition efi_init.c:383
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition efi_init.c:399
void efi_nullify_usbio(EFI_USB_IO_PROTOCOL *usbio)
Nullify USB I/O protocol.
Definition efi_null.c:712
EFI null interfaces.
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
Definition efi_path.c:697
EFI device paths.
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 void efi_usb_sync_complete(struct usb_endpoint *ep, struct io_buffer *iobuf __unused, int rc)
Complete synchronous transfer.
Definition efi_usb.c:288
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 void efi_usb_uninstall_all(struct efi_usb_device *efiusb)
Uninstall all interfaces.
Definition efi_usb.c:1244
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 EFI_USB_IO_PROTOCOL efi_usb_io_protocol
USB I/O protocol.
Definition efi_usb.c:1078
static int efi_usb_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition efi_usb.c:1262
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 void efi_usb_async_stop(struct efi_usb_interface *usbintf, unsigned int endpoint)
Stop asynchronous transfer.
Definition efi_usb.c:514
static void efi_usb_close(struct efi_usb_endpoint *usbep)
Close endpoint.
Definition efi_usb.c:225
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 struct usb_endpoint_driver_operations efi_usb_async_driver
Asynchronous endpoint operations.
Definition efi_usb.c:435
static EFI_STATUS EFIAPI efi_usb_port_reset(EFI_USB_IO_PROTOCOL *usbio)
Reset port.
Definition efi_usb.c:1061
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
static void efi_usb_async_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete asynchronous transfer.
Definition efi_usb.c:406
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 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 int efi_usb_install(struct efi_usb_device *usbdev, unsigned int interface)
Install interface.
Definition efi_usb.c:1108
static struct usb_device_id efi_usb_ids[]
USB I/O protocol device IDs.
Definition efi_usb.c:1351
static void efi_usb_uninstall(struct efi_usb_interface *usbintf)
Uninstall interface.
Definition efi_usb.c:1188
static void efi_usb_remove(struct usb_function *func)
Remove device.
Definition efi_usb.c:1339
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 struct usb_endpoint_driver_operations efi_usb_sync_driver
Synchronous endpoint operations.
Definition efi_usb.c:298
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 void efi_usb_free_all(struct efi_usb_interface *usbintf)
Free all endpoints.
Definition efi_usb.c:266
static const char * efi_usb_direction_name(EFI_USB_DATA_DIRECTION direction)
Transcribe data direction (for debugging)
Definition efi_usb.c:52
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 int efi_usb_mtu(struct efi_usb_interface *usbintf, unsigned int endpoint)
Get endpoint MTU.
Definition efi_usb.c:95
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 void efi_usb_close_all(struct efi_usb_interface *usbintf)
Close all endpoints.
Definition efi_usb.c:249
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.
#define EFI_USB_ASYNC_FILL
Asynchronous transfer fill level.
Definition efi_usb.h:81
uint8_t direction
Direction.
Definition ena.h:3
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint32_t mtu
Maximum MTU.
Definition ena.h:17
struct ena_llq_option header
Header locations.
Definition ena.h:5
uint8_t status
Status.
Definition ena.h:5
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
uint32_t start
Starting offset.
Definition netvsc.h:1
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define ENOMEM
Not enough space.
Definition errno.h:535
#define EINPROGRESS
Operation in progress.
Definition errno.h:419
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ENODEV
No such device.
Definition errno.h:510
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
struct ib_cm_path alternate
Alternate path.
Definition ib_mad.h:31
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
#define le16_to_cpu(value)
Definition byteswap.h:113
EFI API.
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:167
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
#define EFI_EVENT
Definition efi.h:54
EFI_SYSTEM_TABLE * efi_systab
Universal Serial Bus (USB)
#define USB_ENDPOINT_DESCRIPTOR
A USB endpoint descriptor.
Definition usb.h:278
static void usb_recycle(struct usb_endpoint *ep, struct io_buffer *iobuf)
Recycle I/O buffer.
Definition usb.h:633
#define USB_ENDPOINT_ATTR_BULK
Bulk endpoint transfer type.
Definition usb.h:290
#define __usb_fallback_driver
Declare a USB fallback driver.
Definition usb.h:1456
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
#define USB_REQUEST_TYPE(type)
Construct USB request type.
Definition usb.h:122
#define USB_ENDPOINT_IDX(address)
Construct endpoint index from endpoint address.
Definition usb.h:528
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_ANY_ID
Match-anything ID.
Definition usb.h:1385
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1401
#define for_each_interface_descriptor(desc, config, interface)
Iterate over all configuration descriptors within an interface descriptor.
Definition usb.h:394
#define USB_ENDPOINT_IN
Endpoint direction is in.
Definition usb.h:525
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition usb.h:1072
#define USB_STRING_DESCRIPTOR
A USB string descriptor.
Definition usb.h:239
#define USB_ENDPOINT_ATTR_INTERRUPT
Interrupt endpoint transfer type.
Definition usb.h:293
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
#define USB_ID(_vendor, _product, _name, _description, _data)
Definition usb.h:1373
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition usb.h:707
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
#define USB_SET_INTERFACE
Set interface.
Definition usb.h:153
@ USB_SCORE_FALLBACK
Fallback driver (has no effect on overall score)
Definition usb.h:1461
#define USB_ENDPOINT_MTU(sizes)
USB endpoint MTU.
Definition usb.h:308
#define USB_SET_CONFIGURATION
Set configuration.
Definition usb.h:146
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:718
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void * memmove(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
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#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
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_SET_TIMER SetTimer
Definition UefiSpec.h:1956
EFI_FREE_POOL FreePool
Definition UefiSpec.h:1950
EFI_CREATE_EVENT CreateEvent
Definition UefiSpec.h:1955
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_CLOSE_EVENT CloseEvent
Definition UefiSpec.h:1959
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
EFI_ALLOCATE_POOL AllocatePool
Definition UefiSpec.h:1949
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
An EFI USB device.
Definition efi_usb.h:20
struct list_head interfaces
List of interfaces.
Definition efi_usb.h:32
struct usb_function * func
The underlying USB function.
Definition efi_usb.h:24
size_t lang_len
Length of supported languages.
Definition efi_usb.h:30
uint16_t * lang
Supported languages.
Definition efi_usb.h:28
const char * name
Name.
Definition efi_usb.h:22
struct usb_configuration_descriptor * config
Configuration descriptor.
Definition efi_usb.h:26
An EFI USB device endpoint.
Definition efi_usb.h:60
EFI_EVENT event
Asynchronous timer event.
Definition efi_usb.h:70
struct efi_usb_interface * usbintf
EFI USB device interface.
Definition efi_usb.h:62
EFI_ASYNC_USB_TRANSFER_CALLBACK callback
Asynchronous callback handler.
Definition efi_usb.h:72
void * context
Asynchronous callback context.
Definition efi_usb.h:74
int rc
Most recent synchronous completion status.
Definition efi_usb.h:67
struct usb_endpoint ep
USB endpoint.
Definition efi_usb.h:64
An EFI USB device interface.
Definition efi_usb.h:36
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition efi_usb.h:53
unsigned int alternate
Alternate setting.
Definition efi_usb.h:47
struct efi_usb_device * usbdev
Containing USB device.
Definition efi_usb.h:40
struct efi_usb_endpoint * endpoint[32]
Opened endpoints.
Definition efi_usb.h:56
EFI_HANDLE handle
EFI handle.
Definition efi_usb.h:49
EFI_USB_IO_PROTOCOL usbio
USB I/O protocol.
Definition efi_usb.h:51
struct list_head list
List of interfaces.
Definition efi_usb.h:42
unsigned int interface
Interface number.
Definition efi_usb.h:45
char name[32]
Name.
Definition efi_usb.h:38
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
A USB configuration descriptor.
Definition usb.h:210
uint8_t config
Configuration value.
Definition usb.h:218
uint16_t len
Total length.
Definition usb.h:214
A USB descriptor header.
Definition usb.h:173
A USB device ID.
Definition usb.h:1361
A USB device.
Definition usb.h:723
struct usb_port * port
USB port.
Definition usb.h:727
struct usb_device_descriptor device
Device descriptor.
Definition usb.h:735
A USB driver.
Definition usb.h:1419
A USB endpoint descriptor.
Definition usb.h:264
USB endpoint driver operations.
Definition usb.h:489
A USB endpoint.
Definition usb.h:404
int open
Endpoint is open.
Definition usb.h:419
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
const char * name
Name.
Definition usb.h:676
struct usb_bus * bus
USB bus.
Definition usb.h:845
A USB interface descriptor.
Definition usb.h:245
struct usb_hub * hub
USB hub.
Definition usb.h:815
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
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
int usb_prefill(struct usb_endpoint *ep)
Prefill endpoint recycled buffer list.
Definition usb.c:620
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging)
Definition usb.c:221
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
int usb_refill(struct usb_endpoint *ep)
Refill endpoint.
Definition usb.c:711
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
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition usb.c:546
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383