]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/LsiScsiDxe: Report Targets and LUNs
authorGary Lin <glin@suse.com>
Fri, 17 Jul 2020 06:11:25 +0000 (14:11 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 17 Jul 2020 20:51:55 +0000 (20:51 +0000)
Implement LsiScsiGetNextTargetLun(), LsiScsiBuildDevicePath(),
LsiScsiGetTargetLun(), and LsiScsiGetNextTarget() to report Targets and
LUNs and build the device path.

This commit also introduces two PCD value: PcdLsiScsiMaxTargetLimit and
PcdLsiScsiMaxLunLimit as the limits for Targets and LUNs.

v3:
  - Update the range of LUN in the assertioin
  - Squash the spurious newline into the previous commit
v2:
  - Zero out (*Target) in LsiScsiGetTargetLun()
  - Use CopyMem() instead of the one-byte shortcut to copy target from
    ScsiDevicePath->Pun
  - Add asserts for PcdLsiScsiMaxTargetLimit and PcdLsiScsiMaxLunLimit

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Message-Id: <20200717061130.8881-7-glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
OvmfPkg/LsiScsiDxe/LsiScsi.c
OvmfPkg/LsiScsiDxe/LsiScsi.h
OvmfPkg/LsiScsiDxe/LsiScsiDxe.inf
OvmfPkg/OvmfPkg.dec

index 67fadb411e85debf0d6a695127768db7db0096f0..1727792406368973f3f7aca599c3738e6beddc1d 100644 (file)
@@ -15,6 +15,7 @@
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Protocol/PciIo.h>\r
@@ -53,6 +54,49 @@ LsiScsiGetNextTargetLun (
   IN OUT UINT64                      *Lun\r
   )\r
 {\r
+  LSI_SCSI_DEV *Dev;\r
+  UINTN        Idx;\r
+  UINT8        *Target;\r
+  UINT16       LastTarget;\r
+\r
+  //\r
+  // the TargetPointer input parameter is unnecessarily a pointer-to-pointer\r
+  //\r
+  Target = *TargetPointer;\r
+\r
+  //\r
+  // Search for first non-0xFF byte. If not found, return first target & LUN.\r
+  //\r
+  for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx)\r
+    ;\r
+  if (Idx == TARGET_MAX_BYTES) {\r
+    SetMem (Target, TARGET_MAX_BYTES, 0x00);\r
+    *Lun = 0;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  CopyMem (&LastTarget, Target, sizeof LastTarget);\r
+\r
+  //\r
+  // increment (target, LUN) pair if valid on input\r
+  //\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if (LastTarget > Dev->MaxTarget || *Lun > Dev->MaxLun) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (*Lun < Dev->MaxLun) {\r
+    ++*Lun;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (LastTarget < Dev->MaxTarget) {\r
+    *Lun = 0;\r
+    ++LastTarget;\r
+    CopyMem (Target, &LastTarget, sizeof LastTarget);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -65,7 +109,34 @@ LsiScsiBuildDevicePath (
   IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath\r
   )\r
 {\r
-  return EFI_NOT_FOUND;\r
+  UINT16           TargetValue;\r
+  LSI_SCSI_DEV     *Dev;\r
+  SCSI_DEVICE_PATH *ScsiDevicePath;\r
+\r
+  if (DevicePath == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CopyMem (&TargetValue, Target, sizeof TargetValue);\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if (TargetValue > Dev->MaxTarget || Lun > Dev->MaxLun || Lun > 0xFFFF) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  ScsiDevicePath = AllocatePool (sizeof *ScsiDevicePath);\r
+  if (ScsiDevicePath == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  ScsiDevicePath->Header.Type      = MESSAGING_DEVICE_PATH;\r
+  ScsiDevicePath->Header.SubType   = MSG_SCSI_DP;\r
+  ScsiDevicePath->Header.Length[0] = (UINT8)  sizeof *ScsiDevicePath;\r
+  ScsiDevicePath->Header.Length[1] = (UINT8) (sizeof *ScsiDevicePath >> 8);\r
+  ScsiDevicePath->Pun              = TargetValue;\r
+  ScsiDevicePath->Lun              = (UINT16) Lun;\r
+\r
+  *DevicePath = &ScsiDevicePath->Header;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 EFI_STATUS\r
@@ -77,7 +148,33 @@ LsiScsiGetTargetLun (
   OUT UINT64                          *Lun\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  SCSI_DEVICE_PATH *ScsiDevicePath;\r
+  LSI_SCSI_DEV     *Dev;\r
+  UINT8            *Target;\r
+\r
+  if (DevicePath == NULL || TargetPointer == NULL || *TargetPointer == NULL ||\r
+      Lun == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DevicePath->Type    != MESSAGING_DEVICE_PATH ||\r
+      DevicePath->SubType != MSG_SCSI_DP) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ScsiDevicePath = (SCSI_DEVICE_PATH *) DevicePath;\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if (ScsiDevicePath->Pun > Dev->MaxTarget ||\r
+      ScsiDevicePath->Lun > Dev->MaxLun) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Target = *TargetPointer;\r
+  ZeroMem (Target, TARGET_MAX_BYTES);\r
+  CopyMem (Target, &ScsiDevicePath->Pun, sizeof ScsiDevicePath->Pun);\r
+  *Lun = ScsiDevicePath->Lun;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 EFI_STATUS\r
@@ -107,6 +204,42 @@ LsiScsiGetNextTarget (
   IN OUT UINT8                       **TargetPointer\r
   )\r
 {\r
+  LSI_SCSI_DEV *Dev;\r
+  UINTN        Idx;\r
+  UINT8        *Target;\r
+  UINT16       LastTarget;\r
+\r
+  //\r
+  // the TargetPointer input parameter is unnecessarily a pointer-to-pointer\r
+  //\r
+  Target = *TargetPointer;\r
+\r
+  //\r
+  // Search for first non-0xFF byte. If not found, return first target.\r
+  //\r
+  for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx)\r
+    ;\r
+  if (Idx == TARGET_MAX_BYTES) {\r
+    SetMem (Target, TARGET_MAX_BYTES, 0x00);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  CopyMem (&LastTarget, Target, sizeof LastTarget);\r
+\r
+  //\r
+  // increment target if valid on input\r
+  //\r
+  Dev = LSI_SCSI_FROM_PASS_THRU (This);\r
+  if (LastTarget > Dev->MaxTarget) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (LastTarget < Dev->MaxTarget) {\r
+    ++LastTarget;\r
+    CopyMem (Target, &LastTarget, sizeof LastTarget);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -189,6 +322,17 @@ LsiScsiControllerStart (
 \r
   Dev->Signature = LSI_SCSI_DEV_SIGNATURE;\r
 \r
+  STATIC_ASSERT (\r
+    FixedPcdGet8 (PcdLsiScsiMaxTargetLimit) < 8,\r
+    "LSI 53C895A supports targets [0..7]"\r
+    );\r
+  STATIC_ASSERT (\r
+    FixedPcdGet8 (PcdLsiScsiMaxLunLimit) < 128,\r
+    "LSI 53C895A supports LUNs [0..127]"\r
+    );\r
+  Dev->MaxTarget = PcdGet8 (PcdLsiScsiMaxTargetLimit);\r
+  Dev->MaxLun = PcdGet8 (PcdLsiScsiMaxLunLimit);\r
+\r
   //\r
   // Host adapter channel, doesn't exist\r
   //\r
index 751d5b193b5122a3ade241518f664a76ae8f62c5..6c6ed25f1c333356d150b56a79b3c403c2a032fe 100644 (file)
@@ -14,6 +14,8 @@
 \r
 typedef struct {\r
   UINT32                          Signature;\r
+  UINT8                           MaxTarget;\r
+  UINT8                           MaxLun;\r
   EFI_EXT_SCSI_PASS_THRU_MODE     PassThruMode;\r
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;\r
 } LSI_SCSI_DEV;\r
index 14f9c68308cc311a7272c2aff850680b4827b576..6111449577a8f0a9d06067ee8c1961b21ddce001 100644 (file)
@@ -27,7 +27,9 @@
 [LibraryClasses]\r
   BaseLib\r
   BaseMemoryLib\r
+  DebugLib\r
   MemoryAllocationLib\r
+  PcdLib\r
   UefiBootServicesTableLib\r
   UefiDriverEntryPoint\r
   UefiLib\r
@@ -35,3 +37,7 @@
 [Protocols]\r
   gEfiExtScsiPassThruProtocolGuid        ## BY_START\r
   gEfiPciIoProtocolGuid                  ## TO_START\r
+\r
+[FixedPcd]\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdLsiScsiMaxTargetLimit   ## CONSUMES\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdLsiScsiMaxLunLimit      ## CONSUMES\r
index 2b0f137cbcce54e5e9803374df5023a5983c7d90..ca13a3cb11d3b6f02bd1f35b178e895a54966f9f 100644 (file)
   ## Microseconds to stall between polling for MptScsi request result\r
   gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiStallPerPollUsec|5|UINT32|0x3a\r
 \r
+  ## Set the *inclusive* number of targets and LUNs that LsiScsi exposes for\r
+  #  scan by ScsiBusDxe.\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdLsiScsiMaxTargetLimit|7|UINT8|0x3b\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdLsiScsiMaxLunLimit|0|UINT8|0x3c\r
+\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa\r