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