-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- ScsiLib.c\r
- \r
-Abstract: \r
- \r
-\r
-Revision History\r
---*/\r
-\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <PiDxe.h>\r
-\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/ScsiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
+/** @file\r
+ UEFI SCSI Library implementation\r
+\r
+ Copyright (c) 2006 - 2008, Intel Corporation.<BR>\r
+ All rights reserved. This program and the accompanying materials \r
+ are licensed and made available under the terms and conditions of the BSD License \r
+ which accompanies this distribution. The full text of the license may be found at \r
+ http://opensource.org/licenses/bsd-license.php \r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
\r
-#include <IndustryStandard/scsi.h>\r
+**/\r
\r
+\r
+#include <Uefi.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiScsiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+ \r
+#include <IndustryStandard/Scsi.h>\r
+ \r
+ \r
+ //\r
+ // Max bytes needed to represent ID of a SCSI device\r
+ //\r
+#define EFI_SCSI_TARGET_MAX_BYTES (0x10)\r
+ \r
+ //\r
+ // bit5..7 are for Logical unit number\r
+ // 11100000b (0xe0)\r
+ //\r
+#define EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK 0xe0\r
+ \r
+ //\r
+ // Scsi Command Length six or ten\r
+ //\r
+#define EFI_SCSI_OP_LENGTH_SIX 0x6\r
+#define EFI_SCSI_OP_LENGTH_TEN 0xa\r
+\r
+\r
+\r
+/**\r
+ Execute Test Unit Ready SCSI command on a specific SCSI target.\r
+\r
+ Executes the Test Unit Ready command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+\r
+\r
+ @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
+ for the specific SCSI target.\r
+ @param[in] Timeout The timeout in 100 ns units to use for the execution\r
+ of this SCSI Request Packet. A Timeout value of\r
+ zero means that this function will wait indefinitely\r
+ for the SCSI Request Packet to execute. If Timeout\r
+ is greater than zero, then this function will return\r
+ EFI_TIMEOUT if the time required to execute the SCSI\r
+ Request Packet is greater than Timeout.\r
+ @param[in, out] SenseData A pointer to sense data that was generated by\r
+ the execution of the SCSI Request Packet. This\r
+ buffer must be allocated by the caller.\r
+ If SenseDataLength is 0, then this parameter is\r
+ optional and may be NULL.\r
+ @param[in, out] SenseDataLength On input, a pointer to the length in bytes of\r
+ the SenseData buffer. On output, a pointer to\r
+ the number of bytes written to the SenseData buffer. \r
+ @param[out] HostAdapterStatus The status of the SCSI Host Controller that produces\r
+ the SCSI bus containing the SCSI target specified by\r
+ ScsiIo when the SCSI Request Packet was executed.\r
+ See the EFI SCSI I/O Protocol in the UEFI Specification\r
+ for details on the possible return values.\r
+ @param[out] TargetStatus The status returned by the SCSI target specified\r
+ by ScsiIo when the SCSI Request Packet was executed\r
+ on the SCSI Host Controller. See the EFI SCSI I/O\r
+ Protocol in the UEFI Specification for details on\r
+ the possible return values. \r
+\r
+ @retval EFI_SUCCESS The command was executed successfully.\r
+ See HostAdapterStatus, TargetStatus, SenseDataLength,\r
+ and SenseData in that order for additional status\r
+ information.\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. The SCSI Request Packet was not sent, so\r
+ no additional status information is available.\r
+ The caller may retry again later.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send\r
+ SCSI Request Packet. See HostAdapterStatus,\r
+ TargetStatus, SenseDataLength, and SenseData in that\r
+ order for additional status information.\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). The SCSI Request Packet was not\r
+ sent, so no additional status information is available.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request\r
+ Packet to execute. See HostAdapterStatus, TargetStatus,\r
+ SenseDataLength, and SenseData in that order for\r
+ additional status information.\r
+\r
+**/\r
EFI_STATUS\r
-SubmitTestUnitReadyCommand (\r
- IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
- IN UINT64 Timeout,\r
- OUT VOID *SenseData,\r
- OUT UINT8 *SenseDataLength,\r
- OUT UINT8 *HostAdapterStatus,\r
- OUT UINT8 *TargetStatus\r
+EFIAPI\r
+ScsiTestUnitReadyCommand (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Function tests the ready status of SCSI unit.\r
-\r
-Arguments:\r
- ScsiIo - A pointer to SCSI IO protocol.\r
- Timeout - The length of timeout period.\r
- SenseData - A pointer to output sense data.\r
- SenseDataLength - The length of output sense data.\r
- HostAdapterStatus - The status of Host Adapter.\r
- TargetStatus - The status of the target.\r
-\r
-Returns:\r
-\r
- Returns:\r
- EFI_SUCCESS - The status of the unit is tested successfully.\r
- 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 InTransferLength.\r
- EFI_NOT_READY - The SCSI Request Packet could not be sent because \r
- there are too many SCSI Command Packets already \r
- queued.\r
- EFI_DEVICE_ERROR - A device error occurred while attempting to send \r
- the SCSI Request Packet.\r
- EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid. \r
- 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
- EFI_TIMEOUT - A timeout occurred while waiting for the SCSI \r
- Request Packet to execute.\r
-\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[6];\r
+ UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
\r
+ ASSERT (SenseDataLength != NULL);\r
+ ASSERT (HostAdapterStatus != NULL);\r
+ ASSERT (TargetStatus != NULL);\r
+ ASSERT (ScsiIo != NULL);\r
\r
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 6);\r
+ ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
\r
CommandPacket.Timeout = Timeout;\r
CommandPacket.InDataBuffer = NULL;\r
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
\r
Cdb[0] = EFI_SCSI_OP_TEST_UNIT_READY;\r
- Cdb[1] = (UINT8) (Lun & 0xe0);\r
- CommandPacket.CdbLength = (UINT8) 6;\r
+ Cdb[1] = (UINT8) ((Lun << 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);\r
+ CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
CommandPacket.SenseDataLength = *SenseDataLength;\r
\r
Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
return Status;\r
}\r
\r
+\r
+/**\r
+ Execute Inquiry SCSI command on a specific SCSI target.\r
+\r
+ Executes the Inquiry command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+ If InquiryDataLength is NULL, then ASSERT().\r
+\r
+ @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
+ for the specific SCSI target.\r
+ @param[in] Timeout The timeout in 100 ns units to use for the\r
+ execution of this SCSI Request Packet. A Timeout\r
+ value of zero means that this function will wait\r
+ indefinitely for the SCSI Request Packet to execute.\r
+ If Timeout is greater than zero, then this function\r
+ will return EFI_TIMEOUT if the time required to\r
+ execute the SCSI Request Packet is greater than Timeout.\r
+ @param[in, out] SenseData A pointer to sense data that was generated\r
+ by the execution of the SCSI Request Packet.\r
+ This buffer must be allocated by the caller.\r
+ If SenseDataLength is 0, then this parameter\r
+ is optional and may be NULL.\r
+ @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.\r
+ On output, the number of bytes written to the SenseData buffer. \r
+ @param[out] HostAdapterStatus The status of the SCSI Host Controller that\r
+ produces the SCSI bus containing the SCSI\r
+ target specified by ScsiIo when the SCSI\r
+ Request Packet was executed. See the EFI\r
+ SCSI I/O Protocol in the UEFI Specification\r
+ for details on the possible return values.\r
+ @param[out] TargetStatus The status returned by the SCSI target specified\r
+ by ScsiIo when the SCSI Request Packet was\r
+ executed on the SCSI Host Controller.\r
+ See the EFI SCSI I/O Protocol in the UEFI\r
+ Specification for details on the possible\r
+ return values. \r
+ @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated\r
+ by the execution of the SCSI Request Packet.\r
+ This buffer must be allocated by the caller.\r
+ If InquiryDataLength is 0, then this parameter\r
+ is optional and may be NULL. \r
+ @param[in, out] InquiryDataLength On input, a pointer to the length in bytes\r
+ of the InquiryDataBuffer buffer.\r
+ On output, a pointer to the number of bytes\r
+ written to the InquiryDataBuffer buffer.\r
+ @param[in] EnableVitalProductData If TRUE, then the supported vital product\r
+ data is returned in InquiryDataBuffer.\r
+ If FALSE, then the standard inquiry data is\r
+ returned in InquiryDataBuffer. \r
+\r
+ @retval EFI_SUCCESS The command was executed successfully. See HostAdapterStatus,\r
+ TargetStatus, SenseDataLength, and SenseData in that order\r
+ for additional status information.\r
+ @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
+ InquiryDataBuffer could not be transferred. The actual\r
+ number of bytes transferred is returned in InquiryDataLength.\r
+ @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there\r
+ are too many SCSI Command Packets already queued.\r
+ The SCSI Request Packet was not sent, so no additional\r
+ status information is available. The caller may retry again later.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI\r
+ Request Packet. See HostAdapterStatus, TargetStatus,\r
+ SenseDataLength, and SenseData in that order for additional\r
+ status information.\r
+ @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not\r
+ supported by the SCSI initiator(i.e., SCSI Host Controller).\r
+ The SCSI Request Packet was not sent, so no additional\r
+ status information is available.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request\r
+ Packet to execute. See HostAdapterStatus, TargetStatus,\r
+ SenseDataLength, and SenseData in that order for\r
+ additional status information.\r
+\r
+**/\r
EFI_STATUS\r
-SubmitInquiryCommand (\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
- IN OUT VOID *InquiryDataBuffer,\r
- IN OUT UINT32 *InquiryDataLength,\r
- IN BOOLEAN EnableVitalProductData\r
+EFIAPI\r
+ScsiInquiryCommand (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus,\r
+ IN OUT VOID *InquiryDataBuffer, OPTIONAL\r
+ IN OUT UINT32 *InquiryDataLength,\r
+ IN BOOLEAN EnableVitalProductData\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Function to submit SCSI inquiry command.\r
-\r
-Arguments:\r
- ScsiIo - A pointer to SCSI IO protocol.\r
- Timeout - The length of timeout period.\r
- SenseData - A pointer to output sense data.\r
- SenseDataLength - The length of output sense data.\r
- HostAdapterStatus - The status of Host Adapter.\r
- TargetStatus - The status of the target.\r
- InquiryDataBuffer - A pointer to inquiry data buffer.\r
- InquiryDataLength - The length of inquiry data buffer.\r
- EnableVitalProductData - Boolean to enable Vital Product Data.\r
-\r
-Returns:\r
-\r
- Returns:\r
- EFI_SUCCESS - The status of the unit is tested successfully.\r
- 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
- EFI_NOT_READY - The SCSI Request Packet could not be sent because \r
- there are too many SCSI Command Packets already \r
- queued.\r
- EFI_DEVICE_ERROR - A device error occurred while attempting to send \r
- the SCSI Request Packet.\r
- EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid. \r
- 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
- EFI_TIMEOUT - A timeout occurred while waiting for the SCSI \r
- Request Packet to execute.\r
-\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[6];\r
+ UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
+\r
+ ASSERT (SenseDataLength != NULL);\r
+ ASSERT (HostAdapterStatus != NULL);\r
+ ASSERT (TargetStatus != NULL);\r
+ ASSERT (InquiryDataLength != NULL);\r
+ ASSERT (ScsiIo != NULL);\r
\r
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 6);\r
+ ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
\r
CommandPacket.Timeout = Timeout;\r
CommandPacket.InDataBuffer = InquiryDataBuffer;\r
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
\r
Cdb[0] = EFI_SCSI_OP_INQUIRY;\r
- Cdb[1] = (UINT8) (Lun & 0xe0);\r
+ Cdb[1] = (UINT8) ((Lun << 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);\r
if (EnableVitalProductData) {\r
Cdb[1] |= 0x01;\r
}\r
}\r
\r
Cdb[4] = (UINT8) (*InquiryDataLength);\r
- CommandPacket.CdbLength = (UINT8) 6;\r
+ CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
\r
Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
return Status;\r
}\r
\r
+\r
+/**\r
+ Execute Mode Sense(10) SCSI command on a specific SCSI target.\r
+\r
+ Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout\r
+ after Timeout 100 ns units. The DBDField, PageControl, and PageCode parameters\r
+ are used to construct the CDB for this SCSI command.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+ If DataLength is NULL, then ASSERT().\r
+\r
+\r
+ @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
+ for the specific SCSI target.\r
+ @param[in] Timeout The timeout in 100 ns units to use for the\r
+ execution of this SCSI Request Packet. A Timeout\r
+ value of zero means that this function will wait\r
+ indefinitely for the SCSI Request Packet to execute.\r
+ If Timeout is greater than zero, then this function\r
+ will return EFI_TIMEOUT if the time required to\r
+ execute the SCSI Request Packet is greater than Timeout.\r
+ @param[in, out] SenseData A pointer to sense data that was generated\r
+ by the execution of the SCSI Request Packet.\r
+ This buffer must be allocated by the caller.\r
+ If SenseDataLength is 0, then this parameter\r
+ is optional and may be NULL.\r
+ @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.\r
+ On output, the number of bytes written to the SenseData buffer. \r
+ @param[out] HostAdapterStatus The status of the SCSI Host Controller that\r
+ produces the SCSI bus containing the SCSI target\r
+ specified by ScsiIo when the SCSI Request Packet\r
+ was executed. See the EFI SCSI I/O Protocol in the\r
+ UEFI Specification for details on the possible\r
+ return values.\r
+ @param[out] TargetStatus The status returned by the SCSI target specified\r
+ by ScsiIo when the SCSI Request Packet was executed\r
+ on the SCSI Host Controller. See the EFI SCSI\r
+ I/O Protocol in the UEFI Specification for details\r
+ on the possible return values.\r
+ @param[in, out] DataBuffer A pointer to data that was generated by the\r
+ execution of the SCSI Request Packet. This\r
+ buffer must be allocated by the caller. If\r
+ DataLength is 0, then this parameter is optional\r
+ and may be NULL. \r
+ @param[in, out] DataLength On input, a pointer to the length in bytes of\r
+ the DataBuffer buffer. On output, a pointer\r
+ to the number of bytes written to the DataBuffer\r
+ buffer. \r
+ @param[in] DBDField Specifies the DBD field of the CDB for this SCSI Command.\r
+ @param[in] PageControl Specifies the PC field of the CDB for this SCSI Command. \r
+ @param[in] PageCode Specifies the Page Control field of the CDB for this SCSI Command. \r
+\r
+ @retval EFI_SUCCESS The command was executed successfully.\r
+ See HostAdapterStatus, TargetStatus, SenseDataLength,\r
+ and SenseData in that order for additional status information.\r
+ @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the\r
+ entire DataBuffer could not be transferred.\r
+ The actual number of bytes transferred is returned\r
+ in DataLength.\r
+ @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
+ there are too many SCSI Command Packets already queued.\r
+ The SCSI Request Packet was not sent, so no additional\r
+ status information is available. The caller may retry\r
+ again later.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send\r
+ SCSI Request Packet. See HostAdapterStatus, TargetStatus,\r
+ SenseDataLength, and SenseData in that order for\r
+ additional status information.\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). The SCSI Request Packet was not\r
+ sent, so no additional status information is available.\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI\r
+ Request Packet to execute. See HostAdapterStatus,\r
+ TargetStatus, SenseDataLength, and SenseData in that\r
+ order for additional status information.\r
+\r
+**/\r
EFI_STATUS\r
-SubmitModeSense10Command (\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
- IN VOID *DataBuffer,\r
- IN OUT UINT32 *DataLength,\r
- IN UINT8 DBDField, OPTIONAL\r
- IN UINT8 PageControl,\r
- IN UINT8 PageCode\r
+EFIAPI\r
+ScsiModeSense10Command (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus,\r
+ IN OUT VOID *DataBuffer, OPTIONAL\r
+ IN OUT UINT32 *DataLength,\r
+ IN UINT8 DBDField, OPTIONAL\r
+ IN UINT8 PageControl,\r
+ IN UINT8 PageCode\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Function to submit SCSI mode sense 10 command.\r
-\r
-Arguments:\r
- ScsiIo - A pointer to SCSI IO protocol.\r
- Timeout - The length of timeout period.\r
- SenseData - A pointer to output sense data.\r
- SenseDataLength - The length of output sense data.\r
- HostAdapterStatus - The status of Host Adapter.\r
- TargetStatus - The status of the target.\r
- DataBuffer - A pointer to input data buffer.\r
- DataLength - The length of input data buffer.\r
- DBDField - The DBD Field (Optional).\r
- PageControl - Page Control.\r
- PageCode - Page code.\r
-\r
-Returns:\r
-\r
- Returns:\r
- EFI_SUCCESS - The status of the unit is tested successfully.\r
- EFI_WARN_BUFFER_TOO_SMALL - 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
- EFI_NOT_READY - The SCSI Request Packet could not be sent because \r
- there are too many SCSI Command Packets already \r
- queued.\r
- EFI_DEVICE_ERROR - A device error occurred while attempting to send \r
- the SCSI Request Packet.\r
- EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid. \r
- 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
- EFI_TIMEOUT - A timeout occurred while waiting for the SCSI \r
- Request Packet to execute.\r
-\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[10];\r
+ UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
+\r
+ ASSERT (SenseDataLength != NULL);\r
+ ASSERT (HostAdapterStatus != NULL);\r
+ ASSERT (TargetStatus != NULL);\r
+ ASSERT (DataLength != NULL);\r
+ ASSERT (ScsiIo != NULL);\r
\r
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 10);\r
+ ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
\r
CommandPacket.Timeout = Timeout;\r
CommandPacket.InDataBuffer = DataBuffer;\r
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
\r
Cdb[0] = EFI_SCSI_OP_MODE_SEN10;\r
- Cdb[1] = (UINT8) (Lun & 0xe0 + (DBDField << 3) & 0x08);\r
- Cdb[2] = (UINT8) ((PageControl & 0xc0) | (PageCode & 0x3f));\r
+ //\r
+ // DBDField is in Cdb[1] bit3 of (bit7..0)\r
+ //\r
+ Cdb[1] = (UINT8) (((Lun << 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK) + ((DBDField << 3) & 0x08));\r
+ //\r
+ // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0\r
+ //\r
+ Cdb[2] = (UINT8) (((PageControl << 6) & 0xc0) | (PageCode & 0x3f));\r
Cdb[7] = (UINT8) (*DataLength >> 8);\r
Cdb[8] = (UINT8) (*DataLength);\r
\r
- CommandPacket.CdbLength = 10;\r
+ CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
CommandPacket.SenseDataLength = *SenseDataLength;\r
\r
return Status;\r
}\r
\r
+\r
+/**\r
+ Execute Request Sense SCSI command on a specific SCSI target.\r
+\r
+ Executes the Request Sense command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+\r
+ @param[in] ScsiIo A pointer to SCSI IO protocol.\r
+ @param[in] Timeout The length of timeout period.\r
+ @param[in, out] SenseData A pointer to output sense data.\r
+ @param[in, out] SenseDataLength The length of output sense data.\r
+ @param[out] HostAdapterStatus The status of Host Adapter.\r
+ @param[out] TargetStatus The status of the target.\r
+\r
+ @retval EFI_SUCCESS Command is executed successfully.\r
+ @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are\r
+ too many SCSI Command Packets already queued.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
+ @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by\r
+ the SCSI initiator(i.e., SCSI Host Controller)\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
+\r
+**/\r
EFI_STATUS\r
-SubmitRequestSenseCommand (\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
+EFIAPI\r
+ScsiRequestSenseCommand (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Function to submit SCSI request sense command.\r
-\r
-Arguments:\r
- ScsiIo - A pointer to SCSI IO protocol.\r
- Timeout - The length of timeout period.\r
- SenseData - A pointer to output sense data.\r
- SenseDataLength - The length of output sense data.\r
- HostAdapterStatus - The status of Host Adapter.\r
- TargetStatus - The status of the target.\r
-\r
-Returns:\r
-\r
- Returns:\r
- EFI_SUCCESS - The status of the unit is tested successfully.\r
- EFI_WARN_BUFFER_TOO_SMALL - 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
- EFI_NOT_READY - The SCSI Request Packet could not be sent because \r
- there are too many SCSI Command Packets already \r
- queued.\r
- EFI_DEVICE_ERROR - A device error occurred while attempting to send \r
- the SCSI Request Packet.\r
- EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid. \r
- 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
- EFI_TIMEOUT - A timeout occurred while waiting for the SCSI \r
- Request Packet to execute.\r
-\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[6];\r
+ UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
+\r
+ ASSERT (SenseDataLength != NULL);\r
+ ASSERT (HostAdapterStatus != NULL);\r
+ ASSERT (TargetStatus != NULL);\r
+ ASSERT (ScsiIo != NULL);\r
\r
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 6);\r
+ ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
\r
CommandPacket.Timeout = Timeout;\r
CommandPacket.InDataBuffer = SenseData;\r
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
\r
Cdb[0] = EFI_SCSI_OP_REQUEST_SENSE;\r
- Cdb[1] = (UINT8) (Lun & 0xe0);\r
+ Cdb[1] = (UINT8) ((Lun << 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);\r
Cdb[4] = (UINT8) (*SenseDataLength);\r
\r
- CommandPacket.CdbLength = (UINT8) 6;\r
+ CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
CommandPacket.SenseDataLength = 0;\r
\r
return Status;\r
}\r
\r
+\r
+/**\r
+ Execute Read Capacity SCSI command on a specific SCSI target.\r
+\r
+ Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout after\r
+ Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+ If DataLength is NULL, then ASSERT().\r
+\r
+ @param[in] ScsiIo A pointer to SCSI IO protocol.\r
+ @param[in] Timeout The length of timeout period.\r
+ @param[in, out] SenseData A pointer to output sense data.\r
+ @param[in, out] SenseDataLength The length of output sense data.\r
+ @param[out] HostAdapterStatus The status of Host Adapter.\r
+ @param[out] TargetStatus The status of the target.\r
+ @param[in, out] DataBuffer A pointer to a data buffer.\r
+ @param[in, out] DataLength The length of data buffer.\r
+ @param[in] Pmi Partial medium indicator.\r
+\r
+ @retval EFI_SUCCESS Command is executed successfully.\r
+ @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
+ DataBuffer could not be transferred. The actual\r
+ number of bytes transferred is returned in DataLength.\r
+ @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
+ there are too many SCSI Command Packets already queued.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
+ @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
+ is not supported by the SCSI initiator(i.e., SCSI Host Controller)\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
+\r
+**/\r
EFI_STATUS\r
-SubmitReadCapacityCommand (\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
+EFIAPI\r
+ScsiReadCapacityCommand (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus,\r
+ IN OUT VOID *DataBuffer, OPTIONAL\r
+ IN OUT UINT32 *DataLength,\r
+ IN BOOLEAN Pmi\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Function to submit read capacity command.\r
-\r
-Arguments:\r
- ScsiIo - A pointer to SCSI IO protocol.\r
- Timeout - The length of timeout period.\r
- SenseData - A pointer to output sense data.\r
- SenseDataLength - The length of output sense data.\r
- HostAdapterStatus - The status of Host Adapter.\r
- TargetStatus - The status of the target.\r
- DataBuffer - A pointer to a data buffer.\r
- DataLength - The length of data buffer.\r
- PMI - Partial medium indicator.\r
-\r
-Returns:\r
-\r
- Returns:\r
- EFI_SUCCESS - The status of the unit is tested successfully.\r
- EFI_WARN_BUFFER_TOO_SMALL - 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
- EFI_NOT_READY - The SCSI Request Packet could not be sent because \r
- there are too many SCSI Command Packets already \r
- queued.\r
- EFI_DEVICE_ERROR - A device error occurred while attempting to send \r
- the SCSI Request Packet.\r
- EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid. \r
- 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
- EFI_TIMEOUT - A timeout occurred while waiting for the SCSI \r
- Request Packet to execute.\r
-\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[10];\r
+ UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
+\r
+ ASSERT (SenseDataLength != NULL);\r
+ ASSERT (HostAdapterStatus != NULL);\r
+ ASSERT (TargetStatus != NULL);\r
+ ASSERT (DataLength != NULL);\r
+ ASSERT (ScsiIo != NULL);\r
\r
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 10);\r
+ ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
\r
CommandPacket.Timeout = Timeout;\r
CommandPacket.InDataBuffer = DataBuffer;\r
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
\r
Cdb[0] = EFI_SCSI_OP_READ_CAPACITY;\r
- Cdb[1] = (UINT8) (Lun & 0xe0);\r
- if (!PMI) {\r
+ Cdb[1] = (UINT8) ((Lun << 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);\r
+ if (!Pmi) {\r
//\r
- // Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.\r
+ // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.\r
//\r
ZeroMem ((Cdb + 2), 4);\r
} else {\r
Cdb[8] |= 0x01;\r
}\r
\r
- CommandPacket.CdbLength = 10;\r
+ CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\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 Capacity SCSI 16 command on a specific SCSI target.\r
+\r
+ Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout after\r
+ Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+ If DataLength is NULL, then ASSERT().\r
+\r
+ @param[in] ScsiIo A pointer to SCSI IO protocol.\r
+ @param[in] Timeout The length of timeout period.\r
+ @param[in, out] SenseData A pointer to output sense data.\r
+ @param[in, out] SenseDataLength The length of output sense data.\r
+ @param[out] HostAdapterStatus The status of Host Adapter.\r
+ @param[out] TargetStatus The status of the target.\r
+ @param[in, out] DataBuffer A pointer to a data buffer.\r
+ @param[in, out] DataLength The length of data buffer.\r
+ @param[in] Pmi Partial medium indicator.\r
+\r
+ @retval EFI_SUCCESS Command is executed successfully.\r
+ @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
+ DataBuffer could not be transferred. The actual\r
+ number of bytes transferred is returned in DataLength.\r
+ @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
+ there are too many SCSI Command Packets already queued.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
+ @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
+ is not supported by the SCSI initiator(i.e., SCSI Host Controller)\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiReadCapacity16Command (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus,\r
+ IN OUT VOID *DataBuffer, OPTIONAL\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
return Status;\r
}\r
\r
+\r
+/**\r
+ Execute Read(10) SCSI command on a specific SCSI target.\r
+\r
+ Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout\r
+ after Timeout 100 ns units. The StartLba and SectorSize parameters are used to\r
+ construct the CDB for this SCSI command.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+ If DataLength is NULL, then ASSERT().\r
+\r
+\r
+ @param[in] ScsiIo A pointer to SCSI IO protocol.\r
+ @param[in] Timeout The length of timeout period.\r
+ @param[in, out] SenseData A pointer to output sense data.\r
+ @param[in, out] SenseDataLength The length of output sense data.\r
+ @param[out] HostAdapterStatus The status of Host Adapter.\r
+ @param[out] TargetStatus The status of the target.\r
+ @param[in, out] DataBuffer Read 10 command data.\r
+ @param[in, out] DataLength The length of data buffer.\r
+ @param[in] StartLba The start address of LBA.\r
+ @param[in] SectorSize The sector size.\r
+\r
+ @retval EFI_SUCCESS Command is executed successfully.\r
+ @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
+ not be transferred. The actual number of bytes transferred is returned in DataLength.\r
+ @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
+ SCSI Command Packets already queued.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
+ @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
+ the SCSI initiator(i.e., SCSI Host Controller)\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
+\r
+**/\r
EFI_STATUS\r
-SubmitRead10Command (\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 UINT32 StartLba,\r
- IN UINT32 SectorSize\r
+EFIAPI\r
+ScsiRead10Command (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus,\r
+ IN OUT VOID *DataBuffer, OPTIONAL\r
+ IN OUT UINT32 *DataLength,\r
+ IN UINT32 StartLba,\r
+ IN UINT32 SectorSize\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Function to submit read 10 command.\r
-\r
-Arguments:\r
- ScsiIo - A pointer to SCSI IO protocol.\r
- Timeout - The length of timeout period.\r
- SenseData - A pointer to output sense data.\r
- SenseDataLength - The length of output sense data.\r
- HostAdapterStatus - The status of Host Adapter.\r
- TargetStatus - The status of the target.\r
- DataBuffer - A pointer to a data buffer.\r
- DataLength - The length of data buffer.\r
- StartLba - The start address of LBA.\r
- SectorSize - The sector size.\r
-\r
-Returns:\r
-\r
- Returns:\r
- EFI_SUCCESS - The status of the unit is tested successfully.\r
- EFI_WARN_BUFFER_TOO_SMALL - 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
- EFI_NOT_READY - The SCSI Request Packet could not be sent because \r
- there are too many SCSI Command Packets already \r
- queued.\r
- EFI_DEVICE_ERROR - A device error occurred while attempting to send \r
- the SCSI Request Packet.\r
- EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid. \r
- 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
- EFI_TIMEOUT - A timeout occurred while waiting for the SCSI \r
- Request Packet to execute.\r
-\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[10];\r
+ UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
+\r
+ ASSERT (SenseDataLength != NULL);\r
+ ASSERT (HostAdapterStatus != NULL);\r
+ ASSERT (TargetStatus != NULL);\r
+ ASSERT (DataLength != NULL);\r
+ ASSERT (ScsiIo != NULL);\r
\r
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 10);\r
+ ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
\r
CommandPacket.Timeout = Timeout;\r
CommandPacket.InDataBuffer = DataBuffer;\r
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
\r
Cdb[0] = EFI_SCSI_OP_READ10;\r
- Cdb[1] = (UINT8) (Lun & 0xe0);\r
+ Cdb[1] = (UINT8) ((Lun << 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);\r
Cdb[2] = (UINT8) (StartLba >> 24);\r
Cdb[3] = (UINT8) (StartLba >> 16);\r
Cdb[4] = (UINT8) (StartLba >> 8);\r
Cdb[7] = (UINT8) (SectorSize >> 8);\r
Cdb[8] = (UINT8) (SectorSize & 0xff);\r
\r
- CommandPacket.CdbLength = 10;\r
+ CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
CommandPacket.SenseDataLength = *SenseDataLength;\r
\r
return Status;\r
}\r
\r
+\r
+/**\r
+ Execute Write(10) SCSI command on a specific SCSI target.\r
+\r
+ Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.\r
+ If Timeout is zero, then this function waits indefinitely for the command to complete.\r
+ If Timeout is greater than zero, then the command is executed and will timeout after\r
+ Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct\r
+ the CDB for this SCSI command.\r
+ If ScsiIo is NULL, then ASSERT().\r
+ If SenseDataLength is NULL, then ASSERT().\r
+ If HostAdapterStatus is NULL, then ASSERT().\r
+ If TargetStatus is NULL, then ASSERT().\r
+ If DataLength is NULL, then ASSERT().\r
+\r
+ @param[in] ScsiIo SCSI IO Protocol to use\r
+ @param[in] Timeout The length of timeout period.\r
+ @param[in, out] SenseData A pointer to output sense data.\r
+ @param[in, out] SenseDataLength The length of output sense data.\r
+ @param[out] HostAdapterStatus The status of Host Adapter.\r
+ @param[out] TargetStatus The status of the target.\r
+ @param[in, out] DataBuffer A pointer to a data buffer.\r
+ @param[in, out] DataLength The length of data buffer.\r
+ @param[in] StartLba The start address of LBA.\r
+ @param[in] SectorSize The sector size.\r
+\r
+ @retval EFI_SUCCESS Command is executed successfully.\r
+ @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
+ not be transferred. The actual number of bytes transferred is returned in DataLength.\r
+ @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
+ SCSI Command Packets already queued.\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
+ @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
+ the SCSI initiator(i.e., SCSI Host Controller)\r
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
+\r
+**/\r
EFI_STATUS\r
-SubmitWrite10Command (\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 UINT32 StartLba,\r
- IN UINT32 SectorSize\r
+EFIAPI\r
+ScsiWrite10Command (\r
+ IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
+ IN UINT64 Timeout,\r
+ IN OUT VOID *SenseData, OPTIONAL\r
+ IN OUT UINT8 *SenseDataLength,\r
+ OUT UINT8 *HostAdapterStatus,\r
+ OUT UINT8 *TargetStatus,\r
+ IN OUT VOID *DataBuffer, OPTIONAL\r
+ IN OUT UINT32 *DataLength,\r
+ IN UINT32 StartLba,\r
+ IN UINT32 SectorSize\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Function to submit SCSI write 10 command.\r
-\r
-Arguments:\r
- ScsiIo - A pointer to SCSI IO protocol.\r
- Timeout - The length of timeout period.\r
- SenseData - A pointer to output sense data.\r
- SenseDataLength - The length of output sense data.\r
- HostAdapterStatus - The status of Host Adapter.\r
- TargetStatus - The status of the target.\r
- DataBuffer - A pointer to a data buffer.\r
- DataLength - The length of data buffer.\r
- StartLba - The start address of LBA.\r
- SectorSize - The sector size.\r
-\r
-Returns:\r
-\r
- Returns:\r
- EFI_SUCCESS - The status of the unit is tested successfully.\r
- EFI_WARN_BUFFER_TOO_SMALL - 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 InTransferLength.\r
- EFI_NOT_READY - The SCSI Request Packet could not be sent because \r
- there are too many SCSI Command Packets already \r
- queued.\r
- EFI_DEVICE_ERROR - A device error occurred while attempting to send \r
- the SCSI Request Packet.\r
- EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid. \r
- 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
- EFI_TIMEOUT - A timeout occurred while waiting for the SCSI \r
- Request Packet to execute.\r
-\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[10];\r
+ UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
+\r
+ ASSERT (SenseDataLength != NULL);\r
+ ASSERT (HostAdapterStatus != NULL);\r
+ ASSERT (TargetStatus != NULL);\r
+ ASSERT (DataLength != NULL);\r
+ ASSERT (ScsiIo != NULL);\r
\r
ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
- ZeroMem (Cdb, 10);\r
+ ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
\r
CommandPacket.Timeout = Timeout;\r
CommandPacket.OutDataBuffer = DataBuffer;\r
ScsiIo->GetDeviceLocation (ScsiIo, &Target, &Lun);\r
\r
Cdb[0] = EFI_SCSI_OP_WRITE10;\r
- Cdb[1] = (UINT8) (Lun & 0xe0);\r
+ Cdb[1] = (UINT8) ((Lun << 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK);\r
Cdb[2] = (UINT8) (StartLba >> 24);\r
Cdb[3] = (UINT8) (StartLba >> 16);\r
Cdb[4] = (UINT8) (StartLba >> 8);\r
Cdb[7] = (UINT8) (SectorSize >> 8);\r
Cdb[8] = (UINT8) SectorSize;\r
\r
- CommandPacket.CdbLength = 10;\r
+ CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
CommandPacket.DataDirection = EFI_SCSI_DATA_OUT;\r
CommandPacket.SenseDataLength = *SenseDataLength;\r
\r
*HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
*TargetStatus = CommandPacket.TargetStatus;\r
*SenseDataLength = CommandPacket.SenseDataLength;\r
- *DataLength = CommandPacket.InTransferLength;\r
+ *DataLength = CommandPacket.OutTransferLength;\r
\r
return Status;\r
}\r
+\r