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 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <assert.h>
32 #include <ipxe/efi/efi.h>
33 #include <ipxe/efi/efi_path.h>
34 #include <ipxe/efi/efi_driver.h>
35 #include <ipxe/efi/efi_null.h>
36 #include <ipxe/efi/efi_usb.h>
37 #include <ipxe/usb.h>
38 
39 /** @file
40  *
41  * EFI USB I/O PROTOCOL
42  *
43  */
44 
45 /**
46  * Transcribe data direction (for debugging)
47  *
48  * @v direction Data direction
49  * @ret text Transcribed data direction
50  */
52 
53  switch ( direction ) {
54  case EfiUsbDataIn: return "in";
55  case EfiUsbDataOut: return "out";
56  case EfiUsbNoData: return "none";
57  default: return "<UNKNOWN>";
58  }
59 }
60 
61 /******************************************************************************
62  *
63  * Endpoints
64  *
65  ******************************************************************************
66  */
67 
68 /**
69  * Poll USB bus (from endpoint event timer)
70  *
71  * @v event EFI event
72  * @v context EFI USB endpoint
73  */
75  VOID *context ) {
76  struct efi_usb_endpoint *usbep = context;
77  struct usb_function *func = usbep->usbintf->usbdev->func;
78 
79  /* Poll bus */
80  usb_poll ( func->usb->port->hub->bus );
81 
82  /* Refill endpoint */
83  if ( usbep->ep.open )
84  usb_refill ( &usbep->ep );
85 }
86 
87 /**
88  * Get endpoint MTU
89  *
90  * @v usbintf EFI USB interface
91  * @v endpoint Endpoint address
92  * @ret mtu Endpoint MTU, or negative error
93  */
94 static int efi_usb_mtu ( struct efi_usb_interface *usbintf,
95  unsigned int endpoint ) {
96  struct efi_usb_device *usbdev = usbintf->usbdev;
98  struct usb_endpoint_descriptor *desc;
99 
100  /* Locate cached interface descriptor */
101  interface = usb_interface_descriptor ( usbdev->config,
102  usbintf->interface,
103  usbintf->alternate );
104  if ( ! interface ) {
105  DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
106  usbintf->name, usbintf->alternate );
107  return -ENOENT;
108  }
109 
110  /* Locate and copy cached endpoint descriptor */
111  for_each_interface_descriptor ( desc, usbdev->config, interface ) {
112  if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
113  ( desc->endpoint == endpoint ) )
114  return USB_ENDPOINT_MTU ( le16_to_cpu ( desc->sizes ) );
115  }
116 
117  DBGC ( usbdev, "USBDEV %s alt %d ep %02x has no descriptor\n",
118  usbintf->name, usbintf->alternate, endpoint );
119  return -ENOENT;
120 }
121 
122 /**
123  * Check if endpoint is open
124  *
125  * @v usbintf EFI USB interface
126  * @v endpoint Endpoint address
127  * @ret is_open Endpoint is open
128  */
129 static int efi_usb_is_open ( struct efi_usb_interface *usbintf,
130  unsigned int endpoint ) {
131  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
132  struct efi_usb_endpoint *usbep = usbintf->endpoint[index];
133 
134  return ( usbep && usbep->ep.open );
135 }
136 
137 /**
138  * Open endpoint
139  *
140  * @v usbintf EFI USB interface
141  * @v endpoint Endpoint address
142  * @v attributes Endpoint attributes
143  * @v interval Interval (in milliseconds)
144  * @v driver Driver operations
145  * @ret rc Return status code
146  */
148  unsigned int endpoint, unsigned int attributes,
149  unsigned int interval,
150  struct usb_endpoint_driver_operations *driver ) {
152  struct efi_usb_device *usbdev = usbintf->usbdev;
153  struct efi_usb_endpoint *usbep;
154  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
155  int mtu;
156  EFI_STATUS efirc;
157  int rc;
158 
159  /* Allocate structure, if needed. Once allocated, we leave
160  * the endpoint structure in place until the device is
161  * removed, to work around external UEFI code that closes the
162  * endpoint at illegal times.
163  */
164  usbep = usbintf->endpoint[index];
165  if ( ! usbep ) {
166  usbep = zalloc ( sizeof ( *usbep ) );
167  if ( ! usbep ) {
168  rc = -ENOMEM;
169  goto err_alloc;
170  }
171  usbep->usbintf = usbintf;
172  usbintf->endpoint[index] = usbep;
173  }
174 
175  /* Get endpoint MTU */
176  mtu = efi_usb_mtu ( usbintf, endpoint );
177  if ( mtu < 0 ) {
178  rc = mtu;
179  goto err_mtu;
180  }
181 
182  /* Allocate and initialise structure */
183  usb_endpoint_init ( &usbep->ep, usbdev->func->usb, driver );
184  usb_endpoint_describe ( &usbep->ep, endpoint, attributes, mtu, 0,
185  ( interval << 3 /* microframes */ ) );
186 
187  /* Open endpoint */
188  if ( ( rc = usb_endpoint_open ( &usbep->ep ) ) != 0 ) {
189  DBGC ( usbdev, "USBDEV %s %s could not open: %s\n",
190  usbintf->name, usb_endpoint_name ( &usbep->ep ),
191  strerror ( rc ) );
192  goto err_open;
193  }
194  DBGC ( usbdev, "USBDEV %s %s opened\n",
195  usbintf->name, usb_endpoint_name ( &usbep->ep ) );
196 
197  /* Create event */
198  if ( ( efirc = bs->CreateEvent ( ( EVT_TIMER | EVT_NOTIFY_SIGNAL ),
199  TPL_CALLBACK, efi_usb_timer, usbep,
200  &usbep->event ) ) != 0 ) {
201  rc = -EEFI ( efirc );
202  DBGC ( usbdev, "USBDEV %s %s could not create event: %s\n",
203  usbintf->name, usb_endpoint_name ( &usbep->ep ),
204  strerror ( rc ) );
205  goto err_event;
206  }
207 
208  return 0;
209 
210  bs->CloseEvent ( usbep->event );
211  err_event:
212  usb_endpoint_close ( &usbep->ep );
213  err_open:
214  err_mtu:
215  err_alloc:
216  return rc;
217 }
218 
219 /**
220  * Close endpoint
221  *
222  * @v usbep EFI USB endpoint
223  */
224 static void efi_usb_close ( struct efi_usb_endpoint *usbep ) {
226  struct efi_usb_interface *usbintf = usbep->usbintf;
227  struct efi_usb_device *usbdev = usbintf->usbdev;
228  unsigned int index = USB_ENDPOINT_IDX ( usbep->ep.address );
229 
230  /* Sanity check */
231  assert ( usbintf->endpoint[index] == usbep );
232 
233  /* Cancel timer (if applicable) and close event */
234  bs->SetTimer ( usbep->event, TimerCancel, 0 );
235  bs->CloseEvent ( usbep->event );
236 
237  /* Close endpoint */
238  usb_endpoint_close ( &usbep->ep );
239  DBGC ( usbdev, "USBDEV %s %s closed\n",
240  usbintf->name, usb_endpoint_name ( &usbep->ep ) );
241 }
242 
243 /**
244  * Close all endpoints
245  *
246  * @v usbintf EFI USB interface
247  */
248 static void efi_usb_close_all ( struct efi_usb_interface *usbintf ) {
249  struct efi_usb_endpoint *usbep;
250  unsigned int i;
251 
252  for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
253  sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
254  usbep = usbintf->endpoint[i];
255  if ( usbep && usbep->ep.open )
256  efi_usb_close ( usbep );
257  }
258 }
259 
260 /**
261  * Free all endpoints
262  *
263  * @v usbintf EFI USB interface
264  */
265 static void efi_usb_free_all ( struct efi_usb_interface *usbintf ) {
266  struct efi_usb_endpoint *usbep;
267  unsigned int i;
268 
269  for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
270  sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
271  usbep = usbintf->endpoint[i];
272  if ( usbep ) {
273  assert ( ! usbep->ep.open );
274  free ( usbep );
275  usbintf->endpoint[i] = NULL;
276  }
277  }
278 }
279 
280 /**
281  * Complete synchronous transfer
282  *
283  * @v ep USB endpoint
284  * @v iobuf I/O buffer
285  * @v rc Completion status code
286  */
287 static void efi_usb_sync_complete ( struct usb_endpoint *ep,
288  struct io_buffer *iobuf __unused, int rc ) {
289  struct efi_usb_endpoint *usbep =
290  container_of ( ep, struct efi_usb_endpoint, ep );
291 
292  /* Record completion status */
293  usbep->rc = rc;
294 }
295 
296 /** Synchronous endpoint operations */
299 };
300 
301 /**
302  * Perform synchronous transfer
303  *
304  * @v usbintf USB endpoint
305  * @v endpoint Endpoint address
306  * @v attributes Endpoint attributes
307  * @v timeout Timeout (in milliseconds)
308  * @v data Data buffer
309  * @v len Length of data buffer
310  * @ret rc Return status code
311  */
312 static int efi_usb_sync_transfer ( struct efi_usb_interface *usbintf,
313  unsigned int endpoint,
314  unsigned int attributes,
315  unsigned int timeout,
316  void *data, size_t *len ) {
317  struct efi_usb_device *usbdev = usbintf->usbdev;
318  struct efi_usb_endpoint *usbep;
319  struct io_buffer *iobuf;
320  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
321  unsigned int i;
322  int rc;
323 
324  /* Open endpoint, if applicable */
325  if ( ( ! efi_usb_is_open ( usbintf, endpoint ) ) &&
326  ( ( rc = efi_usb_open ( usbintf, endpoint, attributes, 0,
327  &efi_usb_sync_driver ) ) != 0 ) ) {
328  goto err_open;
329  }
330  usbep = usbintf->endpoint[index];
331 
332  /* Allocate and construct I/O buffer */
333  iobuf = alloc_iob ( *len );
334  if ( ! iobuf ) {
335  rc = -ENOMEM;
336  goto err_alloc;
337  }
338  iob_put ( iobuf, *len );
339  if ( ! ( endpoint & USB_ENDPOINT_IN ) )
340  memcpy ( iobuf->data, data, *len );
341 
342  /* Initialise completion status */
343  usbep->rc = -EINPROGRESS;
344 
345  /* Enqueue transfer */
346  if ( ( rc = usb_stream ( &usbep->ep, iobuf, 0 ) ) != 0 ) {
347  DBGC ( usbdev, "USBDEV %s %s could not enqueue: %s\n",
348  usbintf->name, usb_endpoint_name ( &usbep->ep ),
349  strerror ( rc ) );
350  goto err_stream;
351  }
352 
353  /* Wait for completion */
354  rc = -ETIMEDOUT;
355  for ( i = 0 ; ( ( timeout == 0 ) || ( i < timeout ) ) ; i++ ) {
356 
357  /* Poll bus */
358  usb_poll ( usbdev->func->usb->port->hub->bus );
359 
360  /* Check for completion */
361  if ( usbep->rc != -EINPROGRESS ) {
362  rc = usbep->rc;
363  break;
364  }
365 
366  /* Delay */
367  mdelay ( 1 );
368  }
369 
370  /* Check for errors */
371  if ( rc != 0 ) {
372  DBGC ( usbdev, "USBDEV %s %s failed: %s\n", usbintf->name,
373  usb_endpoint_name ( &usbep->ep ), strerror ( rc ) );
374  goto err_completion;
375  }
376 
377  /* Copy completion to data buffer, if applicable */
378  assert ( iob_len ( iobuf ) <= *len );
379  if ( endpoint & USB_ENDPOINT_IN )
380  memcpy ( data, iobuf->data, iob_len ( iobuf ) );
381  *len = iob_len ( iobuf );
382 
383  /* Free I/O buffer */
384  free_iob ( iobuf );
385 
386  /* Leave endpoint open */
387  return 0;
388 
389  err_completion:
390  err_stream:
391  free_iob ( iobuf );
392  err_alloc:
393  efi_usb_close ( usbep );
394  err_open:
395  return EFIRC ( rc );
396 }
397 
398 /**
399  * Complete asynchronous transfer
400  *
401  * @v ep USB endpoint
402  * @v iobuf I/O buffer
403  * @v rc Completion status code
404  */
405 static void efi_usb_async_complete ( struct usb_endpoint *ep,
406  struct io_buffer *iobuf, int rc ) {
407  struct efi_usb_endpoint *usbep =
408  container_of ( ep, struct efi_usb_endpoint, ep );
409  UINT32 status;
410 
411  /* Ignore packets cancelled when the endpoint closes */
412  if ( ! ep->open )
413  goto drop;
414 
415  /* Construct status */
416  status = ( ( rc == 0 ) ? 0 : EFI_USB_ERR_SYSTEM );
417 
418  /* Report completion, if applicable */
419  if ( usbep->callback ) {
420  usbep->callback ( iobuf->data, iob_len ( iobuf ),
421  usbep->context, status );
422  }
423 
424  drop:
425  /* Recycle or free I/O buffer */
426  if ( usbep->ep.open ) {
427  usb_recycle ( &usbep->ep, iobuf );
428  } else {
429  free_iob ( iobuf );
430  }
431 }
432 
433 /** Asynchronous endpoint operations */
436 };
437 
438 /**
439  * Start asynchronous transfer
440  *
441  * @v usbintf EFI USB interface
442  * @v endpoint Endpoint address
443  * @v interval Interval (in milliseconds)
444  * @v len Transfer length
445  * @v callback Callback function
446  * @v context Context for callback function
447  * @ret rc Return status code
448  */
449 static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
450  unsigned int endpoint, unsigned int interval,
451  size_t len,
453  void *context ) {
455  struct efi_usb_device *usbdev = usbintf->usbdev;
456  struct efi_usb_endpoint *usbep;
457  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
458  EFI_STATUS efirc;
459  int rc;
460 
461  /* Close endpoint, if applicable */
462  if ( efi_usb_is_open ( usbintf, endpoint ) )
464 
465  /* Open endpoint */
466  if ( ( rc = efi_usb_open ( usbintf, endpoint,
467  USB_ENDPOINT_ATTR_INTERRUPT, interval,
468  &efi_usb_async_driver ) ) != 0 )
469  goto err_open;
470  usbep = usbintf->endpoint[index];
471 
472  /* Record callback parameters */
473  usbep->callback = callback;
474  usbep->context = context;
475 
476  /* Prefill endpoint */
477  usb_refill_init ( &usbep->ep, 0, len, EFI_USB_ASYNC_FILL );
478  if ( ( rc = usb_prefill ( &usbep->ep ) ) != 0 ) {
479  DBGC ( usbdev, "USBDEV %s %s could not prefill: %s\n",
480  usbintf->name, usb_endpoint_name ( &usbep->ep ),
481  strerror ( rc ) );
482  goto err_prefill;
483  }
484 
485  /* Start timer */
486  if ( ( efirc = bs->SetTimer ( usbep->event, TimerPeriodic,
487  ( interval * 10000 ) ) ) != 0 ) {
488  rc = -EEFI ( efirc );
489  DBGC ( usbdev, "USBDEV %s %s could not set timer: %s\n",
490  usbintf->name, usb_endpoint_name ( &usbep->ep ),
491  strerror ( rc ) );
492  goto err_timer;
493  }
494 
495  return 0;
496 
497  bs->SetTimer ( usbep->event, TimerCancel, 0 );
498  err_timer:
499  err_prefill:
500  usbep->callback = NULL;
501  usbep->context = NULL;
502  efi_usb_close ( usbep );
503  err_open:
504  return rc;
505 }
506 
507 /**
508  * Stop asynchronous transfer
509  *
510  * @v usbintf EFI USB interface
511  * @v endpoint Endpoint address
512  */
514  unsigned int endpoint ) {
516  struct efi_usb_endpoint *usbep;
517  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
518 
519  /* Do nothing if endpoint is already closed */
520  if ( ! efi_usb_is_open ( usbintf, endpoint ) )
521  return;
522  usbep = usbintf->endpoint[index];
523 
524  /* Stop timer */
525  bs->SetTimer ( usbep->event, TimerCancel, 0 );
526 
527  /* Clear callback parameters */
528  usbep->callback = NULL;
529  usbep->context = NULL;
530 }
531 
532 /******************************************************************************
533  *
534  * USB I/O protocol
535  *
536  ******************************************************************************
537  */
538 
539 /**
540  * Perform control transfer
541  *
542  * @v usbio USB I/O protocol
543  * @v packet Setup packet
544  * @v direction Data direction
545  * @v timeout Timeout (in milliseconds)
546  * @v data Data buffer
547  * @v len Length of data
548  * @ret status Transfer status
549  * @ret efirc EFI status code
550  */
551 static EFI_STATUS EFIAPI
553  EFI_USB_DEVICE_REQUEST *packet,
556  UINT32 *status ) {
557  struct efi_usb_interface *usbintf =
559  struct efi_usb_device *usbdev = usbintf->usbdev;
560  unsigned int request = ( packet->RequestType |
561  USB_REQUEST_TYPE ( packet->Request ) );
562  unsigned int value = le16_to_cpu ( packet->Value );
563  unsigned int index = le16_to_cpu ( packet->Index );
564  struct efi_saved_tpl tpl;
565  int rc;
566 
567  DBGC2 ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %s %dms "
568  "%p+%zx\n", usbintf->name, request, value, index,
569  le16_to_cpu ( packet->Length ),
571  ( ( size_t ) len ) );
572 
573  /* Raise TPL */
574  efi_raise_tpl ( &tpl );
575 
576  /* Clear status */
577  *status = 0;
578 
579  /* Block attempts to change the device configuration, since
580  * this is logically impossible to do given the constraints of
581  * the EFI_USB_IO_PROTOCOL design.
582  */
583  if ( ( request == USB_SET_CONFIGURATION ) &&
584  ( value != usbdev->config->config ) ) {
585  DBGC ( usbdev, "USBDEV %s cannot set configuration %d: not "
586  "logically possible\n", usbintf->name, index );
587  rc = -ENOTSUP;
588  goto err_change_config;
589  }
590 
591  /* If we are selecting a new alternate setting then close all
592  * open endpoints.
593  */
594  if ( ( request == USB_SET_INTERFACE ) &&
595  ( value != usbintf->alternate ) )
596  efi_usb_close_all ( usbintf );
597 
598  /* Issue control transfer */
599  if ( ( rc = usb_control ( usbdev->func->usb, request, value, index,
600  data, len ) ) != 0 ) {
601  DBGC ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %p+%zx "
602  "failed: %s\n", usbintf->name, request, value, index,
603  le16_to_cpu ( packet->Length ), data, ( ( size_t ) len ),
604  strerror ( rc ) );
606  goto err_control;
607  }
608 
609  /* Update alternate setting, if applicable */
610  if ( request == USB_SET_INTERFACE ) {
611  usbintf->alternate = value;
612  DBGC ( usbdev, "USBDEV %s alt %d selected\n",
613  usbintf->name, usbintf->alternate );
614  }
615 
616  err_control:
617  err_change_config:
618  efi_restore_tpl ( &tpl );
619  return EFIRC ( rc );
620 }
621 
622 /**
623  * Perform bulk transfer
624  *
625  * @v usbio USB I/O protocol
626  * @v endpoint Endpoint address
627  * @v data Data buffer
628  * @v len Length of data
629  * @v timeout Timeout (in milliseconds)
630  * @ret status Transfer status
631  * @ret efirc EFI status code
632  */
633 static EFI_STATUS EFIAPI
636  struct efi_usb_interface *usbintf =
638  struct efi_usb_device *usbdev = usbintf->usbdev;
639  size_t actual = *len;
640  struct efi_saved_tpl tpl;
641  int rc;
642 
643  DBGC2 ( usbdev, "USBDEV %s bulk %s %p+%zx %dms\n", usbintf->name,
644  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
645  ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
646 
647  /* Raise TPL */
648  efi_raise_tpl ( &tpl );
649 
650  /* Clear status */
651  *status = 0;
652 
653  /* Perform synchronous transfer */
654  if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
656  data, &actual ) ) != 0 ) {
657  /* Assume that any error represents a timeout */
659  goto err_transfer;
660  }
661 
662  err_transfer:
663  efi_restore_tpl ( &tpl );
664  return EFIRC ( rc );
665 }
666 
667 /**
668  * Perform synchronous interrupt transfer
669  *
670  * @v usbio USB I/O protocol
671  * @v endpoint Endpoint address
672  * @v data Data buffer
673  * @v len Length of data
674  * @v timeout Timeout (in milliseconds)
675  * @ret status Transfer status
676  * @ret efirc EFI status code
677  */
678 static EFI_STATUS EFIAPI
681  UINT32 *status ) {
682  struct efi_usb_interface *usbintf =
684  struct efi_usb_device *usbdev = usbintf->usbdev;
685  size_t actual = *len;
686  struct efi_saved_tpl tpl;
687  int rc;
688 
689  DBGC2 ( usbdev, "USBDEV %s sync intr %s %p+%zx %dms\n", usbintf->name,
690  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
691  ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
692 
693  /* Raise TPL */
694  efi_raise_tpl ( &tpl );
695 
696  /* Clear status */
697  *status = 0;
698 
699  /* Perform synchronous transfer */
700  if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
702  timeout, data, &actual ) ) != 0 ) {
703  /* Assume that any error represents a timeout */
705  goto err_transfer;
706  }
707 
708  err_transfer:
709  efi_restore_tpl ( &tpl );
710  return EFIRC ( rc );
711 }
712 
713 /**
714  * Perform asynchronous interrupt transfer
715  *
716  * @v usbio USB I/O protocol
717  * @v endpoint Endpoint address
718  * @v start Start (rather than stop) transfer
719  * @v interval Polling interval (in milliseconds)
720  * @v len Data length
721  * @v callback Callback function
722  * @v context Context for callback function
723  * @ret efirc EFI status code
724  */
725 static EFI_STATUS EFIAPI
727  BOOLEAN start, UINTN interval, UINTN len,
729  VOID *context ) {
730  struct efi_usb_interface *usbintf =
732  struct efi_usb_device *usbdev = usbintf->usbdev;
733  struct efi_saved_tpl tpl;
734  int rc;
735 
736  DBGC2 ( usbdev, "USBDEV %s async intr %s len %#zx int %d %p/%p\n",
737  usbintf->name,
738  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ),
739  ( ( size_t ) len ), ( ( unsigned int ) interval ),
740  callback, context );
741 
742  /* Raise TPL */
743  efi_raise_tpl ( &tpl );
744 
745  /* Start/stop transfer as applicable */
746  if ( start ) {
747 
748  /* Start new transfer */
749  if ( ( rc = efi_usb_async_start ( usbintf, endpoint, interval,
750  len, callback,
751  context ) ) != 0 )
752  goto err_start;
753 
754  } else {
755 
756  /* Stop transfer */
757  efi_usb_async_stop ( usbintf, endpoint );
758 
759  /* Success */
760  rc = 0;
761 
762  }
763 
764  err_start:
765  efi_restore_tpl ( &tpl );
766  return EFIRC ( rc );
767 }
768 
769 /**
770  * Perform synchronous isochronous transfer
771  *
772  * @v usbio USB I/O protocol
773  * @v endpoint Endpoint address
774  * @v data Data buffer
775  * @v len Length of data
776  * @ret status Transfer status
777  * @ret efirc EFI status code
778  */
779 static EFI_STATUS EFIAPI
781  VOID *data, UINTN len, UINT32 *status ) {
782  struct efi_usb_interface *usbintf =
784  struct efi_usb_device *usbdev = usbintf->usbdev;
785 
786  DBGC2 ( usbdev, "USBDEV %s sync iso %s %p+%zx\n", usbintf->name,
787  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
788  ( ( size_t ) len ) );
789 
790  /* Clear status */
791  *status = 0;
792 
793  /* Not supported */
794  return EFI_UNSUPPORTED;
795 }
796 
797 /**
798  * Perform asynchronous isochronous transfers
799  *
800  * @v usbio USB I/O protocol
801  * @v endpoint Endpoint address
802  * @v data Data buffer
803  * @v len Length of data
804  * @v callback Callback function
805  * @v context Context for callback function
806  * @ret status Transfer status
807  * @ret efirc EFI status code
808  */
809 static EFI_STATUS EFIAPI
811  VOID *data, UINTN len,
813  VOID *context ) {
814  struct efi_usb_interface *usbintf =
816  struct efi_usb_device *usbdev = usbintf->usbdev;
817 
818  DBGC2 ( usbdev, "USBDEV %s async iso %s %p+%zx %p/%p\n", usbintf->name,
819  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
820  ( ( size_t ) len ), callback, context );
821 
822  /* Not supported */
823  return EFI_UNSUPPORTED;
824 }
825 
826 /**
827  * Get device descriptor
828  *
829  * @v usbio USB I/O protocol
830  * @ret efidesc EFI device descriptor
831  * @ret efirc EFI status code
832  */
833 static EFI_STATUS EFIAPI
835  EFI_USB_DEVICE_DESCRIPTOR *efidesc ) {
836  struct efi_usb_interface *usbintf =
838  struct efi_usb_device *usbdev = usbintf->usbdev;
839 
840  DBGC2 ( usbdev, "USBDEV %s get device descriptor\n", usbintf->name );
841 
842  /* Copy cached device descriptor */
843  memcpy ( efidesc, &usbdev->func->usb->device, sizeof ( *efidesc ) );
844 
845  return 0;
846 }
847 
848 /**
849  * Get configuration descriptor
850  *
851  * @v usbio USB I/O protocol
852  * @ret efidesc EFI interface descriptor
853  * @ret efirc EFI status code
854  */
855 static EFI_STATUS EFIAPI
857  EFI_USB_CONFIG_DESCRIPTOR *efidesc ) {
858  struct efi_usb_interface *usbintf =
860  struct efi_usb_device *usbdev = usbintf->usbdev;
861 
862  DBGC2 ( usbdev, "USBDEV %s get configuration descriptor\n",
863  usbintf->name );
864 
865  /* Copy cached configuration descriptor */
866  memcpy ( efidesc, usbdev->config, sizeof ( *efidesc ) );
867 
868  return 0;
869 }
870 
871 /**
872  * Get interface descriptor
873  *
874  * @v usbio USB I/O protocol
875  * @ret efidesc EFI interface descriptor
876  * @ret efirc EFI status code
877  */
878 static EFI_STATUS EFIAPI
880  EFI_USB_INTERFACE_DESCRIPTOR *efidesc ) {
881  struct efi_usb_interface *usbintf =
883  struct efi_usb_device *usbdev = usbintf->usbdev;
884  struct usb_interface_descriptor *desc;
885 
886  DBGC2 ( usbdev, "USBDEV %s get interface descriptor\n", usbintf->name );
887 
888  /* Locate cached interface descriptor */
889  desc = usb_interface_descriptor ( usbdev->config, usbintf->interface,
890  usbintf->alternate );
891  if ( ! desc ) {
892  DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
893  usbintf->name, usbintf->alternate );
894  return -ENOENT;
895  }
896 
897  /* Copy cached interface descriptor */
898  memcpy ( efidesc, desc, sizeof ( *efidesc ) );
899 
900  return 0;
901 }
902 
903 /**
904  * Get endpoint descriptor
905  *
906  * @v usbio USB I/O protocol
907  * @v address Endpoint index
908  * @ret efidesc EFI interface descriptor
909  * @ret efirc EFI status code
910  */
911 static EFI_STATUS EFIAPI
913  EFI_USB_ENDPOINT_DESCRIPTOR *efidesc ) {
914  struct efi_usb_interface *usbintf =
916  struct efi_usb_device *usbdev = usbintf->usbdev;
918  struct usb_endpoint_descriptor *desc;
919 
920  DBGC2 ( usbdev, "USBDEV %s get endpoint %d descriptor\n",
921  usbintf->name, index );
922 
923  /* Locate cached interface descriptor */
924  interface = usb_interface_descriptor ( usbdev->config,
925  usbintf->interface,
926  usbintf->alternate );
927  if ( ! interface ) {
928  DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
929  usbintf->name, usbintf->alternate );
930  return -ENOENT;
931  }
932 
933  /* Locate and copy cached endpoint descriptor */
934  for_each_interface_descriptor ( desc, usbdev->config, interface ) {
935  if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
936  ( index-- == 0 ) ) {
937  memcpy ( efidesc, desc, sizeof ( *efidesc ) );
938  return 0;
939  }
940  }
941  return -ENOENT;
942 }
943 
944 /**
945  * Get string descriptor
946  *
947  * @v usbio USB I/O protocol
948  * @v language Language ID
949  * @v index String index
950  * @ret string String
951  * @ret efirc EFI status code
952  */
953 static EFI_STATUS EFIAPI
955  UINT8 index, CHAR16 **string ) {
957  struct efi_usb_interface *usbintf =
959  struct efi_usb_device *usbdev = usbintf->usbdev;
961  struct efi_saved_tpl tpl;
962  VOID *buffer;
963  size_t len;
964  EFI_STATUS efirc;
965  int rc;
966 
967  DBGC2 ( usbdev, "USBDEV %s get string %d:%d descriptor\n",
968  usbintf->name, language, index );
969 
970  /* Raise TPL */
971  efi_raise_tpl ( &tpl );
972 
973  /* Read descriptor header */
974  if ( ( rc = usb_get_descriptor ( usbdev->func->usb, 0,
976  language, &header,
977  sizeof ( header ) ) ) != 0 ) {
978  DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
979  "descriptor header: %s\n", usbintf->name, language,
980  index, strerror ( rc ) );
981  goto err_get_header;
982  }
983  len = header.len;
984  if ( len < sizeof ( header ) ) {
985  DBGC ( usbdev, "USBDEV %s underlength string %d:%d\n",
986  usbintf->name, language, index );
987  rc = -EINVAL;
988  goto err_len;
989  }
990 
991  /* Allocate buffer */
992  if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
993  &buffer ) ) != 0 ) {
994  rc = -EEFI ( efirc );
995  goto err_alloc;
996  }
997 
998  /* Read whole descriptor */
999  if ( ( rc = usb_get_descriptor ( usbdev->func->usb, 0,
1001  language, buffer, len ) ) != 0 ) {
1002  DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
1003  "descriptor: %s\n", usbintf->name, language,
1004  index, strerror ( rc ) );
1005  goto err_get_descriptor;
1006  }
1007 
1008  /* Shuffle down and terminate string */
1009  memmove ( buffer, ( buffer + sizeof ( header ) ),
1010  ( len - sizeof ( header ) ) );
1011  memset ( ( buffer + len - sizeof ( header ) ), 0, sizeof ( **string ) );
1012 
1013  /* Restore TPL */
1014  efi_restore_tpl ( &tpl );
1015 
1016  /* Return allocated string */
1017  *string = buffer;
1018  return 0;
1019 
1020  err_get_descriptor:
1021  bs->FreePool ( buffer );
1022  err_alloc:
1023  err_len:
1024  err_get_header:
1025  efi_restore_tpl ( &tpl );
1026  return EFIRC ( rc );
1027 }
1028 
1029 /**
1030  * Get supported languages
1031  *
1032  * @v usbio USB I/O protocol
1033  * @ret languages Language ID table
1034  * @ret len Length of language ID table
1035  * @ret efirc EFI status code
1036  */
1037 static EFI_STATUS EFIAPI
1039  UINT16 **languages, UINT16 *len ) {
1040  struct efi_usb_interface *usbintf =
1042  struct efi_usb_device *usbdev = usbintf->usbdev;
1043 
1044  DBGC2 ( usbdev, "USBDEV %s get supported languages\n", usbintf->name );
1045 
1046  /* Return cached supported languages */
1047  *languages = usbdev->lang;
1048  *len = usbdev->lang_len;
1049 
1050  return 0;
1051 }
1052 
1053 /**
1054  * Reset port
1055  *
1056  * @v usbio USB I/O protocol
1057  * @ret efirc EFI status code
1058  */
1059 static EFI_STATUS EFIAPI
1061  struct efi_usb_interface *usbintf =
1063  struct efi_usb_device *usbdev = usbintf->usbdev;
1064 
1065  DBGC2 ( usbdev, "USBDEV %s reset port\n", usbintf->name );
1066 
1067  /* This is logically impossible to do, since resetting the
1068  * port may destroy state belonging to other
1069  * EFI_USB_IO_PROTOCOL instances belonging to the same USB
1070  * device. (This is yet another artifact of the incredibly
1071  * poor design of the EFI_USB_IO_PROTOCOL.)
1072  */
1073  return EFI_INVALID_PARAMETER;
1074 }
1075 
1076 /** USB I/O protocol */
1079  .UsbBulkTransfer = efi_usb_bulk_transfer,
1080  .UsbAsyncInterruptTransfer = efi_usb_async_interrupt_transfer,
1081  .UsbSyncInterruptTransfer = efi_usb_sync_interrupt_transfer,
1082  .UsbIsochronousTransfer = efi_usb_isochronous_transfer,
1083  .UsbAsyncIsochronousTransfer = efi_usb_async_isochronous_transfer,
1084  .UsbGetDeviceDescriptor = efi_usb_get_device_descriptor,
1085  .UsbGetConfigDescriptor = efi_usb_get_config_descriptor,
1086  .UsbGetInterfaceDescriptor = efi_usb_get_interface_descriptor,
1087  .UsbGetEndpointDescriptor = efi_usb_get_endpoint_descriptor,
1088  .UsbGetStringDescriptor = efi_usb_get_string_descriptor,
1089  .UsbGetSupportedLanguages = efi_usb_get_supported_languages,
1090  .UsbPortReset = efi_usb_port_reset,
1091 };
1092 
1093 /******************************************************************************
1094  *
1095  * USB driver
1096  *
1097  ******************************************************************************
1098  */
1099 
1100 /**
1101  * Install interface
1102  *
1103  * @v usbdev EFI USB device
1104  * @v interface Interface number
1105  * @ret rc Return status code
1106  */
1107 static int efi_usb_install ( struct efi_usb_device *usbdev,
1108  unsigned int interface ) {
1110  struct usb_function *func = usbdev->func;
1111  struct efi_usb_interface *usbintf;
1112  int leak = 0;
1113  EFI_STATUS efirc;
1114  int rc;
1115 
1116  /* Allocate and initialise structure */
1117  usbintf = zalloc ( sizeof ( *usbintf ) );
1118  if ( ! usbintf ) {
1119  rc = -ENOMEM;
1120  goto err_alloc;
1121  }
1122  snprintf ( usbintf->name, sizeof ( usbintf->name ), "%s[%d]",
1123  usbdev->name, interface );
1124  usbintf->usbdev = usbdev;
1125  usbintf->interface = interface;
1126  memcpy ( &usbintf->usbio, &efi_usb_io_protocol,
1127  sizeof ( usbintf->usbio ) );
1128 
1129  /* Construct device path */
1130  usbintf->path = efi_usb_path ( func );
1131  if ( ! usbintf->path ) {
1132  rc = -ENODEV;
1133  goto err_path;
1134  }
1135 
1136  /* Add to list of interfaces */
1137  list_add_tail ( &usbintf->list, &usbdev->interfaces );
1138 
1139  /* Install protocols */
1140  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1141  &usbintf->handle,
1142  &efi_usb_io_protocol_guid, &usbintf->usbio,
1144  NULL ) ) != 0 ) {
1145  rc = -EEFI ( efirc );
1146  DBGC ( usbdev, "USBDEV %s could not install protocols: %s\n",
1147  usbintf->name, strerror ( rc ) );
1148  goto err_install_protocol;
1149  }
1150 
1151  DBGC ( usbdev, "USBDEV %s installed as %s\n",
1152  usbintf->name, efi_handle_name ( usbintf->handle ) );
1153  return 0;
1154 
1155  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1156  usbintf->handle,
1157  &efi_usb_io_protocol_guid, &usbintf->usbio,
1159  NULL ) ) != 0 ) {
1160  DBGC ( usbdev, "USBDEV %s could not uninstall: %s\n",
1161  usbintf->name, strerror ( -EEFI ( efirc ) ) );
1162  leak = 1;
1163  }
1164  efi_nullify_usbio ( &usbintf->usbio );
1165  err_install_protocol:
1166  efi_usb_close_all ( usbintf );
1167  efi_usb_free_all ( usbintf );
1168  list_del ( &usbintf->list );
1169  if ( ! leak )
1170  free ( usbintf->path );
1171  err_path:
1172  if ( ! leak )
1173  free ( usbintf );
1174  err_alloc:
1175  if ( leak ) {
1176  DBGC ( usbdev, "USBDEV %s nullified and leaked\n",
1177  usbintf->name );
1178  }
1179  return rc;
1180 }
1181 
1182 /**
1183  * Uninstall interface
1184  *
1185  * @v usbintf EFI USB interface
1186  */
1187 static void efi_usb_uninstall ( struct efi_usb_interface *usbintf ) {
1189  struct efi_usb_device *usbdev = usbintf->usbdev;
1190  int leak = efi_shutdown_in_progress;
1191  EFI_STATUS efirc;
1192 
1193  DBGC ( usbdev, "USBDEV %s uninstalling %s\n",
1194  usbintf->name, efi_handle_name ( usbintf->handle ) );
1195 
1196  /* Disconnect controllers. This should not be necessary, but
1197  * seems to be required on some platforms to avoid failures
1198  * when uninstalling protocols.
1199  */
1200  if ( ! efi_shutdown_in_progress )
1201  bs->DisconnectController ( usbintf->handle, NULL, NULL );
1202 
1203  /* Uninstall protocols */
1204  if ( ( ! efi_shutdown_in_progress ) &&
1205  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1206  usbintf->handle,
1207  &efi_usb_io_protocol_guid, &usbintf->usbio,
1209  NULL ) ) != 0 ) ) {
1210  DBGC ( usbdev, "USBDEV %s could not uninstall: %s\n",
1211  usbintf->name, strerror ( -EEFI ( efirc ) ) );
1212  leak = 1;
1213  }
1214  efi_nullify_usbio ( &usbintf->usbio );
1215 
1216  /* Close and free all endpoints */
1217  efi_usb_close_all ( usbintf );
1218  efi_usb_free_all ( usbintf );
1219 
1220  /* Remove from list of interfaces */
1221  list_del ( &usbintf->list );
1222 
1223  /* Free device path */
1224  if ( ! leak )
1225  free ( usbintf->path );
1226 
1227  /* Free interface */
1228  if ( ! leak )
1229  free ( usbintf );
1230 
1231  /* Report leakage, if applicable */
1232  if ( leak && ( ! efi_shutdown_in_progress ) ) {
1233  DBGC ( usbdev, "USBDEV %s nullified and leaked\n",
1234  usbintf->name );
1235  }
1236 }
1237 
1238 /**
1239  * Uninstall all interfaces
1240  *
1241  * @v usbdev EFI USB device
1242  */
1243 static void efi_usb_uninstall_all ( struct efi_usb_device *efiusb ) {
1244  struct efi_usb_interface *usbintf;
1245 
1246  /* Uninstall all interfaces */
1247  while ( ( usbintf = list_first_entry ( &efiusb->interfaces,
1248  struct efi_usb_interface,
1249  list ) ) ) {
1250  efi_usb_uninstall ( usbintf );
1251  }
1252 }
1253 
1254 /**
1255  * Probe device
1256  *
1257  * @v func USB function
1258  * @v config Configuration descriptor
1259  * @ret rc Return status code
1260  */
1261 static int efi_usb_probe ( struct usb_function *func,
1262  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  bs->ConnectController ( usbintf->handle, NULL, NULL, TRUE );
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:25
UINT8 Request
Definition: Usb.h:101
A USB driver.
Definition: usb.h:1381
static void efi_usb_async_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete asynchronous transfer.
Definition: efi_usb.c:405
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
#define EINVAL
Invalid argument.
Definition: errno.h:428
static EFI_USB_IO_PROTOCOL efi_usb_io_protocol
USB I/O protocol.
Definition: efi_usb.c:1077
static void efi_usb_close(struct efi_usb_endpoint *usbep)
Close endpoint.
Definition: efi_usb.c:224
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EFI_USB_ASYNC_FILL
Asynchronous transfer fill level.
Definition: efi_usb.h:78
A USB device ID.
Definition: usb.h:1335
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:879
#define iob_put(iobuf, len)
Definition: iobuf.h:120
size_t lang_len
Length of supported languages.
Definition: efi_usb.h:27
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:481
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
unsigned int alternate
Alternate setting.
Definition: efi_usb.h:44
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:703
An event is to be signaled periodically at a specified interval from the current time.
Definition: UefiSpec.h:489
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:856
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:543
EFI driver interface.
uint8_t interface[0]
List of interface numbers.
Definition: usb.h:682
static void efi_usb_close_all(struct efi_usb_interface *usbintf)
Close all endpoints.
Definition: efi_usb.c:248
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:679
static EFI_STATUS EFIAPI efi_usb_port_reset(EFI_USB_IO_PROTOCOL *usbio)
Reset port.
Definition: efi_usb.c:1060
const char * name
Name.
Definition: usb.h:661
char name[32]
Name.
Definition: efi_usb.h:35
struct usb_function * func
The underlying USB function.
Definition: efi_usb.h:21
const char * name
Name.
Definition: usb.h:1337
static struct usb_endpoint_driver_operations efi_usb_sync_driver
Synchronous endpoint operations.
Definition: efi_usb.c:297
unsigned int count
Number of interfaces.
Definition: usb.h:650
#define USB_STRING_DESCRIPTOR
A USB string descriptor.
Definition: usb.h:224
Error codes.
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to TPL_CALLBACK.
Definition: efi_init.c:373
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
VOID * EFI_EVENT
Handle to an event structure.
Definition: UefiBaseType.h:43
static void efi_usb_async_stop(struct efi_usb_interface *usbintf, unsigned int endpoint)
Stop asynchronous transfer.
Definition: efi_usb.c:513
unsigned char BOOLEAN
Definition: ProcessorBind.h:61
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:552
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:810
const char * name
Name.
Definition: efi_usb.h:19
static VOID EFIAPI efi_usb_timer(EFI_EVENT event __unused, VOID *context)
Poll USB bus (from endpoint event timer)
Definition: efi_usb.c:74
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition: efi_usb.h:50
#define DBGC(...)
Definition: compiler.h:505
static struct usb_endpoint_driver_operations efi_usb_async_driver
Asynchronous endpoint operations.
Definition: efi_usb.c:434
USB I/O protocol.
#define ENOENT
No such file or directory.
Definition: errno.h:514
Standard Interface Descriptor USB 2.0 spec, Section 9.6.5.
Definition: Usb.h:147
unsigned int UINT32
Definition: ProcessorBind.h:56
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:954
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition: usb.c:545
The EFI_USB_IO_PROTOCOL provides four basic transfers types described in the USB 1....
Definition: UsbIo.h:485
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1915
int usb_prefill(struct usb_endpoint *ep)
Prefill endpoint recycled buffer list.
Definition: usb.c:619
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
Definition: usb.c:293
#define for_each_interface_descriptor(desc, config, interface)
Iterate over all configuration descriptors within an interface descriptor.
Definition: usb.h:379
unsigned short CHAR16
Definition: ProcessorBind.h:59
EFI_CLOSE_EVENT CloseEvent
Definition: UefiSpec.h:1864
EFI_SET_TIMER SetTimer
Definition: UefiSpec.h:1861
uint8_t direction
Direction.
Definition: ena.h:14
#define USB_ENDPOINT_ATTR_BULK
Bulk endpoint transfer type.
Definition: usb.h:275
uint8_t endpoint
Endpoint address.
Definition: usb.h:253
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An EFI USB device.
Definition: efi_usb.h:17
EFI_USB_DATA_DIRECTION
USB data transfer direction.
Definition: UsbIo.h:52
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
Definition: usb.c:399
int open
Endpoint is open.
Definition: usb.h:404
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
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:912
unsigned char UINT8
Definition: ProcessorBind.h:62
int usb_refill(struct usb_endpoint *ep)
Refill endpoint.
Definition: usb.c:710
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:783
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:53
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
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:780
#define EFI_USB_ERR_SYSTEM
Definition: UsbIo.h:70
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
uint8_t status
Status.
Definition: ena.h:16
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ENOMEM
Not enough space.
Definition: errno.h:534
A USB endpoint.
Definition: usb.h:389
An EFI USB device interface.
Definition: efi_usb.h:33
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:485
A USB interface descriptor.
Definition: usb.h:230
Format of Setup Data for USB Device Requests USB 2.0 spec, Section 9.3.
Definition: Usb.h:99
struct usb_port * port
USB port.
Definition: usb.h:712
Assertions.
static void usb_recycle(struct usb_endpoint *ep, struct io_buffer *iobuf)
Recycle I/O buffer.
Definition: usb.h:618
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An object interface.
Definition: interface.h:124
static int efi_usb_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: efi_usb.c:1261
void efi_nullify_usbio(EFI_USB_IO_PROTOCOL *usbio)
Nullify USB I/O protocol.
Definition: efi_null.c:669
static const char * efi_usb_direction_name(EFI_USB_DATA_DIRECTION direction)
Transcribe data direction (for debugging)
Definition: efi_usb.c:51
struct ib_cm_path alternate
Alternate path.
Definition: ib_mad.h:42
EFI_EVENT event
Asynchronous timer event.
Definition: efi_usb.h:67
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
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:449
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:602
EFI_CREATE_EVENT CreateEvent
Definition: UefiSpec.h:1860
int rc
Most recent synchronous completion status.
Definition: efi_usb.h:64
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:692
void * context
Asynchronous callback context.
Definition: efi_usb.h:71
struct list_head interfaces
List of interfaces.
Definition: efi_usb.h:29
struct efi_usb_interface * usbintf
EFI USB device interface.
Definition: efi_usb.h:59
EFI_ASYNC_USB_TRANSFER_CALLBACK callback
Asynchronous callback handler.
Definition: efi_usb.h:69
static int efi_usb_is_open(struct efi_usb_interface *usbintf, unsigned int endpoint)
Check if endpoint is open.
Definition: efi_usb.c:129
static void efi_usb_sync_complete(struct usb_endpoint *ep, struct io_buffer *iobuf __unused, int rc)
Complete synchronous transfer.
Definition: efi_usb.c:287
EFI null interfaces.
A USB device.
Definition: usb.h:708
uint8_t type
Descriptor type.
Definition: usb.h:162
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:143
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
UINT8 RequestType
Definition: Usb.h:100
#define EINPROGRESS
Operation in progress.
Definition: errno.h:418
unsigned short UINT16
Definition: ProcessorBind.h:58
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:722
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition: usb.h:1051
#define USB_ENDPOINT_IN
Endpoint direction is in.
Definition: usb.h:510
#define USB_ENDPOINT_ATTR_INTERRUPT
Interrupt endpoint transfer type.
Definition: usb.h:278
unsigned int interface
Interface number.
Definition: efi_usb.h:42
#define USB_SET_INTERFACE
Set interface.
Definition: usb.h:138
static void efi_usb_uninstall(struct efi_usb_interface *usbintf)
Uninstall interface.
Definition: efi_usb.c:1187
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI_GUID efi_usb_io_protocol_guid
USB I/O protocol GUID.
Definition: efi_guid.c:296
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
Definition: efi_path.c:435
#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:147
An EFI USB device endpoint.
Definition: efi_usb.h:57
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1836
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
struct usb_driver usbio_driver __usb_fallback_driver
USB I/O protocol driver.
Definition: efi_usb.c:1360
UINT16 Length
Definition: Usb.h:104
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1363
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
EFI_CONNECT_CONTROLLER ConnectController
Definition: UefiSpec.h:1899
#define TPL_CALLBACK
Definition: UefiSpec.h:591
#define ENODEV
No such device.
Definition: errno.h:509
#define EFI_USB_ERR_TIMEOUT
Definition: UsbIo.h:68
EFI device paths.
struct usb_configuration_descriptor * config
Configuration descriptor.
Definition: efi_usb.h:23
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
#define EVT_NOTIFY_SIGNAL
Definition: UefiSpec.h:394
static void efi_usb_free_all(struct efi_usb_interface *usbintf)
Free all endpoints.
Definition: efi_usb.c:265
uint8_t name
Interface name.
Definition: usb.h:242
static void efi_usb_uninstall_all(struct efi_usb_device *efiusb)
Uninstall all interfaces.
Definition: efi_usb.c:1243
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:312
#define EFI_INVALID_PARAMETER
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:122
struct usb_device_descriptor device
Device descriptor.
Definition: usb.h:720
Standard Endpoint Descriptor USB 2.0 spec, Section 9.6.6.
Definition: Usb.h:163
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:132
struct usb_device * usb
USB device.
Definition: usb.h:663
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:525
#define le16_to_cpu(value)
Definition: byteswap.h:112
#define VOID
Undeclared type.
Definition: Base.h:319
#define USB_ENDPOINT_IDX(address)
Construct endpoint index from endpoint address.
Definition: usb.h:513
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1855
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging)
Definition: usb.c:220
void * memmove(void *dest, const void *src, size_t len) __nonnull
#define TRUE
Definition: tlan.h:46
struct usb_endpoint ep
USB endpoint.
Definition: efi_usb.h:61
EFI_USB_IO_CONTROL_TRANSFER UsbControlTransfer
Definition: UsbIo.h:489
EFI API.
A USB descriptor header.
Definition: usb.h:158
EFI_USB_IO_PROTOCOL usbio
USB I/O protocol.
Definition: efi_usb.h:48
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define USB_REQUEST_TYPE(type)
Construct USB request type.
Definition: usb.h:107
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
A USB configuration descriptor.
Definition: usb.h:195
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:834
A USB endpoint descriptor.
Definition: usb.h:249
uint8_t alternate
Alternate setting.
Definition: usb.h:236
An EFI saved task priority level.
Definition: efi.h:67
struct list_head list
List of interfaces.
Definition: efi_usb.h:39
static int efi_usb_mtu(struct efi_usb_interface *usbintf, unsigned int endpoint)
Get endpoint MTU.
Definition: efi_usb.c:94
uint32_t len
Length.
Definition: ena.h:14
uint8_t config
Configuration value.
Definition: usb.h:203
#define DBGC2(...)
Definition: compiler.h:522
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1347
Universal Serial Bus (USB)
uint32_t mtu
Maximum MTU.
Definition: ena.h:28
void * data
Start of data.
Definition: iobuf.h:48
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
struct usb_hub * hub
USB hub.
Definition: usb.h:800
static int efi_usb_install(struct efi_usb_device *usbdev, unsigned int interface)
Install interface.
Definition: efi_usb.c:1107
EFI_HANDLE handle
EFI handle.
Definition: efi_usb.h:46
struct ena_aq_header header
Header.
Definition: ena.h:12
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:132
struct usb_descriptor_header header
Descriptor header.
Definition: usb.h:251
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
uint16_t len
Total length.
Definition: usb.h:199
struct usb_function_descriptor desc
Function descriptor.
Definition: usb.h:665
void timeout(int)
EFI_SYSTEM_TABLE * efi_systab
#define USB_ENDPOINT_MTU(sizes)
USB endpoint MTU.
Definition: usb.h:293
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
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:1156
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
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:474
A USB function.
Definition: usb.h:659
uint16_t sizes
Maximum packet size and burst size.
Definition: usb.h:257
struct efi_usb_device * usbdev
Containing USB device.
Definition: efi_usb.h:37
struct usb_bus * bus
USB bus.
Definition: usb.h:830
Fallback driver (has no effect on overall score)
Definition: usb.h:1423
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:634
#define USB_SET_CONFIGURATION
Set configuration.
Definition: usb.h:131
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:389
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
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:1038
Standard Device Descriptor USB 2.0 spec, Section 9.6.1.
Definition: Usb.h:111
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
String functions.
UINT16 Value
Definition: Usb.h:102
uint8_t interface
Interface number.
Definition: usb.h:234
unsigned int address
Endpoint address.
Definition: usb.h:393
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:154
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:88
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:726
struct usb_device_id * ids
USB ID table.
Definition: usb.h:1383
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1854
void * memset(void *dest, int character, size_t len) __nonnull
UINT16 Index
Definition: Usb.h:103
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:54
A persistent I/O buffer.
Definition: iobuf.h:33
#define EVT_TIMER
Definition: UefiSpec.h:391
EFI_DISCONNECT_CONTROLLER DisconnectController
Definition: UefiSpec.h:1900