scsilib.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 671 行 · 第 1/2 页
C
671 行
Host Controller).
EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
Request Packet to execute.
--*/
{
EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;
UINT64 Lun;
UINT8 *Target;
UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];
EFI_STATUS Status;
UINT8 Cdb[6];
EfiZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
EfiZeroMem (Cdb, 6);
CommandPacket.Timeout = Timeout;
CommandPacket.InDataBuffer = SenseData;
CommandPacket.SenseData = NULL;
CommandPacket.InTransferLength= *SenseDataLength;
CommandPacket.Cdb = Cdb;
//
// Fill Cdb for Request Sense Command
//
Target = &TargetArray[0];
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
Cdb[0] = EFI_SCSI_OP_REQUEST_SENSE;
Cdb[1] = (UINT8) (Lun & 0xe0);
Cdb[4] = (UINT8) (*SenseDataLength);
CommandPacket.CdbLength = (UINT8) 6;
CommandPacket.DataDirection = EFI_SCSI_DATA_IN;
CommandPacket.SenseDataLength = 0;
Status = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);
*HostAdapterStatus = CommandPacket.HostAdapterStatus;
*TargetStatus = CommandPacket.TargetStatus;
*SenseDataLength = (UINT8) CommandPacket.InTransferLength;
return Status;
}
EFI_STATUS
SubmitReadCapacityCommand (
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
)
/*++
Routine Description:
Function to submit read capacity command.
Arguments:
ScsiIo - A pointer to SCSI IO protocol.
Timeout - The length of timeout period.
SenseData - A pointer to output sense data.
SenseDataLength - The length of output sense data.
HostAdapterStatus - The status of Host Adapter.
TargetStatus - The status of the target.
DataBuffer - A pointer to a data buffer.
DataLength - The length of data buffer.
PMI - Partial medium indicator.
Returns:
EFI_SUCCESS - The status of the unit is tested successfully.
EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
but the entire DataBuffer could not be transferred.
The actual number of bytes transferred is returned
in TransferLength.
EFI_NOT_READY - The SCSI Request Packet could not be sent because
there are too many SCSI Command Packets already
queued.
EFI_DEVICE_ERROR - A device error occurred while attempting to send
the SCSI Request Packet.
EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
EFI_UNSUPPORTED - The command described by the SCSI Request Packet
is not supported by the SCSI initiator(i.e., SCSI
Host Controller).
EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
Request Packet to execute.
--*/
{
EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;
UINT64 Lun;
UINT8 *Target;
UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];
EFI_STATUS Status;
UINT8 Cdb[10];
EfiZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
EfiZeroMem (Cdb, 10);
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_CAPACITY;
Cdb[1] = (UINT8) (Lun & 0xe0);
if (!PMI) {
//
// Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.
//
EfiZeroMem ((Cdb + 2), 4);
} else {
Cdb[8] |= 0x01;
}
CommandPacket.CdbLength = 10;
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;
}
EFI_STATUS
SubmitRead10Command (
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 UINT32 StartLba,
IN UINT32 SectorSize
)
/*++
Routine Description:
Function to submit read 10 command.
Arguments:
ScsiIo - A pointer to SCSI IO protocol.
Timeout - The length of timeout period.
SenseData - A pointer to output sense data.
SenseDataLength - The length of output sense data.
HostAdapterStatus - The status of Host Adapter.
TargetStatus - The status of the target.
DataBuffer - A pointer to a data buffer.
DataLength - The length of data buffer.
StartLba - The start address of LBA.
SectorSize - The sector size.
Returns:
EFI_SUCCESS - The status of the unit is tested successfully.
EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
but the entire DataBuffer could not be transferred.
The actual number of bytes transferred is returned
in TransferLength.
EFI_NOT_READY - The SCSI Request Packet could not be sent because
there are too many SCSI Command Packets already
queued.
EFI_DEVICE_ERROR - A device error occurred while attempting to send
the SCSI Request Packet.
EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
EFI_UNSUPPORTED - The command described by the SCSI Request Packet
is not supported by the SCSI initiator(i.e., SCSI
Host Controller).
EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
Request Packet to execute.
--*/
{
EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;
UINT64 Lun;
UINT8 *Target;
UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];
EFI_STATUS Status;
UINT8 Cdb[10];
EfiZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
EfiZeroMem (Cdb, 10);
CommandPacket.Timeout = Timeout;
CommandPacket.InDataBuffer = DataBuffer;
CommandPacket.SenseData = SenseData;
CommandPacket.InTransferLength= *DataLength;
CommandPacket.Cdb = Cdb;
//
// Fill Cdb for Read (10) Command
//
Target = &TargetArray[0];
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
Cdb[0] = EFI_SCSI_OP_READ10;
Cdb[1] = (UINT8) (Lun & 0xe0);
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);
CommandPacket.CdbLength = 10;
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;
}
EFI_STATUS
SubmitWrite10Command (
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 UINT32 StartLba,
IN UINT32 SectorSize
)
/*++
Routine Description:
Function to submit SCSI write 10 command.
Arguments:
ScsiIo - A pointer to SCSI IO protocol.
Timeout - The length of timeout period.
SenseData - A pointer to output sense data.
SenseDataLength - The length of output sense data.
HostAdapterStatus - The status of Host Adapter.
TargetStatus - The status of the target.
DataBuffer - A pointer to a data buffer.
DataLength - The length of data buffer.
StartLba - The start address of LBA.
SectorSize - The sector size.
Returns:
EFI_SUCCESS - The status of the unit is tested successfully.
EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
but the entire DataBuffer could not be transferred.
The actual number of bytes transferred is returned
in TransferLength.
EFI_NOT_READY - The SCSI Request Packet could not be sent because
there are too many SCSI Command Packets already
queued.
EFI_DEVICE_ERROR - A device error occurred while attempting to send
the SCSI Request Packet.
EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
EFI_UNSUPPORTED - The command described by the SCSI Request Packet
is not supported by the SCSI initiator(i.e., SCSI
Host Controller).
EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
Request Packet to execute.
--*/
{
EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;
UINT64 Lun;
UINT8 *Target;
UINT8 TargetArray[EFI_SCSI_TARGET_MAX_BYTES];
EFI_STATUS Status;
UINT8 Cdb[10];
EfiZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
EfiZeroMem (Cdb, 10);
CommandPacket.Timeout = Timeout;
CommandPacket.OutDataBuffer = DataBuffer;
CommandPacket.SenseData = SenseData;
CommandPacket.OutTransferLength= *DataLength;
CommandPacket.Cdb = Cdb;
//
// Fill Cdb for Write (10) Command
//
Target = &TargetArray[0];
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
Cdb[0] = EFI_SCSI_OP_WRITE10;
Cdb[1] = (UINT8) (Lun & 0xe0);
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;
CommandPacket.CdbLength = 10;
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.InTransferLength;
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?