mirror of https://github.com/acidanthera/audk.git
Add Read/Write (16) command to SCSI library.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10549 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
4515103850
commit
a24faca37a
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Support for SCSI-2 standard
|
||||
|
||||
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -48,6 +48,7 @@
|
|||
#define EFI_SCSI_OP_MEDIA_REMOVAL 0x1e
|
||||
#define EFI_SCSI_OP_READ6 0x08
|
||||
#define EFI_SCSI_OP_READ10 0x28
|
||||
#define EFI_SCSI_OP_READ16 0x88
|
||||
#define EFI_SCSI_OP_READ_CAPACITY 0x25
|
||||
#define EFI_SCSI_OP_READ_CAPACITY16 0x9e
|
||||
#define EFI_SCSI_OP_READ_DEFECT 0x37
|
||||
|
@ -67,6 +68,7 @@
|
|||
#define EFI_SCSI_OP_VERIFY 0x2f
|
||||
#define EFI_SCSI_OP_WRITE6 0x0a
|
||||
#define EFI_SCSI_OP_WRITE10 0x2a
|
||||
#define EFI_SCSI_OP_WRITE16 0x8a
|
||||
#define EFI_SCSI_OP_WRITE_VERIFY 0x2e
|
||||
#define EFI_SCSI_OP_WRITE_LONG 0x3f
|
||||
#define EFI_SCSI_OP_WRITE_SAME 0x41
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
for hard drive, CD and DVD devices that are the most common SCSI boot targets used by UEFI platforms.
|
||||
This library class depends on SCSI I/O Protocol defined in UEFI Specification and SCSI-2 industry standard.
|
||||
|
||||
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -531,5 +531,108 @@ ScsiWrite10Command (
|
|||
IN UINT32 SectorSize
|
||||
);
|
||||
|
||||
/**
|
||||
Execute Read(16) SCSI command on a specific SCSI target.
|
||||
|
||||
Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.
|
||||
If Timeout is zero, then this function waits indefinitely for the command to complete.
|
||||
If Timeout is greater than zero, then the command is executed and will timeout
|
||||
after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
|
||||
construct the CDB for this SCSI command.
|
||||
If ScsiIo is NULL, then ASSERT().
|
||||
If SenseDataLength is NULL, then ASSERT().
|
||||
If HostAdapterStatus is NULL, then ASSERT().
|
||||
If TargetStatus is NULL, then ASSERT().
|
||||
If DataLength is NULL, then ASSERT().
|
||||
|
||||
|
||||
@param[in] ScsiIo A pointer to SCSI IO protocol.
|
||||
@param[in] Timeout The length of timeout period.
|
||||
@param[in, out] SenseData A pointer to output sense data.
|
||||
@param[in, out] SenseDataLength The length of output sense data.
|
||||
@param[out] HostAdapterStatus The status of Host Adapter.
|
||||
@param[out] TargetStatus The status of the target.
|
||||
@param[in, out] DataBuffer Read 16 command data.
|
||||
@param[in, out] DataLength The length of data buffer.
|
||||
@param[in] StartLba The start address of LBA.
|
||||
@param[in] SectorSize The sector size.
|
||||
|
||||
@retval EFI_SUCCESS Command is executed 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 DataLength.
|
||||
@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 SCSI Request Packet.
|
||||
@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
|
||||
ScsiRead16Command (
|
||||
IN EFI_SCSI_IO_PROTOCOL *ScsiIo,
|
||||
IN UINT64 Timeout,
|
||||
IN OUT VOID *SenseData, OPTIONAL
|
||||
IN OUT UINT8 *SenseDataLength,
|
||||
OUT UINT8 *HostAdapterStatus,
|
||||
OUT UINT8 *TargetStatus,
|
||||
IN OUT VOID *DataBuffer, OPTIONAL
|
||||
IN OUT UINT32 *DataLength,
|
||||
IN UINT64 StartLba,
|
||||
IN UINT32 SectorSize
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Execute Write(16) SCSI command on a specific SCSI target.
|
||||
|
||||
Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.
|
||||
If Timeout is zero, then this function waits indefinitely for the command to complete.
|
||||
If Timeout is greater than zero, then the command is executed and will timeout after
|
||||
Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
|
||||
the CDB for this SCSI command.
|
||||
If ScsiIo is NULL, then ASSERT().
|
||||
If SenseDataLength is NULL, then ASSERT().
|
||||
If HostAdapterStatus is NULL, then ASSERT().
|
||||
If TargetStatus is NULL, then ASSERT().
|
||||
If DataLength is NULL, then ASSERT().
|
||||
|
||||
@param[in] ScsiIo SCSI IO Protocol to use
|
||||
@param[in] Timeout The length of timeout period.
|
||||
@param[in, out] SenseData A pointer to output sense data.
|
||||
@param[in, out] SenseDataLength The length of output sense data.
|
||||
@param[out] HostAdapterStatus The status of Host Adapter.
|
||||
@param[out] TargetStatus The status of the target.
|
||||
@param[in, out] DataBuffer A pointer to a data buffer.
|
||||
@param[in, out] DataLength The length of data buffer.
|
||||
@param[in] StartLba The start address of LBA.
|
||||
@param[in] SectorSize The sector size.
|
||||
|
||||
@retval EFI_SUCCESS Command is executed 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 DataLength.
|
||||
@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 SCSI Request Packet.
|
||||
@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
|
||||
ScsiWrite16Command (
|
||||
IN EFI_SCSI_IO_PROTOCOL *ScsiIo,
|
||||
IN UINT64 Timeout,
|
||||
IN OUT VOID *SenseData, OPTIONAL
|
||||
IN OUT UINT8 *SenseDataLength,
|
||||
OUT UINT8 *HostAdapterStatus,
|
||||
OUT UINT8 *TargetStatus,
|
||||
IN OUT VOID *DataBuffer, OPTIONAL
|
||||
IN OUT UINT32 *DataLength,
|
||||
IN UINT64 StartLba,
|
||||
IN UINT32 SectorSize
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
UEFI SCSI Library implementation
|
||||
|
||||
Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -34,10 +34,11 @@
|
|||
#define EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK 0xe0
|
||||
|
||||
//
|
||||
// Scsi Command Length six or ten
|
||||
// Scsi Command Length
|
||||
//
|
||||
#define EFI_SCSI_OP_LENGTH_SIX 0x6
|
||||
#define EFI_SCSI_OP_LENGTH_TEN 0xa
|
||||
#define EFI_SCSI_OP_LENGTH_SIX 0x6
|
||||
#define EFI_SCSI_OP_LENGTH_TEN 0xa
|
||||
#define EFI_SCSI_OP_LENGTH_SIXTEEN 0x10
|
||||
|
||||
|
||||
|
||||
|
@ -820,12 +821,8 @@ ScsiRead10Command (
|
|||
|
||||
Cdb[0] = EFI_SCSI_OP_READ10;
|
||||
Cdb[1] = (UINT8) (LShiftU64 (Lun, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);
|
||||
Cdb[2] = (UINT8) (StartLba >> 24);
|
||||
Cdb[3] = (UINT8) (StartLba >> 16);
|
||||
Cdb[4] = (UINT8) (StartLba >> 8);
|
||||
Cdb[5] = (UINT8) (StartLba & 0xff);
|
||||
Cdb[7] = (UINT8) (SectorSize >> 8);
|
||||
Cdb[8] = (UINT8) (SectorSize & 0xff);
|
||||
WriteUnaligned32 ((UINT32 *)&Cdb[2], SwapBytes32 (StartLba));
|
||||
WriteUnaligned16 ((UINT16 *)&Cdb[7], SwapBytes16 ((UINT16) SectorSize));
|
||||
|
||||
CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;
|
||||
CommandPacket.DataDirection = EFI_SCSI_DATA_IN;
|
||||
|
@ -922,12 +919,8 @@ ScsiWrite10Command (
|
|||
|
||||
Cdb[0] = EFI_SCSI_OP_WRITE10;
|
||||
Cdb[1] = (UINT8) (LShiftU64 (Lun, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);
|
||||
Cdb[2] = (UINT8) (StartLba >> 24);
|
||||
Cdb[3] = (UINT8) (StartLba >> 16);
|
||||
Cdb[4] = (UINT8) (StartLba >> 8);
|
||||
Cdb[5] = (UINT8) StartLba;
|
||||
Cdb[7] = (UINT8) (SectorSize >> 8);
|
||||
Cdb[8] = (UINT8) SectorSize;
|
||||
WriteUnaligned32 ((UINT32 *)&Cdb[2], SwapBytes32 (StartLba));
|
||||
WriteUnaligned16 ((UINT16 *)&Cdb[7], SwapBytes16 ((UINT16) SectorSize));
|
||||
|
||||
CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;
|
||||
CommandPacket.DataDirection = EFI_SCSI_DATA_OUT;
|
||||
|
@ -943,3 +936,198 @@ ScsiWrite10Command (
|
|||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Execute Read(16) SCSI command on a specific SCSI target.
|
||||
|
||||
Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.
|
||||
If Timeout is zero, then this function waits indefinitely for the command to complete.
|
||||
If Timeout is greater than zero, then the command is executed and will timeout
|
||||
after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
|
||||
construct the CDB for this SCSI command.
|
||||
If ScsiIo is NULL, then ASSERT().
|
||||
If SenseDataLength is NULL, then ASSERT().
|
||||
If HostAdapterStatus is NULL, then ASSERT().
|
||||
If TargetStatus is NULL, then ASSERT().
|
||||
If DataLength is NULL, then ASSERT().
|
||||
|
||||
|
||||
@param[in] ScsiIo A pointer to SCSI IO protocol.
|
||||
@param[in] Timeout The length of timeout period.
|
||||
@param[in, out] SenseData A pointer to output sense data.
|
||||
@param[in, out] SenseDataLength The length of output sense data.
|
||||
@param[out] HostAdapterStatus The status of Host Adapter.
|
||||
@param[out] TargetStatus The status of the target.
|
||||
@param[in, out] DataBuffer Read 16 command data.
|
||||
@param[in, out] DataLength The length of data buffer.
|
||||
@param[in] StartLba The start address of LBA.
|
||||
@param[in] SectorSize The sector size.
|
||||
|
||||
@retval EFI_SUCCESS Command is executed 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 DataLength.
|
||||
@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 SCSI Request Packet.
|
||||
@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
|
||||
ScsiRead16Command (
|
||||
IN EFI_SCSI_IO_PROTOCOL *ScsiIo,
|
||||
IN UINT64 Timeout,
|
||||
IN OUT VOID *SenseData, OPTIONAL
|
||||
IN OUT UINT8 *SenseDataLength,
|
||||
OUT UINT8 *HostAdapterStatus,
|
||||
OUT UINT8 *TargetStatus,
|
||||
IN OUT VOID *DataBuffer, OPTIONAL
|
||||
IN OUT UINT32 *DataLength,
|
||||
IN UINT64 StartLba,
|
||||
IN UINT32 SectorSize
|
||||
)
|
||||
{
|
||||
EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;
|
||||
UINT64 Lun;
|
||||
UINT8 *Target;
|
||||
UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];
|
||||
EFI_STATUS Status;
|
||||
UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIXTEEN];
|
||||
|
||||
ASSERT (SenseDataLength != NULL);
|
||||
ASSERT (HostAdapterStatus != NULL);
|
||||
ASSERT (TargetStatus != NULL);
|
||||
ASSERT (DataLength != NULL);
|
||||
ASSERT (ScsiIo != NULL);
|
||||
|
||||
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
|
||||
ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIXTEEN);
|
||||
|
||||
CommandPacket.Timeout = Timeout;
|
||||
CommandPacket.InDataBuffer = DataBuffer;
|
||||
CommandPacket.SenseData = SenseData;
|
||||
CommandPacket.InTransferLength = *DataLength;
|
||||
CommandPacket.Cdb = Cdb;
|
||||
//
|
||||
// Fill Cdb for Read (16) Command
|
||||
//
|
||||
Target = &TargetArray[0];
|
||||
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
|
||||
|
||||
Cdb[0] = EFI_SCSI_OP_READ16;
|
||||
Cdb[1] = (UINT8) (LShiftU64 (Lun, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);
|
||||
WriteUnaligned64 ((UINT64 *)&Cdb[2], SwapBytes64 (StartLba));
|
||||
WriteUnaligned32 ((UINT32 *)&Cdb[10], SwapBytes32 (SectorSize));
|
||||
|
||||
CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_SIXTEEN;
|
||||
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 Write(16) SCSI command on a specific SCSI target.
|
||||
|
||||
Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.
|
||||
If Timeout is zero, then this function waits indefinitely for the command to complete.
|
||||
If Timeout is greater than zero, then the command is executed and will timeout after
|
||||
Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
|
||||
the CDB for this SCSI command.
|
||||
If ScsiIo is NULL, then ASSERT().
|
||||
If SenseDataLength is NULL, then ASSERT().
|
||||
If HostAdapterStatus is NULL, then ASSERT().
|
||||
If TargetStatus is NULL, then ASSERT().
|
||||
If DataLength is NULL, then ASSERT().
|
||||
|
||||
@param[in] ScsiIo SCSI IO Protocol to use
|
||||
@param[in] Timeout The length of timeout period.
|
||||
@param[in, out] SenseData A pointer to output sense data.
|
||||
@param[in, out] SenseDataLength The length of output sense data.
|
||||
@param[out] HostAdapterStatus The status of Host Adapter.
|
||||
@param[out] TargetStatus The status of the target.
|
||||
@param[in, out] DataBuffer A pointer to a data buffer.
|
||||
@param[in, out] DataLength The length of data buffer.
|
||||
@param[in] StartLba The start address of LBA.
|
||||
@param[in] SectorSize The sector size.
|
||||
|
||||
@retval EFI_SUCCESS Command is executed 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 DataLength.
|
||||
@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 SCSI Request Packet.
|
||||
@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
|
||||
ScsiWrite16Command (
|
||||
IN EFI_SCSI_IO_PROTOCOL *ScsiIo,
|
||||
IN UINT64 Timeout,
|
||||
IN OUT VOID *SenseData, OPTIONAL
|
||||
IN OUT UINT8 *SenseDataLength,
|
||||
OUT UINT8 *HostAdapterStatus,
|
||||
OUT UINT8 *TargetStatus,
|
||||
IN OUT VOID *DataBuffer, OPTIONAL
|
||||
IN OUT UINT32 *DataLength,
|
||||
IN UINT64 StartLba,
|
||||
IN UINT32 SectorSize
|
||||
)
|
||||
{
|
||||
EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;
|
||||
UINT64 Lun;
|
||||
UINT8 *Target;
|
||||
UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];
|
||||
EFI_STATUS Status;
|
||||
UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIXTEEN];
|
||||
|
||||
ASSERT (SenseDataLength != NULL);
|
||||
ASSERT (HostAdapterStatus != NULL);
|
||||
ASSERT (TargetStatus != NULL);
|
||||
ASSERT (DataLength != NULL);
|
||||
ASSERT (ScsiIo != NULL);
|
||||
|
||||
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
|
||||
ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIXTEEN);
|
||||
|
||||
CommandPacket.Timeout = Timeout;
|
||||
CommandPacket.OutDataBuffer = DataBuffer;
|
||||
CommandPacket.SenseData = SenseData;
|
||||
CommandPacket.OutTransferLength = *DataLength;
|
||||
CommandPacket.Cdb = Cdb;
|
||||
//
|
||||
// Fill Cdb for Write (16) Command
|
||||
//
|
||||
Target = &TargetArray[0];
|
||||
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
|
||||
|
||||
Cdb[0] = EFI_SCSI_OP_WRITE16;
|
||||
Cdb[1] = (UINT8) (LShiftU64 (Lun, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);
|
||||
WriteUnaligned64 ((UINT64 *)&Cdb[2], SwapBytes64 (StartLba));
|
||||
WriteUnaligned32 ((UINT32 *)&Cdb[10], SwapBytes32 (SectorSize));
|
||||
|
||||
CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_SIXTEEN;
|
||||
CommandPacket.DataDirection = EFI_SCSI_DATA_OUT;
|
||||
CommandPacket.SenseDataLength = *SenseDataLength;
|
||||
|
||||
Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);
|
||||
|
||||
*HostAdapterStatus = CommandPacket.HostAdapterStatus;
|
||||
*TargetStatus = CommandPacket.TargetStatus;
|
||||
*SenseDataLength = CommandPacket.SenseDataLength;
|
||||
*DataLength = CommandPacket.OutTransferLength;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue