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_usb.h>
36 #include <ipxe/usb.h>
37 
38 /** @file
39  *
40  * EFI USB I/O PROTOCOL
41  *
42  */
43 
44 /**
45  * Transcribe data direction (for debugging)
46  *
47  * @v direction Data direction
48  * @ret text Transcribed data direction
49  */
51 
52  switch ( direction ) {
53  case EfiUsbDataIn: return "in";
54  case EfiUsbDataOut: return "out";
55  case EfiUsbNoData: return "none";
56  default: return "<UNKNOWN>";
57  }
58 }
59 
60 /******************************************************************************
61  *
62  * Endpoints
63  *
64  ******************************************************************************
65  */
66 
67 /**
68  * Poll USB bus (from endpoint event timer)
69  *
70  * @v event EFI event
71  * @v context EFI USB endpoint
72  */
74  VOID *context ) {
75  struct efi_usb_endpoint *usbep = context;
76  struct usb_function *func = usbep->usbintf->usbdev->func;
77 
78  /* Poll bus */
79  usb_poll ( func->usb->port->hub->bus );
80 
81  /* Refill endpoint */
82  if ( usbep->ep.open )
83  usb_refill ( &usbep->ep );
84 }
85 
86 /**
87  * Get endpoint MTU
88  *
89  * @v usbintf EFI USB interface
90  * @v endpoint Endpoint address
91  * @ret mtu Endpoint MTU, or negative error
92  */
93 static int efi_usb_mtu ( struct efi_usb_interface *usbintf,
94  unsigned int endpoint ) {
95  struct efi_usb_device *usbdev = usbintf->usbdev;
97  struct usb_endpoint_descriptor *desc;
98 
99  /* Locate cached interface descriptor */
100  interface = usb_interface_descriptor ( usbdev->config,
101  usbintf->interface,
102  usbintf->alternate );
103  if ( ! interface ) {
104  DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
105  usbintf->name, usbintf->alternate );
106  return -ENOENT;
107  }
108 
109  /* Locate and copy cached endpoint descriptor */
110  for_each_interface_descriptor ( desc, usbdev->config, interface ) {
111  if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
112  ( desc->endpoint == endpoint ) )
113  return USB_ENDPOINT_MTU ( le16_to_cpu ( desc->sizes ) );
114  }
115 
116  DBGC ( usbdev, "USBDEV %s alt %d ep %02x has no descriptor\n",
117  usbintf->name, usbintf->alternate, endpoint );
118  return -ENOENT;
119 }
120 
121 /**
122  * Check if endpoint is open
123  *
124  * @v usbintf EFI USB interface
125  * @v endpoint Endpoint address
126  * @ret is_open Endpoint is open
127  */
128 static int efi_usb_is_open ( struct efi_usb_interface *usbintf,
129  unsigned int endpoint ) {
130  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
131  struct efi_usb_endpoint *usbep = usbintf->endpoint[index];
132 
133  return ( usbep && usbep->ep.open );
134 }
135 
136 /**
137  * Open endpoint
138  *
139  * @v usbintf EFI USB interface
140  * @v endpoint Endpoint address
141  * @v attributes Endpoint attributes
142  * @v interval Interval (in milliseconds)
143  * @v driver Driver operations
144  * @ret rc Return status code
145  */
147  unsigned int endpoint, unsigned int attributes,
148  unsigned int interval,
149  struct usb_endpoint_driver_operations *driver ) {
151  struct efi_usb_device *usbdev = usbintf->usbdev;
152  struct efi_usb_endpoint *usbep;
153  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
154  int mtu;
155  EFI_STATUS efirc;
156  int rc;
157 
158  /* Allocate structure, if needed. Once allocated, we leave
159  * the endpoint structure in place until the device is
160  * removed, to work around external UEFI code that closes the
161  * endpoint at illegal times.
162  */
163  usbep = usbintf->endpoint[index];
164  if ( ! usbep ) {
165  usbep = zalloc ( sizeof ( *usbep ) );
166  if ( ! usbep ) {
167  rc = -ENOMEM;
168  goto err_alloc;
169  }
170  usbep->usbintf = usbintf;
171  usbintf->endpoint[index] = usbep;
172  }
173 
174  /* Get endpoint MTU */
175  mtu = efi_usb_mtu ( usbintf, endpoint );
176  if ( mtu < 0 ) {
177  rc = mtu;
178  goto err_mtu;
179  }
180 
181  /* Allocate and initialise structure */
182  usb_endpoint_init ( &usbep->ep, usbdev->func->usb, driver );
183  usb_endpoint_describe ( &usbep->ep, endpoint, attributes, mtu, 0,
184  ( interval << 3 /* microframes */ ) );
185 
186  /* Open endpoint */
187  if ( ( rc = usb_endpoint_open ( &usbep->ep ) ) != 0 ) {
188  DBGC ( usbdev, "USBDEV %s %s could not open: %s\n",
189  usbintf->name, usb_endpoint_name ( &usbep->ep ),
190  strerror ( rc ) );
191  goto err_open;
192  }
193  DBGC ( usbdev, "USBDEV %s %s opened\n",
194  usbintf->name, usb_endpoint_name ( &usbep->ep ) );
195 
196  /* Create event */
197  if ( ( efirc = bs->CreateEvent ( ( EVT_TIMER | EVT_NOTIFY_SIGNAL ),
198  TPL_CALLBACK, efi_usb_timer, usbep,
199  &usbep->event ) ) != 0 ) {
200  rc = -EEFI ( efirc );
201  DBGC ( usbdev, "USBDEV %s %s could not create event: %s\n",
202  usbintf->name, usb_endpoint_name ( &usbep->ep ),
203  strerror ( rc ) );
204  goto err_event;
205  }
206 
207  return 0;
208 
209  bs->CloseEvent ( usbep->event );
210  err_event:
211  usb_endpoint_close ( &usbep->ep );
212  err_open:
213  err_mtu:
214  err_alloc:
215  return rc;
216 }
217 
218 /**
219  * Close endpoint
220  *
221  * @v usbep EFI USB endpoint
222  */
223 static void efi_usb_close ( struct efi_usb_endpoint *usbep ) {
225  struct efi_usb_interface *usbintf = usbep->usbintf;
226  struct efi_usb_device *usbdev = usbintf->usbdev;
227  unsigned int index = USB_ENDPOINT_IDX ( usbep->ep.address );
228 
229  /* Sanity check */
230  assert ( usbintf->endpoint[index] == usbep );
231 
232  /* Cancel timer (if applicable) and close event */
233  bs->SetTimer ( usbep->event, TimerCancel, 0 );
234  bs->CloseEvent ( usbep->event );
235 
236  /* Close endpoint */
237  usb_endpoint_close ( &usbep->ep );
238  DBGC ( usbdev, "USBDEV %s %s closed\n",
239  usbintf->name, usb_endpoint_name ( &usbep->ep ) );
240 }
241 
242 /**
243  * Close all endpoints
244  *
245  * @v usbintf EFI USB interface
246  */
247 static void efi_usb_close_all ( struct efi_usb_interface *usbintf ) {
248  struct efi_usb_endpoint *usbep;
249  unsigned int i;
250 
251  for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
252  sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
253  usbep = usbintf->endpoint[i];
254  if ( usbep && usbep->ep.open )
255  efi_usb_close ( usbep );
256  }
257 }
258 
259 /**
260  * Free all endpoints
261  *
262  * @v usbintf EFI USB interface
263  */
264 static void efi_usb_free_all ( struct efi_usb_interface *usbintf ) {
265  struct efi_usb_endpoint *usbep;
266  unsigned int i;
267 
268  for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
269  sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
270  usbep = usbintf->endpoint[i];
271  if ( usbep ) {
272  assert ( ! usbep->ep.open );
273  free ( usbep );
274  usbintf->endpoint[i] = NULL;
275  }
276  }
277 }
278 
279 /**
280  * Complete synchronous transfer
281  *
282  * @v ep USB endpoint
283  * @v iobuf I/O buffer
284  * @v rc Completion status code
285  */
286 static void efi_usb_sync_complete ( struct usb_endpoint *ep,
287  struct io_buffer *iobuf __unused, int rc ) {
288  struct efi_usb_endpoint *usbep =
289  container_of ( ep, struct efi_usb_endpoint, ep );
290 
291  /* Record completion status */
292  usbep->rc = rc;
293 }
294 
295 /** Synchronous endpoint operations */
298 };
299 
300 /**
301  * Perform synchronous transfer
302  *
303  * @v usbintf USB endpoint
304  * @v endpoint Endpoint address
305  * @v attributes Endpoint attributes
306  * @v timeout Timeout (in milliseconds)
307  * @v data Data buffer
308  * @v len Length of data buffer
309  * @ret rc Return status code
310  */
311 static int efi_usb_sync_transfer ( struct efi_usb_interface *usbintf,
312  unsigned int endpoint,
313  unsigned int attributes,
314  unsigned int timeout,
315  void *data, size_t *len ) {
316  struct efi_usb_device *usbdev = usbintf->usbdev;
317  struct efi_usb_endpoint *usbep;
318  struct io_buffer *iobuf;
319  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
320  unsigned int i;
321  int rc;
322 
323  /* Open endpoint, if applicable */
324  if ( ( ! efi_usb_is_open ( usbintf, endpoint ) ) &&
325  ( ( rc = efi_usb_open ( usbintf, endpoint, attributes, 0,
326  &efi_usb_sync_driver ) ) != 0 ) ) {
327  goto err_open;
328  }
329  usbep = usbintf->endpoint[index];
330 
331  /* Allocate and construct I/O buffer */
332  iobuf = alloc_iob ( *len );
333  if ( ! iobuf ) {
334  rc = -ENOMEM;
335  goto err_alloc;
336  }
337  iob_put ( iobuf, *len );
338  if ( ! ( endpoint & USB_ENDPOINT_IN ) )
339  memcpy ( iobuf->data, data, *len );
340 
341  /* Initialise completion status */
342  usbep->rc = -EINPROGRESS;
343 
344  /* Enqueue transfer */
345  if ( ( rc = usb_stream ( &usbep->ep, iobuf, 0 ) ) != 0 ) {
346  DBGC ( usbdev, "USBDEV %s %s could not enqueue: %s\n",
347  usbintf->name, usb_endpoint_name ( &usbep->ep ),
348  strerror ( rc ) );
349  goto err_stream;
350  }
351 
352  /* Wait for completion */
353  rc = -ETIMEDOUT;
354  for ( i = 0 ; ( ( timeout == 0 ) || ( i < timeout ) ) ; i++ ) {
355 
356  /* Poll bus */
357  usb_poll ( usbdev->func->usb->port->hub->bus );
358 
359  /* Check for completion */
360  if ( usbep->rc != -EINPROGRESS ) {
361  rc = usbep->rc;
362  break;
363  }
364 
365  /* Delay */
366  mdelay ( 1 );
367  }
368 
369  /* Check for errors */
370  if ( rc != 0 ) {
371  DBGC ( usbdev, "USBDEV %s %s failed: %s\n", usbintf->name,
372  usb_endpoint_name ( &usbep->ep ), strerror ( rc ) );
373  goto err_completion;
374  }
375 
376  /* Copy completion to data buffer, if applicable */
377  assert ( iob_len ( iobuf ) <= *len );
378  if ( endpoint & USB_ENDPOINT_IN )
379  memcpy ( data, iobuf->data, iob_len ( iobuf ) );
380  *len = iob_len ( iobuf );
381 
382  /* Free I/O buffer */
383  free_iob ( iobuf );
384 
385  /* Leave endpoint open */
386  return 0;
387 
388  err_completion:
389  err_stream:
390  free_iob ( iobuf );
391  err_alloc:
392  efi_usb_close ( usbep );
393  err_open:
394  return EFIRC ( rc );
395 }
396 
397 /**
398  * Complete asynchronous transfer
399  *
400  * @v ep USB endpoint
401  * @v iobuf I/O buffer
402  * @v rc Completion status code
403  */
404 static void efi_usb_async_complete ( struct usb_endpoint *ep,
405  struct io_buffer *iobuf, int rc ) {
406  struct efi_usb_endpoint *usbep =
407  container_of ( ep, struct efi_usb_endpoint, ep );
408  UINT32 status;
409 
410  /* Ignore packets cancelled when the endpoint closes */
411  if ( ! ep->open )
412  goto drop;
413 
414  /* Construct status */
415  status = ( ( rc == 0 ) ? 0 : EFI_USB_ERR_SYSTEM );
416 
417  /* Report completion */
418  usbep->callback ( iobuf->data, iob_len ( iobuf ), usbep->context,
419  status );
420 
421  drop:
422  /* Recycle or free I/O buffer */
423  if ( usbep->ep.open ) {
424  usb_recycle ( &usbep->ep, iobuf );
425  } else {
426  free_iob ( iobuf );
427  }
428 }
429 
430 /** Asynchronous endpoint operations */
433 };
434 
435 /**
436  * Start asynchronous transfer
437  *
438  * @v usbintf EFI USB interface
439  * @v endpoint Endpoint address
440  * @v interval Interval (in milliseconds)
441  * @v len Transfer length
442  * @v callback Callback function
443  * @v context Context for callback function
444  * @ret rc Return status code
445  */
446 static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
447  unsigned int endpoint, unsigned int interval,
448  size_t len,
450  void *context ) {
452  struct efi_usb_device *usbdev = usbintf->usbdev;
453  struct efi_usb_endpoint *usbep;
454  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
455  EFI_STATUS efirc;
456  int rc;
457 
458  /* Fail if endpoint is already open */
459  if ( efi_usb_is_open ( usbintf, endpoint ) ) {
460  rc = -EINVAL;
461  goto err_already_open;
462  }
463 
464  /* Open endpoint */
465  if ( ( rc = efi_usb_open ( usbintf, endpoint,
466  USB_ENDPOINT_ATTR_INTERRUPT, interval,
467  &efi_usb_async_driver ) ) != 0 )
468  goto err_open;
469  usbep = usbintf->endpoint[index];
470 
471  /* Record callback parameters */
472  usbep->callback = callback;
473  usbep->context = context;
474 
475  /* Prefill endpoint */
476  usb_refill_init ( &usbep->ep, 0, len, EFI_USB_ASYNC_FILL );
477  if ( ( rc = usb_prefill ( &usbep->ep ) ) != 0 ) {
478  DBGC ( usbdev, "USBDEV %s %s could not prefill: %s\n",
479  usbintf->name, usb_endpoint_name ( &usbep->ep ),
480  strerror ( rc ) );
481  goto err_prefill;
482  }
483 
484  /* Start timer */
485  if ( ( efirc = bs->SetTimer ( usbep->event, TimerPeriodic,
486  ( interval * 10000 ) ) ) != 0 ) {
487  rc = -EEFI ( efirc );
488  DBGC ( usbdev, "USBDEV %s %s could not set timer: %s\n",
489  usbintf->name, usb_endpoint_name ( &usbep->ep ),
490  strerror ( rc ) );
491  goto err_timer;
492  }
493 
494  return 0;
495 
496  bs->SetTimer ( usbep->event, TimerCancel, 0 );
497  err_timer:
498  err_prefill:
499  efi_usb_close ( usbep );
500  err_open:
501  err_already_open:
502  return rc;
503 }
504 
505 /**
506  * Stop asynchronous transfer
507  *
508  * @v usbintf EFI USB interface
509  * @v endpoint Endpoint address
510  */
512  unsigned int endpoint ) {
514  struct efi_usb_endpoint *usbep;
515  unsigned int index = USB_ENDPOINT_IDX ( endpoint );
516 
517  /* Do nothing if endpoint is already closed */
518  if ( ! efi_usb_is_open ( usbintf, endpoint ) )
519  return;
520  usbep = usbintf->endpoint[index];
521 
522  /* Stop timer */
523  bs->SetTimer ( usbep->event, TimerCancel, 0 );
524 
525  /* Close endpoint */
526  efi_usb_close ( usbep );
527 }
528 
529 /******************************************************************************
530  *
531  * USB I/O protocol
532  *
533  ******************************************************************************
534  */
535 
536 /**
537  * Perform control transfer
538  *
539  * @v usbio USB I/O protocol
540  * @v packet Setup packet
541  * @v direction Data direction
542  * @v timeout Timeout (in milliseconds)
543  * @v data Data buffer
544  * @v len Length of data
545  * @ret status Transfer status
546  * @ret efirc EFI status code
547  */
548 static EFI_STATUS EFIAPI
550  EFI_USB_DEVICE_REQUEST *packet,
553  UINT32 *status ) {
554  struct efi_usb_interface *usbintf =
556  struct efi_usb_device *usbdev = usbintf->usbdev;
557  unsigned int request = ( packet->RequestType |
558  USB_REQUEST_TYPE ( packet->Request ) );
559  unsigned int value = le16_to_cpu ( packet->Value );
560  unsigned int index = le16_to_cpu ( packet->Index );
561  struct efi_saved_tpl tpl;
562  int rc;
563 
564  DBGC2 ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %s %dms "
565  "%p+%zx\n", usbintf->name, request, value, index,
566  le16_to_cpu ( packet->Length ),
568  ( ( size_t ) len ) );
569 
570  /* Raise TPL */
571  efi_raise_tpl ( &tpl );
572 
573  /* Clear status */
574  *status = 0;
575 
576  /* Block attempts to change the device configuration, since
577  * this is logically impossible to do given the constraints of
578  * the EFI_USB_IO_PROTOCOL design.
579  */
580  if ( ( request == USB_SET_CONFIGURATION ) &&
581  ( value != usbdev->config->config ) ) {
582  DBGC ( usbdev, "USBDEV %s cannot set configuration %d: not "
583  "logically possible\n", usbintf->name, index );
584  rc = -ENOTSUP;
585  goto err_change_config;
586  }
587 
588  /* If we are selecting a new alternate setting then close all
589  * open endpoints.
590  */
591  if ( ( request == USB_SET_INTERFACE ) &&
592  ( value != usbintf->alternate ) )
593  efi_usb_close_all ( usbintf );
594 
595  /* Issue control transfer */
596  if ( ( rc = usb_control ( usbdev->func->usb, request, value, index,
597  data, len ) ) != 0 ) {
598  DBGC ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %p+%zx "
599  "failed: %s\n", usbintf->name, request, value, index,
600  le16_to_cpu ( packet->Length ), data, ( ( size_t ) len ),
601  strerror ( rc ) );
603  goto err_control;
604  }
605 
606  /* Update alternate setting, if applicable */
607  if ( request == USB_SET_INTERFACE ) {
608  usbintf->alternate = value;
609  DBGC ( usbdev, "USBDEV %s alt %d selected\n",
610  usbintf->name, usbintf->alternate );
611  }
612 
613  err_control:
614  err_change_config:
615  efi_restore_tpl ( &tpl );
616  return EFIRC ( rc );
617 }
618 
619 /**
620  * Perform bulk transfer
621  *
622  * @v usbio USB I/O protocol
623  * @v endpoint Endpoint address
624  * @v data Data buffer
625  * @v len Length of data
626  * @v timeout Timeout (in milliseconds)
627  * @ret status Transfer status
628  * @ret efirc EFI status code
629  */
630 static EFI_STATUS EFIAPI
633  struct efi_usb_interface *usbintf =
635  struct efi_usb_device *usbdev = usbintf->usbdev;
636  size_t actual = *len;
637  struct efi_saved_tpl tpl;
638  int rc;
639 
640  DBGC2 ( usbdev, "USBDEV %s bulk %s %p+%zx %dms\n", usbintf->name,
641  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
642  ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
643 
644  /* Raise TPL */
645  efi_raise_tpl ( &tpl );
646 
647  /* Clear status */
648  *status = 0;
649 
650  /* Perform synchronous transfer */
651  if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
653  data, &actual ) ) != 0 ) {
654  /* Assume that any error represents a timeout */
656  goto err_transfer;
657  }
658 
659  err_transfer:
660  efi_restore_tpl ( &tpl );
661  return EFIRC ( rc );
662 }
663 
664 /**
665  * Perform synchronous interrupt transfer
666  *
667  * @v usbio USB I/O protocol
668  * @v endpoint Endpoint address
669  * @v data Data buffer
670  * @v len Length of data
671  * @v timeout Timeout (in milliseconds)
672  * @ret status Transfer status
673  * @ret efirc EFI status code
674  */
675 static EFI_STATUS EFIAPI
678  UINT32 *status ) {
679  struct efi_usb_interface *usbintf =
681  struct efi_usb_device *usbdev = usbintf->usbdev;
682  size_t actual = *len;
683  struct efi_saved_tpl tpl;
684  int rc;
685 
686  DBGC2 ( usbdev, "USBDEV %s sync intr %s %p+%zx %dms\n", usbintf->name,
687  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
688  ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
689 
690  /* Raise TPL */
691  efi_raise_tpl ( &tpl );
692 
693  /* Clear status */
694  *status = 0;
695 
696  /* Perform synchronous transfer */
697  if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
699  timeout, data, &actual ) ) != 0 ) {
700  /* Assume that any error represents a timeout */
702  goto err_transfer;
703  }
704 
705  err_transfer:
706  efi_restore_tpl ( &tpl );
707  return EFIRC ( rc );
708 }
709 
710 /**
711  * Perform asynchronous interrupt transfer
712  *
713  * @v usbio USB I/O protocol
714  * @v endpoint Endpoint address
715  * @v start Start (rather than stop) transfer
716  * @v interval Polling interval (in milliseconds)
717  * @v len Data length
718  * @v callback Callback function
719  * @v context Context for callback function
720  * @ret efirc EFI status code
721  */
722 static EFI_STATUS EFIAPI
724  BOOLEAN start, UINTN interval, UINTN len,
726  VOID *context ) {
727  struct efi_usb_interface *usbintf =
729  struct efi_usb_device *usbdev = usbintf->usbdev;
730  struct efi_saved_tpl tpl;
731  int rc;
732 
733  DBGC2 ( usbdev, "USBDEV %s async intr %s len %#zx int %d %p/%p\n",
734  usbintf->name,
735  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ),
736  ( ( size_t ) len ), ( ( unsigned int ) interval ),
737  callback, context );
738 
739  /* Raise TPL */
740  efi_raise_tpl ( &tpl );
741 
742  /* Start/stop transfer as applicable */
743  if ( start ) {
744 
745  /* Start new transfer */
746  if ( ( rc = efi_usb_async_start ( usbintf, endpoint, interval,
747  len, callback,
748  context ) ) != 0 )
749  goto err_start;
750 
751  } else {
752 
753  /* Stop transfer */
754  efi_usb_async_stop ( usbintf, endpoint );
755 
756  /* Success */
757  rc = 0;
758 
759  }
760 
761  err_start:
762  efi_restore_tpl ( &tpl );
763  return EFIRC ( rc );
764 }
765 
766 /**
767  * Perform synchronous isochronous transfer
768  *
769  * @v usbio USB I/O protocol
770  * @v endpoint Endpoint address
771  * @v data Data buffer
772  * @v len Length of data
773  * @ret status Transfer status
774  * @ret efirc EFI status code
775  */
776 static EFI_STATUS EFIAPI
778  VOID *data, UINTN len, UINT32 *status ) {
779  struct efi_usb_interface *usbintf =
781  struct efi_usb_device *usbdev = usbintf->usbdev;
782 
783  DBGC2 ( usbdev, "USBDEV %s sync iso %s %p+%zx\n", usbintf->name,
784  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
785  ( ( size_t ) len ) );
786 
787  /* Clear status */
788  *status = 0;
789 
790  /* Not supported */
791  return EFI_UNSUPPORTED;
792 }
793 
794 /**
795  * Perform asynchronous isochronous transfers
796  *
797  * @v usbio USB I/O protocol
798  * @v endpoint Endpoint address
799  * @v data Data buffer
800  * @v len Length of data
801  * @v callback Callback function
802  * @v context Context for callback function
803  * @ret status Transfer status
804  * @ret efirc EFI status code
805  */
806 static EFI_STATUS EFIAPI
808  VOID *data, UINTN len,
810  VOID *context ) {
811  struct efi_usb_interface *usbintf =
813  struct efi_usb_device *usbdev = usbintf->usbdev;
814 
815  DBGC2 ( usbdev, "USBDEV %s async iso %s %p+%zx %p/%p\n", usbintf->name,
816  ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
817  ( ( size_t ) len ), callback, context );
818 
819  /* Not supported */
820  return EFI_UNSUPPORTED;
821 }
822 
823 /**
824  * Get device descriptor
825  *
826  * @v usbio USB I/O protocol
827  * @ret efidesc EFI device descriptor
828  * @ret efirc EFI status code
829  */
830 static EFI_STATUS EFIAPI
832  EFI_USB_DEVICE_DESCRIPTOR *efidesc ) {
833  struct efi_usb_interface *usbintf =
835  struct efi_usb_device *usbdev = usbintf->usbdev;
836 
837  DBGC2 ( usbdev, "USBDEV %s get device descriptor\n", usbintf->name );
838 
839  /* Copy cached device descriptor */
840  memcpy ( efidesc, &usbdev->func->usb->device, sizeof ( *efidesc ) );
841 
842  return 0;
843 }
844 
845 /**
846  * Get configuration descriptor
847  *
848  * @v usbio USB I/O protocol
849  * @ret efidesc EFI interface descriptor
850  * @ret efirc EFI status code
851  */
852 static EFI_STATUS EFIAPI
854  EFI_USB_CONFIG_DESCRIPTOR *efidesc ) {
855  struct efi_usb_interface *usbintf =
857  struct efi_usb_device *usbdev = usbintf->usbdev;
858 
859  DBGC2 ( usbdev, "USBDEV %s get configuration descriptor\n",
860  usbintf->name );
861 
862  /* Copy cached configuration descriptor */
863  memcpy ( efidesc, usbdev->config, sizeof ( *efidesc ) );
864 
865  return 0;
866 }
867 
868 /**
869  * Get interface descriptor
870  *
871  * @v usbio USB I/O protocol
872  * @ret efidesc EFI interface descriptor
873  * @ret efirc EFI status code
874  */
875 static EFI_STATUS EFIAPI
877  EFI_USB_INTERFACE_DESCRIPTOR *efidesc ) {
878  struct efi_usb_interface *usbintf =
880  struct efi_usb_device *usbdev = usbintf->usbdev;
881  struct usb_interface_descriptor *desc;
882 
883  DBGC2 ( usbdev, "USBDEV %s get interface descriptor\n", usbintf->name );
884 
885  /* Locate cached interface descriptor */
886  desc = usb_interface_descriptor ( usbdev->config, usbintf->interface,
887  usbintf->alternate );
888  if ( ! desc ) {
889  DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
890  usbintf->name, usbintf->alternate );
891  return -ENOENT;
892  }
893 
894  /* Copy cached interface descriptor */
895  memcpy ( efidesc, desc, sizeof ( *efidesc ) );
896 
897  return 0;
898 }
899 
900 /**
901  * Get endpoint descriptor
902  *
903  * @v usbio USB I/O protocol
904  * @v address Endpoint index
905  * @ret efidesc EFI interface descriptor
906  * @ret efirc EFI status code
907  */
908 static EFI_STATUS EFIAPI
910  EFI_USB_ENDPOINT_DESCRIPTOR *efidesc ) {
911  struct efi_usb_interface *usbintf =
913  struct efi_usb_device *usbdev = usbintf->usbdev;
915  struct usb_endpoint_descriptor *desc;
916 
917  DBGC2 ( usbdev, "USBDEV %s get endpoint %d descriptor\n",
918  usbintf->name, index );
919 
920  /* Locate cached interface descriptor */
921  interface = usb_interface_descriptor ( usbdev->config,
922  usbintf->interface,
923  usbintf->alternate );
924  if ( ! interface ) {
925  DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
926  usbintf->name, usbintf->alternate );
927  return -ENOENT;
928  }
929 
930  /* Locate and copy cached endpoint descriptor */
931  for_each_interface_descriptor ( desc, usbdev->config, interface ) {
932  if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
933  ( index-- == 0 ) ) {
934  memcpy ( efidesc, desc, sizeof ( *efidesc ) );
935  return 0;
936  }
937  }
938  return -ENOENT;
939 }
940 
941 /**
942  * Get string descriptor
943  *
944  * @v usbio USB I/O protocol
945  * @v language Language ID
946  * @v index String index
947  * @ret string String
948  * @ret efirc EFI status code
949  */
950 static EFI_STATUS EFIAPI
952  UINT8 index, CHAR16 **string ) {
954  struct efi_usb_interface *usbintf =
956  struct efi_usb_device *usbdev = usbintf->usbdev;
958  struct efi_saved_tpl tpl;
959  VOID *buffer;
960  size_t len;
961  EFI_STATUS efirc;
962  int rc;
963 
964  DBGC2 ( usbdev, "USBDEV %s get string %d:%d descriptor\n",
965  usbintf->name, language, index );
966 
967  /* Raise TPL */
968  efi_raise_tpl ( &tpl );
969 
970  /* Read descriptor header */
971  if ( ( rc = usb_get_descriptor ( usbdev->func->usb, 0,
973  language, &header,
974  sizeof ( header ) ) ) != 0 ) {
975  DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
976  "descriptor header: %s\n", usbintf->name, language,
977  index, strerror ( rc ) );
978  goto err_get_header;
979  }
980  len = header.len;
981  if ( len < sizeof ( header ) ) {
982  DBGC ( usbdev, "USBDEV %s underlength string %d:%d\n",
983  usbintf->name, language, index );
984  rc = -EINVAL;
985  goto err_len;
986  }
987 
988  /* Allocate buffer */
989  if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
990  &buffer ) ) != 0 ) {
991  rc = -EEFI ( efirc );
992  goto err_alloc;
993  }
994 
995  /* Read whole descriptor */
996  if ( ( rc = usb_get_descriptor ( usbdev->func->usb, 0,
998  language, buffer, len ) ) != 0 ) {
999  DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
1000  "descriptor: %s\n", usbintf->name, language,
1001  index, strerror ( rc ) );
1002  goto err_get_descriptor;
1003  }
1004 
1005  /* Shuffle down and terminate string */
1006  memmove ( buffer, ( buffer + sizeof ( header ) ),
1007  ( len - sizeof ( header ) ) );
1008  memset ( ( buffer + len - sizeof ( header ) ), 0, sizeof ( **string ) );
1009 
1010  /* Restore TPL */
1011  efi_restore_tpl ( &tpl );
1012 
1013  /* Return allocated string */
1014  *string = buffer;
1015  return 0;
1016 
1017  err_get_descriptor:
1018  bs->FreePool ( buffer );
1019  err_alloc:
1020  err_len:
1021  err_get_header:
1022  efi_restore_tpl ( &tpl );
1023  return EFIRC ( rc );
1024 }
1025 
1026 /**
1027  * Get supported languages
1028  *
1029  * @v usbio USB I/O protocol
1030  * @ret languages Language ID table
1031  * @ret len Length of language ID table
1032  * @ret efirc EFI status code
1033  */
1034 static EFI_STATUS EFIAPI
1036  UINT16 **languages, UINT16 *len ) {
1037  struct efi_usb_interface *usbintf =
1039  struct efi_usb_device *usbdev = usbintf->usbdev;
1040 
1041  DBGC2 ( usbdev, "USBDEV %s get supported languages\n", usbintf->name );
1042 
1043  /* Return cached supported languages */
1044  *languages = usbdev->lang;
1045  *len = usbdev->lang_len;
1046 
1047  return 0;
1048 }
1049 
1050 /**
1051  * Reset port
1052  *
1053  * @v usbio USB I/O protocol
1054  * @ret efirc EFI status code
1055  */
1056 static EFI_STATUS EFIAPI
1058  struct efi_usb_interface *usbintf =
1060  struct efi_usb_device *usbdev = usbintf->usbdev;
1061 
1062  DBGC2 ( usbdev, "USBDEV %s reset port\n", usbintf->name );
1063 
1064  /* This is logically impossible to do, since resetting the
1065  * port may destroy state belonging to other
1066  * EFI_USB_IO_PROTOCOL instances belonging to the same USB
1067  * device. (This is yet another artifact of the incredibly
1068  * poor design of the EFI_USB_IO_PROTOCOL.)
1069  */
1070  return EFI_INVALID_PARAMETER;
1071 }
1072 
1073 /** USB I/O protocol */
1076  .UsbBulkTransfer = efi_usb_bulk_transfer,
1077  .UsbAsyncInterruptTransfer = efi_usb_async_interrupt_transfer,
1078  .UsbSyncInterruptTransfer = efi_usb_sync_interrupt_transfer,
1079  .UsbIsochronousTransfer = efi_usb_isochronous_transfer,
1080  .UsbAsyncIsochronousTransfer = efi_usb_async_isochronous_transfer,
1081  .UsbGetDeviceDescriptor = efi_usb_get_device_descriptor,
1082  .UsbGetConfigDescriptor = efi_usb_get_config_descriptor,
1083  .UsbGetInterfaceDescriptor = efi_usb_get_interface_descriptor,
1084  .UsbGetEndpointDescriptor = efi_usb_get_endpoint_descriptor,
1085  .UsbGetStringDescriptor = efi_usb_get_string_descriptor,
1086  .UsbGetSupportedLanguages = efi_usb_get_supported_languages,
1087  .UsbPortReset = efi_usb_port_reset,
1088 };
1089 
1090 /******************************************************************************
1091  *
1092  * USB driver
1093  *
1094  ******************************************************************************
1095  */
1096 
1097 /**
1098  * Install interface
1099  *
1100  * @v usbdev EFI USB device
1101  * @v interface Interface number
1102  * @ret rc Return status code
1103  */
1104 static int efi_usb_install ( struct efi_usb_device *usbdev,
1105  unsigned int interface ) {
1107  struct usb_function *func = usbdev->func;
1108  struct efi_usb_interface *usbintf;
1109  EFI_STATUS efirc;
1110  int rc;
1111 
1112  /* Allocate and initialise structure */
1113  usbintf = zalloc ( sizeof ( *usbintf ) );
1114  if ( ! usbintf ) {
1115  rc = -ENOMEM;
1116  goto err_alloc;
1117  }
1118  snprintf ( usbintf->name, sizeof ( usbintf->name ), "%s[%d]",
1119  usbdev->name, interface );
1120  usbintf->usbdev = usbdev;
1121  usbintf->interface = interface;
1122  memcpy ( &usbintf->usbio, &efi_usb_io_protocol,
1123  sizeof ( usbintf->usbio ) );
1124 
1125  /* Construct device path */
1126  usbintf->path = efi_usb_path ( func );
1127  if ( ! usbintf->path ) {
1128  rc = -ENODEV;
1129  goto err_path;
1130  }
1131 
1132  /* Add to list of interfaces */
1133  list_add_tail ( &usbintf->list, &usbdev->interfaces );
1134 
1135  /* Install protocols */
1136  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1137  &usbintf->handle,
1138  &efi_usb_io_protocol_guid, &usbintf->usbio,
1140  NULL ) ) != 0 ) {
1141  rc = -EEFI ( efirc );
1142  DBGC ( usbdev, "USBDEV %s could not install protocols: %s\n",
1143  usbintf->name, strerror ( rc ) );
1144  goto err_install_protocol;
1145  }
1146 
1147  DBGC ( usbdev, "USBDEV %s installed as %s\n",
1148  usbintf->name, efi_handle_name ( usbintf->handle ) );
1149  return 0;
1150 
1152  usbintf->handle,
1153  &efi_usb_io_protocol_guid, &usbintf->usbio,
1155  NULL );
1156  err_install_protocol:
1157  efi_usb_close_all ( usbintf );
1158  efi_usb_free_all ( usbintf );
1159  list_del ( &usbintf->list );
1160  free ( usbintf->path );
1161  err_path:
1162  free ( usbintf );
1163  err_alloc:
1164  return rc;
1165 }
1166 
1167 /**
1168  * Uninstall interface
1169  *
1170  * @v usbintf EFI USB interface
1171  */
1172 static void efi_usb_uninstall ( struct efi_usb_interface *usbintf ) {
1174  struct efi_usb_device *usbdev = usbintf->usbdev;
1175 
1176  DBGC ( usbdev, "USBDEV %s uninstalling %s\n",
1177  usbintf->name, efi_handle_name ( usbintf->handle ) );
1178 
1179  /* Disconnect controllers. This should not be necessary, but
1180  * seems to be required on some platforms to avoid failures
1181  * when uninstalling protocols.
1182  */
1183  bs->DisconnectController ( usbintf->handle, NULL, NULL );
1184 
1185  /* Uninstall protocols */
1187  usbintf->handle,
1188  &efi_usb_io_protocol_guid, &usbintf->usbio,
1190  NULL );
1191 
1192  /* Close and free all endpoints */
1193  efi_usb_close_all ( usbintf );
1194  efi_usb_free_all ( usbintf );
1195 
1196  /* Remove from list of interfaces */
1197  list_del ( &usbintf->list );
1198 
1199  /* Free device path */
1200  free ( usbintf->path );
1201 
1202  /* Free interface */
1203  free ( usbintf );
1204 }
1205 
1206 /**
1207  * Uninstall all interfaces
1208  *
1209  * @v usbdev EFI USB device
1210  */
1211 static void efi_usb_uninstall_all ( struct efi_usb_device *efiusb ) {
1212  struct efi_usb_interface *usbintf;
1213 
1214  /* Uninstall all interfaces */
1215  while ( ( usbintf = list_first_entry ( &efiusb->interfaces,
1216  struct efi_usb_interface,
1217  list ) ) ) {
1218  efi_usb_uninstall ( usbintf );
1219  }
1220 }
1221 
1222 /**
1223  * Probe device
1224  *
1225  * @v func USB function
1226  * @v config Configuration descriptor
1227  * @ret rc Return status code
1228  */
1229 static int efi_usb_probe ( struct usb_function *func,
1230  struct usb_configuration_descriptor *config ) {
1232  struct usb_device *usb = func->usb;
1233  struct efi_usb_device *usbdev;
1234  struct efi_usb_interface *usbintf;
1236  struct usb_descriptor_header *lang;
1237  size_t config_len;
1238  size_t lang_len;
1239  unsigned int i;
1240  int rc;
1241 
1242  /* Get configuration length */
1243  config_len = le16_to_cpu ( config->len );
1244 
1245  /* Get supported languages descriptor header */
1246  if ( ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
1247  &header, sizeof ( header ) ) ) != 0 ) {
1248  /* Assume no strings are present */
1249  header.len = 0;
1250  }
1251  lang_len = ( ( header.len >= sizeof ( header ) ) ?
1252  ( header.len - sizeof ( header ) ) : 0 );
1253 
1254  /* Allocate and initialise structure */
1255  usbdev = zalloc ( sizeof ( *usbdev ) + config_len +
1256  sizeof ( *lang ) + lang_len );
1257  if ( ! usbdev ) {
1258  rc = -ENOMEM;
1259  goto err_alloc;
1260  }
1261  usb_func_set_drvdata ( func, usbdev );
1262  usbdev->name = func->name;
1263  usbdev->func = func;
1264  usbdev->config = ( ( ( void * ) usbdev ) + sizeof ( *usbdev ) );
1265  memcpy ( usbdev->config, config, config_len );
1266  lang = ( ( ( void * ) usbdev->config ) + config_len );
1267  usbdev->lang = ( ( ( void * ) lang ) + sizeof ( *lang ) );
1268  usbdev->lang_len = lang_len;
1269  INIT_LIST_HEAD ( &usbdev->interfaces );
1270 
1271  /* Get supported languages descriptor, if applicable */
1272  if ( lang_len &&
1274  0, 0, lang, header.len ) ) != 0 ) ) {
1275  DBGC ( usbdev, "USBDEV %s could not get supported languages: "
1276  "%s\n", usbdev->name, strerror ( rc ) );
1277  goto err_get_languages;
1278  }
1279 
1280  /* Install interfaces */
1281  for ( i = 0 ; i < func->desc.count ; i++ ) {
1282  if ( ( rc = efi_usb_install ( usbdev,
1283  func->interface[i] ) ) != 0 )
1284  goto err_install;
1285  }
1286 
1287  /* Connect any external drivers */
1288  list_for_each_entry ( usbintf, &usbdev->interfaces, list )
1289  bs->ConnectController ( usbintf->handle, NULL, NULL, TRUE );
1290 
1291  return 0;
1292 
1293  err_install:
1294  efi_usb_uninstall_all ( usbdev );
1295  assert ( list_empty ( &usbdev->interfaces ) );
1296  err_get_languages:
1297  free ( usbdev );
1298  err_alloc:
1299  return rc;
1300 }
1301 
1302 /**
1303  * Remove device
1304  *
1305  * @v func USB function
1306  */
1307 static void efi_usb_remove ( struct usb_function *func ) {
1308  struct efi_usb_device *usbdev = usb_func_get_drvdata ( func );
1309 
1310  /* Uninstall all interfaces */
1311  efi_usb_uninstall_all ( usbdev );
1312  assert ( list_empty ( &usbdev->interfaces ) );
1313 
1314  /* Free device */
1315  free ( usbdev );
1316 }
1317 
1318 /** USB I/O protocol device IDs */
1319 static struct usb_device_id efi_usb_ids[] = {
1320  {
1321  .name = "usbio",
1322  .vendor = USB_ANY_ID,
1323  .product = USB_ANY_ID,
1324  },
1325 };
1326 
1327 /** USB I/O protocol driver */
1328 struct usb_driver usbio_driver __usb_fallback_driver = {
1329  .ids = efi_usb_ids,
1330  .id_count = ( sizeof ( efi_usb_ids ) / sizeof ( efi_usb_ids[0] ) ),
1332  .score = USB_SCORE_FALLBACK,
1333  .probe = efi_usb_probe,
1334  .remove = efi_usb_remove,
1335 };
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:404
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:1074
static void efi_usb_close(struct efi_usb_endpoint *usbep)
Close endpoint.
Definition: efi_usb.c:223
#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:876
#define iob_put(iobuf, len)
Definition: iobuf.h:116
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:167
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:853
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:247
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:676
static EFI_STATUS EFIAPI efi_usb_port_reset(EFI_USB_IO_PROTOCOL *usbio)
Reset port.
Definition: efi_usb.c:1057
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:296
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:145
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:511
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:549
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:807
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:73
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:431
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:1307
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:951
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:128
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:909
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:1319
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:777
#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:1229
static const char * efi_usb_direction_name(EFI_USB_DATA_DIRECTION direction)
Transcribe data direction (for debugging)
Definition: efi_usb.c:50
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:446
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:128
static void efi_usb_sync_complete(struct usb_endpoint *ep, struct io_buffer *iobuf __unused, int rc)
Complete synchronous transfer.
Definition: efi_usb.c:286
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:713
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:1172
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:146
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:151
struct usb_driver usbio_driver __usb_fallback_driver
USB I/O protocol driver.
Definition: efi_usb.c:1328
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:264
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:1211
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:311
#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:831
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:72
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:93
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:44
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:1104
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
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
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
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:631
#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:1035
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:159
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:723
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
A persistent I/O buffer.
Definition: iobuf.h:32
#define EVT_TIMER
Definition: UefiSpec.h:391
EFI_DISCONNECT_CONTROLLER DisconnectController
Definition: UefiSpec.h:1900