iPXE
efi_usb.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <unistd.h>
00030 #include <errno.h>
00031 #include <assert.h>
00032 #include <ipxe/efi/efi.h>
00033 #include <ipxe/efi/efi_utils.h>
00034 #include <ipxe/efi/efi_driver.h>
00035 #include <ipxe/efi/efi_usb.h>
00036 #include <ipxe/usb.h>
00037 
00038 /** @file
00039  *
00040  * EFI USB I/O PROTOCOL
00041  *
00042  */
00043 
00044 /**
00045  * Transcribe data direction (for debugging)
00046  *
00047  * @v direction         Data direction
00048  * @ret text            Transcribed data direction
00049  */
00050 static const char * efi_usb_direction_name ( EFI_USB_DATA_DIRECTION direction ){
00051 
00052         switch ( direction ) {
00053         case EfiUsbDataIn:      return "in";
00054         case EfiUsbDataOut:     return "out";
00055         case EfiUsbNoData:      return "none";
00056         default:                return "<UNKNOWN>";
00057         }
00058 }
00059 
00060 /******************************************************************************
00061  *
00062  * Endpoints
00063  *
00064  ******************************************************************************
00065  */
00066 
00067 /**
00068  * Poll USB bus (from endpoint event timer)
00069  *
00070  * @v event             EFI event
00071  * @v context           EFI USB endpoint
00072  */
00073 static VOID EFIAPI efi_usb_timer ( EFI_EVENT event __unused,
00074                                    VOID *context ) {
00075         struct efi_usb_endpoint *usbep = context;
00076         struct usb_bus *bus = usbep->usbintf->usbdev->usb->port->hub->bus;
00077 
00078         /* Poll bus */
00079         usb_poll ( bus );
00080 
00081         /* Refill endpoint */
00082         usb_refill ( &usbep->ep );
00083 }
00084 
00085 /**
00086  * Get endpoint MTU
00087  *
00088  * @v usbintf           EFI USB interface
00089  * @v endpoint          Endpoint address
00090  * @ret mtu             Endpoint MTU, or negative error
00091  */
00092 static int efi_usb_mtu ( struct efi_usb_interface *usbintf,
00093                          unsigned int endpoint ) {
00094         struct efi_usb_device *usbdev = usbintf->usbdev;
00095         struct usb_interface_descriptor *interface;
00096         struct usb_endpoint_descriptor *desc;
00097 
00098         /* Locate cached interface descriptor */
00099         interface = usb_interface_descriptor ( usbdev->config,
00100                                                usbintf->interface,
00101                                                usbintf->alternate );
00102         if ( ! interface ) {
00103                 DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
00104                        usbintf->name, usbintf->alternate );
00105                 return -ENOENT;
00106         }
00107 
00108         /* Locate and copy cached endpoint descriptor */
00109         for_each_interface_descriptor ( desc, usbdev->config, interface ) {
00110                 if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
00111                      ( desc->endpoint == endpoint ) )
00112                         return USB_ENDPOINT_MTU ( le16_to_cpu ( desc->sizes ) );
00113         }
00114 
00115         DBGC ( usbdev, "USBDEV %s alt %d ep %02x has no descriptor\n",
00116                usbintf->name, usbintf->alternate, endpoint );
00117         return -ENOENT;
00118 }
00119 
00120 /**
00121  * Open endpoint
00122  *
00123  * @v usbintf           EFI USB interface
00124  * @v endpoint          Endpoint address
00125  * @v attributes        Endpoint attributes
00126  * @v interval          Interval (in milliseconds)
00127  * @v driver            Driver operations
00128  * @ret rc              Return status code
00129  */
00130 static int efi_usb_open ( struct efi_usb_interface *usbintf,
00131                           unsigned int endpoint, unsigned int attributes,
00132                           unsigned int interval,
00133                           struct usb_endpoint_driver_operations *driver ) {
00134         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00135         struct efi_usb_device *usbdev = usbintf->usbdev;
00136         struct efi_usb_endpoint *usbep;
00137         unsigned int index = USB_ENDPOINT_IDX ( endpoint );
00138         int mtu;
00139         EFI_STATUS efirc;
00140         int rc;
00141 
00142         /* Get endpoint MTU */
00143         mtu = efi_usb_mtu ( usbintf, endpoint );
00144         if ( mtu < 0 ) {
00145                 rc = mtu;
00146                 goto err_mtu;
00147         }
00148 
00149         /* Allocate and initialise structure */
00150         usbep = zalloc ( sizeof ( *usbep ) );
00151         if ( ! usbep ) {
00152                 rc = -ENOMEM;
00153                 goto err_alloc;
00154         }
00155         usbep->usbintf = usbintf;
00156         usb_endpoint_init ( &usbep->ep, usbdev->usb, driver );
00157         usb_endpoint_describe ( &usbep->ep, endpoint, attributes, mtu, 0,
00158                                 ( interval << 3 /* microframes */ ) );
00159 
00160         /* Open endpoint */
00161         if ( ( rc = usb_endpoint_open ( &usbep->ep ) ) != 0 ) {
00162                 DBGC ( usbdev, "USBDEV %s %s could not open: %s\n",
00163                        usbintf->name, usb_endpoint_name ( &usbep->ep ),
00164                        strerror ( rc ) );
00165                 goto err_open;
00166         }
00167 
00168         /* Record opened endpoint */
00169         usbintf->endpoint[index] = usbep;
00170         DBGC ( usbdev, "USBDEV %s %s opened\n",
00171                usbintf->name, usb_endpoint_name ( &usbep->ep ) );
00172 
00173         /* Create event */
00174         if ( ( efirc = bs->CreateEvent ( ( EVT_TIMER | EVT_NOTIFY_SIGNAL ),
00175                                          TPL_CALLBACK, efi_usb_timer, usbep,
00176                                          &usbep->event ) ) != 0 ) {
00177                 rc = -EEFI ( efirc );
00178                 DBGC ( usbdev, "USBDEV %s %s could not create event: %s\n",
00179                        usbintf->name, usb_endpoint_name ( &usbep->ep ),
00180                        strerror ( rc ) );
00181                 goto err_event;
00182         }
00183 
00184         return 0;
00185 
00186         bs->CloseEvent ( usbep->event );
00187  err_event:
00188         usbintf->endpoint[index] = usbep;
00189         usb_endpoint_close ( &usbep->ep );
00190  err_open:
00191         free ( usbep );
00192  err_alloc:
00193  err_mtu:
00194         return rc;
00195 }
00196 
00197 /**
00198  * Close endpoint
00199  *
00200  * @v usbep             EFI USB endpoint
00201  */
00202 static void efi_usb_close ( struct efi_usb_endpoint *usbep ) {
00203         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00204         struct efi_usb_interface *usbintf = usbep->usbintf;
00205         struct efi_usb_device *usbdev = usbintf->usbdev;
00206         unsigned int index = USB_ENDPOINT_IDX ( usbep->ep.address );
00207 
00208         /* Sanity check */
00209         assert ( usbintf->endpoint[index] == usbep );
00210 
00211         /* Cancel timer (if applicable) and close event */
00212         bs->SetTimer ( usbep->event, TimerCancel, 0 );
00213         bs->CloseEvent ( usbep->event );
00214 
00215         /* Close endpoint */
00216         usb_endpoint_close ( &usbep->ep );
00217         DBGC ( usbdev, "USBDEV %s %s closed\n",
00218                usbintf->name, usb_endpoint_name ( &usbep->ep ) );
00219 
00220         /* Free endpoint */
00221         free ( usbep );
00222 
00223         /* Record closed endpoint */
00224         usbintf->endpoint[index] = NULL;
00225 }
00226 
00227 /**
00228  * Close all endpoints
00229  *
00230  * @v usbintf           EFI USB interface
00231  */
00232 static void efi_usb_close_all ( struct efi_usb_interface *usbintf ) {
00233         struct efi_usb_endpoint *usbep;
00234         unsigned int i;
00235 
00236         for ( i = 0 ; i < ( sizeof ( usbintf->endpoint ) /
00237                             sizeof ( usbintf->endpoint[0] ) ) ; i++ ) {
00238                 usbep = usbintf->endpoint[i];
00239                 if ( usbep )
00240                         efi_usb_close ( usbep );
00241         }
00242 }
00243 
00244 /**
00245  * Complete synchronous transfer
00246  *
00247  * @v ep                USB endpoint
00248  * @v iobuf             I/O buffer
00249  * @v rc                Completion status code
00250  */
00251 static void efi_usb_sync_complete ( struct usb_endpoint *ep,
00252                                     struct io_buffer *iobuf __unused, int rc ) {
00253         struct efi_usb_endpoint *usbep =
00254                 container_of ( ep, struct efi_usb_endpoint, ep );
00255 
00256         /* Record completion status */
00257         usbep->rc = rc;
00258 }
00259 
00260 /** Synchronous endpoint operations */
00261 static struct usb_endpoint_driver_operations efi_usb_sync_driver = {
00262         .complete = efi_usb_sync_complete,
00263 };
00264 
00265 /**
00266  * Perform synchronous transfer
00267  *
00268  * @v usbintf           USB endpoint
00269  * @v endpoint          Endpoint address
00270  * @v attributes        Endpoint attributes
00271  * @v timeout           Timeout (in milliseconds)
00272  * @v data              Data buffer
00273  * @v len               Length of data buffer
00274  * @ret rc              Return status code
00275  */
00276 static int efi_usb_sync_transfer ( struct efi_usb_interface *usbintf,
00277                                    unsigned int endpoint,
00278                                    unsigned int attributes,
00279                                    unsigned int timeout,
00280                                    void *data, size_t *len ) {
00281         struct efi_usb_device *usbdev = usbintf->usbdev;
00282         struct efi_usb_endpoint *usbep;
00283         struct io_buffer *iobuf;
00284         unsigned int index = USB_ENDPOINT_IDX ( endpoint );
00285         unsigned int i;
00286         int rc;
00287 
00288         /* Open endpoint, if applicable */
00289         if ( ( ! usbintf->endpoint[index] ) &&
00290              ( ( rc = efi_usb_open ( usbintf, endpoint, attributes, 0,
00291                                      &efi_usb_sync_driver ) ) != 0 ) ) {
00292                 goto err_open;
00293         }
00294         usbep = usbintf->endpoint[index];
00295 
00296         /* Allocate and construct I/O buffer */
00297         iobuf = alloc_iob ( *len );
00298         if ( ! iobuf ) {
00299                 rc = -ENOMEM;
00300                 goto err_alloc;
00301         }
00302         iob_put ( iobuf, *len );
00303         if ( ! ( endpoint & USB_ENDPOINT_IN ) )
00304                 memcpy ( iobuf->data, data, *len );
00305 
00306         /* Initialise completion status */
00307         usbep->rc = -EINPROGRESS;
00308 
00309         /* Enqueue transfer */
00310         if ( ( rc = usb_stream ( &usbep->ep, iobuf, 0 ) ) != 0 ) {
00311                 DBGC ( usbdev, "USBDEV %s %s could not enqueue: %s\n",
00312                        usbintf->name, usb_endpoint_name ( &usbep->ep ),
00313                        strerror ( rc ) );
00314                 goto err_stream;
00315         }
00316 
00317         /* Wait for completion */
00318         rc = -ETIMEDOUT;
00319         for ( i = 0 ; ( ( timeout == 0 ) || ( i < timeout ) ) ; i++ ) {
00320 
00321                 /* Poll bus */
00322                 usb_poll ( usbdev->usb->port->hub->bus );
00323 
00324                 /* Check for completion */
00325                 if ( usbep->rc != -EINPROGRESS ) {
00326                         rc = usbep->rc;
00327                         break;
00328                 }
00329 
00330                 /* Delay */
00331                 mdelay ( 1 );
00332         }
00333 
00334         /* Check for errors */
00335         if ( rc != 0 ) {
00336                 DBGC ( usbdev, "USBDEV %s %s failed: %s\n", usbintf->name,
00337                        usb_endpoint_name ( &usbep->ep ), strerror ( rc ) );
00338                 goto err_completion;
00339         }
00340 
00341         /* Copy completion to data buffer, if applicable */
00342         assert ( iob_len ( iobuf ) <= *len );
00343         if ( endpoint & USB_ENDPOINT_IN )
00344                 memcpy ( data, iobuf->data, iob_len ( iobuf ) );
00345         *len = iob_len ( iobuf );
00346 
00347         /* Free I/O buffer */
00348         free_iob ( iobuf );
00349 
00350         /* Leave endpoint open */
00351         return 0;
00352 
00353  err_completion:
00354  err_stream:
00355         free_iob ( iobuf );
00356  err_alloc:
00357         efi_usb_close ( usbep );
00358  err_open:
00359         return EFIRC ( rc );
00360 }
00361 
00362 /**
00363  * Complete asynchronous transfer
00364  *
00365  * @v ep                USB endpoint
00366  * @v iobuf             I/O buffer
00367  * @v rc                Completion status code
00368  */
00369 static void efi_usb_async_complete ( struct usb_endpoint *ep,
00370                                      struct io_buffer *iobuf, int rc ) {
00371         struct efi_usb_endpoint *usbep =
00372                 container_of ( ep, struct efi_usb_endpoint, ep );
00373         UINT32 status;
00374 
00375         /* Ignore packets cancelled when the endpoint closes */
00376         if ( ! ep->open )
00377                 goto drop;
00378 
00379         /* Construct status */
00380         status = ( ( rc == 0 ) ? 0 : EFI_USB_ERR_STALL );
00381 
00382         /* Report completion */
00383         usbep->callback ( iobuf->data, iob_len ( iobuf ), usbep->context,
00384                           status );
00385 
00386  drop:
00387         /* Recycle I/O buffer */
00388         usb_recycle ( &usbep->ep, iobuf );
00389 }
00390 
00391 /** Asynchronous endpoint operations */
00392 static struct usb_endpoint_driver_operations efi_usb_async_driver = {
00393         .complete = efi_usb_async_complete,
00394 };
00395 
00396 /**
00397  * Start asynchronous transfer
00398  *
00399  * @v usbintf           EFI USB interface
00400  * @v endpoint          Endpoint address
00401  * @v interval          Interval (in milliseconds)
00402  * @v len               Transfer length
00403  * @v callback          Callback function
00404  * @v context           Context for callback function
00405  * @ret rc              Return status code
00406  */
00407 static int efi_usb_async_start ( struct efi_usb_interface *usbintf,
00408                                  unsigned int endpoint, unsigned int interval,
00409                                  size_t len,
00410                                  EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
00411                                  void *context ) {
00412         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00413         struct efi_usb_device *usbdev = usbintf->usbdev;
00414         struct efi_usb_endpoint *usbep;
00415         unsigned int index = USB_ENDPOINT_IDX ( endpoint );
00416         EFI_STATUS efirc;
00417         int rc;
00418 
00419         /* Open endpoint */
00420         if ( ( rc = efi_usb_open ( usbintf, endpoint,
00421                                    USB_ENDPOINT_ATTR_INTERRUPT, interval,
00422                                    &efi_usb_async_driver ) ) != 0 )
00423                 goto err_open;
00424         usbep = usbintf->endpoint[index];
00425 
00426         /* Record callback parameters */
00427         usbep->callback = callback;
00428         usbep->context = context;
00429 
00430         /* Prefill endpoint */
00431         usb_refill_init ( &usbep->ep, 0, len, EFI_USB_ASYNC_FILL );
00432         if ( ( rc = usb_prefill ( &usbep->ep ) ) != 0 ) {
00433                 DBGC ( usbdev, "USBDEV %s %s could not prefill: %s\n",
00434                        usbintf->name, usb_endpoint_name ( &usbep->ep ),
00435                        strerror ( rc ) );
00436                 goto err_prefill;
00437         }
00438 
00439         /* Start timer */
00440         if ( ( efirc = bs->SetTimer ( usbep->event, TimerPeriodic,
00441                                       ( interval * 10000 ) ) ) != 0 ) {
00442                 rc = -EEFI ( efirc );
00443                 DBGC ( usbdev, "USBDEV %s %s could not set timer: %s\n",
00444                        usbintf->name, usb_endpoint_name ( &usbep->ep ),
00445                        strerror ( rc ) );
00446                 goto err_timer;
00447         }
00448 
00449         return 0;
00450 
00451         bs->SetTimer ( usbep->event, TimerCancel, 0 );
00452  err_timer:
00453  err_prefill:
00454         efi_usb_close ( usbep );
00455  err_open:
00456         return rc;
00457 }
00458 
00459 /**
00460  * Stop asynchronous transfer
00461  *
00462  * @v usbintf           EFI USB interface
00463  * @v endpoint          Endpoint address
00464  */
00465 static void efi_usb_async_stop ( struct efi_usb_interface *usbintf,
00466                                  unsigned int endpoint ) {
00467         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00468         struct efi_usb_endpoint *usbep;
00469         unsigned int index = USB_ENDPOINT_IDX ( endpoint );
00470 
00471         /* Do nothing if endpoint is already closed */
00472         usbep = usbintf->endpoint[index];
00473         if ( ! usbep )
00474                 return;
00475 
00476         /* Stop timer */
00477         bs->SetTimer ( usbep->event, TimerCancel, 0 );
00478 
00479         /* Close endpoint */
00480         efi_usb_close ( usbep );
00481 }
00482 
00483 /******************************************************************************
00484  *
00485  * USB I/O protocol
00486  *
00487  ******************************************************************************
00488  */
00489 
00490 /**
00491  * Perform control transfer
00492  *
00493  * @v usbio             USB I/O protocol
00494  * @v packet            Setup packet
00495  * @v direction         Data direction
00496  * @v timeout           Timeout (in milliseconds)
00497  * @v data              Data buffer
00498  * @v len               Length of data
00499  * @ret status          Transfer status
00500  * @ret efirc           EFI status code
00501  */
00502 static EFI_STATUS EFIAPI
00503 efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
00504                            EFI_USB_DEVICE_REQUEST *packet,
00505                            EFI_USB_DATA_DIRECTION direction,
00506                            UINT32 timeout, VOID *data, UINTN len,
00507                            UINT32 *status ) {
00508         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00509         struct efi_usb_interface *usbintf =
00510                 container_of ( usbio, struct efi_usb_interface, usbio );
00511         struct efi_usb_device *usbdev = usbintf->usbdev;
00512         unsigned int request = ( packet->RequestType |
00513                                  USB_REQUEST_TYPE ( packet->Request ) );
00514         unsigned int value = le16_to_cpu ( packet->Value );
00515         unsigned int index = le16_to_cpu ( packet->Index );
00516         EFI_TPL saved_tpl;
00517         int rc;
00518 
00519         DBGC2 ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %s %dms "
00520                 "%p+%zx\n", usbintf->name, request, value, index,
00521                 le16_to_cpu ( packet->Length ),
00522                 efi_usb_direction_name ( direction ), timeout, data,
00523                 ( ( size_t ) len ) );
00524 
00525         /* Raise TPL */
00526         saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
00527 
00528         /* Clear status */
00529         *status = 0;
00530 
00531         /* Block attempts to change the device configuration, since
00532          * this is logically impossible to do given the constraints of
00533          * the EFI_USB_IO_PROTOCOL design.
00534          */
00535         if ( ( request == USB_SET_CONFIGURATION ) &&
00536              ( value != usbdev->config->config ) ) {
00537                 DBGC ( usbdev, "USBDEV %s cannot set configuration %d: not "
00538                        "logically possible\n", usbintf->name, index );
00539                 rc = -ENOTSUP;
00540                 goto err_change_config;
00541         }
00542 
00543         /* If we are selecting a new alternate setting then close all
00544          * open endpoints.
00545          */
00546         if ( ( request == USB_SET_INTERFACE ) &&
00547              ( value != usbintf->alternate ) )
00548                 efi_usb_close_all ( usbintf );
00549 
00550         /* Issue control transfer */
00551         if ( ( rc = usb_control ( usbdev->usb, request, value, index,
00552                                   data, len ) ) != 0 ) {
00553                 DBGC ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %p+%zx "
00554                        "failed: %s\n", usbintf->name, request, value, index,
00555                        le16_to_cpu ( packet->Length ), data, ( ( size_t ) len ),
00556                        strerror ( rc ) );
00557                 /* Assume that any error represents a stall */
00558                 *status = EFI_USB_ERR_STALL;
00559                 goto err_control;
00560         }
00561 
00562         /* Update alternate setting, if applicable */
00563         if ( request == USB_SET_INTERFACE ) {
00564                 usbintf->alternate = value;
00565                 DBGC ( usbdev, "USBDEV %s alt %d selected\n",
00566                        usbintf->name, usbintf->alternate );
00567         }
00568 
00569  err_control:
00570  err_change_config:
00571         bs->RestoreTPL ( saved_tpl );
00572         return EFIRC ( rc );
00573 }
00574 
00575 /**
00576  * Perform bulk transfer
00577  *
00578  * @v usbio             USB I/O protocol
00579  * @v endpoint          Endpoint address
00580  * @v data              Data buffer
00581  * @v len               Length of data
00582  * @v timeout           Timeout (in milliseconds)
00583  * @ret status          Transfer status
00584  * @ret efirc           EFI status code
00585  */
00586 static EFI_STATUS EFIAPI
00587 efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data,
00588                         UINTN *len, UINTN timeout, UINT32 *status ) {
00589         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00590         struct efi_usb_interface *usbintf =
00591                 container_of ( usbio, struct efi_usb_interface, usbio );
00592         struct efi_usb_device *usbdev = usbintf->usbdev;
00593         size_t actual = *len;
00594         EFI_TPL saved_tpl;
00595         int rc;
00596 
00597         DBGC2 ( usbdev, "USBDEV %s bulk %s %p+%zx %dms\n", usbintf->name,
00598                 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
00599                 ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
00600 
00601         /* Raise TPL */
00602         saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
00603 
00604         /* Clear status */
00605         *status = 0;
00606 
00607         /* Perform synchronous transfer */
00608         if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
00609                                             USB_ENDPOINT_ATTR_BULK, timeout,
00610                                             data, &actual ) ) != 0 ) {
00611                 /* Assume that any error represents a timeout */
00612                 *status = EFI_USB_ERR_TIMEOUT;
00613                 goto err_transfer;
00614         }
00615 
00616  err_transfer:
00617         bs->RestoreTPL ( saved_tpl );
00618         return EFIRC ( rc );
00619 }
00620 
00621 /**
00622  * Perform synchronous interrupt transfer
00623  *
00624  * @v usbio             USB I/O protocol
00625  * @v endpoint          Endpoint address
00626  * @v data              Data buffer
00627  * @v len               Length of data
00628  * @v timeout           Timeout (in milliseconds)
00629  * @ret status          Transfer status
00630  * @ret efirc           EFI status code
00631  */
00632 static EFI_STATUS EFIAPI
00633 efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
00634                                   VOID *data, UINTN *len, UINTN timeout,
00635                                   UINT32 *status ) {
00636         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00637         struct efi_usb_interface *usbintf =
00638                 container_of ( usbio, struct efi_usb_interface, usbio );
00639         struct efi_usb_device *usbdev = usbintf->usbdev;
00640         size_t actual = *len;
00641         EFI_TPL saved_tpl;
00642         int rc;
00643 
00644         DBGC2 ( usbdev, "USBDEV %s sync intr %s %p+%zx %dms\n", usbintf->name,
00645                 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
00646                 ( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
00647 
00648         /* Raise TPL */
00649         saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
00650 
00651         /* Clear status */
00652         *status = 0;
00653 
00654         /* Perform synchronous transfer */
00655         if ( ( rc = efi_usb_sync_transfer ( usbintf, endpoint,
00656                                             USB_ENDPOINT_ATTR_INTERRUPT,
00657                                             timeout, data, &actual ) ) != 0 ) {
00658                 /* Assume that any error represents a timeout */
00659                 *status = EFI_USB_ERR_TIMEOUT;
00660                 goto err_transfer;
00661         }
00662 
00663  err_transfer:
00664         bs->RestoreTPL ( saved_tpl );
00665         return EFIRC ( rc );
00666 }
00667 
00668 /**
00669  * Perform asynchronous interrupt transfer
00670  *
00671  * @v usbio             USB I/O protocol
00672  * @v endpoint          Endpoint address
00673  * @v start             Start (rather than stop) transfer
00674  * @v interval          Polling interval (in milliseconds)
00675  * @v len               Data length
00676  * @v callback          Callback function
00677  * @v context           Context for callback function
00678  * @ret efirc           EFI status code
00679  */
00680 static EFI_STATUS EFIAPI
00681 efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
00682                                    BOOLEAN start, UINTN interval, UINTN len,
00683                                    EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
00684                                    VOID *context ) {
00685         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00686         struct efi_usb_interface *usbintf =
00687                 container_of ( usbio, struct efi_usb_interface, usbio );
00688         struct efi_usb_device *usbdev = usbintf->usbdev;
00689         EFI_TPL saved_tpl;
00690         int rc;
00691 
00692         DBGC2 ( usbdev, "USBDEV %s async intr %s len %#zx int %d %p/%p\n",
00693                 usbintf->name,
00694                 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ),
00695                 ( ( size_t ) len ), ( ( unsigned int ) interval ),
00696                 callback, context );
00697 
00698         /* Raise TPL */
00699         saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
00700 
00701         /* Start/stop transfer as applicable */
00702         if ( start ) {
00703 
00704                 /* Start new transfer */
00705                 if ( ( rc = efi_usb_async_start ( usbintf, endpoint, interval,
00706                                                   len, callback,
00707                                                   context ) ) != 0 )
00708                         goto err_start;
00709 
00710         } else {
00711 
00712                 /* Stop transfer */
00713                 efi_usb_async_stop ( usbintf, endpoint );
00714 
00715                 /* Success */
00716                 rc = 0;
00717 
00718         }
00719 
00720  err_start:
00721         bs->RestoreTPL ( saved_tpl );
00722         return EFIRC ( rc );
00723 }
00724 
00725 /**
00726  * Perform synchronous isochronous transfer
00727  *
00728  * @v usbio             USB I/O protocol
00729  * @v endpoint          Endpoint address
00730  * @v data              Data buffer
00731  * @v len               Length of data
00732  * @ret status          Transfer status
00733  * @ret efirc           EFI status code
00734  */
00735 static EFI_STATUS EFIAPI
00736 efi_usb_isochronous_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
00737                                VOID *data, UINTN len, UINT32 *status ) {
00738         struct efi_usb_interface *usbintf =
00739                 container_of ( usbio, struct efi_usb_interface, usbio );
00740         struct efi_usb_device *usbdev = usbintf->usbdev;
00741 
00742         DBGC2 ( usbdev, "USBDEV %s sync iso %s %p+%zx\n", usbintf->name,
00743                 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
00744                 ( ( size_t ) len ) );
00745 
00746         /* Clear status */
00747         *status = 0;
00748 
00749         /* Not supported */
00750         return EFI_UNSUPPORTED;
00751 }
00752 
00753 /**
00754  * Perform asynchronous isochronous transfers
00755  *
00756  * @v usbio             USB I/O protocol
00757  * @v endpoint          Endpoint address
00758  * @v data              Data buffer
00759  * @v len               Length of data
00760  * @v callback          Callback function
00761  * @v context           Context for callback function
00762  * @ret status          Transfer status
00763  * @ret efirc           EFI status code
00764  */
00765 static EFI_STATUS EFIAPI
00766 efi_usb_async_isochronous_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
00767                                      VOID *data, UINTN len,
00768                                      EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
00769                                      VOID *context ) {
00770         struct efi_usb_interface *usbintf =
00771                 container_of ( usbio, struct efi_usb_interface, usbio );
00772         struct efi_usb_device *usbdev = usbintf->usbdev;
00773 
00774         DBGC2 ( usbdev, "USBDEV %s async iso %s %p+%zx %p/%p\n", usbintf->name,
00775                 ( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
00776                 ( ( size_t ) len ), callback, context );
00777 
00778         /* Not supported */
00779         return EFI_UNSUPPORTED;
00780 }
00781 
00782 /**
00783  * Get device descriptor
00784  *
00785  * @v usbio             USB I/O protocol
00786  * @ret efidesc         EFI device descriptor
00787  * @ret efirc           EFI status code
00788  */
00789 static EFI_STATUS EFIAPI
00790 efi_usb_get_device_descriptor ( EFI_USB_IO_PROTOCOL *usbio,
00791                                 EFI_USB_DEVICE_DESCRIPTOR *efidesc ) {
00792         struct efi_usb_interface *usbintf =
00793                 container_of ( usbio, struct efi_usb_interface, usbio );
00794         struct efi_usb_device *usbdev = usbintf->usbdev;
00795 
00796         DBGC2 ( usbdev, "USBDEV %s get device descriptor\n", usbintf->name );
00797 
00798         /* Copy cached device descriptor */
00799         memcpy ( efidesc, &usbdev->usb->device, sizeof ( *efidesc ) );
00800 
00801         return 0;
00802 }
00803 
00804 /**
00805  * Get configuration descriptor
00806  *
00807  * @v usbio             USB I/O protocol
00808  * @ret efidesc         EFI interface descriptor
00809  * @ret efirc           EFI status code
00810  */
00811 static EFI_STATUS EFIAPI
00812 efi_usb_get_config_descriptor ( EFI_USB_IO_PROTOCOL *usbio,
00813                                 EFI_USB_CONFIG_DESCRIPTOR *efidesc ) {
00814         struct efi_usb_interface *usbintf =
00815                 container_of ( usbio, struct efi_usb_interface, usbio );
00816         struct efi_usb_device *usbdev = usbintf->usbdev;
00817 
00818         DBGC2 ( usbdev, "USBDEV %s get configuration descriptor\n",
00819                 usbintf->name );
00820 
00821         /* Copy cached configuration descriptor */
00822         memcpy ( efidesc, usbdev->config, sizeof ( *efidesc ) );
00823 
00824         return 0;
00825 }
00826 
00827 /**
00828  * Get interface descriptor
00829  *
00830  * @v usbio             USB I/O protocol
00831  * @ret efidesc         EFI interface descriptor
00832  * @ret efirc           EFI status code
00833  */
00834 static EFI_STATUS EFIAPI
00835 efi_usb_get_interface_descriptor ( EFI_USB_IO_PROTOCOL *usbio,
00836                                    EFI_USB_INTERFACE_DESCRIPTOR *efidesc ) {
00837         struct efi_usb_interface *usbintf =
00838                 container_of ( usbio, struct efi_usb_interface, usbio );
00839         struct efi_usb_device *usbdev = usbintf->usbdev;
00840         struct usb_interface_descriptor *desc;
00841 
00842         DBGC2 ( usbdev, "USBDEV %s get interface descriptor\n", usbintf->name );
00843 
00844         /* Locate cached interface descriptor */
00845         desc = usb_interface_descriptor ( usbdev->config, usbintf->interface,
00846                                           usbintf->alternate );
00847         if ( ! desc ) {
00848                 DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
00849                        usbintf->name, usbintf->alternate );
00850                 return -ENOENT;
00851         }
00852 
00853         /* Copy cached interface descriptor */
00854         memcpy ( efidesc, desc, sizeof ( *efidesc ) );
00855 
00856         return 0;
00857 }
00858 
00859 /**
00860  * Get endpoint descriptor
00861  *
00862  * @v usbio             USB I/O protocol
00863  * @v address           Endpoint index
00864  * @ret efidesc         EFI interface descriptor
00865  * @ret efirc           EFI status code
00866  */
00867 static EFI_STATUS EFIAPI
00868 efi_usb_get_endpoint_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT8 index,
00869                                   EFI_USB_ENDPOINT_DESCRIPTOR *efidesc ) {
00870         struct efi_usb_interface *usbintf =
00871                 container_of ( usbio, struct efi_usb_interface, usbio );
00872         struct efi_usb_device *usbdev = usbintf->usbdev;
00873         struct usb_interface_descriptor *interface;
00874         struct usb_endpoint_descriptor *desc;
00875 
00876         DBGC2 ( usbdev, "USBDEV %s get endpoint %d descriptor\n",
00877                 usbintf->name, index );
00878 
00879         /* Locate cached interface descriptor */
00880         interface = usb_interface_descriptor ( usbdev->config,
00881                                                usbintf->interface,
00882                                                usbintf->alternate );
00883         if ( ! interface ) {
00884                 DBGC ( usbdev, "USBDEV %s alt %d has no interface descriptor\n",
00885                        usbintf->name, usbintf->alternate );
00886                 return -ENOENT;
00887         }
00888 
00889         /* Locate and copy cached endpoint descriptor */
00890         for_each_interface_descriptor ( desc, usbdev->config, interface ) {
00891                 if ( ( desc->header.type == USB_ENDPOINT_DESCRIPTOR ) &&
00892                      ( index-- == 0 ) ) {
00893                         memcpy ( efidesc, desc, sizeof ( *efidesc ) );
00894                         return 0;
00895                 }
00896         }
00897         return -ENOENT;
00898 }
00899 
00900 /**
00901  * Get string descriptor
00902  *
00903  * @v usbio             USB I/O protocol
00904  * @v language          Language ID
00905  * @v index             String index
00906  * @ret string          String
00907  * @ret efirc           EFI status code
00908  */
00909 static EFI_STATUS EFIAPI
00910 efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
00911                                 UINT8 index, CHAR16 **string ) {
00912         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00913         struct efi_usb_interface *usbintf =
00914                 container_of ( usbio, struct efi_usb_interface, usbio );
00915         struct efi_usb_device *usbdev = usbintf->usbdev;
00916         struct usb_descriptor_header header;
00917         VOID *buffer;
00918         size_t len;
00919         EFI_TPL saved_tpl;
00920         EFI_STATUS efirc;
00921         int rc;
00922 
00923         DBGC2 ( usbdev, "USBDEV %s get string %d:%d descriptor\n",
00924                 usbintf->name, language, index );
00925 
00926         /* Raise TPL */
00927         saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
00928 
00929         /* Read descriptor header */
00930         if ( ( rc = usb_get_descriptor ( usbdev->usb, 0, USB_STRING_DESCRIPTOR,
00931                                          index, language, &header,
00932                                          sizeof ( header ) ) ) != 0 ) {
00933                 DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
00934                        "descriptor header: %s\n", usbintf->name, language,
00935                        index, strerror ( rc ) );
00936                 goto err_get_header;
00937         }
00938         len = header.len;
00939 
00940         /* Allocate buffer */
00941         if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
00942                                           &buffer ) ) != 0 ) {
00943                 rc = -EEFI ( efirc );
00944                 goto err_alloc;
00945         }
00946 
00947         /* Read whole descriptor */
00948         if ( ( rc = usb_get_descriptor ( usbdev->usb, 0, USB_STRING_DESCRIPTOR,
00949                                          index, language, buffer,
00950                                          len ) ) != 0 ) {
00951                 DBGC ( usbdev, "USBDEV %s could not get string %d:%d "
00952                        "descriptor: %s\n", usbintf->name, language,
00953                        index, strerror ( rc ) );
00954                 goto err_get_descriptor;
00955         }
00956 
00957         /* Shuffle down and terminate string */
00958         memmove ( buffer, ( buffer + sizeof ( header ) ),
00959                   ( len - sizeof ( header ) ) );
00960         memset ( ( buffer + len - sizeof ( header ) ), 0, sizeof ( **string ) );
00961 
00962         /* Restore TPL */
00963         bs->RestoreTPL ( saved_tpl );
00964 
00965         /* Return allocated string */
00966         *string = buffer;
00967         return 0;
00968 
00969  err_get_descriptor:
00970         bs->FreePool ( buffer );
00971  err_alloc:
00972  err_get_header:
00973         bs->RestoreTPL ( saved_tpl );
00974         return EFIRC ( rc );
00975 }
00976 
00977 /**
00978  * Get supported languages
00979  *
00980  * @v usbio             USB I/O protocol
00981  * @ret languages       Language ID table
00982  * @ret len             Length of language ID table
00983  * @ret efirc           EFI status code
00984  */
00985 static EFI_STATUS EFIAPI
00986 efi_usb_get_supported_languages ( EFI_USB_IO_PROTOCOL *usbio,
00987                                   UINT16 **languages, UINT16 *len ) {
00988         struct efi_usb_interface *usbintf =
00989                 container_of ( usbio, struct efi_usb_interface, usbio );
00990         struct efi_usb_device *usbdev = usbintf->usbdev;
00991 
00992         DBGC2 ( usbdev, "USBDEV %s get supported languages\n", usbintf->name );
00993 
00994         /* Return cached supported languages */
00995         *languages = ( ( ( void * ) usbdev->languages ) +
00996                        sizeof ( *(usbdev->languages) ) );
00997         *len = usbdev->languages->len;
00998 
00999         return 0;
01000 }
01001 
01002 /**
01003  * Reset port
01004  *
01005  * @v usbio             USB I/O protocol
01006  * @ret efirc           EFI status code
01007  */
01008 static EFI_STATUS EFIAPI
01009 efi_usb_port_reset ( EFI_USB_IO_PROTOCOL *usbio ) {
01010         struct efi_usb_interface *usbintf =
01011                 container_of ( usbio, struct efi_usb_interface, usbio );
01012         struct efi_usb_device *usbdev = usbintf->usbdev;
01013 
01014         DBGC2 ( usbdev, "USBDEV %s reset port\n", usbintf->name );
01015 
01016         /* This is logically impossible to do, since resetting the
01017          * port may destroy state belonging to other
01018          * EFI_USB_IO_PROTOCOL instances belonging to the same USB
01019          * device.  (This is yet another artifact of the incredibly
01020          * poor design of the EFI_USB_IO_PROTOCOL.)
01021          */
01022         return EFI_INVALID_PARAMETER;
01023 }
01024 
01025 /** USB I/O protocol */
01026 static EFI_USB_IO_PROTOCOL efi_usb_io_protocol = {
01027         .UsbControlTransfer             = efi_usb_control_transfer,
01028         .UsbBulkTransfer                = efi_usb_bulk_transfer,
01029         .UsbAsyncInterruptTransfer      = efi_usb_async_interrupt_transfer,
01030         .UsbSyncInterruptTransfer       = efi_usb_sync_interrupt_transfer,
01031         .UsbIsochronousTransfer         = efi_usb_isochronous_transfer,
01032         .UsbAsyncIsochronousTransfer    = efi_usb_async_isochronous_transfer,
01033         .UsbGetDeviceDescriptor         = efi_usb_get_device_descriptor,
01034         .UsbGetConfigDescriptor         = efi_usb_get_config_descriptor,
01035         .UsbGetInterfaceDescriptor      = efi_usb_get_interface_descriptor,
01036         .UsbGetEndpointDescriptor       = efi_usb_get_endpoint_descriptor,
01037         .UsbGetStringDescriptor         = efi_usb_get_string_descriptor,
01038         .UsbGetSupportedLanguages       = efi_usb_get_supported_languages,
01039         .UsbPortReset                   = efi_usb_port_reset,
01040 };
01041 
01042 /******************************************************************************
01043  *
01044  * USB driver
01045  *
01046  ******************************************************************************
01047  */
01048 
01049 /**
01050  * Install interface
01051  *
01052  * @v usbdev            EFI USB device
01053  * @v interface         Interface number
01054  * @ret rc              Return status code
01055  */
01056 static int efi_usb_install ( struct efi_usb_device *usbdev,
01057                              unsigned int interface ) {
01058         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
01059         struct efi_device *efidev = usbdev->efidev;
01060         struct efi_usb_interface *usbintf;
01061         struct usb_device *usb;
01062         EFI_DEVICE_PATH_PROTOCOL *path_end;
01063         USB_DEVICE_PATH *usbpath;
01064         unsigned int path_count;
01065         size_t path_prefix_len;
01066         size_t path_len;
01067         EFI_STATUS efirc;
01068         int rc;
01069 
01070         /* Calculate device path length */
01071         path_count = ( usb_depth ( usbdev->usb ) + 1 );
01072         path_prefix_len = efi_devpath_len ( efidev->path );
01073         path_len = ( path_prefix_len + ( path_count * sizeof ( *usbpath ) ) +
01074                      sizeof ( *path_end ) );
01075 
01076         /* Allocate and initialise structure */
01077         usbintf = zalloc ( sizeof ( *usbintf ) + path_len );
01078         if ( ! usbintf ) {
01079                 rc = -ENOMEM;
01080                 goto err_alloc;
01081         }
01082         snprintf ( usbintf->name, sizeof ( usbintf->name ), "%s[%d]",
01083                    usbdev->name, interface );
01084         usbintf->usbdev = usbdev;
01085         usbintf->interface = interface;
01086         memcpy ( &usbintf->usbio, &efi_usb_io_protocol,
01087                  sizeof ( usbintf->usbio ) );
01088         usbintf->path = ( ( ( void * ) usbintf ) + sizeof ( *usbintf ) );
01089 
01090         /* Construct device path */
01091         memcpy ( usbintf->path, efidev->path, path_prefix_len );
01092         path_end = ( ( ( void * ) usbintf->path ) + path_len -
01093                      sizeof ( *path_end ) );
01094         path_end->Type = END_DEVICE_PATH_TYPE;
01095         path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
01096         path_end->Length[0] = sizeof ( *path_end );
01097         usbpath = ( ( ( void * ) path_end ) - sizeof ( *usbpath ) );
01098         usbpath->InterfaceNumber = interface;
01099         for ( usb = usbdev->usb ; usb ; usbpath--, usb = usb->port->hub->usb ) {
01100                 usbpath->Header.Type = MESSAGING_DEVICE_PATH;
01101                 usbpath->Header.SubType = MSG_USB_DP;
01102                 usbpath->Header.Length[0] = sizeof ( *usbpath );
01103                 usbpath->ParentPortNumber = usb->port->address;
01104         }
01105 
01106         /* Add to list of interfaces */
01107         list_add_tail ( &usbintf->list, &usbdev->interfaces );
01108 
01109         /* Install protocols */
01110         if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
01111                         &usbintf->handle,
01112                         &efi_usb_io_protocol_guid, &usbintf->usbio,
01113                         &efi_device_path_protocol_guid, usbintf->path,
01114                         NULL ) ) != 0 ) {
01115                 rc = -EEFI ( efirc );
01116                 DBGC ( usbdev, "USBDEV %s could not install protocols: %s\n",
01117                        usbintf->name, strerror ( rc ) );
01118                 goto err_install_protocol;
01119         }
01120 
01121         DBGC ( usbdev, "USBDEV %s installed as %s\n",
01122                usbintf->name, efi_handle_name ( usbintf->handle ) );
01123         return 0;
01124 
01125         efi_usb_close_all ( usbintf );
01126         bs->UninstallMultipleProtocolInterfaces (
01127                         usbintf->handle,
01128                         &efi_usb_io_protocol_guid, &usbintf->usbio,
01129                         &efi_device_path_protocol_guid, usbintf->path,
01130                         NULL );
01131  err_install_protocol:
01132         list_del ( &usbintf->list );
01133         free ( usbintf );
01134  err_alloc:
01135         return rc;
01136 }
01137 
01138 /**
01139  * Uninstall interface
01140  *
01141  * @v usbintf           EFI USB interface
01142  */
01143 static void efi_usb_uninstall ( struct efi_usb_interface *usbintf ) {
01144         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
01145 
01146         /* Close all endpoints */
01147         efi_usb_close_all ( usbintf );
01148 
01149         /* Uninstall protocols */
01150         bs->UninstallMultipleProtocolInterfaces (
01151                         usbintf->handle,
01152                         &efi_usb_io_protocol_guid, &usbintf->usbio,
01153                         &efi_device_path_protocol_guid, usbintf->path,
01154                         NULL );
01155 
01156         /* Remove from list of interfaces */
01157         list_del ( &usbintf->list );
01158 
01159         /* Free interface */
01160         free ( usbintf );
01161 }
01162 
01163 /**
01164  * Uninstall all interfaces
01165  *
01166  * @v usbdev            EFI USB device
01167  */
01168 static void efi_usb_uninstall_all ( struct efi_usb_device *efiusb ) {
01169         struct efi_usb_interface *usbintf;
01170 
01171         /* Uninstall all interfaces */
01172         while ( ( usbintf = list_first_entry ( &efiusb->interfaces,
01173                                                struct efi_usb_interface,
01174                                                list ) ) ) {
01175                 efi_usb_uninstall ( usbintf );
01176         }
01177 }
01178 
01179 /**
01180  * Probe device
01181  *
01182  * @v func              USB function
01183  * @v config            Configuration descriptor
01184  * @ret rc              Return status code
01185  */
01186 static int efi_usb_probe ( struct usb_function *func,
01187                            struct usb_configuration_descriptor *config ) {
01188         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
01189         struct usb_device *usb = func->usb;
01190         struct efi_usb_device *usbdev;
01191         struct efi_usb_interface *usbintf;
01192         struct efi_device *efidev;
01193         struct usb_descriptor_header header;
01194         size_t config_len;
01195         unsigned int i;
01196         int rc;
01197 
01198         /* Find parent EFI device */
01199         efidev = efidev_parent ( &func->dev );
01200         if ( ! efidev ) {
01201                 rc = -ENOTTY;
01202                 goto err_no_efidev;
01203         }
01204 
01205         /* Get configuration length */
01206         config_len = le16_to_cpu ( config->len );
01207 
01208         /* Get supported languages descriptor header */
01209         if ( ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
01210                                          &header, sizeof ( header ) ) ) != 0 ) {
01211                 /* Assume no strings are present */
01212                 header.len = 0;
01213         }
01214 
01215         /* Allocate and initialise structure */
01216         usbdev = zalloc ( sizeof ( *usbdev ) + config_len + header.len );
01217         if ( ! usbdev ) {
01218                 rc = -ENOMEM;
01219                 goto err_alloc;
01220         }
01221         usb_func_set_drvdata ( func, usbdev );
01222         usbdev->name = func->name;
01223         usbdev->usb = usb;
01224         usbdev->efidev = efidev;
01225         usbdev->config = ( ( ( void * ) usbdev ) + sizeof ( *usbdev ) );
01226         memcpy ( usbdev->config, config, config_len );
01227         usbdev->languages = ( ( ( void * ) usbdev->config ) + config_len );
01228         INIT_LIST_HEAD ( &usbdev->interfaces );
01229 
01230         /* Get supported languages descriptor */
01231         if ( header.len &&
01232              ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
01233                                          usbdev->languages,
01234                                          header.len ) ) != 0 ) {
01235                 DBGC ( usbdev, "USBDEV %s could not get supported languages: "
01236                        "%s\n", usbdev->name, strerror ( rc ) );
01237                 goto err_get_languages;
01238         }
01239 
01240         /* Install interfaces */
01241         for ( i = 0 ; i < func->desc.count ; i++ ) {
01242                 if ( ( rc = efi_usb_install ( usbdev,
01243                                               func->interface[i] ) ) != 0 )
01244                         goto err_install;
01245         }
01246 
01247         /* Connect any external drivers */
01248         list_for_each_entry ( usbintf, &usbdev->interfaces, list )
01249                 bs->ConnectController ( usbintf->handle, NULL, NULL, TRUE );
01250 
01251         return 0;
01252 
01253  err_install:
01254         efi_usb_uninstall_all ( usbdev );
01255         assert ( list_empty ( &usbdev->interfaces ) );
01256  err_get_languages:
01257         free ( usbdev );
01258  err_alloc:
01259  err_no_efidev:
01260         return rc;
01261 }
01262 
01263 /**
01264  * Remove device
01265  *
01266  * @v func              USB function
01267  */
01268 static void efi_usb_remove ( struct usb_function *func ) {
01269         struct efi_usb_device *usbdev = usb_func_get_drvdata ( func );
01270 
01271         /* Uninstall all interfaces */
01272         efi_usb_uninstall_all ( usbdev );
01273         assert ( list_empty ( &usbdev->interfaces ) );
01274 
01275         /* Free device */
01276         free ( usbdev );
01277 }
01278 
01279 /** USB I/O protocol device IDs */
01280 static struct usb_device_id efi_usb_ids[] = {
01281         {
01282                 .name = "usbio",
01283                 .vendor = USB_ANY_ID,
01284                 .product = USB_ANY_ID,
01285         },
01286 };
01287 
01288 /** USB I/O protocol driver */
01289 struct usb_driver usbio_driver __usb_driver = {
01290         .ids = efi_usb_ids,
01291         .id_count = ( sizeof ( efi_usb_ids ) / sizeof ( efi_usb_ids[0] ) ),
01292         .class = USB_CLASS_ID ( USB_ANY_ID, USB_ANY_ID, USB_ANY_ID ),
01293         .score = USB_SCORE_FALLBACK,
01294         .probe = efi_usb_probe,
01295         .remove = efi_usb_remove,
01296 };