]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiScsiLib/UefiScsiLib.c
ShellPkg: Fix Shell fail with redundant space following delay number.
[mirror_edk2.git] / MdePkg / Library / UefiScsiLib / UefiScsiLib.c
CommitLineData
bf231ea6
A
1/** @file\r
2 UEFI SCSI Library implementation\r
3\r
b8a62661 4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
19388d29 5 This program and the accompanying materials \r
bf231ea6
A
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
2fc59a00 8 http://opensource.org/licenses/bsd-license.php. \r
bf231ea6
A
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
3e0c79b5 17#include <Library/BaseLib.h>\r
306431f7 18#include <Library/DebugLib.h>\r
172ea7c7 19#include <Library/UefiScsiLib.h>\r
a02e796b 20#include <Library/BaseMemoryLib.h>\r
d5954c61 21 \r
a3589760 22#include <IndustryStandard/Scsi.h>\r
d5954c61 23 \r
24 \r
d5954c61 25 //\r
a24faca3 26 // Scsi Command Length\r
d5954c61 27 //\r
a24faca3 28#define EFI_SCSI_OP_LENGTH_SIX 0x6\r
29#define EFI_SCSI_OP_LENGTH_TEN 0xa\r
30#define EFI_SCSI_OP_LENGTH_SIXTEEN 0x10\r
bf231ea6 31\r
b91d5eca 32\r
b91d5eca 33\r
d5954c61 34/**\r
35 Execute Test Unit Ready SCSI command on a specific SCSI target.\r
b91d5eca 36\r
d5954c61 37 Executes the Test Unit Ready command on the SCSI target specified by ScsiIo.\r
38 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
39 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
40 If ScsiIo is NULL, then ASSERT().\r
41 If SenseDataLength is NULL, then ASSERT().\r
52cd71dc
LG
42 If HostAdapterStatus is NULL, then ASSERT().\r
43 If TargetStatus is NULL, then ASSERT().\r
a3589760 44\r
d5954c61 45\r
46 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
47 for the specific SCSI target.\r
48 @param[in] Timeout The timeout in 100 ns units to use for the execution\r
49 of this SCSI Request Packet. A Timeout value of\r
50 zero means that this function will wait indefinitely\r
51 for the SCSI Request Packet to execute. If Timeout\r
52 is greater than zero, then this function will return\r
53 EFI_TIMEOUT if the time required to execute the SCSI\r
54 Request Packet is greater than Timeout.\r
55 @param[in, out] SenseData A pointer to sense data that was generated by\r
56 the execution of the SCSI Request Packet. This\r
57 buffer must be allocated by the caller.\r
58 If SenseDataLength is 0, then this parameter is\r
59 optional and may be NULL.\r
60 @param[in, out] SenseDataLength On input, a pointer to the length in bytes of\r
9ccbe812 61 the SenseData buffer. On output, a pointer to\r
d5954c61 62 the number of bytes written to the SenseData buffer. \r
63 @param[out] HostAdapterStatus The status of the SCSI Host Controller that produces\r
64 the SCSI bus containing the SCSI target specified by\r
65 ScsiIo when the SCSI Request Packet was executed.\r
66 See the EFI SCSI I/O Protocol in the UEFI Specification\r
67 for details on the possible return values.\r
68 @param[out] TargetStatus The status returned by the SCSI target specified\r
9ccbe812 69 by ScsiIo when the SCSI Request Packet was executed\r
d5954c61 70 on the SCSI Host Controller. See the EFI SCSI I/O\r
71 Protocol in the UEFI Specification for details on\r
72 the possible return values. \r
73\r
74 @retval EFI_SUCCESS The command was executed successfully.\r
75 See HostAdapterStatus, TargetStatus, SenseDataLength,\r
76 and SenseData in that order for additional status\r
77 information.\r
78 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
79 there are too many SCSI Command Packets already\r
80 queued. The SCSI Request Packet was not sent, so\r
81 no additional status information is available.\r
82 The caller may retry again later.\r
83 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send\r
84 SCSI Request Packet. See HostAdapterStatus,\r
85 TargetStatus, SenseDataLength, and SenseData in that\r
86 order for additional status information.\r
87 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
88 is not supported by the SCSI initiator(i.e., SCSI\r
89 Host Controller). The SCSI Request Packet was not\r
90 sent, so no additional status information is available.\r
91 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request\r
92 Packet to execute. See HostAdapterStatus, TargetStatus,\r
93 SenseDataLength, and SenseData in that order for\r
94 additional status information.\r
a3589760 95\r
bf231ea6 96**/\r
a02e796b 97EFI_STATUS\r
373b5cf9 98EFIAPI\r
d35be2a4 99ScsiTestUnitReadyCommand (\r
d5954c61 100 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
101 IN UINT64 Timeout,\r
102 IN OUT VOID *SenseData, OPTIONAL\r
103 IN OUT UINT8 *SenseDataLength,\r
104 OUT UINT8 *HostAdapterStatus,\r
105 OUT UINT8 *TargetStatus\r
a02e796b 106 )\r
a02e796b 107{\r
108 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 109 EFI_STATUS Status;\r
52cd71dc 110 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
a02e796b 111\r
8069d49e
LG
112 ASSERT (SenseDataLength != NULL);\r
113 ASSERT (HostAdapterStatus != NULL);\r
114 ASSERT (TargetStatus != NULL);\r
d5954c61 115 ASSERT (ScsiIo != NULL);\r
a02e796b 116\r
117 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 118 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
a02e796b 119\r
120 CommandPacket.Timeout = Timeout;\r
121 CommandPacket.InDataBuffer = NULL;\r
122 CommandPacket.InTransferLength= 0;\r
123 CommandPacket.OutDataBuffer = NULL;\r
124 CommandPacket.OutTransferLength= 0;\r
125 CommandPacket.SenseData = SenseData;\r
126 CommandPacket.Cdb = Cdb;\r
127 //\r
128 // Fill Cdb for Test Unit Ready Command\r
129 //\r
a02e796b 130 Cdb[0] = EFI_SCSI_OP_TEST_UNIT_READY;\r
52cd71dc 131 CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
a02e796b 132 CommandPacket.SenseDataLength = *SenseDataLength;\r
133\r
134 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
135\r
136 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
137 *TargetStatus = CommandPacket.TargetStatus;\r
138 *SenseDataLength = CommandPacket.SenseDataLength;\r
139\r
140 return Status;\r
141}\r
142\r
bf231ea6 143\r
a3589760 144/**\r
d5954c61 145 Execute Inquiry SCSI command on a specific SCSI target.\r
b91d5eca 146\r
d5954c61 147 Executes the Inquiry command on the SCSI target specified by ScsiIo.\r
148 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
149 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
150 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
151 If SenseDataLength is NULL, then ASSERT().\r
152 If HostAdapterStatus is NULL, then ASSERT().\r
153 If TargetStatus is NULL, then ASSERT().\r
154 If InquiryDataLength is NULL, then ASSERT().\r
a3589760 155\r
d5954c61 156 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
157 for the specific SCSI target.\r
158 @param[in] Timeout The timeout in 100 ns units to use for the\r
159 execution of this SCSI Request Packet. A Timeout\r
160 value of zero means that this function will wait\r
161 indefinitely for the SCSI Request Packet to execute.\r
162 If Timeout is greater than zero, then this function\r
163 will return EFI_TIMEOUT if the time required to\r
164 execute the SCSI Request Packet is greater than Timeout.\r
165 @param[in, out] SenseData A pointer to sense data that was generated\r
166 by the execution of the SCSI Request Packet.\r
167 This buffer must be allocated by the caller.\r
168 If SenseDataLength is 0, then this parameter\r
169 is optional and may be NULL.\r
170 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.\r
171 On output, the number of bytes written to the SenseData buffer. \r
172 @param[out] HostAdapterStatus The status of the SCSI Host Controller that\r
173 produces the SCSI bus containing the SCSI\r
174 target specified by ScsiIo when the SCSI\r
175 Request Packet was executed. See the EFI\r
176 SCSI I/O Protocol in the UEFI Specification\r
177 for details on the possible return values.\r
178 @param[out] TargetStatus The status returned by the SCSI target specified\r
070a76b1 179 by ScsiIo when the SCSI Request Packet was\r
d5954c61 180 executed on the SCSI Host Controller.\r
181 See the EFI SCSI I/O Protocol in the UEFI\r
182 Specification for details on the possible\r
183 return values. \r
184 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated\r
185 by the execution of the SCSI Request Packet.\r
186 This buffer must be allocated by the caller.\r
187 If InquiryDataLength is 0, then this parameter\r
188 is optional and may be NULL. \r
189 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes\r
190 of the InquiryDataBuffer buffer.\r
191 On output, a pointer to the number of bytes\r
192 written to the InquiryDataBuffer buffer.\r
193 @param[in] EnableVitalProductData If TRUE, then the supported vital product\r
b8a62661 194 data for the PageCode is returned in InquiryDataBuffer.\r
d5954c61 195 If FALSE, then the standard inquiry data is\r
b8a62661
RN
196 returned in InquiryDataBuffer and PageCode is ignored.\r
197 @param[in] PageCode The page code of the vital product data.\r
198 It's ignored if EnableVitalProductData is FALSE.\r
d5954c61 199\r
58380e9c 200 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,\r
d5954c61 201 TargetStatus, SenseDataLength, and SenseData in that order\r
202 for additional status information.\r
203 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
204 InquiryDataBuffer could not be transferred. The actual\r
205 number of bytes transferred is returned in InquiryDataLength.\r
206 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there\r
207 are too many SCSI Command Packets already queued.\r
208 The SCSI Request Packet was not sent, so no additional\r
209 status information is available. The caller may retry again later.\r
210 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI\r
211 Request Packet. See HostAdapterStatus, TargetStatus,\r
212 SenseDataLength, and SenseData in that order for additional\r
213 status information.\r
214 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not\r
215 supported by the SCSI initiator(i.e., SCSI Host Controller).\r
216 The SCSI Request Packet was not sent, so no additional\r
217 status information is available.\r
218 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request\r
219 Packet to execute. See HostAdapterStatus, TargetStatus,\r
220 SenseDataLength, and SenseData in that order for\r
221 additional status information.\r
a3589760 222\r
bf231ea6 223**/\r
a02e796b 224EFI_STATUS\r
373b5cf9 225EFIAPI\r
b8a62661 226ScsiInquiryCommandEx (\r
d5954c61 227 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
228 IN UINT64 Timeout,\r
229 IN OUT VOID *SenseData, OPTIONAL\r
230 IN OUT UINT8 *SenseDataLength,\r
231 OUT UINT8 *HostAdapterStatus,\r
232 OUT UINT8 *TargetStatus,\r
233 IN OUT VOID *InquiryDataBuffer, OPTIONAL\r
234 IN OUT UINT32 *InquiryDataLength,\r
b8a62661
RN
235 IN BOOLEAN EnableVitalProductData,\r
236 IN UINT8 PageCode\r
a02e796b 237 )\r
a02e796b 238{\r
239 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 240 EFI_STATUS Status;\r
52cd71dc 241 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
a02e796b 242\r
8069d49e
LG
243 ASSERT (SenseDataLength != NULL);\r
244 ASSERT (HostAdapterStatus != NULL);\r
245 ASSERT (TargetStatus != NULL);\r
246 ASSERT (InquiryDataLength != NULL);\r
d5954c61 247 ASSERT (ScsiIo != NULL);\r
8069d49e 248\r
a02e796b 249 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 250 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
a02e796b 251\r
252 CommandPacket.Timeout = Timeout;\r
253 CommandPacket.InDataBuffer = InquiryDataBuffer;\r
254 CommandPacket.InTransferLength= *InquiryDataLength;\r
255 CommandPacket.SenseData = SenseData;\r
256 CommandPacket.SenseDataLength = *SenseDataLength;\r
257 CommandPacket.Cdb = Cdb;\r
258\r
a02e796b 259 Cdb[0] = EFI_SCSI_OP_INQUIRY;\r
a02e796b 260 if (EnableVitalProductData) {\r
261 Cdb[1] |= 0x01;\r
b8a62661 262 Cdb[2] = PageCode;\r
a02e796b 263 }\r
264\r
265 if (*InquiryDataLength > 0xff) {\r
266 *InquiryDataLength = 0xff;\r
267 }\r
268\r
269 Cdb[4] = (UINT8) (*InquiryDataLength);\r
52cd71dc 270 CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
a02e796b 271 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
272\r
273 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
274\r
275 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
276 *TargetStatus = CommandPacket.TargetStatus;\r
277 *SenseDataLength = CommandPacket.SenseDataLength;\r
278 *InquiryDataLength = CommandPacket.InTransferLength;\r
279\r
280 return Status;\r
281}\r
282\r
bf231ea6 283\r
b8a62661
RN
284/**\r
285 Execute Inquiry SCSI command on a specific SCSI target.\r
286\r
287 Executes the Inquiry command on the SCSI target specified by ScsiIo.\r
288 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
289 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
290 If ScsiIo is NULL, then ASSERT().\r
291 If SenseDataLength is NULL, then ASSERT().\r
292 If HostAdapterStatus is NULL, then ASSERT().\r
293 If TargetStatus is NULL, then ASSERT().\r
294 If InquiryDataLength is NULL, then ASSERT().\r
295\r
296 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
297 for the specific SCSI target.\r
298 @param[in] Timeout The timeout in 100 ns units to use for the\r
299 execution of this SCSI Request Packet. A Timeout\r
300 value of zero means that this function will wait\r
301 indefinitely for the SCSI Request Packet to execute.\r
302 If Timeout is greater than zero, then this function\r
303 will return EFI_TIMEOUT if the time required to\r
304 execute the SCSI Request Packet is greater than Timeout.\r
305 @param[in, out] SenseData A pointer to sense data that was generated\r
306 by the execution of the SCSI Request Packet.\r
307 This buffer must be allocated by the caller.\r
308 If SenseDataLength is 0, then this parameter\r
309 is optional and may be NULL.\r
310 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.\r
311 On output, the number of bytes written to the SenseData buffer. \r
312 @param[out] HostAdapterStatus The status of the SCSI Host Controller that\r
313 produces the SCSI bus containing the SCSI\r
314 target specified by ScsiIo when the SCSI\r
315 Request Packet was executed. See the EFI\r
316 SCSI I/O Protocol in the UEFI Specification\r
317 for details on the possible return values.\r
318 @param[out] TargetStatus The status returned by the SCSI target specified\r
319 by ScsiIo when the SCSI Request Packet was\r
320 executed on the SCSI Host Controller.\r
321 See the EFI SCSI I/O Protocol in the UEFI\r
322 Specification for details on the possible\r
323 return values. \r
324 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated\r
325 by the execution of the SCSI Request Packet.\r
326 This buffer must be allocated by the caller.\r
327 If InquiryDataLength is 0, then this parameter\r
328 is optional and may be NULL. \r
329 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes\r
330 of the InquiryDataBuffer buffer.\r
331 On output, a pointer to the number of bytes\r
332 written to the InquiryDataBuffer buffer.\r
333 @param[in] EnableVitalProductData If TRUE, then the supported vital product\r
334 data is returned in InquiryDataBuffer.\r
335 If FALSE, then the standard inquiry data is\r
336 returned in InquiryDataBuffer. \r
337\r
338 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,\r
339 TargetStatus, SenseDataLength, and SenseData in that order\r
340 for additional status information.\r
341 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
342 InquiryDataBuffer could not be transferred. The actual\r
343 number of bytes transferred is returned in InquiryDataLength.\r
344 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there\r
345 are too many SCSI Command Packets already queued.\r
346 The SCSI Request Packet was not sent, so no additional\r
347 status information is available. The caller may retry again later.\r
348 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI\r
349 Request Packet. See HostAdapterStatus, TargetStatus,\r
350 SenseDataLength, and SenseData in that order for additional\r
351 status information.\r
352 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not\r
353 supported by the SCSI initiator(i.e., SCSI Host Controller).\r
354 The SCSI Request Packet was not sent, so no additional\r
355 status information is available.\r
356 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request\r
357 Packet to execute. See HostAdapterStatus, TargetStatus,\r
358 SenseDataLength, and SenseData in that order for\r
359 additional status information.\r
360\r
361**/\r
362EFI_STATUS\r
363EFIAPI\r
364ScsiInquiryCommand (\r
365 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
366 IN UINT64 Timeout,\r
367 IN OUT VOID *SenseData, OPTIONAL\r
368 IN OUT UINT8 *SenseDataLength,\r
369 OUT UINT8 *HostAdapterStatus,\r
370 OUT UINT8 *TargetStatus,\r
371 IN OUT VOID *InquiryDataBuffer, OPTIONAL\r
372 IN OUT UINT32 *InquiryDataLength,\r
373 IN BOOLEAN EnableVitalProductData\r
374 )\r
375{\r
376 return ScsiInquiryCommandEx (\r
377 ScsiIo,\r
378 Timeout,\r
379 SenseData,\r
380 SenseDataLength,\r
381 HostAdapterStatus,\r
382 TargetStatus,\r
383 InquiryDataBuffer,\r
384 InquiryDataLength,\r
385 EnableVitalProductData,\r
386 0\r
387 );\r
388}\r
389\r
a3589760 390/**\r
d5954c61 391 Execute Mode Sense(10) SCSI command on a specific SCSI target.\r
392\r
393 Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.\r
394 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
395 If Timeout is greater than zero, then the command is executed and will timeout\r
396 after Timeout 100 ns units. The DBDField, PageControl, and PageCode parameters\r
397 are used to construct the CDB for this SCSI command.\r
398 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
399 If SenseDataLength is NULL, then ASSERT().\r
400 If HostAdapterStatus is NULL, then ASSERT().\r
401 If TargetStatus is NULL, then ASSERT().\r
402 If DataLength is NULL, then ASSERT().\r
a3589760 403\r
d5954c61 404\r
405 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance\r
406 for the specific SCSI target.\r
407 @param[in] Timeout The timeout in 100 ns units to use for the\r
408 execution of this SCSI Request Packet. A Timeout\r
409 value of zero means that this function will wait\r
410 indefinitely for the SCSI Request Packet to execute.\r
411 If Timeout is greater than zero, then this function\r
412 will return EFI_TIMEOUT if the time required to\r
413 execute the SCSI Request Packet is greater than Timeout.\r
6089ba62 414 @param[in, out] SenseData A pointer to sense data that was generated\r
d5954c61 415 by the execution of the SCSI Request Packet.\r
416 This buffer must be allocated by the caller.\r
417 If SenseDataLength is 0, then this parameter\r
418 is optional and may be NULL.\r
6089ba62 419 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.\r
d5954c61 420 On output, the number of bytes written to the SenseData buffer. \r
421 @param[out] HostAdapterStatus The status of the SCSI Host Controller that\r
422 produces the SCSI bus containing the SCSI target\r
423 specified by ScsiIo when the SCSI Request Packet\r
424 was executed. See the EFI SCSI I/O Protocol in the\r
425 UEFI Specification for details on the possible\r
426 return values.\r
427 @param[out] TargetStatus The status returned by the SCSI target specified\r
070a76b1 428 by ScsiIo when the SCSI Request Packet was executed\r
d5954c61 429 on the SCSI Host Controller. See the EFI SCSI\r
430 I/O Protocol in the UEFI Specification for details\r
431 on the possible return values.\r
432 @param[in, out] DataBuffer A pointer to data that was generated by the\r
433 execution of the SCSI Request Packet. This\r
434 buffer must be allocated by the caller. If\r
435 DataLength is 0, then this parameter is optional\r
436 and may be NULL. \r
437 @param[in, out] DataLength On input, a pointer to the length in bytes of\r
438 the DataBuffer buffer. On output, a pointer\r
439 to the number of bytes written to the DataBuffer\r
440 buffer. \r
441 @param[in] DBDField Specifies the DBD field of the CDB for this SCSI Command.\r
442 @param[in] PageControl Specifies the PC field of the CDB for this SCSI Command. \r
443 @param[in] PageCode Specifies the Page Control field of the CDB for this SCSI Command. \r
444\r
58380e9c 445 @retval EFI_SUCCESS The command executed successfully.\r
d5954c61 446 See HostAdapterStatus, TargetStatus, SenseDataLength,\r
447 and SenseData in that order for additional status information.\r
448 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the\r
449 entire DataBuffer could not be transferred.\r
bf231ea6 450 The actual number of bytes transferred is returned\r
d5954c61 451 in DataLength.\r
452 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
453 there are too many SCSI Command Packets already queued.\r
454 The SCSI Request Packet was not sent, so no additional\r
455 status information is available. The caller may retry\r
456 again later.\r
457 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send\r
458 SCSI Request Packet. See HostAdapterStatus, TargetStatus,\r
459 SenseDataLength, and SenseData in that order for\r
460 additional status information.\r
bf231ea6 461 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
d5954c61 462 is not supported by the SCSI initiator(i.e., SCSI\r
463 Host Controller). The SCSI Request Packet was not\r
464 sent, so no additional status information is available.\r
465 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI\r
466 Request Packet to execute. See HostAdapterStatus,\r
467 TargetStatus, SenseDataLength, and SenseData in that\r
468 order for additional status information.\r
a3589760 469\r
bf231ea6 470**/\r
a02e796b 471EFI_STATUS\r
373b5cf9 472EFIAPI\r
d35be2a4 473ScsiModeSense10Command (\r
d5954c61 474 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
475 IN UINT64 Timeout,\r
476 IN OUT VOID *SenseData, OPTIONAL\r
477 IN OUT UINT8 *SenseDataLength,\r
478 OUT UINT8 *HostAdapterStatus,\r
479 OUT UINT8 *TargetStatus,\r
480 IN OUT VOID *DataBuffer, OPTIONAL\r
481 IN OUT UINT32 *DataLength,\r
482 IN UINT8 DBDField, OPTIONAL\r
483 IN UINT8 PageControl,\r
484 IN UINT8 PageCode\r
a02e796b 485 )\r
a02e796b 486{\r
487 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 488 EFI_STATUS Status;\r
52cd71dc 489 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 490\r
8069d49e
LG
491 ASSERT (SenseDataLength != NULL);\r
492 ASSERT (HostAdapterStatus != NULL);\r
493 ASSERT (TargetStatus != NULL);\r
494 ASSERT (DataLength != NULL);\r
d5954c61 495 ASSERT (ScsiIo != NULL);\r
8069d49e 496\r
a02e796b 497 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 498 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 499\r
500 CommandPacket.Timeout = Timeout;\r
501 CommandPacket.InDataBuffer = DataBuffer;\r
502 CommandPacket.SenseData = SenseData;\r
503 CommandPacket.InTransferLength= *DataLength;\r
504 CommandPacket.Cdb = Cdb;\r
505 //\r
506 // Fill Cdb for Mode Sense (10) Command\r
507 //\r
a02e796b 508 Cdb[0] = EFI_SCSI_OP_MODE_SEN10;\r
52cd71dc
LG
509 //\r
510 // DBDField is in Cdb[1] bit3 of (bit7..0)\r
511 //\r
b04a63ac 512 Cdb[1] = (UINT8) ((DBDField << 3) & 0x08);\r
52cd71dc
LG
513 //\r
514 // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0\r
515 //\r
6b3ecf5c 516 Cdb[2] = (UINT8) (((PageControl << 6) & 0xc0) | (PageCode & 0x3f));\r
a02e796b 517 Cdb[7] = (UINT8) (*DataLength >> 8);\r
518 Cdb[8] = (UINT8) (*DataLength);\r
519\r
52cd71dc 520 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 521 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
522 CommandPacket.SenseDataLength = *SenseDataLength;\r
523\r
524 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
525\r
526 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
527 *TargetStatus = CommandPacket.TargetStatus;\r
528 *SenseDataLength = CommandPacket.SenseDataLength;\r
529 *DataLength = CommandPacket.InTransferLength;\r
530\r
531 return Status;\r
532}\r
533\r
bf231ea6 534\r
a3589760 535/**\r
d5954c61 536 Execute Request Sense SCSI command on a specific SCSI target.\r
b91d5eca 537\r
d5954c61 538 Executes the Request Sense command on the SCSI target specified by ScsiIo.\r
539 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
540 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.\r
541 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
542 If SenseDataLength is NULL, then ASSERT().\r
543 If HostAdapterStatus is NULL, then ASSERT().\r
544 If TargetStatus is NULL, then ASSERT().\r
a3589760 545\r
b91d5eca 546 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
547 @param[in] Timeout The length of timeout period.\r
d5954c61 548 @param[in, out] SenseData A pointer to output sense data.\r
549 @param[in, out] SenseDataLength The length of output sense data.\r
b91d5eca 550 @param[out] HostAdapterStatus The status of Host Adapter.\r
551 @param[out] TargetStatus The status of the target.\r
552\r
58380e9c 553 @retval EFI_SUCCESS The command executed successfully.\r
b91d5eca 554 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are\r
555 too many SCSI Command Packets already queued.\r
556 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
557 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by\r
558 the SCSI initiator(i.e., SCSI Host Controller)\r
559 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 560\r
bf231ea6 561**/\r
a02e796b 562EFI_STATUS\r
373b5cf9 563EFIAPI\r
d35be2a4 564ScsiRequestSenseCommand (\r
d5954c61 565 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
566 IN UINT64 Timeout,\r
567 IN OUT VOID *SenseData, OPTIONAL\r
568 IN OUT UINT8 *SenseDataLength,\r
569 OUT UINT8 *HostAdapterStatus,\r
570 OUT UINT8 *TargetStatus\r
a02e796b 571 )\r
a02e796b 572{\r
573 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 574 EFI_STATUS Status;\r
52cd71dc 575 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIX];\r
a02e796b 576\r
8069d49e
LG
577 ASSERT (SenseDataLength != NULL);\r
578 ASSERT (HostAdapterStatus != NULL);\r
579 ASSERT (TargetStatus != NULL);\r
d5954c61 580 ASSERT (ScsiIo != NULL);\r
8069d49e 581\r
a02e796b 582 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 583 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);\r
a02e796b 584\r
585 CommandPacket.Timeout = Timeout;\r
586 CommandPacket.InDataBuffer = SenseData;\r
587 CommandPacket.SenseData = NULL;\r
588 CommandPacket.InTransferLength= *SenseDataLength;\r
589 CommandPacket.Cdb = Cdb;\r
590 //\r
591 // Fill Cdb for Request Sense Command\r
592 //\r
a02e796b 593 Cdb[0] = EFI_SCSI_OP_REQUEST_SENSE;\r
a02e796b 594 Cdb[4] = (UINT8) (*SenseDataLength);\r
595\r
52cd71dc 596 CommandPacket.CdbLength = (UINT8) EFI_SCSI_OP_LENGTH_SIX;\r
a02e796b 597 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
598 CommandPacket.SenseDataLength = 0;\r
599\r
600 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
601\r
602 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
603 *TargetStatus = CommandPacket.TargetStatus;\r
604 *SenseDataLength = (UINT8) CommandPacket.InTransferLength;\r
605\r
606 return Status;\r
607}\r
608\r
bf231ea6 609\r
a3589760 610/**\r
d5954c61 611 Execute Read Capacity SCSI command on a specific SCSI target.\r
b91d5eca 612\r
d5954c61 613 Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.\r
614 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
615 If Timeout is greater than zero, then the command is executed and will timeout after\r
51969ecb 616 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.\r
d5954c61 617 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
618 If SenseDataLength is NULL, then ASSERT().\r
619 If HostAdapterStatus is NULL, then ASSERT().\r
620 If TargetStatus is NULL, then ASSERT().\r
621 If DataLength is NULL, then ASSERT().\r
bf231ea6 622\r
d5954c61 623 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
624 @param[in] Timeout The length of timeout period.\r
625 @param[in, out] SenseData A pointer to output sense data.\r
ee256e2c 626 @param[in, out] SenseDataLength The length of output sense data.\r
d5954c61 627 @param[out] HostAdapterStatus The status of Host Adapter.\r
628 @param[out] TargetStatus The status of the target.\r
629 @param[in, out] DataBuffer A pointer to a data buffer.\r
ee256e2c 630 @param[in, out] DataLength The length of data buffer.\r
58380e9c 631 @param[in] Pmi A partial medium indicator.\r
b91d5eca 632\r
58380e9c 633 @retval EFI_SUCCESS The command executed successfully.\r
6089ba62 634 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
635 DataBuffer could not be transferred. The actual\r
636 number of bytes transferred is returned in DataLength.\r
637 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
638 there are too many SCSI Command Packets already queued.\r
639 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
640 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
641 is not supported by the SCSI initiator(i.e., SCSI Host Controller)\r
642 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 643\r
bf231ea6 644**/\r
a02e796b 645EFI_STATUS\r
373b5cf9 646EFIAPI\r
d35be2a4 647ScsiReadCapacityCommand (\r
d5954c61 648 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
649 IN UINT64 Timeout,\r
650 IN OUT VOID *SenseData, OPTIONAL\r
651 IN OUT UINT8 *SenseDataLength,\r
652 OUT UINT8 *HostAdapterStatus,\r
653 OUT UINT8 *TargetStatus,\r
654 IN OUT VOID *DataBuffer, OPTIONAL\r
655 IN OUT UINT32 *DataLength,\r
51969ecb 656 IN BOOLEAN Pmi\r
a02e796b 657 )\r
a02e796b 658{\r
659 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 660 EFI_STATUS Status;\r
52cd71dc 661 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 662\r
8069d49e
LG
663 ASSERT (SenseDataLength != NULL);\r
664 ASSERT (HostAdapterStatus != NULL);\r
665 ASSERT (TargetStatus != NULL);\r
666 ASSERT (DataLength != NULL);\r
d5954c61 667 ASSERT (ScsiIo != NULL);\r
8069d49e 668\r
a02e796b 669 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 670 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 671\r
672 CommandPacket.Timeout = Timeout;\r
673 CommandPacket.InDataBuffer = DataBuffer;\r
674 CommandPacket.SenseData = SenseData;\r
675 CommandPacket.InTransferLength= *DataLength;\r
676 CommandPacket.Cdb = Cdb;\r
677 //\r
678 // Fill Cdb for Read Capacity Command\r
679 //\r
a02e796b 680 Cdb[0] = EFI_SCSI_OP_READ_CAPACITY;\r
51969ecb 681 if (!Pmi) {\r
a02e796b 682 //\r
51969ecb 683 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.\r
a02e796b 684 //\r
685 ZeroMem ((Cdb + 2), 4);\r
686 } else {\r
687 Cdb[8] |= 0x01;\r
688 }\r
689\r
52cd71dc 690 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 691 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
692 CommandPacket.SenseDataLength = *SenseDataLength;\r
693\r
694 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
695\r
696 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
697 *TargetStatus = CommandPacket.TargetStatus;\r
698 *SenseDataLength = CommandPacket.SenseDataLength;\r
699 *DataLength = CommandPacket.InTransferLength;\r
700\r
701 return Status;\r
702}\r
703\r
bf231ea6 704\r
ccb491c8 705/**\r
5e11e7c6 706 Execute Read Capacity SCSI 16 command on a specific SCSI target.\r
707\r
708 Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.\r
709 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
710 If Timeout is greater than zero, then the command is executed and will timeout after\r
711 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.\r
712 If ScsiIo is NULL, then ASSERT().\r
713 If SenseDataLength is NULL, then ASSERT().\r
714 If HostAdapterStatus is NULL, then ASSERT().\r
715 If TargetStatus is NULL, then ASSERT().\r
716 If DataLength is NULL, then ASSERT().\r
717\r
718 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
719 @param[in] Timeout The length of timeout period.\r
720 @param[in, out] SenseData A pointer to output sense data.\r
721 @param[in, out] SenseDataLength The length of output sense data.\r
722 @param[out] HostAdapterStatus The status of Host Adapter.\r
723 @param[out] TargetStatus The status of the target.\r
724 @param[in, out] DataBuffer A pointer to a data buffer.\r
725 @param[in, out] DataLength The length of data buffer.\r
726 @param[in] Pmi Partial medium indicator.\r
727\r
58380e9c 728 @retval EFI_SUCCESS The command executed successfully.\r
5e11e7c6 729 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire\r
730 DataBuffer could not be transferred. The actual\r
731 number of bytes transferred is returned in DataLength.\r
732 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
733 there are too many SCSI Command Packets already queued.\r
734 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
735 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
736 is not supported by the SCSI initiator(i.e., SCSI Host Controller)\r
737 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
ccb491c8 738\r
739**/\r
ccb491c8 740EFI_STATUS\r
741EFIAPI\r
742ScsiReadCapacity16Command (\r
f158ee67 743 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
744 IN UINT64 Timeout,\r
745 IN OUT VOID *SenseData, OPTIONAL\r
746 IN OUT UINT8 *SenseDataLength,\r
747 OUT UINT8 *HostAdapterStatus,\r
748 OUT UINT8 *TargetStatus,\r
749 IN OUT VOID *DataBuffer, OPTIONAL\r
750 IN OUT UINT32 *DataLength,\r
751 IN BOOLEAN Pmi\r
ccb491c8 752 )\r
753{\r
754 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
ccb491c8 755 EFI_STATUS Status;\r
756 UINT8 Cdb[16];\r
757\r
5fe71b5f 758 ASSERT (SenseDataLength != NULL);\r
759 ASSERT (HostAdapterStatus != NULL);\r
760 ASSERT (TargetStatus != NULL);\r
761 ASSERT (DataLength != NULL);\r
762 ASSERT (ScsiIo != NULL);\r
763\r
ccb491c8 764 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
765 ZeroMem (Cdb, 16);\r
766\r
767 CommandPacket.Timeout = Timeout;\r
768 CommandPacket.InDataBuffer = DataBuffer;\r
769 CommandPacket.SenseData = SenseData;\r
770 CommandPacket.InTransferLength= *DataLength;\r
771 CommandPacket.Cdb = Cdb;\r
772 //\r
773 // Fill Cdb for Read Capacity Command\r
774 //\r
ccb491c8 775 Cdb[0] = EFI_SCSI_OP_READ_CAPACITY16;\r
776 Cdb[1] = 0x10;\r
51969ecb 777 if (!Pmi) {\r
ccb491c8 778 //\r
51969ecb 779 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.\r
ccb491c8 780 //\r
781 ZeroMem ((Cdb + 2), 8);\r
782 } else {\r
783 Cdb[14] |= 0x01;\r
784 }\r
785\r
786 Cdb[13] = 0x20;\r
787 CommandPacket.CdbLength = 16;\r
788 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
789 CommandPacket.SenseDataLength = *SenseDataLength;\r
790\r
791 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
792\r
793 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
794 *TargetStatus = CommandPacket.TargetStatus;\r
795 *SenseDataLength = CommandPacket.SenseDataLength;\r
796 *DataLength = CommandPacket.InTransferLength;\r
797\r
798 return Status;\r
799}\r
800\r
801\r
a3589760 802/**\r
d5954c61 803 Execute Read(10) SCSI command on a specific SCSI target.\r
804\r
805 Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.\r
806 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
807 If Timeout is greater than zero, then the command is executed and will timeout\r
808 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to\r
809 construct the CDB for this SCSI command.\r
810 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
811 If SenseDataLength is NULL, then ASSERT().\r
812 If HostAdapterStatus is NULL, then ASSERT().\r
813 If TargetStatus is NULL, then ASSERT().\r
b91d5eca 814 If DataLength is NULL, then ASSERT().\r
a3589760 815\r
d5954c61 816\r
817 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
818 @param[in] Timeout The length of timeout period.\r
819 @param[in, out] SenseData A pointer to output sense data.\r
ee256e2c 820 @param[in, out] SenseDataLength The length of output sense data.\r
d5954c61 821 @param[out] HostAdapterStatus The status of Host Adapter.\r
822 @param[out] TargetStatus The status of the target.\r
823 @param[in, out] DataBuffer Read 10 command data.\r
ee256e2c 824 @param[in, out] DataLength The length of data buffer.\r
d5954c61 825 @param[in] StartLba The start address of LBA.\r
b95eb5e0 826 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.\r
b91d5eca 827\r
58380e9c 828 @retval EFI_SUCCESS The command is executed successfully.\r
6089ba62 829 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
830 not be transferred. The actual number of bytes transferred is returned in DataLength.\r
831 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
832 SCSI Command Packets already queued.\r
833 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
834 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
835 the SCSI initiator(i.e., SCSI Host Controller)\r
836 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 837\r
bf231ea6 838**/\r
a02e796b 839EFI_STATUS\r
373b5cf9 840EFIAPI\r
d35be2a4 841ScsiRead10Command (\r
d5954c61 842 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
843 IN UINT64 Timeout,\r
844 IN OUT VOID *SenseData, OPTIONAL\r
845 IN OUT UINT8 *SenseDataLength,\r
846 OUT UINT8 *HostAdapterStatus,\r
847 OUT UINT8 *TargetStatus,\r
848 IN OUT VOID *DataBuffer, OPTIONAL\r
849 IN OUT UINT32 *DataLength,\r
850 IN UINT32 StartLba,\r
851 IN UINT32 SectorSize\r
a02e796b 852 )\r
a02e796b 853{\r
854 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 855 EFI_STATUS Status;\r
52cd71dc 856 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 857\r
8069d49e
LG
858 ASSERT (SenseDataLength != NULL);\r
859 ASSERT (HostAdapterStatus != NULL);\r
860 ASSERT (TargetStatus != NULL);\r
861 ASSERT (DataLength != NULL);\r
d5954c61 862 ASSERT (ScsiIo != NULL);\r
8069d49e 863\r
a02e796b 864 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 865 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 866\r
867 CommandPacket.Timeout = Timeout;\r
868 CommandPacket.InDataBuffer = DataBuffer;\r
869 CommandPacket.SenseData = SenseData;\r
870 CommandPacket.InTransferLength= *DataLength;\r
871 CommandPacket.Cdb = Cdb;\r
872 //\r
873 // Fill Cdb for Read (10) Command\r
874 //\r
a02e796b 875 Cdb[0] = EFI_SCSI_OP_READ10;\r
a24faca3 876 WriteUnaligned32 ((UINT32 *)&Cdb[2], SwapBytes32 (StartLba));\r
877 WriteUnaligned16 ((UINT16 *)&Cdb[7], SwapBytes16 ((UINT16) SectorSize));\r
a02e796b 878\r
52cd71dc 879 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 880 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
881 CommandPacket.SenseDataLength = *SenseDataLength;\r
882\r
883 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
884\r
885 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
886 *TargetStatus = CommandPacket.TargetStatus;\r
887 *SenseDataLength = CommandPacket.SenseDataLength;\r
888 *DataLength = CommandPacket.InTransferLength;\r
889\r
890 return Status;\r
891}\r
892\r
bf231ea6 893\r
a3589760 894/**\r
d5954c61 895 Execute Write(10) SCSI command on a specific SCSI target.\r
896\r
897 Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.\r
898 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
899 If Timeout is greater than zero, then the command is executed and will timeout after\r
900 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct\r
901 the CDB for this SCSI command.\r
902 If ScsiIo is NULL, then ASSERT().\r
52cd71dc
LG
903 If SenseDataLength is NULL, then ASSERT().\r
904 If HostAdapterStatus is NULL, then ASSERT().\r
905 If TargetStatus is NULL, then ASSERT().\r
b91d5eca 906 If DataLength is NULL, then ASSERT().\r
a3589760 907\r
d5954c61 908 @param[in] ScsiIo SCSI IO Protocol to use\r
909 @param[in] Timeout The length of timeout period.\r
910 @param[in, out] SenseData A pointer to output sense data.\r
6089ba62 911 @param[in, out] SenseDataLength The length of output sense data.\r
d5954c61 912 @param[out] HostAdapterStatus The status of Host Adapter.\r
913 @param[out] TargetStatus The status of the target.\r
914 @param[in, out] DataBuffer A pointer to a data buffer.\r
6089ba62 915 @param[in, out] DataLength The length of data buffer.\r
d5954c61 916 @param[in] StartLba The start address of LBA.\r
b95eb5e0 917 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.\r
b91d5eca 918\r
58380e9c 919 @retval EFI_SUCCESS The command executed successfully.\r
6089ba62 920 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
921 not be transferred. The actual number of bytes transferred is returned in DataLength.\r
922 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
923 SCSI Command Packets already queued.\r
924 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
925 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
926 the SCSI initiator(i.e., SCSI Host Controller)\r
927 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
a3589760 928\r
bf231ea6 929**/\r
a02e796b 930EFI_STATUS\r
373b5cf9 931EFIAPI\r
d35be2a4 932ScsiWrite10Command (\r
d5954c61 933 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
934 IN UINT64 Timeout,\r
935 IN OUT VOID *SenseData, OPTIONAL\r
936 IN OUT UINT8 *SenseDataLength,\r
937 OUT UINT8 *HostAdapterStatus,\r
938 OUT UINT8 *TargetStatus,\r
939 IN OUT VOID *DataBuffer, OPTIONAL\r
940 IN OUT UINT32 *DataLength,\r
941 IN UINT32 StartLba,\r
942 IN UINT32 SectorSize\r
a02e796b 943 )\r
a02e796b 944{\r
945 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a02e796b 946 EFI_STATUS Status;\r
52cd71dc 947 UINT8 Cdb[EFI_SCSI_OP_LENGTH_TEN];\r
a02e796b 948\r
8069d49e
LG
949 ASSERT (SenseDataLength != NULL);\r
950 ASSERT (HostAdapterStatus != NULL);\r
951 ASSERT (TargetStatus != NULL);\r
952 ASSERT (DataLength != NULL);\r
d5954c61 953 ASSERT (ScsiIo != NULL);\r
8069d49e 954\r
a02e796b 955 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
52cd71dc 956 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);\r
a02e796b 957\r
958 CommandPacket.Timeout = Timeout;\r
959 CommandPacket.OutDataBuffer = DataBuffer;\r
960 CommandPacket.SenseData = SenseData;\r
961 CommandPacket.OutTransferLength= *DataLength;\r
962 CommandPacket.Cdb = Cdb;\r
963 //\r
964 // Fill Cdb for Write (10) Command\r
965 //\r
a02e796b 966 Cdb[0] = EFI_SCSI_OP_WRITE10;\r
a24faca3 967 WriteUnaligned32 ((UINT32 *)&Cdb[2], SwapBytes32 (StartLba));\r
968 WriteUnaligned16 ((UINT16 *)&Cdb[7], SwapBytes16 ((UINT16) SectorSize));\r
a02e796b 969\r
52cd71dc 970 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_TEN;\r
a02e796b 971 CommandPacket.DataDirection = EFI_SCSI_DATA_OUT;\r
972 CommandPacket.SenseDataLength = *SenseDataLength;\r
973\r
974 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
975\r
976 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
977 *TargetStatus = CommandPacket.TargetStatus;\r
978 *SenseDataLength = CommandPacket.SenseDataLength;\r
ba7e162e 979 *DataLength = CommandPacket.OutTransferLength;\r
a02e796b 980\r
981 return Status;\r
982}\r
373b5cf9 983\r
a24faca3 984/**\r
985 Execute Read(16) SCSI command on a specific SCSI target.\r
986\r
987 Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.\r
988 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
989 If Timeout is greater than zero, then the command is executed and will timeout\r
990 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to\r
991 construct the CDB for this SCSI command.\r
992 If ScsiIo is NULL, then ASSERT().\r
993 If SenseDataLength is NULL, then ASSERT().\r
994 If HostAdapterStatus is NULL, then ASSERT().\r
995 If TargetStatus is NULL, then ASSERT().\r
996 If DataLength is NULL, then ASSERT().\r
997\r
998\r
999 @param[in] ScsiIo A pointer to SCSI IO protocol.\r
1000 @param[in] Timeout The length of timeout period.\r
1001 @param[in, out] SenseData A pointer to output sense data.\r
1002 @param[in, out] SenseDataLength The length of output sense data.\r
1003 @param[out] HostAdapterStatus The status of Host Adapter.\r
1004 @param[out] TargetStatus The status of the target.\r
1005 @param[in, out] DataBuffer Read 16 command data.\r
1006 @param[in, out] DataLength The length of data buffer.\r
1007 @param[in] StartLba The start address of LBA.\r
b95eb5e0 1008 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.\r
a24faca3 1009\r
58380e9c 1010 @retval EFI_SUCCESS The command executed successfully.\r
a24faca3 1011 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
1012 not be transferred. The actual number of bytes transferred is returned in DataLength.\r
1013 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
1014 SCSI Command Packets already queued.\r
1015 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
1016 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
1017 the SCSI initiator(i.e., SCSI Host Controller)\r
1018 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
1019\r
1020**/\r
1021EFI_STATUS\r
1022EFIAPI\r
1023ScsiRead16Command (\r
1024 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
1025 IN UINT64 Timeout,\r
1026 IN OUT VOID *SenseData, OPTIONAL\r
1027 IN OUT UINT8 *SenseDataLength,\r
1028 OUT UINT8 *HostAdapterStatus,\r
1029 OUT UINT8 *TargetStatus,\r
1030 IN OUT VOID *DataBuffer, OPTIONAL\r
1031 IN OUT UINT32 *DataLength,\r
1032 IN UINT64 StartLba,\r
1033 IN UINT32 SectorSize\r
1034 )\r
1035{\r
1036 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a24faca3 1037 EFI_STATUS Status;\r
1038 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIXTEEN];\r
1039\r
1040 ASSERT (SenseDataLength != NULL);\r
1041 ASSERT (HostAdapterStatus != NULL);\r
1042 ASSERT (TargetStatus != NULL);\r
1043 ASSERT (DataLength != NULL);\r
1044 ASSERT (ScsiIo != NULL);\r
1045\r
1046 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
1047 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIXTEEN);\r
1048\r
1049 CommandPacket.Timeout = Timeout;\r
1050 CommandPacket.InDataBuffer = DataBuffer;\r
1051 CommandPacket.SenseData = SenseData;\r
1052 CommandPacket.InTransferLength = *DataLength;\r
1053 CommandPacket.Cdb = Cdb;\r
1054 //\r
1055 // Fill Cdb for Read (16) Command\r
1056 //\r
a24faca3 1057 Cdb[0] = EFI_SCSI_OP_READ16;\r
a24faca3 1058 WriteUnaligned64 ((UINT64 *)&Cdb[2], SwapBytes64 (StartLba));\r
1059 WriteUnaligned32 ((UINT32 *)&Cdb[10], SwapBytes32 (SectorSize));\r
1060\r
1061 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_SIXTEEN;\r
1062 CommandPacket.DataDirection = EFI_SCSI_DATA_IN;\r
1063 CommandPacket.SenseDataLength = *SenseDataLength;\r
1064\r
1065 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
1066\r
1067 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
1068 *TargetStatus = CommandPacket.TargetStatus;\r
1069 *SenseDataLength = CommandPacket.SenseDataLength;\r
1070 *DataLength = CommandPacket.InTransferLength;\r
1071\r
1072 return Status;\r
1073}\r
1074\r
1075\r
1076/**\r
1077 Execute Write(16) SCSI command on a specific SCSI target.\r
1078\r
1079 Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.\r
1080 If Timeout is zero, then this function waits indefinitely for the command to complete.\r
1081 If Timeout is greater than zero, then the command is executed and will timeout after\r
1082 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct\r
1083 the CDB for this SCSI command.\r
1084 If ScsiIo is NULL, then ASSERT().\r
1085 If SenseDataLength is NULL, then ASSERT().\r
1086 If HostAdapterStatus is NULL, then ASSERT().\r
1087 If TargetStatus is NULL, then ASSERT().\r
1088 If DataLength is NULL, then ASSERT().\r
1089\r
1090 @param[in] ScsiIo SCSI IO Protocol to use\r
1091 @param[in] Timeout The length of timeout period.\r
1092 @param[in, out] SenseData A pointer to output sense data.\r
1093 @param[in, out] SenseDataLength The length of output sense data.\r
1094 @param[out] HostAdapterStatus The status of Host Adapter.\r
1095 @param[out] TargetStatus The status of the target.\r
1096 @param[in, out] DataBuffer A pointer to a data buffer.\r
1097 @param[in, out] DataLength The length of data buffer.\r
1098 @param[in] StartLba The start address of LBA.\r
b95eb5e0 1099 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.\r
a24faca3 1100\r
58380e9c 1101 @retval EFI_SUCCESS The command is executed successfully.\r
a24faca3 1102 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could\r
1103 not be transferred. The actual number of bytes transferred is returned in DataLength.\r
1104 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many \r
1105 SCSI Command Packets already queued.\r
1106 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.\r
1107 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by \r
1108 the SCSI initiator(i.e., SCSI Host Controller)\r
1109 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.\r
1110\r
1111**/\r
1112EFI_STATUS\r
1113EFIAPI\r
1114ScsiWrite16Command (\r
1115 IN EFI_SCSI_IO_PROTOCOL *ScsiIo,\r
1116 IN UINT64 Timeout,\r
1117 IN OUT VOID *SenseData, OPTIONAL\r
1118 IN OUT UINT8 *SenseDataLength,\r
1119 OUT UINT8 *HostAdapterStatus,\r
1120 OUT UINT8 *TargetStatus,\r
1121 IN OUT VOID *DataBuffer, OPTIONAL\r
1122 IN OUT UINT32 *DataLength,\r
1123 IN UINT64 StartLba,\r
1124 IN UINT32 SectorSize\r
1125 )\r
1126{\r
1127 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
a24faca3 1128 EFI_STATUS Status;\r
1129 UINT8 Cdb[EFI_SCSI_OP_LENGTH_SIXTEEN];\r
1130\r
1131 ASSERT (SenseDataLength != NULL);\r
1132 ASSERT (HostAdapterStatus != NULL);\r
1133 ASSERT (TargetStatus != NULL);\r
1134 ASSERT (DataLength != NULL);\r
1135 ASSERT (ScsiIo != NULL);\r
1136\r
1137 ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));\r
1138 ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIXTEEN);\r
1139\r
1140 CommandPacket.Timeout = Timeout;\r
1141 CommandPacket.OutDataBuffer = DataBuffer;\r
1142 CommandPacket.SenseData = SenseData;\r
1143 CommandPacket.OutTransferLength = *DataLength;\r
1144 CommandPacket.Cdb = Cdb;\r
1145 //\r
1146 // Fill Cdb for Write (16) Command\r
1147 //\r
a24faca3 1148 Cdb[0] = EFI_SCSI_OP_WRITE16;\r
a24faca3 1149 WriteUnaligned64 ((UINT64 *)&Cdb[2], SwapBytes64 (StartLba));\r
1150 WriteUnaligned32 ((UINT32 *)&Cdb[10], SwapBytes32 (SectorSize));\r
1151\r
1152 CommandPacket.CdbLength = EFI_SCSI_OP_LENGTH_SIXTEEN;\r
1153 CommandPacket.DataDirection = EFI_SCSI_DATA_OUT;\r
1154 CommandPacket.SenseDataLength = *SenseDataLength;\r
1155\r
1156 Status = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);\r
1157\r
1158 *HostAdapterStatus = CommandPacket.HostAdapterStatus;\r
1159 *TargetStatus = CommandPacket.TargetStatus;\r
1160 *SenseDataLength = CommandPacket.SenseDataLength;\r
1161 *DataLength = CommandPacket.OutTransferLength;\r
1162\r
1163 return Status;\r
1164}\r