]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/UefiScsiLib/UefiScsiLib.c
Read-Capacity16 command added for SCSI drivers
[mirror_edk2.git] / MdePkg / Library / UefiScsiLib / UefiScsiLib.c
index e26905e1e33e9dbc61bf2ebae9dcf7b300a342b3..1458efd2f918dced2b563fe0e826611050b253d6 100644 (file)
@@ -635,6 +635,100 @@ ScsiReadCapacityCommand (
 }\r
 \r
 \r
+/**\r
+  Function to submit read capacity16 command.\r
+\r
+  @param  ScsiIo            A pointer to SCSI IO protocol.\r
+  @param  Timeout           The length of timeout period.\r
+  @param  SenseData         A pointer to output sense data.\r
+  @param  SenseDataLength   The length of output sense data.\r
+  @param  HostAdapterStatus The status of Host Adapter.\r
+  @param  TargetStatus      The status of the target.\r
+  @param  DataBuffer        A pointer to a data buffer.\r
+  @param  DataLength        The length of data buffer.\r
+  @param  PMI               Partial medium indicator.\r
+\r
+  @retval  EFI_SUCCESS            The status of the unit is tested successfully.\r
+  @retval  EFI_BAD_BUFFER_SIZE    The SCSI Request Packet was executed, \r
+                                  but the entire DataBuffer could not be transferred.\r
+                                  The actual number of bytes transferred is returned\r
+                                  in TransferLength.\r
+  @retval  EFI_NOT_READY          The SCSI Request Packet could not be sent because \r
+                                  there are too many SCSI Command Packets already \r
+                                  queued.\r
+  @retval  EFI_DEVICE_ERROR       A device error occurred while attempting to send \r
+                                  the SCSI Request Packet.\r
+  @retval  EFI_INVALID_PARAMETER  The contents of CommandPacket are invalid.  \r
+  @retval  EFI_UNSUPPORTED        The command described by the SCSI Request Packet\r
+                                  is not supported by the SCSI initiator(i.e., SCSI \r
+                                  Host Controller).\r
+  @retval  EFI_TIMEOUT            A timeout occurred while waiting for the SCSI \r
+                                  Request Packet to execute.\r
+\r
+**/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiReadCapacity16Command (\r
+  IN  EFI_SCSI_IO_PROTOCOL  *ScsiIo,\r
+  IN  UINT64                Timeout,\r
+  IN  VOID                  *SenseData,\r
+  IN OUT UINT8              *SenseDataLength,\r
+  OUT UINT8                 *HostAdapterStatus,\r
+  OUT UINT8                 *TargetStatus,\r
+  OUT VOID                  *DataBuffer,\r
+  IN OUT UINT32             *DataLength,\r
+  IN  BOOLEAN               PMI\r
+  )\r
+{\r
+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
+  UINT64                          Lun;\r
+  UINT8                           *Target;\r
+  UINT8                           TargetArray[EFI_SCSI_TARGET_MAX_BYTES];\r
+  EFI_STATUS                      Status;\r
+  UINT8                           Cdb[16];\r
+\r
+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
+  ZeroMem (Cdb, 16);\r
+\r
+  CommandPacket.Timeout         = Timeout;\r
+  CommandPacket.InDataBuffer    = DataBuffer;\r
+  CommandPacket.SenseData       = SenseData;\r
+  CommandPacket.InTransferLength= *DataLength;\r
+  CommandPacket.Cdb             = Cdb;\r
+  //\r
+  // Fill Cdb for Read Capacity Command\r
+  //\r
+  Target = &TargetArray[0];\r
+  ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
+\r
+  Cdb[0]  = EFI_SCSI_OP_READ_CAPACITY16;\r
+  Cdb[1]  = 0x10;\r
+  if (!PMI) {\r
+    //\r
+    // Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.\r
+    //\r
+    ZeroMem ((Cdb + 2), 8);\r
+  } else {\r
+    Cdb[14] |= 0x01;\r
+  }\r
+\r
+  Cdb[13] = 0x20;\r
+  CommandPacket.CdbLength       = 16;\r
+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;\r
+  CommandPacket.SenseDataLength = *SenseDataLength;\r
+\r
+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
+\r
+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;\r
+  *TargetStatus                 = CommandPacket.TargetStatus;\r
+  *SenseDataLength              = CommandPacket.SenseDataLength;\r
+  *DataLength                   = CommandPacket.InTransferLength;\r
+\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Execute Read(10) SCSI command on a specific SCSI target.\r
 \r