Home | History | Annotate | Download | only in EhciDxe
      1 /** @file
      2   The Ehci controller driver.
      3 
      4   EhciDxe driver is responsible for managing the behavior of EHCI controller.
      5   It implements the interfaces of monitoring the status of all ports and transferring
      6   Control, Bulk, Interrupt and Isochronous requests to Usb2.0 device.
      7 
      8   Note that EhciDxe driver is enhanced to guarantee that the EHCI controller get attached
      9   to the EHCI controller before a UHCI or OHCI driver attaches to the companion UHCI or
     10   OHCI controller.  This way avoids the control transfer on a shared port between EHCI
     11   and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a
     12   USB 2.0 device inserts.
     13 
     14 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
     15 This program and the accompanying materials
     16 are licensed and made available under the terms and conditions of the BSD License
     17 which accompanies this distribution.  The full text of the license may be found at
     18 http://opensource.org/licenses/bsd-license.php
     19 
     20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     21 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     22 
     23 **/
     24 
     25 
     26 #include "Ehci.h"
     27 
     28 //
     29 // Two arrays used to translate the EHCI port state (change)
     30 // to the UEFI protocol's port state (change).
     31 //
     32 USB_PORT_STATE_MAP  mUsbPortStateMap[] = {
     33   {PORTSC_CONN,     USB_PORT_STAT_CONNECTION},
     34   {PORTSC_ENABLED,  USB_PORT_STAT_ENABLE},
     35   {PORTSC_SUSPEND,  USB_PORT_STAT_SUSPEND},
     36   {PORTSC_OVERCUR,  USB_PORT_STAT_OVERCURRENT},
     37   {PORTSC_RESET,    USB_PORT_STAT_RESET},
     38   {PORTSC_POWER,    USB_PORT_STAT_POWER},
     39   {PORTSC_OWNER,    USB_PORT_STAT_OWNER}
     40 };
     41 
     42 USB_PORT_STATE_MAP  mUsbPortChangeMap[] = {
     43   {PORTSC_CONN_CHANGE,    USB_PORT_STAT_C_CONNECTION},
     44   {PORTSC_ENABLE_CHANGE,  USB_PORT_STAT_C_ENABLE},
     45   {PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT}
     46 };
     47 
     48 EFI_DRIVER_BINDING_PROTOCOL
     49 gEhciDriverBinding = {
     50   EhcDriverBindingSupported,
     51   EhcDriverBindingStart,
     52   EhcDriverBindingStop,
     53   0x30,
     54   NULL,
     55   NULL
     56 };
     57 
     58 /**
     59   Retrieves the capability of root hub ports.
     60 
     61   @param  This                  This EFI_USB_HC_PROTOCOL instance.
     62   @param  MaxSpeed              Max speed supported by the controller.
     63   @param  PortNumber            Number of the root hub ports.
     64   @param  Is64BitCapable        Whether the controller supports 64-bit memory
     65                                 addressing.
     66 
     67   @retval EFI_SUCCESS           Host controller capability were retrieved successfully.
     68   @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.
     69 
     70 **/
     71 EFI_STATUS
     72 EFIAPI
     73 EhcGetCapability (
     74   IN  EFI_USB2_HC_PROTOCOL  *This,
     75   OUT UINT8                 *MaxSpeed,
     76   OUT UINT8                 *PortNumber,
     77   OUT UINT8                 *Is64BitCapable
     78   )
     79 {
     80   USB2_HC_DEV             *Ehc;
     81   EFI_TPL                 OldTpl;
     82 
     83   if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) {
     84     return EFI_INVALID_PARAMETER;
     85   }
     86 
     87   OldTpl          = gBS->RaiseTPL (EHC_TPL);
     88   Ehc             = EHC_FROM_THIS (This);
     89 
     90   *MaxSpeed       = EFI_USB_SPEED_HIGH;
     91   *PortNumber     = (UINT8) (Ehc->HcStructParams & HCSP_NPORTS);
     92   *Is64BitCapable = (UINT8) Ehc->Support64BitDma;
     93 
     94   DEBUG ((EFI_D_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable));
     95 
     96   gBS->RestoreTPL (OldTpl);
     97   return EFI_SUCCESS;
     98 }
     99 
    100 
    101 /**
    102   Provides software reset for the USB host controller.
    103 
    104   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
    105   @param  Attributes            A bit mask of the reset operation to perform.
    106 
    107   @retval EFI_SUCCESS           The reset operation succeeded.
    108   @retval EFI_INVALID_PARAMETER Attributes is not valid.
    109   @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is
    110                                 not currently supported by the host controller.
    111   @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.
    112 
    113 **/
    114 EFI_STATUS
    115 EFIAPI
    116 EhcReset (
    117   IN EFI_USB2_HC_PROTOCOL *This,
    118   IN UINT16               Attributes
    119   )
    120 {
    121   USB2_HC_DEV             *Ehc;
    122   EFI_TPL                 OldTpl;
    123   EFI_STATUS              Status;
    124   UINT32                  DbgCtrlStatus;
    125 
    126   Ehc = EHC_FROM_THIS (This);
    127 
    128   if (Ehc->DevicePath != NULL) {
    129     //
    130     // Report Status Code to indicate reset happens
    131     //
    132     REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    133       EFI_PROGRESS_CODE,
    134       (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
    135       Ehc->DevicePath
    136       );
    137   }
    138 
    139   OldTpl  = gBS->RaiseTPL (EHC_TPL);
    140 
    141   switch (Attributes) {
    142   case EFI_USB_HC_RESET_GLOBAL:
    143   //
    144   // Flow through, same behavior as Host Controller Reset
    145   //
    146   case EFI_USB_HC_RESET_HOST_CONTROLLER:
    147     //
    148     // Host Controller must be Halt when Reset it
    149     //
    150     if (Ehc->DebugPortNum != 0) {
    151       DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0);
    152       if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {
    153         Status = EFI_SUCCESS;
    154         goto ON_EXIT;
    155       }
    156     }
    157 
    158     if (!EhcIsHalt (Ehc)) {
    159       Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
    160 
    161       if (EFI_ERROR (Status)) {
    162         Status = EFI_DEVICE_ERROR;
    163         goto ON_EXIT;
    164       }
    165     }
    166 
    167     //
    168     // Clean up the asynchronous transfers, currently only
    169     // interrupt supports asynchronous operation.
    170     //
    171     EhciDelAllAsyncIntTransfers (Ehc);
    172     EhcAckAllInterrupt (Ehc);
    173     EhcFreeSched (Ehc);
    174 
    175     Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT);
    176 
    177     if (EFI_ERROR (Status)) {
    178       goto ON_EXIT;
    179     }
    180 
    181     Status = EhcInitHC (Ehc);
    182     break;
    183 
    184   case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:
    185   case EFI_USB_HC_RESET_HOST_WITH_DEBUG:
    186     Status = EFI_UNSUPPORTED;
    187     break;
    188 
    189   default:
    190     Status = EFI_INVALID_PARAMETER;
    191   }
    192 
    193 ON_EXIT:
    194   DEBUG ((EFI_D_INFO, "EhcReset: exit status %r\n", Status));
    195   gBS->RestoreTPL (OldTpl);
    196   return Status;
    197 }
    198 
    199 
    200 /**
    201   Retrieve the current state of the USB host controller.
    202 
    203   @param  This                   This EFI_USB2_HC_PROTOCOL instance.
    204   @param  State                  Variable to return the current host controller
    205                                  state.
    206 
    207   @retval EFI_SUCCESS            Host controller state was returned in State.
    208   @retval EFI_INVALID_PARAMETER  State is NULL.
    209   @retval EFI_DEVICE_ERROR       An error was encountered while attempting to
    210                                  retrieve the host controller's current state.
    211 
    212 **/
    213 EFI_STATUS
    214 EFIAPI
    215 EhcGetState (
    216   IN   EFI_USB2_HC_PROTOCOL  *This,
    217   OUT  EFI_USB_HC_STATE      *State
    218   )
    219 {
    220   EFI_TPL                 OldTpl;
    221   USB2_HC_DEV             *Ehc;
    222 
    223   if (State == NULL) {
    224     return EFI_INVALID_PARAMETER;
    225   }
    226 
    227   OldTpl  = gBS->RaiseTPL (EHC_TPL);
    228   Ehc     = EHC_FROM_THIS (This);
    229 
    230   if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {
    231     *State = EfiUsbHcStateHalt;
    232   } else {
    233     *State = EfiUsbHcStateOperational;
    234   }
    235 
    236   gBS->RestoreTPL (OldTpl);
    237 
    238   DEBUG ((EFI_D_INFO, "EhcGetState: current state %d\n", *State));
    239   return EFI_SUCCESS;
    240 }
    241 
    242 
    243 /**
    244   Sets the USB host controller to a specific state.
    245 
    246   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
    247   @param  State                 The state of the host controller that will be set.
    248 
    249   @retval EFI_SUCCESS           The USB host controller was successfully placed
    250                                 in the state specified by State.
    251   @retval EFI_INVALID_PARAMETER State is invalid.
    252   @retval EFI_DEVICE_ERROR      Failed to set the state due to device error.
    253 
    254 **/
    255 EFI_STATUS
    256 EFIAPI
    257 EhcSetState (
    258   IN EFI_USB2_HC_PROTOCOL *This,
    259   IN EFI_USB_HC_STATE     State
    260   )
    261 {
    262   USB2_HC_DEV             *Ehc;
    263   EFI_TPL                 OldTpl;
    264   EFI_STATUS              Status;
    265   EFI_USB_HC_STATE        CurState;
    266 
    267   Status = EhcGetState (This, &CurState);
    268 
    269   if (EFI_ERROR (Status)) {
    270     return EFI_DEVICE_ERROR;
    271   }
    272 
    273   if (CurState == State) {
    274     return EFI_SUCCESS;
    275   }
    276 
    277   OldTpl  = gBS->RaiseTPL (EHC_TPL);
    278   Ehc     = EHC_FROM_THIS (This);
    279 
    280   switch (State) {
    281   case EfiUsbHcStateHalt:
    282     Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
    283     break;
    284 
    285   case EfiUsbHcStateOperational:
    286     if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR)) {
    287       Status = EFI_DEVICE_ERROR;
    288       break;
    289     }
    290 
    291     //
    292     // Software must not write a one to this field unless the host controller
    293     // is in the Halted state. Doing so will yield undefined results.
    294     // refers to Spec[EHCI1.0-2.3.1]
    295     //
    296     if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {
    297       Status = EFI_DEVICE_ERROR;
    298       break;
    299     }
    300 
    301     Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);
    302     break;
    303 
    304   case EfiUsbHcStateSuspend:
    305     Status = EFI_UNSUPPORTED;
    306     break;
    307 
    308   default:
    309     Status = EFI_INVALID_PARAMETER;
    310   }
    311 
    312   DEBUG ((EFI_D_INFO, "EhcSetState: exit status %r\n", Status));
    313   gBS->RestoreTPL (OldTpl);
    314   return Status;
    315 }
    316 
    317 
    318 /**
    319   Retrieves the current status of a USB root hub port.
    320 
    321   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
    322   @param  PortNumber            The root hub port to retrieve the state from.
    323                                 This value is zero-based.
    324   @param  PortStatus            Variable to receive the port state.
    325 
    326   @retval EFI_SUCCESS           The status of the USB root hub port specified.
    327                                 by PortNumber was returned in PortStatus.
    328   @retval EFI_INVALID_PARAMETER PortNumber is invalid.
    329   @retval EFI_DEVICE_ERROR      Can't read register.
    330 
    331 **/
    332 EFI_STATUS
    333 EFIAPI
    334 EhcGetRootHubPortStatus (
    335   IN   EFI_USB2_HC_PROTOCOL  *This,
    336   IN   UINT8                 PortNumber,
    337   OUT  EFI_USB_PORT_STATUS   *PortStatus
    338   )
    339 {
    340   USB2_HC_DEV             *Ehc;
    341   EFI_TPL                 OldTpl;
    342   UINT32                  Offset;
    343   UINT32                  State;
    344   UINT32                  TotalPort;
    345   UINTN                   Index;
    346   UINTN                   MapSize;
    347   EFI_STATUS              Status;
    348   UINT32                  DbgCtrlStatus;
    349 
    350   if (PortStatus == NULL) {
    351     return EFI_INVALID_PARAMETER;
    352   }
    353 
    354   OldTpl    = gBS->RaiseTPL (EHC_TPL);
    355 
    356   Ehc       = EHC_FROM_THIS (This);
    357   Status    = EFI_SUCCESS;
    358 
    359   TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);
    360 
    361   if (PortNumber >= TotalPort) {
    362     Status = EFI_INVALID_PARAMETER;
    363     goto ON_EXIT;
    364   }
    365 
    366   Offset                        = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));
    367   PortStatus->PortStatus        = 0;
    368   PortStatus->PortChangeStatus  = 0;
    369 
    370   if ((Ehc->DebugPortNum != 0) && (PortNumber == (Ehc->DebugPortNum - 1))) {
    371     DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0);
    372     if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {
    373       goto ON_EXIT;
    374     }
    375   }
    376 
    377   State                         = EhcReadOpReg (Ehc, Offset);
    378 
    379   //
    380   // Identify device speed. If in K state, it is low speed.
    381   // If the port is enabled after reset, the device is of
    382   // high speed. The USB bus driver should retrieve the actual
    383   // port speed after reset.
    384   //
    385   if (EHC_BIT_IS_SET (State, PORTSC_LINESTATE_K)) {
    386     PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
    387 
    388   } else if (EHC_BIT_IS_SET (State, PORTSC_ENABLED)) {
    389     PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;
    390   }
    391 
    392   //
    393   // Convert the EHCI port/port change state to UEFI status
    394   //
    395   MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP);
    396 
    397   for (Index = 0; Index < MapSize; Index++) {
    398     if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) {
    399       PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);
    400     }
    401   }
    402 
    403   MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP);
    404 
    405   for (Index = 0; Index < MapSize; Index++) {
    406     if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) {
    407       PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);
    408     }
    409   }
    410 
    411 ON_EXIT:
    412   gBS->RestoreTPL (OldTpl);
    413   return Status;
    414 }
    415 
    416 
    417 /**
    418   Sets a feature for the specified root hub port.
    419 
    420   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
    421   @param  PortNumber            Root hub port to set.
    422   @param  PortFeature           Feature to set.
    423 
    424   @retval EFI_SUCCESS           The feature specified by PortFeature was set.
    425   @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
    426   @retval EFI_DEVICE_ERROR      Can't read register.
    427 
    428 **/
    429 EFI_STATUS
    430 EFIAPI
    431 EhcSetRootHubPortFeature (
    432   IN  EFI_USB2_HC_PROTOCOL  *This,
    433   IN  UINT8                 PortNumber,
    434   IN  EFI_USB_PORT_FEATURE  PortFeature
    435   )
    436 {
    437   USB2_HC_DEV             *Ehc;
    438   EFI_TPL                 OldTpl;
    439   UINT32                  Offset;
    440   UINT32                  State;
    441   UINT32                  TotalPort;
    442   EFI_STATUS              Status;
    443 
    444   OldTpl    = gBS->RaiseTPL (EHC_TPL);
    445   Ehc       = EHC_FROM_THIS (This);
    446   Status    = EFI_SUCCESS;
    447 
    448   TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);
    449 
    450   if (PortNumber >= TotalPort) {
    451     Status = EFI_INVALID_PARAMETER;
    452     goto ON_EXIT;
    453   }
    454 
    455   Offset  = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));
    456   State   = EhcReadOpReg (Ehc, Offset);
    457 
    458   //
    459   // Mask off the port status change bits, these bits are
    460   // write clean bit
    461   //
    462   State &= ~PORTSC_CHANGE_MASK;
    463 
    464   switch (PortFeature) {
    465   case EfiUsbPortEnable:
    466     //
    467     // Sofeware can't set this bit, Port can only be enable by
    468     // EHCI as a part of the reset and enable
    469     //
    470     State |= PORTSC_ENABLED;
    471     EhcWriteOpReg (Ehc, Offset, State);
    472     break;
    473 
    474   case EfiUsbPortSuspend:
    475     State |= PORTSC_SUSPEND;
    476     EhcWriteOpReg (Ehc, Offset, State);
    477     break;
    478 
    479   case EfiUsbPortReset:
    480     //
    481     // Make sure Host Controller not halt before reset it
    482     //
    483     if (EhcIsHalt (Ehc)) {
    484       Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);
    485 
    486       if (EFI_ERROR (Status)) {
    487         DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature :failed to start HC - %r\n", Status));
    488         break;
    489       }
    490     }
    491 
    492     //
    493     // Set one to PortReset bit must also set zero to PortEnable bit
    494     //
    495     State |= PORTSC_RESET;
    496     State &= ~PORTSC_ENABLED;
    497     EhcWriteOpReg (Ehc, Offset, State);
    498     break;
    499 
    500   case EfiUsbPortPower:
    501     //
    502     // Set port power bit when PPC is 1
    503     //
    504     if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) {
    505       State |= PORTSC_POWER;
    506       EhcWriteOpReg (Ehc, Offset, State);
    507     }
    508     break;
    509 
    510   case EfiUsbPortOwner:
    511     State |= PORTSC_OWNER;
    512     EhcWriteOpReg (Ehc, Offset, State);
    513     break;
    514 
    515   default:
    516     Status = EFI_INVALID_PARAMETER;
    517   }
    518 
    519 ON_EXIT:
    520   DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature: exit status %r\n", Status));
    521 
    522   gBS->RestoreTPL (OldTpl);
    523   return Status;
    524 }
    525 
    526 
    527 /**
    528   Clears a feature for the specified root hub port.
    529 
    530   @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
    531   @param  PortNumber            Specifies the root hub port whose feature is
    532                                 requested to be cleared.
    533   @param  PortFeature           Indicates the feature selector associated with the
    534                                 feature clear request.
    535 
    536   @retval EFI_SUCCESS           The feature specified by PortFeature was cleared
    537                                 for the USB root hub port specified by PortNumber.
    538   @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
    539   @retval EFI_DEVICE_ERROR      Can't read register.
    540 
    541 **/
    542 EFI_STATUS
    543 EFIAPI
    544 EhcClearRootHubPortFeature (
    545   IN  EFI_USB2_HC_PROTOCOL  *This,
    546   IN  UINT8                 PortNumber,
    547   IN  EFI_USB_PORT_FEATURE  PortFeature
    548   )
    549 {
    550   USB2_HC_DEV             *Ehc;
    551   EFI_TPL                 OldTpl;
    552   UINT32                  Offset;
    553   UINT32                  State;
    554   UINT32                  TotalPort;
    555   EFI_STATUS              Status;
    556 
    557   OldTpl    = gBS->RaiseTPL (EHC_TPL);
    558   Ehc       = EHC_FROM_THIS (This);
    559   Status    = EFI_SUCCESS;
    560 
    561   TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);
    562 
    563   if (PortNumber >= TotalPort) {
    564     Status = EFI_INVALID_PARAMETER;
    565     goto ON_EXIT;
    566   }
    567 
    568   Offset  = EHC_PORT_STAT_OFFSET + (4 * PortNumber);
    569   State   = EhcReadOpReg (Ehc, Offset);
    570   State &= ~PORTSC_CHANGE_MASK;
    571 
    572   switch (PortFeature) {
    573   case EfiUsbPortEnable:
    574     //
    575     // Clear PORT_ENABLE feature means disable port.
    576     //
    577     State &= ~PORTSC_ENABLED;
    578     EhcWriteOpReg (Ehc, Offset, State);
    579     break;
    580 
    581   case EfiUsbPortSuspend:
    582     //
    583     // A write of zero to this bit is ignored by the host
    584     // controller. The host controller will unconditionally
    585     // set this bit to a zero when:
    586     //   1. software sets the Forct Port Resume bit to a zero from a one.
    587     //   2. software sets the Port Reset bit to a one frome a zero.
    588     //
    589     State &= ~PORSTSC_RESUME;
    590     EhcWriteOpReg (Ehc, Offset, State);
    591     break;
    592 
    593   case EfiUsbPortReset:
    594     //
    595     // Clear PORT_RESET means clear the reset signal.
    596     //
    597     State &= ~PORTSC_RESET;
    598     EhcWriteOpReg (Ehc, Offset, State);
    599     break;
    600 
    601   case EfiUsbPortOwner:
    602     //
    603     // Clear port owner means this port owned by EHC
    604     //
    605     State &= ~PORTSC_OWNER;
    606     EhcWriteOpReg (Ehc, Offset, State);
    607     break;
    608 
    609   case EfiUsbPortConnectChange:
    610     //
    611     // Clear connect status change
    612     //
    613     State |= PORTSC_CONN_CHANGE;
    614     EhcWriteOpReg (Ehc, Offset, State);
    615     break;
    616 
    617   case EfiUsbPortEnableChange:
    618     //
    619     // Clear enable status change
    620     //
    621     State |= PORTSC_ENABLE_CHANGE;
    622     EhcWriteOpReg (Ehc, Offset, State);
    623     break;
    624 
    625   case EfiUsbPortOverCurrentChange:
    626     //
    627     // Clear PortOverCurrent change
    628     //
    629     State |= PORTSC_OVERCUR_CHANGE;
    630     EhcWriteOpReg (Ehc, Offset, State);
    631     break;
    632 
    633   case EfiUsbPortPower:
    634     //
    635     // Clear port power bit when PPC is 1
    636     //
    637     if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) {
    638       State &= ~PORTSC_POWER;
    639       EhcWriteOpReg (Ehc, Offset, State);
    640     }
    641     break;
    642   case EfiUsbPortSuspendChange:
    643   case EfiUsbPortResetChange:
    644     //
    645     // Not supported or not related operation
    646     //
    647     break;
    648 
    649   default:
    650     Status = EFI_INVALID_PARAMETER;
    651     break;
    652   }
    653 
    654 ON_EXIT:
    655   DEBUG ((EFI_D_INFO, "EhcClearRootHubPortFeature: exit status %r\n", Status));
    656   gBS->RestoreTPL (OldTpl);
    657   return Status;
    658 }
    659 
    660 
    661 /**
    662   Submits control transfer to a target USB device.
    663 
    664   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
    665   @param  DeviceAddress         The target device address.
    666   @param  DeviceSpeed           Target device speed.
    667   @param  MaximumPacketLength   Maximum packet size the default control transfer
    668                                 endpoint is capable of sending or receiving.
    669   @param  Request               USB device request to send.
    670   @param  TransferDirection     Specifies the data direction for the data stage
    671   @param  Data                  Data buffer to be transmitted or received from USB
    672                                 device.
    673   @param  DataLength            The size (in bytes) of the data buffer.
    674   @param  TimeOut               Indicates the maximum timeout, in millisecond.
    675   @param  Translator            Transaction translator to be used by this device.
    676   @param  TransferResult        Return the result of this control transfer.
    677 
    678   @retval EFI_SUCCESS           Transfer was completed successfully.
    679   @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resources.
    680   @retval EFI_INVALID_PARAMETER Some parameters are invalid.
    681   @retval EFI_TIMEOUT           Transfer failed due to timeout.
    682   @retval EFI_DEVICE_ERROR      Transfer failed due to host controller or device error.
    683 
    684 **/
    685 EFI_STATUS
    686 EFIAPI
    687 EhcControlTransfer (
    688   IN  EFI_USB2_HC_PROTOCOL                *This,
    689   IN  UINT8                               DeviceAddress,
    690   IN  UINT8                               DeviceSpeed,
    691   IN  UINTN                               MaximumPacketLength,
    692   IN  EFI_USB_DEVICE_REQUEST              *Request,
    693   IN  EFI_USB_DATA_DIRECTION              TransferDirection,
    694   IN  OUT VOID                            *Data,
    695   IN  OUT UINTN                           *DataLength,
    696   IN  UINTN                               TimeOut,
    697   IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
    698   OUT UINT32                              *TransferResult
    699   )
    700 {
    701   USB2_HC_DEV             *Ehc;
    702   URB                     *Urb;
    703   EFI_TPL                 OldTpl;
    704   UINT8                   Endpoint;
    705   EFI_STATUS              Status;
    706 
    707   //
    708   // Validate parameters
    709   //
    710   if ((Request == NULL) || (TransferResult == NULL)) {
    711     return EFI_INVALID_PARAMETER;
    712   }
    713 
    714   if ((TransferDirection != EfiUsbDataIn) &&
    715       (TransferDirection != EfiUsbDataOut) &&
    716       (TransferDirection != EfiUsbNoData)) {
    717     return EFI_INVALID_PARAMETER;
    718   }
    719 
    720   if ((TransferDirection == EfiUsbNoData) &&
    721       ((Data != NULL) || (*DataLength != 0))) {
    722     return EFI_INVALID_PARAMETER;
    723   }
    724 
    725   if ((TransferDirection != EfiUsbNoData) &&
    726      ((Data == NULL) || (*DataLength == 0))) {
    727     return EFI_INVALID_PARAMETER;
    728   }
    729 
    730   if ((MaximumPacketLength != 8)  && (MaximumPacketLength != 16) &&
    731       (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) {
    732     return EFI_INVALID_PARAMETER;
    733   }
    734 
    735   if ((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) {
    736     return EFI_INVALID_PARAMETER;
    737   }
    738 
    739   OldTpl          = gBS->RaiseTPL (EHC_TPL);
    740   Ehc             = EHC_FROM_THIS (This);
    741 
    742   Status          = EFI_DEVICE_ERROR;
    743   *TransferResult = EFI_USB_ERR_SYSTEM;
    744 
    745   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {
    746     DEBUG ((EFI_D_ERROR, "EhcControlTransfer: HC halted at entrance\n"));
    747 
    748     EhcAckAllInterrupt (Ehc);
    749     goto ON_EXIT;
    750   }
    751 
    752   EhcAckAllInterrupt (Ehc);
    753 
    754   //
    755   // Create a new URB, insert it into the asynchronous
    756   // schedule list, then poll the execution status.
    757   //
    758   //
    759   // Encode the direction in address, although default control
    760   // endpoint is bidirectional. EhcCreateUrb expects this
    761   // combination of Ep addr and its direction.
    762   //
    763   Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));
    764   Urb = EhcCreateUrb (
    765           Ehc,
    766           DeviceAddress,
    767           Endpoint,
    768           DeviceSpeed,
    769           0,
    770           MaximumPacketLength,
    771           Translator,
    772           EHC_CTRL_TRANSFER,
    773           Request,
    774           Data,
    775           *DataLength,
    776           NULL,
    777           NULL,
    778           1
    779           );
    780 
    781   if (Urb == NULL) {
    782     DEBUG ((EFI_D_ERROR, "EhcControlTransfer: failed to create URB"));
    783 
    784     Status = EFI_OUT_OF_RESOURCES;
    785     goto ON_EXIT;
    786   }
    787 
    788   EhcLinkQhToAsync (Ehc, Urb->Qh);
    789   Status = EhcExecTransfer (Ehc, Urb, TimeOut);
    790   EhcUnlinkQhFromAsync (Ehc, Urb->Qh);
    791 
    792   //
    793   // Get the status from URB. The result is updated in EhcCheckUrbResult
    794   // which is called by EhcExecTransfer
    795   //
    796   *TransferResult = Urb->Result;
    797   *DataLength     = Urb->Completed;
    798 
    799   if (*TransferResult == EFI_USB_NOERROR) {
    800     Status = EFI_SUCCESS;
    801   }
    802 
    803   EhcAckAllInterrupt (Ehc);
    804   EhcFreeUrb (Ehc, Urb);
    805 
    806 ON_EXIT:
    807   Ehc->PciIo->Flush (Ehc->PciIo);
    808   gBS->RestoreTPL (OldTpl);
    809 
    810   if (EFI_ERROR (Status)) {
    811     DEBUG ((EFI_D_ERROR, "EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
    812   }
    813 
    814   return Status;
    815 }
    816 
    817 
    818 /**
    819   Submits bulk transfer to a bulk endpoint of a USB device.
    820 
    821   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
    822   @param  DeviceAddress         Target device address.
    823   @param  EndPointAddress       Endpoint number and its direction in bit 7.
    824   @param  DeviceSpeed           Device speed, Low speed device doesn't support bulk
    825                                 transfer.
    826   @param  MaximumPacketLength   Maximum packet size the endpoint is capable of
    827                                 sending or receiving.
    828   @param  DataBuffersNumber     Number of data buffers prepared for the transfer.
    829   @param  Data                  Array of pointers to the buffers of data to transmit
    830                                 from or receive into.
    831   @param  DataLength            The lenght of the data buffer.
    832   @param  DataToggle            On input, the initial data toggle for the transfer;
    833                                 On output, it is updated to to next data toggle to
    834                                 use of the subsequent bulk transfer.
    835   @param  TimeOut               Indicates the maximum time, in millisecond, which
    836                                 the transfer is allowed to complete.
    837   @param  Translator            A pointr to the transaction translator data.
    838   @param  TransferResult        A pointer to the detailed result information of the
    839                                 bulk transfer.
    840 
    841   @retval EFI_SUCCESS           The transfer was completed successfully.
    842   @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
    843   @retval EFI_INVALID_PARAMETER Some parameters are invalid.
    844   @retval EFI_TIMEOUT           The transfer failed due to timeout.
    845   @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.
    846 
    847 **/
    848 EFI_STATUS
    849 EFIAPI
    850 EhcBulkTransfer (
    851   IN  EFI_USB2_HC_PROTOCOL                *This,
    852   IN  UINT8                               DeviceAddress,
    853   IN  UINT8                               EndPointAddress,
    854   IN  UINT8                               DeviceSpeed,
    855   IN  UINTN                               MaximumPacketLength,
    856   IN  UINT8                               DataBuffersNumber,
    857   IN  OUT VOID                            *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
    858   IN  OUT UINTN                           *DataLength,
    859   IN  OUT UINT8                           *DataToggle,
    860   IN  UINTN                               TimeOut,
    861   IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
    862   OUT UINT32                              *TransferResult
    863   )
    864 {
    865   USB2_HC_DEV             *Ehc;
    866   URB                     *Urb;
    867   EFI_TPL                 OldTpl;
    868   EFI_STATUS              Status;
    869 
    870   //
    871   // Validate the parameters
    872   //
    873   if ((DataLength == NULL) || (*DataLength == 0) ||
    874       (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) {
    875     return EFI_INVALID_PARAMETER;
    876   }
    877 
    878   if ((*DataToggle != 0) && (*DataToggle != 1)) {
    879     return EFI_INVALID_PARAMETER;
    880   }
    881 
    882   if ((DeviceSpeed == EFI_USB_SPEED_LOW) ||
    883       ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||
    884       ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) {
    885     return EFI_INVALID_PARAMETER;
    886   }
    887 
    888   OldTpl          = gBS->RaiseTPL (EHC_TPL);
    889   Ehc             = EHC_FROM_THIS (This);
    890 
    891   *TransferResult = EFI_USB_ERR_SYSTEM;
    892   Status          = EFI_DEVICE_ERROR;
    893 
    894   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {
    895     DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: HC is halted\n"));
    896 
    897     EhcAckAllInterrupt (Ehc);
    898     goto ON_EXIT;
    899   }
    900 
    901   EhcAckAllInterrupt (Ehc);
    902 
    903   //
    904   // Create a new URB, insert it into the asynchronous
    905   // schedule list, then poll the execution status.
    906   //
    907   Urb = EhcCreateUrb (
    908           Ehc,
    909           DeviceAddress,
    910           EndPointAddress,
    911           DeviceSpeed,
    912           *DataToggle,
    913           MaximumPacketLength,
    914           Translator,
    915           EHC_BULK_TRANSFER,
    916           NULL,
    917           Data[0],
    918           *DataLength,
    919           NULL,
    920           NULL,
    921           1
    922           );
    923 
    924   if (Urb == NULL) {
    925     DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: failed to create URB\n"));
    926 
    927     Status = EFI_OUT_OF_RESOURCES;
    928     goto ON_EXIT;
    929   }
    930 
    931   EhcLinkQhToAsync (Ehc, Urb->Qh);
    932   Status = EhcExecTransfer (Ehc, Urb, TimeOut);
    933   EhcUnlinkQhFromAsync (Ehc, Urb->Qh);
    934 
    935   *TransferResult = Urb->Result;
    936   *DataLength     = Urb->Completed;
    937   *DataToggle     = Urb->DataToggle;
    938 
    939   if (*TransferResult == EFI_USB_NOERROR) {
    940     Status = EFI_SUCCESS;
    941   }
    942 
    943   EhcAckAllInterrupt (Ehc);
    944   EhcFreeUrb (Ehc, Urb);
    945 
    946 ON_EXIT:
    947   Ehc->PciIo->Flush (Ehc->PciIo);
    948   gBS->RestoreTPL (OldTpl);
    949 
    950   if (EFI_ERROR (Status)) {
    951     DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
    952   }
    953 
    954   return Status;
    955 }
    956 
    957 
    958 /**
    959   Submits an asynchronous interrupt transfer to an
    960   interrupt endpoint of a USB device.
    961 
    962   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
    963   @param  DeviceAddress         Target device address.
    964   @param  EndPointAddress       Endpoint number and its direction encoded in bit 7
    965   @param  DeviceSpeed           Indicates device speed.
    966   @param  MaximumPacketLength   Maximum packet size the target endpoint is capable
    967   @param  IsNewTransfer         If TRUE, to submit an new asynchronous interrupt
    968                                 transfer If FALSE, to remove the specified
    969                                 asynchronous interrupt.
    970   @param  DataToggle            On input, the initial data toggle to use; on output,
    971                                 it is updated to indicate the next data toggle.
    972   @param  PollingInterval       The he interval, in milliseconds, that the transfer
    973                                 is polled.
    974   @param  DataLength            The length of data to receive at the rate specified
    975                                 by  PollingInterval.
    976   @param  Translator            Transaction translator to use.
    977   @param  CallBackFunction      Function to call at the rate specified by
    978                                 PollingInterval.
    979   @param  Context               Context to CallBackFunction.
    980 
    981   @retval EFI_SUCCESS           The request has been successfully submitted or canceled.
    982   @retval EFI_INVALID_PARAMETER Some parameters are invalid.
    983   @retval EFI_OUT_OF_RESOURCES  The request failed due to a lack of resources.
    984   @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.
    985 
    986 **/
    987 EFI_STATUS
    988 EFIAPI
    989 EhcAsyncInterruptTransfer (
    990   IN  EFI_USB2_HC_PROTOCOL                  * This,
    991   IN  UINT8                                 DeviceAddress,
    992   IN  UINT8                                 EndPointAddress,
    993   IN  UINT8                                 DeviceSpeed,
    994   IN  UINTN                                 MaximumPacketLength,
    995   IN  BOOLEAN                               IsNewTransfer,
    996   IN  OUT UINT8                             *DataToggle,
    997   IN  UINTN                                 PollingInterval,
    998   IN  UINTN                                 DataLength,
    999   IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR    * Translator,
   1000   IN  EFI_ASYNC_USB_TRANSFER_CALLBACK       CallBackFunction,
   1001   IN  VOID                                  *Context OPTIONAL
   1002   )
   1003 {
   1004   USB2_HC_DEV             *Ehc;
   1005   URB                     *Urb;
   1006   EFI_TPL                 OldTpl;
   1007   EFI_STATUS              Status;
   1008   UINT8                   *Data;
   1009 
   1010   //
   1011   // Validate parameters
   1012   //
   1013   if (!EHCI_IS_DATAIN (EndPointAddress)) {
   1014     return EFI_INVALID_PARAMETER;
   1015   }
   1016 
   1017   if (IsNewTransfer) {
   1018     if (DataLength == 0) {
   1019       return EFI_INVALID_PARAMETER;
   1020     }
   1021 
   1022     if ((*DataToggle != 1) && (*DataToggle != 0)) {
   1023       return EFI_INVALID_PARAMETER;
   1024     }
   1025 
   1026     if ((PollingInterval > 255) || (PollingInterval < 1)) {
   1027       return EFI_INVALID_PARAMETER;
   1028     }
   1029   }
   1030 
   1031   OldTpl  = gBS->RaiseTPL (EHC_TPL);
   1032   Ehc     = EHC_FROM_THIS (This);
   1033 
   1034   //
   1035   // Delete Async interrupt transfer request. DataToggle will return
   1036   // the next data toggle to use.
   1037   //
   1038   if (!IsNewTransfer) {
   1039     Status = EhciDelAsyncIntTransfer (Ehc, DeviceAddress, EndPointAddress, DataToggle);
   1040 
   1041     DEBUG ((EFI_D_INFO, "EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status));
   1042     goto ON_EXIT;
   1043   }
   1044 
   1045   Status = EFI_SUCCESS;
   1046 
   1047   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {
   1048     DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: HC is halt\n"));
   1049     EhcAckAllInterrupt (Ehc);
   1050 
   1051     Status = EFI_DEVICE_ERROR;
   1052     goto ON_EXIT;
   1053   }
   1054 
   1055   EhcAckAllInterrupt (Ehc);
   1056 
   1057   Data = AllocatePool (DataLength);
   1058 
   1059   if (Data == NULL) {
   1060     DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to allocate buffer\n"));
   1061 
   1062     Status = EFI_OUT_OF_RESOURCES;
   1063     goto ON_EXIT;
   1064   }
   1065 
   1066   Urb = EhcCreateUrb (
   1067           Ehc,
   1068           DeviceAddress,
   1069           EndPointAddress,
   1070           DeviceSpeed,
   1071           *DataToggle,
   1072           MaximumPacketLength,
   1073           Translator,
   1074           EHC_INT_TRANSFER_ASYNC,
   1075           NULL,
   1076           Data,
   1077           DataLength,
   1078           CallBackFunction,
   1079           Context,
   1080           PollingInterval
   1081           );
   1082 
   1083   if (Urb == NULL) {
   1084     DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to create URB\n"));
   1085 
   1086     gBS->FreePool (Data);
   1087     Status = EFI_OUT_OF_RESOURCES;
   1088     goto ON_EXIT;
   1089   }
   1090 
   1091   //
   1092   // New asynchronous transfer must inserted to the head.
   1093   // Check the comments in EhcMoniteAsyncRequests
   1094   //
   1095   EhcLinkQhToPeriod (Ehc, Urb->Qh);
   1096   InsertHeadList (&Ehc->AsyncIntTransfers, &Urb->UrbList);
   1097 
   1098 ON_EXIT:
   1099   Ehc->PciIo->Flush (Ehc->PciIo);
   1100   gBS->RestoreTPL (OldTpl);
   1101 
   1102   return Status;
   1103 }
   1104 
   1105 
   1106 /**
   1107   Submits synchronous interrupt transfer to an interrupt endpoint
   1108   of a USB device.
   1109 
   1110   @param  This                  This EFI_USB2_HC_PROTOCOL instance.
   1111   @param  DeviceAddress         Target device address.
   1112   @param  EndPointAddress       Endpoint number and its direction encoded in bit 7
   1113   @param  DeviceSpeed           Indicates device speed.
   1114   @param  MaximumPacketLength   Maximum packet size the target endpoint is capable
   1115                                 of sending or receiving.
   1116   @param  Data                  Buffer of data that will be transmitted to  USB
   1117                                 device or received from USB device.
   1118   @param  DataLength            On input, the size, in bytes, of the data buffer; On
   1119                                 output, the number of bytes transferred.
   1120   @param  DataToggle            On input, the initial data toggle to use; on output,
   1121                                 it is updated to indicate the next data toggle.
   1122   @param  TimeOut               Maximum time, in second, to complete.
   1123   @param  Translator            Transaction translator to use.
   1124   @param  TransferResult        Variable to receive the transfer result.
   1125 
   1126   @return EFI_SUCCESS           The transfer was completed successfully.
   1127   @return EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
   1128   @return EFI_INVALID_PARAMETER Some parameters are invalid.
   1129   @return EFI_TIMEOUT           The transfer failed due to timeout.
   1130   @return EFI_DEVICE_ERROR      The failed due to host controller or device error
   1131 
   1132 **/
   1133 EFI_STATUS
   1134 EFIAPI
   1135 EhcSyncInterruptTransfer (
   1136   IN  EFI_USB2_HC_PROTOCOL                *This,
   1137   IN  UINT8                               DeviceAddress,
   1138   IN  UINT8                               EndPointAddress,
   1139   IN  UINT8                               DeviceSpeed,
   1140   IN  UINTN                               MaximumPacketLength,
   1141   IN  OUT VOID                            *Data,
   1142   IN  OUT UINTN                           *DataLength,
   1143   IN  OUT UINT8                           *DataToggle,
   1144   IN  UINTN                               TimeOut,
   1145   IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
   1146   OUT UINT32                              *TransferResult
   1147   )
   1148 {
   1149   USB2_HC_DEV             *Ehc;
   1150   EFI_TPL                 OldTpl;
   1151   URB                     *Urb;
   1152   EFI_STATUS              Status;
   1153 
   1154   //
   1155   // Validates parameters
   1156   //
   1157   if ((DataLength == NULL) || (*DataLength == 0) ||
   1158       (Data == NULL) || (TransferResult == NULL)) {
   1159     return EFI_INVALID_PARAMETER;
   1160   }
   1161 
   1162   if ((*DataToggle != 1) && (*DataToggle != 0)) {
   1163     return EFI_INVALID_PARAMETER;
   1164   }
   1165 
   1166   if (((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8))  ||
   1167       ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||
   1168       ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072))) {
   1169     return EFI_INVALID_PARAMETER;
   1170   }
   1171 
   1172   OldTpl          = gBS->RaiseTPL (EHC_TPL);
   1173   Ehc             = EHC_FROM_THIS (This);
   1174 
   1175   *TransferResult = EFI_USB_ERR_SYSTEM;
   1176   Status          = EFI_DEVICE_ERROR;
   1177 
   1178   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {
   1179     DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: HC is halt\n"));
   1180 
   1181     EhcAckAllInterrupt (Ehc);
   1182     goto ON_EXIT;
   1183   }
   1184 
   1185   EhcAckAllInterrupt (Ehc);
   1186 
   1187   Urb = EhcCreateUrb (
   1188           Ehc,
   1189           DeviceAddress,
   1190           EndPointAddress,
   1191           DeviceSpeed,
   1192           *DataToggle,
   1193           MaximumPacketLength,
   1194           Translator,
   1195           EHC_INT_TRANSFER_SYNC,
   1196           NULL,
   1197           Data,
   1198           *DataLength,
   1199           NULL,
   1200           NULL,
   1201           1
   1202           );
   1203 
   1204   if (Urb == NULL) {
   1205     DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: failed to create URB\n"));
   1206 
   1207     Status = EFI_OUT_OF_RESOURCES;
   1208     goto ON_EXIT;
   1209   }
   1210 
   1211   EhcLinkQhToPeriod (Ehc, Urb->Qh);
   1212   Status = EhcExecTransfer (Ehc, Urb, TimeOut);
   1213   EhcUnlinkQhFromPeriod (Ehc, Urb->Qh);
   1214 
   1215   *TransferResult = Urb->Result;
   1216   *DataLength     = Urb->Completed;
   1217   *DataToggle     = Urb->DataToggle;
   1218 
   1219   if (*TransferResult == EFI_USB_NOERROR) {
   1220     Status = EFI_SUCCESS;
   1221   }
   1222 
   1223 ON_EXIT:
   1224   Ehc->PciIo->Flush (Ehc->PciIo);
   1225   gBS->RestoreTPL (OldTpl);
   1226 
   1227   if (EFI_ERROR (Status)) {
   1228     DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
   1229   }
   1230 
   1231   return Status;
   1232 }
   1233 
   1234 
   1235 /**
   1236   Submits isochronous transfer to a target USB device.
   1237 
   1238   @param  This                 This EFI_USB2_HC_PROTOCOL instance.
   1239   @param  DeviceAddress        Target device address.
   1240   @param  EndPointAddress      End point address with its direction.
   1241   @param  DeviceSpeed          Device speed, Low speed device doesn't support this
   1242                                type.
   1243   @param  MaximumPacketLength  Maximum packet size that the endpoint is capable of
   1244                                sending or receiving.
   1245   @param  DataBuffersNumber    Number of data buffers prepared for the transfer.
   1246   @param  Data                 Array of pointers to the buffers of data that will
   1247                                be transmitted to USB device or received from USB
   1248                                device.
   1249   @param  DataLength           The size, in bytes, of the data buffer.
   1250   @param  Translator           Transaction translator to use.
   1251   @param  TransferResult       Variable to receive the transfer result.
   1252 
   1253   @return EFI_UNSUPPORTED      Isochronous transfer is unsupported.
   1254 
   1255 **/
   1256 EFI_STATUS
   1257 EFIAPI
   1258 EhcIsochronousTransfer (
   1259   IN  EFI_USB2_HC_PROTOCOL                *This,
   1260   IN  UINT8                               DeviceAddress,
   1261   IN  UINT8                               EndPointAddress,
   1262   IN  UINT8                               DeviceSpeed,
   1263   IN  UINTN                               MaximumPacketLength,
   1264   IN  UINT8                               DataBuffersNumber,
   1265   IN  OUT VOID                            *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
   1266   IN  UINTN                               DataLength,
   1267   IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
   1268   OUT UINT32                              *TransferResult
   1269   )
   1270 {
   1271   return EFI_UNSUPPORTED;
   1272 }
   1273 
   1274 
   1275 /**
   1276   Submits Async isochronous transfer to a target USB device.
   1277 
   1278   @param  This                 This EFI_USB2_HC_PROTOCOL instance.
   1279   @param  DeviceAddress        Target device address.
   1280   @param  EndPointAddress      End point address with its direction.
   1281   @param  DeviceSpeed          Device speed, Low speed device doesn't support this
   1282                                type.
   1283   @param  MaximumPacketLength  Maximum packet size that the endpoint is capable of
   1284                                sending or receiving.
   1285   @param  DataBuffersNumber    Number of data buffers prepared for the transfer.
   1286   @param  Data                 Array of pointers to the buffers of data that will
   1287                                be transmitted to USB device or received from USB
   1288                                device.
   1289   @param  DataLength           The size, in bytes, of the data buffer.
   1290   @param  Translator           Transaction translator to use.
   1291   @param  IsochronousCallBack  Function to be called when the transfer complete.
   1292   @param  Context              Context passed to the call back function as
   1293                                parameter.
   1294 
   1295   @return EFI_UNSUPPORTED      Isochronous transfer isn't supported.
   1296 
   1297 **/
   1298 EFI_STATUS
   1299 EFIAPI
   1300 EhcAsyncIsochronousTransfer (
   1301   IN  EFI_USB2_HC_PROTOCOL                *This,
   1302   IN  UINT8                               DeviceAddress,
   1303   IN  UINT8                               EndPointAddress,
   1304   IN  UINT8                               DeviceSpeed,
   1305   IN  UINTN                               MaximumPacketLength,
   1306   IN  UINT8                               DataBuffersNumber,
   1307   IN  OUT VOID                            *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
   1308   IN  UINTN                               DataLength,
   1309   IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,
   1310   IN  EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,
   1311   IN  VOID                                *Context
   1312   )
   1313 {
   1314   return EFI_UNSUPPORTED;
   1315 }
   1316 
   1317 /**
   1318   Entry point for EFI drivers.
   1319 
   1320   @param  ImageHandle       EFI_HANDLE.
   1321   @param  SystemTable       EFI_SYSTEM_TABLE.
   1322 
   1323   @return EFI_SUCCESS       Success.
   1324           EFI_DEVICE_ERROR  Fail.
   1325 
   1326 **/
   1327 EFI_STATUS
   1328 EFIAPI
   1329 EhcDriverEntryPoint (
   1330   IN EFI_HANDLE           ImageHandle,
   1331   IN EFI_SYSTEM_TABLE     *SystemTable
   1332   )
   1333 {
   1334   return EfiLibInstallDriverBindingComponentName2 (
   1335            ImageHandle,
   1336            SystemTable,
   1337            &gEhciDriverBinding,
   1338            ImageHandle,
   1339            &gEhciComponentName,
   1340            &gEhciComponentName2
   1341            );
   1342 }
   1343 
   1344 
   1345 /**
   1346   Test to see if this driver supports ControllerHandle. Any
   1347   ControllerHandle that has Usb2HcProtocol installed will
   1348   be supported.
   1349 
   1350   @param  This                 Protocol instance pointer.
   1351   @param  Controller           Handle of device to test.
   1352   @param  RemainingDevicePath  Not used.
   1353 
   1354   @return EFI_SUCCESS          This driver supports this device.
   1355   @return EFI_UNSUPPORTED      This driver does not support this device.
   1356 
   1357 **/
   1358 EFI_STATUS
   1359 EFIAPI
   1360 EhcDriverBindingSupported (
   1361   IN EFI_DRIVER_BINDING_PROTOCOL *This,
   1362   IN EFI_HANDLE                  Controller,
   1363   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
   1364   )
   1365 {
   1366   EFI_STATUS              Status;
   1367   EFI_PCI_IO_PROTOCOL     *PciIo;
   1368   USB_CLASSC              UsbClassCReg;
   1369 
   1370   //
   1371   // Test whether there is PCI IO Protocol attached on the controller handle.
   1372   //
   1373   Status = gBS->OpenProtocol (
   1374                   Controller,
   1375                   &gEfiPciIoProtocolGuid,
   1376                   (VOID **) &PciIo,
   1377                   This->DriverBindingHandle,
   1378                   Controller,
   1379                   EFI_OPEN_PROTOCOL_BY_DRIVER
   1380                   );
   1381 
   1382   if (EFI_ERROR (Status)) {
   1383     return EFI_UNSUPPORTED;
   1384   }
   1385 
   1386   Status = PciIo->Pci.Read (
   1387                         PciIo,
   1388                         EfiPciIoWidthUint8,
   1389                         PCI_CLASSCODE_OFFSET,
   1390                         sizeof (USB_CLASSC) / sizeof (UINT8),
   1391                         &UsbClassCReg
   1392                         );
   1393 
   1394   if (EFI_ERROR (Status)) {
   1395     Status = EFI_UNSUPPORTED;
   1396     goto ON_EXIT;
   1397   }
   1398 
   1399   //
   1400   // Test whether the controller belongs to Ehci type
   1401   //
   1402   if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB)
   1403       || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface != PCI_IF_UHCI) && (UsbClassCReg.ProgInterface != PCI_IF_OHCI))) {
   1404 
   1405     Status = EFI_UNSUPPORTED;
   1406   }
   1407 
   1408 ON_EXIT:
   1409   gBS->CloseProtocol (
   1410          Controller,
   1411          &gEfiPciIoProtocolGuid,
   1412          This->DriverBindingHandle,
   1413          Controller
   1414          );
   1415 
   1416   return Status;
   1417 }
   1418 
   1419 /**
   1420   Get the usb debug port related information.
   1421 
   1422   @param  Ehc                The EHCI device.
   1423 
   1424   @retval RETURN_SUCCESS     Get debug port number, bar and offset successfully.
   1425   @retval Others             The usb host controller does not supported usb debug port capability.
   1426 
   1427 **/
   1428 EFI_STATUS
   1429 EhcGetUsbDebugPortInfo (
   1430   IN  USB2_HC_DEV     *Ehc
   1431  )
   1432 {
   1433   EFI_PCI_IO_PROTOCOL *PciIo;
   1434   UINT16              PciStatus;
   1435   UINT8               CapabilityPtr;
   1436   UINT8               CapabilityId;
   1437   UINT16              DebugPort;
   1438   EFI_STATUS          Status;
   1439 
   1440   ASSERT (Ehc->PciIo != NULL);
   1441   PciIo = Ehc->PciIo;
   1442 
   1443   //
   1444   // Detect if the EHCI host controller support Capaility Pointer.
   1445   //
   1446   Status = PciIo->Pci.Read (
   1447                         PciIo,
   1448                         EfiPciIoWidthUint8,
   1449                         PCI_PRIMARY_STATUS_OFFSET,
   1450                         sizeof (UINT16),
   1451                         &PciStatus
   1452                         );
   1453 
   1454   if (EFI_ERROR (Status)) {
   1455     return Status;
   1456   }
   1457 
   1458   if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) {
   1459     //
   1460     // The Pci Device Doesn't Support Capability Pointer.
   1461     //
   1462     return EFI_UNSUPPORTED;
   1463   }
   1464 
   1465   //
   1466   // Get Pointer To Capability List
   1467   //
   1468   Status = PciIo->Pci.Read (
   1469                         PciIo,
   1470                         EfiPciIoWidthUint8,
   1471                         PCI_CAPBILITY_POINTER_OFFSET,
   1472                         1,
   1473                         &CapabilityPtr
   1474                         );
   1475 
   1476   if (EFI_ERROR (Status)) {
   1477     return Status;
   1478   }
   1479 
   1480   //
   1481   // Find Capability ID 0xA, Which Is For Debug Port
   1482   //
   1483   while (CapabilityPtr != 0) {
   1484     Status = PciIo->Pci.Read (
   1485                           PciIo,
   1486                           EfiPciIoWidthUint8,
   1487                           CapabilityPtr,
   1488                           1,
   1489                           &CapabilityId
   1490                           );
   1491 
   1492     if (EFI_ERROR (Status)) {
   1493       return Status;
   1494     }
   1495 
   1496     if (CapabilityId == EHC_DEBUG_PORT_CAP_ID) {
   1497       break;
   1498     }
   1499 
   1500     Status = PciIo->Pci.Read (
   1501                           PciIo,
   1502                           EfiPciIoWidthUint8,
   1503                           CapabilityPtr + 1,
   1504                           1,
   1505                           &CapabilityPtr
   1506                           );
   1507 
   1508     if (EFI_ERROR (Status)) {
   1509       return Status;
   1510     }
   1511   }
   1512 
   1513   //
   1514   // No Debug Port Capability Found
   1515   //
   1516   if (CapabilityPtr == 0) {
   1517     return EFI_UNSUPPORTED;
   1518   }
   1519 
   1520   //
   1521   // Get The Base Address Of Debug Port Register In Debug Port Capability Register
   1522   //
   1523   Status = PciIo->Pci.Read (
   1524                         Ehc->PciIo,
   1525                         EfiPciIoWidthUint8,
   1526                         CapabilityPtr + 2,
   1527                         sizeof (UINT16),
   1528                         &DebugPort
   1529                         );
   1530 
   1531   if (EFI_ERROR (Status)) {
   1532     return Status;
   1533   }
   1534 
   1535   Ehc->DebugPortOffset = DebugPort & 0x1FFF;
   1536   Ehc->DebugPortBarNum = (UINT8)((DebugPort >> 13) - 1);
   1537   Ehc->DebugPortNum    = (UINT8)((Ehc->HcStructParams & 0x00F00000) >> 20);
   1538 
   1539   return EFI_SUCCESS;
   1540 }
   1541 
   1542 
   1543 /**
   1544   Create and initialize a USB2_HC_DEV.
   1545 
   1546   @param  PciIo                  The PciIo on this device.
   1547   @param  DevicePath             The device path of host controller.
   1548   @param  OriginalPciAttributes  Original PCI attributes.
   1549 
   1550   @return  The allocated and initialized USB2_HC_DEV structure if created,
   1551            otherwise NULL.
   1552 
   1553 **/
   1554 USB2_HC_DEV *
   1555 EhcCreateUsb2Hc (
   1556   IN EFI_PCI_IO_PROTOCOL       *PciIo,
   1557   IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
   1558   IN UINT64                    OriginalPciAttributes
   1559   )
   1560 {
   1561   USB2_HC_DEV             *Ehc;
   1562   EFI_STATUS              Status;
   1563 
   1564   Ehc = AllocateZeroPool (sizeof (USB2_HC_DEV));
   1565 
   1566   if (Ehc == NULL) {
   1567     return NULL;
   1568   }
   1569 
   1570   //
   1571   // Init EFI_USB2_HC_PROTOCOL interface and private data structure
   1572   //
   1573   Ehc->Signature                        = USB2_HC_DEV_SIGNATURE;
   1574 
   1575   Ehc->Usb2Hc.GetCapability             = EhcGetCapability;
   1576   Ehc->Usb2Hc.Reset                     = EhcReset;
   1577   Ehc->Usb2Hc.GetState                  = EhcGetState;
   1578   Ehc->Usb2Hc.SetState                  = EhcSetState;
   1579   Ehc->Usb2Hc.ControlTransfer           = EhcControlTransfer;
   1580   Ehc->Usb2Hc.BulkTransfer              = EhcBulkTransfer;
   1581   Ehc->Usb2Hc.AsyncInterruptTransfer    = EhcAsyncInterruptTransfer;
   1582   Ehc->Usb2Hc.SyncInterruptTransfer     = EhcSyncInterruptTransfer;
   1583   Ehc->Usb2Hc.IsochronousTransfer       = EhcIsochronousTransfer;
   1584   Ehc->Usb2Hc.AsyncIsochronousTransfer  = EhcAsyncIsochronousTransfer;
   1585   Ehc->Usb2Hc.GetRootHubPortStatus      = EhcGetRootHubPortStatus;
   1586   Ehc->Usb2Hc.SetRootHubPortFeature     = EhcSetRootHubPortFeature;
   1587   Ehc->Usb2Hc.ClearRootHubPortFeature   = EhcClearRootHubPortFeature;
   1588   Ehc->Usb2Hc.MajorRevision             = 0x2;
   1589   Ehc->Usb2Hc.MinorRevision             = 0x0;
   1590 
   1591   Ehc->PciIo                 = PciIo;
   1592   Ehc->DevicePath            = DevicePath;
   1593   Ehc->OriginalPciAttributes = OriginalPciAttributes;
   1594 
   1595   InitializeListHead (&Ehc->AsyncIntTransfers);
   1596 
   1597   Ehc->HcStructParams = EhcReadCapRegister (Ehc, EHC_HCSPARAMS_OFFSET);
   1598   Ehc->HcCapParams    = EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET);
   1599   Ehc->CapLen         = EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET) & 0x0FF;
   1600 
   1601   DEBUG ((EFI_D_INFO, "EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen));
   1602 
   1603   //
   1604   // EHCI Controllers with a CapLen of 0 are ignored.
   1605   //
   1606   if (Ehc->CapLen == 0) {
   1607     gBS->FreePool (Ehc);
   1608     return NULL;
   1609   }
   1610 
   1611   EhcGetUsbDebugPortInfo (Ehc);
   1612 
   1613   //
   1614   // Create AsyncRequest Polling Timer
   1615   //
   1616   Status = gBS->CreateEvent (
   1617                   EVT_TIMER | EVT_NOTIFY_SIGNAL,
   1618                   TPL_NOTIFY,
   1619                   EhcMonitorAsyncRequests,
   1620                   Ehc,
   1621                   &Ehc->PollTimer
   1622                   );
   1623 
   1624   if (EFI_ERROR (Status)) {
   1625     gBS->FreePool (Ehc);
   1626     return NULL;
   1627   }
   1628 
   1629   return Ehc;
   1630 }
   1631 
   1632 /**
   1633   One notified function to stop the Host Controller when gBS->ExitBootServices() called.
   1634 
   1635   @param  Event                   Pointer to this event
   1636   @param  Context                 Event handler private data
   1637 
   1638 **/
   1639 VOID
   1640 EFIAPI
   1641 EhcExitBootService (
   1642   EFI_EVENT                      Event,
   1643   VOID                           *Context
   1644   )
   1645 
   1646 {
   1647   USB2_HC_DEV   *Ehc;
   1648 
   1649   Ehc = (USB2_HC_DEV *) Context;
   1650 
   1651   //
   1652   // Reset the Host Controller
   1653   //
   1654   EhcResetHC (Ehc, EHC_RESET_TIMEOUT);
   1655 }
   1656 
   1657 
   1658 /**
   1659   Starting the Usb EHCI Driver.
   1660 
   1661   @param  This                 Protocol instance pointer.
   1662   @param  Controller           Handle of device to test.
   1663   @param  RemainingDevicePath  Not used.
   1664 
   1665   @return EFI_SUCCESS          supports this device.
   1666   @return EFI_UNSUPPORTED      do not support this device.
   1667   @return EFI_DEVICE_ERROR     cannot be started due to device Error.
   1668   @return EFI_OUT_OF_RESOURCES cannot allocate resources.
   1669 
   1670 **/
   1671 EFI_STATUS
   1672 EFIAPI
   1673 EhcDriverBindingStart (
   1674   IN EFI_DRIVER_BINDING_PROTOCOL *This,
   1675   IN EFI_HANDLE                  Controller,
   1676   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
   1677   )
   1678 {
   1679   EFI_STATUS              Status;
   1680   USB2_HC_DEV             *Ehc;
   1681   EFI_PCI_IO_PROTOCOL     *PciIo;
   1682   EFI_PCI_IO_PROTOCOL     *Instance;
   1683   UINT64                  Supports;
   1684   UINT64                  OriginalPciAttributes;
   1685   BOOLEAN                 PciAttributesSaved;
   1686   USB_CLASSC              UsbClassCReg;
   1687   EFI_HANDLE              *HandleBuffer;
   1688   UINTN                   NumberOfHandles;
   1689   UINTN                   Index;
   1690   UINTN                   CompanionSegmentNumber;
   1691   UINTN                   CompanionBusNumber;
   1692   UINTN                   CompanionDeviceNumber;
   1693   UINTN                   CompanionFunctionNumber;
   1694   UINTN                   EhciSegmentNumber;
   1695   UINTN                   EhciBusNumber;
   1696   UINTN                   EhciDeviceNumber;
   1697   UINTN                   EhciFunctionNumber;
   1698   UINT32                  State;
   1699   EFI_DEVICE_PATH_PROTOCOL  *HcDevicePath;
   1700 
   1701   //
   1702   // Open the PciIo Protocol, then enable the USB host controller
   1703   //
   1704   Status = gBS->OpenProtocol (
   1705                   Controller,
   1706                   &gEfiPciIoProtocolGuid,
   1707                   (VOID **) &PciIo,
   1708                   This->DriverBindingHandle,
   1709                   Controller,
   1710                   EFI_OPEN_PROTOCOL_BY_DRIVER
   1711                   );
   1712 
   1713   if (EFI_ERROR (Status)) {
   1714     return Status;
   1715   }
   1716 
   1717   //
   1718   // Open Device Path Protocol for on USB host controller
   1719   //
   1720   HcDevicePath = NULL;
   1721   Status = gBS->OpenProtocol (
   1722                   Controller,
   1723                   &gEfiDevicePathProtocolGuid,
   1724                   (VOID **) &HcDevicePath,
   1725                   This->DriverBindingHandle,
   1726                   Controller,
   1727                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1728                   );
   1729 
   1730   PciAttributesSaved = FALSE;
   1731   //
   1732   // Save original PCI attributes
   1733   //
   1734   Status = PciIo->Attributes (
   1735                     PciIo,
   1736                     EfiPciIoAttributeOperationGet,
   1737                     0,
   1738                     &OriginalPciAttributes
   1739                     );
   1740 
   1741   if (EFI_ERROR (Status)) {
   1742     goto CLOSE_PCIIO;
   1743   }
   1744   PciAttributesSaved = TRUE;
   1745 
   1746   Status = PciIo->Attributes (
   1747                     PciIo,
   1748                     EfiPciIoAttributeOperationSupported,
   1749                     0,
   1750                     &Supports
   1751                     );
   1752   if (!EFI_ERROR (Status)) {
   1753     Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
   1754     Status = PciIo->Attributes (
   1755                       PciIo,
   1756                       EfiPciIoAttributeOperationEnable,
   1757                       Supports,
   1758                       NULL
   1759                       );
   1760   }
   1761 
   1762   if (EFI_ERROR (Status)) {
   1763     DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to enable controller\n"));
   1764     goto CLOSE_PCIIO;
   1765   }
   1766 
   1767   //
   1768   // Get the Pci device class code.
   1769   //
   1770   Status = PciIo->Pci.Read (
   1771                         PciIo,
   1772                         EfiPciIoWidthUint8,
   1773                         PCI_CLASSCODE_OFFSET,
   1774                         sizeof (USB_CLASSC) / sizeof (UINT8),
   1775                         &UsbClassCReg
   1776                         );
   1777 
   1778   if (EFI_ERROR (Status)) {
   1779     Status = EFI_UNSUPPORTED;
   1780     goto CLOSE_PCIIO;
   1781   }
   1782   //
   1783   // Determine if the device is UHCI or OHCI host controller or not. If yes, then find out the
   1784   // companion usb ehci host controller and force EHCI driver get attached to it before
   1785   // UHCI or OHCI driver attaches to UHCI or OHCI host controller.
   1786   //
   1787   if ((UsbClassCReg.ProgInterface == PCI_IF_UHCI || UsbClassCReg.ProgInterface == PCI_IF_OHCI) &&
   1788        (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&
   1789        (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) {
   1790     Status = PciIo->GetLocation (
   1791                     PciIo,
   1792                     &CompanionSegmentNumber,
   1793                     &CompanionBusNumber,
   1794                     &CompanionDeviceNumber,
   1795                     &CompanionFunctionNumber
   1796                     );
   1797     if (EFI_ERROR (Status)) {
   1798       goto CLOSE_PCIIO;
   1799     }
   1800 
   1801     Status = gBS->LocateHandleBuffer (
   1802                     ByProtocol,
   1803                     &gEfiPciIoProtocolGuid,
   1804                     NULL,
   1805                     &NumberOfHandles,
   1806                     &HandleBuffer
   1807                     );
   1808     if (EFI_ERROR (Status)) {
   1809       goto CLOSE_PCIIO;
   1810     }
   1811 
   1812     for (Index = 0; Index < NumberOfHandles; Index++) {
   1813       //
   1814       // Get the device path on this handle
   1815       //
   1816       Status = gBS->HandleProtocol (
   1817                     HandleBuffer[Index],
   1818                     &gEfiPciIoProtocolGuid,
   1819                     (VOID **)&Instance
   1820                     );
   1821       ASSERT_EFI_ERROR (Status);
   1822 
   1823       Status = Instance->Pci.Read (
   1824                     Instance,
   1825                     EfiPciIoWidthUint8,
   1826                     PCI_CLASSCODE_OFFSET,
   1827                     sizeof (USB_CLASSC) / sizeof (UINT8),
   1828                     &UsbClassCReg
   1829                     );
   1830 
   1831       if (EFI_ERROR (Status)) {
   1832         Status = EFI_UNSUPPORTED;
   1833         goto CLOSE_PCIIO;
   1834       }
   1835 
   1836       if ((UsbClassCReg.ProgInterface == PCI_IF_EHCI) &&
   1837            (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&
   1838            (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) {
   1839         Status = Instance->GetLocation (
   1840                     Instance,
   1841                     &EhciSegmentNumber,
   1842                     &EhciBusNumber,
   1843                     &EhciDeviceNumber,
   1844                     &EhciFunctionNumber
   1845                     );
   1846         if (EFI_ERROR (Status)) {
   1847           goto CLOSE_PCIIO;
   1848         }
   1849         //
   1850         // Currently, the judgment on the companion usb host controller is through the
   1851         // same bus number, which may vary on different platform.
   1852         //
   1853         if (EhciBusNumber == CompanionBusNumber) {
   1854           gBS->CloseProtocol (
   1855                     Controller,
   1856                     &gEfiPciIoProtocolGuid,
   1857                     This->DriverBindingHandle,
   1858                     Controller
   1859                     );
   1860           EhcDriverBindingStart(This, HandleBuffer[Index], NULL);
   1861         }
   1862       }
   1863     }
   1864     Status = EFI_NOT_FOUND;
   1865     goto CLOSE_PCIIO;
   1866   }
   1867 
   1868   //
   1869   // Create then install USB2_HC_PROTOCOL
   1870   //
   1871   Ehc = EhcCreateUsb2Hc (PciIo, HcDevicePath, OriginalPciAttributes);
   1872 
   1873   if (Ehc == NULL) {
   1874     DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to create USB2_HC\n"));
   1875 
   1876     Status = EFI_OUT_OF_RESOURCES;
   1877     goto CLOSE_PCIIO;
   1878   }
   1879 
   1880   //
   1881   // Enable 64-bit DMA support in the PCI layer if this controller
   1882   // supports it.
   1883   //
   1884   if (EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT)) {
   1885     Status = PciIo->Attributes (
   1886                       PciIo,
   1887                       EfiPciIoAttributeOperationEnable,
   1888                       EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
   1889                       NULL
   1890                       );
   1891     if (!EFI_ERROR (Status)) {
   1892       Ehc->Support64BitDma = TRUE;
   1893     } else {
   1894       DEBUG ((EFI_D_WARN,
   1895         "%a: failed to enable 64-bit DMA on 64-bit capable controller @ %p (%r)\n",
   1896         __FUNCTION__, Controller, Status));
   1897     }
   1898   }
   1899 
   1900   Status = gBS->InstallProtocolInterface (
   1901                   &Controller,
   1902                   &gEfiUsb2HcProtocolGuid,
   1903                   EFI_NATIVE_INTERFACE,
   1904                   &Ehc->Usb2Hc
   1905                   );
   1906 
   1907   if (EFI_ERROR (Status)) {
   1908     DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to install USB2_HC Protocol\n"));
   1909     goto FREE_POOL;
   1910   }
   1911 
   1912   //
   1913   // Robustnesss improvement such as for Duet platform
   1914   // Default is not required.
   1915   //
   1916   if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {
   1917     EhcClearLegacySupport (Ehc);
   1918   }
   1919 
   1920   if (Ehc->DebugPortNum != 0) {
   1921     State = EhcReadDbgRegister(Ehc, 0);
   1922     if ((State & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) != (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {
   1923       EhcResetHC (Ehc, EHC_RESET_TIMEOUT);
   1924     }
   1925   }
   1926 
   1927   Status = EhcInitHC (Ehc);
   1928 
   1929   if (EFI_ERROR (Status)) {
   1930     DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to init host controller\n"));
   1931     goto UNINSTALL_USBHC;
   1932   }
   1933 
   1934   //
   1935   // Start the asynchronous interrupt monitor
   1936   //
   1937   Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_INTERVAL);
   1938 
   1939   if (EFI_ERROR (Status)) {
   1940     DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to start async interrupt monitor\n"));
   1941 
   1942     EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
   1943     goto UNINSTALL_USBHC;
   1944   }
   1945 
   1946   //
   1947   // Create event to stop the HC when exit boot service.
   1948   //
   1949   Status = gBS->CreateEventEx (
   1950                   EVT_NOTIFY_SIGNAL,
   1951                   TPL_NOTIFY,
   1952                   EhcExitBootService,
   1953                   Ehc,
   1954                   &gEfiEventExitBootServicesGuid,
   1955                   &Ehc->ExitBootServiceEvent
   1956                   );
   1957   if (EFI_ERROR (Status)) {
   1958     goto UNINSTALL_USBHC;
   1959   }
   1960 
   1961   //
   1962   // Install the component name protocol, don't fail the start
   1963   // because of something for display.
   1964   //
   1965   AddUnicodeString2 (
   1966     "eng",
   1967     gEhciComponentName.SupportedLanguages,
   1968     &Ehc->ControllerNameTable,
   1969     L"Enhanced Host Controller (USB 2.0)",
   1970     TRUE
   1971     );
   1972   AddUnicodeString2 (
   1973     "en",
   1974     gEhciComponentName2.SupportedLanguages,
   1975     &Ehc->ControllerNameTable,
   1976     L"Enhanced Host Controller (USB 2.0)",
   1977     FALSE
   1978     );
   1979 
   1980 
   1981   DEBUG ((EFI_D_INFO, "EhcDriverBindingStart: EHCI started for controller @ %p\n", Controller));
   1982   return EFI_SUCCESS;
   1983 
   1984 UNINSTALL_USBHC:
   1985   gBS->UninstallProtocolInterface (
   1986          Controller,
   1987          &gEfiUsb2HcProtocolGuid,
   1988          &Ehc->Usb2Hc
   1989          );
   1990 
   1991 FREE_POOL:
   1992   EhcFreeSched (Ehc);
   1993   gBS->CloseEvent (Ehc->PollTimer);
   1994   gBS->FreePool (Ehc);
   1995 
   1996 CLOSE_PCIIO:
   1997   if (PciAttributesSaved) {
   1998     //
   1999     // Restore original PCI attributes
   2000     //
   2001     PciIo->Attributes (
   2002                     PciIo,
   2003                     EfiPciIoAttributeOperationSet,
   2004                     OriginalPciAttributes,
   2005                     NULL
   2006                     );
   2007   }
   2008 
   2009   gBS->CloseProtocol (
   2010          Controller,
   2011          &gEfiPciIoProtocolGuid,
   2012          This->DriverBindingHandle,
   2013          Controller
   2014          );
   2015 
   2016   return Status;
   2017 }
   2018 
   2019 
   2020 /**
   2021   Stop this driver on ControllerHandle. Support stopping any child handles
   2022   created by this driver.
   2023 
   2024   @param  This                 Protocol instance pointer.
   2025   @param  Controller           Handle of device to stop driver on.
   2026   @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
   2027   @param  ChildHandleBuffer    List of handles for the children we need to stop.
   2028 
   2029   @return EFI_SUCCESS          Success.
   2030   @return EFI_DEVICE_ERROR     Fail.
   2031 
   2032 **/
   2033 EFI_STATUS
   2034 EFIAPI
   2035 EhcDriverBindingStop (
   2036   IN EFI_DRIVER_BINDING_PROTOCOL *This,
   2037   IN EFI_HANDLE                  Controller,
   2038   IN UINTN                       NumberOfChildren,
   2039   IN EFI_HANDLE                  *ChildHandleBuffer
   2040   )
   2041 {
   2042   EFI_STATUS            Status;
   2043   EFI_USB2_HC_PROTOCOL  *Usb2Hc;
   2044   EFI_PCI_IO_PROTOCOL   *PciIo;
   2045   USB2_HC_DEV           *Ehc;
   2046 
   2047   //
   2048   // Test whether the Controller handler passed in is a valid
   2049   // Usb controller handle that should be supported, if not,
   2050   // return the error status directly
   2051   //
   2052   Status = gBS->OpenProtocol (
   2053                   Controller,
   2054                   &gEfiUsb2HcProtocolGuid,
   2055                   (VOID **) &Usb2Hc,
   2056                   This->DriverBindingHandle,
   2057                   Controller,
   2058                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
   2059                   );
   2060 
   2061   if (EFI_ERROR (Status)) {
   2062     return Status;
   2063   }
   2064 
   2065   Ehc   = EHC_FROM_THIS (Usb2Hc);
   2066   PciIo = Ehc->PciIo;
   2067 
   2068   Status = gBS->UninstallProtocolInterface (
   2069                   Controller,
   2070                   &gEfiUsb2HcProtocolGuid,
   2071                   Usb2Hc
   2072                   );
   2073 
   2074   if (EFI_ERROR (Status)) {
   2075     return Status;
   2076   }
   2077 
   2078   //
   2079   // Stop AsyncRequest Polling timer then stop the EHCI driver
   2080   // and uninstall the EHCI protocl.
   2081   //
   2082   gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL);
   2083   EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
   2084 
   2085   if (Ehc->PollTimer != NULL) {
   2086     gBS->CloseEvent (Ehc->PollTimer);
   2087   }
   2088 
   2089   if (Ehc->ExitBootServiceEvent != NULL) {
   2090     gBS->CloseEvent (Ehc->ExitBootServiceEvent);
   2091   }
   2092 
   2093   EhcFreeSched (Ehc);
   2094 
   2095   if (Ehc->ControllerNameTable != NULL) {
   2096     FreeUnicodeStringTable (Ehc->ControllerNameTable);
   2097   }
   2098 
   2099   //
   2100   // Disable routing of all ports to EHCI controller, so all ports are
   2101   // routed back to the UHCI or OHCI controller.
   2102   //
   2103   EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);
   2104 
   2105   //
   2106   // Restore original PCI attributes
   2107   //
   2108   PciIo->Attributes (
   2109                   PciIo,
   2110                   EfiPciIoAttributeOperationSet,
   2111                   Ehc->OriginalPciAttributes,
   2112                   NULL
   2113                   );
   2114 
   2115   gBS->CloseProtocol (
   2116          Controller,
   2117          &gEfiPciIoProtocolGuid,
   2118          This->DriverBindingHandle,
   2119          Controller
   2120          );
   2121 
   2122   FreePool (Ehc);
   2123 
   2124   return EFI_SUCCESS;
   2125 }
   2126 
   2127