2 UEFI SCSI Library implementation
4 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/BaseLib.h>
11 #include <Library/DebugLib.h>
12 #include <Library/UefiScsiLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
17 #include <IndustryStandard/Scsi.h>
20 // Scsi Command Length
22 #define EFI_SCSI_OP_LENGTH_SIX 0x6
23 #define EFI_SCSI_OP_LENGTH_TEN 0xa
24 #define EFI_SCSI_OP_LENGTH_TWELVE 0xc
25 #define EFI_SCSI_OP_LENGTH_SIXTEEN 0x10
28 // The context structure used when non-blocking SCSI read/write operation
33 /// The SCSI request packet to send to the SCSI controller specified by
34 /// the device handle.
36 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
38 /// The length of the output sense data.
40 UINT8
*SenseDataLength
;
42 /// The status of the SCSI host adapter.
44 UINT8
*HostAdapterStatus
;
46 /// The status of the target SCSI device.
50 /// The length of the data buffer for the SCSI read/write command.
54 /// The caller event to be signaled when the SCSI read/write command
57 EFI_EVENT CallerEvent
;
58 } EFI_SCSI_LIB_ASYNC_CONTEXT
;
61 Execute Test Unit Ready SCSI command on a specific SCSI target.
63 Executes the Test Unit Ready command on the SCSI target specified by ScsiIo.
64 If Timeout is zero, then this function waits indefinitely for the command to complete.
65 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
66 If ScsiIo is NULL, then ASSERT().
67 If SenseDataLength is NULL, then ASSERT().
68 If HostAdapterStatus is NULL, then ASSERT().
69 If TargetStatus is NULL, then ASSERT().
71 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
72 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
75 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
76 for the specific SCSI target.
77 @param[in] Timeout The timeout in 100 ns units to use for the execution
78 of this SCSI Request Packet. A Timeout value of
79 zero means that this function will wait indefinitely
80 for the SCSI Request Packet to execute. If Timeout
81 is greater than zero, then this function will return
82 EFI_TIMEOUT if the time required to execute the SCSI
83 Request Packet is greater than Timeout.
84 @param[in, out] SenseData A pointer to sense data that was generated by
85 the execution of the SCSI Request Packet. This
86 buffer must be allocated by the caller.
87 If SenseDataLength is 0, then this parameter is
88 optional and may be NULL.
89 @param[in, out] SenseDataLength On input, a pointer to the length in bytes of
90 the SenseData buffer. On output, a pointer to
91 the number of bytes written to the SenseData buffer.
92 @param[out] HostAdapterStatus The status of the SCSI Host Controller that produces
93 the SCSI bus containing the SCSI target specified by
94 ScsiIo when the SCSI Request Packet was executed.
95 See the EFI SCSI I/O Protocol in the UEFI Specification
96 for details on the possible return values.
97 @param[out] TargetStatus The status returned by the SCSI target specified
98 by ScsiIo when the SCSI Request Packet was executed
99 on the SCSI Host Controller. See the EFI SCSI I/O
100 Protocol in the UEFI Specification for details on
101 the possible return values.
103 @retval EFI_SUCCESS The command was executed successfully.
104 See HostAdapterStatus, TargetStatus, SenseDataLength,
105 and SenseData in that order for additional status
107 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
108 there are too many SCSI Command Packets already
109 queued. The SCSI Request Packet was not sent, so
110 no additional status information is available.
111 The caller may retry again later.
112 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
113 SCSI Request Packet. See HostAdapterStatus,
114 TargetStatus, SenseDataLength, and SenseData in that
115 order for additional status information.
116 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
117 is not supported by the SCSI initiator(i.e., SCSI
118 Host Controller). The SCSI Request Packet was not
119 sent, so no additional status information is available.
120 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
121 Packet to execute. See HostAdapterStatus, TargetStatus,
122 SenseDataLength, and SenseData in that order for
123 additional status information.
124 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
129 ScsiTestUnitReadyCommand (
130 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
132 IN OUT VOID
*SenseData OPTIONAL
,
133 IN OUT UINT8
*SenseDataLength
,
134 OUT UINT8
*HostAdapterStatus
,
135 OUT UINT8
*TargetStatus
138 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
140 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
142 ASSERT (SenseDataLength
!= NULL
);
143 ASSERT (HostAdapterStatus
!= NULL
);
144 ASSERT (TargetStatus
!= NULL
);
145 ASSERT (ScsiIo
!= NULL
);
147 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
148 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
150 CommandPacket
.Timeout
= Timeout
;
151 CommandPacket
.InDataBuffer
= NULL
;
152 CommandPacket
.InTransferLength
= 0;
153 CommandPacket
.OutDataBuffer
= NULL
;
154 CommandPacket
.OutTransferLength
= 0;
155 CommandPacket
.SenseData
= SenseData
;
156 CommandPacket
.Cdb
= Cdb
;
158 // Fill Cdb for Test Unit Ready Command
160 Cdb
[0] = EFI_SCSI_OP_TEST_UNIT_READY
;
161 CommandPacket
.CdbLength
= (UINT8
)EFI_SCSI_OP_LENGTH_SIX
;
162 CommandPacket
.SenseDataLength
= *SenseDataLength
;
164 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
166 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
167 *TargetStatus
= CommandPacket
.TargetStatus
;
168 *SenseDataLength
= CommandPacket
.SenseDataLength
;
174 Execute Inquiry SCSI command on a specific SCSI target.
176 Executes the Inquiry command on the SCSI target specified by ScsiIo.
177 If Timeout is zero, then this function waits indefinitely for the command to complete.
178 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
179 If ScsiIo is NULL, then ASSERT().
180 If SenseDataLength is NULL, then ASSERT().
181 If HostAdapterStatus is NULL, then ASSERT().
182 If TargetStatus is NULL, then ASSERT().
183 If InquiryDataLength is NULL, then ASSERT().
185 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
186 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
189 If InquiryDataLength is non-zero and InquiryDataBuffer is not NULL, InquiryDataBuffer
190 must meet buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
191 EFI_INVALID_PARAMETER gets returned.
193 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
194 for the specific SCSI target.
195 @param[in] Timeout The timeout in 100 ns units to use for the
196 execution of this SCSI Request Packet. A Timeout
197 value of zero means that this function will wait
198 indefinitely for the SCSI Request Packet to execute.
199 If Timeout is greater than zero, then this function
200 will return EFI_TIMEOUT if the time required to
201 execute the SCSI Request Packet is greater than Timeout.
202 @param[in, out] SenseData A pointer to sense data that was generated
203 by the execution of the SCSI Request Packet.
204 This buffer must be allocated by the caller.
205 If SenseDataLength is 0, then this parameter
206 is optional and may be NULL.
207 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
208 On output, the number of bytes written to the SenseData buffer.
209 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
210 produces the SCSI bus containing the SCSI
211 target specified by ScsiIo when the SCSI
212 Request Packet was executed. See the EFI
213 SCSI I/O Protocol in the UEFI Specification
214 for details on the possible return values.
215 @param[out] TargetStatus The status returned by the SCSI target specified
216 by ScsiIo when the SCSI Request Packet was
217 executed on the SCSI Host Controller.
218 See the EFI SCSI I/O Protocol in the UEFI
219 Specification for details on the possible
221 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated
222 by the execution of the SCSI Request Packet.
223 This buffer must be allocated by the caller.
224 If InquiryDataLength is 0, then this parameter
225 is optional and may be NULL.
226 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes
227 of the InquiryDataBuffer buffer.
228 On output, a pointer to the number of bytes
229 written to the InquiryDataBuffer buffer.
230 @param[in] EnableVitalProductData If TRUE, then the supported vital product
231 data for the PageCode is returned in InquiryDataBuffer.
232 If FALSE, then the standard inquiry data is
233 returned in InquiryDataBuffer and PageCode is ignored.
234 @param[in] PageCode The page code of the vital product data.
235 It's ignored if EnableVitalProductData is FALSE.
237 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,
238 TargetStatus, SenseDataLength, and SenseData in that order
239 for additional status information.
240 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
241 InquiryDataBuffer could not be transferred. The actual
242 number of bytes transferred is returned in InquiryDataLength.
243 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there
244 are too many SCSI Command Packets already queued.
245 The SCSI Request Packet was not sent, so no additional
246 status information is available. The caller may retry again later.
247 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI
248 Request Packet. See HostAdapterStatus, TargetStatus,
249 SenseDataLength, and SenseData in that order for additional
251 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not
252 supported by the SCSI initiator(i.e., SCSI Host Controller).
253 The SCSI Request Packet was not sent, so no additional
254 status information is available.
255 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
256 Packet to execute. See HostAdapterStatus, TargetStatus,
257 SenseDataLength, and SenseData in that order for
258 additional status information.
259 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
264 ScsiInquiryCommandEx (
265 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
267 IN OUT VOID
*SenseData OPTIONAL
,
268 IN OUT UINT8
*SenseDataLength
,
269 OUT UINT8
*HostAdapterStatus
,
270 OUT UINT8
*TargetStatus
,
271 IN OUT VOID
*InquiryDataBuffer OPTIONAL
,
272 IN OUT UINT32
*InquiryDataLength
,
273 IN BOOLEAN EnableVitalProductData
,
277 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
279 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
281 ASSERT (SenseDataLength
!= NULL
);
282 ASSERT (HostAdapterStatus
!= NULL
);
283 ASSERT (TargetStatus
!= NULL
);
284 ASSERT (InquiryDataLength
!= NULL
);
285 ASSERT (ScsiIo
!= NULL
);
287 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
288 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
290 CommandPacket
.Timeout
= Timeout
;
291 CommandPacket
.InDataBuffer
= InquiryDataBuffer
;
292 CommandPacket
.InTransferLength
= *InquiryDataLength
;
293 CommandPacket
.SenseData
= SenseData
;
294 CommandPacket
.SenseDataLength
= *SenseDataLength
;
295 CommandPacket
.Cdb
= Cdb
;
297 Cdb
[0] = EFI_SCSI_OP_INQUIRY
;
298 if (EnableVitalProductData
) {
303 if (*InquiryDataLength
> 0xff) {
304 *InquiryDataLength
= 0xff;
307 Cdb
[4] = (UINT8
)(*InquiryDataLength
);
308 CommandPacket
.CdbLength
= (UINT8
)EFI_SCSI_OP_LENGTH_SIX
;
309 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
311 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
313 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
314 *TargetStatus
= CommandPacket
.TargetStatus
;
315 *SenseDataLength
= CommandPacket
.SenseDataLength
;
316 *InquiryDataLength
= CommandPacket
.InTransferLength
;
322 Execute Inquiry SCSI command on a specific SCSI target.
324 Executes the Inquiry command on the SCSI target specified by ScsiIo.
325 If Timeout is zero, then this function waits indefinitely for the command to complete.
326 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
327 If ScsiIo is NULL, then ASSERT().
328 If SenseDataLength is NULL, then ASSERT().
329 If HostAdapterStatus is NULL, then ASSERT().
330 If TargetStatus is NULL, then ASSERT().
331 If InquiryDataLength is NULL, then ASSERT().
333 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
334 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
337 If InquiryDataLength is non-zero and InquiryDataBuffer is not NULL, InquiryDataBuffer
338 must meet buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
339 EFI_INVALID_PARAMETER gets returned.
341 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
342 for the specific SCSI target.
343 @param[in] Timeout The timeout in 100 ns units to use for the
344 execution of this SCSI Request Packet. A Timeout
345 value of zero means that this function will wait
346 indefinitely for the SCSI Request Packet to execute.
347 If Timeout is greater than zero, then this function
348 will return EFI_TIMEOUT if the time required to
349 execute the SCSI Request Packet is greater than Timeout.
350 @param[in, out] SenseData A pointer to sense data that was generated
351 by the execution of the SCSI Request Packet.
352 This buffer must be allocated by the caller.
353 If SenseDataLength is 0, then this parameter
354 is optional and may be NULL.
355 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
356 On output, the number of bytes written to the SenseData buffer.
357 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
358 produces the SCSI bus containing the SCSI
359 target specified by ScsiIo when the SCSI
360 Request Packet was executed. See the EFI
361 SCSI I/O Protocol in the UEFI Specification
362 for details on the possible return values.
363 @param[out] TargetStatus The status returned by the SCSI target specified
364 by ScsiIo when the SCSI Request Packet was
365 executed on the SCSI Host Controller.
366 See the EFI SCSI I/O Protocol in the UEFI
367 Specification for details on the possible
369 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated
370 by the execution of the SCSI Request Packet.
371 This buffer must be allocated by the caller.
372 If InquiryDataLength is 0, then this parameter
373 is optional and may be NULL.
374 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes
375 of the InquiryDataBuffer buffer.
376 On output, a pointer to the number of bytes
377 written to the InquiryDataBuffer buffer.
378 @param[in] EnableVitalProductData If TRUE, then the supported vital product
379 data is returned in InquiryDataBuffer.
380 If FALSE, then the standard inquiry data is
381 returned in InquiryDataBuffer.
383 @retval EFI_SUCCESS The command was executed successfully. See HostAdapterStatus,
384 TargetStatus, SenseDataLength, and SenseData in that order
385 for additional status information.
386 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
387 InquiryDataBuffer could not be transferred. The actual
388 number of bytes transferred is returned in InquiryDataLength.
389 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there
390 are too many SCSI Command Packets already queued.
391 The SCSI Request Packet was not sent, so no additional
392 status information is available. The caller may retry again later.
393 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI
394 Request Packet. See HostAdapterStatus, TargetStatus,
395 SenseDataLength, and SenseData in that order for additional
397 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not
398 supported by the SCSI initiator(i.e., SCSI Host Controller).
399 The SCSI Request Packet was not sent, so no additional
400 status information is available.
401 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
402 Packet to execute. See HostAdapterStatus, TargetStatus,
403 SenseDataLength, and SenseData in that order for
404 additional status information.
405 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
411 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
413 IN OUT VOID
*SenseData OPTIONAL
,
414 IN OUT UINT8
*SenseDataLength
,
415 OUT UINT8
*HostAdapterStatus
,
416 OUT UINT8
*TargetStatus
,
417 IN OUT VOID
*InquiryDataBuffer OPTIONAL
,
418 IN OUT UINT32
*InquiryDataLength
,
419 IN BOOLEAN EnableVitalProductData
422 return ScsiInquiryCommandEx (
431 EnableVitalProductData
,
437 Execute Mode Sense(10) SCSI command on a specific SCSI target.
439 Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.
440 If Timeout is zero, then this function waits indefinitely for the command to complete.
441 If Timeout is greater than zero, then the command is executed and will timeout
442 after Timeout 100 ns units. The DBDField, PageControl, and PageCode parameters
443 are used to construct the CDB for this SCSI command.
444 If ScsiIo is NULL, then ASSERT().
445 If SenseDataLength is NULL, then ASSERT().
446 If HostAdapterStatus is NULL, then ASSERT().
447 If TargetStatus is NULL, then ASSERT().
448 If DataLength is NULL, then ASSERT().
450 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
451 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
454 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
455 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
458 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
459 for the specific SCSI target.
460 @param[in] Timeout The timeout in 100 ns units to use for the
461 execution of this SCSI Request Packet. A Timeout
462 value of zero means that this function will wait
463 indefinitely for the SCSI Request Packet to execute.
464 If Timeout is greater than zero, then this function
465 will return EFI_TIMEOUT if the time required to
466 execute the SCSI Request Packet is greater than Timeout.
467 @param[in, out] SenseData A pointer to sense data that was generated
468 by the execution of the SCSI Request Packet.
469 This buffer must be allocated by the caller.
470 If SenseDataLength is 0, then this parameter
471 is optional and may be NULL.
472 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
473 On output, the number of bytes written to the SenseData buffer.
474 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
475 produces the SCSI bus containing the SCSI target
476 specified by ScsiIo when the SCSI Request Packet
477 was executed. See the EFI SCSI I/O Protocol in the
478 UEFI Specification for details on the possible
480 @param[out] TargetStatus The status returned by the SCSI target specified
481 by ScsiIo when the SCSI Request Packet was executed
482 on the SCSI Host Controller. See the EFI SCSI
483 I/O Protocol in the UEFI Specification for details
484 on the possible return values.
485 @param[in, out] DataBuffer A pointer to data that was generated by the
486 execution of the SCSI Request Packet. This
487 buffer must be allocated by the caller. If
488 DataLength is 0, then this parameter is optional
490 @param[in, out] DataLength On input, a pointer to the length in bytes of
491 the DataBuffer buffer. On output, a pointer
492 to the number of bytes written to the DataBuffer
494 @param[in] DBDField Specifies the DBD field of the CDB for this SCSI Command.
495 @param[in] PageControl Specifies the PC field of the CDB for this SCSI Command.
496 @param[in] PageCode Specifies the Page Control field of the CDB for this SCSI Command.
498 @retval EFI_SUCCESS The command was executed successfully.
499 See HostAdapterStatus, TargetStatus, SenseDataLength,
500 and SenseData in that order for additional status information.
501 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the
502 entire DataBuffer could not be transferred.
503 The actual number of bytes transferred is returned
505 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
506 there are too many SCSI Command Packets already queued.
507 The SCSI Request Packet was not sent, so no additional
508 status information is available. The caller may retry
510 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
511 SCSI Request Packet. See HostAdapterStatus, TargetStatus,
512 SenseDataLength, and SenseData in that order for
513 additional status information.
514 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
515 is not supported by the SCSI initiator(i.e., SCSI
516 Host Controller). The SCSI Request Packet was not
517 sent, so no additional status information is available.
518 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
519 Request Packet to execute. See HostAdapterStatus,
520 TargetStatus, SenseDataLength, and SenseData in that
521 order for additional status information.
522 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
527 ScsiModeSense10Command (
528 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
530 IN OUT VOID
*SenseData OPTIONAL
,
531 IN OUT UINT8
*SenseDataLength
,
532 OUT UINT8
*HostAdapterStatus
,
533 OUT UINT8
*TargetStatus
,
534 IN OUT VOID
*DataBuffer OPTIONAL
,
535 IN OUT UINT32
*DataLength
,
536 IN UINT8 DBDField OPTIONAL
,
537 IN UINT8 PageControl
,
541 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
543 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
545 ASSERT (SenseDataLength
!= NULL
);
546 ASSERT (HostAdapterStatus
!= NULL
);
547 ASSERT (TargetStatus
!= NULL
);
548 ASSERT (DataLength
!= NULL
);
549 ASSERT (ScsiIo
!= NULL
);
551 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
552 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
554 CommandPacket
.Timeout
= Timeout
;
555 CommandPacket
.InDataBuffer
= DataBuffer
;
556 CommandPacket
.SenseData
= SenseData
;
557 CommandPacket
.InTransferLength
= *DataLength
;
558 CommandPacket
.Cdb
= Cdb
;
560 // Fill Cdb for Mode Sense (10) Command
562 Cdb
[0] = EFI_SCSI_OP_MODE_SEN10
;
564 // DBDField is in Cdb[1] bit3 of (bit7..0)
566 Cdb
[1] = (UINT8
)((DBDField
<< 3) & 0x08);
568 // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0
570 Cdb
[2] = (UINT8
)(((PageControl
<< 6) & 0xc0) | (PageCode
& 0x3f));
571 Cdb
[7] = (UINT8
)(*DataLength
>> 8);
572 Cdb
[8] = (UINT8
)(*DataLength
);
574 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
575 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
576 CommandPacket
.SenseDataLength
= *SenseDataLength
;
578 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
580 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
581 *TargetStatus
= CommandPacket
.TargetStatus
;
582 *SenseDataLength
= CommandPacket
.SenseDataLength
;
583 *DataLength
= CommandPacket
.InTransferLength
;
589 Execute Request Sense SCSI command on a specific SCSI target.
591 Executes the Request Sense command on the SCSI target specified by ScsiIo.
592 If Timeout is zero, then this function waits indefinitely for the command to complete.
593 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
594 If ScsiIo is NULL, then ASSERT().
595 If SenseDataLength is NULL, then ASSERT().
596 If HostAdapterStatus is NULL, then ASSERT().
597 If TargetStatus is NULL, then ASSERT().
599 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
600 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
603 @param[in] ScsiIo A pointer to SCSI IO protocol.
604 @param[in] Timeout The length of timeout period.
605 @param[in, out] SenseData A pointer to output sense data.
606 @param[in, out] SenseDataLength The length of output sense data.
607 @param[out] HostAdapterStatus The status of Host Adapter.
608 @param[out] TargetStatus The status of the target.
610 @retval EFI_SUCCESS Command is executed successfully.
611 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are
612 too many SCSI Command Packets already queued.
613 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
614 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
615 the SCSI initiator(i.e., SCSI Host Controller)
616 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
617 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
622 ScsiRequestSenseCommand (
623 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
625 IN OUT VOID
*SenseData OPTIONAL
,
626 IN OUT UINT8
*SenseDataLength
,
627 OUT UINT8
*HostAdapterStatus
,
628 OUT UINT8
*TargetStatus
631 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
633 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
635 ASSERT (SenseDataLength
!= NULL
);
636 ASSERT (HostAdapterStatus
!= NULL
);
637 ASSERT (TargetStatus
!= NULL
);
638 ASSERT (ScsiIo
!= NULL
);
640 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
641 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
643 CommandPacket
.Timeout
= Timeout
;
644 CommandPacket
.InDataBuffer
= SenseData
;
645 CommandPacket
.SenseData
= NULL
;
646 CommandPacket
.InTransferLength
= *SenseDataLength
;
647 CommandPacket
.Cdb
= Cdb
;
649 // Fill Cdb for Request Sense Command
651 Cdb
[0] = EFI_SCSI_OP_REQUEST_SENSE
;
652 Cdb
[4] = (UINT8
)(*SenseDataLength
);
654 CommandPacket
.CdbLength
= (UINT8
)EFI_SCSI_OP_LENGTH_SIX
;
655 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
656 CommandPacket
.SenseDataLength
= 0;
658 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
660 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
661 *TargetStatus
= CommandPacket
.TargetStatus
;
662 *SenseDataLength
= (UINT8
)CommandPacket
.InTransferLength
;
668 Execute Read Capacity SCSI command on a specific SCSI target.
670 Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.
671 If Timeout is zero, then this function waits indefinitely for the command to complete.
672 If Timeout is greater than zero, then the command is executed and will timeout after
673 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
674 If ScsiIo is NULL, then ASSERT().
675 If SenseDataLength is NULL, then ASSERT().
676 If HostAdapterStatus is NULL, then ASSERT().
677 If TargetStatus is NULL, then ASSERT().
678 If DataLength is NULL, then ASSERT().
680 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
681 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
684 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
685 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
688 @param[in] ScsiIo A pointer to SCSI IO protocol.
689 @param[in] Timeout The length of timeout period.
690 @param[in, out] SenseData A pointer to output sense data.
691 @param[in, out] SenseDataLength The length of output sense data.
692 @param[out] HostAdapterStatus The status of Host Adapter.
693 @param[out] TargetStatus The status of the target.
694 @param[in, out] DataBuffer A pointer to a data buffer.
695 @param[in, out] DataLength The length of data buffer.
696 @param[in] Pmi Partial medium indicator.
698 @retval EFI_SUCCESS Command is executed successfully.
699 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
700 DataBuffer could not be transferred. The actual
701 number of bytes transferred is returned in DataLength.
702 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
703 there are too many SCSI Command Packets already queued.
704 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
705 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
706 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
707 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
708 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
713 ScsiReadCapacityCommand (
714 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
716 IN OUT VOID
*SenseData OPTIONAL
,
717 IN OUT UINT8
*SenseDataLength
,
718 OUT UINT8
*HostAdapterStatus
,
719 OUT UINT8
*TargetStatus
,
720 IN OUT VOID
*DataBuffer OPTIONAL
,
721 IN OUT UINT32
*DataLength
,
725 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
727 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
729 ASSERT (SenseDataLength
!= NULL
);
730 ASSERT (HostAdapterStatus
!= NULL
);
731 ASSERT (TargetStatus
!= NULL
);
732 ASSERT (DataLength
!= NULL
);
733 ASSERT (ScsiIo
!= NULL
);
735 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
736 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
738 CommandPacket
.Timeout
= Timeout
;
739 CommandPacket
.InDataBuffer
= DataBuffer
;
740 CommandPacket
.SenseData
= SenseData
;
741 CommandPacket
.InTransferLength
= *DataLength
;
742 CommandPacket
.Cdb
= Cdb
;
744 // Fill Cdb for Read Capacity Command
746 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY
;
749 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.
751 ZeroMem ((Cdb
+ 2), 4);
756 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
757 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
758 CommandPacket
.SenseDataLength
= *SenseDataLength
;
760 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
762 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
763 *TargetStatus
= CommandPacket
.TargetStatus
;
764 *SenseDataLength
= CommandPacket
.SenseDataLength
;
765 *DataLength
= CommandPacket
.InTransferLength
;
771 Execute Read Capacity SCSI 16 command on a specific SCSI target.
773 Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.
774 If Timeout is zero, then this function waits indefinitely for the command to complete.
775 If Timeout is greater than zero, then the command is executed and will timeout after
776 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
777 If ScsiIo is NULL, then ASSERT().
778 If SenseDataLength is NULL, then ASSERT().
779 If HostAdapterStatus is NULL, then ASSERT().
780 If TargetStatus is NULL, then ASSERT().
781 If DataLength is NULL, then ASSERT().
783 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
784 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
787 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
788 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
791 @param[in] ScsiIo A pointer to SCSI IO protocol.
792 @param[in] Timeout The length of timeout period.
793 @param[in, out] SenseData A pointer to output sense data.
794 @param[in, out] SenseDataLength The length of output sense data.
795 @param[out] HostAdapterStatus The status of Host Adapter.
796 @param[out] TargetStatus The status of the target.
797 @param[in, out] DataBuffer A pointer to a data buffer.
798 @param[in, out] DataLength The length of data buffer.
799 @param[in] Pmi Partial medium indicator.
801 @retval EFI_SUCCESS Command is executed successfully.
802 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
803 DataBuffer could not be transferred. The actual
804 number of bytes transferred is returned in DataLength.
805 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
806 there are too many SCSI Command Packets already queued.
807 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
808 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
809 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
810 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
811 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
816 ScsiReadCapacity16Command (
817 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
819 IN OUT VOID
*SenseData OPTIONAL
,
820 IN OUT UINT8
*SenseDataLength
,
821 OUT UINT8
*HostAdapterStatus
,
822 OUT UINT8
*TargetStatus
,
823 IN OUT VOID
*DataBuffer OPTIONAL
,
824 IN OUT UINT32
*DataLength
,
828 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
832 ASSERT (SenseDataLength
!= NULL
);
833 ASSERT (HostAdapterStatus
!= NULL
);
834 ASSERT (TargetStatus
!= NULL
);
835 ASSERT (DataLength
!= NULL
);
836 ASSERT (ScsiIo
!= NULL
);
838 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
841 CommandPacket
.Timeout
= Timeout
;
842 CommandPacket
.InDataBuffer
= DataBuffer
;
843 CommandPacket
.SenseData
= SenseData
;
844 CommandPacket
.InTransferLength
= *DataLength
;
845 CommandPacket
.Cdb
= Cdb
;
847 // Fill Cdb for Read Capacity Command
849 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY16
;
853 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.
855 ZeroMem ((Cdb
+ 2), 8);
861 CommandPacket
.CdbLength
= 16;
862 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
863 CommandPacket
.SenseDataLength
= *SenseDataLength
;
865 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
867 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
868 *TargetStatus
= CommandPacket
.TargetStatus
;
869 *SenseDataLength
= CommandPacket
.SenseDataLength
;
870 *DataLength
= CommandPacket
.InTransferLength
;
876 Execute Read(10) SCSI command on a specific SCSI target.
878 Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.
879 If Timeout is zero, then this function waits indefinitely for the command to complete.
880 If Timeout is greater than zero, then the command is executed and will timeout
881 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
882 construct the CDB for this SCSI command.
883 If ScsiIo is NULL, then ASSERT().
884 If SenseDataLength is NULL, then ASSERT().
885 If HostAdapterStatus is NULL, then ASSERT().
886 If TargetStatus is NULL, then ASSERT().
887 If DataLength is NULL, then ASSERT().
889 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
890 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
893 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
894 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
897 @param[in] ScsiIo A pointer to SCSI IO protocol.
898 @param[in] Timeout The length of timeout period.
899 @param[in, out] SenseData A pointer to output sense data.
900 @param[in, out] SenseDataLength The length of output sense data.
901 @param[out] HostAdapterStatus The status of Host Adapter.
902 @param[out] TargetStatus The status of the target.
903 @param[in, out] DataBuffer Read 10 command data.
904 @param[in, out] DataLength The length of data buffer.
905 @param[in] StartLba The start address of LBA.
906 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
908 @retval EFI_SUCCESS Command is executed successfully.
909 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
910 not be transferred. The actual number of bytes transferred is returned in DataLength.
911 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
912 SCSI Command Packets already queued.
913 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
914 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
915 the SCSI initiator(i.e., SCSI Host Controller)
916 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
917 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
923 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
925 IN OUT VOID
*SenseData OPTIONAL
,
926 IN OUT UINT8
*SenseDataLength
,
927 OUT UINT8
*HostAdapterStatus
,
928 OUT UINT8
*TargetStatus
,
929 IN OUT VOID
*DataBuffer OPTIONAL
,
930 IN OUT UINT32
*DataLength
,
935 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
937 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
939 ASSERT (SenseDataLength
!= NULL
);
940 ASSERT (HostAdapterStatus
!= NULL
);
941 ASSERT (TargetStatus
!= NULL
);
942 ASSERT (DataLength
!= NULL
);
943 ASSERT (ScsiIo
!= NULL
);
945 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
946 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
948 CommandPacket
.Timeout
= Timeout
;
949 CommandPacket
.InDataBuffer
= DataBuffer
;
950 CommandPacket
.SenseData
= SenseData
;
951 CommandPacket
.InTransferLength
= *DataLength
;
952 CommandPacket
.Cdb
= Cdb
;
954 // Fill Cdb for Read (10) Command
956 Cdb
[0] = EFI_SCSI_OP_READ10
;
957 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
958 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
)SectorSize
));
960 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
961 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
962 CommandPacket
.SenseDataLength
= *SenseDataLength
;
964 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
966 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
967 *TargetStatus
= CommandPacket
.TargetStatus
;
968 *SenseDataLength
= CommandPacket
.SenseDataLength
;
969 *DataLength
= CommandPacket
.InTransferLength
;
975 Execute Write(10) SCSI command on a specific SCSI target.
977 Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.
978 If Timeout is zero, then this function waits indefinitely for the command to complete.
979 If Timeout is greater than zero, then the command is executed and will timeout after
980 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
981 the CDB for this SCSI command.
982 If ScsiIo is NULL, then ASSERT().
983 If SenseDataLength is NULL, then ASSERT().
984 If HostAdapterStatus is NULL, then ASSERT().
985 If TargetStatus is NULL, then ASSERT().
986 If DataLength is NULL, then ASSERT().
988 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
989 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
992 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
993 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
996 @param[in] ScsiIo SCSI IO Protocol to use
997 @param[in] Timeout The length of timeout period.
998 @param[in, out] SenseData A pointer to output sense data.
999 @param[in, out] SenseDataLength The length of output sense data.
1000 @param[out] HostAdapterStatus The status of Host Adapter.
1001 @param[out] TargetStatus The status of the target.
1002 @param[in, out] DataBuffer A pointer to a data buffer.
1003 @param[in, out] DataLength The length of data buffer.
1004 @param[in] StartLba The start address of LBA.
1005 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
1007 @retval EFI_SUCCESS Command is executed successfully.
1008 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1009 not be transferred. The actual number of bytes transferred is returned in DataLength.
1010 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1011 SCSI Command Packets already queued.
1012 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1013 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1014 the SCSI initiator(i.e., SCSI Host Controller)
1015 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1016 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
1021 ScsiWrite10Command (
1022 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1024 IN OUT VOID
*SenseData OPTIONAL
,
1025 IN OUT UINT8
*SenseDataLength
,
1026 OUT UINT8
*HostAdapterStatus
,
1027 OUT UINT8
*TargetStatus
,
1028 IN OUT VOID
*DataBuffer OPTIONAL
,
1029 IN OUT UINT32
*DataLength
,
1031 IN UINT32 SectorSize
1034 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1036 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
1038 ASSERT (SenseDataLength
!= NULL
);
1039 ASSERT (HostAdapterStatus
!= NULL
);
1040 ASSERT (TargetStatus
!= NULL
);
1041 ASSERT (DataLength
!= NULL
);
1042 ASSERT (ScsiIo
!= NULL
);
1044 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1045 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
1047 CommandPacket
.Timeout
= Timeout
;
1048 CommandPacket
.OutDataBuffer
= DataBuffer
;
1049 CommandPacket
.SenseData
= SenseData
;
1050 CommandPacket
.OutTransferLength
= *DataLength
;
1051 CommandPacket
.Cdb
= Cdb
;
1053 // Fill Cdb for Write (10) Command
1055 Cdb
[0] = EFI_SCSI_OP_WRITE10
;
1056 Cdb
[1] = EFI_SCSI_BLOCK_FUA
;
1057 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
1058 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
)SectorSize
));
1060 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
1061 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
1062 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1064 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1066 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1067 *TargetStatus
= CommandPacket
.TargetStatus
;
1068 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1069 *DataLength
= CommandPacket
.OutTransferLength
;
1075 Execute Read(16) SCSI command on a specific SCSI target.
1077 Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.
1078 If Timeout is zero, then this function waits indefinitely for the command to complete.
1079 If Timeout is greater than zero, then the command is executed and will timeout
1080 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
1081 construct the CDB for this SCSI command.
1082 If ScsiIo is NULL, then ASSERT().
1083 If SenseDataLength is NULL, then ASSERT().
1084 If HostAdapterStatus is NULL, then ASSERT().
1085 If TargetStatus is NULL, then ASSERT().
1086 If DataLength is NULL, then ASSERT().
1088 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
1089 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1092 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
1093 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1096 @param[in] ScsiIo A pointer to SCSI IO protocol.
1097 @param[in] Timeout The length of timeout period.
1098 @param[in, out] SenseData A pointer to output sense data.
1099 @param[in, out] SenseDataLength The length of output sense data.
1100 @param[out] HostAdapterStatus The status of Host Adapter.
1101 @param[out] TargetStatus The status of the target.
1102 @param[in, out] DataBuffer Read 16 command data.
1103 @param[in, out] DataLength The length of data buffer.
1104 @param[in] StartLba The start address of LBA.
1105 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
1107 @retval EFI_SUCCESS Command is executed successfully.
1108 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1109 not be transferred. The actual number of bytes transferred is returned in DataLength.
1110 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1111 SCSI Command Packets already queued.
1112 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1113 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1114 the SCSI initiator(i.e., SCSI Host Controller)
1115 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1116 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
1122 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1124 IN OUT VOID
*SenseData OPTIONAL
,
1125 IN OUT UINT8
*SenseDataLength
,
1126 OUT UINT8
*HostAdapterStatus
,
1127 OUT UINT8
*TargetStatus
,
1128 IN OUT VOID
*DataBuffer OPTIONAL
,
1129 IN OUT UINT32
*DataLength
,
1131 IN UINT32 SectorSize
1134 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1136 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
1138 ASSERT (SenseDataLength
!= NULL
);
1139 ASSERT (HostAdapterStatus
!= NULL
);
1140 ASSERT (TargetStatus
!= NULL
);
1141 ASSERT (DataLength
!= NULL
);
1142 ASSERT (ScsiIo
!= NULL
);
1144 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1145 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1147 CommandPacket
.Timeout
= Timeout
;
1148 CommandPacket
.InDataBuffer
= DataBuffer
;
1149 CommandPacket
.SenseData
= SenseData
;
1150 CommandPacket
.InTransferLength
= *DataLength
;
1151 CommandPacket
.Cdb
= Cdb
;
1153 // Fill Cdb for Read (16) Command
1155 Cdb
[0] = EFI_SCSI_OP_READ16
;
1156 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1157 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1159 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1160 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
1161 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1163 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1165 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1166 *TargetStatus
= CommandPacket
.TargetStatus
;
1167 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1168 *DataLength
= CommandPacket
.InTransferLength
;
1174 Execute Write(16) SCSI command on a specific SCSI target.
1176 Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.
1177 If Timeout is zero, then this function waits indefinitely for the command to complete.
1178 If Timeout is greater than zero, then the command is executed and will timeout after
1179 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
1180 the CDB for this SCSI command.
1181 If ScsiIo is NULL, then ASSERT().
1182 If SenseDataLength is NULL, then ASSERT().
1183 If HostAdapterStatus is NULL, then ASSERT().
1184 If TargetStatus is NULL, then ASSERT().
1185 If DataLength is NULL, then ASSERT().
1187 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
1188 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1191 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
1192 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1195 @param[in] ScsiIo SCSI IO Protocol to use
1196 @param[in] Timeout The length of timeout period.
1197 @param[in, out] SenseData A pointer to output sense data.
1198 @param[in, out] SenseDataLength The length of output sense data.
1199 @param[out] HostAdapterStatus The status of Host Adapter.
1200 @param[out] TargetStatus The status of the target.
1201 @param[in, out] DataBuffer A pointer to a data buffer.
1202 @param[in, out] DataLength The length of data buffer.
1203 @param[in] StartLba The start address of LBA.
1204 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
1206 @retval EFI_SUCCESS Command is executed successfully.
1207 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1208 not be transferred. The actual number of bytes transferred is returned in DataLength.
1209 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1210 SCSI Command Packets already queued.
1211 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1212 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1213 the SCSI initiator(i.e., SCSI Host Controller)
1214 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1215 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
1220 ScsiWrite16Command (
1221 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1223 IN OUT VOID
*SenseData OPTIONAL
,
1224 IN OUT UINT8
*SenseDataLength
,
1225 OUT UINT8
*HostAdapterStatus
,
1226 OUT UINT8
*TargetStatus
,
1227 IN OUT VOID
*DataBuffer OPTIONAL
,
1228 IN OUT UINT32
*DataLength
,
1230 IN UINT32 SectorSize
1233 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1235 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
1237 ASSERT (SenseDataLength
!= NULL
);
1238 ASSERT (HostAdapterStatus
!= NULL
);
1239 ASSERT (TargetStatus
!= NULL
);
1240 ASSERT (DataLength
!= NULL
);
1241 ASSERT (ScsiIo
!= NULL
);
1243 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1244 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1246 CommandPacket
.Timeout
= Timeout
;
1247 CommandPacket
.OutDataBuffer
= DataBuffer
;
1248 CommandPacket
.SenseData
= SenseData
;
1249 CommandPacket
.OutTransferLength
= *DataLength
;
1250 CommandPacket
.Cdb
= Cdb
;
1252 // Fill Cdb for Write (16) Command
1254 Cdb
[0] = EFI_SCSI_OP_WRITE16
;
1255 Cdb
[1] = EFI_SCSI_BLOCK_FUA
;
1256 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1257 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1259 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1260 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
1261 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1263 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1265 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1266 *TargetStatus
= CommandPacket
.TargetStatus
;
1267 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1268 *DataLength
= CommandPacket
.OutTransferLength
;
1274 Execute Security Protocol In SCSI command on a specific SCSI target.
1276 Executes the SCSI Security Protocol In command on the SCSI target specified by ScsiIo.
1277 If Timeout is zero, then this function waits indefinitely for the command to complete.
1278 If Timeout is greater than zero, then the command is executed and will timeout after
1279 Timeout 100 ns units.
1280 If ScsiIo is NULL, then ASSERT().
1281 If SenseDataLength is NULL, then ASSERT().
1282 If HostAdapterStatus is NULL, then ASSERT().
1283 If TargetStatus is NULL, then ASSERT().
1284 If TransferLength is NULL, then ASSERT().
1286 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
1287 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1290 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
1291 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1294 @param[in] ScsiIo SCSI IO Protocol to use.
1295 @param[in] Timeout The length of timeout period.
1296 @param[in, out] SenseData A pointer to output sense data.
1297 @param[in, out] SenseDataLength The length of output sense data.
1298 @param[out] HostAdapterStatus The status of Host Adapter.
1299 @param[out] TargetStatus The status of the target.
1300 @param[in] SecurityProtocol The Security Protocol to use.
1301 @param[in] SecurityProtocolSpecific The Security Protocol Specific data.
1302 @param[in] Inc512 If TRUE, 512 increment (INC_512) bit will be set for the
1303 SECURITY PROTOCOL IN command.
1304 @param[in] DataLength The size in bytes of the data buffer.
1305 @param[in, out] DataBuffer A pointer to a data buffer.
1306 @param[out] TransferLength A pointer to a buffer to store the size in
1307 bytes of the data written to the data buffer.
1309 @retval EFI_SUCCESS Command is executed successfully.
1310 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1311 not be transferred. The actual number of bytes transferred is returned in TransferLength.
1312 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1313 SCSI Command Packets already queued.
1314 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1315 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1316 the SCSI initiator(i.e., SCSI Host Controller)
1317 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1318 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
1323 ScsiSecurityProtocolInCommand (
1324 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1326 IN OUT VOID
*SenseData OPTIONAL
,
1327 IN OUT UINT8
*SenseDataLength
,
1328 OUT UINT8
*HostAdapterStatus
,
1329 OUT UINT8
*TargetStatus
,
1330 IN UINT8 SecurityProtocol
,
1331 IN UINT16 SecurityProtocolSpecific
,
1333 IN UINTN DataLength
,
1334 IN OUT VOID
*DataBuffer OPTIONAL
,
1335 OUT UINTN
*TransferLength
1338 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1340 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TWELVE
];
1342 ASSERT (SenseDataLength
!= NULL
);
1343 ASSERT (HostAdapterStatus
!= NULL
);
1344 ASSERT (TargetStatus
!= NULL
);
1345 ASSERT (ScsiIo
!= NULL
);
1346 ASSERT (TransferLength
!= NULL
);
1347 ASSERT (DataLength
<= MAX_UINT32
);
1349 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1350 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TWELVE
);
1352 CommandPacket
.Timeout
= Timeout
;
1353 CommandPacket
.InDataBuffer
= DataBuffer
;
1354 CommandPacket
.SenseData
= SenseData
;
1355 CommandPacket
.InTransferLength
= (UINT32
)DataLength
;
1356 CommandPacket
.Cdb
= Cdb
;
1358 // Fill Cdb for Security Protocol In Command
1360 Cdb
[0] = EFI_SCSI_OP_SECURITY_PROTOCOL_IN
;
1361 Cdb
[1] = SecurityProtocol
;
1362 WriteUnaligned16 ((UINT16
*)&Cdb
[2], SwapBytes16 (SecurityProtocolSpecific
));
1365 if (DataLength
% 512 != 0) {
1366 return EFI_INVALID_PARAMETER
;
1370 WriteUnaligned32 ((UINT32
*)&Cdb
[6], SwapBytes32 ((UINT32
)DataLength
/ 512));
1372 WriteUnaligned32 ((UINT32
*)&Cdb
[6], SwapBytes32 ((UINT32
)DataLength
));
1375 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TWELVE
;
1376 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
1377 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1379 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1381 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1382 *TargetStatus
= CommandPacket
.TargetStatus
;
1383 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1384 *TransferLength
= (UINTN
)CommandPacket
.InTransferLength
;
1390 Execute Security Protocol Out SCSI command on a specific SCSI target.
1392 Executes the SCSI Security Protocol Out command on the SCSI target specified by ScsiIo.
1393 If Timeout is zero, then this function waits indefinitely for the command to complete.
1394 If Timeout is greater than zero, then the command is executed and will timeout after
1395 Timeout 100 ns units.
1396 If ScsiIo is NULL, then ASSERT().
1397 If SenseDataLength is NULL, then ASSERT().
1398 If HostAdapterStatus is NULL, then ASSERT().
1399 If TargetStatus is NULL, then ASSERT().
1401 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet buffer
1402 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1405 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet buffer
1406 alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise EFI_INVALID_PARAMETER
1409 @param[in] ScsiIo SCSI IO Protocol to use.
1410 @param[in] Timeout The length of timeout period.
1411 @param[in, out] SenseData A pointer to output sense data.
1412 @param[in, out] SenseDataLength The length of output sense data.
1413 @param[out] HostAdapterStatus The status of Host Adapter.
1414 @param[out] TargetStatus The status of the target.
1415 @param[in] SecurityProtocol The Security Protocol to use.
1416 @param[in] SecurityProtocolSpecific The Security Protocol Specific data.
1417 @param[in] Inc512 If TRUE, 512 increment (INC_512) bit will be set for the
1418 SECURITY PROTOCOL OUT command.
1419 @param[in] DataLength The size in bytes of the transfer data.
1420 @param[in, out] DataBuffer A pointer to a data buffer.
1422 @retval EFI_SUCCESS Command is executed successfully.
1423 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1424 not be transferred. The actual number of bytes transferred is returned in DataLength.
1425 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1426 SCSI Command Packets already queued.
1427 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1428 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1429 the SCSI initiator(i.e., SCSI Host Controller)
1430 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1431 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet are invalid.
1436 ScsiSecurityProtocolOutCommand (
1437 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1439 IN OUT VOID
*SenseData OPTIONAL
,
1440 IN OUT UINT8
*SenseDataLength
,
1441 OUT UINT8
*HostAdapterStatus
,
1442 OUT UINT8
*TargetStatus
,
1443 IN UINT8 SecurityProtocol
,
1444 IN UINT16 SecurityProtocolSpecific
,
1446 IN UINTN DataLength
,
1447 IN OUT VOID
*DataBuffer OPTIONAL
1450 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1452 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TWELVE
];
1454 ASSERT (SenseDataLength
!= NULL
);
1455 ASSERT (HostAdapterStatus
!= NULL
);
1456 ASSERT (TargetStatus
!= NULL
);
1457 ASSERT (ScsiIo
!= NULL
);
1458 ASSERT (DataLength
<= MAX_UINT32
);
1460 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1461 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TWELVE
);
1463 CommandPacket
.Timeout
= Timeout
;
1464 CommandPacket
.OutDataBuffer
= DataBuffer
;
1465 CommandPacket
.SenseData
= SenseData
;
1466 CommandPacket
.OutTransferLength
= (UINT32
)DataLength
;
1467 CommandPacket
.Cdb
= Cdb
;
1469 // Fill Cdb for Security Protocol Out Command
1471 Cdb
[0] = EFI_SCSI_OP_SECURITY_PROTOCOL_OUT
;
1472 Cdb
[1] = SecurityProtocol
;
1473 WriteUnaligned16 ((UINT16
*)&Cdb
[2], SwapBytes16 (SecurityProtocolSpecific
));
1476 if (DataLength
% 512 != 0) {
1477 return EFI_INVALID_PARAMETER
;
1481 WriteUnaligned32 ((UINT32
*)&Cdb
[6], SwapBytes32 ((UINT32
)DataLength
/ 512));
1483 WriteUnaligned32 ((UINT32
*)&Cdb
[6], SwapBytes32 ((UINT32
)DataLength
));
1486 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TWELVE
;
1487 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
1488 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1490 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1492 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1493 *TargetStatus
= CommandPacket
.TargetStatus
;
1494 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1500 Internal helper notify function in which update the result of the
1501 non-blocking SCSI Read/Write commands and signal caller event.
1503 @param Event The instance of EFI_EVENT.
1504 @param Context The parameter passed in.
1514 EFI_SCSI_LIB_ASYNC_CONTEXT
*LibContext
;
1515 EFI_SCSI_IO_SCSI_REQUEST_PACKET
*CommandPacket
;
1516 EFI_EVENT CallerEvent
;
1518 LibContext
= (EFI_SCSI_LIB_ASYNC_CONTEXT
*)Context
;
1519 CommandPacket
= &LibContext
->CommandPacket
;
1520 CallerEvent
= LibContext
->CallerEvent
;
1523 // Update SCSI Read/Write operation results
1525 *LibContext
->SenseDataLength
= CommandPacket
->SenseDataLength
;
1526 *LibContext
->HostAdapterStatus
= CommandPacket
->HostAdapterStatus
;
1527 *LibContext
->TargetStatus
= CommandPacket
->TargetStatus
;
1528 if (CommandPacket
->InDataBuffer
!= NULL
) {
1529 *LibContext
->DataLength
= CommandPacket
->InTransferLength
;
1531 *LibContext
->DataLength
= CommandPacket
->OutTransferLength
;
1534 if (CommandPacket
->Cdb
!= NULL
) {
1535 FreePool (CommandPacket
->Cdb
);
1540 gBS
->CloseEvent (Event
);
1541 gBS
->SignalEvent (CallerEvent
);
1545 Execute blocking/non-blocking Read(10) SCSI command on a specific SCSI
1548 Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.
1549 When Event is NULL, blocking command will be executed. Otherwise non-blocking
1550 command will be executed.
1551 For blocking I/O, if Timeout is zero, this function will wait indefinitely
1552 for the command to complete. If Timeout is greater than zero, then the
1553 command is executed and will timeout after Timeout 100 ns units.
1554 For non-blocking I/O, if Timeout is zero, Event will be signaled only after
1555 the command to completes. If Timeout is greater than zero, Event will also be
1556 signaled after Timeout 100 ns units.
1557 The StartLba and SectorSize parameters are used to construct the CDB for this
1560 If ScsiIo is NULL, then ASSERT().
1561 If SenseDataLength is NULL, then ASSERT().
1562 If HostAdapterStatus is NULL, then ASSERT().
1563 If TargetStatus is NULL, then ASSERT().
1564 If DataLength is NULL, then ASSERT().
1566 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet
1567 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
1568 EFI_INVALID_PARAMETER gets returned.
1570 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet
1571 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
1572 EFI_INVALID_PARAMETER gets returned.
1574 @param[in] ScsiIo A pointer to SCSI IO protocol.
1575 @param[in] Timeout The length of timeout period.
1576 @param[in, out] SenseData A pointer to output sense data.
1577 @param[in, out] SenseDataLength The length of output sense data.
1578 @param[out] HostAdapterStatus The status of Host Adapter.
1579 @param[out] TargetStatus The status of the target.
1580 @param[in, out] DataBuffer Read 16 command data.
1581 @param[in, out] DataLength The length of data buffer.
1582 @param[in] StartLba The start address of LBA.
1583 @param[in] SectorSize The number of contiguous logical blocks
1584 of data that shall be transferred.
1585 @param[in] Event If the SCSI target does not support
1586 non-blocking I/O, then Event is ignored,
1587 and blocking I/O is performed. If Event
1588 is NULL, then blocking I/O is performed.
1589 If Event is not NULL and non-blocking
1590 I/O is supported, then non-blocking I/O
1591 is performed, and Event will be signaled
1592 when the SCSI Read(10) command
1595 @retval EFI_SUCCESS Command is executed successfully.
1596 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
1597 but the entire DataBuffer could not be
1598 transferred. The actual number of bytes
1599 transferred is returned in DataLength.
1600 @retval EFI_NOT_READY The SCSI Request Packet could not be
1601 sent because there are too many SCSI
1602 Command Packets already queued.
1603 @retval EFI_DEVICE_ERROR A device error occurred while attempting
1604 to send SCSI Request Packet.
1605 @retval EFI_UNSUPPORTED The command described by the SCSI
1606 Request Packet is not supported by the
1607 SCSI initiator(i.e., SCSI Host
1609 @retval EFI_TIMEOUT A timeout occurred while waiting for the
1610 SCSI Request Packet to execute.
1611 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet
1613 @retval EFI_OUT_OF_RESOURCES The request could not be completed due
1614 to a lack of resources.
1619 ScsiRead10CommandEx (
1620 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1622 IN OUT VOID
*SenseData OPTIONAL
,
1623 IN OUT UINT8
*SenseDataLength
,
1624 OUT UINT8
*HostAdapterStatus
,
1625 OUT UINT8
*TargetStatus
,
1626 IN OUT VOID
*DataBuffer OPTIONAL
,
1627 IN OUT UINT32
*DataLength
,
1629 IN UINT32 SectorSize
,
1630 IN EFI_EVENT Event OPTIONAL
1633 EFI_SCSI_LIB_ASYNC_CONTEXT
*Context
;
1634 EFI_SCSI_IO_SCSI_REQUEST_PACKET
*CommandPacket
;
1637 EFI_EVENT SelfEvent
;
1639 if (Event
== NULL
) {
1640 return ScsiRead10Command (
1654 ASSERT (SenseDataLength
!= NULL
);
1655 ASSERT (HostAdapterStatus
!= NULL
);
1656 ASSERT (TargetStatus
!= NULL
);
1657 ASSERT (DataLength
!= NULL
);
1658 ASSERT (ScsiIo
!= NULL
);
1660 Context
= AllocateZeroPool (sizeof (EFI_SCSI_LIB_ASYNC_CONTEXT
));
1661 if (Context
== NULL
) {
1662 return EFI_OUT_OF_RESOURCES
;
1665 Cdb
= AllocateZeroPool (EFI_SCSI_OP_LENGTH_TEN
);
1667 Status
= EFI_OUT_OF_RESOURCES
;
1671 Context
->SenseDataLength
= SenseDataLength
;
1672 Context
->HostAdapterStatus
= HostAdapterStatus
;
1673 Context
->TargetStatus
= TargetStatus
;
1674 Context
->CallerEvent
= Event
;
1676 CommandPacket
= &Context
->CommandPacket
;
1677 CommandPacket
->Timeout
= Timeout
;
1678 CommandPacket
->InDataBuffer
= DataBuffer
;
1679 CommandPacket
->SenseData
= SenseData
;
1680 CommandPacket
->InTransferLength
= *DataLength
;
1681 CommandPacket
->Cdb
= Cdb
;
1683 // Fill Cdb for Read (10) Command
1685 Cdb
[0] = EFI_SCSI_OP_READ10
;
1686 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
1687 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
)SectorSize
));
1689 CommandPacket
->CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
1690 CommandPacket
->DataDirection
= EFI_SCSI_DATA_IN
;
1691 CommandPacket
->SenseDataLength
= *SenseDataLength
;
1696 Status
= gBS
->CreateEvent (
1703 if (EFI_ERROR (Status
)) {
1707 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, CommandPacket
, SelfEvent
);
1708 if (EFI_ERROR (Status
)) {
1710 // Since ScsiLibNotify() will not be signaled if ExecuteScsiCommand()
1711 // returns with error, close the event here.
1713 gBS
->CloseEvent (SelfEvent
);
1720 if (Context
!= NULL
) {
1728 Execute blocking/non-blocking Write(10) SCSI command on a specific SCSI
1731 Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.
1732 When Event is NULL, blocking command will be executed. Otherwise non-blocking
1733 command will be executed.
1734 For blocking I/O, if Timeout is zero, this function will wait indefinitely
1735 for the command to complete. If Timeout is greater than zero, then the
1736 command is executed and will timeout after Timeout 100 ns units.
1737 For non-blocking I/O, if Timeout is zero, Event will be signaled only after
1738 the command to completes. If Timeout is greater than zero, Event will also be
1739 signaled after Timeout 100 ns units.
1740 The StartLba and SectorSize parameters are used to construct the CDB for this
1743 If ScsiIo is NULL, then ASSERT().
1744 If SenseDataLength is NULL, then ASSERT().
1745 If HostAdapterStatus is NULL, then ASSERT().
1746 If TargetStatus is NULL, then ASSERT().
1747 If DataLength is NULL, then ASSERT().
1749 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet
1750 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
1751 EFI_INVALID_PARAMETER gets returned.
1753 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet
1754 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
1755 EFI_INVALID_PARAMETER gets returned.
1757 @param[in] ScsiIo SCSI IO Protocol to use
1758 @param[in] Timeout The length of timeout period.
1759 @param[in, out] SenseData A pointer to output sense data.
1760 @param[in, out] SenseDataLength The length of output sense data.
1761 @param[out] HostAdapterStatus The status of Host Adapter.
1762 @param[out] TargetStatus The status of the target.
1763 @param[in, out] DataBuffer A pointer to a data buffer.
1764 @param[in, out] DataLength The length of data buffer.
1765 @param[in] StartLba The start address of LBA.
1766 @param[in] SectorSize The number of contiguous logical blocks
1767 of data that shall be transferred.
1768 @param[in] Event If the SCSI target does not support
1769 non-blocking I/O, then Event is ignored,
1770 and blocking I/O is performed. If Event
1771 is NULL, then blocking I/O is performed.
1772 If Event is not NULL and non-blocking
1773 I/O is supported, then non-blocking I/O
1774 is performed, and Event will be signaled
1775 when the SCSI Write(10) command
1778 @retval EFI_SUCCESS Command is executed successfully.
1779 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
1780 but the entire DataBuffer could not be
1781 transferred. The actual number of bytes
1782 transferred is returned in DataLength.
1783 @retval EFI_NOT_READY The SCSI Request Packet could not be
1784 sent because there are too many SCSI
1785 Command Packets already queued.
1786 @retval EFI_DEVICE_ERROR A device error occurred while attempting
1787 to send SCSI Request Packet.
1788 @retval EFI_UNSUPPORTED The command described by the SCSI
1789 Request Packet is not supported by the
1790 SCSI initiator(i.e., SCSI Host
1792 @retval EFI_TIMEOUT A timeout occurred while waiting for the
1793 SCSI Request Packet to execute.
1794 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet
1796 @retval EFI_OUT_OF_RESOURCES The request could not be completed due
1797 to a lack of resources.
1802 ScsiWrite10CommandEx (
1803 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1805 IN OUT VOID
*SenseData OPTIONAL
,
1806 IN OUT UINT8
*SenseDataLength
,
1807 OUT UINT8
*HostAdapterStatus
,
1808 OUT UINT8
*TargetStatus
,
1809 IN OUT VOID
*DataBuffer OPTIONAL
,
1810 IN OUT UINT32
*DataLength
,
1812 IN UINT32 SectorSize
,
1813 IN EFI_EVENT Event OPTIONAL
1816 EFI_SCSI_LIB_ASYNC_CONTEXT
*Context
;
1817 EFI_SCSI_IO_SCSI_REQUEST_PACKET
*CommandPacket
;
1820 EFI_EVENT SelfEvent
;
1822 if (Event
== NULL
) {
1823 return ScsiWrite10Command (
1837 ASSERT (SenseDataLength
!= NULL
);
1838 ASSERT (HostAdapterStatus
!= NULL
);
1839 ASSERT (TargetStatus
!= NULL
);
1840 ASSERT (DataLength
!= NULL
);
1841 ASSERT (ScsiIo
!= NULL
);
1843 Context
= AllocateZeroPool (sizeof (EFI_SCSI_LIB_ASYNC_CONTEXT
));
1844 if (Context
== NULL
) {
1845 return EFI_OUT_OF_RESOURCES
;
1848 Cdb
= AllocateZeroPool (EFI_SCSI_OP_LENGTH_TEN
);
1850 Status
= EFI_OUT_OF_RESOURCES
;
1854 Context
->SenseDataLength
= SenseDataLength
;
1855 Context
->HostAdapterStatus
= HostAdapterStatus
;
1856 Context
->TargetStatus
= TargetStatus
;
1857 Context
->CallerEvent
= Event
;
1859 CommandPacket
= &Context
->CommandPacket
;
1860 CommandPacket
->Timeout
= Timeout
;
1861 CommandPacket
->OutDataBuffer
= DataBuffer
;
1862 CommandPacket
->SenseData
= SenseData
;
1863 CommandPacket
->OutTransferLength
= *DataLength
;
1864 CommandPacket
->Cdb
= Cdb
;
1866 // Fill Cdb for Write (10) Command
1868 Cdb
[0] = EFI_SCSI_OP_WRITE10
;
1869 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
1870 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
)SectorSize
));
1872 CommandPacket
->CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
1873 CommandPacket
->DataDirection
= EFI_SCSI_DATA_OUT
;
1874 CommandPacket
->SenseDataLength
= *SenseDataLength
;
1879 Status
= gBS
->CreateEvent (
1886 if (EFI_ERROR (Status
)) {
1890 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, CommandPacket
, SelfEvent
);
1891 if (EFI_ERROR (Status
)) {
1893 // Since ScsiLibNotify() will not be signaled if ExecuteScsiCommand()
1894 // returns with error, close the event here.
1896 gBS
->CloseEvent (SelfEvent
);
1903 if (Context
!= NULL
) {
1911 Execute blocking/non-blocking Read(16) SCSI command on a specific SCSI
1914 Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.
1915 When Event is NULL, blocking command will be executed. Otherwise non-blocking
1916 command will be executed.
1917 For blocking I/O, if Timeout is zero, this function will wait indefinitely
1918 for the command to complete. If Timeout is greater than zero, then the
1919 command is executed and will timeout after Timeout 100 ns units.
1920 For non-blocking I/O, if Timeout is zero, Event will be signaled only after
1921 the command to completes. If Timeout is greater than zero, Event will also be
1922 signaled after Timeout 100 ns units.
1923 The StartLba and SectorSize parameters are used to construct the CDB for this
1926 If ScsiIo is NULL, then ASSERT().
1927 If SenseDataLength is NULL, then ASSERT().
1928 If HostAdapterStatus is NULL, then ASSERT().
1929 If TargetStatus is NULL, then ASSERT().
1930 If DataLength is NULL, then ASSERT().
1932 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet
1933 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
1934 EFI_INVALID_PARAMETER gets returned.
1936 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet
1937 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
1938 EFI_INVALID_PARAMETER gets returned.
1940 @param[in] ScsiIo A pointer to SCSI IO protocol.
1941 @param[in] Timeout The length of timeout period.
1942 @param[in, out] SenseData A pointer to output sense data.
1943 @param[in, out] SenseDataLength The length of output sense data.
1944 @param[out] HostAdapterStatus The status of Host Adapter.
1945 @param[out] TargetStatus The status of the target.
1946 @param[in, out] DataBuffer Read 16 command data.
1947 @param[in, out] DataLength The length of data buffer.
1948 @param[in] StartLba The start address of LBA.
1949 @param[in] SectorSize The number of contiguous logical blocks
1950 of data that shall be transferred.
1951 @param[in] Event If the SCSI target does not support
1952 non-blocking I/O, then Event is ignored,
1953 and blocking I/O is performed. If Event
1954 is NULL, then blocking I/O is performed.
1955 If Event is not NULL and non-blocking
1956 I/O is supported, then non-blocking I/O
1957 is performed, and Event will be signaled
1958 when the SCSI Read(16) command
1961 @retval EFI_SUCCESS Command is executed successfully.
1962 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
1963 but the entire DataBuffer could not be
1964 transferred. The actual number of bytes
1965 transferred is returned in DataLength.
1966 @retval EFI_NOT_READY The SCSI Request Packet could not be
1967 sent because there are too many SCSI
1968 Command Packets already queued.
1969 @retval EFI_DEVICE_ERROR A device error occurred while attempting
1970 to send SCSI Request Packet.
1971 @retval EFI_UNSUPPORTED The command described by the SCSI
1972 Request Packet is not supported by the
1973 SCSI initiator(i.e., SCSI Host
1975 @retval EFI_TIMEOUT A timeout occurred while waiting for the
1976 SCSI Request Packet to execute.
1977 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet
1979 @retval EFI_OUT_OF_RESOURCES The request could not be completed due
1980 to a lack of resources.
1985 ScsiRead16CommandEx (
1986 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1988 IN OUT VOID
*SenseData OPTIONAL
,
1989 IN OUT UINT8
*SenseDataLength
,
1990 OUT UINT8
*HostAdapterStatus
,
1991 OUT UINT8
*TargetStatus
,
1992 IN OUT VOID
*DataBuffer OPTIONAL
,
1993 IN OUT UINT32
*DataLength
,
1995 IN UINT32 SectorSize
,
1996 IN EFI_EVENT Event OPTIONAL
1999 EFI_SCSI_LIB_ASYNC_CONTEXT
*Context
;
2000 EFI_SCSI_IO_SCSI_REQUEST_PACKET
*CommandPacket
;
2003 EFI_EVENT SelfEvent
;
2005 if (Event
== NULL
) {
2006 return ScsiRead16Command (
2020 ASSERT (SenseDataLength
!= NULL
);
2021 ASSERT (HostAdapterStatus
!= NULL
);
2022 ASSERT (TargetStatus
!= NULL
);
2023 ASSERT (DataLength
!= NULL
);
2024 ASSERT (ScsiIo
!= NULL
);
2026 Context
= AllocateZeroPool (sizeof (EFI_SCSI_LIB_ASYNC_CONTEXT
));
2027 if (Context
== NULL
) {
2028 return EFI_OUT_OF_RESOURCES
;
2031 Cdb
= AllocateZeroPool (EFI_SCSI_OP_LENGTH_SIXTEEN
);
2033 Status
= EFI_OUT_OF_RESOURCES
;
2037 Context
->SenseDataLength
= SenseDataLength
;
2038 Context
->HostAdapterStatus
= HostAdapterStatus
;
2039 Context
->TargetStatus
= TargetStatus
;
2040 Context
->CallerEvent
= Event
;
2042 CommandPacket
= &Context
->CommandPacket
;
2043 CommandPacket
->Timeout
= Timeout
;
2044 CommandPacket
->InDataBuffer
= DataBuffer
;
2045 CommandPacket
->SenseData
= SenseData
;
2046 CommandPacket
->InTransferLength
= *DataLength
;
2047 CommandPacket
->Cdb
= Cdb
;
2049 // Fill Cdb for Read (16) Command
2051 Cdb
[0] = EFI_SCSI_OP_READ16
;
2052 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
2053 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
2055 CommandPacket
->CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
2056 CommandPacket
->DataDirection
= EFI_SCSI_DATA_IN
;
2057 CommandPacket
->SenseDataLength
= *SenseDataLength
;
2062 Status
= gBS
->CreateEvent (
2069 if (EFI_ERROR (Status
)) {
2073 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, CommandPacket
, SelfEvent
);
2074 if (EFI_ERROR (Status
)) {
2076 // Since ScsiLibNotify() will not be signaled if ExecuteScsiCommand()
2077 // returns with error, close the event here.
2079 gBS
->CloseEvent (SelfEvent
);
2086 if (Context
!= NULL
) {
2094 Execute blocking/non-blocking Write(16) SCSI command on a specific SCSI
2097 Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.
2098 When Event is NULL, blocking command will be executed. Otherwise non-blocking
2099 command will be executed.
2100 For blocking I/O, if Timeout is zero, this function will wait indefinitely
2101 for the command to complete. If Timeout is greater than zero, then the
2102 command is executed and will timeout after Timeout 100 ns units.
2103 For non-blocking I/O, if Timeout is zero, Event will be signaled only after
2104 the command to completes. If Timeout is greater than zero, Event will also be
2105 signaled after Timeout 100 ns units.
2106 The StartLba and SectorSize parameters are used to construct the CDB for this
2109 If ScsiIo is NULL, then ASSERT().
2110 If SenseDataLength is NULL, then ASSERT().
2111 If HostAdapterStatus is NULL, then ASSERT().
2112 If TargetStatus is NULL, then ASSERT().
2113 If DataLength is NULL, then ASSERT().
2115 If SenseDataLength is non-zero and SenseData is not NULL, SenseData must meet
2116 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
2117 EFI_INVALID_PARAMETER gets returned.
2119 If DataLength is non-zero and DataBuffer is not NULL, DataBuffer must meet
2120 buffer alignment requirement defined in EFI_SCSI_IO_PROTOCOL. Otherwise
2121 EFI_INVALID_PARAMETER gets returned.
2123 @param[in] ScsiIo SCSI IO Protocol to use
2124 @param[in] Timeout The length of timeout period.
2125 @param[in, out] SenseData A pointer to output sense data.
2126 @param[in, out] SenseDataLength The length of output sense data.
2127 @param[out] HostAdapterStatus The status of Host Adapter.
2128 @param[out] TargetStatus The status of the target.
2129 @param[in, out] DataBuffer A pointer to a data buffer.
2130 @param[in, out] DataLength The length of data buffer.
2131 @param[in] StartLba The start address of LBA.
2132 @param[in] SectorSize The number of contiguous logical blocks
2133 of data that shall be transferred.
2134 @param[in] Event If the SCSI target does not support
2135 non-blocking I/O, then Event is ignored,
2136 and blocking I/O is performed. If Event
2137 is NULL, then blocking I/O is performed.
2138 If Event is not NULL and non-blocking
2139 I/O is supported, then non-blocking I/O
2140 is performed, and Event will be signaled
2141 when the SCSI Write(16) command
2144 @retval EFI_SUCCESS Command is executed successfully.
2145 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
2146 but the entire DataBuffer could not be
2147 transferred. The actual number of bytes
2148 transferred is returned in DataLength.
2149 @retval EFI_NOT_READY The SCSI Request Packet could not be
2150 sent because there are too many SCSI
2151 Command Packets already queued.
2152 @retval EFI_DEVICE_ERROR A device error occurred while attempting
2153 to send SCSI Request Packet.
2154 @retval EFI_UNSUPPORTED The command described by the SCSI
2155 Request Packet is not supported by the
2156 SCSI initiator(i.e., SCSI Host
2158 @retval EFI_TIMEOUT A timeout occurred while waiting for the
2159 SCSI Request Packet to execute.
2160 @retval EFI_INVALID_PARAMETER The contents of the SCSI Request Packet
2162 @retval EFI_OUT_OF_RESOURCES The request could not be completed due
2163 to a lack of resources.
2168 ScsiWrite16CommandEx (
2169 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
2171 IN OUT VOID
*SenseData OPTIONAL
,
2172 IN OUT UINT8
*SenseDataLength
,
2173 OUT UINT8
*HostAdapterStatus
,
2174 OUT UINT8
*TargetStatus
,
2175 IN OUT VOID
*DataBuffer OPTIONAL
,
2176 IN OUT UINT32
*DataLength
,
2178 IN UINT32 SectorSize
,
2179 IN EFI_EVENT Event OPTIONAL
2182 EFI_SCSI_LIB_ASYNC_CONTEXT
*Context
;
2183 EFI_SCSI_IO_SCSI_REQUEST_PACKET
*CommandPacket
;
2186 EFI_EVENT SelfEvent
;
2188 if (Event
== NULL
) {
2189 return ScsiWrite16Command (
2203 ASSERT (SenseDataLength
!= NULL
);
2204 ASSERT (HostAdapterStatus
!= NULL
);
2205 ASSERT (TargetStatus
!= NULL
);
2206 ASSERT (DataLength
!= NULL
);
2207 ASSERT (ScsiIo
!= NULL
);
2209 Context
= AllocateZeroPool (sizeof (EFI_SCSI_LIB_ASYNC_CONTEXT
));
2210 if (Context
== NULL
) {
2211 return EFI_OUT_OF_RESOURCES
;
2214 Cdb
= AllocateZeroPool (EFI_SCSI_OP_LENGTH_SIXTEEN
);
2216 Status
= EFI_OUT_OF_RESOURCES
;
2220 Context
->SenseDataLength
= SenseDataLength
;
2221 Context
->HostAdapterStatus
= HostAdapterStatus
;
2222 Context
->TargetStatus
= TargetStatus
;
2223 Context
->CallerEvent
= Event
;
2225 CommandPacket
= &Context
->CommandPacket
;
2226 CommandPacket
->Timeout
= Timeout
;
2227 CommandPacket
->OutDataBuffer
= DataBuffer
;
2228 CommandPacket
->SenseData
= SenseData
;
2229 CommandPacket
->OutTransferLength
= *DataLength
;
2230 CommandPacket
->Cdb
= Cdb
;
2232 // Fill Cdb for Write (16) Command
2234 Cdb
[0] = EFI_SCSI_OP_WRITE16
;
2235 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
2236 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
2238 CommandPacket
->CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
2239 CommandPacket
->DataDirection
= EFI_SCSI_DATA_OUT
;
2240 CommandPacket
->SenseDataLength
= *SenseDataLength
;
2245 Status
= gBS
->CreateEvent (
2252 if (EFI_ERROR (Status
)) {
2256 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, CommandPacket
, SelfEvent
);
2257 if (EFI_ERROR (Status
)) {
2259 // Since ScsiLibNotify() will not be signaled if ExecuteScsiCommand()
2260 // returns with error, close the event here.
2262 gBS
->CloseEvent (SelfEvent
);
2269 if (Context
!= NULL
) {