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