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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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  */
95 static 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 */
112  for_each_interface_descriptor ( desc, usbdev->config, interface ) {
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  */
130 static 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 ) {
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 ),
200  TPL_CALLBACK, efi_usb_timer, usbep,
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  */
225 static void efi_usb_close ( struct efi_usb_endpoint *usbep ) {
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  */
249 static 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  */
266 static void efi_usb_free_all ( struct efi_usb_interface *usbintf ) {
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  */
288 static void efi_usb_sync_complete ( struct usb_endpoint *ep,
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 */
300 };
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  */
313 static 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  */
406 static 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 );
410  UINT32 status;
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 */
437 };
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  */
450 static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
451  unsigned int endpoint, unsigned int interval,
452  size_t len,
454  void *context ) {
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,
468  USB_ENDPOINT_ATTR_INTERRUPT, interval,
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 ) {
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  */
552 static EFI_STATUS EFIAPI
554  EFI_USB_DEVICE_REQUEST *packet,
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  */
634 static 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  */
679 static 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  */
726 static 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  */
780 static EFI_STATUS EFIAPI
782  VOID *data, UINTN len, UINT32 *status ) {
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  */
810 static 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  */
834 static 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  */
856 static 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  */
879 static EFI_STATUS EFIAPI
881  EFI_USB_INTERFACE_DESCRIPTOR *efidesc ) {
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  */
912 static 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 */
935  for_each_interface_descriptor ( desc, usbdev->config, interface ) {
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  */
954 static EFI_STATUS EFIAPI
956  UINT8 index, CHAR16 **string ) {
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  */
1038 static 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  */
1060 static 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 */
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  */
1108 static int efi_usb_install ( struct efi_usb_device *usbdev,
1109  unsigned int interface ) {
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  */
1188 static void efi_usb_uninstall ( struct efi_usb_interface *usbintf ) {
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  */
1201  if ( ! efi_shutdown_in_progress )
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  */
1244 static 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  */
1262 static 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  */
1339 static 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 */
1351 static struct usb_device_id efi_usb_ids[] = {
1352  {
1353  .name = "usbio",
1354  .vendor = USB_ANY_ID,
1355  .product = USB_ANY_ID,
1356  },
1357 };
1358 
1359 /** USB I/O protocol driver */
1360 struct usb_driver usbio_driver __usb_fallback_driver = {
1361  .ids = efi_usb_ids,
1362  .id_count = ( sizeof ( efi_usb_ids ) / sizeof ( efi_usb_ids[0] ) ),
1364  .score = USB_SCORE_FALLBACK,
1365  .probe = efi_usb_probe,
1366  .remove = efi_usb_remove,
1367 };
uint16_t * lang
Supported languages.
Definition: efi_usb.h:28
UINT8 Request
Definition: Usb.h:97
A USB driver.
Definition: usb.h:1407
static void efi_usb_async_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete asynchronous transfer.
Definition: efi_usb.c:406
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
#define EINVAL
Invalid argument.
Definition: errno.h:429
static EFI_USB_IO_PROTOCOL efi_usb_io_protocol
USB I/O protocol.
Definition: efi_usb.c:1078
static void efi_usb_close(struct efi_usb_endpoint *usbep)
Close endpoint.
Definition: efi_usb.c:225
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:118
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EFI_USB_ASYNC_FILL
Asynchronous transfer fill level.
Definition: efi_usb.h:81
A USB device ID.
Definition: usb.h:1361
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
#define iob_put(iobuf, len)
Definition: iobuf.h:125
size_t lang_len
Length of supported languages.
Definition: efi_usb.h:30
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:496
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:175
unsigned int alternate
Alternate setting.
Definition: efi_usb.h:47
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:718
An event is to be signaled periodically at a specified interval from the current time.
Definition: UefiSpec.h:548
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 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
EFI driver interface.
int efi_connect(EFI_HANDLE device, EFI_HANDLE driver)
Connect UEFI driver(s)
Definition: efi_connect.c:58
uint8_t interface[0]
List of interface numbers.
Definition: usb.h:697
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_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_port_reset(EFI_USB_IO_PROTOCOL *usbio)
Reset port.
Definition: efi_usb.c:1061
const char * name
Name.
Definition: usb.h:676
char name[32]
Name.
Definition: efi_usb.h:38
struct usb_function * func
The underlying USB function.
Definition: efi_usb.h:24
const char * name
Name.
Definition: usb.h:1363
static struct usb_endpoint_driver_operations efi_usb_sync_driver
Synchronous endpoint operations.
Definition: efi_usb.c:298
unsigned int count
Number of interfaces.
Definition: usb.h:665
#define USB_STRING_DESCRIPTOR
A USB string descriptor.
Definition: usb.h:239
Error codes.
Definition: efi.h:63
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:383
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
static void efi_usb_async_stop(struct efi_usb_interface *usbintf, unsigned int endpoint)
Stop asynchronous transfer.
Definition: efi_usb.c:514
unsigned char BOOLEAN
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_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
const char * name
Name.
Definition: efi_usb.h:22
static VOID EFIAPI efi_usb_timer(EFI_EVENT event __unused, VOID *context)
Poll USB bus (from endpoint event timer)
Definition: efi_usb.c:75
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition: efi_usb.h:53
#define DBGC(...)
Definition: compiler.h:505
static struct usb_endpoint_driver_operations efi_usb_async_driver
Asynchronous endpoint operations.
Definition: efi_usb.c:435
USB I/O protocol.
long index
Definition: bigint.h:65
#define ENOENT
No such file or directory.
Definition: errno.h:515
Standard Interface Descriptor USB 2.0 spec, Section 9.6.5.
Definition: Usb.h:158
unsigned int UINT32
Definition: ProcessorBind.h:99
static void efi_usb_remove(struct usb_function *func)
Remove device.
Definition: efi_usb.c:1339
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
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition: usb.c:546
The EFI_USB_IO_PROTOCOL provides four basic transfers types described in the USB 1....
Definition: UsbIo.h:479
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2010
int usb_prefill(struct usb_endpoint *ep)
Prefill endpoint recycled buffer list.
Definition: usb.c:620
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
Definition: usb.c:294
#define for_each_interface_descriptor(desc, config, interface)
Iterate over all configuration descriptors within an interface descriptor.
Definition: usb.h:394
unsigned short CHAR16
EFI_CLOSE_EVENT CloseEvent
Definition: UefiSpec.h:1959
EFI_SET_TIMER SetTimer
Definition: UefiSpec.h:1956
uint8_t direction
Direction.
Definition: ena.h:14
#define USB_ENDPOINT_ATTR_BULK
Bulk endpoint transfer type.
Definition: usb.h:290
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An EFI USB device.
Definition: efi_usb.h:20
EFI_USB_DATA_DIRECTION
USB data transfer direction.
Definition: UsbIo.h:47
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
Definition: usb.c:400
int open
Endpoint is open.
Definition: usb.h:419
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:131
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
unsigned char UINT8
int usb_refill(struct usb_endpoint *ep)
Refill endpoint.
Definition: usb.c:711
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
static struct usb_device_id efi_usb_ids[]
USB I/O protocol device IDs.
Definition: efi_usb.c:1351
struct efi_usb_endpoint * endpoint[32]
Opened endpoints.
Definition: efi_usb.h:56
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
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
#define EFI_USB_ERR_SYSTEM
Definition: UsbIo.h:65
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ENOMEM
Not enough space.
Definition: errno.h:535
A USB endpoint.
Definition: usb.h:404
An EFI USB device interface.
Definition: efi_usb.h:36
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An event's timer settings is to be cancelled and not trigger time is to be set/.
Definition: UefiSpec.h:544
A USB interface descriptor.
Definition: usb.h:245
Format of Setup Data for USB Device Requests USB 2.0 spec, Section 9.3.
Definition: Usb.h:95
struct usb_port * port
USB port.
Definition: usb.h:727
Assertions.
static void usb_recycle(struct usb_endpoint *ep, struct io_buffer *iobuf)
Recycle I/O buffer.
Definition: usb.h:633
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
An object interface.
Definition: interface.h:125
static int efi_usb_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: efi_usb.c:1262
void efi_nullify_usbio(EFI_USB_IO_PROTOCOL *usbio)
Nullify USB I/O protocol.
Definition: efi_null.c:712
static const char * efi_usb_direction_name(EFI_USB_DATA_DIRECTION direction)
Transcribe data direction (for debugging)
Definition: efi_usb.c:52
struct ib_cm_path alternate
Alternate path.
Definition: ib_mad.h:43
EFI_EVENT event
Asynchronous timer event.
Definition: efi_usb.h:70
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
ring len
Length.
Definition: dwmac.h:231
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 usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition: usb.h:617
EFI_CREATE_EVENT CreateEvent
Definition: UefiSpec.h:1955
int rc
Most recent synchronous completion status.
Definition: efi_usb.h:67
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:707
void * context
Asynchronous callback context.
Definition: efi_usb.h:74
struct list_head interfaces
List of interfaces.
Definition: efi_usb.h:32
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
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 void efi_usb_sync_complete(struct usb_endpoint *ep, struct io_buffer *iobuf __unused, int rc)
Complete synchronous transfer.
Definition: efi_usb.c:288
EFI null interfaces.
A USB device.
Definition: usb.h:723
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
UINT8 RequestType
Definition: Usb.h:96
#define EINPROGRESS
Operation in progress.
Definition: errno.h:419
unsigned short UINT16
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition: usb.h:1072
#define USB_ENDPOINT_IN
Endpoint direction is in.
Definition: usb.h:525
#define USB_ENDPOINT_ATTR_INTERRUPT
Interrupt endpoint transfer type.
Definition: usb.h:293
unsigned int interface
Interface number.
Definition: efi_usb.h:45
#define USB_SET_INTERFACE
Set interface.
Definition: usb.h:153
static void efi_usb_uninstall(struct efi_usb_interface *usbintf)
Uninstall interface.
Definition: efi_usb.c:1188
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
EFI_GUID efi_usb_io_protocol_guid
USB I/O protocol GUID.
Definition: efi_guid.c:429
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
Definition: efi_path.c:697
#define EFIAPI
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
An EFI USB device endpoint.
Definition: efi_usb.h:60
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
EFI Boot Services Table.
Definition: UefiSpec.h:1931
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
struct usb_driver usbio_driver __usb_fallback_driver
USB I/O protocol driver.
Definition: efi_usb.c:1360
UINT16 Length
Definition: Usb.h:100
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1389
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2011
#define TPL_CALLBACK
Definition: UefiSpec.h:649
#define ENODEV
No such device.
Definition: errno.h:510
#define EFI_USB_ERR_TIMEOUT
Definition: UsbIo.h:63
EFI device paths.
struct usb_configuration_descriptor * config
Configuration descriptor.
Definition: efi_usb.h:26
UINT64 UINTN
Unsigned value of native width.
#define EVT_NOTIFY_SIGNAL
Definition: UefiSpec.h:454
static void efi_usb_free_all(struct efi_usb_interface *usbintf)
Free all endpoints.
Definition: efi_usb.c:266
uint8_t name
Interface name.
Definition: usb.h:257
static void efi_usb_uninstall_all(struct efi_usb_device *efiusb)
Uninstall all interfaces.
Definition: efi_usb.c:1244
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 EFI_INVALID_PARAMETER
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
struct usb_device_descriptor device
Device descriptor.
Definition: usb.h:735
Standard Endpoint Descriptor USB 2.0 spec, Section 9.6.6.
Definition: Usb.h:174
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:169
struct usb_device * usb
USB device.
Definition: usb.h:678
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 le16_to_cpu(value)
Definition: byteswap.h:113
#define VOID
Undeclared type.
Definition: Base.h:272
#define USB_ENDPOINT_IDX(address)
Construct endpoint index from endpoint address.
Definition: usb.h:528
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1950
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging)
Definition: usb.c:221
void * memmove(void *dest, const void *src, size_t len) __nonnull
struct usb_endpoint ep
USB endpoint.
Definition: efi_usb.h:64
EFI_USB_IO_CONTROL_TRANSFER UsbControlTransfer
Definition: UsbIo.h:483
EFI API.
uint8_t status
Status.
Definition: ena.h:16
A USB descriptor header.
Definition: usb.h:173
EFI_USB_IO_PROTOCOL usbio
USB I/O protocol.
Definition: efi_usb.h:51
FILE_SECBOOT(PERMITTED)
#define USB_REQUEST_TYPE(type)
Construct USB request type.
Definition: usb.h:122
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:79
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
A USB configuration descriptor.
Definition: usb.h:210
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
A USB endpoint descriptor.
Definition: usb.h:264
uint8_t alternate
Alternate setting.
Definition: usb.h:251
An EFI saved task priority level.
Definition: efi.h:80
struct list_head list
List of interfaces.
Definition: efi_usb.h:42
static int efi_usb_mtu(struct efi_usb_interface *usbintf, unsigned int endpoint)
Get endpoint MTU.
Definition: efi_usb.c:95
uint8_t config
Configuration value.
Definition: usb.h:218
#define DBGC2(...)
Definition: compiler.h:522
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1373
Universal Serial Bus (USB)
uint32_t mtu
Maximum MTU.
Definition: ena.h:28
void * data
Start of data.
Definition: iobuf.h:53
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
struct usb_hub * hub
USB hub.
Definition: usb.h:815
static int efi_usb_install(struct efi_usb_device *usbdev, unsigned int interface)
Install interface.
Definition: efi_usb.c:1108
EFI_HANDLE handle
EFI handle.
Definition: efi_usb.h:49
struct ena_llq_option header
Header locations.
Definition: ena.h:16
u8 request[0]
List of IEs requested.
Definition: ieee80211.h:16
Standard Configuration Descriptor USB 2.0 spec, Section 9.6.3.
Definition: Usb.h:128
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
uint16_t len
Total length.
Definition: usb.h:214
struct usb_function_descriptor desc
Function descriptor.
Definition: usb.h:680
void timeout(int)
EFI_SYSTEM_TABLE * efi_systab
#define USB_ENDPOINT_MTU(sizes)
USB endpoint MTU.
Definition: usb.h:308
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
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
USB endpoint driver operations.
Definition: usb.h:489
A USB function.
Definition: usb.h:674
struct efi_usb_device * usbdev
Containing USB device.
Definition: efi_usb.h:40
struct usb_bus * bus
USB bus.
Definition: usb.h:845
Fallback driver (has no effect on overall score)
Definition: usb.h:1449
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
#define USB_SET_CONFIGURATION
Set configuration.
Definition: usb.h:146
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:399
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
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
Standard Device Descriptor USB 2.0 spec, Section 9.6.1.
Definition: Usb.h:107
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670
String functions.
UINT16 Value
Definition: Usb.h:98
uint8_t interface
Interface number.
Definition: usb.h:249
unsigned int address
Endpoint address.
Definition: usb.h:408
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:167
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
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
struct usb_device_id * ids
USB ID table.
Definition: usb.h:1409
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1949
int efi_disconnect(EFI_HANDLE device, EFI_HANDLE driver)
Disconnect UEFI driver(s)
Definition: efi_connect.c:90
void * memset(void *dest, int character, size_t len) __nonnull
UINT16 Index
Definition: Usb.h:99
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:60
A persistent I/O buffer.
Definition: iobuf.h:38
#define EVT_TIMER
Definition: UefiSpec.h:451