]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiScsiLib/UefiScsiLib.c
Fix bugs in the UEFI SCSI Library.
[mirror_edk2.git] / MdePkg / Library / UefiScsiLib / UefiScsiLib.c
CommitLineData
bf231ea6
A
1/** @file\r
2 UEFI SCSI Library implementation\r
3\r
dfc5aca1 4 Copyright (c) 2006 - 2008, Intel Corporation.<BR>\r
bf231ea6
A
5 All rights reserved. This program and the accompanying materials \r
6 are licensed and made available under the terms and conditions of the BSD License \r
7 which accompanies this distribution. The full text of the license may be found at \r
8 http://opensource.org/licenses/bsd-license.php \r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
13**/\r
a02e796b 14\r
bf231ea6 15\r
60c93673 16#include <Uefi.h>\r
306431f7 17#include <Library/DebugLib.h>\r
172ea7c7 18#include <Library/UefiScsiLib.h>\r
a02e796b 19#include <Library/BaseMemoryLib.h>\r
d5954c61 20 \r
a3589760 21#include <IndustryStandard/Scsi.h>\r
d5954c61 22 \r
23 \r
24 //\r
25 // Max bytes needed to represent ID of a SCSI device\r
26 //\r
dfc5aca1 27#define EFI_SCSI_TARGET_MAX_BYTES (0x10)\r
d5954c61 28 \r
29 //\r
30 // bit5..7 are for Logical unit number\r
31 // 11100000b (0xe0)\r
32 //\r
52cd71dc 33#define EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK 0xe0\r
d5954c61 34 \r
35 //\r
36 // Scsi Command Length six or ten\r
37 //\r
52cd71dc
LG
38#define EFI_SCSI_OP_LENGTH_SIX 0x6\r
39#define EFI_SCSI_OP_LENGTH_TEN 0xa\r
bf231ea6 40\r
b91d5eca 41\r
b91d5eca 42\r
d5954c61 43/**\r
44 Execute Test Unit Ready SCSI command on a specific SCSI target.\r
b91d5eca 45\r
d5954c61 46 Executes the Test Unit Ready command on the SCSI target specified by ScsiIo.\r
47 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
48 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
49 If ScsiIo is NULL, then ASSERT().\r
50 If SenseDataLength is NULL, then ASSERT().\r
52cd71dc
LG
51 If HostAdapterStatus is NULL, then ASSERT().\r
52 If TargetStatus is NULL, then ASSERT().\r
a3589760 53\r
d5954c61 54\r
55 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
56 for the specific SCSI target.\r
57 @param[in] Timeout The timeout in 100 ns units to use for the execution\r
58 of this SCSI Request Packet. A Timeout value of\r
59 zero means that this function will wait indefinitely\r
60 for the SCSI Request Packet to execute. If Timeout\r
61 is greater than zero, then this function will return\r
62 EFI_TIMEOUT if the time required to execute the SCSI\r
63 Request Packet is greater than Timeout.\r
64 @param[in, out] SenseData A pointer to sense data that was generated by\r
65 the execution of the SCSI Request Packet. This\r
66 buffer must be allocated by the caller.\r
67 If SenseDataLength is 0, then this parameter is\r
68 optional and may be NULL.\r
69 @param[in, out] SenseDataLength On input, a pointer to the length in bytes of\r
9ccbe812 70 the SenseData buffer. On output, a pointer to\r
d5954c61 71 the number of bytes written to the SenseData buffer. \r
72 @param[out] HostAdapterStatus The status of the SCSI Host Controller that produces\r
73 the SCSI bus containing the SCSI target specified by\r
74 ScsiIo when the SCSI Request Packet was executed.\r
75 See the EFI SCSI I/O Protocol in the UEFI Specification\r
76 for details on the possible return values.\r
77 @param[out] TargetStatus The status returned by the SCSI target specified\r
9ccbe812 78 by ScsiIo when the SCSI Request Packet was executed\r
d5954c61 79 on the SCSI Host Controller. See the EFI SCSI I/O\r
80 Protocol in the UEFI Specification for details on\r
81 the possible return values. \r
82\r
83 @retval EFI_SUCCESS The command was executed successfully.\r
84 See HostAdapterStatus, TargetStatus, SenseDataLength,\r
85 and SenseData in that order for additional status\r
86 information.\r
87 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
88 there are too many SCSI Command Packets already\r
89 queued. The SCSI Request Packet was not sent, so\r
90 no additional status information is available.\r
91 The caller may retry again later.\r
92 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send\r
93 SCSI Request Packet. See HostAdapterStatus,\r
94 TargetStatus, SenseDataLength, and SenseData in that\r
95 order for additional status information.\r
96 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
97 is not supported by the SCSI initiator(i.e., SCSI\r
98 Host Controller). The SCSI Request Packet was not\r
99 sent, so no additional status information is available.\r
100 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request\r
101 Packet to execute. See HostAdapterStatus, TargetStatus,\r
102 SenseDataLength, and SenseData in that order for\r
103 additional status information.\r
a3589760 104\r
bf231ea6 105**/\r
a02e796b 106EFI_STATUS\r
373b5cf9 107EFIAPI\r
d35be2a4 108ScsiTestUnitReadyCommand (\r
d5954c61 109 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
110 IN UINT64 Timeout,\r
111 IN OUT VOID *SenseData, OPTIONAL\r
112 IN OUT UINT8 *SenseDataLength,\r
113 OUT UINT8 *HostAdapterStatus,\r
114 OUT UINT8 *TargetStatus\r
a02e796b 115 )\r
a02e796b 116{\r
117 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 118 EFI_STATUS Status;\r
52cd71dc 119 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
a02e796b 120\r
8069d49e
LG
121 ASSERT (SenseDataLength != NULL);\r
122 ASSERT (HostAdapterStatus != NULL);\r
123 ASSERT (TargetStatus != NULL);\r
d5954c61 124 ASSERT (ScsiIo != NULL);\r
a02e796b 125\r
126 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 127 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
a02e796b 128\r
129 CommandPacket.Timeout = Timeout;\r
130 CommandPacket.InDataBuffer = NULL;\r
131 CommandPacket.InTransferLength= 0;\r
132 CommandPacket.OutDataBuffer = NULL;\r
133 CommandPacket.OutTransferLength= 0;\r
134 CommandPacket.SenseData = SenseData;\r
135 CommandPacket.Cdb = Cdb;\r
136 //\r
137 // Fill Cdb for Test Unit Ready Command\r
138 //\r
a02e796b 139 Cdb[0] = EFI_SCSI_OP_TEST_UNIT_READY;\r
52cd71dc 140 CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
a02e796b 141 CommandPacket.SenseDataLength = *SenseDataLength;\r
142\r
143 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
144\r
145 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
146 *TargetStatus = CommandPacket.TargetStatus;\r
147 *SenseDataLength = CommandPacket.SenseDataLength;\r
148\r
149 return Status;\r
150}\r
151\r
bf231ea6 152\r
a3589760 153/**\r
d5954c61 154 Execute Inquiry SCSI command on a specific SCSI target.\r
b91d5eca 155\r
d5954c61 156 Executes the Inquiry command on the SCSI target specified by ScsiIo.\r
157 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
158 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
159 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
160 If SenseDataLength is NULL, then ASSERT().\r
161 If HostAdapterStatus is NULL, then ASSERT().\r
162 If TargetStatus is NULL, then ASSERT().\r
163 If InquiryDataLength is NULL, then ASSERT().\r
a3589760 164\r
d5954c61 165 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
166 for the specific SCSI target.\r
167 @param[in] Timeout The timeout in 100 ns units to use for the\r
168 execution of this SCSI Request Packet. A Timeout\r
169 value of zero means that this function will wait\r
170 indefinitely for the SCSI Request Packet to execute.\r
171 If Timeout is greater than zero, then this function\r
172 will return EFI_TIMEOUT if the time required to\r
173 execute the SCSI Request Packet is greater than Timeout.\r
174 @param[in, out] SenseData A pointer to sense data that was generated\r
175 by the execution of the SCSI Request Packet.\r
176 This buffer must be allocated by the caller.\r
177 If SenseDataLength is 0, then this parameter\r
178 is optional and may be NULL.\r
179 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.\r
180 On output, the number of bytes written to the SenseData buffer. \r
181 @param[out] HostAdapterStatus The status of the SCSI Host Controller that\r
182 produces the SCSI bus containing the SCSI\r
183 target specified by ScsiIo when the SCSI\r
184 Request Packet was executed. See the EFI\r
185 SCSI I/O Protocol in the UEFI Specification\r
186 for details on the possible return values.\r
187 @param[out] TargetStatus The status returned by the SCSI target specified\r
070a76b1 188 by ScsiIo when the SCSI Request Packet was\r
d5954c61 189 executed on the SCSI Host Controller.\r
190 See the EFI SCSI I/O Protocol in the UEFI\r
191 Specification for details on the possible\r
192 return values. \r
193 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated\r
194 by the execution of the SCSI Request Packet.\r
195 This buffer must be allocated by the caller.\r
196 If InquiryDataLength is 0, then this parameter\r
197 is optional and may be NULL. \r
198 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes\r
199 of the InquiryDataBuffer buffer.\r
200 On output, a pointer to the number of bytes\r
201 written to the InquiryDataBuffer buffer.\r
202 @param[in] EnableVitalProductData If TRUE, then the supported vital product\r
203 data is returned in InquiryDataBuffer.\r
204 If FALSE, then the standard inquiry data is\r
205 returned in InquiryDataBuffer. \r
206\r
207 @retval EFI_SUCCESS The command was executed successfully. See HostAdapterStatus,\r
208 TargetStatus, SenseDataLength, and SenseData in that order\r
209 for additional status information.\r
210 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
211 InquiryDataBuffer could not be transferred. The actual\r
212 number of bytes transferred is returned in InquiryDataLength.\r
213 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there\r
214 are too many SCSI Command Packets already queued.\r
215 The SCSI Request Packet was not sent, so no additional\r
216 status information is available. The caller may retry again later.\r
217 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI\r
218 Request Packet. See HostAdapterStatus, TargetStatus,\r
219 SenseDataLength, and SenseData in that order for additional\r
220 status information.\r
221 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not\r
222 supported by the SCSI initiator(i.e., SCSI Host Controller).\r
223 The SCSI Request Packet was not sent, so no additional\r
224 status information is available.\r
225 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request\r
226 Packet to execute. See HostAdapterStatus, TargetStatus,\r
227 SenseDataLength, and SenseData in that order for\r
228 additional status information.\r
a3589760 229\r
bf231ea6 230**/\r
a02e796b 231EFI_STATUS\r
373b5cf9 232EFIAPI\r
d35be2a4 233ScsiInquiryCommand (\r
d5954c61 234 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
235 IN UINT64 Timeout,\r
236 IN OUT VOID *SenseData, OPTIONAL\r
237 IN OUT UINT8 *SenseDataLength,\r
238 OUT UINT8 *HostAdapterStatus,\r
239 OUT UINT8 *TargetStatus,\r
240 IN OUT VOID *InquiryDataBuffer, OPTIONAL\r
241 IN OUT UINT32 *InquiryDataLength,\r
242 IN BOOLEAN EnableVitalProductData\r
a02e796b 243 )\r
a02e796b 244{\r
245 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 246 EFI_STATUS Status;\r
52cd71dc 247 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
a02e796b 248\r
8069d49e
LG
249 ASSERT (SenseDataLength != NULL);\r
250 ASSERT (HostAdapterStatus != NULL);\r
251 ASSERT (TargetStatus != NULL);\r
252 ASSERT (InquiryDataLength != NULL);\r
d5954c61 253 ASSERT (ScsiIo != NULL);\r
8069d49e 254\r
a02e796b 255 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 256 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
a02e796b 257\r
258 CommandPacket.Timeout = Timeout;\r
259 CommandPacket.InDataBuffer = InquiryDataBuffer;\r
260 CommandPacket.InTransferLength= *InquiryDataLength;\r
261 CommandPacket.SenseData = SenseData;\r
262 CommandPacket.SenseDataLength = *SenseDataLength;\r
263 CommandPacket.Cdb = Cdb;\r
264\r
a02e796b 265 Cdb[0] = EFI_SCSI_OP_INQUIRY;\r
a02e796b 266 if (EnableVitalProductData) {\r
267 Cdb[1] |= 0x01;\r
268 }\r
269\r
270 if (*InquiryDataLength > 0xff) {\r
271 *InquiryDataLength = 0xff;\r
272 }\r
273\r
274 Cdb[4] = (UINT8) (*InquiryDataLength);\r
52cd71dc 275 CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
a02e796b 276 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
277\r
278 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
279\r
280 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
281 *TargetStatus = CommandPacket.TargetStatus;\r
282 *SenseDataLength = CommandPacket.SenseDataLength;\r
283 *InquiryDataLength = CommandPacket.InTransferLength;\r
284\r
285 return Status;\r
286}\r
287\r
bf231ea6 288\r
a3589760 289/**\r
d5954c61 290 Execute Mode Sense(10) SCSI command on a specific SCSI target.\r
291\r
292 Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.\r
293 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
294 If Timeout is greater than zero, then the command is executed and will timeout\r
295 after Timeout 100 ns units. The DBDField, PageControl, and PageCode parameters\r
296 are used to construct the CDB for this SCSI command.\r
297 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
298 If SenseDataLength is NULL, then ASSERT().\r
299 If HostAdapterStatus is NULL, then ASSERT().\r
300 If TargetStatus is NULL, then ASSERT().\r
301 If DataLength is NULL, then ASSERT().\r
a3589760 302\r
d5954c61 303\r
304 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
305 for the specific SCSI target.\r
306 @param[in] Timeout The timeout in 100 ns units to use for the\r
307 execution of this SCSI Request Packet. A Timeout\r
308 value of zero means that this function will wait\r
309 indefinitely for the SCSI Request Packet to execute.\r
310 If Timeout is greater than zero, then this function\r
311 will return EFI_TIMEOUT if the time required to\r
312 execute the SCSI Request Packet is greater than Timeout.\r
6089ba62 313 @param[in, out] SenseData A pointer to sense data that was generated\r
d5954c61 314 by the execution of the SCSI Request Packet.\r
315 This buffer must be allocated by the caller.\r
316 If SenseDataLength is 0, then this parameter\r
317 is optional and may be NULL.\r
6089ba62 318 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.\r
d5954c61 319 On output, the number of bytes written to the SenseData buffer. \r
320 @param[out] HostAdapterStatus The status of the SCSI Host Controller that\r
321 produces the SCSI bus containing the SCSI target\r
322 specified by ScsiIo when the SCSI Request Packet\r
323 was executed. See the EFI SCSI I/O Protocol in the\r
324 UEFI Specification for details on the possible\r
325 return values.\r
326 @param[out] TargetStatus The status returned by the SCSI target specified\r
070a76b1 327 by ScsiIo when the SCSI Request Packet was executed\r
d5954c61 328 on the SCSI Host Controller. See the EFI SCSI\r
329 I/O Protocol in the UEFI Specification for details\r
330 on the possible return values.\r
331 @param[in, out] DataBuffer A pointer to data that was generated by the\r
332 execution of the SCSI Request Packet. This\r
333 buffer must be allocated by the caller. If\r
334 DataLength is 0, then this parameter is optional\r
335 and may be NULL. \r
336 @param[in, out] DataLength On input, a pointer to the length in bytes of\r
337 the DataBuffer buffer. On output, a pointer\r
338 to the number of bytes written to the DataBuffer\r
339 buffer. \r
340 @param[in] DBDField Specifies the DBD field of the CDB for this SCSI Command.\r
341 @param[in] PageControl Specifies the PC field of the CDB for this SCSI Command. \r
342 @param[in] PageCode Specifies the Page Control field of the CDB for this SCSI Command. \r
343\r
344 @retval EFI_SUCCESS The command was executed successfully.\r
345 See HostAdapterStatus, TargetStatus, SenseDataLength,\r
346 and SenseData in that order for additional status information.\r
347 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the\r
348 entire DataBuffer could not be transferred.\r
bf231ea6 349 The actual number of bytes transferred is returned\r
d5954c61 350 in DataLength.\r
351 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
352 there are too many SCSI Command Packets already queued.\r
353 The SCSI Request Packet was not sent, so no additional\r
354 status information is available. The caller may retry\r
355 again later.\r
356 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send\r
357 SCSI Request Packet. See HostAdapterStatus, TargetStatus,\r
358 SenseDataLength, and SenseData in that order for\r
359 additional status information.\r
bf231ea6 360 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
d5954c61 361 is not supported by the SCSI initiator(i.e., SCSI\r
362 Host Controller). The SCSI Request Packet was not\r
363 sent, so no additional status information is available.\r
364 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI\r
365 Request Packet to execute. See HostAdapterStatus,\r
366 TargetStatus, SenseDataLength, and SenseData in that\r
367 order for additional status information.\r
a3589760 368\r
bf231ea6 369**/\r
a02e796b 370EFI_STATUS\r
373b5cf9 371EFIAPI\r
d35be2a4 372ScsiModeSense10Command (\r
d5954c61 373 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
374 IN UINT64 Timeout,\r
375 IN OUT VOID *SenseData, OPTIONAL\r
376 IN OUT UINT8 *SenseDataLength,\r
377 OUT UINT8 *HostAdapterStatus,\r
378 OUT UINT8 *TargetStatus,\r
379 IN OUT VOID *DataBuffer, OPTIONAL\r
380 IN OUT UINT32 *DataLength,\r
381 IN UINT8 DBDField, OPTIONAL\r
382 IN UINT8 PageControl,\r
383 IN UINT8 PageCode\r
a02e796b 384 )\r
a02e796b 385{\r
386 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 387 EFI_STATUS Status;\r
52cd71dc 388 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 389\r
8069d49e
LG
390 ASSERT (SenseDataLength != NULL);\r
391 ASSERT (HostAdapterStatus != NULL);\r
392 ASSERT (TargetStatus != NULL);\r
393 ASSERT (DataLength != NULL);\r
d5954c61 394 ASSERT (ScsiIo != NULL);\r
8069d49e 395\r
a02e796b 396 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 397 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 398\r
399 CommandPacket.Timeout = Timeout;\r
400 CommandPacket.InDataBuffer = DataBuffer;\r
401 CommandPacket.SenseData = SenseData;\r
402 CommandPacket.InTransferLength= *DataLength;\r
403 CommandPacket.Cdb = Cdb;\r
404 //\r
405 // Fill Cdb for Mode Sense (10) Command\r
406 //\r
a02e796b 407 Cdb[0] = EFI_SCSI_OP_MODE_SEN10;\r
52cd71dc
LG
408 //\r
409 // DBDField is in Cdb[1] bit3 of (bit7..0)\r
410 //\r
676e2a32 411 Cdb[1] = (UINT8) ((DBDField << 3) & 0x08);\r
52cd71dc
LG
412 //\r
413 // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0\r
414 //\r
676e2a32 415 Cdb[2] = (UINT8) (((PageControl & 0x3) << 6) | (PageCode & 0x3f));\r
a02e796b 416 Cdb[7] = (UINT8) (*DataLength >> 8);\r
417 Cdb[8] = (UINT8) (*DataLength);\r
418\r
52cd71dc 419 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 420 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
421 CommandPacket.SenseDataLength = *SenseDataLength;\r
422\r
423 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
424\r
425 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
426 *TargetStatus = CommandPacket.TargetStatus;\r
427 *SenseDataLength = CommandPacket.SenseDataLength;\r
428 *DataLength = CommandPacket.InTransferLength;\r
429\r
430 return Status;\r
431}\r
432\r
bf231ea6 433\r
a3589760 434/**\r
d5954c61 435 Execute Request Sense SCSI command on a specific SCSI target.\r
b91d5eca 436\r
d5954c61 437 Executes the Request Sense command on the SCSI target specified by ScsiIo.\r
438 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
439 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
440 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
441 If SenseDataLength is NULL, then ASSERT().\r
442 If HostAdapterStatus is NULL, then ASSERT().\r
443 If TargetStatus is NULL, then ASSERT().\r
a3589760 444\r
b91d5eca 445 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
446 @param[in] Timeout The length of timeout period.\r
d5954c61 447 @param[in, out] SenseData A pointer to output sense data.\r
448 @param[in, out] SenseDataLength The length of output sense data.\r
b91d5eca 449 @param[out] HostAdapterStatus The status of Host Adapter.\r
450 @param[out] TargetStatus The status of the target.\r
451\r
452 @retval EFI_SUCCESS Command is executed successfully.\r
453 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are\r
454 too many SCSI Command Packets already queued.\r
455 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
456 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by\r
457 the SCSI initiator(i.e., SCSI Host Controller)\r
458 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 459\r
bf231ea6 460**/\r
a02e796b 461EFI_STATUS\r
373b5cf9 462EFIAPI\r
d35be2a4 463ScsiRequestSenseCommand (\r
d5954c61 464 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
465 IN UINT64 Timeout,\r
466 IN OUT VOID *SenseData, OPTIONAL\r
467 IN OUT UINT8 *SenseDataLength,\r
468 OUT UINT8 *HostAdapterStatus,\r
469 OUT UINT8 *TargetStatus\r
a02e796b 470 )\r
a02e796b 471{\r
472 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 473 EFI_STATUS Status;\r
52cd71dc 474 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
a02e796b 475\r
8069d49e
LG
476 ASSERT (SenseDataLength != NULL);\r
477 ASSERT (HostAdapterStatus != NULL);\r
478 ASSERT (TargetStatus != NULL);\r
d5954c61 479 ASSERT (ScsiIo != NULL);\r
8069d49e 480\r
a02e796b 481 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 482 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
a02e796b 483\r
484 CommandPacket.Timeout = Timeout;\r
485 CommandPacket.InDataBuffer = SenseData;\r
486 CommandPacket.SenseData = NULL;\r
487 CommandPacket.InTransferLength= *SenseDataLength;\r
488 CommandPacket.Cdb = Cdb;\r
489 //\r
490 // Fill Cdb for Request Sense Command\r
491 //\r
a02e796b 492 Cdb[0] = EFI_SCSI_OP_REQUEST_SENSE;\r
a02e796b 493 Cdb[4] = (UINT8) (*SenseDataLength);\r
494\r
52cd71dc 495 CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
a02e796b 496 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
497 CommandPacket.SenseDataLength = 0;\r
498\r
499 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
500\r
501 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
502 *TargetStatus = CommandPacket.TargetStatus;\r
503 *SenseDataLength = (UINT8) CommandPacket.InTransferLength;\r
504\r
505 return Status;\r
506}\r
507\r
bf231ea6 508\r
a3589760 509/**\r
d5954c61 510 Execute Read Capacity SCSI command on a specific SCSI target.\r
b91d5eca 511\r
d5954c61 512 Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.\r
513 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
514 If Timeout is greater than zero, then the command is executed and will timeout after\r
51969ecb 515 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.\r
d5954c61 516 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
517 If SenseDataLength is NULL, then ASSERT().\r
518 If HostAdapterStatus is NULL, then ASSERT().\r
519 If TargetStatus is NULL, then ASSERT().\r
520 If DataLength is NULL, then ASSERT().\r
bf231ea6 521\r
d5954c61 522 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
523 @param[in] Timeout The length of timeout period.\r
524 @param[in, out] SenseData A pointer to output sense data.\r
ee256e2c 525 @param[in, out] SenseDataLength The length of output sense data.\r
d5954c61 526 @param[out] HostAdapterStatus The status of Host Adapter.\r
527 @param[out] TargetStatus The status of the target.\r
528 @param[in, out] DataBuffer A pointer to a data buffer.\r
ee256e2c 529 @param[in, out] DataLength The length of data buffer.\r
51969ecb 530 @param[in] Pmi Partial medium indicator.\r
b91d5eca 531\r
6089ba62 532 @retval EFI_SUCCESS Command is executed successfully.\r
533 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
534 DataBuffer could not be transferred. The actual\r
535 number of bytes transferred is returned in DataLength.\r
536 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
537 there are too many SCSI Command Packets already queued.\r
538 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
539 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
540 is not supported by the SCSI initiator(i.e., SCSI Host Controller)\r
541 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 542\r
bf231ea6 543**/\r
a02e796b 544EFI_STATUS\r
373b5cf9 545EFIAPI\r
d35be2a4 546ScsiReadCapacityCommand (\r
d5954c61 547 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
548 IN UINT64 Timeout,\r
549 IN OUT VOID *SenseData, OPTIONAL\r
550 IN OUT UINT8 *SenseDataLength,\r
551 OUT UINT8 *HostAdapterStatus,\r
552 OUT UINT8 *TargetStatus,\r
553 IN OUT VOID *DataBuffer, OPTIONAL\r
554 IN OUT UINT32 *DataLength,\r
51969ecb 555 IN BOOLEAN Pmi\r
a02e796b 556 )\r
a02e796b 557{\r
558 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 559 EFI_STATUS Status;\r
52cd71dc 560 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 561\r
8069d49e
LG
562 ASSERT (SenseDataLength != NULL);\r
563 ASSERT (HostAdapterStatus != NULL);\r
564 ASSERT (TargetStatus != NULL);\r
565 ASSERT (DataLength != NULL);\r
d5954c61 566 ASSERT (ScsiIo != NULL);\r
8069d49e 567\r
a02e796b 568 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 569 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 570\r
571 CommandPacket.Timeout = Timeout;\r
572 CommandPacket.InDataBuffer = DataBuffer;\r
573 CommandPacket.SenseData = SenseData;\r
574 CommandPacket.InTransferLength= *DataLength;\r
575 CommandPacket.Cdb = Cdb;\r
576 //\r
577 // Fill Cdb for Read Capacity Command\r
578 //\r
a02e796b 579 Cdb[0] = EFI_SCSI_OP_READ_CAPACITY;\r
51969ecb 580 if (!Pmi) {\r
a02e796b 581 //\r
51969ecb 582 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.\r
a02e796b 583 //\r
584 ZeroMem ((Cdb + 2), 4);\r
585 } else {\r
586 Cdb[8] |= 0x01;\r
587 }\r
588\r
52cd71dc 589 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 590 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
591 CommandPacket.SenseDataLength = *SenseDataLength;\r
592\r
593 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
594\r
595 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
596 *TargetStatus = CommandPacket.TargetStatus;\r
597 *SenseDataLength = CommandPacket.SenseDataLength;\r
598 *DataLength = CommandPacket.InTransferLength;\r
599\r
600 return Status;\r
601}\r
602\r
bf231ea6 603\r
ccb491c8 604/**\r
5e11e7c6 605 Execute Read Capacity SCSI 16 command on a specific SCSI target.\r
606\r
607 Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.\r
608 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
609 If Timeout is greater than zero, then the command is executed and will timeout after\r
610 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.\r
611 If ScsiIo is NULL, then ASSERT().\r
612 If SenseDataLength is NULL, then ASSERT().\r
613 If HostAdapterStatus is NULL, then ASSERT().\r
614 If TargetStatus is NULL, then ASSERT().\r
615 If DataLength is NULL, then ASSERT().\r
616\r
617 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
618 @param[in] Timeout The length of timeout period.\r
619 @param[in, out] SenseData A pointer to output sense data.\r
620 @param[in, out] SenseDataLength The length of output sense data.\r
621 @param[out] HostAdapterStatus The status of Host Adapter.\r
622 @param[out] TargetStatus The status of the target.\r
623 @param[in, out] DataBuffer A pointer to a data buffer.\r
624 @param[in, out] DataLength The length of data buffer.\r
625 @param[in] Pmi Partial medium indicator.\r
626\r
627 @retval EFI_SUCCESS Command is executed successfully.\r
628 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
629 DataBuffer could not be transferred. The actual\r
630 number of bytes transferred is returned in DataLength.\r
631 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
632 there are too many SCSI Command Packets already queued.\r
633 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
634 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
635 is not supported by the SCSI initiator(i.e., SCSI Host Controller)\r
636 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
ccb491c8 637\r
638**/\r
ccb491c8 639EFI_STATUS\r
640EFIAPI\r
641ScsiReadCapacity16Command (\r
f158ee67 642 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
643 IN UINT64 Timeout,\r
644 IN OUT VOID *SenseData, OPTIONAL\r
645 IN OUT UINT8 *SenseDataLength,\r
646 OUT UINT8 *HostAdapterStatus,\r
647 OUT UINT8 *TargetStatus,\r
648 IN OUT VOID *DataBuffer, OPTIONAL\r
649 IN OUT UINT32 *DataLength,\r
650 IN BOOLEAN Pmi\r
ccb491c8 651 )\r
652{\r
653 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
ccb491c8 654 EFI_STATUS Status;\r
655 UINT8 Cdb[16];\r
656\r
657 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
658 ZeroMem (Cdb, 16);\r
659\r
660 CommandPacket.Timeout = Timeout;\r
661 CommandPacket.InDataBuffer = DataBuffer;\r
662 CommandPacket.SenseData = SenseData;\r
663 CommandPacket.InTransferLength= *DataLength;\r
664 CommandPacket.Cdb = Cdb;\r
665 //\r
666 // Fill Cdb for Read Capacity Command\r
667 //\r
ccb491c8 668 Cdb[0] = EFI_SCSI_OP_READ_CAPACITY16;\r
669 Cdb[1] = 0x10;\r
51969ecb 670 if (!Pmi) {\r
ccb491c8 671 //\r
51969ecb 672 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.\r
ccb491c8 673 //\r
674 ZeroMem ((Cdb + 2), 8);\r
675 } else {\r
676 Cdb[14] |= 0x01;\r
677 }\r
678\r
679 Cdb[13] = 0x20;\r
680 CommandPacket.CdbLength = 16;\r
681 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
682 CommandPacket.SenseDataLength = *SenseDataLength;\r
683\r
684 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
685\r
686 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
687 *TargetStatus = CommandPacket.TargetStatus;\r
688 *SenseDataLength = CommandPacket.SenseDataLength;\r
689 *DataLength = CommandPacket.InTransferLength;\r
690\r
691 return Status;\r
692}\r
693\r
694\r
a3589760 695/**\r
d5954c61 696 Execute Read(10) SCSI command on a specific SCSI target.\r
697\r
698 Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.\r
699 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
700 If Timeout is greater than zero, then the command is executed and will timeout\r
701 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to\r
702 construct the CDB for this SCSI command.\r
703 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
704 If SenseDataLength is NULL, then ASSERT().\r
705 If HostAdapterStatus is NULL, then ASSERT().\r
706 If TargetStatus is NULL, then ASSERT().\r
b91d5eca 707 If DataLength is NULL, then ASSERT().\r
a3589760 708\r
d5954c61 709\r
710 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
711 @param[in] Timeout The length of timeout period.\r
712 @param[in, out] SenseData A pointer to output sense data.\r
ee256e2c 713 @param[in, out] SenseDataLength The length of output sense data.\r
d5954c61 714 @param[out] HostAdapterStatus The status of Host Adapter.\r
715 @param[out] TargetStatus The status of the target.\r
716 @param[in, out] DataBuffer Read 10 command data.\r
ee256e2c 717 @param[in, out] DataLength The length of data buffer.\r
d5954c61 718 @param[in] StartLba The start address of LBA.\r
719 @param[in] SectorSize The sector size.\r
b91d5eca 720\r
6089ba62 721 @retval EFI_SUCCESS Command is executed successfully.\r
722 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
723 not be transferred. The actual number of bytes transferred is returned in DataLength.\r
724 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
725 SCSI Command Packets already queued.\r
726 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
727 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
728 the SCSI initiator(i.e., SCSI Host Controller)\r
729 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 730\r
bf231ea6 731**/\r
a02e796b 732EFI_STATUS\r
373b5cf9 733EFIAPI\r
d35be2a4 734ScsiRead10Command (\r
d5954c61 735 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
736 IN UINT64 Timeout,\r
737 IN OUT VOID *SenseData, OPTIONAL\r
738 IN OUT UINT8 *SenseDataLength,\r
739 OUT UINT8 *HostAdapterStatus,\r
740 OUT UINT8 *TargetStatus,\r
741 IN OUT VOID *DataBuffer, OPTIONAL\r
742 IN OUT UINT32 *DataLength,\r
743 IN UINT32 StartLba,\r
744 IN UINT32 SectorSize\r
a02e796b 745 )\r
a02e796b 746{\r
747 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 748 EFI_STATUS Status;\r
52cd71dc 749 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 750\r
8069d49e
LG
751 ASSERT (SenseDataLength != NULL);\r
752 ASSERT (HostAdapterStatus != NULL);\r
753 ASSERT (TargetStatus != NULL);\r
754 ASSERT (DataLength != NULL);\r
d5954c61 755 ASSERT (ScsiIo != NULL);\r
8069d49e 756\r
a02e796b 757 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 758 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 759\r
760 CommandPacket.Timeout = Timeout;\r
761 CommandPacket.InDataBuffer = DataBuffer;\r
762 CommandPacket.SenseData = SenseData;\r
763 CommandPacket.InTransferLength= *DataLength;\r
764 CommandPacket.Cdb = Cdb;\r
765 //\r
766 // Fill Cdb for Read (10) Command\r
767 //\r
a02e796b 768 Cdb[0] = EFI_SCSI_OP_READ10;\r
a02e796b 769 Cdb[2] = (UINT8) (StartLba >> 24);\r
770 Cdb[3] = (UINT8) (StartLba >> 16);\r
771 Cdb[4] = (UINT8) (StartLba >> 8);\r
772 Cdb[5] = (UINT8) (StartLba & 0xff);\r
773 Cdb[7] = (UINT8) (SectorSize >> 8);\r
774 Cdb[8] = (UINT8) (SectorSize & 0xff);\r
775\r
52cd71dc 776 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 777 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
778 CommandPacket.SenseDataLength = *SenseDataLength;\r
779\r
780 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
781\r
782 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
783 *TargetStatus = CommandPacket.TargetStatus;\r
784 *SenseDataLength = CommandPacket.SenseDataLength;\r
785 *DataLength = CommandPacket.InTransferLength;\r
786\r
787 return Status;\r
788}\r
789\r
bf231ea6 790\r
a3589760 791/**\r
d5954c61 792 Execute Write(10) SCSI command on a specific SCSI target.\r
793\r
794 Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.\r
795 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
796 If Timeout is greater than zero, then the command is executed and will timeout after\r
797 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct\r
798 the CDB for this SCSI command.\r
799 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
800 If SenseDataLength is NULL, then ASSERT().\r
801 If HostAdapterStatus is NULL, then ASSERT().\r
802 If TargetStatus is NULL, then ASSERT().\r
b91d5eca 803 If DataLength is NULL, then ASSERT().\r
a3589760 804\r
d5954c61 805 @param[in] ScsiIo SCSI IO Protocol to use\r
806 @param[in] Timeout The length of timeout period.\r
807 @param[in, out] SenseData A pointer to output sense data.\r
6089ba62 808 @param[in, out] SenseDataLength The length of output sense data.\r
d5954c61 809 @param[out] HostAdapterStatus The status of Host Adapter.\r
810 @param[out] TargetStatus The status of the target.\r
811 @param[in, out] DataBuffer A pointer to a data buffer.\r
6089ba62 812 @param[in, out] DataLength The length of data buffer.\r
d5954c61 813 @param[in] StartLba The start address of LBA.\r
814 @param[in] SectorSize The sector size.\r
b91d5eca 815\r
6089ba62 816 @retval EFI_SUCCESS Command is executed successfully.\r
817 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
818 not be transferred. The actual number of bytes transferred is returned in DataLength.\r
819 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
820 SCSI Command Packets already queued.\r
821 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
822 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
823 the SCSI initiator(i.e., SCSI Host Controller)\r
824 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 825\r
bf231ea6 826**/\r
a02e796b 827EFI_STATUS\r
373b5cf9 828EFIAPI\r
d35be2a4 829ScsiWrite10Command (\r
d5954c61 830 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
831 IN UINT64 Timeout,\r
832 IN OUT VOID *SenseData, OPTIONAL\r
833 IN OUT UINT8 *SenseDataLength,\r
834 OUT UINT8 *HostAdapterStatus,\r
835 OUT UINT8 *TargetStatus,\r
836 IN OUT VOID *DataBuffer, OPTIONAL\r
837 IN OUT UINT32 *DataLength,\r
838 IN UINT32 StartLba,\r
839 IN UINT32 SectorSize\r
a02e796b 840 )\r
a02e796b 841{\r
842 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 843 EFI_STATUS Status;\r
52cd71dc 844 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 845\r
8069d49e
LG
846 ASSERT (SenseDataLength != NULL);\r
847 ASSERT (HostAdapterStatus != NULL);\r
848 ASSERT (TargetStatus != NULL);\r
849 ASSERT (DataLength != NULL);\r
d5954c61 850 ASSERT (ScsiIo != NULL);\r
8069d49e 851\r
a02e796b 852 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 853 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 854\r
855 CommandPacket.Timeout = Timeout;\r
856 CommandPacket.OutDataBuffer = DataBuffer;\r
857 CommandPacket.SenseData = SenseData;\r
858 CommandPacket.OutTransferLength= *DataLength;\r
859 CommandPacket.Cdb = Cdb;\r
860 //\r
861 // Fill Cdb for Write (10) Command\r
862 //\r
a02e796b 863 Cdb[0] = EFI_SCSI_OP_WRITE10;\r
a02e796b 864 Cdb[2] = (UINT8) (StartLba >> 24);\r
865 Cdb[3] = (UINT8) (StartLba >> 16);\r
866 Cdb[4] = (UINT8) (StartLba >> 8);\r
867 Cdb[5] = (UINT8) StartLba;\r
868 Cdb[7] = (UINT8) (SectorSize >> 8);\r
869 Cdb[8] = (UINT8) SectorSize;\r
870\r
52cd71dc 871 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 872 CommandPacket.DataDirection = EFI_SCSI_DATA_OUT;\r
873 CommandPacket.SenseDataLength = *SenseDataLength;\r
874\r
875 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
876\r
877 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
878 *TargetStatus = CommandPacket.TargetStatus;\r
879 *SenseDataLength = CommandPacket.SenseDataLength;\r
ba7e162e 880 *DataLength = CommandPacket.OutTransferLength;\r
a02e796b 881\r
882 return Status;\r
883}\r
373b5cf9 884\r