#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
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
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
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
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
\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