diff --git a/MdePkg/Include/IndustryStandard/Scsi.h b/MdePkg/Include/IndustryStandard/Scsi.h index aa097fd214..721c096abe 100644 --- a/MdePkg/Include/IndustryStandard/Scsi.h +++ b/MdePkg/Include/IndustryStandard/Scsi.h @@ -49,6 +49,7 @@ #define EFI_SCSI_OP_READ6 0x08 #define EFI_SCSI_OP_READ10 0x28 #define EFI_SCSI_OP_READ_CAPACITY 0x25 +#define EFI_SCSI_OP_READ_CAPACITY16 0x9e #define EFI_SCSI_OP_READ_DEFECT 0x37 #define EFI_SCSI_OP_READ_LONG 0x3e #define EFI_SCSI_OP_REASSIGN_BLK 0x07 @@ -240,6 +241,27 @@ typedef struct { UINT8 BlockSize0; } EFI_SCSI_DISK_CAPACITY_DATA; +typedef struct { + UINT8 LastLba7; + UINT8 LastLba6; + UINT8 LastLba5; + UINT8 LastLba4; + UINT8 LastLba3; + UINT8 LastLba2; + UINT8 LastLba1; + UINT8 LastLba0; + UINT8 BlockSize3; + UINT8 BlockSize2; + UINT8 BlockSize1; + UINT8 BlockSize0; + UINT8 Protection; + UINT8 LogicPerPhysical; + UINT8 LowestAlignLogic2; + UINT8 LowestAlignLogic1; + UINT8 Reserved[16]; +} EFI_SCSI_DISK_CAPACITY_DATA16; + + #pragma pack() // diff --git a/MdePkg/Include/Library/UefiScsiLib.h b/MdePkg/Include/Library/UefiScsiLib.h index 1ff091aaca..7d27a2a0b0 100644 --- a/MdePkg/Include/Library/UefiScsiLib.h +++ b/MdePkg/Include/Library/UefiScsiLib.h @@ -377,6 +377,53 @@ ScsiReadCapacityCommand ( ); +/** + Function to submit read capacity16 command. + + @param ScsiIo A pointer to SCSI IO protocol. + @param Timeout The length of timeout period. + @param SenseData A pointer to output sense data. + @param SenseDataLength The length of output sense data. + @param HostAdapterStatus The status of Host Adapter. + @param TargetStatus The status of the target. + @param DataBuffer A pointer to a data buffer. + @param DataLength The length of data buffer. + @param PMI Partial medium indicator. + + @retval EFI_SUCCESS The status of the unit is tested successfully. + @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, + but the entire DataBuffer could not be transferred. + The actual number of bytes transferred is returned + in TransferLength. + @retval EFI_NOT_READY The SCSI Request Packet could not be sent because + there are too many SCSI Command Packets already + queued. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to send + the SCSI Request Packet. + @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid. + @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet + is not supported by the SCSI initiator(i.e., SCSI + Host Controller). + @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI + Request Packet to execute. + +**/ + +EFI_STATUS +EFIAPI +ScsiReadCapacity16Command ( + IN EFI_SCSI_IO_PROTOCOL *ScsiIo, + IN UINT64 Timeout, + IN VOID *SenseData, + IN OUT UINT8 *SenseDataLength, + OUT UINT8 *HostAdapterStatus, + OUT UINT8 *TargetStatus, + OUT VOID *DataBuffer, + IN OUT UINT32 *DataLength, + IN BOOLEAN PMI + ); + + /** Execute Read(10) SCSI command on a specific SCSI target. diff --git a/MdePkg/Library/UefiScsiLib/UefiScsiLib.c b/MdePkg/Library/UefiScsiLib/UefiScsiLib.c index e26905e1e3..1458efd2f9 100644 --- a/MdePkg/Library/UefiScsiLib/UefiScsiLib.c +++ b/MdePkg/Library/UefiScsiLib/UefiScsiLib.c @@ -635,6 +635,100 @@ ScsiReadCapacityCommand ( } +/** + Function to submit read capacity16 command. + + @param ScsiIo A pointer to SCSI IO protocol. + @param Timeout The length of timeout period. + @param SenseData A pointer to output sense data. + @param SenseDataLength The length of output sense data. + @param HostAdapterStatus The status of Host Adapter. + @param TargetStatus The status of the target. + @param DataBuffer A pointer to a data buffer. + @param DataLength The length of data buffer. + @param PMI Partial medium indicator. + + @retval EFI_SUCCESS The status of the unit is tested successfully. + @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, + but the entire DataBuffer could not be transferred. + The actual number of bytes transferred is returned + in TransferLength. + @retval EFI_NOT_READY The SCSI Request Packet could not be sent because + there are too many SCSI Command Packets already + queued. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to send + the SCSI Request Packet. + @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid. + @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet + is not supported by the SCSI initiator(i.e., SCSI + Host Controller). + @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI + Request Packet to execute. + +**/ + +EFI_STATUS +EFIAPI +ScsiReadCapacity16Command ( + IN EFI_SCSI_IO_PROTOCOL *ScsiIo, + IN UINT64 Timeout, + IN VOID *SenseData, + IN OUT UINT8 *SenseDataLength, + OUT UINT8 *HostAdapterStatus, + OUT UINT8 *TargetStatus, + OUT VOID *DataBuffer, + IN OUT UINT32 *DataLength, + IN BOOLEAN PMI + ) +{ + EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket; + UINT64 Lun; + UINT8 *Target; + UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES]; + EFI_STATUS Status; + UINT8 Cdb[16]; + + ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET)); + ZeroMem (Cdb, 16); + + CommandPacket.Timeout = Timeout; + CommandPacket.InDataBuffer = DataBuffer; + CommandPacket.SenseData = SenseData; + CommandPacket.InTransferLength= *DataLength; + CommandPacket.Cdb = Cdb; + // + // Fill Cdb for Read Capacity Command + // + Target = &TargetArray[0]; + ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun); + + Cdb[0] = EFI_SCSI_OP_READ_CAPACITY16; + Cdb[1] = 0x10; + if (!PMI) { + // + // Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO. + // + ZeroMem ((Cdb + 2), 8); + } else { + Cdb[14] |= 0x01; + } + + Cdb[13] = 0x20; + CommandPacket.CdbLength = 16; + CommandPacket.DataDirection = EFI_SCSI_DATA_IN; + CommandPacket.SenseDataLength = *SenseDataLength; + + Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL); + + *HostAdapterStatus = CommandPacket.HostAdapterStatus; + *TargetStatus = CommandPacket.TargetStatus; + *SenseDataLength = CommandPacket.SenseDataLength; + *DataLength = CommandPacket.InTransferLength; + + return Status; +} + + /** Execute Read(10) SCSI command on a specific SCSI target.