mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-04 05:25:45 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			649 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			649 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c) 2006, Intel Corporation                                                         
 | 
						|
All rights reserved. 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        
 | 
						|
http://opensource.org/licenses/bsd-license.php                                            
 | 
						|
                                                                                          
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
 | 
						|
 | 
						|
Module Name:
 | 
						|
 | 
						|
    ScsiLib.c
 | 
						|
    
 | 
						|
Abstract: 
 | 
						|
    
 | 
						|
 | 
						|
Revision History
 | 
						|
--*/
 | 
						|
 | 
						|
 | 
						|
#include <IndustryStandard/scsi.h>
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
SubmitTestUnitReadyCommand (
 | 
						|
  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,
 | 
						|
  IN  UINT64                Timeout,
 | 
						|
  OUT VOID                  *SenseData,
 | 
						|
  OUT UINT8                 *SenseDataLength,
 | 
						|
  OUT UINT8                 *HostAdapterStatus,
 | 
						|
  OUT UINT8                 *TargetStatus
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Function tests the ready status of SCSI unit.
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  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 InTransferLength.
 | 
						|
    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;
 | 
						|
  UINT32                          Target;
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  UINT8                           Cdb[6];
 | 
						|
 | 
						|
  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
 | 
						|
  ZeroMem (Cdb, 6);
 | 
						|
 | 
						|
  CommandPacket.Timeout         = Timeout;
 | 
						|
  CommandPacket.DataBuffer      = NULL;
 | 
						|
  CommandPacket.SenseData       = SenseData;
 | 
						|
  CommandPacket.TransferLength  = 0;
 | 
						|
  CommandPacket.Cdb             = Cdb;
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Cdb for Test Unit Ready Command
 | 
						|
  //
 | 
						|
  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
 | 
						|
 | 
						|
  Cdb[0]                        = EFI_SCSI_OP_TEST_UNIT_READY;
 | 
						|
  Cdb[1]                        = (UINT8) (Lun & 0xe0);
 | 
						|
  CommandPacket.CdbLength       = (UINT8) 6;
 | 
						|
  CommandPacket.SenseDataLength = *SenseDataLength;
 | 
						|
 | 
						|
  Status                        = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);
 | 
						|
 | 
						|
  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;
 | 
						|
  *TargetStatus                 = CommandPacket.TargetStatus;
 | 
						|
  *SenseDataLength              = CommandPacket.SenseDataLength;
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
SubmitInquiryCommand (
 | 
						|
  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,
 | 
						|
  IN  UINT64                Timeout,
 | 
						|
  IN  VOID                  *SenseData,
 | 
						|
  IN OUT UINT8              *SenseDataLength,
 | 
						|
  OUT UINT8                 *HostAdapterStatus,
 | 
						|
  OUT UINT8                 *TargetStatus,
 | 
						|
  IN OUT VOID               *InquiryDataBuffer,
 | 
						|
  IN OUT UINT32             *InquiryDataLength,
 | 
						|
  IN  BOOLEAN               EnableVitalProductData
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Function to submit SCSI inquiry 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.
 | 
						|
  InquiryDataBuffer    - A pointer to inquiry data buffer.
 | 
						|
  InquiryDataLength    - The length of inquiry data buffer.
 | 
						|
  EnableVitalProductData - Boolean to enable Vital Product Data.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  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;
 | 
						|
  UINT32                          Target;
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  UINT8                           Cdb[6];
 | 
						|
 | 
						|
  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
 | 
						|
  ZeroMem (Cdb, 6);
 | 
						|
 | 
						|
  CommandPacket.Timeout         = Timeout;
 | 
						|
  CommandPacket.DataBuffer      = InquiryDataBuffer;
 | 
						|
  CommandPacket.TransferLength  = *InquiryDataLength;
 | 
						|
  CommandPacket.SenseData       = SenseData;
 | 
						|
  CommandPacket.SenseDataLength = *SenseDataLength;
 | 
						|
  CommandPacket.Cdb             = Cdb;
 | 
						|
 | 
						|
  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
 | 
						|
 | 
						|
  Cdb[0]  = EFI_SCSI_OP_INQUIRY;
 | 
						|
  Cdb[1]  = (UINT8) (Lun & 0xe0);
 | 
						|
  if (EnableVitalProductData) {
 | 
						|
    Cdb[1] |= 0x01;
 | 
						|
  }
 | 
						|
 | 
						|
  if (*InquiryDataLength > 0xff) {
 | 
						|
    *InquiryDataLength = 0xff;
 | 
						|
  }
 | 
						|
 | 
						|
  Cdb[4]                      = (UINT8) (*InquiryDataLength);
 | 
						|
  CommandPacket.CdbLength     = (UINT8) 6;
 | 
						|
  CommandPacket.DataDirection = EFI_SCSI_DATA_IN;
 | 
						|
 | 
						|
  Status                      = ScsiIo->ExecuteSCSICommand (ScsiIo, &CommandPacket, NULL);
 | 
						|
 | 
						|
  *HostAdapterStatus          = CommandPacket.HostAdapterStatus;
 | 
						|
  *TargetStatus               = CommandPacket.TargetStatus;
 | 
						|
  *SenseDataLength            = CommandPacket.SenseDataLength;
 | 
						|
  *InquiryDataLength          = CommandPacket.TransferLength;
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
SubmitModeSense10Command (
 | 
						|
  IN  EFI_SCSI_IO_PROTOCOL    *ScsiIo,
 | 
						|
  IN  UINT64                  Timeout,
 | 
						|
  IN  VOID                    *SenseData,
 | 
						|
  IN OUT UINT8                *SenseDataLength,
 | 
						|
  OUT UINT8                   *HostAdapterStatus,
 | 
						|
  OUT UINT8                   *TargetStatus,
 | 
						|
  IN  VOID                    *DataBuffer,
 | 
						|
  IN OUT UINT32               *DataLength,
 | 
						|
  IN  UINT8                   DBDField, OPTIONAL
 | 
						|
  IN  UINT8                   PageControl,
 | 
						|
  IN  UINT8                   PageCode
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Function to submit SCSI mode sense 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 input data buffer.
 | 
						|
  DataLength           - The length of input data buffer.
 | 
						|
  DBDField             - The DBD Field (Optional).
 | 
						|
  PageControl          - Page Control.
 | 
						|
  PageCode             - Page code.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  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;
 | 
						|
  UINT32                          Target;
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  UINT8                           Cdb[10];
 | 
						|
 | 
						|
  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
 | 
						|
  ZeroMem (Cdb, 10);
 | 
						|
 | 
						|
  CommandPacket.Timeout         = Timeout;
 | 
						|
  CommandPacket.DataBuffer      = DataBuffer;
 | 
						|
  CommandPacket.SenseData       = SenseData;
 | 
						|
  CommandPacket.TransferLength  = *DataLength;
 | 
						|
  CommandPacket.Cdb             = Cdb;
 | 
						|
  //
 | 
						|
  // Fill Cdb for Mode Sense (10) Command
 | 
						|
  //
 | 
						|
  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);
 | 
						|
 | 
						|
  Cdb[0]                        = EFI_SCSI_OP_MODE_SEN10;
 | 
						|
  Cdb[1]                        = (UINT8) ((Lun & 0xe0) + ((DBDField << 3) & 0x08));
 | 
						|
  Cdb[2]                        = (UINT8) ((PageControl & 0xc0) | (PageCode & 0x3f));
 | 
						|
  Cdb[7]                        = (UINT8) (*DataLength >> 8);
 | 
						|
  Cdb[8]                        = (UINT8) (*DataLength);
 | 
						|
 | 
						|
  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.TransferLength;
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
SubmitRequestSenseCommand (
 | 
						|
  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,
 | 
						|
  IN  UINT64                Timeout,
 | 
						|
  IN  VOID                  *SenseData,
 | 
						|
  IN OUT UINT8              *SenseDataLength,
 | 
						|
  OUT UINT8                 *HostAdapterStatus,
 | 
						|
  OUT UINT8                 *TargetStatus
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Function to submit SCSI request sense 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.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  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;
 | 
						|
  UINT32                          Target;
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  UINT8                           Cdb[6];
 | 
						|
 | 
						|
  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
 | 
						|
  ZeroMem (Cdb, 6);
 | 
						|
 | 
						|
  CommandPacket.Timeout         = Timeout;
 | 
						|
  CommandPacket.DataBuffer      = SenseData;
 | 
						|
  CommandPacket.SenseData       = NULL;
 | 
						|
  CommandPacket.TransferLength  = *SenseDataLength;
 | 
						|
  CommandPacket.Cdb             = Cdb;
 | 
						|
  //
 | 
						|
  // Fill Cdb for Request Sense Command
 | 
						|
  //
 | 
						|
  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.TransferLength;
 | 
						|
 | 
						|
  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:
 | 
						|
 | 
						|
  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;
 | 
						|
  UINT32                          Target;
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  UINT8                           Cdb[10];
 | 
						|
 | 
						|
  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
 | 
						|
  ZeroMem (Cdb, 10);
 | 
						|
 | 
						|
  CommandPacket.Timeout         = Timeout;
 | 
						|
  CommandPacket.DataBuffer      = DataBuffer;
 | 
						|
  CommandPacket.SenseData       = SenseData;
 | 
						|
  CommandPacket.TransferLength  = *DataLength;
 | 
						|
  CommandPacket.Cdb             = Cdb;
 | 
						|
  //
 | 
						|
  // Fill Cdb for Read Capacity Command
 | 
						|
  //
 | 
						|
  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.
 | 
						|
    //
 | 
						|
    ZeroMem ((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.TransferLength;
 | 
						|
 | 
						|
  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:
 | 
						|
 | 
						|
  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;
 | 
						|
  UINT32                          Target;
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  UINT8                           Cdb[10];
 | 
						|
 | 
						|
  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
 | 
						|
  ZeroMem (Cdb, 10);
 | 
						|
 | 
						|
  CommandPacket.Timeout         = Timeout;
 | 
						|
  CommandPacket.DataBuffer      = DataBuffer;
 | 
						|
  CommandPacket.SenseData       = SenseData;
 | 
						|
  CommandPacket.TransferLength  = *DataLength;
 | 
						|
  CommandPacket.Cdb             = Cdb;
 | 
						|
  //
 | 
						|
  // Fill Cdb for Read (10) Command
 | 
						|
  //
 | 
						|
  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;
 | 
						|
  Cdb[7]                        = (UINT8) (SectorSize >> 8);
 | 
						|
  Cdb[8]                        = (UINT8) SectorSize;
 | 
						|
 | 
						|
  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.TransferLength;
 | 
						|
 | 
						|
  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:
 | 
						|
 | 
						|
  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 InTransferLength.
 | 
						|
    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;
 | 
						|
  UINT32                          Target;
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  UINT8                           Cdb[10];
 | 
						|
 | 
						|
  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));
 | 
						|
  ZeroMem (Cdb, 10);
 | 
						|
 | 
						|
  CommandPacket.Timeout         = Timeout;
 | 
						|
  CommandPacket.DataBuffer      = DataBuffer;
 | 
						|
  CommandPacket.SenseData       = SenseData;
 | 
						|
  CommandPacket.TransferLength  = *DataLength;
 | 
						|
  CommandPacket.Cdb             = Cdb;
 | 
						|
  //
 | 
						|
  // Fill Cdb for Write (10) Command
 | 
						|
  //
 | 
						|
  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.TransferLength;
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |