2 UEFI SCSI Library implementation
4 Copyright (c) 2006 - 2008, Intel Corporation.<BR>
5 All rights reserved. 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/DebugLib.h>
18 #include <Library/ScsiLib.h>
19 #include <Library/BaseMemoryLib.h>
21 #include <IndustryStandard/Scsi.h>
24 // Max bytes needed to represent ID of a SCSI device
26 #define EFI_SCSI_TARGET_MAX_BYTES (0x10)
29 // bit5..7 are for Logical unit number
32 #define EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK 0xe0
35 // Scsi Command Length six or ten
37 #define EFI_SCSI_OP_LENGTH_SIX 0x6
38 #define EFI_SCSI_OP_LENGTH_TEN 0xa
41 Function test the ready status of the SCSI unit.
43 Submit SCSI test unit ready command with SCSI request packet specified by this scsi command, TimeOut
44 and SenseData, then get the status of the target Scsi unit.
46 If SenseDataLength is NULL, then ASSERT().
48 If HostAdapterStatus is NULL, then ASSERT().
50 If TargetStatus is NULL, then ASSERT().
52 @param[in] ScsiIo A pointer to SCSI IO protocol.
53 @param[in] Timeout The length of timeout period.
54 @param[in] SenseData A pointer to output sense data.
55 @param[out] SenseDataLength The length of output sense data.
56 @param[out] HostAdapterStatus The status of Host Adapter.
57 @param[out] TargetStatus The status of the target.
59 @retval EFI_SUCCESS The status of the unit is tested successfully.
60 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
61 but the entire DataBuffer could not be transferred.
62 The actual number of bytes transferred is returned
64 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
65 there are too many SCSI Command Packets already
67 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
68 the SCSI Request Packet.
69 @retval EFI_INVALID_PARAMETER ScsiIo is NULL.
70 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
71 is not supported by the SCSI initiator(i.e., SCSI
73 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
74 Request Packet to execute.
79 ScsiTestUnitReadyCommand (
80 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
83 OUT UINT8
*SenseDataLength
,
84 OUT UINT8
*HostAdapterStatus
,
85 OUT UINT8
*TargetStatus
88 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
91 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
93 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
95 ASSERT (SenseDataLength
!= NULL
);
96 ASSERT (HostAdapterStatus
!= NULL
);
97 ASSERT (TargetStatus
!= NULL
);
100 return EFI_INVALID_PARAMETER
;
103 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
104 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
106 CommandPacket
.Timeout
= Timeout
;
107 CommandPacket
.InDataBuffer
= NULL
;
108 CommandPacket
.InTransferLength
= 0;
109 CommandPacket
.OutDataBuffer
= NULL
;
110 CommandPacket
.OutTransferLength
= 0;
111 CommandPacket
.SenseData
= SenseData
;
112 CommandPacket
.Cdb
= Cdb
;
114 // Fill Cdb for Test Unit Ready Command
116 Target
= &TargetArray
[0];
117 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
119 Cdb
[0] = EFI_SCSI_OP_TEST_UNIT_READY
;
120 Cdb
[1] = (UINT8
) (Lun
& EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
121 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
122 CommandPacket
.SenseDataLength
= *SenseDataLength
;
124 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
126 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
127 *TargetStatus
= CommandPacket
.TargetStatus
;
128 *SenseDataLength
= CommandPacket
.SenseDataLength
;
135 Function to submit SCSI inquiry command.
137 Submit SCSI inquiry command with the SCSI request packet specified by this SCSI command and input
138 parameters, then return the status of Scsi unit execution.
140 If SenseDataLength is NULL, then ASSERT().
142 If HostAdapterStatus is NULL, then ASSERT().
144 If TargetStatus is NULL, then ASSERT().
146 If InquiryDataLength is NULL, then ASSERT().
148 @param[in] ScsiIo SCSI IO Protocol to use
149 @param[in] Timeout The length of timeout period.
150 @param[in] SenseData A pointer to output sense data.
151 @param[in, out] SenseDataLength The length of output sense data.
152 @param[out] HostAdapterStatus The status of Host Adapter.
153 @param[out] TargetStatus The status of the target.
154 @param[in, out] InquirydataBuffer A pointer to inquiry data buffer.
155 @param[in, out] InquiryDataLength The length of inquiry data buffer.
156 @param[in] EnableVitalProductData Boolean to enable Vital Product Data.
158 @retval EFI_SUCCESS Command is executed successfully.
159 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
160 but the entire DataBuffer could not be transferred.
161 The actual number of bytes transferred is returned
163 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
164 there are too many SCSI Command Packets already
166 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
167 the SCSI Request Packet.
168 @retval EFI_INVALID_PARAMETER ScsiIo is NULL.
169 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
170 is not supported by the SCSI initiator(i.e., SCSI
172 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
173 Request Packet to execute.
179 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
182 IN OUT UINT8
*SenseDataLength
,
183 OUT UINT8
*HostAdapterStatus
,
184 OUT UINT8
*TargetStatus
,
185 IN OUT VOID
*InquiryDataBuffer
,
186 IN OUT UINT32
*InquiryDataLength
,
187 IN BOOLEAN EnableVitalProductData
190 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
193 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
195 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
197 ASSERT (SenseDataLength
!= NULL
);
198 ASSERT (HostAdapterStatus
!= NULL
);
199 ASSERT (TargetStatus
!= NULL
);
200 ASSERT (InquiryDataLength
!= NULL
);
202 if (ScsiIo
== NULL
) {
203 return EFI_INVALID_PARAMETER
;
206 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
207 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
209 CommandPacket
.Timeout
= Timeout
;
210 CommandPacket
.InDataBuffer
= InquiryDataBuffer
;
211 CommandPacket
.InTransferLength
= *InquiryDataLength
;
212 CommandPacket
.SenseData
= SenseData
;
213 CommandPacket
.SenseDataLength
= *SenseDataLength
;
214 CommandPacket
.Cdb
= Cdb
;
216 Target
= &TargetArray
[0];
217 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
219 Cdb
[0] = EFI_SCSI_OP_INQUIRY
;
220 Cdb
[1] = (UINT8
) (Lun
& EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
221 if (EnableVitalProductData
) {
225 if (*InquiryDataLength
> 0xff) {
226 *InquiryDataLength
= 0xff;
229 Cdb
[4] = (UINT8
) (*InquiryDataLength
);
230 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
231 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
233 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
235 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
236 *TargetStatus
= CommandPacket
.TargetStatus
;
237 *SenseDataLength
= CommandPacket
.SenseDataLength
;
238 *InquiryDataLength
= CommandPacket
.InTransferLength
;
245 Function to submit SCSI mode sense 10 command.
247 Submit SCSI Mode Sense (10) command with the SCSI request packet specified by this SCSI command and
248 the input parameters, then return the status of Scsi unit execution.
250 If SenseDataLength is NULL, then ASSERT().
252 If HostAdapterStatus is NULL, then ASSERT().
254 If TargetStatus is NULL, then ASSERT().
256 If DataLength is NULL, then ASSERT().
258 @param[in] ScsiIo A pointer to SCSI IO protocol.
259 @param[in] Timeout The length of timeout period.
260 @param[in] SenseData A pointer to output sense data.
261 @param[in, out] SenseDataLength The length of output sense data.
262 @param[out] HostAdapterStatus The status of Host Adapter.
263 @param[out] TargetStatus The status of the target.
264 @param[in] DataBuffer A pointer to input data buffer.
265 @param[in, out] DataLength The length of input data buffer.
266 @param[in] DBDField The DBD Field (Optional).
267 @param[in] PageControl Page Control.
268 @param[in] PageCode Page code.
270 @retval EFI_SUCCESS The status of the unit is tested successfully.
271 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,
272 but the entire DataBuffer could not be transferred.
273 The actual number of bytes transferred is returned
275 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because
276 there are too many SCSI Command Packets already
278 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send
279 the SCSI Request Packet.
280 @retval EFI_INVALID_PARAMETER ScsiIo is NULL.
281 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet
282 is not supported by the SCSI initiator(i.e., SCSI
284 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI
285 Request Packet to execute.
290 ScsiModeSense10Command (
291 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
294 IN OUT UINT8
*SenseDataLength
,
295 OUT UINT8
*HostAdapterStatus
,
296 OUT UINT8
*TargetStatus
,
298 IN OUT UINT32
*DataLength
,
299 IN UINT8 DBDField
, OPTIONAL
300 IN UINT8 PageControl
,
304 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
307 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
309 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
311 ASSERT (SenseDataLength
!= NULL
);
312 ASSERT (HostAdapterStatus
!= NULL
);
313 ASSERT (TargetStatus
!= NULL
);
314 ASSERT (DataLength
!= NULL
);
316 if (ScsiIo
== NULL
) {
317 return EFI_INVALID_PARAMETER
;
320 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
321 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
323 CommandPacket
.Timeout
= Timeout
;
324 CommandPacket
.InDataBuffer
= DataBuffer
;
325 CommandPacket
.SenseData
= SenseData
;
326 CommandPacket
.InTransferLength
= *DataLength
;
327 CommandPacket
.Cdb
= Cdb
;
329 // Fill Cdb for Mode Sense (10) Command
331 Target
= &TargetArray
[0];
332 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
334 Cdb
[0] = EFI_SCSI_OP_MODE_SEN10
;
336 // DBDField is in Cdb[1] bit3 of (bit7..0)
338 Cdb
[1] = (UINT8
) ((Lun
& EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
) + ((DBDField
<< 3) & 0x08));
340 // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0
342 Cdb
[2] = (UINT8
) ((PageControl
& 0xc0) | (PageCode
& 0x3f));
343 Cdb
[7] = (UINT8
) (*DataLength
>> 8);
344 Cdb
[8] = (UINT8
) (*DataLength
);
346 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
347 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
348 CommandPacket
.SenseDataLength
= *SenseDataLength
;
350 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
352 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
353 *TargetStatus
= CommandPacket
.TargetStatus
;
354 *SenseDataLength
= CommandPacket
.SenseDataLength
;
355 *DataLength
= CommandPacket
.InTransferLength
;
362 Function to submit SCSI request sense command.
364 Submit SCSI request sense command with the SCSI requested packet specified by this
365 SCSI command, TimeOut and SenseData, and then return the status of scsi unit execution.
367 If SenseDataLength is NULL, then ASSERT().
369 If HostAdapterStatus is NULL, then ASSERT().
371 If TargetStatus is NULL, then ASSERT().
373 @param[in] ScsiIo A pointer to SCSI IO protocol.
374 @param[in] Timeout The length of timeout period.
375 @param[in] SenseData A pointer to output sense data.
376 @param[in, out] SenseDataLength The length of output sense data.
377 @param[out] HostAdapterStatus The status of Host Adapter.
378 @param[out] TargetStatus The status of the target.
380 @retval EFI_SUCCESS Command is executed successfully.
381 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are
382 too many SCSI Command Packets already queued.
383 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
384 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
385 the SCSI initiator(i.e., SCSI Host Controller)
386 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
387 @retval EFI_INVALID_PARAMETER ScsiIo is NULL.
392 ScsiRequestSenseCommand (
393 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
396 IN OUT UINT8
*SenseDataLength
,
397 OUT UINT8
*HostAdapterStatus
,
398 OUT UINT8
*TargetStatus
401 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
404 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
406 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_SIX
];
408 ASSERT (SenseDataLength
!= NULL
);
409 ASSERT (HostAdapterStatus
!= NULL
);
410 ASSERT (TargetStatus
!= NULL
);
412 if (ScsiIo
== NULL
) {
413 return EFI_INVALID_PARAMETER
;
416 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
417 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_SIX
);
419 CommandPacket
.Timeout
= Timeout
;
420 CommandPacket
.InDataBuffer
= SenseData
;
421 CommandPacket
.SenseData
= NULL
;
422 CommandPacket
.InTransferLength
= *SenseDataLength
;
423 CommandPacket
.Cdb
= Cdb
;
425 // Fill Cdb for Request Sense Command
427 Target
= &TargetArray
[0];
428 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
430 Cdb
[0] = EFI_SCSI_OP_REQUEST_SENSE
;
431 Cdb
[1] = (UINT8
) (Lun
& EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
432 Cdb
[4] = (UINT8
) (*SenseDataLength
);
434 CommandPacket
.CdbLength
= (UINT8
) EFI_SCSI_OP_LENGTH_SIX
;
435 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
436 CommandPacket
.SenseDataLength
= 0;
438 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
440 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
441 *TargetStatus
= CommandPacket
.TargetStatus
;
442 *SenseDataLength
= (UINT8
) CommandPacket
.InTransferLength
;
449 Function to submit read capacity command.
451 Submit SCSI read capacity command with the SCSI request packet specified by this SCSI
452 command and the input parameters, and then return the status of Scsi unit execution.
454 If SenseDataLength is NULL, then ASSERT().
456 If HostAdapterStatus is NULL, then ASSERT().
458 If TargetStatus is NULL, then ASSERT().
460 If DataLength is NULL, then ASSERT().
462 @param[in] ScsiIo A pointer to SCSI IO protocol.
463 @param[in] Timeout The length of timeout period.
464 @param[in] SenseData A pointer to output sense data.
465 @param[in, out] SenseDataLength The length of output sense data.
466 @param[out] HostAdapterStatus The status of Host Adapter.
467 @param[out] TargetStatus The status of the target.
468 @param[out] DataBuffer A pointer to a data buffer.
469 @param[in, out] DataLength The length of data buffer.
470 @param[in] PMI Partial medium indicator.
472 @retval EFI_SUCCESS Command is executed successfully.
473 @retval EFI_WARN_BUFFER_TOO_SMALL The SCSI Request Packet was executed, but the entire DataBuffer could
474 not be transferred. The actual number of bytes transferred is returned in DataLength.
475 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
476 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.
481 @retval EFI_INVALID_PARAMETER ScsiIo is NULL.
486 ScsiReadCapacityCommand (
487 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
490 IN OUT UINT8
*SenseDataLength
,
491 OUT UINT8
*HostAdapterStatus
,
492 OUT UINT8
*TargetStatus
,
493 OUT VOID
*DataBuffer
,
494 IN OUT UINT32
*DataLength
,
498 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
501 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
503 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
505 ASSERT (SenseDataLength
!= NULL
);
506 ASSERT (HostAdapterStatus
!= NULL
);
507 ASSERT (TargetStatus
!= NULL
);
508 ASSERT (DataLength
!= NULL
);
510 if (ScsiIo
== NULL
) {
511 return EFI_INVALID_PARAMETER
;
514 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
515 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
517 CommandPacket
.Timeout
= Timeout
;
518 CommandPacket
.InDataBuffer
= DataBuffer
;
519 CommandPacket
.SenseData
= SenseData
;
520 CommandPacket
.InTransferLength
= *DataLength
;
521 CommandPacket
.Cdb
= Cdb
;
523 // Fill Cdb for Read Capacity Command
525 Target
= &TargetArray
[0];
526 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
528 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY
;
529 Cdb
[1] = (UINT8
) (Lun
& EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
532 // Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.
534 ZeroMem ((Cdb
+ 2), 4);
539 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
540 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
541 CommandPacket
.SenseDataLength
= *SenseDataLength
;
543 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
545 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
546 *TargetStatus
= CommandPacket
.TargetStatus
;
547 *SenseDataLength
= CommandPacket
.SenseDataLength
;
548 *DataLength
= CommandPacket
.InTransferLength
;
555 Function to submit read 10 command.
557 Submit SCSI read (10) command with the SCSI request packet specified by this SCSI command
558 and the input parameters, and then return the status of Scsi unit execution.
560 If SenseDataLength is NULL, then ASSERT().
562 If HostAdapterStatus is NULL, then ASSERT().
564 If TargetStatus is NULL, then ASSERT().
566 If DataLength is NULL, then ASSERT().
568 @param[in] ScsiIo A pointer to SCSI IO protocol.
569 @param[in] Timeout The length of timeout period.
570 @param[in] SenseData A pointer to output sense data.
571 @param[in, out] SenseDataLength The length of output sense data.
572 @param[out] HostAdapterStatus The status of Host Adapter.
573 @param[out] TargetStatus The status of the target.
574 @param[out] DataBuffer Read 10 command data.
575 @param[in, out] DataLength The length of data buffer.
576 @param[in] StartLba The start address of LBA.
577 @param[in] SectorSize The sector size.
579 @retval EFI_SUCCESS Command is executed successfully.
580 @retval EFI_WARN_BUFFER_TOO_SMALL The SCSI Request Packet was executed, but the entire DataBuffer could
581 not be transferred. The actual number of bytes transferred is returned in DataLength.
582 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
583 SCSI Command Packets already queued.
584 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
585 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
586 the SCSI initiator(i.e., SCSI Host Controller)
587 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
588 @retval EFI_INVALID_PARAMETER ScsiIo is NULL.
594 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
597 IN OUT UINT8
*SenseDataLength
,
598 OUT UINT8
*HostAdapterStatus
,
599 OUT UINT8
*TargetStatus
,
600 OUT VOID
*DataBuffer
,
601 IN OUT UINT32
*DataLength
,
606 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
609 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
611 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
613 ASSERT (SenseDataLength
!= NULL
);
614 ASSERT (HostAdapterStatus
!= NULL
);
615 ASSERT (TargetStatus
!= NULL
);
616 ASSERT (DataLength
!= NULL
);
618 if (ScsiIo
== NULL
) {
619 return EFI_INVALID_PARAMETER
;
622 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
623 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
625 CommandPacket
.Timeout
= Timeout
;
626 CommandPacket
.InDataBuffer
= DataBuffer
;
627 CommandPacket
.SenseData
= SenseData
;
628 CommandPacket
.InTransferLength
= *DataLength
;
629 CommandPacket
.Cdb
= Cdb
;
631 // Fill Cdb for Read (10) Command
633 Target
= &TargetArray
[0];
634 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
636 Cdb
[0] = EFI_SCSI_OP_READ10
;
637 Cdb
[1] = (UINT8
) (Lun
& EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
638 Cdb
[2] = (UINT8
) (StartLba
>> 24);
639 Cdb
[3] = (UINT8
) (StartLba
>> 16);
640 Cdb
[4] = (UINT8
) (StartLba
>> 8);
641 Cdb
[5] = (UINT8
) (StartLba
& 0xff);
642 Cdb
[7] = (UINT8
) (SectorSize
>> 8);
643 Cdb
[8] = (UINT8
) (SectorSize
& 0xff);
645 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
646 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
647 CommandPacket
.SenseDataLength
= *SenseDataLength
;
649 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
651 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
652 *TargetStatus
= CommandPacket
.TargetStatus
;
653 *SenseDataLength
= CommandPacket
.SenseDataLength
;
654 *DataLength
= CommandPacket
.InTransferLength
;
661 Function to submit SCSI write 10 command.
663 Submit SCSI write (10) command with the SCSI request packet specified by this SCSI command and the
664 input parameters, and then return the status of Scsi unit execution.
666 If SenseDataLength is NULL, then ASSERT().
668 If HostAdapterStatus is NULL, then ASSERT().
670 If TargetStatus is NULL, then ASSERT().
672 If DataLength is NULL, then ASSERT().
674 @param[in] ScsiIo SCSI IO Protocol to use
675 @param[in] Timeout The length of timeout period.
676 @param[in] SenseData A pointer to output sense data.
677 @param[in, out] SenseDataLength The length of output sense data.
678 @param[out] HostAdapterStatus The status of Host Adapter.
679 @param[out] TargetStatus The status of the target.
680 @param[out] DataBuffer A pointer to a data buffer.
681 @param[in, out] DataLength The length of data buffer.
682 @param[in] StartLba The start address of LBA.
683 @param[in] SectorSize The sector size.
685 @retval EFI_SUCCESS Command is executed successfully.
686 @retval EFI_WARN_BUFFER_TOO_SMALL The SCSI Request Packet was executed, but the entire DataBuffer could
687 not be transferred. The actual number of bytes transferred is returned in DataLength.
688 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many
689 SCSI Command Packets already queued.
690 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send SCSI Request Packet.
691 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported by
692 the SCSI initiator(i.e., SCSI Host Controller)
693 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute.
694 @retval EFI_INVALID_PARAMETER ScsiIo is NULL.
700 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
703 IN OUT UINT8
*SenseDataLength
,
704 OUT UINT8
*HostAdapterStatus
,
705 OUT UINT8
*TargetStatus
,
706 OUT VOID
*DataBuffer
,
707 IN OUT UINT32
*DataLength
,
712 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
715 UINT8 TargetArray
[EFI_SCSI_TARGET_MAX_BYTES
];
717 UINT8 Cdb
[EFI_SCSI_OP_LENGTH_TEN
];
719 ASSERT (SenseDataLength
!= NULL
);
720 ASSERT (HostAdapterStatus
!= NULL
);
721 ASSERT (TargetStatus
!= NULL
);
722 ASSERT (DataLength
!= NULL
);
724 if (ScsiIo
== NULL
) {
725 return EFI_INVALID_PARAMETER
;
728 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
729 ZeroMem (Cdb
, EFI_SCSI_OP_LENGTH_TEN
);
731 CommandPacket
.Timeout
= Timeout
;
732 CommandPacket
.OutDataBuffer
= DataBuffer
;
733 CommandPacket
.SenseData
= SenseData
;
734 CommandPacket
.OutTransferLength
= *DataLength
;
735 CommandPacket
.Cdb
= Cdb
;
737 // Fill Cdb for Write (10) Command
739 Target
= &TargetArray
[0];
740 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
742 Cdb
[0] = EFI_SCSI_OP_WRITE10
;
743 Cdb
[1] = (UINT8
) (Lun
& EFI_SCSI_LOGICAL_UNIT_NUMBER_MASK
);
744 Cdb
[2] = (UINT8
) (StartLba
>> 24);
745 Cdb
[3] = (UINT8
) (StartLba
>> 16);
746 Cdb
[4] = (UINT8
) (StartLba
>> 8);
747 Cdb
[5] = (UINT8
) StartLba
;
748 Cdb
[7] = (UINT8
) (SectorSize
>> 8);
749 Cdb
[8] = (UINT8
) SectorSize
;
751 CommandPacket
.CdbLength
= EFI_SCSI_OP_LENGTH_TEN
;
752 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
753 CommandPacket
.SenseDataLength
= *SenseDataLength
;
755 Status
= ScsiIo
->ExecuteScsiCommand (ScsiIo
, &CommandPacket
, NULL
);
757 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
758 *TargetStatus
= CommandPacket
.TargetStatus
;
759 *SenseDataLength
= CommandPacket
.SenseDataLength
;
760 *DataLength
= CommandPacket
.OutTransferLength
;