]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Skip to manage usb debug port in EDKII EHCI driver if it's used by...
authorerictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 28 Apr 2012 05:02:54 +0000 (05:02 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 28 Apr 2012 05:02:54 +0000 (05:02 +0000)
Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13226 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h

index c141803c388071bab53b82cb7c7ade936e588abf..64a0943ddcb952812d0212138d3c4af2990eff88 100644 (file)
@@ -120,6 +120,7 @@ EhcReset (
   USB2_HC_DEV             *Ehc;\r
   EFI_TPL                 OldTpl;\r
   EFI_STATUS              Status;\r
+  UINT32                  DbgCtrlStatus;\r
 \r
   OldTpl  = gBS->RaiseTPL (EHC_TPL);\r
   Ehc     = EHC_FROM_THIS (This);\r
@@ -133,6 +134,14 @@ EhcReset (
     //\r
     // Host Controller must be Halt when Reset it\r
     //\r
+    if (Ehc->DebugPortNum != 0) {\r
+      DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0);\r
+      if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {\r
+        Status = EFI_SUCCESS;\r
+        goto ON_EXIT;\r
+      }\r
+    }\r
+\r
     if (!EhcIsHalt (Ehc)) {\r
       Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
 \r
@@ -323,6 +332,7 @@ EhcGetRootHubPortStatus (
   UINTN                   Index;\r
   UINTN                   MapSize;\r
   EFI_STATUS              Status;\r
+  UINT32                  DbgCtrlStatus;\r
 \r
   if (PortStatus == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -344,6 +354,13 @@ EhcGetRootHubPortStatus (
   PortStatus->PortStatus        = 0;\r
   PortStatus->PortChangeStatus  = 0;\r
 \r
+  if ((Ehc->DebugPortNum != 0) && (PortNumber == (Ehc->DebugPortNum - 1))) {\r
+    DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0);\r
+    if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+\r
   State                         = EhcReadOpReg (Ehc, Offset);\r
 \r
   //\r
@@ -1390,6 +1407,129 @@ ON_EXIT:
   return Status;\r
 }\r
 \r
+/**\r
+  Get the usb debug port related information.\r
+\r
+  @param  Ehc                The EHCI device.\r
+\r
+  @retval RETURN_SUCCESS     Get debug port number, bar and offset successfully.\r
+  @retval Others             The usb host controller does not supported usb debug port capability.\r
+\r
+**/\r
+EFI_STATUS\r
+EhcGetUsbDebugPortInfo (\r
+  IN  USB2_HC_DEV     *Ehc\r
+ )\r
+{\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  UINT16              PciStatus;\r
+  UINT8               CapabilityPtr;\r
+  UINT8               CapabilityId;\r
+  UINT16              DebugPort;\r
+  EFI_STATUS          Status;\r
+\r
+  ASSERT (Ehc->PciIo != NULL);\r
+  PciIo = Ehc->PciIo;\r
+\r
+  //\r
+  // Detect if the EHCI host controller support Capaility Pointer.\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        PCI_PRIMARY_STATUS_OFFSET,\r
+                        sizeof (UINT16),\r
+                        &PciStatus\r
+                        );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) {\r
+    //\r
+    // The Pci Device Doesn't Support Capability Pointer.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get Pointer To Capability List\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        PCI_CAPBILITY_POINTER_OFFSET,\r
+                        1,\r
+                        &CapabilityPtr\r
+                        );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Find Capability ID 0xA, Which Is For Debug Port\r
+  //\r
+  while (CapabilityPtr != 0) {\r
+    Status = PciIo->Pci.Read (\r
+                          PciIo,\r
+                          EfiPciIoWidthUint8,\r
+                          CapabilityPtr,\r
+                          1,\r
+                          &CapabilityId\r
+                          );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    if (CapabilityId == EHC_DEBUG_PORT_CAP_ID) {\r
+      break;\r
+    }\r
+\r
+    Status = PciIo->Pci.Read (\r
+                          PciIo,\r
+                          EfiPciIoWidthUint8,\r
+                          CapabilityPtr + 1,\r
+                          1,\r
+                          &CapabilityPtr\r
+                          );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // No Debug Port Capability Found\r
+  //\r
+  if (CapabilityPtr == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get The Base Address Of Debug Port Register In Debug Port Capability Register\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        Ehc->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        CapabilityPtr + 2,\r
+                        sizeof (UINT16),\r
+                        &DebugPort\r
+                        );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Ehc->DebugPortOffset = DebugPort & 0x1FFF;\r
+  Ehc->DebugPortBarNum = (DebugPort >> 13) - 1;\r
+  Ehc->DebugPortNum    = (UINT8)((Ehc->HcStructParams & 0x00F00000) >> 20);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 \r
 /**\r
   Create and initialize a USB2_HC_DEV.\r
@@ -1455,6 +1595,8 @@ EhcCreateUsb2Hc (
     gBS->FreePool (Ehc);\r
     return NULL;\r
   }\r
+  \r
+  EhcGetUsbDebugPortInfo (Ehc);\r
 \r
   //\r
   // Create AsyncRequest Polling Timer\r
@@ -1541,6 +1683,7 @@ EhcDriverBindingStart (
   UINTN                   EhciBusNumber;\r
   UINTN                   EhciDeviceNumber;\r
   UINTN                   EhciFunctionNumber;\r
+  UINT32                  State;\r
 \r
   //\r
   // Open the PciIo Protocol, then enable the USB host controller\r
@@ -1727,7 +1870,13 @@ EhcDriverBindingStart (
   if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {\r
     EhcClearLegacySupport (Ehc);\r
   }\r
-  EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+\r
+  if (Ehc->DebugPortNum != 0) {\r
+    State = EhcReadDbgRegister(Ehc, 0);\r
+    if ((State & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) != (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {\r
+      EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+    }\r
+  }\r
 \r
   Status = EhcInitHC (Ehc);\r
 \r
index f8d5444c38d3a6c86700f99fc6b28da007842fb2..42e4a6e6d9c7bdf7d5c632a7c98fecc0393108ab 100644 (file)
@@ -2,7 +2,7 @@
 \r
   Provides some data struct used by EHCI controller driver.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -70,11 +70,18 @@ typedef struct _USB2_HC_DEV  USB2_HC_DEV;
 #define EHC_SYNC_POLL_INTERVAL       (1 * EHC_1_MILLISECOND)\r
 #define EHC_ASYNC_POLL_INTERVAL      (50 * 10000U)\r
 \r
+//\r
+// EHCI debug port control status register bit definition\r
+//\r
+#define USB_DEBUG_PORT_IN_USE        BIT10\r
+#define USB_DEBUG_PORT_ENABLE        BIT28\r
+#define USB_DEBUG_PORT_OWNER         BIT30\r
+\r
 //\r
 // EHC raises TPL to TPL_NOTIFY to serialize all its operations\r
 // to protect shared data structures.\r
 //\r
-#define  EHC_TPL                TPL_NOTIFY\r
+#define  EHC_TPL                     TPL_NOTIFY\r
 \r
 //\r
 //Iterate through the doule linked list. NOT delete safe\r
@@ -157,6 +164,13 @@ struct _USB2_HC_DEV {
   // Misc\r
   //\r
   EFI_UNICODE_STRING_TABLE  *ControllerNameTable;\r
+\r
+  //\r
+  // EHCI debug port info\r
+  //\r
+  UINT16                    DebugPortOffset; // The offset of debug port mmio register\r
+  UINT8                     DebugPortBarNum; // The bar number of debug port mmio register\r
+  UINT8                     DebugPortNum;    // The port number of usb debug port\r
 };\r
 \r
 \r
index 252e3d5fa2dc1f0a9976f33899385afeb5ed6969..88a66aee71028ced1cf80bc1eac4d8a20e59c1c9 100644 (file)
@@ -2,7 +2,7 @@
 \r
   The EHCI register operation routines.\r
 \r
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -53,6 +53,42 @@ EhcReadCapRegister (
   return Data;\r
 }\r
 \r
+/**\r
+  Read EHCI debug port register.\r
+\r
+  @param  Ehc          The EHCI device.\r
+  @param  Offset       Debug port register offset.\r
+\r
+  @return The register content read.\r
+  @retval If err, return 0xffff.\r
+\r
+**/\r
+UINT32\r
+EhcReadDbgRegister (\r
+  IN  USB2_HC_DEV         *Ehc,\r
+  IN  UINT32              Offset\r
+  )\r
+{\r
+  UINT32                  Data;\r
+  EFI_STATUS              Status;\r
+\r
+  Status = Ehc->PciIo->Mem.Read (\r
+                             Ehc->PciIo,\r
+                             EfiPciIoWidthUint32,\r
+                             Ehc->DebugPortBarNum,\r
+                             (UINT64) (Ehc->DebugPortOffset + Offset),\r
+                             1,\r
+                             &Data\r
+                             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "EhcReadDbgRegister: Pci Io read error - %r at %d\n", Status, Offset));\r
+    Data = 0xFFFF;\r
+  }\r
+\r
+  return Data;\r
+}\r
+\r
 \r
 /**\r
   Read EHCI Operation register.\r
index d1f38d38f0e3d77521553dfd927ee5b84f965ae9..2347ee125fa72f95b35dddbd79f865e16e130c48 100644 (file)
@@ -2,7 +2,7 @@
 \r
   This file contains the definination for host controller register operation routines.\r
 \r
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -89,6 +89,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 #define EHC_BAR_INDEX           0      // how many bytes away from USB_BASE to 0x10\r
 \r
+//\r
+// Debug port capability id\r
+//\r
+#define EHC_DEBUG_PORT_CAP_ID   0x0A\r
+\r
 #define EHC_LINK_TERMINATED(Link) (((Link) & 0x01) != 0)\r
 \r
 #define EHC_ADDR(High, QhHw32)   \\r
@@ -131,6 +136,21 @@ EhcReadCapRegister (
   IN  UINT32              Offset\r
   );\r
 \r
+/**\r
+  Read EHCI debug port register.\r
+\r
+  @param  Ehc          The EHCI device.\r
+  @param  Offset       Debug port register address.\r
+\r
+  @return The register content read.\r
+  @retval If err, return 0xffff.\r
+\r
+**/\r
+UINT32\r
+EhcReadDbgRegister (\r
+  IN  USB2_HC_DEV         *Ehc,\r
+  IN  UINT32              Offset\r
+  );\r
 \r
 /**\r
   Read EHCI Operation register.\r