]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/PvScsiDxe/PvScsi.c
OvmfPkg/PvScsiDxe: Refactor setup of rings to separate function
[mirror_edk2.git] / OvmfPkg / PvScsiDxe / PvScsi.c
index d7f0d3c8790c93e465947c3e67d2a268c52c69d1..843534ebf71103fee18381a96be17cca48f746e9 100644 (file)
@@ -455,8 +455,12 @@ HandleResponse (
 \r
   //\r
   // Report target status\r
+  // (Strangely, PVSCSI interface defines Response->ScsiStatus as UINT16.\r
+  // But it should de-facto always have a value that fits UINT8. To avoid\r
+  // unexpected behavior, verify value is in UINT8 bounds before casting)\r
   //\r
-  Packet->TargetStatus = Response->ScsiStatus;\r
+  ASSERT (Response->ScsiStatus <= MAX_UINT8);\r
+  Packet->TargetStatus = (UINT8)Response->ScsiStatus;\r
 \r
   //\r
   // Host adapter status and function return value depend on\r
@@ -874,6 +878,29 @@ PvScsiSetPciAttributes (
     return Status;\r
   }\r
 \r
+  //\r
+  // Signal device supports 64-bit DMA addresses\r
+  //\r
+  Status = Dev->PciIo->Attributes (\r
+                         Dev->PciIo,\r
+                         EfiPciIoAttributeOperationEnable,\r
+                         EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,\r
+                         NULL\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Warn user that device will only be using 32-bit DMA addresses.\r
+    //\r
+    // Note that this does not prevent the device/driver from working\r
+    // and therefore we only warn and continue as usual.\r
+    //\r
+    DEBUG ((\r
+      DEBUG_WARN,\r
+      "%a: failed to enable 64-bit DMA addresses\n",\r
+      __FUNCTION__\r
+      ));\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -964,13 +991,6 @@ PvScsiInitRings (
   )\r
 {\r
   EFI_STATUS Status;\r
-  union {\r
-    PVSCSI_CMD_DESC_SETUP_RINGS Cmd;\r
-    UINT32                      Uint32;\r
-  } AlignedCmd;\r
-  PVSCSI_CMD_DESC_SETUP_RINGS *Cmd;\r
-\r
-  Cmd = &AlignedCmd.Cmd;\r
 \r
   Status = PvScsiAllocateSharedPages (\r
              Dev,\r
@@ -1005,46 +1025,8 @@ PvScsiInitRings (
   }\r
   ZeroMem (Dev->RingDesc.RingCmps, EFI_PAGE_SIZE);\r
 \r
-  ZeroMem (Cmd, sizeof (*Cmd));\r
-  Cmd->ReqRingNumPages = 1;\r
-  Cmd->CmpRingNumPages = 1;\r
-  Cmd->RingsStatePPN = RShiftU64 (\r
-                         Dev->RingDesc.RingStateDmaDesc.DeviceAddress,\r
-                         EFI_PAGE_SHIFT\r
-                         );\r
-  Cmd->ReqRingPPNs[0] = RShiftU64 (\r
-                          Dev->RingDesc.RingReqsDmaDesc.DeviceAddress,\r
-                          EFI_PAGE_SHIFT\r
-                          );\r
-  Cmd->CmpRingPPNs[0] = RShiftU64 (\r
-                          Dev->RingDesc.RingCmpsDmaDesc.DeviceAddress,\r
-                          EFI_PAGE_SHIFT\r
-                          );\r
-\r
-  STATIC_ASSERT (\r
-    sizeof (*Cmd) % sizeof (UINT32) == 0,\r
-    "Cmd must be multiple of 32-bit words"\r
-    );\r
-  Status = PvScsiWriteCmdDesc (\r
-             Dev,\r
-             PvScsiCmdSetupRings,\r
-             (UINT32 *)Cmd,\r
-             sizeof (*Cmd) / sizeof (UINT32)\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto FreeRingCmps;\r
-  }\r
-\r
   return EFI_SUCCESS;\r
 \r
-FreeRingCmps:\r
-  PvScsiFreeSharedPages (\r
-    Dev,\r
-    1,\r
-    Dev->RingDesc.RingCmps,\r
-    &Dev->RingDesc.RingCmpsDmaDesc\r
-    );\r
-\r
 FreeRingReqs:\r
   PvScsiFreeSharedPages (\r
     Dev,\r
@@ -1092,6 +1074,48 @@ PvScsiFreeRings (
     );\r
 }\r
 \r
+STATIC\r
+EFI_STATUS\r
+PvScsiSetupRings (\r
+  IN OUT PVSCSI_DEV *Dev\r
+  )\r
+{\r
+  union {\r
+    PVSCSI_CMD_DESC_SETUP_RINGS Cmd;\r
+    UINT32                      Uint32;\r
+  } AlignedCmd;\r
+  PVSCSI_CMD_DESC_SETUP_RINGS *Cmd;\r
+\r
+  Cmd = &AlignedCmd.Cmd;\r
+\r
+  ZeroMem (Cmd, sizeof (*Cmd));\r
+  Cmd->ReqRingNumPages = 1;\r
+  Cmd->CmpRingNumPages = 1;\r
+  Cmd->RingsStatePPN = RShiftU64 (\r
+                         Dev->RingDesc.RingStateDmaDesc.DeviceAddress,\r
+                         EFI_PAGE_SHIFT\r
+                         );\r
+  Cmd->ReqRingPPNs[0] = RShiftU64 (\r
+                          Dev->RingDesc.RingReqsDmaDesc.DeviceAddress,\r
+                          EFI_PAGE_SHIFT\r
+                          );\r
+  Cmd->CmpRingPPNs[0] = RShiftU64 (\r
+                          Dev->RingDesc.RingCmpsDmaDesc.DeviceAddress,\r
+                          EFI_PAGE_SHIFT\r
+                          );\r
+\r
+  STATIC_ASSERT (\r
+    sizeof (*Cmd) % sizeof (UINT32) == 0,\r
+    "Cmd must be multiple of 32-bit words"\r
+    );\r
+  return PvScsiWriteCmdDesc (\r
+           Dev,\r
+           PvScsiCmdSetupRings,\r
+           (UINT32 *)Cmd,\r
+           sizeof (*Cmd) / sizeof (UINT32)\r
+           );\r
+}\r
+\r
 STATIC\r
 EFI_STATUS\r
 PvScsiInit (\r
@@ -1144,6 +1168,14 @@ PvScsiInit (
     goto FreeRings;\r
   }\r
 \r
+  //\r
+  // Setup rings against device\r
+  //\r
+  Status = PvScsiSetupRings (Dev);\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreeDmaCommBuffer;\r
+  }\r
+\r
   //\r
   // Populate the exported interface's attributes\r
   //\r
@@ -1175,13 +1207,15 @@ PvScsiInit (
 \r
   return EFI_SUCCESS;\r
 \r
-FreeRings:\r
-  //\r
-  // Reset device to stop device usage of the rings.\r
-  // This is required to safely free the rings.\r
-  //\r
-  PvScsiResetAdapter (Dev);\r
+FreeDmaCommBuffer:\r
+  PvScsiFreeSharedPages (\r
+    Dev,\r
+    EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),\r
+    Dev->DmaBuf,\r
+    &Dev->DmaBufDmaDesc\r
+    );\r
 \r
+FreeRings:\r
   PvScsiFreeRings (Dev);\r
 \r
 RestorePciAttributes:\r