2 UEFI SCSI Library implementation
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/BaseLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiScsiLib.h>
20 #include <Library/BaseMemoryLib.h>
22 #include <IndustryStandard/Scsi.h>
26 // Scsi Command Length
28 #define EFI_SCSI_OP_LENGTH_SIX 0x6
29 #define EFI_SCSI_OP_LENGTH_TEN 0xa
30 #define EFI_SCSI_OP_LENGTH_SIXTEEN 0x10
35 Execute Test Unit Ready SCSI command on a specific SCSI target.
37 Executes the Test Unit Ready command on the SCSI target specified by ScsiIo.
38 If Timeout is zero, then this function waits indefinitely for the command to complete.
39 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
40 If ScsiIo is NULL, then ASSERT().
41 If SenseDataLength is NULL, then ASSERT().
42 If HostAdapterStatus is NULL, then ASSERT().
43 If TargetStatus is NULL, then ASSERT().
46 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
47 for the specific SCSI target.
48 @param[in] Timeout The timeout in 100 ns units to use for the execution
49 of this SCSI Request Packet. A Timeout value of
50 zero means that this function will wait indefinitely
51 for the SCSI Request Packet to execute. If Timeout
52 is greater than zero, then this function will return
53 EFI_TIMEOUT if the time required to execute the SCSI
54 Request Packet is greater than Timeout.
55 @param[in, out] SenseData A pointer to sense data that was generated by
56 the execution of the SCSI Request Packet. This
57 buffer must be allocated by the caller.
58 If SenseDataLength is 0, then this parameter is
59 optional and may be NULL.
60 @param[in, out] SenseDataLength On input, a pointer to the length in bytes of
61 the SenseData buffer. On output, a pointer to
62 the number of bytes written to the SenseData buffer.
63 @param[out] HostAdapterStatus The status of the SCSI Host Controller that produces
64 the SCSI bus containing the SCSI target specified by
65 ScsiIo when the SCSI Request Packet was executed.
66 See the EFI SCSI I/O Protocol in the UEFI Specification
67 for details on the possible return values.
68 @param[out] TargetStatus The status returned by the SCSI target specified
69 by ScsiIo when the SCSI Request Packet was executed
70 on the SCSI Host Controller. See the EFI SCSI I/O
71 Protocol in the UEFI Specification for details on
72 the possible return values.
74 @retval EFI_SUCCESS The command was executed successfully.
75 See HostAdapterStatus, TargetStatus, SenseDataLength,
76 and SenseData in that order for additional status
78 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
79 there are too many SCSI Command Packets already
80 queued. The SCSI Request Packet was not sent, so
81 no additional status information is available.
82 The caller may retry again later.
83 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
84 SCSI Request Packet. See HostAdapterStatus,
85 TargetStatus, SenseDataLength, and SenseData in that
86 order for additional status information.
87 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
88 is not supported by the SCSI initiator(i.e., SCSI
89 Host Controller). The SCSI Request Packet was not
90 sent, so no additional status information is available.
91 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
92 Packet to execute. See HostAdapterStatus, TargetStatus,
93 SenseDataLength, and SenseData in that order for
94 additional status information.
99 ScsiTestUnitReadyCommand (
100 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
102 IN OUT VOID
*SenseData
, OPTIONAL
103 IN OUT UINT8
*SenseDataLength
,
104 OUT UINT8
*HostAdapterStatus
,
105 OUT UINT8
*TargetStatus
108 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
110 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
112 ASSERT (SenseDataLength
!= NULL
);
113 ASSERT (HostAdapterStatus
!= NULL
);
114 ASSERT (TargetStatus
!= NULL
);
115 ASSERT (ScsiIo
!= NULL
);
117 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
118 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
120 CommandPacket
.Timeout
= Timeout
;
121 CommandPacket
.InDataBuffer
= NULL
;
122 CommandPacket
.InTransferLength
= 0;
123 CommandPacket
.OutDataBuffer
= NULL
;
124 CommandPacket
.OutTransferLength
= 0;
125 CommandPacket
.SenseData
= SenseData
;
126 CommandPacket
.Cdb
= Cdb
;
128 // Fill Cdb for Test Unit Ready Command
130 Cdb
[0] = EFI_SCSI_OP_TEST_UNIT_READY
;
131 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
132 CommandPacket
.SenseDataLength
= *SenseDataLength
;
134 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
136 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
137 *TargetStatus
= CommandPacket
.TargetStatus
;
138 *SenseDataLength
= CommandPacket
.SenseDataLength
;
145 Execute Inquiry SCSI command on a specific SCSI target.
147 Executes the Inquiry command on the SCSI target specified by ScsiIo.
148 If Timeout is zero, then this function waits indefinitely for the command to complete.
149 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
150 If ScsiIo is NULL, then ASSERT().
151 If SenseDataLength is NULL, then ASSERT().
152 If HostAdapterStatus is NULL, then ASSERT().
153 If TargetStatus is NULL, then ASSERT().
154 If InquiryDataLength is NULL, then ASSERT().
156 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
157 for the specific SCSI target.
158 @param[in] Timeout The timeout in 100 ns units to use for the
159 execution of this SCSI Request Packet. A Timeout
160 value of zero means that this function will wait
161 indefinitely for the SCSI Request Packet to execute.
162 If Timeout is greater than zero, then this function
163 will return EFI_TIMEOUT if the time required to
164 execute the SCSI Request Packet is greater than Timeout.
165 @param[in, out] SenseData A pointer to sense data that was generated
166 by the execution of the SCSI Request Packet.
167 This buffer must be allocated by the caller.
168 If SenseDataLength is 0, then this parameter
169 is optional and may be NULL.
170 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
171 On output, the number of bytes written to the SenseData buffer.
172 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
173 produces the SCSI bus containing the SCSI
174 target specified by ScsiIo when the SCSI
175 Request Packet was executed. See the EFI
176 SCSI I/O Protocol in the UEFI Specification
177 for details on the possible return values.
178 @param[out] TargetStatus The status returned by the SCSI target specified
179 by ScsiIo when the SCSI Request Packet was
180 executed on the SCSI Host Controller.
181 See the EFI SCSI I/O Protocol in the UEFI
182 Specification for details on the possible
184 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated
185 by the execution of the SCSI Request Packet.
186 This buffer must be allocated by the caller.
187 If InquiryDataLength is 0, then this parameter
188 is optional and may be NULL.
189 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes
190 of the InquiryDataBuffer buffer.
191 On output, a pointer to the number of bytes
192 written to the InquiryDataBuffer buffer.
193 @param[in] EnableVitalProductData If TRUE, then the supported vital product
194 data for the PageCode is returned in InquiryDataBuffer.
195 If FALSE, then the standard inquiry data is
196 returned in InquiryDataBuffer and PageCode is ignored.
197 @param[in] PageCode The page code of the vital product data.
198 It's ignored if EnableVitalProductData is FALSE.
200 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,
201 TargetStatus, SenseDataLength, and SenseData in that order
202 for additional status information.
203 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
204 InquiryDataBuffer could not be transferred. The actual
205 number of bytes transferred is returned in InquiryDataLength.
206 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there
207 are too many SCSI Command Packets already queued.
208 The SCSI Request Packet was not sent, so no additional
209 status information is available. The caller may retry again later.
210 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI
211 Request Packet. See HostAdapterStatus, TargetStatus,
212 SenseDataLength, and SenseData in that order for additional
214 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not
215 supported by the SCSI initiator(i.e., SCSI Host Controller).
216 The SCSI Request Packet was not sent, so no additional
217 status information is available.
218 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
219 Packet to execute. See HostAdapterStatus, TargetStatus,
220 SenseDataLength, and SenseData in that order for
221 additional status information.
226 ScsiInquiryCommandEx (
227 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
229 IN OUT VOID
*SenseData
, OPTIONAL
230 IN OUT UINT8
*SenseDataLength
,
231 OUT UINT8
*HostAdapterStatus
,
232 OUT UINT8
*TargetStatus
,
233 IN OUT VOID
*InquiryDataBuffer
, OPTIONAL
234 IN OUT UINT32
*InquiryDataLength
,
235 IN BOOLEAN EnableVitalProductData
,
239 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
241 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
243 ASSERT (SenseDataLength
!= NULL
);
244 ASSERT (HostAdapterStatus
!= NULL
);
245 ASSERT (TargetStatus
!= NULL
);
246 ASSERT (InquiryDataLength
!= NULL
);
247 ASSERT (ScsiIo
!= NULL
);
249 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
250 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
252 CommandPacket
.Timeout
= Timeout
;
253 CommandPacket
.InDataBuffer
= InquiryDataBuffer
;
254 CommandPacket
.InTransferLength
= *InquiryDataLength
;
255 CommandPacket
.SenseData
= SenseData
;
256 CommandPacket
.SenseDataLength
= *SenseDataLength
;
257 CommandPacket
.Cdb
= Cdb
;
259 Cdb
[0] = EFI_SCSI_OP_INQUIRY
;
260 if (EnableVitalProductData
) {
265 if (*InquiryDataLength
> 0xff) {
266 *InquiryDataLength
= 0xff;
269 Cdb
[4] = (UINT8
) (*InquiryDataLength
);
270 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
271 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
273 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
275 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
276 *TargetStatus
= CommandPacket
.TargetStatus
;
277 *SenseDataLength
= CommandPacket
.SenseDataLength
;
278 *InquiryDataLength
= CommandPacket
.InTransferLength
;
285 Execute Inquiry SCSI command on a specific SCSI target.
287 Executes the Inquiry command on the SCSI target specified by ScsiIo.
288 If Timeout is zero, then this function waits indefinitely for the command to complete.
289 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
290 If ScsiIo is NULL, then ASSERT().
291 If SenseDataLength is NULL, then ASSERT().
292 If HostAdapterStatus is NULL, then ASSERT().
293 If TargetStatus is NULL, then ASSERT().
294 If InquiryDataLength is NULL, then ASSERT().
296 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
297 for the specific SCSI target.
298 @param[in] Timeout The timeout in 100 ns units to use for the
299 execution of this SCSI Request Packet. A Timeout
300 value of zero means that this function will wait
301 indefinitely for the SCSI Request Packet to execute.
302 If Timeout is greater than zero, then this function
303 will return EFI_TIMEOUT if the time required to
304 execute the SCSI Request Packet is greater than Timeout.
305 @param[in, out] SenseData A pointer to sense data that was generated
306 by the execution of the SCSI Request Packet.
307 This buffer must be allocated by the caller.
308 If SenseDataLength is 0, then this parameter
309 is optional and may be NULL.
310 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
311 On output, the number of bytes written to the SenseData buffer.
312 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
313 produces the SCSI bus containing the SCSI
314 target specified by ScsiIo when the SCSI
315 Request Packet was executed. See the EFI
316 SCSI I/O Protocol in the UEFI Specification
317 for details on the possible return values.
318 @param[out] TargetStatus The status returned by the SCSI target specified
319 by ScsiIo when the SCSI Request Packet was
320 executed on the SCSI Host Controller.
321 See the EFI SCSI I/O Protocol in the UEFI
322 Specification for details on the possible
324 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated
325 by the execution of the SCSI Request Packet.
326 This buffer must be allocated by the caller.
327 If InquiryDataLength is 0, then this parameter
328 is optional and may be NULL.
329 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes
330 of the InquiryDataBuffer buffer.
331 On output, a pointer to the number of bytes
332 written to the InquiryDataBuffer buffer.
333 @param[in] EnableVitalProductData If TRUE, then the supported vital product
334 data is returned in InquiryDataBuffer.
335 If FALSE, then the standard inquiry data is
336 returned in InquiryDataBuffer.
338 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,
339 TargetStatus, SenseDataLength, and SenseData in that order
340 for additional status information.
341 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
342 InquiryDataBuffer could not be transferred. The actual
343 number of bytes transferred is returned in InquiryDataLength.
344 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there
345 are too many SCSI Command Packets already queued.
346 The SCSI Request Packet was not sent, so no additional
347 status information is available. The caller may retry again later.
348 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI
349 Request Packet. See HostAdapterStatus, TargetStatus,
350 SenseDataLength, and SenseData in that order for additional
352 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not
353 supported by the SCSI initiator(i.e., SCSI Host Controller).
354 The SCSI Request Packet was not sent, so no additional
355 status information is available.
356 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
357 Packet to execute. See HostAdapterStatus, TargetStatus,
358 SenseDataLength, and SenseData in that order for
359 additional status information.
365 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
367 IN OUT VOID
*SenseData
, OPTIONAL
368 IN OUT UINT8
*SenseDataLength
,
369 OUT UINT8
*HostAdapterStatus
,
370 OUT UINT8
*TargetStatus
,
371 IN OUT VOID
*InquiryDataBuffer
, OPTIONAL
372 IN OUT UINT32
*InquiryDataLength
,
373 IN BOOLEAN EnableVitalProductData
376 return ScsiInquiryCommandEx (
385 EnableVitalProductData
,
391 Execute Mode Sense(10) SCSI command on a specific SCSI target.
393 Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.
394 If Timeout is zero, then this function waits indefinitely for the command to complete.
395 If Timeout is greater than zero, then the command is executed and will timeout
396 after Timeout 100 ns units. The DBDField, PageControl, and PageCode parameters
397 are used to construct the CDB for this SCSI command.
398 If ScsiIo is NULL, then ASSERT().
399 If SenseDataLength is NULL, then ASSERT().
400 If HostAdapterStatus is NULL, then ASSERT().
401 If TargetStatus is NULL, then ASSERT().
402 If DataLength is NULL, then ASSERT().
405 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
406 for the specific SCSI target.
407 @param[in] Timeout The timeout in 100 ns units to use for the
408 execution of this SCSI Request Packet. A Timeout
409 value of zero means that this function will wait
410 indefinitely for the SCSI Request Packet to execute.
411 If Timeout is greater than zero, then this function
412 will return EFI_TIMEOUT if the time required to
413 execute the SCSI Request Packet is greater than Timeout.
414 @param[in, out] SenseData A pointer to sense data that was generated
415 by the execution of the SCSI Request Packet.
416 This buffer must be allocated by the caller.
417 If SenseDataLength is 0, then this parameter
418 is optional and may be NULL.
419 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
420 On output, the number of bytes written to the SenseData buffer.
421 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
422 produces the SCSI bus containing the SCSI target
423 specified by ScsiIo when the SCSI Request Packet
424 was executed. See the EFI SCSI I/O Protocol in the
425 UEFI Specification for details on the possible
427 @param[out] TargetStatus The status returned by the SCSI target specified
428 by ScsiIo when the SCSI Request Packet was executed
429 on the SCSI Host Controller. See the EFI SCSI
430 I/O Protocol in the UEFI Specification for details
431 on the possible return values.
432 @param[in, out] DataBuffer A pointer to data that was generated by the
433 execution of the SCSI Request Packet. This
434 buffer must be allocated by the caller. If
435 DataLength is 0, then this parameter is optional
437 @param[in, out] DataLength On input, a pointer to the length in bytes of
438 the DataBuffer buffer. On output, a pointer
439 to the number of bytes written to the DataBuffer
441 @param[in] DBDField Specifies the DBD field of the CDB for this SCSI Command.
442 @param[in] PageControl Specifies the PC field of the CDB for this SCSI Command.
443 @param[in] PageCode Specifies the Page Control field of the CDB for this SCSI Command.
445 @retval EFI_SUCCESS The command executed successfully.
446 See HostAdapterStatus, TargetStatus, SenseDataLength,
447 and SenseData in that order for additional status information.
448 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the
449 entire DataBuffer could not be transferred.
450 The actual number of bytes transferred is returned
452 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
453 there are too many SCSI Command Packets already queued.
454 The SCSI Request Packet was not sent, so no additional
455 status information is available. The caller may retry
457 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
458 SCSI Request Packet. See HostAdapterStatus, TargetStatus,
459 SenseDataLength, and SenseData in that order for
460 additional status information.
461 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
462 is not supported by the SCSI initiator(i.e., SCSI
463 Host Controller). The SCSI Request Packet was not
464 sent, so no additional status information is available.
465 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
466 Request Packet to execute. See HostAdapterStatus,
467 TargetStatus, SenseDataLength, and SenseData in that
468 order for additional status information.
473 ScsiModeSense10Command (
474 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
476 IN OUT VOID
*SenseData
, OPTIONAL
477 IN OUT UINT8
*SenseDataLength
,
478 OUT UINT8
*HostAdapterStatus
,
479 OUT UINT8
*TargetStatus
,
480 IN OUT VOID
*DataBuffer
, OPTIONAL
481 IN OUT UINT32
*DataLength
,
482 IN UINT8 DBDField
, OPTIONAL
483 IN UINT8 PageControl
,
487 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
489 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
491 ASSERT (SenseDataLength
!= NULL
);
492 ASSERT (HostAdapterStatus
!= NULL
);
493 ASSERT (TargetStatus
!= NULL
);
494 ASSERT (DataLength
!= NULL
);
495 ASSERT (ScsiIo
!= NULL
);
497 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
498 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
500 CommandPacket
.Timeout
= Timeout
;
501 CommandPacket
.InDataBuffer
= DataBuffer
;
502 CommandPacket
.SenseData
= SenseData
;
503 CommandPacket
.InTransferLength
= *DataLength
;
504 CommandPacket
.Cdb
= Cdb
;
506 // Fill Cdb for Mode Sense (10) Command
508 Cdb
[0] = EFI_SCSI_OP_MODE_SEN10
;
510 // DBDField is in Cdb[1] bit3 of (bit7..0)
512 Cdb
[1] = (UINT8
) ((DBDField
<< 3) & 0x08);
514 // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0
516 Cdb
[2] = (UINT8
) (((PageControl
<< 6) & 0xc0) | (PageCode
& 0x3f));
517 Cdb
[7] = (UINT8
) (*DataLength
>> 8);
518 Cdb
[8] = (UINT8
) (*DataLength
);
520 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
521 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
522 CommandPacket
.SenseDataLength
= *SenseDataLength
;
524 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
526 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
527 *TargetStatus
= CommandPacket
.TargetStatus
;
528 *SenseDataLength
= CommandPacket
.SenseDataLength
;
529 *DataLength
= CommandPacket
.InTransferLength
;
536 Execute Request Sense SCSI command on a specific SCSI target.
538 Executes the Request Sense command on the SCSI target specified by ScsiIo.
539 If Timeout is zero, then this function waits indefinitely for the command to complete.
540 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
541 If ScsiIo is NULL, then ASSERT().
542 If SenseDataLength is NULL, then ASSERT().
543 If HostAdapterStatus is NULL, then ASSERT().
544 If TargetStatus is NULL, then ASSERT().
546 @param[in] ScsiIo A pointer to SCSI IO protocol.
547 @param[in] Timeout The length of timeout period.
548 @param[in, out] SenseData A pointer to output sense data.
549 @param[in, out] SenseDataLength The length of output sense data.
550 @param[out] HostAdapterStatus The status of Host Adapter.
551 @param[out] TargetStatus The status of the target.
553 @retval EFI_SUCCESS The command executed successfully.
554 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are
555 too many SCSI Command Packets already queued.
556 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
557 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
558 the SCSI initiator(i.e., SCSI Host Controller)
559 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
564 ScsiRequestSenseCommand (
565 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
567 IN OUT VOID
*SenseData
, OPTIONAL
568 IN OUT UINT8
*SenseDataLength
,
569 OUT UINT8
*HostAdapterStatus
,
570 OUT UINT8
*TargetStatus
573 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
575 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
577 ASSERT (SenseDataLength
!= NULL
);
578 ASSERT (HostAdapterStatus
!= NULL
);
579 ASSERT (TargetStatus
!= NULL
);
580 ASSERT (ScsiIo
!= NULL
);
582 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
583 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
585 CommandPacket
.Timeout
= Timeout
;
586 CommandPacket
.InDataBuffer
= SenseData
;
587 CommandPacket
.SenseData
= NULL
;
588 CommandPacket
.InTransferLength
= *SenseDataLength
;
589 CommandPacket
.Cdb
= Cdb
;
591 // Fill Cdb for Request Sense Command
593 Cdb
[0] = EFI_SCSI_OP_REQUEST_SENSE
;
594 Cdb
[4] = (UINT8
) (*SenseDataLength
);
596 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
597 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
598 CommandPacket
.SenseDataLength
= 0;
600 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
602 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
603 *TargetStatus
= CommandPacket
.TargetStatus
;
604 *SenseDataLength
= (UINT8
) CommandPacket
.InTransferLength
;
611 Execute Read Capacity SCSI command on a specific SCSI target.
613 Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.
614 If Timeout is zero, then this function waits indefinitely for the command to complete.
615 If Timeout is greater than zero, then the command is executed and will timeout after
616 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
617 If ScsiIo is NULL, then ASSERT().
618 If SenseDataLength is NULL, then ASSERT().
619 If HostAdapterStatus is NULL, then ASSERT().
620 If TargetStatus is NULL, then ASSERT().
621 If DataLength is NULL, then ASSERT().
623 @param[in] ScsiIo A pointer to SCSI IO protocol.
624 @param[in] Timeout The length of timeout period.
625 @param[in, out] SenseData A pointer to output sense data.
626 @param[in, out] SenseDataLength The length of output sense data.
627 @param[out] HostAdapterStatus The status of Host Adapter.
628 @param[out] TargetStatus The status of the target.
629 @param[in, out] DataBuffer A pointer to a data buffer.
630 @param[in, out] DataLength The length of data buffer.
631 @param[in] Pmi A partial medium indicator.
633 @retval EFI_SUCCESS The command executed successfully.
634 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
635 DataBuffer could not be transferred. The actual
636 number of bytes transferred is returned in DataLength.
637 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
638 there are too many SCSI Command Packets already queued.
639 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
640 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
641 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
642 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
647 ScsiReadCapacityCommand (
648 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
650 IN OUT VOID
*SenseData
, OPTIONAL
651 IN OUT UINT8
*SenseDataLength
,
652 OUT UINT8
*HostAdapterStatus
,
653 OUT UINT8
*TargetStatus
,
654 IN OUT VOID
*DataBuffer
, OPTIONAL
655 IN OUT UINT32
*DataLength
,
659 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
661 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
663 ASSERT (SenseDataLength
!= NULL
);
664 ASSERT (HostAdapterStatus
!= NULL
);
665 ASSERT (TargetStatus
!= NULL
);
666 ASSERT (DataLength
!= NULL
);
667 ASSERT (ScsiIo
!= NULL
);
669 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
670 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
672 CommandPacket
.Timeout
= Timeout
;
673 CommandPacket
.InDataBuffer
= DataBuffer
;
674 CommandPacket
.SenseData
= SenseData
;
675 CommandPacket
.InTransferLength
= *DataLength
;
676 CommandPacket
.Cdb
= Cdb
;
678 // Fill Cdb for Read Capacity Command
680 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY
;
683 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.
685 ZeroMem ((Cdb
+ 2), 4);
690 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
691 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
692 CommandPacket
.SenseDataLength
= *SenseDataLength
;
694 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
696 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
697 *TargetStatus
= CommandPacket
.TargetStatus
;
698 *SenseDataLength
= CommandPacket
.SenseDataLength
;
699 *DataLength
= CommandPacket
.InTransferLength
;
706 Execute Read Capacity SCSI 16 command on a specific SCSI target.
708 Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.
709 If Timeout is zero, then this function waits indefinitely for the command to complete.
710 If Timeout is greater than zero, then the command is executed and will timeout after
711 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
712 If ScsiIo is NULL, then ASSERT().
713 If SenseDataLength is NULL, then ASSERT().
714 If HostAdapterStatus is NULL, then ASSERT().
715 If TargetStatus is NULL, then ASSERT().
716 If DataLength is NULL, then ASSERT().
718 @param[in] ScsiIo A pointer to SCSI IO protocol.
719 @param[in] Timeout The length of timeout period.
720 @param[in, out] SenseData A pointer to output sense data.
721 @param[in, out] SenseDataLength The length of output sense data.
722 @param[out] HostAdapterStatus The status of Host Adapter.
723 @param[out] TargetStatus The status of the target.
724 @param[in, out] DataBuffer A pointer to a data buffer.
725 @param[in, out] DataLength The length of data buffer.
726 @param[in] Pmi Partial medium indicator.
728 @retval EFI_SUCCESS The command executed successfully.
729 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
730 DataBuffer could not be transferred. The actual
731 number of bytes transferred is returned in DataLength.
732 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
733 there are too many SCSI Command Packets already queued.
734 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
735 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
736 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
737 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
742 ScsiReadCapacity16Command (
743 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
745 IN OUT VOID
*SenseData
, OPTIONAL
746 IN OUT UINT8
*SenseDataLength
,
747 OUT UINT8
*HostAdapterStatus
,
748 OUT UINT8
*TargetStatus
,
749 IN OUT VOID
*DataBuffer
, OPTIONAL
750 IN OUT UINT32
*DataLength
,
754 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
758 ASSERT (SenseDataLength
!= NULL
);
759 ASSERT (HostAdapterStatus
!= NULL
);
760 ASSERT (TargetStatus
!= NULL
);
761 ASSERT (DataLength
!= NULL
);
762 ASSERT (ScsiIo
!= NULL
);
764 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
767 CommandPacket
.Timeout
= Timeout
;
768 CommandPacket
.InDataBuffer
= DataBuffer
;
769 CommandPacket
.SenseData
= SenseData
;
770 CommandPacket
.InTransferLength
= *DataLength
;
771 CommandPacket
.Cdb
= Cdb
;
773 // Fill Cdb for Read Capacity Command
775 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY16
;
779 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.
781 ZeroMem ((Cdb
+ 2), 8);
787 CommandPacket
.CdbLength
= 16;
788 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
789 CommandPacket
.SenseDataLength
= *SenseDataLength
;
791 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
793 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
794 *TargetStatus
= CommandPacket
.TargetStatus
;
795 *SenseDataLength
= CommandPacket
.SenseDataLength
;
796 *DataLength
= CommandPacket
.InTransferLength
;
803 Execute Read(10) SCSI command on a specific SCSI target.
805 Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.
806 If Timeout is zero, then this function waits indefinitely for the command to complete.
807 If Timeout is greater than zero, then the command is executed and will timeout
808 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
809 construct the CDB for this SCSI command.
810 If ScsiIo is NULL, then ASSERT().
811 If SenseDataLength is NULL, then ASSERT().
812 If HostAdapterStatus is NULL, then ASSERT().
813 If TargetStatus is NULL, then ASSERT().
814 If DataLength is NULL, then ASSERT().
817 @param[in] ScsiIo A pointer to SCSI IO protocol.
818 @param[in] Timeout The length of timeout period.
819 @param[in, out] SenseData A pointer to output sense data.
820 @param[in, out] SenseDataLength The length of output sense data.
821 @param[out] HostAdapterStatus The status of Host Adapter.
822 @param[out] TargetStatus The status of the target.
823 @param[in, out] DataBuffer Read 10 command data.
824 @param[in, out] DataLength The length of data buffer.
825 @param[in] StartLba The start address of LBA.
826 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
828 @retval EFI_SUCCESS The command is executed successfully.
829 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
830 not be transferred. The actual number of bytes transferred is returned in DataLength.
831 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
832 SCSI Command Packets already queued.
833 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
834 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
835 the SCSI initiator(i.e., SCSI Host Controller)
836 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
842 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
844 IN OUT VOID
*SenseData
, OPTIONAL
845 IN OUT UINT8
*SenseDataLength
,
846 OUT UINT8
*HostAdapterStatus
,
847 OUT UINT8
*TargetStatus
,
848 IN OUT VOID
*DataBuffer
, OPTIONAL
849 IN OUT UINT32
*DataLength
,
854 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
856 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
858 ASSERT (SenseDataLength
!= NULL
);
859 ASSERT (HostAdapterStatus
!= NULL
);
860 ASSERT (TargetStatus
!= NULL
);
861 ASSERT (DataLength
!= NULL
);
862 ASSERT (ScsiIo
!= NULL
);
864 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
865 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
867 CommandPacket
.Timeout
= Timeout
;
868 CommandPacket
.InDataBuffer
= DataBuffer
;
869 CommandPacket
.SenseData
= SenseData
;
870 CommandPacket
.InTransferLength
= *DataLength
;
871 CommandPacket
.Cdb
= Cdb
;
873 // Fill Cdb for Read (10) Command
875 Cdb
[0] = EFI_SCSI_OP_READ10
;
876 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
877 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
) SectorSize
));
879 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
880 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
881 CommandPacket
.SenseDataLength
= *SenseDataLength
;
883 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
885 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
886 *TargetStatus
= CommandPacket
.TargetStatus
;
887 *SenseDataLength
= CommandPacket
.SenseDataLength
;
888 *DataLength
= CommandPacket
.InTransferLength
;
895 Execute Write(10) SCSI command on a specific SCSI target.
897 Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.
898 If Timeout is zero, then this function waits indefinitely for the command to complete.
899 If Timeout is greater than zero, then the command is executed and will timeout after
900 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
901 the CDB for this SCSI command.
902 If ScsiIo is NULL, then ASSERT().
903 If SenseDataLength is NULL, then ASSERT().
904 If HostAdapterStatus is NULL, then ASSERT().
905 If TargetStatus is NULL, then ASSERT().
906 If DataLength is NULL, then ASSERT().
908 @param[in] ScsiIo SCSI IO Protocol to use
909 @param[in] Timeout The length of timeout period.
910 @param[in, out] SenseData A pointer to output sense data.
911 @param[in, out] SenseDataLength The length of output sense data.
912 @param[out] HostAdapterStatus The status of Host Adapter.
913 @param[out] TargetStatus The status of the target.
914 @param[in, out] DataBuffer A pointer to a data buffer.
915 @param[in, out] DataLength The length of data buffer.
916 @param[in] StartLba The start address of LBA.
917 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
919 @retval EFI_SUCCESS The command executed successfully.
920 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
921 not be transferred. The actual number of bytes transferred is returned in DataLength.
922 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
923 SCSI Command Packets already queued.
924 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
925 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
926 the SCSI initiator(i.e., SCSI Host Controller)
927 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
933 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
935 IN OUT VOID
*SenseData
, OPTIONAL
936 IN OUT UINT8
*SenseDataLength
,
937 OUT UINT8
*HostAdapterStatus
,
938 OUT UINT8
*TargetStatus
,
939 IN OUT VOID
*DataBuffer
, OPTIONAL
940 IN OUT UINT32
*DataLength
,
945 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
947 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
949 ASSERT (SenseDataLength
!= NULL
);
950 ASSERT (HostAdapterStatus
!= NULL
);
951 ASSERT (TargetStatus
!= NULL
);
952 ASSERT (DataLength
!= NULL
);
953 ASSERT (ScsiIo
!= NULL
);
955 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
956 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
958 CommandPacket
.Timeout
= Timeout
;
959 CommandPacket
.OutDataBuffer
= DataBuffer
;
960 CommandPacket
.SenseData
= SenseData
;
961 CommandPacket
.OutTransferLength
= *DataLength
;
962 CommandPacket
.Cdb
= Cdb
;
964 // Fill Cdb for Write (10) Command
966 Cdb
[0] = EFI_SCSI_OP_WRITE10
;
967 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
968 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
) SectorSize
));
970 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
971 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
972 CommandPacket
.SenseDataLength
= *SenseDataLength
;
974 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
976 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
977 *TargetStatus
= CommandPacket
.TargetStatus
;
978 *SenseDataLength
= CommandPacket
.SenseDataLength
;
979 *DataLength
= CommandPacket
.OutTransferLength
;
985 Execute Read(16) SCSI command on a specific SCSI target.
987 Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.
988 If Timeout is zero, then this function waits indefinitely for the command to complete.
989 If Timeout is greater than zero, then the command is executed and will timeout
990 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
991 construct the CDB for this SCSI command.
992 If ScsiIo is NULL, then ASSERT().
993 If SenseDataLength is NULL, then ASSERT().
994 If HostAdapterStatus is NULL, then ASSERT().
995 If TargetStatus is NULL, then ASSERT().
996 If DataLength is NULL, then ASSERT().
999 @param[in] ScsiIo A pointer to SCSI IO protocol.
1000 @param[in] Timeout The length of timeout period.
1001 @param[in, out] SenseData A pointer to output sense data.
1002 @param[in, out] SenseDataLength The length of output sense data.
1003 @param[out] HostAdapterStatus The status of Host Adapter.
1004 @param[out] TargetStatus The status of the target.
1005 @param[in, out] DataBuffer Read 16 command data.
1006 @param[in, out] DataLength The length of data buffer.
1007 @param[in] StartLba The start address of LBA.
1008 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
1010 @retval EFI_SUCCESS The command executed successfully.
1011 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1012 not be transferred. The actual number of bytes transferred is returned in DataLength.
1013 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1014 SCSI Command Packets already queued.
1015 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1016 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1017 the SCSI initiator(i.e., SCSI Host Controller)
1018 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1024 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1026 IN OUT VOID
*SenseData
, OPTIONAL
1027 IN OUT UINT8
*SenseDataLength
,
1028 OUT UINT8
*HostAdapterStatus
,
1029 OUT UINT8
*TargetStatus
,
1030 IN OUT VOID
*DataBuffer
, OPTIONAL
1031 IN OUT UINT32
*DataLength
,
1033 IN UINT32 SectorSize
1036 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1038 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
1040 ASSERT (SenseDataLength
!= NULL
);
1041 ASSERT (HostAdapterStatus
!= NULL
);
1042 ASSERT (TargetStatus
!= NULL
);
1043 ASSERT (DataLength
!= NULL
);
1044 ASSERT (ScsiIo
!= NULL
);
1046 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1047 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1049 CommandPacket
.Timeout
= Timeout
;
1050 CommandPacket
.InDataBuffer
= DataBuffer
;
1051 CommandPacket
.SenseData
= SenseData
;
1052 CommandPacket
.InTransferLength
= *DataLength
;
1053 CommandPacket
.Cdb
= Cdb
;
1055 // Fill Cdb for Read (16) Command
1057 Cdb
[0] = EFI_SCSI_OP_READ16
;
1058 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1059 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1061 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1062 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
1063 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1065 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1067 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1068 *TargetStatus
= CommandPacket
.TargetStatus
;
1069 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1070 *DataLength
= CommandPacket
.InTransferLength
;
1077 Execute Write(16) SCSI command on a specific SCSI target.
1079 Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.
1080 If Timeout is zero, then this function waits indefinitely for the command to complete.
1081 If Timeout is greater than zero, then the command is executed and will timeout after
1082 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
1083 the CDB for this SCSI command.
1084 If ScsiIo is NULL, then ASSERT().
1085 If SenseDataLength is NULL, then ASSERT().
1086 If HostAdapterStatus is NULL, then ASSERT().
1087 If TargetStatus is NULL, then ASSERT().
1088 If DataLength is NULL, then ASSERT().
1090 @param[in] ScsiIo SCSI IO Protocol to use
1091 @param[in] Timeout The length of timeout period.
1092 @param[in, out] SenseData A pointer to output sense data.
1093 @param[in, out] SenseDataLength The length of output sense data.
1094 @param[out] HostAdapterStatus The status of Host Adapter.
1095 @param[out] TargetStatus The status of the target.
1096 @param[in, out] DataBuffer A pointer to a data buffer.
1097 @param[in, out] DataLength The length of data buffer.
1098 @param[in] StartLba The start address of LBA.
1099 @param[in] SectorSize The number of contiguous logical blocks of data that shall be transferred.
1101 @retval EFI_SUCCESS The command is executed successfully.
1102 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1103 not be transferred. The actual number of bytes transferred is returned in DataLength.
1104 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1105 SCSI Command Packets already queued.
1106 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1107 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1108 the SCSI initiator(i.e., SCSI Host Controller)
1109 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1114 ScsiWrite16Command (
1115 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1117 IN OUT VOID
*SenseData
, OPTIONAL
1118 IN OUT UINT8
*SenseDataLength
,
1119 OUT UINT8
*HostAdapterStatus
,
1120 OUT UINT8
*TargetStatus
,
1121 IN OUT VOID
*DataBuffer
, OPTIONAL
1122 IN OUT UINT32
*DataLength
,
1124 IN UINT32 SectorSize
1127 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1129 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
1131 ASSERT (SenseDataLength
!= NULL
);
1132 ASSERT (HostAdapterStatus
!= NULL
);
1133 ASSERT (TargetStatus
!= NULL
);
1134 ASSERT (DataLength
!= NULL
);
1135 ASSERT (ScsiIo
!= NULL
);
1137 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1138 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1140 CommandPacket
.Timeout
= Timeout
;
1141 CommandPacket
.OutDataBuffer
= DataBuffer
;
1142 CommandPacket
.SenseData
= SenseData
;
1143 CommandPacket
.OutTransferLength
= *DataLength
;
1144 CommandPacket
.Cdb
= Cdb
;
1146 // Fill Cdb for Write (16) Command
1148 Cdb
[0] = EFI_SCSI_OP_WRITE16
;
1149 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1150 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1152 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1153 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
1154 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1156 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1158 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1159 *TargetStatus
= CommandPacket
.TargetStatus
;
1160 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1161 *DataLength
= CommandPacket
.OutTransferLength
;