Save original PCI attributes in start() function and restore it in Stop() for those...
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / EhciDxe / Ehci.c
index 093388d..32ae6b6 100644 (file)
@@ -126,7 +126,7 @@ EhcReset (
     // Host Controller must be Halt when Reset it\r
     //\r
     if (!EhcIsHalt (Ehc)) {\r
-      Status = EhcHaltHC (Ehc, EHC_GENERIC_TIME);\r
+      Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
 \r
       if (EFI_ERROR (Status)) {\r
         Status = EFI_DEVICE_ERROR;\r
@@ -142,7 +142,7 @@ EhcReset (
     EhcAckAllInterrupt (Ehc);\r
     EhcFreeSched (Ehc);\r
 \r
-    Status = EhcResetHC (Ehc, EHC_STALL_1_SECOND);\r
+    Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
 \r
     if (EFI_ERROR (Status)) {\r
       goto ON_EXIT;\r
@@ -251,7 +251,7 @@ EhcSetState (
 \r
   switch (State) {\r
   case EfiUsbHcStateHalt:\r
-    Status = EhcHaltHC (Ehc, EHC_GENERIC_TIME);\r
+    Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
     break;\r
 \r
   case EfiUsbHcStateOperational:\r
@@ -260,7 +260,17 @@ EhcSetState (
       break;\r
     }\r
 \r
-    Status = EhcRunHC (Ehc, EHC_GENERIC_TIME);\r
+    //\r
+    // Software must not write a one to this field unless the host controller\r
+    // is in the Halted state. Doing so will yield undefined results.\r
+    // refers to Spec[EHCI1.0-2.3.1]\r
+    //\r
+    if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      break;\r
+    }\r
+\r
+    Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
     break;\r
 \r
   case EfiUsbHcStateSuspend:\r
@@ -351,7 +361,7 @@ EhcGetRootHubPortStatus (
 \r
   for (Index = 0; Index < MapSize; Index++) {\r
     if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) {\r
-      PortStatus->PortStatus |= mUsbPortStateMap[Index].UefiState;\r
+      PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);\r
     }\r
   }\r
 \r
@@ -359,7 +369,7 @@ EhcGetRootHubPortStatus (
 \r
   for (Index = 0; Index < MapSize; Index++) {\r
     if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) {\r
-      PortStatus->PortChangeStatus |= mUsbPortChangeMap[Index].UefiState;\r
+      PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);\r
     }\r
   }\r
 \r
@@ -437,7 +447,7 @@ EhcSetRootHubPortFeature (
     // Make sure Host Controller not halt before reset it\r
     //\r
     if (EhcIsHalt (Ehc)) {\r
-      Status = EhcRunHC (Ehc, EHC_GENERIC_TIME);\r
+      Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
 \r
       if (EFI_ERROR (Status)) {\r
         EHC_DEBUG (("EhcSetRootHubPortFeature :failed to start HC - %r\n", Status));\r
@@ -707,7 +717,7 @@ EhcControlTransfer (
   // endpoint is bidirectional. EhcCreateUrb expects this\r
   // combination of Ep addr and its direction.\r
   //\r
-  Endpoint = 0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0);\r
+  Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));\r
   Urb = EhcCreateUrb (\r
           Ehc,\r
           DeviceAddress,\r
@@ -1271,8 +1281,6 @@ EhcAsyncIsochronousTransfer (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-//@MT: EFI_DRIVER_ENTRY_POINT (EhcDriverEntryPoint)\r
-\r
 EFI_STATUS\r
 EFIAPI\r
 EhcDriverEntryPoint (\r
@@ -1297,14 +1305,13 @@ Returns:
 \r
 --*/\r
 {\r
-  return EfiLibInstallAllDriverProtocols (\r
+  return EfiLibInstallDriverBindingComponentName2 (\r
            ImageHandle,\r
            SystemTable,\r
            &gEhciDriverBinding,\r
            ImageHandle,\r
            &gEhciComponentName,\r
-           NULL,\r
-           NULL\r
+           &gEhciComponentName2\r
            );\r
 }\r
 \r
@@ -1340,7 +1347,7 @@ EhcDriverBindingSupported (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiPciIoProtocolGuid,\r
-                  &PciIo,\r
+                  (VOID **) &PciIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -1388,7 +1395,8 @@ ON_EXIT:
 /**\r
   Create and initialize a USB2_HC_DEV\r
 \r
-  @param  PciIo                The PciIo on this device\r
+  @param  PciIo                  The PciIo on this device\r
+  @param  OriginalPciAttributes  Original PCI attributes\r
 \r
   @return The allocated and initialized USB2_HC_DEV structure\r
   @return if created, otherwise NULL.\r
@@ -1397,7 +1405,8 @@ ON_EXIT:
 STATIC\r
 USB2_HC_DEV *\r
 EhcCreateUsb2Hc (\r
-  IN EFI_PCI_IO_PROTOCOL  *PciIo\r
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN UINT64               OriginalPciAttributes\r
   )\r
 {\r
   USB2_HC_DEV             *Ehc;\r
@@ -1430,7 +1439,8 @@ EhcCreateUsb2Hc (
   Ehc->Usb2Hc.MajorRevision             = 0x1;\r
   Ehc->Usb2Hc.MinorRevision             = 0x1;\r
 \r
-  Ehc->PciIo = PciIo;\r
+  Ehc->PciIo                 = PciIo;\r
+  Ehc->OriginalPciAttributes = OriginalPciAttributes;\r
 \r
   InitializeListHead (&Ehc->AsyncIntTransfers);\r
 \r
@@ -1484,6 +1494,8 @@ EhcDriverBindingStart (
   EFI_STATUS              Status;\r
   USB2_HC_DEV             *Ehc;\r
   EFI_PCI_IO_PROTOCOL     *PciIo;\r
+  UINT64                  Supports;\r
+  UINT64                  OriginalPciAttributes;\r
 \r
   //\r
   // Open the PciIo Protocol, then enable the USB host controller\r
@@ -1491,7 +1503,7 @@ EhcDriverBindingStart (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiPciIoProtocolGuid,\r
-                  &PciIo,\r
+                  (VOID **) &PciIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -1502,12 +1514,35 @@ EhcDriverBindingStart (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  //\r
+  // Save original PCI attributes\r
+  //\r
+  Status = PciIo->Attributes (\r
+                    PciIo,\r
+                    EfiPciIoAttributeOperationGet,\r
+                    0,\r
+                    &OriginalPciAttributes\r
+                    );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Status = PciIo->Attributes (\r
                     PciIo,\r
-                    EfiPciIoAttributeOperationEnable,\r
-                    EFI_PCI_DEVICE_ENABLE,\r
-                    NULL\r
+                    EfiPciIoAttributeOperationSupported,\r
+                    0,\r
+                    &Supports\r
                     );\r
+  if (!EFI_ERROR (Status)) {\r
+    Supports &= EFI_PCI_DEVICE_ENABLE;\r
+    Status = PciIo->Attributes (\r
+                      PciIo,\r
+                      EfiPciIoAttributeOperationEnable,\r
+                      Supports,\r
+                      NULL\r
+                      );\r
+  }\r
 \r
   if (EFI_ERROR (Status)) {\r
     EHC_ERROR (("EhcDriverBindingStart: failed to enable controller\n"));\r
@@ -1517,7 +1552,7 @@ EhcDriverBindingStart (
   //\r
   // Create then install USB2_HC_PROTOCOL\r
   //\r
-  Ehc = EhcCreateUsb2Hc (PciIo);\r
+  Ehc = EhcCreateUsb2Hc (PciIo, OriginalPciAttributes);\r
 \r
   if (Ehc == NULL) {\r
     EHC_ERROR (("EhcDriverBindingStart: failed to create USB2_HC\n"));\r
@@ -1542,7 +1577,7 @@ EhcDriverBindingStart (
   // Robustnesss improvement such as for UoL\r
   //\r
   EhcClearLegacySupport (Ehc);\r
-  EhcResetHC (Ehc, EHC_STALL_1_SECOND);\r
+  EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
 \r
   Status = EhcInitHC (Ehc);\r
 \r
@@ -1554,12 +1589,12 @@ EhcDriverBindingStart (
   //\r
   // Start the asynchronous interrupt monitor\r
   //\r
-  Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_TIME);\r
+  Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_INTERVAL);\r
 \r
   if (EFI_ERROR (Status)) {\r
     EHC_ERROR (("EhcDriverBindingStart: failed to start async interrupt monitor\n"));\r
 \r
-    EhcHaltHC (Ehc, EHC_GENERIC_TIME);\r
+    EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
     goto UNINSTALL_USBHC;\r
   }\r
 \r
@@ -1567,13 +1602,22 @@ EhcDriverBindingStart (
   // Install the component name protocol, don't fail the start\r
   // because of something for display.\r
   //\r
-  AddUnicodeString (\r
+  AddUnicodeString2 (\r
     "eng",\r
     gEhciComponentName.SupportedLanguages,\r
     &Ehc->ControllerNameTable,\r
-    L"Enhanced Host Controller (USB 2.0)"\r
+    L"Enhanced Host Controller (USB 2.0)",\r
+    TRUE\r
+    );\r
+  AddUnicodeString2 (\r
+    "en",\r
+    gEhciComponentName2.SupportedLanguages,\r
+    &Ehc->ControllerNameTable,\r
+    L"Enhanced Host Controller (USB 2.0)",\r
+    FALSE\r
     );\r
 \r
+\r
   EHC_DEBUG (("EhcDriverBindingStart: EHCI started for controller @ %x\n", Controller));\r
   return EFI_SUCCESS;\r
 \r
@@ -1590,6 +1634,16 @@ FREE_POOL:
   gBS->FreePool (Ehc);\r
 \r
 CLOSE_PCIIO:\r
+  //\r
+  // Restore original PCI attributes\r
+  //\r
+  PciIo->Attributes (\r
+                  PciIo,\r
+                  EfiPciIoAttributeOperationSet,\r
+                  OriginalPciAttributes,\r
+                  NULL\r
+                  );\r
+\r
   gBS->CloseProtocol (\r
          Controller,\r
          &gEfiPciIoProtocolGuid,\r
@@ -1636,7 +1690,7 @@ EhcDriverBindingStop (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiUsb2HcProtocolGuid,\r
-                  &Usb2Hc,\r
+                  (VOID **) &Usb2Hc,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -1653,8 +1707,8 @@ EhcDriverBindingStop (
   // Stop AsyncRequest Polling timer then stop the EHCI driver\r
   // and uninstall the EHCI protocl.\r
   //\r
-  gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_TIME);\r
-  EhcHaltHC (Ehc, EHC_GENERIC_TIME);\r
+  gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL);\r
+  EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
 \r
   Status = gBS->UninstallProtocolInterface (\r
                   Controller,\r
@@ -1677,14 +1731,14 @@ EhcDriverBindingStop (
   }\r
 \r
   //\r
-  // Disable the USB Host Controller\r
+  // Restore original PCI attributes\r
   //\r
   PciIo->Attributes (\r
-           PciIo,\r
-           EfiPciIoAttributeOperationDisable,\r
-           EFI_PCI_DEVICE_ENABLE,\r
-           NULL\r
-           );\r
+                  PciIo,\r
+                  EfiPciIoAttributeOperationSet,\r
+                  Ehc->OriginalPciAttributes,\r
+                  NULL\r
+                  );\r
 \r
   gBS->CloseProtocol (\r
          Controller,\r
@@ -1693,8 +1747,9 @@ EhcDriverBindingStop (
          Controller\r
          );\r
 \r
-  gBS->FreePool (Ehc);\r
-  return Status;\r
+  FreePool (Ehc);\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL\r