]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Virtio10Dxe/Virtio10.c
OvmfPkg/Virtio10Dxe: convert to PciCapLib
[mirror_edk2.git] / OvmfPkg / Virtio10Dxe / Virtio10.c
index e9b50b6e437b268456840e8f3ab11dab34edfe15..9ebb72c76bfdac65f2532b3caa4183d2c68d9881 100644 (file)
@@ -21,6 +21,8 @@
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
+#include <Library/PciCapLib.h>\r
+#include <Library/PciCapPciIoLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiLib.h>\r
 \r
@@ -184,48 +186,6 @@ GetBarType (
 }\r
 \r
 \r
-/**\r
-  Read a slice from PCI config space at the given offset, then advance the\r
-  offset.\r
-\r
-  @param [in]     PciIo   The EFI_PCI_IO_PROTOCOL instance that represents the\r
-                          device.\r
-\r
-  @param [in,out] Offset  On input, the offset in PCI config space to start\r
-                          reading from. On output, the offset of the first byte\r
-                          that was not read. On error, Offset is not modified.\r
-\r
-  @param [in]     Size    The number of bytes to read.\r
-\r
-  @param [out]    Buffer  On output, the bytes read from PCI config space are\r
-                          stored in this object.\r
-\r
-  @retval EFI_SUCCESS  Size bytes have been transferred from PCI config space\r
-                       (from Offset) to Buffer, and Offset has been incremented\r
-                       by Size.\r
-\r
-  @return              Error codes from PciIo->Pci.Read().\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-ReadConfigSpace (\r
-  IN     EFI_PCI_IO_PROTOCOL *PciIo,\r
-  IN OUT UINT32              *Offset,\r
-  IN     UINTN               Size,\r
-     OUT VOID                *Buffer\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, *Offset, Size, Buffer);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  *Offset += (UINT32)Size;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
 /*\r
   Traverse the PCI capabilities list of a virtio-1.0 device, and capture the\r
   locations of the interesting virtio-1.0 register blocks.\r
@@ -239,57 +199,51 @@ ReadConfigSpace (
                                 will have been updated from the PCI\r
                                 capabilities found.\r
 \r
-  @param[in]     CapabilityPtr  The offset of the first capability in PCI\r
-                                config space, taken from the standard PCI\r
-                                device header.\r
-\r
   @retval EFI_SUCCESS  Traversal successful.\r
 \r
-  @return              Error codes from the ReadConfigSpace() and GetBarType()\r
-                       helper functions.\r
+  @return              Error codes from PciCapPciIoLib, PciCapLib, and the\r
+                       GetBarType() helper function.\r
 */\r
 STATIC\r
 EFI_STATUS\r
 ParseCapabilities (\r
-  IN OUT VIRTIO_1_0_DEV *Device,\r
-  IN     UINT8          CapabilityPtr\r
+  IN OUT VIRTIO_1_0_DEV *Device\r
   )\r
 {\r
-  UINT32              Offset;\r
-  VIRTIO_PCI_CAP_LINK CapLink;\r
-\r
-  for (Offset = CapabilityPtr & 0xFC;\r
-       Offset > 0;\r
-       Offset = CapLink.CapNext & 0xFC\r
-       ) {\r
-    EFI_STATUS        Status;\r
+  EFI_STATUS   Status;\r
+  PCI_CAP_DEV  *PciDevice;\r
+  PCI_CAP_LIST *CapList;\r
+  UINT16       VendorInstance;\r
+  PCI_CAP      *VendorCap;\r
+\r
+  Status = PciCapPciIoDeviceInit (Device->PciIo, &PciDevice);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = PciCapListInit (PciDevice, &CapList);\r
+  if (EFI_ERROR (Status)) {\r
+    goto UninitPciDevice;\r
+  }\r
+\r
+  for (VendorInstance = 0;\r
+       !EFI_ERROR (PciCapListFindCap (CapList, PciCapNormal,\r
+                     EFI_PCI_CAPABILITY_ID_VENDOR, VendorInstance,\r
+                     &VendorCap));\r
+       VendorInstance++) {\r
     UINT8             CapLen;\r
     VIRTIO_PCI_CAP    VirtIoCap;\r
     VIRTIO_1_0_CONFIG *ParsedConfig;\r
 \r
-    //\r
-    // Read capability identifier and link to next capability.\r
-    //\r
-    Status = ReadConfigSpace (Device->PciIo, &Offset, sizeof CapLink,\r
-               &CapLink);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    if (CapLink.CapId != 0x09) {\r
-      //\r
-      // Not a vendor-specific capability, move to the next one.\r
-      //\r
-      continue;\r
-    }\r
-\r
     //\r
     // Big enough to accommodate a VIRTIO_PCI_CAP structure?\r
     //\r
-    Status = ReadConfigSpace (Device->PciIo, &Offset, sizeof CapLen, &CapLen);\r
+    Status = PciCapRead (PciDevice, VendorCap,\r
+               OFFSET_OF (EFI_PCI_CAPABILITY_VENDOR_HDR, Length), &CapLen,\r
+               sizeof CapLen);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto UninitCapList;\r
     }\r
-    if (CapLen < sizeof CapLink + sizeof CapLen + sizeof VirtIoCap) {\r
+    if (CapLen < sizeof VirtIoCap) {\r
       //\r
       // Too small, move to next.\r
       //\r
@@ -299,11 +253,11 @@ ParseCapabilities (
     //\r
     // Read interesting part of capability.\r
     //\r
-    Status = ReadConfigSpace (Device->PciIo, &Offset, sizeof VirtIoCap,\r
-               &VirtIoCap);\r
+    Status = PciCapRead (PciDevice, VendorCap, 0, &VirtIoCap, sizeof VirtIoCap);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto UninitCapList;\r
     }\r
+\r
     switch (VirtIoCap.ConfigType) {\r
     case VIRTIO_PCI_CAP_COMMON_CFG:\r
       ParsedConfig = &Device->CommonConfig;\r
@@ -326,7 +280,7 @@ ParseCapabilities (
     //\r
     Status = GetBarType (Device->PciIo, VirtIoCap.Bar, &ParsedConfig->BarType);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto UninitCapList;\r
     }\r
     ParsedConfig->Bar    = VirtIoCap.Bar;\r
     ParsedConfig->Offset = VirtIoCap.Offset;\r
@@ -337,19 +291,18 @@ ParseCapabilities (
       // This capability has an additional field called NotifyOffsetMultiplier;\r
       // parse it too.\r
       //\r
-      if (CapLen < sizeof CapLink + sizeof CapLen + sizeof VirtIoCap +\r
-                   sizeof Device->NotifyOffsetMultiplier) {\r
+      if (CapLen < sizeof VirtIoCap + sizeof Device->NotifyOffsetMultiplier) {\r
         //\r
         // Too small, move to next.\r
         //\r
         continue;\r
       }\r
 \r
-      Status = ReadConfigSpace (Device->PciIo, &Offset,\r
-                 sizeof Device->NotifyOffsetMultiplier,\r
-                 &Device->NotifyOffsetMultiplier);\r
+      Status = PciCapRead (PciDevice, VendorCap, sizeof VirtIoCap,\r
+                 &Device->NotifyOffsetMultiplier,\r
+                 sizeof Device->NotifyOffsetMultiplier);\r
       if (EFI_ERROR (Status)) {\r
-        return Status;\r
+        goto UninitCapList;\r
       }\r
     }\r
 \r
@@ -359,7 +312,15 @@ ParseCapabilities (
     ParsedConfig->Exists = TRUE;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+UninitCapList:\r
+  PciCapListUninit (CapList);\r
+\r
+UninitPciDevice:\r
+  PciCapPciIoDeviceUninit (PciDevice);\r
+\r
+  return Status;\r
 }\r
 \r
 \r
@@ -1015,7 +976,7 @@ Virtio10BindingStart (
 \r
   Device->VirtIo.SubSystemDeviceId = Pci.Hdr.DeviceId - 0x1040;\r
 \r
-  Status = ParseCapabilities (Device, Pci.Device.CapabilityPtr);\r
+  Status = ParseCapabilities (Device);\r
   if (EFI_ERROR (Status)) {\r
     goto ClosePciIo;\r
   }\r