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 // Max bytes needed to represent ID of a SCSI device
28 #define EFI_SCSI_TARGET_MAX_BYTES (0x10)
31 // bit5..7 are for Logical unit number
34 #define EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK 0xe0
37 // Scsi Command Length
39 #define EFI_SCSI_OP_LENGTH_SIX 0x6
40 #define EFI_SCSI_OP_LENGTH_TEN 0xa
41 #define EFI_SCSI_OP_LENGTH_SIXTEEN 0x10
46 Execute Test Unit Ready SCSI command on a specific SCSI target.
48 Executes the Test Unit Ready command on the SCSI target specified by ScsiIo.
49 If Timeout is zero, then this function waits indefinitely for the command to complete.
50 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
51 If ScsiIo is NULL, then ASSERT().
52 If SenseDataLength is NULL, then ASSERT().
53 If HostAdapterStatus is NULL, then ASSERT().
54 If TargetStatus is NULL, then ASSERT().
57 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
58 for the specific SCSI target.
59 @param[in] Timeout The timeout in 100 ns units to use for the execution
60 of this SCSI Request Packet. A Timeout value of
61 zero means that this function will wait indefinitely
62 for the SCSI Request Packet to execute. If Timeout
63 is greater than zero, then this function will return
64 EFI_TIMEOUT if the time required to execute the SCSI
65 Request Packet is greater than Timeout.
66 @param[in, out] SenseData A pointer to sense data that was generated by
67 the execution of the SCSI Request Packet. This
68 buffer must be allocated by the caller.
69 If SenseDataLength is 0, then this parameter is
70 optional and may be NULL.
71 @param[in, out] SenseDataLength On input, a pointer to the length in bytes of
72 the SenseData buffer. On output, a pointer to
73 the number of bytes written to the SenseData buffer.
74 @param[out] HostAdapterStatus The status of the SCSI Host Controller that produces
75 the SCSI bus containing the SCSI target specified by
76 ScsiIo when the SCSI Request Packet was executed.
77 See the EFI SCSI I/O Protocol in the UEFI Specification
78 for details on the possible return values.
79 @param[out] TargetStatus The status returned by the SCSI target specified
80 by ScsiIo when the SCSI Request Packet was executed
81 on the SCSI Host Controller. See the EFI SCSI I/O
82 Protocol in the UEFI Specification for details on
83 the possible return values.
85 @retval EFI_SUCCESS The command was executed successfully.
86 See HostAdapterStatus, TargetStatus, SenseDataLength,
87 and SenseData in that order for additional status
89 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
90 there are too many SCSI Command Packets already
91 queued. The SCSI Request Packet was not sent, so
92 no additional status information is available.
93 The caller may retry again later.
94 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
95 SCSI Request Packet. See HostAdapterStatus,
96 TargetStatus, SenseDataLength, and SenseData in that
97 order for additional status information.
98 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
99 is not supported by the SCSI initiator(i.e., SCSI
100 Host Controller). The SCSI Request Packet was not
101 sent, so no additional status information is available.
102 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
103 Packet to execute. See HostAdapterStatus, TargetStatus,
104 SenseDataLength, and SenseData in that order for
105 additional status information.
110 ScsiTestUnitReadyCommand (
111 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
113 IN OUT VOID
*SenseData
, OPTIONAL
114 IN OUT UINT8
*SenseDataLength
,
115 OUT UINT8
*HostAdapterStatus
,
116 OUT UINT8
*TargetStatus
119 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
122 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
124 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
126 ASSERT (SenseDataLength
!= NULL
);
127 ASSERT (HostAdapterStatus
!= NULL
);
128 ASSERT (TargetStatus
!= NULL
);
129 ASSERT (ScsiIo
!= NULL
);
131 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
132 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
134 CommandPacket
.Timeout
= Timeout
;
135 CommandPacket
.InDataBuffer
= NULL
;
136 CommandPacket
.InTransferLength
= 0;
137 CommandPacket
.OutDataBuffer
= NULL
;
138 CommandPacket
.OutTransferLength
= 0;
139 CommandPacket
.SenseData
= SenseData
;
140 CommandPacket
.Cdb
= Cdb
;
142 // Fill Cdb for Test Unit Ready Command
144 Target
= &TargetArray
[0];
145 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
147 Cdb
[0] = EFI_SCSI_OP_TEST_UNIT_READY
;
148 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
149 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
150 CommandPacket
.SenseDataLength
= *SenseDataLength
;
152 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
154 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
155 *TargetStatus
= CommandPacket
.TargetStatus
;
156 *SenseDataLength
= CommandPacket
.SenseDataLength
;
163 Execute Inquiry SCSI command on a specific SCSI target.
165 Executes the Inquiry command on the SCSI target specified by ScsiIo.
166 If Timeout is zero, then this function waits indefinitely for the command to complete.
167 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
168 If ScsiIo is NULL, then ASSERT().
169 If SenseDataLength is NULL, then ASSERT().
170 If HostAdapterStatus is NULL, then ASSERT().
171 If TargetStatus is NULL, then ASSERT().
172 If InquiryDataLength is NULL, then ASSERT().
174 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
175 for the specific SCSI target.
176 @param[in] Timeout The timeout in 100 ns units to use for the
177 execution of this SCSI Request Packet. A Timeout
178 value of zero means that this function will wait
179 indefinitely for the SCSI Request Packet to execute.
180 If Timeout is greater than zero, then this function
181 will return EFI_TIMEOUT if the time required to
182 execute the SCSI Request Packet is greater than Timeout.
183 @param[in, out] SenseData A pointer to sense data that was generated
184 by the execution of the SCSI Request Packet.
185 This buffer must be allocated by the caller.
186 If SenseDataLength is 0, then this parameter
187 is optional and may be NULL.
188 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
189 On output, the number of bytes written to the SenseData buffer.
190 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
191 produces the SCSI bus containing the SCSI
192 target specified by ScsiIo when the SCSI
193 Request Packet was executed. See the EFI
194 SCSI I/O Protocol in the UEFI Specification
195 for details on the possible return values.
196 @param[out] TargetStatus The status returned by the SCSI target specified
197 by ScsiIo when the SCSI Request Packet was
198 executed on the SCSI Host Controller.
199 See the EFI SCSI I/O Protocol in the UEFI
200 Specification for details on the possible
202 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated
203 by the execution of the SCSI Request Packet.
204 This buffer must be allocated by the caller.
205 If InquiryDataLength is 0, then this parameter
206 is optional and may be NULL.
207 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes
208 of the InquiryDataBuffer buffer.
209 On output, a pointer to the number of bytes
210 written to the InquiryDataBuffer buffer.
211 @param[in] EnableVitalProductData If TRUE, then the supported vital product
212 data for the PageCode is returned in InquiryDataBuffer.
213 If FALSE, then the standard inquiry data is
214 returned in InquiryDataBuffer and PageCode is ignored.
215 @param[in] PageCode The page code of the vital product data.
216 It's ignored if EnableVitalProductData is FALSE.
218 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,
219 TargetStatus, SenseDataLength, and SenseData in that order
220 for additional status information.
221 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
222 InquiryDataBuffer could not be transferred. The actual
223 number of bytes transferred is returned in InquiryDataLength.
224 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there
225 are too many SCSI Command Packets already queued.
226 The SCSI Request Packet was not sent, so no additional
227 status information is available. The caller may retry again later.
228 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI
229 Request Packet. See HostAdapterStatus, TargetStatus,
230 SenseDataLength, and SenseData in that order for additional
232 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not
233 supported by the SCSI initiator(i.e., SCSI Host Controller).
234 The SCSI Request Packet was not sent, so no additional
235 status information is available.
236 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
237 Packet to execute. See HostAdapterStatus, TargetStatus,
238 SenseDataLength, and SenseData in that order for
239 additional status information.
244 ScsiInquiryCommandEx (
245 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
247 IN OUT VOID
*SenseData
, OPTIONAL
248 IN OUT UINT8
*SenseDataLength
,
249 OUT UINT8
*HostAdapterStatus
,
250 OUT UINT8
*TargetStatus
,
251 IN OUT VOID
*InquiryDataBuffer
, OPTIONAL
252 IN OUT UINT32
*InquiryDataLength
,
253 IN BOOLEAN EnableVitalProductData
,
257 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
260 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
262 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
264 ASSERT (SenseDataLength
!= NULL
);
265 ASSERT (HostAdapterStatus
!= NULL
);
266 ASSERT (TargetStatus
!= NULL
);
267 ASSERT (InquiryDataLength
!= NULL
);
268 ASSERT (ScsiIo
!= NULL
);
270 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
271 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
273 CommandPacket
.Timeout
= Timeout
;
274 CommandPacket
.InDataBuffer
= InquiryDataBuffer
;
275 CommandPacket
.InTransferLength
= *InquiryDataLength
;
276 CommandPacket
.SenseData
= SenseData
;
277 CommandPacket
.SenseDataLength
= *SenseDataLength
;
278 CommandPacket
.Cdb
= Cdb
;
280 Target
= &TargetArray
[0];
281 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
283 Cdb
[0] = EFI_SCSI_OP_INQUIRY
;
284 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
285 if (EnableVitalProductData
) {
290 if (*InquiryDataLength
> 0xff) {
291 *InquiryDataLength
= 0xff;
294 Cdb
[4] = (UINT8
) (*InquiryDataLength
);
295 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
296 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
298 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
300 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
301 *TargetStatus
= CommandPacket
.TargetStatus
;
302 *SenseDataLength
= CommandPacket
.SenseDataLength
;
303 *InquiryDataLength
= CommandPacket
.InTransferLength
;
310 Execute Inquiry SCSI command on a specific SCSI target.
312 Executes the Inquiry command on the SCSI target specified by ScsiIo.
313 If Timeout is zero, then this function waits indefinitely for the command to complete.
314 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
315 If ScsiIo is NULL, then ASSERT().
316 If SenseDataLength is NULL, then ASSERT().
317 If HostAdapterStatus is NULL, then ASSERT().
318 If TargetStatus is NULL, then ASSERT().
319 If InquiryDataLength is NULL, then ASSERT().
321 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
322 for the specific SCSI target.
323 @param[in] Timeout The timeout in 100 ns units to use for the
324 execution of this SCSI Request Packet. A Timeout
325 value of zero means that this function will wait
326 indefinitely for the SCSI Request Packet to execute.
327 If Timeout is greater than zero, then this function
328 will return EFI_TIMEOUT if the time required to
329 execute the SCSI Request Packet is greater than Timeout.
330 @param[in, out] SenseData A pointer to sense data that was generated
331 by the execution of the SCSI Request Packet.
332 This buffer must be allocated by the caller.
333 If SenseDataLength is 0, then this parameter
334 is optional and may be NULL.
335 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
336 On output, the number of bytes written to the SenseData buffer.
337 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
338 produces the SCSI bus containing the SCSI
339 target specified by ScsiIo when the SCSI
340 Request Packet was executed. See the EFI
341 SCSI I/O Protocol in the UEFI Specification
342 for details on the possible return values.
343 @param[out] TargetStatus The status returned by the SCSI target specified
344 by ScsiIo when the SCSI Request Packet was
345 executed on the SCSI Host Controller.
346 See the EFI SCSI I/O Protocol in the UEFI
347 Specification for details on the possible
349 @param[in, out] InquiryDataBuffer A pointer to inquiry data that was generated
350 by the execution of the SCSI Request Packet.
351 This buffer must be allocated by the caller.
352 If InquiryDataLength is 0, then this parameter
353 is optional and may be NULL.
354 @param[in, out] InquiryDataLength On input, a pointer to the length in bytes
355 of the InquiryDataBuffer buffer.
356 On output, a pointer to the number of bytes
357 written to the InquiryDataBuffer buffer.
358 @param[in] EnableVitalProductData If TRUE, then the supported vital product
359 data is returned in InquiryDataBuffer.
360 If FALSE, then the standard inquiry data is
361 returned in InquiryDataBuffer.
363 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,
364 TargetStatus, SenseDataLength, and SenseData in that order
365 for additional status information.
366 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
367 InquiryDataBuffer could not be transferred. The actual
368 number of bytes transferred is returned in InquiryDataLength.
369 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there
370 are too many SCSI Command Packets already queued.
371 The SCSI Request Packet was not sent, so no additional
372 status information is available. The caller may retry again later.
373 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI
374 Request Packet. See HostAdapterStatus, TargetStatus,
375 SenseDataLength, and SenseData in that order for additional
377 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not
378 supported by the SCSI initiator(i.e., SCSI Host Controller).
379 The SCSI Request Packet was not sent, so no additional
380 status information is available.
381 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
382 Packet to execute. See HostAdapterStatus, TargetStatus,
383 SenseDataLength, and SenseData in that order for
384 additional status information.
390 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
392 IN OUT VOID
*SenseData
, OPTIONAL
393 IN OUT UINT8
*SenseDataLength
,
394 OUT UINT8
*HostAdapterStatus
,
395 OUT UINT8
*TargetStatus
,
396 IN OUT VOID
*InquiryDataBuffer
, OPTIONAL
397 IN OUT UINT32
*InquiryDataLength
,
398 IN BOOLEAN EnableVitalProductData
401 return ScsiInquiryCommandEx (
410 EnableVitalProductData
,
416 Execute Mode Sense(10) SCSI command on a specific SCSI target.
418 Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.
419 If Timeout is zero, then this function waits indefinitely for the command to complete.
420 If Timeout is greater than zero, then the command is executed and will timeout
421 after Timeout 100 ns units. The DBDField, PageControl, and PageCode parameters
422 are used to construct the CDB for this SCSI command.
423 If ScsiIo is NULL, then ASSERT().
424 If SenseDataLength is NULL, then ASSERT().
425 If HostAdapterStatus is NULL, then ASSERT().
426 If TargetStatus is NULL, then ASSERT().
427 If DataLength is NULL, then ASSERT().
430 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
431 for the specific SCSI target.
432 @param[in] Timeout The timeout in 100 ns units to use for the
433 execution of this SCSI Request Packet. A Timeout
434 value of zero means that this function will wait
435 indefinitely for the SCSI Request Packet to execute.
436 If Timeout is greater than zero, then this function
437 will return EFI_TIMEOUT if the time required to
438 execute the SCSI Request Packet is greater than Timeout.
439 @param[in, out] SenseData A pointer to sense data that was generated
440 by the execution of the SCSI Request Packet.
441 This buffer must be allocated by the caller.
442 If SenseDataLength is 0, then this parameter
443 is optional and may be NULL.
444 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
445 On output, the number of bytes written to the SenseData buffer.
446 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
447 produces the SCSI bus containing the SCSI target
448 specified by ScsiIo when the SCSI Request Packet
449 was executed. See the EFI SCSI I/O Protocol in the
450 UEFI Specification for details on the possible
452 @param[out] TargetStatus The status returned by the SCSI target specified
453 by ScsiIo when the SCSI Request Packet was executed
454 on the SCSI Host Controller. See the EFI SCSI
455 I/O Protocol in the UEFI Specification for details
456 on the possible return values.
457 @param[in, out] DataBuffer A pointer to data that was generated by the
458 execution of the SCSI Request Packet. This
459 buffer must be allocated by the caller. If
460 DataLength is 0, then this parameter is optional
462 @param[in, out] DataLength On input, a pointer to the length in bytes of
463 the DataBuffer buffer. On output, a pointer
464 to the number of bytes written to the DataBuffer
466 @param[in] DBDField Specifies the DBD field of the CDB for this SCSI Command.
467 @param[in] PageControl Specifies the PC field of the CDB for this SCSI Command.
468 @param[in] PageCode Specifies the Page Control field of the CDB for this SCSI Command.
470 @retval EFI_SUCCESS The command executed successfully.
471 See HostAdapterStatus, TargetStatus, SenseDataLength,
472 and SenseData in that order for additional status information.
473 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the
474 entire DataBuffer could not be transferred.
475 The actual number of bytes transferred is returned
477 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
478 there are too many SCSI Command Packets already queued.
479 The SCSI Request Packet was not sent, so no additional
480 status information is available. The caller may retry
482 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
483 SCSI Request Packet. See HostAdapterStatus, TargetStatus,
484 SenseDataLength, and SenseData in that order for
485 additional status information.
486 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
487 is not supported by the SCSI initiator(i.e., SCSI
488 Host Controller). The SCSI Request Packet was not
489 sent, so no additional status information is available.
490 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
491 Request Packet to execute. See HostAdapterStatus,
492 TargetStatus, SenseDataLength, and SenseData in that
493 order for additional status information.
498 ScsiModeSense10Command (
499 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
501 IN OUT VOID
*SenseData
, OPTIONAL
502 IN OUT UINT8
*SenseDataLength
,
503 OUT UINT8
*HostAdapterStatus
,
504 OUT UINT8
*TargetStatus
,
505 IN OUT VOID
*DataBuffer
, OPTIONAL
506 IN OUT UINT32
*DataLength
,
507 IN UINT8 DBDField
, OPTIONAL
508 IN UINT8 PageControl
,
512 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
515 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
517 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
519 ASSERT (SenseDataLength
!= NULL
);
520 ASSERT (HostAdapterStatus
!= NULL
);
521 ASSERT (TargetStatus
!= NULL
);
522 ASSERT (DataLength
!= NULL
);
523 ASSERT (ScsiIo
!= NULL
);
525 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
526 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
528 CommandPacket
.Timeout
= Timeout
;
529 CommandPacket
.InDataBuffer
= DataBuffer
;
530 CommandPacket
.SenseData
= SenseData
;
531 CommandPacket
.InTransferLength
= *DataLength
;
532 CommandPacket
.Cdb
= Cdb
;
534 // Fill Cdb for Mode Sense (10) Command
536 Target
= &TargetArray
[0];
537 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
539 Cdb
[0] = EFI_SCSI_OP_MODE_SEN10
;
541 // DBDField is in Cdb[1] bit3 of (bit7..0)
543 Cdb
[1] = (UINT8
) ((LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
) + ((DBDField
<< 3) & 0x08));
545 // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0
547 Cdb
[2] = (UINT8
) (((PageControl
<< 6) & 0xc0) | (PageCode
& 0x3f));
548 Cdb
[7] = (UINT8
) (*DataLength
>> 8);
549 Cdb
[8] = (UINT8
) (*DataLength
);
551 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
552 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
553 CommandPacket
.SenseDataLength
= *SenseDataLength
;
555 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
557 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
558 *TargetStatus
= CommandPacket
.TargetStatus
;
559 *SenseDataLength
= CommandPacket
.SenseDataLength
;
560 *DataLength
= CommandPacket
.InTransferLength
;
567 Execute Request Sense SCSI command on a specific SCSI target.
569 Executes the Request Sense command on the SCSI target specified by ScsiIo.
570 If Timeout is zero, then this function waits indefinitely for the command to complete.
571 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
572 If ScsiIo is NULL, then ASSERT().
573 If SenseDataLength is NULL, then ASSERT().
574 If HostAdapterStatus is NULL, then ASSERT().
575 If TargetStatus is NULL, then ASSERT().
577 @param[in] ScsiIo A pointer to SCSI IO protocol.
578 @param[in] Timeout The length of timeout period.
579 @param[in, out] SenseData A pointer to output sense data.
580 @param[in, out] SenseDataLength The length of output sense data.
581 @param[out] HostAdapterStatus The status of Host Adapter.
582 @param[out] TargetStatus The status of the target.
584 @retval EFI_SUCCESS The command executed successfully.
585 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are
586 too many SCSI Command Packets already queued.
587 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
588 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
589 the SCSI initiator(i.e., SCSI Host Controller)
590 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
595 ScsiRequestSenseCommand (
596 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
598 IN OUT VOID
*SenseData
, OPTIONAL
599 IN OUT UINT8
*SenseDataLength
,
600 OUT UINT8
*HostAdapterStatus
,
601 OUT UINT8
*TargetStatus
604 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
607 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
609 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
611 ASSERT (SenseDataLength
!= NULL
);
612 ASSERT (HostAdapterStatus
!= NULL
);
613 ASSERT (TargetStatus
!= NULL
);
614 ASSERT (ScsiIo
!= NULL
);
616 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
617 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
619 CommandPacket
.Timeout
= Timeout
;
620 CommandPacket
.InDataBuffer
= SenseData
;
621 CommandPacket
.SenseData
= NULL
;
622 CommandPacket
.InTransferLength
= *SenseDataLength
;
623 CommandPacket
.Cdb
= Cdb
;
625 // Fill Cdb for Request Sense Command
627 Target
= &TargetArray
[0];
628 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
630 Cdb
[0] = EFI_SCSI_OP_REQUEST_SENSE
;
631 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
632 Cdb
[4] = (UINT8
) (*SenseDataLength
);
634 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
635 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
636 CommandPacket
.SenseDataLength
= 0;
638 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
640 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
641 *TargetStatus
= CommandPacket
.TargetStatus
;
642 *SenseDataLength
= (UINT8
) CommandPacket
.InTransferLength
;
649 Execute Read Capacity SCSI command on a specific SCSI target.
651 Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.
652 If Timeout is zero, then this function waits indefinitely for the command to complete.
653 If Timeout is greater than zero, then the command is executed and will timeout after
654 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
655 If ScsiIo is NULL, then ASSERT().
656 If SenseDataLength is NULL, then ASSERT().
657 If HostAdapterStatus is NULL, then ASSERT().
658 If TargetStatus is NULL, then ASSERT().
659 If DataLength is NULL, then ASSERT().
661 @param[in] ScsiIo A pointer to SCSI IO protocol.
662 @param[in] Timeout The length of timeout period.
663 @param[in, out] SenseData A pointer to output sense data.
664 @param[in, out] SenseDataLength The length of output sense data.
665 @param[out] HostAdapterStatus The status of Host Adapter.
666 @param[out] TargetStatus The status of the target.
667 @param[in, out] DataBuffer A pointer to a data buffer.
668 @param[in, out] DataLength The length of data buffer.
669 @param[in] Pmi A partial medium indicator.
671 @retval EFI_SUCCESS The command executed successfully.
672 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
673 DataBuffer could not be transferred. The actual
674 number of bytes transferred is returned in DataLength.
675 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
676 there are too many SCSI Command Packets already queued.
677 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
678 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
679 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
680 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
685 ScsiReadCapacityCommand (
686 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
688 IN OUT VOID
*SenseData
, OPTIONAL
689 IN OUT UINT8
*SenseDataLength
,
690 OUT UINT8
*HostAdapterStatus
,
691 OUT UINT8
*TargetStatus
,
692 IN OUT VOID
*DataBuffer
, OPTIONAL
693 IN OUT UINT32
*DataLength
,
697 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
700 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
702 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
704 ASSERT (SenseDataLength
!= NULL
);
705 ASSERT (HostAdapterStatus
!= NULL
);
706 ASSERT (TargetStatus
!= NULL
);
707 ASSERT (DataLength
!= NULL
);
708 ASSERT (ScsiIo
!= NULL
);
710 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
711 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
713 CommandPacket
.Timeout
= Timeout
;
714 CommandPacket
.InDataBuffer
= DataBuffer
;
715 CommandPacket
.SenseData
= SenseData
;
716 CommandPacket
.InTransferLength
= *DataLength
;
717 CommandPacket
.Cdb
= Cdb
;
719 // Fill Cdb for Read Capacity Command
721 Target
= &TargetArray
[0];
722 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
724 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY
;
725 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
728 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.
730 ZeroMem ((Cdb
+ 2), 4);
735 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
736 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
737 CommandPacket
.SenseDataLength
= *SenseDataLength
;
739 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
741 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
742 *TargetStatus
= CommandPacket
.TargetStatus
;
743 *SenseDataLength
= CommandPacket
.SenseDataLength
;
744 *DataLength
= CommandPacket
.InTransferLength
;
751 Execute Read Capacity SCSI 16 command on a specific SCSI target.
753 Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.
754 If Timeout is zero, then this function waits indefinitely for the command to complete.
755 If Timeout is greater than zero, then the command is executed and will timeout after
756 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
757 If ScsiIo is NULL, then ASSERT().
758 If SenseDataLength is NULL, then ASSERT().
759 If HostAdapterStatus is NULL, then ASSERT().
760 If TargetStatus is NULL, then ASSERT().
761 If DataLength is NULL, then ASSERT().
763 @param[in] ScsiIo A pointer to SCSI IO protocol.
764 @param[in] Timeout The length of timeout period.
765 @param[in, out] SenseData A pointer to output sense data.
766 @param[in, out] SenseDataLength The length of output sense data.
767 @param[out] HostAdapterStatus The status of Host Adapter.
768 @param[out] TargetStatus The status of the target.
769 @param[in, out] DataBuffer A pointer to a data buffer.
770 @param[in, out] DataLength The length of data buffer.
771 @param[in] Pmi Partial medium indicator.
773 @retval EFI_SUCCESS The command executed successfully.
774 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
775 DataBuffer could not be transferred. The actual
776 number of bytes transferred is returned in DataLength.
777 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
778 there are too many SCSI Command Packets already queued.
779 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
780 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
781 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
782 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
787 ScsiReadCapacity16Command (
788 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
790 IN OUT VOID
*SenseData
, OPTIONAL
791 IN OUT UINT8
*SenseDataLength
,
792 OUT UINT8
*HostAdapterStatus
,
793 OUT UINT8
*TargetStatus
,
794 IN OUT VOID
*DataBuffer
, OPTIONAL
795 IN OUT UINT32
*DataLength
,
799 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
802 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
806 ASSERT (SenseDataLength
!= NULL
);
807 ASSERT (HostAdapterStatus
!= NULL
);
808 ASSERT (TargetStatus
!= NULL
);
809 ASSERT (DataLength
!= NULL
);
810 ASSERT (ScsiIo
!= NULL
);
812 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
815 CommandPacket
.Timeout
= Timeout
;
816 CommandPacket
.InDataBuffer
= DataBuffer
;
817 CommandPacket
.SenseData
= SenseData
;
818 CommandPacket
.InTransferLength
= *DataLength
;
819 CommandPacket
.Cdb
= Cdb
;
821 // Fill Cdb for Read Capacity Command
823 Target
= &TargetArray
[0];
824 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
826 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY16
;
830 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.
832 ZeroMem ((Cdb
+ 2), 8);
838 CommandPacket
.CdbLength
= 16;
839 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
840 CommandPacket
.SenseDataLength
= *SenseDataLength
;
842 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
844 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
845 *TargetStatus
= CommandPacket
.TargetStatus
;
846 *SenseDataLength
= CommandPacket
.SenseDataLength
;
847 *DataLength
= CommandPacket
.InTransferLength
;
854 Execute Read(10) SCSI command on a specific SCSI target.
856 Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.
857 If Timeout is zero, then this function waits indefinitely for the command to complete.
858 If Timeout is greater than zero, then the command is executed and will timeout
859 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
860 construct the CDB for this SCSI command.
861 If ScsiIo is NULL, then ASSERT().
862 If SenseDataLength is NULL, then ASSERT().
863 If HostAdapterStatus is NULL, then ASSERT().
864 If TargetStatus is NULL, then ASSERT().
865 If DataLength is NULL, then ASSERT().
868 @param[in] ScsiIo A pointer to SCSI IO protocol.
869 @param[in] Timeout The length of timeout period.
870 @param[in, out] SenseData A pointer to output sense data.
871 @param[in, out] SenseDataLength The length of output sense data.
872 @param[out] HostAdapterStatus The status of Host Adapter.
873 @param[out] TargetStatus The status of the target.
874 @param[in, out] DataBuffer Read 10 command data.
875 @param[in, out] DataLength The length of data buffer.
876 @param[in] StartLba The start address of LBA.
877 @param[in] SectorSize The sector size.
879 @retval EFI_SUCCESS The command is executed successfully.
880 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
881 not be transferred. The actual number of bytes transferred is returned in DataLength.
882 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
883 SCSI Command Packets already queued.
884 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
885 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
886 the SCSI initiator(i.e., SCSI Host Controller)
887 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
893 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
895 IN OUT VOID
*SenseData
, OPTIONAL
896 IN OUT UINT8
*SenseDataLength
,
897 OUT UINT8
*HostAdapterStatus
,
898 OUT UINT8
*TargetStatus
,
899 IN OUT VOID
*DataBuffer
, OPTIONAL
900 IN OUT UINT32
*DataLength
,
905 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
908 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
910 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
912 ASSERT (SenseDataLength
!= NULL
);
913 ASSERT (HostAdapterStatus
!= NULL
);
914 ASSERT (TargetStatus
!= NULL
);
915 ASSERT (DataLength
!= NULL
);
916 ASSERT (ScsiIo
!= NULL
);
918 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
919 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
921 CommandPacket
.Timeout
= Timeout
;
922 CommandPacket
.InDataBuffer
= DataBuffer
;
923 CommandPacket
.SenseData
= SenseData
;
924 CommandPacket
.InTransferLength
= *DataLength
;
925 CommandPacket
.Cdb
= Cdb
;
927 // Fill Cdb for Read (10) Command
929 Target
= &TargetArray
[0];
930 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
932 Cdb
[0] = EFI_SCSI_OP_READ10
;
933 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
934 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
935 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
) SectorSize
));
937 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
938 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
939 CommandPacket
.SenseDataLength
= *SenseDataLength
;
941 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
943 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
944 *TargetStatus
= CommandPacket
.TargetStatus
;
945 *SenseDataLength
= CommandPacket
.SenseDataLength
;
946 *DataLength
= CommandPacket
.InTransferLength
;
953 Execute Write(10) SCSI command on a specific SCSI target.
955 Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.
956 If Timeout is zero, then this function waits indefinitely for the command to complete.
957 If Timeout is greater than zero, then the command is executed and will timeout after
958 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
959 the CDB for this SCSI command.
960 If ScsiIo is NULL, then ASSERT().
961 If SenseDataLength is NULL, then ASSERT().
962 If HostAdapterStatus is NULL, then ASSERT().
963 If TargetStatus is NULL, then ASSERT().
964 If DataLength is NULL, then ASSERT().
966 @param[in] ScsiIo SCSI IO Protocol to use
967 @param[in] Timeout The length of timeout period.
968 @param[in, out] SenseData A pointer to output sense data.
969 @param[in, out] SenseDataLength The length of output sense data.
970 @param[out] HostAdapterStatus The status of Host Adapter.
971 @param[out] TargetStatus The status of the target.
972 @param[in, out] DataBuffer A pointer to a data buffer.
973 @param[in, out] DataLength The length of data buffer.
974 @param[in] StartLba The start address of LBA.
975 @param[in] SectorSize The sector size.
977 @retval EFI_SUCCESS The command executed successfully.
978 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
979 not be transferred. The actual number of bytes transferred is returned in DataLength.
980 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
981 SCSI Command Packets already queued.
982 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
983 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
984 the SCSI initiator(i.e., SCSI Host Controller)
985 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
991 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
993 IN OUT VOID
*SenseData
, OPTIONAL
994 IN OUT UINT8
*SenseDataLength
,
995 OUT UINT8
*HostAdapterStatus
,
996 OUT UINT8
*TargetStatus
,
997 IN OUT VOID
*DataBuffer
, OPTIONAL
998 IN OUT UINT32
*DataLength
,
1000 IN UINT32 SectorSize
1003 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1006 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
1008 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
1010 ASSERT (SenseDataLength
!= NULL
);
1011 ASSERT (HostAdapterStatus
!= NULL
);
1012 ASSERT (TargetStatus
!= NULL
);
1013 ASSERT (DataLength
!= NULL
);
1014 ASSERT (ScsiIo
!= NULL
);
1016 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1017 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
1019 CommandPacket
.Timeout
= Timeout
;
1020 CommandPacket
.OutDataBuffer
= DataBuffer
;
1021 CommandPacket
.SenseData
= SenseData
;
1022 CommandPacket
.OutTransferLength
= *DataLength
;
1023 CommandPacket
.Cdb
= Cdb
;
1025 // Fill Cdb for Write (10) Command
1027 Target
= &TargetArray
[0];
1028 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
1030 Cdb
[0] = EFI_SCSI_OP_WRITE10
;
1031 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
1032 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
1033 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
) SectorSize
));
1035 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
1036 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
1037 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1039 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1041 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1042 *TargetStatus
= CommandPacket
.TargetStatus
;
1043 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1044 *DataLength
= CommandPacket
.OutTransferLength
;
1050 Execute Read(16) SCSI command on a specific SCSI target.
1052 Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.
1053 If Timeout is zero, then this function waits indefinitely for the command to complete.
1054 If Timeout is greater than zero, then the command is executed and will timeout
1055 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
1056 construct the CDB for this SCSI command.
1057 If ScsiIo is NULL, then ASSERT().
1058 If SenseDataLength is NULL, then ASSERT().
1059 If HostAdapterStatus is NULL, then ASSERT().
1060 If TargetStatus is NULL, then ASSERT().
1061 If DataLength is NULL, then ASSERT().
1064 @param[in] ScsiIo A pointer to SCSI IO protocol.
1065 @param[in] Timeout The length of timeout period.
1066 @param[in, out] SenseData A pointer to output sense data.
1067 @param[in, out] SenseDataLength The length of output sense data.
1068 @param[out] HostAdapterStatus The status of Host Adapter.
1069 @param[out] TargetStatus The status of the target.
1070 @param[in, out] DataBuffer Read 16 command data.
1071 @param[in, out] DataLength The length of data buffer.
1072 @param[in] StartLba The start address of LBA.
1073 @param[in] SectorSize The sector size.
1075 @retval EFI_SUCCESS The command executed successfully.
1076 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1077 not be transferred. The actual number of bytes transferred is returned in DataLength.
1078 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1079 SCSI Command Packets already queued.
1080 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1081 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1082 the SCSI initiator(i.e., SCSI Host Controller)
1083 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1089 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1091 IN OUT VOID
*SenseData
, OPTIONAL
1092 IN OUT UINT8
*SenseDataLength
,
1093 OUT UINT8
*HostAdapterStatus
,
1094 OUT UINT8
*TargetStatus
,
1095 IN OUT VOID
*DataBuffer
, OPTIONAL
1096 IN OUT UINT32
*DataLength
,
1098 IN UINT32 SectorSize
1101 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1104 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
1106 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
1108 ASSERT (SenseDataLength
!= NULL
);
1109 ASSERT (HostAdapterStatus
!= NULL
);
1110 ASSERT (TargetStatus
!= NULL
);
1111 ASSERT (DataLength
!= NULL
);
1112 ASSERT (ScsiIo
!= NULL
);
1114 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1115 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1117 CommandPacket
.Timeout
= Timeout
;
1118 CommandPacket
.InDataBuffer
= DataBuffer
;
1119 CommandPacket
.SenseData
= SenseData
;
1120 CommandPacket
.InTransferLength
= *DataLength
;
1121 CommandPacket
.Cdb
= Cdb
;
1123 // Fill Cdb for Read (16) Command
1125 Target
= &TargetArray
[0];
1126 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
1128 Cdb
[0] = EFI_SCSI_OP_READ16
;
1129 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
1130 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1131 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1133 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1134 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
1135 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1137 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1139 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1140 *TargetStatus
= CommandPacket
.TargetStatus
;
1141 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1142 *DataLength
= CommandPacket
.InTransferLength
;
1149 Execute Write(16) SCSI command on a specific SCSI target.
1151 Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.
1152 If Timeout is zero, then this function waits indefinitely for the command to complete.
1153 If Timeout is greater than zero, then the command is executed and will timeout after
1154 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
1155 the CDB for this SCSI command.
1156 If ScsiIo is NULL, then ASSERT().
1157 If SenseDataLength is NULL, then ASSERT().
1158 If HostAdapterStatus is NULL, then ASSERT().
1159 If TargetStatus is NULL, then ASSERT().
1160 If DataLength is NULL, then ASSERT().
1162 @param[in] ScsiIo SCSI IO Protocol to use
1163 @param[in] Timeout The length of timeout period.
1164 @param[in, out] SenseData A pointer to output sense data.
1165 @param[in, out] SenseDataLength The length of output sense data.
1166 @param[out] HostAdapterStatus The status of Host Adapter.
1167 @param[out] TargetStatus The status of the target.
1168 @param[in, out] DataBuffer A pointer to a data buffer.
1169 @param[in, out] DataLength The length of data buffer.
1170 @param[in] StartLba The start address of LBA.
1171 @param[in] SectorSize The sector size.
1173 @retval EFI_SUCCESS The command is executed successfully.
1174 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1175 not be transferred. The actual number of bytes transferred is returned in DataLength.
1176 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1177 SCSI Command Packets already queued.
1178 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1179 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1180 the SCSI initiator(i.e., SCSI Host Controller)
1181 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1186 ScsiWrite16Command (
1187 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1189 IN OUT VOID
*SenseData
, OPTIONAL
1190 IN OUT UINT8
*SenseDataLength
,
1191 OUT UINT8
*HostAdapterStatus
,
1192 OUT UINT8
*TargetStatus
,
1193 IN OUT VOID
*DataBuffer
, OPTIONAL
1194 IN OUT UINT32
*DataLength
,
1196 IN UINT32 SectorSize
1199 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1202 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
1204 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
1206 ASSERT (SenseDataLength
!= NULL
);
1207 ASSERT (HostAdapterStatus
!= NULL
);
1208 ASSERT (TargetStatus
!= NULL
);
1209 ASSERT (DataLength
!= NULL
);
1210 ASSERT (ScsiIo
!= NULL
);
1212 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1213 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1215 CommandPacket
.Timeout
= Timeout
;
1216 CommandPacket
.OutDataBuffer
= DataBuffer
;
1217 CommandPacket
.SenseData
= SenseData
;
1218 CommandPacket
.OutTransferLength
= *DataLength
;
1219 CommandPacket
.Cdb
= Cdb
;
1221 // Fill Cdb for Write (16) Command
1223 Target
= &TargetArray
[0];
1224 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
1226 Cdb
[0] = EFI_SCSI_OP_WRITE16
;
1227 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
1228 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1229 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1231 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1232 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
1233 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1235 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1237 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1238 *TargetStatus
= CommandPacket
.TargetStatus
;
1239 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1240 *DataLength
= CommandPacket
.OutTransferLength
;