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.
24 ScsiDiskDriverBindingSupported (
25 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
26 IN EFI_HANDLE Controller
,
27 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
32 ScsiDiskDriverBindingStart (
33 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
34 IN EFI_HANDLE Controller
,
35 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
40 ScsiDiskDriverBindingStop (
41 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
42 IN EFI_HANDLE Controller
,
43 IN UINTN NumberOfChildren
,
44 IN EFI_HANDLE
*ChildHandleBuffer
47 EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding
= {
48 ScsiDiskDriverBindingSupported
,
49 ScsiDiskDriverBindingStart
,
50 ScsiDiskDriverBindingStop
,
58 ScsiDiskDriverBindingSupported (
59 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
60 IN EFI_HANDLE Controller
,
61 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
72 // TODO: This - add argument and description to function comment
73 // TODO: Controller - add argument and description to function comment
74 // TODO: RemainingDevicePath - add argument and description to function comment
77 EFI_SCSI_IO_PROTOCOL
*ScsiIo
;
80 Status
= gBS
->OpenProtocol (
82 &gEfiScsiIoProtocolGuid
,
84 This
->DriverBindingHandle
,
86 EFI_OPEN_PROTOCOL_BY_DRIVER
88 if (EFI_ERROR (Status
)) {
92 Status
= ScsiIo
->GetDeviceType (ScsiIo
, &DeviceType
);
93 if (!EFI_ERROR (Status
)) {
94 if ((DeviceType
== EFI_SCSI_TYPE_DISK
) || (DeviceType
== EFI_SCSI_TYPE_CDROM
)) {
97 Status
= EFI_UNSUPPORTED
;
103 &gEfiScsiIoProtocolGuid
,
104 This
->DriverBindingHandle
,
112 ScsiDiskDriverBindingStart (
113 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
114 IN EFI_HANDLE Controller
,
115 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
126 // TODO: This - add argument and description to function comment
127 // TODO: Controller - add argument and description to function comment
128 // TODO: RemainingDevicePath - add argument and description to function comment
129 // TODO: EFI_DEVICE_ERROR - add return value to function comment
130 // TODO: EFI_SUCCESS - add return value to function comment
133 EFI_SCSI_IO_PROTOCOL
*ScsiIo
;
134 SCSI_DISK_DEV
*ScsiDiskDevice
;
140 Status
= gBS
->AllocatePool (
142 sizeof (SCSI_DISK_DEV
),
143 (VOID
**) &ScsiDiskDevice
145 if (EFI_ERROR (Status
)) {
149 ZeroMem (ScsiDiskDevice
, sizeof (SCSI_DISK_DEV
));
151 Status
= gBS
->OpenProtocol (
153 &gEfiScsiIoProtocolGuid
,
155 This
->DriverBindingHandle
,
157 EFI_OPEN_PROTOCOL_BY_DRIVER
159 if (EFI_ERROR (Status
)) {
160 gBS
->FreePool (ScsiDiskDevice
);
164 ScsiDiskDevice
->Signature
= SCSI_DISK_DEV_SIGNATURE
;
165 ScsiDiskDevice
->ScsiIo
= ScsiIo
;
166 ScsiDiskDevice
->BlkIo
.Media
= &ScsiDiskDevice
->BlkIoMedia
;
167 ScsiDiskDevice
->BlkIo
.Reset
= ScsiDiskReset
;
168 ScsiDiskDevice
->BlkIo
.ReadBlocks
= ScsiDiskReadBlocks
;
169 ScsiDiskDevice
->BlkIo
.WriteBlocks
= ScsiDiskWriteBlocks
;
170 ScsiDiskDevice
->BlkIo
.FlushBlocks
= ScsiDiskFlushBlocks
;
171 ScsiDiskDevice
->Handle
= Controller
;
173 ScsiIo
->GetDeviceType (ScsiIo
, &(ScsiDiskDevice
->DeviceType
));
174 switch (ScsiDiskDevice
->DeviceType
) {
175 case EFI_SCSI_TYPE_DISK
:
176 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x200;
179 case EFI_SCSI_TYPE_CDROM
:
180 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x800;
184 // The Sense Data Array's initial size is 6
186 ScsiDiskDevice
->SenseDataNumber
= 6;
187 Status
= gBS
->AllocatePool (
189 sizeof (EFI_SCSI_SENSE_DATA
) * ScsiDiskDevice
->SenseDataNumber
,
190 (VOID
**) &(ScsiDiskDevice
->SenseData
)
192 if (EFI_ERROR (Status
)) {
195 &gEfiScsiIoProtocolGuid
,
196 This
->DriverBindingHandle
,
199 gBS
->FreePool (ScsiDiskDevice
);
204 ScsiDiskDevice
->SenseData
,
205 sizeof (EFI_SCSI_SENSE_DATA
) * ScsiDiskDevice
->SenseDataNumber
209 // Retrive device information
212 for (Index
= 0; Index
< MaxRetry
; Index
++) {
213 Status
= ScsiDiskInquiryDevice (ScsiDiskDevice
, &NeedRetry
);
214 if (!EFI_ERROR (Status
)) {
219 gBS
->FreePool (ScsiDiskDevice
->SenseData
);
222 &gEfiScsiIoProtocolGuid
,
223 This
->DriverBindingHandle
,
226 gBS
->FreePool (ScsiDiskDevice
);
227 return EFI_DEVICE_ERROR
;
231 // The second parameter "TRUE" means must
232 // retrieve media capacity
234 Status
= ScsiDiskDetectMedia (ScsiDiskDevice
, TRUE
, &Temp
);
235 if (!EFI_ERROR (Status
)) {
236 Status
= gBS
->InstallMultipleProtocolInterfaces (
238 &gEfiBlockIoProtocolGuid
,
239 &ScsiDiskDevice
->BlkIo
,
244 if (EFI_ERROR (Status
)) {
245 gBS
->FreePool (ScsiDiskDevice
->SenseData
);
248 &gEfiScsiIoProtocolGuid
,
249 This
->DriverBindingHandle
,
252 gBS
->FreePool (ScsiDiskDevice
);
256 ScsiDiskDevice
->ControllerNameTable
= NULL
;
259 gScsiDiskComponentName
.SupportedLanguages
,
260 &ScsiDiskDevice
->ControllerNameTable
,
261 (CHAR16
*) L
"SCSI Disk Device"
270 ScsiDiskDriverBindingStop (
271 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
272 IN EFI_HANDLE Controller
,
273 IN UINTN NumberOfChildren
,
274 IN EFI_HANDLE
*ChildHandleBuffer
285 // TODO: This - add argument and description to function comment
286 // TODO: Controller - add argument and description to function comment
287 // TODO: NumberOfChildren - add argument and description to function comment
288 // TODO: ChildHandleBuffer - add argument and description to function comment
289 // TODO: EFI_SUCCESS - add return value to function comment
291 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
292 SCSI_DISK_DEV
*ScsiDiskDevice
;
295 Status
= gBS
->OpenProtocol (
297 &gEfiBlockIoProtocolGuid
,
299 This
->DriverBindingHandle
,
301 EFI_OPEN_PROTOCOL_GET_PROTOCOL
303 if (EFI_ERROR (Status
)) {
307 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (BlkIo
);
308 Status
= gBS
->UninstallProtocolInterface (
310 &gEfiBlockIoProtocolGuid
,
311 &ScsiDiskDevice
->BlkIo
313 if (!EFI_ERROR (Status
)) {
316 &gEfiScsiIoProtocolGuid
,
317 This
->DriverBindingHandle
,
321 ReleaseScsiDiskDeviceResources (ScsiDiskDevice
);
332 // Block I/O Protocol Interface
338 IN EFI_BLOCK_IO_PROTOCOL
*This
,
339 IN BOOLEAN ExtendedVerification
345 TODO: Add function description
349 This - TODO: add argument description
350 ExtendedVerification - TODO: add argument description
354 TODO: add return values
358 SCSI_DISK_DEV
*ScsiDiskDevice
;
361 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (This
);
363 Status
= ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
365 if (!ExtendedVerification
) {
369 Status
= ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
377 IN EFI_BLOCK_IO_PROTOCOL
*This
,
387 TODO: Add function description
391 This - TODO: add argument description
392 MediaId - TODO: add argument description
393 LBA - TODO: add argument description
394 BufferSize - TODO: add argument description
395 Buffer - TODO: add argument description
399 EFI_INVALID_PARAMETER - TODO: Add description for return value
400 EFI_SUCCESS - TODO: Add description for return value
401 EFI_DEVICE_ERROR - TODO: Add description for return value
402 EFI_NO_MEDIA - TODO: Add description for return value
403 EFI_MEDIA_CHANGED - TODO: Add description for return value
404 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
405 EFI_INVALID_PARAMETER - TODO: Add description for return value
406 EFI_INVALID_PARAMETER - TODO: Add description for return value
407 EFI_INVALID_PARAMETER - TODO: Add description for return value
411 SCSI_DISK_DEV
*ScsiDiskDevice
;
412 EFI_BLOCK_IO_MEDIA
*Media
;
415 UINTN NumberOfBlocks
;
420 return EFI_INVALID_PARAMETER
;
423 if (BufferSize
== 0) {
427 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (This
);
429 if (!IsDeviceFixed (ScsiDiskDevice
)) {
431 Status
= ScsiDiskDetectMedia (ScsiDiskDevice
, FALSE
, &MediaChange
);
432 if (EFI_ERROR (Status
)) {
433 return EFI_DEVICE_ERROR
;
437 gBS
->ReinstallProtocolInterface (
438 ScsiDiskDevice
->Handle
,
439 &gEfiBlockIoProtocolGuid
,
440 &ScsiDiskDevice
->BlkIo
,
441 &ScsiDiskDevice
->BlkIo
446 // Get the intrinsic block size
448 Media
= ScsiDiskDevice
->BlkIo
.Media
;
449 BlockSize
= Media
->BlockSize
;
451 NumberOfBlocks
= BufferSize
/ BlockSize
;
453 if (!(Media
->MediaPresent
)) {
457 if (MediaId
!= Media
->MediaId
) {
458 return EFI_MEDIA_CHANGED
;
461 if (BufferSize
% BlockSize
!= 0) {
462 return EFI_BAD_BUFFER_SIZE
;
465 if (LBA
> Media
->LastBlock
) {
466 return EFI_INVALID_PARAMETER
;
469 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
470 return EFI_INVALID_PARAMETER
;
473 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
474 return EFI_INVALID_PARAMETER
;
478 // if all the parameters are valid, then perform read sectors command
479 // to transfer data from device to host.
481 Status
= ScsiDiskReadSectors (ScsiDiskDevice
, Buffer
, LBA
, NumberOfBlocks
);
488 ScsiDiskWriteBlocks (
489 IN EFI_BLOCK_IO_PROTOCOL
*This
,
499 TODO: Add function description
503 This - TODO: add argument description
504 MediaId - TODO: add argument description
505 LBA - TODO: add argument description
506 BufferSize - TODO: add argument description
507 Buffer - TODO: add argument description
511 EFI_INVALID_PARAMETER - TODO: Add description for return value
512 EFI_SUCCESS - TODO: Add description for return value
513 EFI_DEVICE_ERROR - TODO: Add description for return value
514 EFI_NO_MEDIA - TODO: Add description for return value
515 EFI_MEDIA_CHANGED - TODO: Add description for return value
516 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
517 EFI_INVALID_PARAMETER - TODO: Add description for return value
518 EFI_INVALID_PARAMETER - TODO: Add description for return value
519 EFI_INVALID_PARAMETER - TODO: Add description for return value
523 SCSI_DISK_DEV
*ScsiDiskDevice
;
524 EFI_BLOCK_IO_MEDIA
*Media
;
527 UINTN NumberOfBlocks
;
532 return EFI_INVALID_PARAMETER
;
535 if (BufferSize
== 0) {
539 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (This
);
541 if (!IsDeviceFixed (ScsiDiskDevice
)) {
543 Status
= ScsiDiskDetectMedia (ScsiDiskDevice
, FALSE
, &MediaChange
);
544 if (EFI_ERROR (Status
)) {
545 return EFI_DEVICE_ERROR
;
549 gBS
->ReinstallProtocolInterface (
550 ScsiDiskDevice
->Handle
,
551 &gEfiBlockIoProtocolGuid
,
552 &ScsiDiskDevice
->BlkIo
,
553 &ScsiDiskDevice
->BlkIo
558 // Get the intrinsic block size
560 Media
= ScsiDiskDevice
->BlkIo
.Media
;
561 BlockSize
= Media
->BlockSize
;
563 NumberOfBlocks
= BufferSize
/ BlockSize
;
565 if (!(Media
->MediaPresent
)) {
569 if (MediaId
!= Media
->MediaId
) {
570 return EFI_MEDIA_CHANGED
;
573 if (BufferSize
% BlockSize
!= 0) {
574 return EFI_BAD_BUFFER_SIZE
;
577 if (LBA
> Media
->LastBlock
) {
578 return EFI_INVALID_PARAMETER
;
581 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
582 return EFI_INVALID_PARAMETER
;
585 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
586 return EFI_INVALID_PARAMETER
;
589 // if all the parameters are valid, then perform read sectors command
590 // to transfer data from device to host.
592 Status
= ScsiDiskWriteSectors (ScsiDiskDevice
, Buffer
, LBA
, NumberOfBlocks
);
599 ScsiDiskFlushBlocks (
600 IN EFI_BLOCK_IO_PROTOCOL
*This
606 TODO: Add function description
610 This - TODO: add argument description
614 EFI_SUCCESS - TODO: Add description for return value
625 ScsiDiskDetectMedia (
626 SCSI_DISK_DEV
*ScsiDiskDevice
,
627 BOOLEAN MustReadCapacity
,
634 TODO: Add function description
638 ScsiDiskDevice - TODO: add argument description
639 MustReadCapacity - TODO: add argument description
640 MediaChange - TODO: add argument description
644 EFI_DEVICE_ERROR - TODO: Add description for return value
645 EFI_DEVICE_ERROR - TODO: Add description for return value
646 EFI_DEVICE_ERROR - TODO: Add description for return value
647 EFI_SUCCESS - TODO: Add description for return value
652 EFI_STATUS ReadCapacityStatus
;
653 EFI_SCSI_SENSE_DATA
*SenseData
;
654 UINTN NumberOfSenseKeys
;
656 BOOLEAN NeedReadCapacity
;
659 EFI_BLOCK_IO_MEDIA OldMedia
;
662 Status
= EFI_SUCCESS
;
663 ReadCapacityStatus
= EFI_SUCCESS
;
665 NumberOfSenseKeys
= 0;
666 NeedReadCapacity
= FALSE
;
667 CopyMem (&OldMedia
, ScsiDiskDevice
->BlkIo
.Media
, sizeof (OldMedia
));
668 // OldMedia = *(ScsiDiskDevice->BlkIo.Media);
670 *MediaChange
= FALSE
;
673 for (Index
= 0; Index
< MaxRetry
; Index
++) {
674 Status
= ScsiDiskTestUnitReady (
680 if (!EFI_ERROR (Status
)) {
689 if ((Index
== MaxRetry
) && EFI_ERROR (Status
)) {
690 return EFI_DEVICE_ERROR
;
693 Status
= DetectMediaParsingSenseKeys (
699 if (EFI_ERROR (Status
)) {
703 // ACTION_NO_ACTION: need not read capacity
704 // other action code: need read capacity
706 if (Action
== ACTION_NO_ACTION
) {
707 NeedReadCapacity
= FALSE
;
709 NeedReadCapacity
= TRUE
;
713 // either NeedReadCapacity is TRUE, or MustReadCapacity is TRUE,
714 // retrieve capacity via Read Capacity command
716 if (NeedReadCapacity
|| MustReadCapacity
) {
719 // retrieve media information
722 for (Index
= 0; Index
< MaxRetry
; Index
++) {
724 ReadCapacityStatus
= ScsiDiskReadCapacity (
730 if (EFI_ERROR (ReadCapacityStatus
) && !NeedRetry
) {
731 return EFI_DEVICE_ERROR
;
734 // analyze sense key to action
736 Status
= DetectMediaParsingSenseKeys (
743 // if Status is error, it may indicate crisis error,
744 // so return without retry.
746 if (EFI_ERROR (Status
)) {
751 case ACTION_NO_ACTION
:
758 case ACTION_RETRY_COMMAND_LATER
:
760 // retry the ReadCapacity later and continuously, until the condition
761 // no longer emerges.
762 // stall time is 100000us, or say 0.1 second.
770 // other cases, just retry the command
776 if ((Index
== MaxRetry
) && EFI_ERROR (ReadCapacityStatus
)) {
777 return EFI_DEVICE_ERROR
;
781 if (ScsiDiskDevice
->BlkIo
.Media
->MediaId
!= OldMedia
.MediaId
) {
783 // Media change information got from the device
788 if (ScsiDiskDevice
->BlkIo
.Media
->ReadOnly
!= OldMedia
.ReadOnly
) {
790 ScsiDiskDevice
->BlkIo
.Media
->MediaId
+= 1;
793 if (ScsiDiskDevice
->BlkIo
.Media
->BlockSize
!= OldMedia
.BlockSize
) {
795 ScsiDiskDevice
->BlkIo
.Media
->MediaId
+= 1;
798 if (ScsiDiskDevice
->BlkIo
.Media
->LastBlock
!= OldMedia
.LastBlock
) {
800 ScsiDiskDevice
->BlkIo
.Media
->MediaId
+= 1;
803 if (ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
!= OldMedia
.MediaPresent
) {
804 if (ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
) {
806 // when change from no media to media present, reset the MediaId to 1.
808 ScsiDiskDevice
->BlkIo
.Media
->MediaId
= 1;
811 // when no media, reset the MediaId to zero.
813 ScsiDiskDevice
->BlkIo
.Media
->MediaId
= 0;
823 ScsiDiskInquiryDevice (
824 SCSI_DISK_DEV
*ScsiDiskDevice
,
831 TODO: Add function description
835 ScsiDiskDevice - TODO: add argument description
836 NeedRetry - TODO: add argument description
840 EFI_SUCCESS - TODO: Add description for return value
841 EFI_DEVICE_ERROR - TODO: Add description for return value
842 EFI_DEVICE_ERROR - TODO: Add description for return value
843 EFI_DEVICE_ERROR - TODO: Add description for return value
844 EFI_DEVICE_ERROR - TODO: Add description for return value
845 EFI_DEVICE_ERROR - TODO: Add description for return value
846 EFI_DEVICE_ERROR - TODO: Add description for return value
847 EFI_DEVICE_ERROR - TODO: Add description for return value
848 EFI_DEVICE_ERROR - TODO: Add description for return value
849 EFI_DEVICE_ERROR - TODO: Add description for return value
853 UINT32 InquiryDataLength
;
854 UINT8 SenseDataLength
;
855 UINT8 HostAdapterStatus
;
857 EFI_SCSI_SENSE_DATA
*SenseDataArray
;
858 UINTN NumberOfSenseKeys
;
863 InquiryDataLength
= sizeof (EFI_SCSI_INQUIRY_DATA
);
866 Status
= SubmitInquiryCommand (
867 ScsiDiskDevice
->ScsiIo
,
868 EfiScsiStallSeconds (1),
873 (VOID
*) &(ScsiDiskDevice
->InquiryData
),
877 if ((Status
== EFI_SUCCESS
) || (Status
== EFI_WARN_BUFFER_TOO_SMALL
)) {
879 // no need to check HostAdapterStatus and TargetStatus
881 ParseInquiryData (ScsiDiskDevice
);
883 } else if (Status
== EFI_NOT_READY
) {
885 // no need to check HostAdapterStatus and TargetStatus
888 return EFI_DEVICE_ERROR
;
889 } else if ((Status
== EFI_INVALID_PARAMETER
) || (Status
== EFI_UNSUPPORTED
)) {
891 // no need to check HostAdapterStatus and TargetStatus
894 return EFI_DEVICE_ERROR
;
897 // go ahead to check HostAdapterStatus and TargetStatus
898 // (EFI_TIMEOUT, EFI_DEVICE_ERROR)
900 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
901 if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
903 return EFI_DEVICE_ERROR
;
904 } else if (Status
== EFI_DEVICE_ERROR
) {
906 // reset the scsi channel
908 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
910 return EFI_DEVICE_ERROR
;
913 Status
= CheckTargetStatus (TargetStatus
);
914 if (Status
== EFI_NOT_READY
) {
916 // reset the scsi device
918 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
920 return EFI_DEVICE_ERROR
;
921 } else if (Status
== EFI_DEVICE_ERROR
) {
923 return EFI_DEVICE_ERROR
;
927 // if goes here, meant SubmitInquiryCommand() failed.
928 // if ScsiDiskRequestSenseKeys() succeeds at last,
929 // better retry SubmitInquiryCommand(). (by setting *NeedRetry = TRUE)
932 for (Index
= 0; Index
< MaxRetry
; Index
++) {
934 Status
= ScsiDiskRequestSenseKeys (
941 if (!EFI_ERROR (Status
)) {
943 return EFI_DEVICE_ERROR
;
947 return EFI_DEVICE_ERROR
;
951 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
952 // set *NeedRetry = FALSE to avoid the outside caller try again.
955 return EFI_DEVICE_ERROR
;
959 ScsiDiskTestUnitReady (
960 SCSI_DISK_DEV
*ScsiDiskDevice
,
962 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
963 UINTN
*NumberOfSenseKeys
965 // TODO: function comment should start with '/*++'
967 When Test Unit Ready command succeeds,
968 retrieve Sense Keys via Request Sense;
969 When Test Unit Ready command encounters any error caused by host adapter or
970 target, return error without retrieving Sense Keys.
972 // TODO: function comment should end with '--*/'
973 // TODO: function comment is missing 'Routine Description:'
974 // TODO: function comment is missing 'Arguments:'
975 // TODO: function comment is missing 'Returns:'
976 // TODO: ScsiDiskDevice - add argument and description to function comment
977 // TODO: NeedRetry - add argument and description to function comment
978 // TODO: SenseDataArray - add argument and description to function comment
979 // TODO: NumberOfSenseKeys - add argument and description to function comment
980 // TODO: EFI_DEVICE_ERROR - add return value to function comment
981 // TODO: EFI_DEVICE_ERROR - add return value to function comment
982 // TODO: EFI_DEVICE_ERROR - add return value to function comment
983 // TODO: EFI_DEVICE_ERROR - add return value to function comment
984 // TODO: EFI_DEVICE_ERROR - add return value to function comment
985 // TODO: EFI_DEVICE_ERROR - add return value to function comment
986 // TODO: EFI_SUCCESS - add return value to function comment
987 // TODO: EFI_DEVICE_ERROR - add return value to function comment
988 // TODO: EFI_DEVICE_ERROR - add return value to function comment
991 UINT8 SenseDataLength
;
992 UINT8 HostAdapterStatus
;
998 *NumberOfSenseKeys
= 0;
1001 // Parameter 3 and 4: do not require sense data, retrieve it when needed.
1003 Status
= SubmitTestUnitReadyCommand (
1004 ScsiDiskDevice
->ScsiIo
,
1005 EfiScsiStallSeconds (1),
1011 if (Status
== EFI_NOT_READY
) {
1013 // no need to check HostAdapterStatus and TargetStatus
1016 return EFI_DEVICE_ERROR
;
1017 } else if ((Status
== EFI_INVALID_PARAMETER
) || (Status
== EFI_UNSUPPORTED
)) {
1019 // no need to check HostAdapterStatus and TargetStatus
1022 return EFI_DEVICE_ERROR
;
1025 // go ahead to check HostAdapterStatus and TargetStatus
1027 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
1028 if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
1030 return EFI_DEVICE_ERROR
;
1031 } else if (Status
== EFI_DEVICE_ERROR
) {
1033 // reset the scsi channel
1035 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
1037 return EFI_DEVICE_ERROR
;
1040 Status
= CheckTargetStatus (TargetStatus
);
1041 if (Status
== EFI_NOT_READY
) {
1043 // reset the scsi device
1045 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1047 return EFI_DEVICE_ERROR
;
1048 } else if (Status
== EFI_DEVICE_ERROR
) {
1050 return EFI_DEVICE_ERROR
;
1054 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1056 Status
= ScsiDiskRequestSenseKeys (
1063 if (!EFI_ERROR (Status
)) {
1068 return EFI_DEVICE_ERROR
;
1072 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
1073 // set *NeedRetry = FALSE to avoid the outside caller try again.
1076 return EFI_DEVICE_ERROR
;
1080 DetectMediaParsingSenseKeys (
1081 SCSI_DISK_DEV
*ScsiDiskDevice
,
1082 EFI_SCSI_SENSE_DATA
*SenseData
,
1083 UINTN NumberOfSenseKeys
,
1088 Routine Description:
1090 TODO: Add function description
1094 ScsiDiskDevice - TODO: add argument description
1095 SenseData - TODO: add argument description
1096 NumberOfSenseKeys - TODO: add argument description
1097 Action - TODO: add argument description
1101 EFI_SUCCESS - TODO: Add description for return value
1102 EFI_SUCCESS - TODO: Add description for return value
1103 EFI_SUCCESS - TODO: Add description for return value
1104 EFI_SUCCESS - TODO: Add description for return value
1105 EFI_DEVICE_ERROR - TODO: Add description for return value
1106 EFI_DEVICE_ERROR - TODO: Add description for return value
1107 EFI_SUCCESS - TODO: Add description for return value
1108 EFI_DEVICE_ERROR - TODO: Add description for return value
1109 EFI_SUCCESS - TODO: Add description for return value
1116 // Default is to read capacity, unless..
1118 *Action
= ACTION_READ_CAPACITY
;
1120 if (NumberOfSenseKeys
== 0) {
1121 *Action
= ACTION_NO_ACTION
;
1125 if (!ScsiDiskHaveSenseKey (SenseData
, NumberOfSenseKeys
)) {
1127 // No Sense Key returned from last submitted command
1129 *Action
= ACTION_NO_ACTION
;
1133 if (ScsiDiskIsNoMedia (SenseData
, NumberOfSenseKeys
)) {
1134 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= FALSE
;
1135 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= 0;
1136 *Action
= ACTION_NO_ACTION
;
1140 if (ScsiDiskIsMediaChange (SenseData
, NumberOfSenseKeys
)) {
1141 ScsiDiskDevice
->BlkIo
.Media
->MediaId
++;
1145 if (ScsiDiskIsMediaError (SenseData
, NumberOfSenseKeys
)) {
1146 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= FALSE
;
1147 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= 0;
1148 return EFI_DEVICE_ERROR
;
1151 if (ScsiDiskIsHardwareError (SenseData
, NumberOfSenseKeys
)) {
1152 return EFI_DEVICE_ERROR
;
1155 if (!ScsiDiskIsDriveReady (SenseData
, NumberOfSenseKeys
, &RetryLater
)) {
1157 *Action
= ACTION_RETRY_COMMAND_LATER
;
1161 return EFI_DEVICE_ERROR
;
1168 ScsiDiskReadCapacity (
1169 SCSI_DISK_DEV
*ScsiDiskDevice
,
1171 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1172 UINTN
*NumberOfSenseKeys
1176 Routine Description:
1178 TODO: Add function description
1182 ScsiDiskDevice - TODO: add argument description
1183 NeedRetry - TODO: add argument description
1184 SenseDataArray - TODO: add argument description
1185 NumberOfSenseKeys - TODO: add argument description
1189 EFI_SUCCESS - TODO: Add description for return value
1190 EFI_DEVICE_ERROR - TODO: Add description for return value
1191 EFI_DEVICE_ERROR - TODO: Add description for return value
1192 EFI_DEVICE_ERROR - TODO: Add description for return value
1193 EFI_DEVICE_ERROR - TODO: Add description for return value
1194 EFI_DEVICE_ERROR - TODO: Add description for return value
1195 EFI_DEVICE_ERROR - TODO: Add description for return value
1196 EFI_DEVICE_ERROR - TODO: Add description for return value
1197 EFI_DEVICE_ERROR - TODO: Add description for return value
1198 EFI_DEVICE_ERROR - TODO: Add description for return value
1202 EFI_SCSI_DISK_CAPACITY_DATA CapacityData
;
1204 UINT8 HostAdapterStatus
;
1206 EFI_STATUS CommandStatus
;
1210 UINT8 SenseDataLength
;
1212 SenseDataLength
= 0;
1213 ZeroMem (&CapacityData
, sizeof (EFI_SCSI_DISK_CAPACITY_DATA
));
1214 DataLength
= sizeof (EFI_SCSI_DISK_CAPACITY_DATA
);
1216 *NumberOfSenseKeys
= 0;
1219 // submit Read Capacity Command. in this call,not request sense data
1221 CommandStatus
= SubmitReadCapacityCommand (
1222 ScsiDiskDevice
->ScsiIo
,
1223 EfiScsiStallSeconds (1),
1228 (VOID
*) &CapacityData
,
1232 if (CommandStatus
== EFI_SUCCESS
) {
1234 // no need to check HostAdapterStatus and TargetStatus
1236 GetMediaInfo (ScsiDiskDevice
, &CapacityData
);
1238 } else if (CommandStatus
== EFI_NOT_READY
) {
1240 // no need to check HostAdapterStatus and TargetStatus
1243 return EFI_DEVICE_ERROR
;
1244 } else if ((CommandStatus
== EFI_INVALID_PARAMETER
) || (CommandStatus
== EFI_UNSUPPORTED
)) {
1246 // no need to check HostAdapterStatus and TargetStatus
1249 return EFI_DEVICE_ERROR
;
1252 // go ahead to check HostAdapterStatus and TargetStatus
1253 // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)
1256 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
1257 if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
1259 return EFI_DEVICE_ERROR
;
1260 } else if (Status
== EFI_DEVICE_ERROR
) {
1262 // reset the scsi channel
1264 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
1266 return EFI_DEVICE_ERROR
;
1269 Status
= CheckTargetStatus (TargetStatus
);
1270 if (Status
== EFI_NOT_READY
) {
1272 // reset the scsi device
1274 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1276 return EFI_DEVICE_ERROR
;
1277 } else if (Status
== EFI_DEVICE_ERROR
) {
1279 return EFI_DEVICE_ERROR
;
1283 // if goes here, meant SubmitReadCapacityCommand() failed.
1284 // if ScsiDiskRequestSenseKeys() succeeds at last,
1285 // better retry SubmitReadCapacityCommand(). (by setting *NeedRetry = TRUE)
1288 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1290 Status
= ScsiDiskRequestSenseKeys (
1297 if (!EFI_ERROR (Status
)) {
1299 return EFI_DEVICE_ERROR
;
1303 return EFI_DEVICE_ERROR
;
1307 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
1308 // set *NeedRetry = FALSE to avoid the outside caller try again.
1311 return EFI_DEVICE_ERROR
;
1315 CheckHostAdapterStatus (
1316 UINT8 HostAdapterStatus
1320 Routine Description:
1322 TODO: Add function description
1326 HostAdapterStatus - TODO: add argument description
1330 EFI_SUCCESS - TODO: Add description for return value
1331 EFI_TIMEOUT - TODO: Add description for return value
1332 EFI_NOT_READY - TODO: Add description for return value
1333 EFI_DEVICE_ERROR - TODO: Add description for return value
1334 EFI_SUCCESS - TODO: Add description for return value
1338 switch (HostAdapterStatus
) {
1339 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK
:
1342 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT
:
1343 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT
:
1344 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND
:
1347 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT
:
1348 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR
:
1349 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED
:
1350 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN
:
1351 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET
:
1352 return EFI_NOT_READY
;
1354 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE
:
1355 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR
:
1356 return EFI_DEVICE_ERROR
;
1369 Routine Description:
1371 TODO: Add function description
1375 TargetStatus - TODO: add argument description
1379 EFI_SUCCESS - TODO: Add description for return value
1380 EFI_NOT_READY - TODO: Add description for return value
1381 EFI_DEVICE_ERROR - TODO: Add description for return value
1382 EFI_SUCCESS - TODO: Add description for return value
1386 switch (TargetStatus
) {
1387 case EFI_SCSI_IO_STATUS_TARGET_GOOD
:
1388 case EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION
:
1389 case EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET
:
1392 case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE
:
1393 case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET
:
1394 case EFI_SCSI_IO_STATUS_TARGET_BUSY
:
1395 case EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED
:
1396 case EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL
:
1397 return EFI_NOT_READY
;
1399 case EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT
:
1400 return EFI_DEVICE_ERROR
;
1409 ScsiDiskRequestSenseKeys (
1410 SCSI_DISK_DEV
*ScsiDiskDevice
,
1412 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1413 UINTN
*NumberOfSenseKeys
,
1414 BOOLEAN AskResetIfError
1416 // TODO: function comment should start with '/*++'
1418 Retrieve all sense keys from the device.
1419 When encountering error during the process,
1420 if retrieve sense keys before error encounterred,
1421 return the sense keys with return status set to EFI_SUCCESS,
1422 and NeedRetry set to FALSE; otherwize, return the proper return
1425 // TODO: function comment should end with '--*/'
1426 // TODO: function comment is missing 'Routine Description:'
1427 // TODO: function comment is missing 'Arguments:'
1428 // TODO: function comment is missing 'Returns:'
1429 // TODO: ScsiDiskDevice - add argument and description to function comment
1430 // TODO: NeedRetry - add argument and description to function comment
1431 // TODO: SenseDataArray - add argument and description to function comment
1432 // TODO: NumberOfSenseKeys - add argument and description to function comment
1433 // TODO: AskResetIfError - add argument and description to function comment
1434 // TODO: EFI_SUCCESS - add return value to function comment
1435 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1436 // TODO: EFI_SUCCESS - add return value to function comment
1438 EFI_SCSI_SENSE_DATA
*PtrSenseData
;
1439 UINT8 SenseDataLength
;
1442 EFI_STATUS FallStatus
;
1443 UINT8 HostAdapterStatus
;
1446 FallStatus
= EFI_SUCCESS
;
1447 SenseDataLength
= sizeof (EFI_SCSI_SENSE_DATA
);
1450 ScsiDiskDevice
->SenseData
,
1451 sizeof (EFI_SCSI_SENSE_DATA
) * (ScsiDiskDevice
->SenseDataNumber
)
1454 *NumberOfSenseKeys
= 0;
1455 *SenseDataArray
= ScsiDiskDevice
->SenseData
;
1456 PtrSenseData
= ScsiDiskDevice
->SenseData
;
1458 for (SenseReq
= TRUE
; SenseReq
;) {
1460 Status
= SubmitRequestSenseCommand (
1461 ScsiDiskDevice
->ScsiIo
,
1462 EfiScsiStallSeconds (2),
1468 if ((Status
== EFI_SUCCESS
) || (Status
== EFI_WARN_BUFFER_TOO_SMALL
)) {
1469 FallStatus
= EFI_SUCCESS
;
1470 } else if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
1472 FallStatus
= EFI_DEVICE_ERROR
;
1473 } else if ((Status
== EFI_INVALID_PARAMETER
) || (Status
== EFI_UNSUPPORTED
)) {
1475 FallStatus
= EFI_DEVICE_ERROR
;
1476 } else if (Status
== EFI_DEVICE_ERROR
) {
1477 if (AskResetIfError
) {
1478 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1481 FallStatus
= EFI_DEVICE_ERROR
;
1484 if (EFI_ERROR (FallStatus
)) {
1485 if (*NumberOfSenseKeys
!= 0) {
1489 return EFI_DEVICE_ERROR
;
1493 (*NumberOfSenseKeys
) += 1;
1496 // no more sense key or number of sense keys exceeds predefined,
1499 if ((PtrSenseData
->Sense_Key
== EFI_SCSI_SK_NO_SENSE
) ||
1500 (*NumberOfSenseKeys
== ScsiDiskDevice
->SenseDataNumber
)) {
1513 SCSI_DISK_DEV
*ScsiDiskDevice
,
1514 EFI_SCSI_DISK_CAPACITY_DATA
*Capacity
1518 Routine Description:
1520 TODO: Add function description
1524 ScsiDiskDevice - TODO: add argument description
1525 Capacity - TODO: add argument description
1529 TODO: add return values
1533 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= (Capacity
->LastLba3
<< 24) |
1534 (Capacity
->LastLba2
<< 16) |
1535 (Capacity
->LastLba1
<< 8) |
1538 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= TRUE
;
1539 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= (Capacity
->BlockSize3
<< 24) |
1540 (Capacity
->BlockSize2
<< 16) |
1541 (Capacity
->BlockSize1
<< 8) |
1542 Capacity
->BlockSize0
;
1543 if (ScsiDiskDevice
->DeviceType
== EFI_SCSI_TYPE_DISK
) {
1544 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x200;
1547 if (ScsiDiskDevice
->DeviceType
== EFI_SCSI_TYPE_CDROM
) {
1548 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x800;
1554 SCSI_DISK_DEV
*ScsiDiskDevice
1558 Routine Description:
1560 TODO: Add function description
1564 ScsiDiskDevice - TODO: add argument description
1568 TODO: add return values
1572 ScsiDiskDevice
->FixedDevice
= (BOOLEAN
) (ScsiDiskDevice
->InquiryData
.RMB
? 0 : 1);
1573 ScsiDiskDevice
->BlkIoMedia
.RemovableMedia
= (BOOLEAN
) (!ScsiDiskDevice
->FixedDevice
);
1577 ScsiDiskReadSectors (
1578 SCSI_DISK_DEV
*ScsiDiskDevice
,
1581 UINTN NumberOfBlocks
1585 Routine Description:
1587 TODO: Add function description
1591 ScsiDiskDevice - TODO: add argument description
1592 Buffer - TODO: add argument description
1593 Lba - TODO: add argument description
1594 NumberOfBlocks - TODO: add argument description
1598 EFI_DEVICE_ERROR - TODO: Add description for return value
1599 EFI_DEVICE_ERROR - TODO: Add description for return value
1600 EFI_SUCCESS - TODO: Add description for return value
1604 UINTN BlocksRemaining
;
1616 EFI_SCSI_SENSE_DATA
*SenseData
;
1617 UINTN NumberOfSenseKeys
;
1620 NumberOfSenseKeys
= 0;
1622 Status
= EFI_SUCCESS
;
1624 BlocksRemaining
= NumberOfBlocks
;
1625 BlockSize
= ScsiDiskDevice
->BlkIo
.Media
->BlockSize
;
1627 // limit the data bytes that can be transferred by one Read(10) Command
1632 Lba32
= (UINT32
) Lba
;
1634 while (BlocksRemaining
> 0) {
1636 if (BlocksRemaining
<= MaxBlock
) {
1638 SectorCount
= (UINT16
) BlocksRemaining
;
1641 SectorCount
= MaxBlock
;
1644 ByteCount
= SectorCount
* BlockSize
;
1645 Timeout
= EfiScsiStallSeconds (2);
1648 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1650 Status
= ScsiDiskRead10 (
1661 if (!EFI_ERROR (Status
)) {
1666 return EFI_DEVICE_ERROR
;
1671 if ((Index
== MaxRetry
) && (Status
!= EFI_SUCCESS
)) {
1672 return EFI_DEVICE_ERROR
;
1676 // actual transferred sectors
1678 SectorCount
= ByteCount
/ BlockSize
;
1680 Lba32
+= SectorCount
;
1681 PtrBuffer
= PtrBuffer
+ SectorCount
* BlockSize
;
1682 BlocksRemaining
-= SectorCount
;
1689 ScsiDiskWriteSectors (
1690 SCSI_DISK_DEV
*ScsiDiskDevice
,
1693 UINTN NumberOfBlocks
1697 Routine Description:
1699 TODO: Add function description
1703 ScsiDiskDevice - TODO: add argument description
1704 Buffer - TODO: add argument description
1705 Lba - TODO: add argument description
1706 NumberOfBlocks - TODO: add argument description
1710 EFI_DEVICE_ERROR - TODO: Add description for return value
1711 EFI_DEVICE_ERROR - TODO: Add description for return value
1712 EFI_SUCCESS - TODO: Add description for return value
1716 UINTN BlocksRemaining
;
1728 EFI_SCSI_SENSE_DATA
*SenseData
;
1729 UINTN NumberOfSenseKeys
;
1732 NumberOfSenseKeys
= 0;
1734 Status
= EFI_SUCCESS
;
1736 BlocksRemaining
= NumberOfBlocks
;
1737 BlockSize
= ScsiDiskDevice
->BlkIo
.Media
->BlockSize
;
1739 // limit the data bytes that can be transferred by one Write(10) Command
1744 Lba32
= (UINT32
) Lba
;
1746 while (BlocksRemaining
> 0) {
1748 if (BlocksRemaining
<= MaxBlock
) {
1750 SectorCount
= (UINT16
) BlocksRemaining
;
1753 SectorCount
= MaxBlock
;
1756 ByteCount
= SectorCount
* BlockSize
;
1757 Timeout
= EfiScsiStallSeconds (2);
1759 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1760 Status
= ScsiDiskWrite10 (
1771 if (!EFI_ERROR (Status
)) {
1776 return EFI_DEVICE_ERROR
;
1780 if ((Index
== MaxRetry
) && (Status
!= EFI_SUCCESS
)) {
1781 return EFI_DEVICE_ERROR
;
1784 // actual transferred sectors
1786 SectorCount
= ByteCount
/ BlockSize
;
1788 Lba32
+= SectorCount
;
1789 PtrBuffer
= PtrBuffer
+ SectorCount
* BlockSize
;
1790 BlocksRemaining
-= SectorCount
;
1798 SCSI_DISK_DEV
*ScsiDiskDevice
,
1800 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1801 UINTN
*NumberOfSenseKeys
,
1810 Routine Description:
1812 TODO: Add function description
1816 ScsiDiskDevice - TODO: add argument description
1817 NeedRetry - TODO: add argument description
1818 SenseDataArray - TODO: add argument description
1819 NumberOfSenseKeys - TODO: add argument description
1820 Timeout - TODO: add argument description
1821 DataBuffer - TODO: add argument description
1822 DataLength - TODO: add argument description
1823 StartLba - TODO: add argument description
1824 SectorSize - TODO: add argument description
1828 TODO: add return values
1832 UINT8 SenseDataLength
;
1834 UINT8 HostAdapterStatus
;
1838 *NumberOfSenseKeys
= 0;
1839 SenseDataLength
= 0;
1840 Status
= SubmitRead10Command (
1841 ScsiDiskDevice
->ScsiIo
,
1857 SCSI_DISK_DEV
*ScsiDiskDevice
,
1859 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1860 UINTN
*NumberOfSenseKeys
,
1869 Routine Description:
1871 TODO: Add function description
1875 ScsiDiskDevice - TODO: add argument description
1876 NeedRetry - TODO: add argument description
1877 SenseDataArray - TODO: add argument description
1878 NumberOfSenseKeys - TODO: add argument description
1879 Timeout - TODO: add argument description
1880 DataBuffer - TODO: add argument description
1881 DataLength - TODO: add argument description
1882 StartLba - TODO: add argument description
1883 SectorSize - TODO: add argument description
1887 TODO: add return values
1892 UINT8 SenseDataLength
;
1893 UINT8 HostAdapterStatus
;
1897 *NumberOfSenseKeys
= 0;
1898 SenseDataLength
= 0;
1899 Status
= SubmitWrite10Command (
1900 ScsiDiskDevice
->ScsiIo
,
1916 IN EFI_SCSI_SENSE_DATA
*SenseData
,
1917 IN UINTN SenseCounts
1921 Routine Description:
1923 TODO: Add function description
1927 SenseData - TODO: add argument description
1928 SenseCounts - TODO: add argument description
1932 TODO: add return values
1936 EFI_SCSI_SENSE_DATA
*SensePtr
;
1941 SensePtr
= SenseData
;
1943 for (Index
= 0; Index
< SenseCounts
; Index
++) {
1946 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2),
1947 // Additional Sense Code is ASC_NO_MEDIA (0x3A)
1949 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_NOT_READY
) &&
1950 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_NO_MEDIA
)) {
1961 ScsiDiskIsMediaError (
1962 IN EFI_SCSI_SENSE_DATA
*SenseData
,
1963 IN UINTN SenseCounts
1967 Routine Description:
1969 TODO: Add function description
1973 SenseData - TODO: add argument description
1974 SenseCounts - TODO: add argument description
1978 TODO: add return values
1982 EFI_SCSI_SENSE_DATA
*SensePtr
;
1987 SensePtr
= SenseData
;
1989 for (Index
= 0; Index
< SenseCounts
; Index
++) {
1991 switch (SensePtr
->Sense_Key
) {
1993 case EFI_SCSI_SK_MEDIUM_ERROR
:
1995 // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)
1997 switch (SensePtr
->Addnl_Sense_Code
) {
2002 case EFI_SCSI_ASC_MEDIA_ERR1
:
2007 case EFI_SCSI_ASC_MEDIA_ERR2
:
2012 case EFI_SCSI_ASC_MEDIA_ERR3
:
2013 case EFI_SCSI_ASC_MEDIA_ERR4
:
2023 case EFI_SCSI_SK_NOT_READY
:
2025 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
2027 switch (SensePtr
->Addnl_Sense_Code
) {
2029 // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)
2031 case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN
:
2051 ScsiDiskIsHardwareError (
2052 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2053 IN UINTN SenseCounts
2057 Routine Description:
2059 TODO: Add function description
2063 SenseData - TODO: add argument description
2064 SenseCounts - TODO: add argument description
2068 TODO: add return values
2072 EFI_SCSI_SENSE_DATA
*SensePtr
;
2077 SensePtr
= SenseData
;
2079 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2082 // Sense Key is EFI_SCSI_SK_HARDWARE_ERROR (0x4)
2084 if (SensePtr
->Sense_Key
== EFI_SCSI_SK_HARDWARE_ERROR
) {
2095 ScsiDiskIsMediaChange (
2096 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2097 IN UINTN SenseCounts
2101 Routine Description:
2103 TODO: Add function description
2107 SenseData - TODO: add argument description
2108 SenseCounts - TODO: add argument description
2112 TODO: add return values
2116 EFI_SCSI_SENSE_DATA
*SensePtr
;
2118 BOOLEAN IsMediaChanged
;
2120 IsMediaChanged
= FALSE
;
2121 SensePtr
= SenseData
;
2123 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2125 // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6),
2126 // Additional sense code is EFI_SCSI_ASC_MEDIA_CHANGE (0x28)
2128 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_UNIT_ATTENTION
) &&
2129 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_MEDIA_CHANGE
)) {
2130 IsMediaChanged
= TRUE
;
2136 return IsMediaChanged
;
2140 ScsiDiskIsResetBefore (
2141 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2142 IN UINTN SenseCounts
2146 Routine Description:
2148 TODO: Add function description
2152 SenseData - TODO: add argument description
2153 SenseCounts - TODO: add argument description
2157 TODO: add return values
2161 EFI_SCSI_SENSE_DATA
*SensePtr
;
2163 BOOLEAN IsResetBefore
;
2165 IsResetBefore
= FALSE
;
2166 SensePtr
= SenseData
;
2168 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2171 // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6)
2172 // Additional Sense Code is EFI_SCSI_ASC_RESET (0x29)
2174 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_UNIT_ATTENTION
) &&
2175 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_RESET
)) {
2176 IsResetBefore
= TRUE
;
2182 return IsResetBefore
;
2186 ScsiDiskIsDriveReady (
2187 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2188 IN UINTN SenseCounts
,
2189 OUT BOOLEAN
*RetryLater
2193 Routine Description:
2195 TODO: Add function description
2199 SenseData - TODO: add argument description
2200 SenseCounts - TODO: add argument description
2201 RetryLater - TODO: add argument description
2205 TODO: add return values
2209 EFI_SCSI_SENSE_DATA
*SensePtr
;
2214 *RetryLater
= FALSE
;
2215 SensePtr
= SenseData
;
2217 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2219 switch (SensePtr
->Sense_Key
) {
2221 case EFI_SCSI_SK_NOT_READY
:
2223 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
2225 switch (SensePtr
->Addnl_Sense_Code
) {
2226 case EFI_SCSI_ASC_NOT_READY
:
2228 // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)
2230 switch (SensePtr
->Addnl_Sense_Code_Qualifier
) {
2231 case EFI_SCSI_ASCQ_IN_PROGRESS
:
2233 // Additional Sense Code Qualifier is
2234 // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)
2242 *RetryLater
= FALSE
;
2263 ScsiDiskHaveSenseKey (
2264 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2265 IN UINTN SenseCounts
2269 Routine Description:
2271 TODO: Add function description
2275 SenseData - TODO: add argument description
2276 SenseCounts - TODO: add argument description
2280 TODO: add return values
2284 EFI_SCSI_SENSE_DATA
*SensePtr
;
2286 BOOLEAN HaveSenseKey
;
2288 if (SenseCounts
== 0) {
2289 HaveSenseKey
= FALSE
;
2291 HaveSenseKey
= TRUE
;
2294 SensePtr
= SenseData
;
2296 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2299 // Sense Key is SK_NO_SENSE (0x0)
2301 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_NO_SENSE
) &&
2303 HaveSenseKey
= FALSE
;
2309 return HaveSenseKey
;
2313 ReleaseScsiDiskDeviceResources (
2314 IN SCSI_DISK_DEV
*ScsiDiskDevice
2318 Routine Description:
2320 TODO: Add function description
2324 ScsiDiskDevice - TODO: add argument description
2328 TODO: add return values
2332 if (ScsiDiskDevice
== NULL
) {
2336 if (ScsiDiskDevice
->SenseData
!= NULL
) {
2337 gBS
->FreePool (ScsiDiskDevice
->SenseData
);
2338 ScsiDiskDevice
->SenseData
= NULL
;
2341 if (ScsiDiskDevice
->ControllerNameTable
!= NULL
) {
2342 FreeUnicodeStringTable (ScsiDiskDevice
->ControllerNameTable
);
2343 ScsiDiskDevice
->ControllerNameTable
= NULL
;
2346 gBS
->FreePool (ScsiDiskDevice
);
2348 ScsiDiskDevice
= NULL
;