3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 #include <IndustryStandard/scsi.h>
26 SubmitTestUnitReadyCommand (
27 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
30 OUT UINT8
*SenseDataLength
,
31 OUT UINT8
*HostAdapterStatus
,
32 OUT UINT8
*TargetStatus
37 Function tests the ready status of SCSI unit.
40 ScsiIo - A pointer to SCSI IO protocol.
41 Timeout - The length of timeout period.
42 SenseData - A pointer to output sense data.
43 SenseDataLength - The length of output sense data.
44 HostAdapterStatus - The status of Host Adapter.
45 TargetStatus - The status of the target.
50 EFI_SUCCESS - The status of the unit is tested successfully.
51 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
52 but the entire DataBuffer could not be transferred.
53 The actual number of bytes transferred is returned
55 EFI_NOT_READY - The SCSI Request Packet could not be sent because
56 there are too many SCSI Command Packets already
58 EFI_DEVICE_ERROR - A device error occurred while attempting to send
59 the SCSI Request Packet.
60 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
61 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
62 is not supported by the SCSI initiator(i.e., SCSI
64 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
65 Request Packet to execute.
69 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
75 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
78 CommandPacket
.Timeout
= Timeout
;
79 CommandPacket
.DataBuffer
= NULL
;
80 CommandPacket
.SenseData
= SenseData
;
81 CommandPacket
.TransferLength
= 0;
82 CommandPacket
.Cdb
= Cdb
;
85 // Fill Cdb for Test Unit Ready Command
87 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
89 Cdb
[0] = EFI_SCSI_OP_TEST_UNIT_READY
;
90 Cdb
[1] = (UINT8
) (Lun
& 0xe0);
91 CommandPacket
.CdbLength
= (UINT8
) 6;
92 CommandPacket
.SenseDataLength
= *SenseDataLength
;
94 Status
= ScsiIo
->ExecuteSCSICommand (ScsiIo
, &CommandPacket
, NULL
);
96 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
97 *TargetStatus
= CommandPacket
.TargetStatus
;
98 *SenseDataLength
= CommandPacket
.SenseDataLength
;
104 SubmitInquiryCommand (
105 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
108 IN OUT UINT8
*SenseDataLength
,
109 OUT UINT8
*HostAdapterStatus
,
110 OUT UINT8
*TargetStatus
,
111 IN OUT VOID
*InquiryDataBuffer
,
112 IN OUT UINT32
*InquiryDataLength
,
113 IN BOOLEAN EnableVitalProductData
118 Function to submit SCSI inquiry command.
121 ScsiIo - A pointer to SCSI IO protocol.
122 Timeout - The length of timeout period.
123 SenseData - A pointer to output sense data.
124 SenseDataLength - The length of output sense data.
125 HostAdapterStatus - The status of Host Adapter.
126 TargetStatus - The status of the target.
127 InquiryDataBuffer - A pointer to inquiry data buffer.
128 InquiryDataLength - The length of inquiry data buffer.
129 EnableVitalProductData - Boolean to enable Vital Product Data.
134 EFI_SUCCESS - The status of the unit is tested successfully.
135 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
136 but the entire DataBuffer could not be transferred.
137 The actual number of bytes transferred is returned
139 EFI_NOT_READY - The SCSI Request Packet could not be sent because
140 there are too many SCSI Command Packets already
142 EFI_DEVICE_ERROR - A device error occurred while attempting to send
143 the SCSI Request Packet.
144 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
145 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
146 is not supported by the SCSI initiator(i.e., SCSI
148 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
149 Request Packet to execute.
153 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
159 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
162 CommandPacket
.Timeout
= Timeout
;
163 CommandPacket
.DataBuffer
= InquiryDataBuffer
;
164 CommandPacket
.TransferLength
= *InquiryDataLength
;
165 CommandPacket
.SenseData
= SenseData
;
166 CommandPacket
.SenseDataLength
= *SenseDataLength
;
167 CommandPacket
.Cdb
= Cdb
;
169 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
171 Cdb
[0] = EFI_SCSI_OP_INQUIRY
;
172 Cdb
[1] = (UINT8
) (Lun
& 0xe0);
173 if (EnableVitalProductData
) {
177 if (*InquiryDataLength
> 0xff) {
178 *InquiryDataLength
= 0xff;
181 Cdb
[4] = (UINT8
) (*InquiryDataLength
);
182 CommandPacket
.CdbLength
= (UINT8
) 6;
183 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
185 Status
= ScsiIo
->ExecuteSCSICommand (ScsiIo
, &CommandPacket
, NULL
);
187 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
188 *TargetStatus
= CommandPacket
.TargetStatus
;
189 *SenseDataLength
= CommandPacket
.SenseDataLength
;
190 *InquiryDataLength
= CommandPacket
.TransferLength
;
196 SubmitModeSense10Command (
197 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
200 IN OUT UINT8
*SenseDataLength
,
201 OUT UINT8
*HostAdapterStatus
,
202 OUT UINT8
*TargetStatus
,
204 IN OUT UINT32
*DataLength
,
205 IN UINT8 DBDField
, OPTIONAL
206 IN UINT8 PageControl
,
212 Function to submit SCSI mode sense 10 command.
215 ScsiIo - A pointer to SCSI IO protocol.
216 Timeout - The length of timeout period.
217 SenseData - A pointer to output sense data.
218 SenseDataLength - The length of output sense data.
219 HostAdapterStatus - The status of Host Adapter.
220 TargetStatus - The status of the target.
221 DataBuffer - A pointer to input data buffer.
222 DataLength - The length of input data buffer.
223 DBDField - The DBD Field (Optional).
224 PageControl - Page Control.
225 PageCode - Page code.
230 EFI_SUCCESS - The status of the unit is tested successfully.
231 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
232 but the entire DataBuffer could not be transferred.
233 The actual number of bytes transferred is returned
235 EFI_NOT_READY - The SCSI Request Packet could not be sent because
236 there are too many SCSI Command Packets already
238 EFI_DEVICE_ERROR - A device error occurred while attempting to send
239 the SCSI Request Packet.
240 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
241 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
242 is not supported by the SCSI initiator(i.e., SCSI
244 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
245 Request Packet to execute.
249 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
255 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
258 CommandPacket
.Timeout
= Timeout
;
259 CommandPacket
.DataBuffer
= DataBuffer
;
260 CommandPacket
.SenseData
= SenseData
;
261 CommandPacket
.TransferLength
= *DataLength
;
262 CommandPacket
.Cdb
= Cdb
;
264 // Fill Cdb for Mode Sense (10) Command
266 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
268 Cdb
[0] = EFI_SCSI_OP_MODE_SEN10
;
269 Cdb
[1] = (UINT8
) ((Lun
& 0xe0) + ((DBDField
<< 3) & 0x08));
270 Cdb
[2] = (UINT8
) ((PageControl
& 0xc0) | (PageCode
& 0x3f));
271 Cdb
[7] = (UINT8
) (*DataLength
>> 8);
272 Cdb
[8] = (UINT8
) (*DataLength
);
274 CommandPacket
.CdbLength
= 10;
275 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
276 CommandPacket
.SenseDataLength
= *SenseDataLength
;
278 Status
= ScsiIo
->ExecuteSCSICommand (ScsiIo
, &CommandPacket
, NULL
);
280 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
281 *TargetStatus
= CommandPacket
.TargetStatus
;
282 *SenseDataLength
= CommandPacket
.SenseDataLength
;
283 *DataLength
= CommandPacket
.TransferLength
;
289 SubmitRequestSenseCommand (
290 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
293 IN OUT UINT8
*SenseDataLength
,
294 OUT UINT8
*HostAdapterStatus
,
295 OUT UINT8
*TargetStatus
300 Function to submit SCSI request sense command.
303 ScsiIo - A pointer to SCSI IO protocol.
304 Timeout - The length of timeout period.
305 SenseData - A pointer to output sense data.
306 SenseDataLength - The length of output sense data.
307 HostAdapterStatus - The status of Host Adapter.
308 TargetStatus - The status of the target.
313 EFI_SUCCESS - The status of the unit is tested successfully.
314 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
315 but the entire DataBuffer could not be transferred.
316 The actual number of bytes transferred is returned
318 EFI_NOT_READY - The SCSI Request Packet could not be sent because
319 there are too many SCSI Command Packets already
321 EFI_DEVICE_ERROR - A device error occurred while attempting to send
322 the SCSI Request Packet.
323 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
324 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
325 is not supported by the SCSI initiator(i.e., SCSI
327 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
328 Request Packet to execute.
332 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
338 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
341 CommandPacket
.Timeout
= Timeout
;
342 CommandPacket
.DataBuffer
= SenseData
;
343 CommandPacket
.SenseData
= NULL
;
344 CommandPacket
.TransferLength
= *SenseDataLength
;
345 CommandPacket
.Cdb
= Cdb
;
347 // Fill Cdb for Request Sense Command
349 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
351 Cdb
[0] = EFI_SCSI_OP_REQUEST_SENSE
;
352 Cdb
[1] = (UINT8
) (Lun
& 0xe0);
353 Cdb
[4] = (UINT8
) (*SenseDataLength
);
355 CommandPacket
.CdbLength
= (UINT8
) 6;
356 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
357 CommandPacket
.SenseDataLength
= 0;
359 Status
= ScsiIo
->ExecuteSCSICommand (ScsiIo
, &CommandPacket
, NULL
);
361 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
362 *TargetStatus
= CommandPacket
.TargetStatus
;
363 *SenseDataLength
= (UINT8
) CommandPacket
.TransferLength
;
369 SubmitReadCapacityCommand (
370 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
373 IN OUT UINT8
*SenseDataLength
,
374 OUT UINT8
*HostAdapterStatus
,
375 OUT UINT8
*TargetStatus
,
376 OUT VOID
*DataBuffer
,
377 IN OUT UINT32
*DataLength
,
383 Function to submit read capacity command.
386 ScsiIo - A pointer to SCSI IO protocol.
387 Timeout - The length of timeout period.
388 SenseData - A pointer to output sense data.
389 SenseDataLength - The length of output sense data.
390 HostAdapterStatus - The status of Host Adapter.
391 TargetStatus - The status of the target.
392 DataBuffer - A pointer to a data buffer.
393 DataLength - The length of data buffer.
394 PMI - Partial medium indicator.
399 EFI_SUCCESS - The status of the unit is tested successfully.
400 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
401 but the entire DataBuffer could not be transferred.
402 The actual number of bytes transferred is returned
404 EFI_NOT_READY - The SCSI Request Packet could not be sent because
405 there are too many SCSI Command Packets already
407 EFI_DEVICE_ERROR - A device error occurred while attempting to send
408 the SCSI Request Packet.
409 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
410 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
411 is not supported by the SCSI initiator(i.e., SCSI
413 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
414 Request Packet to execute.
418 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
424 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
427 CommandPacket
.Timeout
= Timeout
;
428 CommandPacket
.DataBuffer
= DataBuffer
;
429 CommandPacket
.SenseData
= SenseData
;
430 CommandPacket
.TransferLength
= *DataLength
;
431 CommandPacket
.Cdb
= Cdb
;
433 // Fill Cdb for Read Capacity Command
435 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
437 Cdb
[0] = EFI_SCSI_OP_READ_CAPACITY
;
438 Cdb
[1] = (UINT8
) (Lun
& 0xe0);
441 // Partial medium indicator,if PMI is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.
443 ZeroMem ((Cdb
+ 2), 4);
448 CommandPacket
.CdbLength
= 10;
449 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
450 CommandPacket
.SenseDataLength
= *SenseDataLength
;
452 Status
= ScsiIo
->ExecuteSCSICommand (ScsiIo
, &CommandPacket
, NULL
);
454 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
455 *TargetStatus
= CommandPacket
.TargetStatus
;
456 *SenseDataLength
= CommandPacket
.SenseDataLength
;
457 *DataLength
= CommandPacket
.TransferLength
;
463 SubmitRead10Command (
464 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
467 IN OUT UINT8
*SenseDataLength
,
468 OUT UINT8
*HostAdapterStatus
,
469 OUT UINT8
*TargetStatus
,
470 OUT VOID
*DataBuffer
,
471 IN OUT UINT32
*DataLength
,
478 Function to submit read 10 command.
481 ScsiIo - A pointer to SCSI IO protocol.
482 Timeout - The length of timeout period.
483 SenseData - A pointer to output sense data.
484 SenseDataLength - The length of output sense data.
485 HostAdapterStatus - The status of Host Adapter.
486 TargetStatus - The status of the target.
487 DataBuffer - A pointer to a data buffer.
488 DataLength - The length of data buffer.
489 StartLba - The start address of LBA.
490 SectorSize - The sector size.
495 EFI_SUCCESS - The status of the unit is tested successfully.
496 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
497 but the entire DataBuffer could not be transferred.
498 The actual number of bytes transferred is returned
500 EFI_NOT_READY - The SCSI Request Packet could not be sent because
501 there are too many SCSI Command Packets already
503 EFI_DEVICE_ERROR - A device error occurred while attempting to send
504 the SCSI Request Packet.
505 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
506 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
507 is not supported by the SCSI initiator(i.e., SCSI
509 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
510 Request Packet to execute.
514 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
520 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
523 CommandPacket
.Timeout
= Timeout
;
524 CommandPacket
.DataBuffer
= DataBuffer
;
525 CommandPacket
.SenseData
= SenseData
;
526 CommandPacket
.TransferLength
= *DataLength
;
527 CommandPacket
.Cdb
= Cdb
;
529 // Fill Cdb for Read (10) Command
531 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
533 Cdb
[0] = EFI_SCSI_OP_READ10
;
534 Cdb
[1] = (UINT8
) (Lun
& 0xe0);
535 Cdb
[2] = (UINT8
) (StartLba
>> 24);
536 Cdb
[3] = (UINT8
) (StartLba
>> 16);
537 Cdb
[4] = (UINT8
) (StartLba
>> 8);
538 Cdb
[5] = (UINT8
) StartLba
;
539 Cdb
[7] = (UINT8
) (SectorSize
>> 8);
540 Cdb
[8] = (UINT8
) SectorSize
;
542 CommandPacket
.CdbLength
= 10;
543 CommandPacket
.DataDirection
= EFI_SCSI_DATA_IN
;
544 CommandPacket
.SenseDataLength
= *SenseDataLength
;
546 Status
= ScsiIo
->ExecuteSCSICommand (ScsiIo
, &CommandPacket
, NULL
);
548 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
549 *TargetStatus
= CommandPacket
.TargetStatus
;
550 *SenseDataLength
= CommandPacket
.SenseDataLength
;
551 *DataLength
= CommandPacket
.TransferLength
;
557 SubmitWrite10Command (
558 IN EFI_SCSI_IO_PROTOCOL
*ScsiIo
,
561 IN OUT UINT8
*SenseDataLength
,
562 OUT UINT8
*HostAdapterStatus
,
563 OUT UINT8
*TargetStatus
,
564 OUT VOID
*DataBuffer
,
565 IN OUT UINT32
*DataLength
,
572 Function to submit SCSI write 10 command.
575 ScsiIo - A pointer to SCSI IO protocol.
576 Timeout - The length of timeout period.
577 SenseData - A pointer to output sense data.
578 SenseDataLength - The length of output sense data.
579 HostAdapterStatus - The status of Host Adapter.
580 TargetStatus - The status of the target.
581 DataBuffer - A pointer to a data buffer.
582 DataLength - The length of data buffer.
583 StartLba - The start address of LBA.
584 SectorSize - The sector size.
589 EFI_SUCCESS - The status of the unit is tested successfully.
590 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
591 but the entire DataBuffer could not be transferred.
592 The actual number of bytes transferred is returned
594 EFI_NOT_READY - The SCSI Request Packet could not be sent because
595 there are too many SCSI Command Packets already
597 EFI_DEVICE_ERROR - A device error occurred while attempting to send
598 the SCSI Request Packet.
599 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
600 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
601 is not supported by the SCSI initiator(i.e., SCSI
603 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
604 Request Packet to execute.
608 EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket
;
614 ZeroMem (&CommandPacket
, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET
));
617 CommandPacket
.Timeout
= Timeout
;
618 CommandPacket
.DataBuffer
= DataBuffer
;
619 CommandPacket
.SenseData
= SenseData
;
620 CommandPacket
.TransferLength
= *DataLength
;
621 CommandPacket
.Cdb
= Cdb
;
623 // Fill Cdb for Write (10) Command
625 ScsiIo
->GetDeviceLocation (ScsiIo
, &Target
, &Lun
);
627 Cdb
[0] = EFI_SCSI_OP_WRITE10
;
628 Cdb
[1] = (UINT8
) (Lun
& 0xe0);
629 Cdb
[2] = (UINT8
) (StartLba
>> 24);
630 Cdb
[3] = (UINT8
) (StartLba
>> 16);
631 Cdb
[4] = (UINT8
) (StartLba
>> 8);
632 Cdb
[5] = (UINT8
) StartLba
;
633 Cdb
[7] = (UINT8
) (SectorSize
>> 8);
634 Cdb
[8] = (UINT8
) SectorSize
;
636 CommandPacket
.CdbLength
= 10;
637 CommandPacket
.DataDirection
= EFI_SCSI_DATA_OUT
;
638 CommandPacket
.SenseDataLength
= *SenseDataLength
;
640 Status
= ScsiIo
->ExecuteSCSICommand (ScsiIo
, &CommandPacket
, NULL
);
642 *HostAdapterStatus
= CommandPacket
.HostAdapterStatus
;
643 *TargetStatus
= CommandPacket
.TargetStatus
;
644 *SenseDataLength
= CommandPacket
.SenseDataLength
;
645 *DataLength
= CommandPacket
.TransferLength
;