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 + -
显示快捷键?