2 UEFI SCSI Library implementation
4 Copyright (c) 2006 - 2010, 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 is returned in InquiryDataBuffer.
213 If FALSE, then the standard inquiry data is
214 returned in InquiryDataBuffer.
216 @retval EFI_SUCCESS The command executed successfully. See HostAdapterStatus,
217 TargetStatus, SenseDataLength, and SenseData in that order
218 for additional status information.
219 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
220 InquiryDataBuffer could not be transferred. The actual
221 number of bytes transferred is returned in InquiryDataLength.
222 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there
223 are too many SCSI Command Packets already queued.
224 The SCSI Request Packet was not sent, so no additional
225 status information is available. The caller may retry again later.
226 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI
227 Request Packet. See HostAdapterStatus, TargetStatus,
228 SenseDataLength, and SenseData in that order for additional
230 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not
231 supported by the SCSI initiator(i.e., SCSI Host Controller).
232 The SCSI Request Packet was not sent, so no additional
233 status information is available.
234 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request
235 Packet to execute. See HostAdapterStatus, TargetStatus,
236 SenseDataLength, and SenseData in that order for
237 additional status information.
243 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
245 IN OUT VOID
*SenseData
, OPTIONAL
246 IN OUT UINT8
*SenseDataLength
,
247 OUT UINT8
*HostAdapterStatus
,
248 OUT UINT8
*TargetStatus
,
249 IN OUT VOID
*InquiryDataBuffer
, OPTIONAL
250 IN OUT UINT32
*InquiryDataLength
,
251 IN BOOLEAN EnableVitalProductData
254 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
257 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
259 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
261 ASSERT (SenseDataLength
!= NULL
);
262 ASSERT (HostAdapterStatus
!= NULL
);
263 ASSERT (TargetStatus
!= NULL
);
264 ASSERT (InquiryDataLength
!= NULL
);
265 ASSERT (ScsiIo
!= NULL
);
267 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
268 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
270 CommandPacket
.Timeout
= Timeout
;
271 CommandPacket
.InDataBuffer
= InquiryDataBuffer
;
272 CommandPacket
.InTransferLength
= *InquiryDataLength
;
273 CommandPacket
.SenseData
= SenseData
;
274 CommandPacket
.SenseDataLength
= *SenseDataLength
;
275 CommandPacket
.Cdb
= Cdb
;
277 Target
= &TargetArray
[0];
278 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
280 Cdb
[0] = EFI_SCSI_OP_INQUIRY
;
281 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
282 if (EnableVitalProductData
) {
286 if (*InquiryDataLength
> 0xff) {
287 *InquiryDataLength
= 0xff;
290 Cdb
[4] = (UINT8
) (*InquiryDataLength
);
291 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
292 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
294 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
296 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
297 *TargetStatus
= CommandPacket
.TargetStatus
;
298 *SenseDataLength
= CommandPacket
.SenseDataLength
;
299 *InquiryDataLength
= CommandPacket
.InTransferLength
;
306 Execute Mode Sense(10) SCSI command on a specific SCSI target.
308 Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.
309 If Timeout is zero, then this function waits indefinitely for the command to complete.
310 If Timeout is greater than zero, then the command is executed and will timeout
311 after Timeout 100 ns units. The DBDField, PageControl, and PageCode parameters
312 are used to construct the CDB for this SCSI command.
313 If ScsiIo is NULL, then ASSERT().
314 If SenseDataLength is NULL, then ASSERT().
315 If HostAdapterStatus is NULL, then ASSERT().
316 If TargetStatus is NULL, then ASSERT().
317 If DataLength is NULL, then ASSERT().
320 @param[in] ScsiIo A pointer to the SCSI I/O Protocol instance
321 for the specific SCSI target.
322 @param[in] Timeout The timeout in 100 ns units to use for the
323 execution of this SCSI Request Packet. A Timeout
324 value of zero means that this function will wait
325 indefinitely for the SCSI Request Packet to execute.
326 If Timeout is greater than zero, then this function
327 will return EFI_TIMEOUT if the time required to
328 execute the SCSI Request Packet is greater than Timeout.
329 @param[in, out] SenseData A pointer to sense data that was generated
330 by the execution of the SCSI Request Packet.
331 This buffer must be allocated by the caller.
332 If SenseDataLength is 0, then this parameter
333 is optional and may be NULL.
334 @param[in, out] SenseDataLength On input, the length in bytes of the SenseData buffer.
335 On output, the number of bytes written to the SenseData buffer.
336 @param[out] HostAdapterStatus The status of the SCSI Host Controller that
337 produces the SCSI bus containing the SCSI target
338 specified by ScsiIo when the SCSI Request Packet
339 was executed. See the EFI SCSI I/O Protocol in the
340 UEFI Specification for details on the possible
342 @param[out] TargetStatus The status returned by the SCSI target specified
343 by ScsiIo when the SCSI Request Packet was executed
344 on the SCSI Host Controller. See the EFI SCSI
345 I/O Protocol in the UEFI Specification for details
346 on the possible return values.
347 @param[in, out] DataBuffer A pointer to data that was generated by the
348 execution of the SCSI Request Packet. This
349 buffer must be allocated by the caller. If
350 DataLength is 0, then this parameter is optional
352 @param[in, out] DataLength On input, a pointer to the length in bytes of
353 the DataBuffer buffer. On output, a pointer
354 to the number of bytes written to the DataBuffer
356 @param[in] DBDField Specifies the DBD field of the CDB for this SCSI Command.
357 @param[in] PageControl Specifies the PC field of the CDB for this SCSI Command.
358 @param[in] PageCode Specifies the Page Control field of the CDB for this SCSI Command.
360 @retval EFI_SUCCESS The command executed successfully.
361 See HostAdapterStatus, TargetStatus, SenseDataLength,
362 and SenseData in that order for additional status information.
363 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the
364 entire DataBuffer could not be transferred.
365 The actual number of bytes transferred is returned
367 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
368 there are too many SCSI Command Packets already queued.
369 The SCSI Request Packet was not sent, so no additional
370 status information is available. The caller may retry
372 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
373 SCSI Request Packet. See HostAdapterStatus, TargetStatus,
374 SenseDataLength, and SenseData in that order for
375 additional status information.
376 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
377 is not supported by the SCSI initiator(i.e., SCSI
378 Host Controller). The SCSI Request Packet was not
379 sent, so no additional status information is available.
380 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
381 Request Packet to execute. See HostAdapterStatus,
382 TargetStatus, SenseDataLength, and SenseData in that
383 order for additional status information.
388 ScsiModeSense10Command (
389 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
391 IN OUT VOID
*SenseData
, OPTIONAL
392 IN OUT UINT8
*SenseDataLength
,
393 OUT UINT8
*HostAdapterStatus
,
394 OUT UINT8
*TargetStatus
,
395 IN OUT VOID
*DataBuffer
, OPTIONAL
396 IN OUT UINT32
*DataLength
,
397 IN UINT8 DBDField
, OPTIONAL
398 IN UINT8 PageControl
,
402 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
405 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
407 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
409 ASSERT (SenseDataLength
!= NULL
);
410 ASSERT (HostAdapterStatus
!= NULL
);
411 ASSERT (TargetStatus
!= NULL
);
412 ASSERT (DataLength
!= NULL
);
413 ASSERT (ScsiIo
!= NULL
);
415 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
416 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
418 CommandPacket
.Timeout
= Timeout
;
419 CommandPacket
.InDataBuffer
= DataBuffer
;
420 CommandPacket
.SenseData
= SenseData
;
421 CommandPacket
.InTransferLength
= *DataLength
;
422 CommandPacket
.Cdb
= Cdb
;
424 // Fill Cdb for Mode Sense (10) Command
426 Target
= &TargetArray
[0];
427 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
429 Cdb
[0] = EFI_SCSI_OP_MODE_SEN10
;
431 // DBDField is in Cdb[1] bit3 of (bit7..0)
433 Cdb
[1] = (UINT8
) ((LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
) + ((DBDField
<< 3) & 0x08));
435 // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0
437 Cdb
[2] = (UINT8
) (((PageControl
<< 6) & 0xc0) | (PageCode
& 0x3f));
438 Cdb
[7] = (UINT8
) (*DataLength
>> 8);
439 Cdb
[8] = (UINT8
) (*DataLength
);
441 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
442 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
443 CommandPacket
.SenseDataLength
= *SenseDataLength
;
445 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
447 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
448 *TargetStatus
= CommandPacket
.TargetStatus
;
449 *SenseDataLength
= CommandPacket
.SenseDataLength
;
450 *DataLength
= CommandPacket
.InTransferLength
;
457 Execute Request Sense SCSI command on a specific SCSI target.
459 Executes the Request Sense command on the SCSI target specified by ScsiIo.
460 If Timeout is zero, then this function waits indefinitely for the command to complete.
461 If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.
462 If ScsiIo is NULL, then ASSERT().
463 If SenseDataLength is NULL, then ASSERT().
464 If HostAdapterStatus is NULL, then ASSERT().
465 If TargetStatus is NULL, then ASSERT().
467 @param[in] ScsiIo A pointer to SCSI IO protocol.
468 @param[in] Timeout The length of timeout period.
469 @param[in, out] SenseData A pointer to output sense data.
470 @param[in, out] SenseDataLength The length of output sense data.
471 @param[out] HostAdapterStatus The status of Host Adapter.
472 @param[out] TargetStatus The status of the target.
474 @retval EFI_SUCCESS The command executed successfully.
475 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are
476 too many SCSI Command Packets already queued.
477 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
478 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
479 the SCSI initiator(i.e., SCSI Host Controller)
480 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
485 ScsiRequestSenseCommand (
486 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
488 IN OUT VOID
*SenseData
, OPTIONAL
489 IN OUT UINT8
*SenseDataLength
,
490 OUT UINT8
*HostAdapterStatus
,
491 OUT UINT8
*TargetStatus
494 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
497 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
499 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
501 ASSERT (SenseDataLength
!= NULL
);
502 ASSERT (HostAdapterStatus
!= NULL
);
503 ASSERT (TargetStatus
!= NULL
);
504 ASSERT (ScsiIo
!= NULL
);
506 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
507 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
509 CommandPacket
.Timeout
= Timeout
;
510 CommandPacket
.InDataBuffer
= SenseData
;
511 CommandPacket
.SenseData
= NULL
;
512 CommandPacket
.InTransferLength
= *SenseDataLength
;
513 CommandPacket
.Cdb
= Cdb
;
515 // Fill Cdb for Request Sense Command
517 Target
= &TargetArray
[0];
518 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
520 Cdb
[0] = EFI_SCSI_OP_REQUEST_SENSE
;
521 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
522 Cdb
[4] = (UINT8
) (*SenseDataLength
);
524 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
525 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
526 CommandPacket
.SenseDataLength
= 0;
528 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
530 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
531 *TargetStatus
= CommandPacket
.TargetStatus
;
532 *SenseDataLength
= (UINT8
) CommandPacket
.InTransferLength
;
539 Execute Read Capacity SCSI command on a specific SCSI target.
541 Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.
542 If Timeout is zero, then this function waits indefinitely for the command to complete.
543 If Timeout is greater than zero, then the command is executed and will timeout after
544 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
545 If ScsiIo is NULL, then ASSERT().
546 If SenseDataLength is NULL, then ASSERT().
547 If HostAdapterStatus is NULL, then ASSERT().
548 If TargetStatus is NULL, then ASSERT().
549 If DataLength is NULL, then ASSERT().
551 @param[in] ScsiIo A pointer to SCSI IO protocol.
552 @param[in] Timeout The length of timeout period.
553 @param[in, out] SenseData A pointer to output sense data.
554 @param[in, out] SenseDataLength The length of output sense data.
555 @param[out] HostAdapterStatus The status of Host Adapter.
556 @param[out] TargetStatus The status of the target.
557 @param[in, out] DataBuffer A pointer to a data buffer.
558 @param[in, out] DataLength The length of data buffer.
559 @param[in] Pmi A partial medium indicator.
561 @retval EFI_SUCCESS The command executed successfully.
562 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
563 DataBuffer could not be transferred. The actual
564 number of bytes transferred is returned in DataLength.
565 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
566 there are too many SCSI Command Packets already queued.
567 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
568 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
569 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
570 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
575 ScsiReadCapacityCommand (
576 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
578 IN OUT VOID
*SenseData
, OPTIONAL
579 IN OUT UINT8
*SenseDataLength
,
580 OUT UINT8
*HostAdapterStatus
,
581 OUT UINT8
*TargetStatus
,
582 IN OUT VOID
*DataBuffer
, OPTIONAL
583 IN OUT UINT32
*DataLength
,
587 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
590 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
592 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
594 ASSERT (SenseDataLength
!= NULL
);
595 ASSERT (HostAdapterStatus
!= NULL
);
596 ASSERT (TargetStatus
!= NULL
);
597 ASSERT (DataLength
!= NULL
);
598 ASSERT (ScsiIo
!= NULL
);
600 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
601 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
603 CommandPacket
.Timeout
= Timeout
;
604 CommandPacket
.InDataBuffer
= DataBuffer
;
605 CommandPacket
.SenseData
= SenseData
;
606 CommandPacket
.InTransferLength
= *DataLength
;
607 CommandPacket
.Cdb
= Cdb
;
609 // Fill Cdb for Read Capacity Command
611 Target
= &TargetArray
[0];
612 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
614 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY
;
615 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
618 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.
620 ZeroMem ((Cdb
+ 2), 4);
625 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
626 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
627 CommandPacket
.SenseDataLength
= *SenseDataLength
;
629 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
631 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
632 *TargetStatus
= CommandPacket
.TargetStatus
;
633 *SenseDataLength
= CommandPacket
.SenseDataLength
;
634 *DataLength
= CommandPacket
.InTransferLength
;
641 Execute Read Capacity SCSI 16 command on a specific SCSI target.
643 Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.
644 If Timeout is zero, then this function waits indefinitely for the command to complete.
645 If Timeout is greater than zero, then the command is executed and will timeout after
646 Timeout 100 ns units. The Pmi parameter is used to construct the CDB for this SCSI command.
647 If ScsiIo is NULL, then ASSERT().
648 If SenseDataLength is NULL, then ASSERT().
649 If HostAdapterStatus is NULL, then ASSERT().
650 If TargetStatus is NULL, then ASSERT().
651 If DataLength is NULL, then ASSERT().
653 @param[in] ScsiIo A pointer to SCSI IO protocol.
654 @param[in] Timeout The length of timeout period.
655 @param[in, out] SenseData A pointer to output sense data.
656 @param[in, out] SenseDataLength The length of output sense data.
657 @param[out] HostAdapterStatus The status of Host Adapter.
658 @param[out] TargetStatus The status of the target.
659 @param[in, out] DataBuffer A pointer to a data buffer.
660 @param[in, out] DataLength The length of data buffer.
661 @param[in] Pmi Partial medium indicator.
663 @retval EFI_SUCCESS The command executed successfully.
664 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire
665 DataBuffer could not be transferred. The actual
666 number of bytes transferred is returned in DataLength.
667 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
668 there are too many SCSI Command Packets already queued.
669 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
670 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
671 is not supported by the SCSI initiator(i.e., SCSI Host Controller)
672 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
677 ScsiReadCapacity16Command (
678 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
680 IN OUT VOID
*SenseData
, OPTIONAL
681 IN OUT UINT8
*SenseDataLength
,
682 OUT UINT8
*HostAdapterStatus
,
683 OUT UINT8
*TargetStatus
,
684 IN OUT VOID
*DataBuffer
, OPTIONAL
685 IN OUT UINT32
*DataLength
,
689 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
692 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
696 ASSERT (SenseDataLength
!= NULL
);
697 ASSERT (HostAdapterStatus
!= NULL
);
698 ASSERT (TargetStatus
!= NULL
);
699 ASSERT (DataLength
!= NULL
);
700 ASSERT (ScsiIo
!= NULL
);
702 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
705 CommandPacket
.Timeout
= Timeout
;
706 CommandPacket
.InDataBuffer
= DataBuffer
;
707 CommandPacket
.SenseData
= SenseData
;
708 CommandPacket
.InTransferLength
= *DataLength
;
709 CommandPacket
.Cdb
= Cdb
;
711 // Fill Cdb for Read Capacity Command
713 Target
= &TargetArray
[0];
714 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
716 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY16
;
720 // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.
722 ZeroMem ((Cdb
+ 2), 8);
728 CommandPacket
.CdbLength
= 16;
729 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
730 CommandPacket
.SenseDataLength
= *SenseDataLength
;
732 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
734 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
735 *TargetStatus
= CommandPacket
.TargetStatus
;
736 *SenseDataLength
= CommandPacket
.SenseDataLength
;
737 *DataLength
= CommandPacket
.InTransferLength
;
744 Execute Read(10) SCSI command on a specific SCSI target.
746 Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.
747 If Timeout is zero, then this function waits indefinitely for the command to complete.
748 If Timeout is greater than zero, then the command is executed and will timeout
749 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
750 construct the CDB for this SCSI command.
751 If ScsiIo is NULL, then ASSERT().
752 If SenseDataLength is NULL, then ASSERT().
753 If HostAdapterStatus is NULL, then ASSERT().
754 If TargetStatus is NULL, then ASSERT().
755 If DataLength is NULL, then ASSERT().
758 @param[in] ScsiIo A pointer to SCSI IO protocol.
759 @param[in] Timeout The length of timeout period.
760 @param[in, out] SenseData A pointer to output sense data.
761 @param[in, out] SenseDataLength The length of output sense data.
762 @param[out] HostAdapterStatus The status of Host Adapter.
763 @param[out] TargetStatus The status of the target.
764 @param[in, out] DataBuffer Read 10 command data.
765 @param[in, out] DataLength The length of data buffer.
766 @param[in] StartLba The start address of LBA.
767 @param[in] SectorSize The sector size.
769 @retval EFI_SUCCESS The command is executed successfully.
770 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
771 not be transferred. The actual number of bytes transferred is returned in DataLength.
772 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
773 SCSI Command Packets already queued.
774 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
775 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
776 the SCSI initiator(i.e., SCSI Host Controller)
777 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
783 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
785 IN OUT VOID
*SenseData
, OPTIONAL
786 IN OUT UINT8
*SenseDataLength
,
787 OUT UINT8
*HostAdapterStatus
,
788 OUT UINT8
*TargetStatus
,
789 IN OUT VOID
*DataBuffer
, OPTIONAL
790 IN OUT UINT32
*DataLength
,
795 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
798 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
800 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
802 ASSERT (SenseDataLength
!= NULL
);
803 ASSERT (HostAdapterStatus
!= NULL
);
804 ASSERT (TargetStatus
!= NULL
);
805 ASSERT (DataLength
!= NULL
);
806 ASSERT (ScsiIo
!= NULL
);
808 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
809 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
811 CommandPacket
.Timeout
= Timeout
;
812 CommandPacket
.InDataBuffer
= DataBuffer
;
813 CommandPacket
.SenseData
= SenseData
;
814 CommandPacket
.InTransferLength
= *DataLength
;
815 CommandPacket
.Cdb
= Cdb
;
817 // Fill Cdb for Read (10) Command
819 Target
= &TargetArray
[0];
820 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
822 Cdb
[0] = EFI_SCSI_OP_READ10
;
823 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
824 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
825 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
) SectorSize
));
827 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
828 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
829 CommandPacket
.SenseDataLength
= *SenseDataLength
;
831 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
833 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
834 *TargetStatus
= CommandPacket
.TargetStatus
;
835 *SenseDataLength
= CommandPacket
.SenseDataLength
;
836 *DataLength
= CommandPacket
.InTransferLength
;
843 Execute Write(10) SCSI command on a specific SCSI target.
845 Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.
846 If Timeout is zero, then this function waits indefinitely for the command to complete.
847 If Timeout is greater than zero, then the command is executed and will timeout after
848 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
849 the CDB for this SCSI command.
850 If ScsiIo is NULL, then ASSERT().
851 If SenseDataLength is NULL, then ASSERT().
852 If HostAdapterStatus is NULL, then ASSERT().
853 If TargetStatus is NULL, then ASSERT().
854 If DataLength is NULL, then ASSERT().
856 @param[in] ScsiIo SCSI IO Protocol to use
857 @param[in] Timeout The length of timeout period.
858 @param[in, out] SenseData A pointer to output sense data.
859 @param[in, out] SenseDataLength The length of output sense data.
860 @param[out] HostAdapterStatus The status of Host Adapter.
861 @param[out] TargetStatus The status of the target.
862 @param[in, out] DataBuffer A pointer to a data buffer.
863 @param[in, out] DataLength The length of data buffer.
864 @param[in] StartLba The start address of LBA.
865 @param[in] SectorSize The sector size.
867 @retval EFI_SUCCESS The command executed successfully.
868 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
869 not be transferred. The actual number of bytes transferred is returned in DataLength.
870 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
871 SCSI Command Packets already queued.
872 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
873 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
874 the SCSI initiator(i.e., SCSI Host Controller)
875 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
881 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
883 IN OUT VOID
*SenseData
, OPTIONAL
884 IN OUT UINT8
*SenseDataLength
,
885 OUT UINT8
*HostAdapterStatus
,
886 OUT UINT8
*TargetStatus
,
887 IN OUT VOID
*DataBuffer
, OPTIONAL
888 IN OUT UINT32
*DataLength
,
893 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
896 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
898 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
900 ASSERT (SenseDataLength
!= NULL
);
901 ASSERT (HostAdapterStatus
!= NULL
);
902 ASSERT (TargetStatus
!= NULL
);
903 ASSERT (DataLength
!= NULL
);
904 ASSERT (ScsiIo
!= NULL
);
906 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
907 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
909 CommandPacket
.Timeout
= Timeout
;
910 CommandPacket
.OutDataBuffer
= DataBuffer
;
911 CommandPacket
.SenseData
= SenseData
;
912 CommandPacket
.OutTransferLength
= *DataLength
;
913 CommandPacket
.Cdb
= Cdb
;
915 // Fill Cdb for Write (10) Command
917 Target
= &TargetArray
[0];
918 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
920 Cdb
[0] = EFI_SCSI_OP_WRITE10
;
921 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
922 WriteUnaligned32 ((UINT32
*)&Cdb
[2], SwapBytes32 (StartLba
));
923 WriteUnaligned16 ((UINT16
*)&Cdb
[7], SwapBytes16 ((UINT16
) SectorSize
));
925 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
926 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
927 CommandPacket
.SenseDataLength
= *SenseDataLength
;
929 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
931 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
932 *TargetStatus
= CommandPacket
.TargetStatus
;
933 *SenseDataLength
= CommandPacket
.SenseDataLength
;
934 *DataLength
= CommandPacket
.OutTransferLength
;
940 Execute Read(16) SCSI command on a specific SCSI target.
942 Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.
943 If Timeout is zero, then this function waits indefinitely for the command to complete.
944 If Timeout is greater than zero, then the command is executed and will timeout
945 after Timeout 100 ns units. The StartLba and SectorSize parameters are used to
946 construct the CDB for this SCSI command.
947 If ScsiIo is NULL, then ASSERT().
948 If SenseDataLength is NULL, then ASSERT().
949 If HostAdapterStatus is NULL, then ASSERT().
950 If TargetStatus is NULL, then ASSERT().
951 If DataLength is NULL, then ASSERT().
954 @param[in] ScsiIo A pointer to SCSI IO protocol.
955 @param[in] Timeout The length of timeout period.
956 @param[in, out] SenseData A pointer to output sense data.
957 @param[in, out] SenseDataLength The length of output sense data.
958 @param[out] HostAdapterStatus The status of Host Adapter.
959 @param[out] TargetStatus The status of the target.
960 @param[in, out] DataBuffer Read 16 command data.
961 @param[in, out] DataLength The length of data buffer.
962 @param[in] StartLba The start address of LBA.
963 @param[in] SectorSize The sector size.
965 @retval EFI_SUCCESS The command executed successfully.
966 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
967 not be transferred. The actual number of bytes transferred is returned in DataLength.
968 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
969 SCSI Command Packets already queued.
970 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
971 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
972 the SCSI initiator(i.e., SCSI Host Controller)
973 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
979 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
981 IN OUT VOID
*SenseData
, OPTIONAL
982 IN OUT UINT8
*SenseDataLength
,
983 OUT UINT8
*HostAdapterStatus
,
984 OUT UINT8
*TargetStatus
,
985 IN OUT VOID
*DataBuffer
, OPTIONAL
986 IN OUT UINT32
*DataLength
,
991 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
994 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
996 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
998 ASSERT (SenseDataLength
!= NULL
);
999 ASSERT (HostAdapterStatus
!= NULL
);
1000 ASSERT (TargetStatus
!= NULL
);
1001 ASSERT (DataLength
!= NULL
);
1002 ASSERT (ScsiIo
!= NULL
);
1004 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1005 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1007 CommandPacket
.Timeout
= Timeout
;
1008 CommandPacket
.InDataBuffer
= DataBuffer
;
1009 CommandPacket
.SenseData
= SenseData
;
1010 CommandPacket
.InTransferLength
= *DataLength
;
1011 CommandPacket
.Cdb
= Cdb
;
1013 // Fill Cdb for Read (16) Command
1015 Target
= &TargetArray
[0];
1016 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
1018 Cdb
[0] = EFI_SCSI_OP_READ16
;
1019 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
1020 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1021 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1023 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1024 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
1025 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1027 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1029 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1030 *TargetStatus
= CommandPacket
.TargetStatus
;
1031 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1032 *DataLength
= CommandPacket
.InTransferLength
;
1039 Execute Write(16) SCSI command on a specific SCSI target.
1041 Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.
1042 If Timeout is zero, then this function waits indefinitely for the command to complete.
1043 If Timeout is greater than zero, then the command is executed and will timeout after
1044 Timeout 100 ns units. The StartLba and SectorSize parameters are used to construct
1045 the CDB for this SCSI command.
1046 If ScsiIo is NULL, then ASSERT().
1047 If SenseDataLength is NULL, then ASSERT().
1048 If HostAdapterStatus is NULL, then ASSERT().
1049 If TargetStatus is NULL, then ASSERT().
1050 If DataLength is NULL, then ASSERT().
1052 @param[in] ScsiIo SCSI IO Protocol to use
1053 @param[in] Timeout The length of timeout period.
1054 @param[in, out] SenseData A pointer to output sense data.
1055 @param[in, out] SenseDataLength The length of output sense data.
1056 @param[out] HostAdapterStatus The status of Host Adapter.
1057 @param[out] TargetStatus The status of the target.
1058 @param[in, out] DataBuffer A pointer to a data buffer.
1059 @param[in, out] DataLength The length of data buffer.
1060 @param[in] StartLba The start address of LBA.
1061 @param[in] SectorSize The sector size.
1063 @retval EFI_SUCCESS The command is executed successfully.
1064 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the entire DataBuffer could
1065 not be transferred. The actual number of bytes transferred is returned in DataLength.
1066 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
1067 SCSI Command Packets already queued.
1068 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
1069 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
1070 the SCSI initiator(i.e., SCSI Host Controller)
1071 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
1076 ScsiWrite16Command (
1077 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
1079 IN OUT VOID
*SenseData
, OPTIONAL
1080 IN OUT UINT8
*SenseDataLength
,
1081 OUT UINT8
*HostAdapterStatus
,
1082 OUT UINT8
*TargetStatus
,
1083 IN OUT VOID
*DataBuffer
, OPTIONAL
1084 IN OUT UINT32
*DataLength
,
1086 IN UINT32 SectorSize
1089 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
1092 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
1094 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIXTEEN
];
1096 ASSERT (SenseDataLength
!= NULL
);
1097 ASSERT (HostAdapterStatus
!= NULL
);
1098 ASSERT (TargetStatus
!= NULL
);
1099 ASSERT (DataLength
!= NULL
);
1100 ASSERT (ScsiIo
!= NULL
);
1102 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
1103 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIXTEEN
);
1105 CommandPacket
.Timeout
= Timeout
;
1106 CommandPacket
.OutDataBuffer
= DataBuffer
;
1107 CommandPacket
.SenseData
= SenseData
;
1108 CommandPacket
.OutTransferLength
= *DataLength
;
1109 CommandPacket
.Cdb
= Cdb
;
1111 // Fill Cdb for Write (16) Command
1113 Target
= &TargetArray
[0];
1114 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
1116 Cdb
[0] = EFI_SCSI_OP_WRITE16
;
1117 Cdb
[1] = (UINT8
) (LShiftU64 (Lun
, 5) & EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
1118 WriteUnaligned64 ((UINT64
*)&Cdb
[2], SwapBytes64 (StartLba
));
1119 WriteUnaligned32 ((UINT32
*)&Cdb
[10], SwapBytes32 (SectorSize
));
1121 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_SIXTEEN
;
1122 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
1123 CommandPacket
.SenseDataLength
= *SenseDataLength
;
1125 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
1127 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
1128 *TargetStatus
= CommandPacket
.TargetStatus
;
1129 *SenseDataLength
= CommandPacket
.SenseDataLength
;
1130 *DataLength
= CommandPacket
.OutTransferLength
;