]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
MdeModulePkg/Bus/Pci/XhciDxe: Check port is compatible before getting PSIV
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciReg.c
index 2b4a4b2444e5a39f3e4255293c9ce154abc2da5e..5700fc5fb89b5fe014f74fe03b5af5d0139392df 100644 (file)
@@ -636,6 +636,7 @@ XhcGetSupportedProtocolCapabilityAddr (
   @param  Xhc            The XHCI Instance.\r
   @param  ExtCapOffset   The USB Major Version in xHCI Support Protocol Capability Field\r
   @param  PortSpeed      The Port Speed Field in USB PortSc register\r
+  @param  PortNumber     The Port Number (0-indexed)\r
 \r
   @return The Protocol Speed ID (PSI) from xHCI Supported Protocol capability register.\r
 \r
@@ -644,12 +645,15 @@ UINT32
 XhciPsivGetPsid (\r
   IN USB_XHCI_INSTANCE  *Xhc,\r
   IN UINT32             ExtCapOffset,\r
-  IN UINT8              PortSpeed\r
+  IN UINT8              PortSpeed,\r
+  IN UINT8              PortNumber\r
   )\r
 {\r
   XHC_SUPPORTED_PROTOCOL_DW2                PortId;\r
   XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID  Reg;\r
   UINT32                                    Count;\r
+  UINT32                                    MinPortIndex;\r
+  UINT32                                    MaxPortIndex;\r
 \r
   if ((Xhc == NULL) || (ExtCapOffset == 0xFFFFFFFF)) {\r
     return 0;\r
@@ -663,6 +667,23 @@ XhciPsivGetPsid (
   //\r
   PortId.Dword = XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PROTOCOL_DW2_OFFSET);\r
 \r
+  //\r
+  // According to XHCI 1.1 spec November 2017, valid values\r
+  // for CompPortOffset are 1 to CompPortCount - 1.\r
+  //\r
+  // PortNumber is zero-indexed, so subtract 1.\r
+  //\r
+  if ((PortId.Data.CompPortOffset == 0) || (PortId.Data.CompPortCount == 0)) {\r
+    return 0;\r
+  }\r
+\r
+  MinPortIndex = PortId.Data.CompPortOffset - 1;\r
+  MaxPortIndex = MinPortIndex + PortId.Data.CompPortCount - 1;\r
+\r
+  if ((PortNumber < MinPortIndex) || (PortNumber > MaxPortIndex)) {\r
+    return 0;\r
+  }\r
+\r
   for (Count = 0; Count < PortId.Data.Psic; Count++) {\r
     Reg.Dword = XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PROTOCOL_PSI_OFFSET + (Count << 2));\r
     if (Reg.Data.Psiv == PortSpeed) {\r
@@ -676,8 +697,9 @@ XhciPsivGetPsid (
 /**\r
   Find PortSpeed value match case in XHCI Supported Protocol Capability\r
 \r
-  @param  Xhc        The XHCI Instance.\r
-  @param  PortSpeed  The Port Speed Field in USB PortSc register\r
+  @param  Xhc         The XHCI Instance.\r
+  @param  PortSpeed   The Port Speed Field in USB PortSc register\r
+  @param  PortNumber  The Port Number (0-indexed)\r
 \r
   @return The USB Port Speed.\r
 \r
@@ -685,7 +707,8 @@ XhciPsivGetPsid (
 UINT16\r
 XhcCheckUsbPortSpeedUsedPsic (\r
   IN USB_XHCI_INSTANCE  *Xhc,\r
-  IN UINT8              PortSpeed\r
+  IN UINT8              PortSpeed,\r
+  IN UINT8              PortNumber\r
   )\r
 {\r
   XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID  SpField;\r
@@ -703,7 +726,7 @@ XhcCheckUsbPortSpeedUsedPsic (
   // PortSpeed definition when the Major Revision is 03h.\r
   //\r
   if (Xhc->Usb3SupOffset != 0xFFFFFFFF) {\r
-    SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed);\r
+    SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed, PortNumber);\r
     if (SpField.Dword != 0) {\r
       //\r
       // Found the corresponding PORTSC value in PSIV field of USB3 offset.\r
@@ -717,7 +740,7 @@ XhcCheckUsbPortSpeedUsedPsic (
   // PortSpeed definition when the Major Revision is 02h.\r
   //\r
   if ((UsbSpeedIdMap == 0) && (Xhc->Usb2SupOffset != 0xFFFFFFFF)) {\r
-    SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb2SupOffset, PortSpeed);\r
+    SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb2SupOffset, PortSpeed, PortNumber);\r
     if (SpField.Dword != 0) {\r
       //\r
       // Found the corresponding PORTSC value in PSIV field of USB2 offset.\r