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
),
879 // no need to check HostAdapterStatus and TargetStatus
882 case EFI_WARN_BUFFER_TOO_SMALL
:
883 ParseInquiryData (ScsiDiskDevice
);
888 return EFI_DEVICE_ERROR
;
890 case EFI_INVALID_PARAMETER
:
891 case EFI_UNSUPPORTED
:
893 return EFI_DEVICE_ERROR
;
896 // go ahead to check HostAdapterStatus and TargetStatus
897 // (EFI_TIMEOUT, EFI_DEVICE_ERROR)
903 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
911 return EFI_DEVICE_ERROR
;
913 case EFI_DEVICE_ERROR
:
915 // reset the scsi channel
917 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
919 return EFI_DEVICE_ERROR
;
922 Status
= CheckTargetStatus (TargetStatus
);
929 // reset the scsi device
931 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
933 return EFI_DEVICE_ERROR
;
935 case EFI_DEVICE_ERROR
:
937 return EFI_DEVICE_ERROR
;
941 // if goes here, meant SubmitInquiryCommand() failed.
942 // if ScsiDiskRequestSenseKeys() succeeds at last,
943 // better retry SubmitInquiryCommand(). (by setting *NeedRetry = TRUE)
946 for (Index
= 0; Index
< MaxRetry
; Index
++) {
948 Status
= ScsiDiskRequestSenseKeys (
955 if (!EFI_ERROR (Status
)) {
957 return EFI_DEVICE_ERROR
;
961 return EFI_DEVICE_ERROR
;
965 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
966 // set *NeedRetry = FALSE to avoid the outside caller try again.
969 return EFI_DEVICE_ERROR
;
973 ScsiDiskTestUnitReady (
974 SCSI_DISK_DEV
*ScsiDiskDevice
,
976 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
977 UINTN
*NumberOfSenseKeys
979 // TODO: function comment should start with '/*++'
981 When Test Unit Ready command succeeds,
982 retrieve Sense Keys via Request Sense;
983 When Test Unit Ready command encounters any error caused by host adapter or
984 target, return error without retrieving Sense Keys.
986 // TODO: function comment should end with '--*/'
987 // TODO: function comment is missing 'Routine Description:'
988 // TODO: function comment is missing 'Arguments:'
989 // TODO: function comment is missing 'Returns:'
990 // TODO: ScsiDiskDevice - add argument and description to function comment
991 // TODO: NeedRetry - add argument and description to function comment
992 // TODO: SenseDataArray - add argument and description to function comment
993 // TODO: NumberOfSenseKeys - add argument and description to function comment
994 // TODO: EFI_DEVICE_ERROR - add return value to function comment
995 // TODO: EFI_DEVICE_ERROR - add return value to function comment
996 // TODO: EFI_DEVICE_ERROR - add return value to function comment
997 // TODO: EFI_DEVICE_ERROR - add return value to function comment
998 // TODO: EFI_DEVICE_ERROR - add return value to function comment
999 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1000 // TODO: EFI_SUCCESS - add return value to function comment
1001 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1002 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1005 UINT8 SenseDataLength
;
1006 UINT8 HostAdapterStatus
;
1011 SenseDataLength
= 0;
1012 *NumberOfSenseKeys
= 0;
1015 // Parameter 3 and 4: do not require sense data, retrieve it when needed.
1017 Status
= SubmitTestUnitReadyCommand (
1018 ScsiDiskDevice
->ScsiIo
,
1019 EfiScsiStallSeconds (1),
1027 // no need to check HostAdapterStatus and TargetStatus
1031 return EFI_DEVICE_ERROR
;
1033 case EFI_INVALID_PARAMETER
:
1034 case EFI_UNSUPPORTED
:
1036 return EFI_DEVICE_ERROR
;
1039 // go ahead to check HostAdapterStatus and TargetStatus
1045 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
1053 return EFI_DEVICE_ERROR
;
1055 case EFI_DEVICE_ERROR
:
1057 // reset the scsi channel
1059 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
1061 return EFI_DEVICE_ERROR
;
1064 Status
= CheckTargetStatus (TargetStatus
);
1071 // reset the scsi device
1073 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1075 return EFI_DEVICE_ERROR
;
1077 case EFI_DEVICE_ERROR
:
1079 return EFI_DEVICE_ERROR
;
1083 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1085 Status
= ScsiDiskRequestSenseKeys (
1092 if (!EFI_ERROR (Status
)) {
1097 return EFI_DEVICE_ERROR
;
1101 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
1102 // set *NeedRetry = FALSE to avoid the outside caller try again.
1105 return EFI_DEVICE_ERROR
;
1109 DetectMediaParsingSenseKeys (
1110 SCSI_DISK_DEV
*ScsiDiskDevice
,
1111 EFI_SCSI_SENSE_DATA
*SenseData
,
1112 UINTN NumberOfSenseKeys
,
1117 Routine Description:
1119 TODO: Add function description
1123 ScsiDiskDevice - TODO: add argument description
1124 SenseData - TODO: add argument description
1125 NumberOfSenseKeys - TODO: add argument description
1126 Action - TODO: add argument description
1130 EFI_SUCCESS - TODO: Add description for return value
1131 EFI_SUCCESS - TODO: Add description for return value
1132 EFI_SUCCESS - TODO: Add description for return value
1133 EFI_SUCCESS - TODO: Add description for return value
1134 EFI_DEVICE_ERROR - TODO: Add description for return value
1135 EFI_DEVICE_ERROR - TODO: Add description for return value
1136 EFI_SUCCESS - TODO: Add description for return value
1137 EFI_DEVICE_ERROR - TODO: Add description for return value
1138 EFI_SUCCESS - TODO: Add description for return value
1145 // Default is to read capacity, unless..
1147 *Action
= ACTION_READ_CAPACITY
;
1149 if (NumberOfSenseKeys
== 0) {
1150 *Action
= ACTION_NO_ACTION
;
1154 if (!ScsiDiskHaveSenseKey (SenseData
, NumberOfSenseKeys
)) {
1156 // No Sense Key returned from last submitted command
1158 *Action
= ACTION_NO_ACTION
;
1162 if (ScsiDiskIsNoMedia (SenseData
, NumberOfSenseKeys
)) {
1163 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= FALSE
;
1164 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= 0;
1165 *Action
= ACTION_NO_ACTION
;
1169 if (ScsiDiskIsMediaChange (SenseData
, NumberOfSenseKeys
)) {
1170 ScsiDiskDevice
->BlkIo
.Media
->MediaId
++;
1174 if (ScsiDiskIsMediaError (SenseData
, NumberOfSenseKeys
)) {
1175 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= FALSE
;
1176 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= 0;
1177 return EFI_DEVICE_ERROR
;
1180 if (ScsiDiskIsHardwareError (SenseData
, NumberOfSenseKeys
)) {
1181 return EFI_DEVICE_ERROR
;
1184 if (!ScsiDiskIsDriveReady (SenseData
, NumberOfSenseKeys
, &RetryLater
)) {
1186 *Action
= ACTION_RETRY_COMMAND_LATER
;
1190 return EFI_DEVICE_ERROR
;
1197 ScsiDiskReadCapacity (
1198 SCSI_DISK_DEV
*ScsiDiskDevice
,
1200 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1201 UINTN
*NumberOfSenseKeys
1205 Routine Description:
1207 TODO: Add function description
1211 ScsiDiskDevice - TODO: add argument description
1212 NeedRetry - TODO: add argument description
1213 SenseDataArray - TODO: add argument description
1214 NumberOfSenseKeys - TODO: add argument description
1218 EFI_SUCCESS - TODO: Add description for return value
1219 EFI_DEVICE_ERROR - TODO: Add description for return value
1220 EFI_DEVICE_ERROR - TODO: Add description for return value
1221 EFI_DEVICE_ERROR - TODO: Add description for return value
1222 EFI_DEVICE_ERROR - TODO: Add description for return value
1223 EFI_DEVICE_ERROR - TODO: Add description for return value
1224 EFI_DEVICE_ERROR - TODO: Add description for return value
1225 EFI_DEVICE_ERROR - TODO: Add description for return value
1226 EFI_DEVICE_ERROR - TODO: Add description for return value
1227 EFI_DEVICE_ERROR - TODO: Add description for return value
1231 EFI_SCSI_DISK_CAPACITY_DATA CapacityData
;
1233 UINT8 HostAdapterStatus
;
1235 EFI_STATUS CommandStatus
;
1239 UINT8 SenseDataLength
;
1241 SenseDataLength
= 0;
1242 ZeroMem (&CapacityData
, sizeof (EFI_SCSI_DISK_CAPACITY_DATA
));
1243 DataLength
= sizeof (EFI_SCSI_DISK_CAPACITY_DATA
);
1245 *NumberOfSenseKeys
= 0;
1248 // submit Read Capacity Command. in this call,not request sense data
1250 CommandStatus
= SubmitReadCapacityCommand (
1251 ScsiDiskDevice
->ScsiIo
,
1252 EfiScsiStallSeconds (1),
1257 (VOID
*) &CapacityData
,
1261 switch (CommandStatus
) {
1263 // no need to check HostAdapterStatus and TargetStatus
1266 GetMediaInfo (ScsiDiskDevice
, &CapacityData
);
1271 return EFI_DEVICE_ERROR
;
1273 case EFI_INVALID_PARAMETER
:
1274 case EFI_UNSUPPORTED
:
1276 return EFI_DEVICE_ERROR
;
1279 // go ahead to check HostAdapterStatus and TargetStatus
1280 // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)
1286 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
1294 return EFI_DEVICE_ERROR
;
1296 case EFI_DEVICE_ERROR
:
1298 // reset the scsi channel
1300 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
1302 return EFI_DEVICE_ERROR
;
1305 Status
= CheckTargetStatus (TargetStatus
);
1312 // reset the scsi device
1314 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1316 return EFI_DEVICE_ERROR
;
1318 case EFI_DEVICE_ERROR
:
1320 return EFI_DEVICE_ERROR
;
1324 // if goes here, meant SubmitReadCapacityCommand() failed.
1325 // if ScsiDiskRequestSenseKeys() succeeds at last,
1326 // better retry SubmitReadCapacityCommand(). (by setting *NeedRetry = TRUE)
1329 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1331 Status
= ScsiDiskRequestSenseKeys (
1338 if (!EFI_ERROR (Status
)) {
1340 return EFI_DEVICE_ERROR
;
1344 return EFI_DEVICE_ERROR
;
1348 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
1349 // set *NeedRetry = FALSE to avoid the outside caller try again.
1352 return EFI_DEVICE_ERROR
;
1356 CheckHostAdapterStatus (
1357 UINT8 HostAdapterStatus
1361 Routine Description:
1363 TODO: Add function description
1367 HostAdapterStatus - TODO: add argument description
1371 EFI_SUCCESS - TODO: Add description for return value
1372 EFI_TIMEOUT - TODO: Add description for return value
1373 EFI_NOT_READY - TODO: Add description for return value
1374 EFI_DEVICE_ERROR - TODO: Add description for return value
1375 EFI_SUCCESS - TODO: Add description for return value
1379 switch (HostAdapterStatus
) {
1380 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK
:
1383 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT
:
1384 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT
:
1385 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND
:
1388 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT
:
1389 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR
:
1390 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED
:
1391 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN
:
1392 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET
:
1393 return EFI_NOT_READY
;
1395 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE
:
1396 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR
:
1397 return EFI_DEVICE_ERROR
;
1410 Routine Description:
1412 TODO: Add function description
1416 TargetStatus - TODO: add argument description
1420 EFI_SUCCESS - TODO: Add description for return value
1421 EFI_NOT_READY - TODO: Add description for return value
1422 EFI_DEVICE_ERROR - TODO: Add description for return value
1423 EFI_SUCCESS - TODO: Add description for return value
1427 switch (TargetStatus
) {
1428 case EFI_SCSI_IO_STATUS_TARGET_GOOD
:
1429 case EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION
:
1430 case EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET
:
1433 case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE
:
1434 case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET
:
1435 case EFI_SCSI_IO_STATUS_TARGET_BUSY
:
1436 case EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED
:
1437 case EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL
:
1438 return EFI_NOT_READY
;
1440 case EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT
:
1441 return EFI_DEVICE_ERROR
;
1450 ScsiDiskRequestSenseKeys (
1451 SCSI_DISK_DEV
*ScsiDiskDevice
,
1453 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1454 UINTN
*NumberOfSenseKeys
,
1455 BOOLEAN AskResetIfError
1457 // TODO: function comment should start with '/*++'
1459 Retrieve all sense keys from the device.
1460 When encountering error during the process,
1461 if retrieve sense keys before error encounterred,
1462 return the sense keys with return status set to EFI_SUCCESS,
1463 and NeedRetry set to FALSE; otherwize, return the proper return
1466 // TODO: function comment should end with '--*/'
1467 // TODO: function comment is missing 'Routine Description:'
1468 // TODO: function comment is missing 'Arguments:'
1469 // TODO: function comment is missing 'Returns:'
1470 // TODO: ScsiDiskDevice - add argument and description to function comment
1471 // TODO: NeedRetry - add argument and description to function comment
1472 // TODO: SenseDataArray - add argument and description to function comment
1473 // TODO: NumberOfSenseKeys - add argument and description to function comment
1474 // TODO: AskResetIfError - add argument and description to function comment
1475 // TODO: EFI_SUCCESS - add return value to function comment
1476 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1477 // TODO: EFI_SUCCESS - add return value to function comment
1479 EFI_SCSI_SENSE_DATA
*PtrSenseData
;
1480 UINT8 SenseDataLength
;
1483 EFI_STATUS FallStatus
;
1484 UINT8 HostAdapterStatus
;
1487 FallStatus
= EFI_SUCCESS
;
1488 SenseDataLength
= sizeof (EFI_SCSI_SENSE_DATA
);
1491 ScsiDiskDevice
->SenseData
,
1492 sizeof (EFI_SCSI_SENSE_DATA
) * (ScsiDiskDevice
->SenseDataNumber
)
1495 *NumberOfSenseKeys
= 0;
1496 *SenseDataArray
= ScsiDiskDevice
->SenseData
;
1497 PtrSenseData
= ScsiDiskDevice
->SenseData
;
1499 for (SenseReq
= TRUE
; SenseReq
;) {
1501 Status
= SubmitRequestSenseCommand (
1502 ScsiDiskDevice
->ScsiIo
,
1503 EfiScsiStallSeconds (2),
1516 case EFI_WARN_BUFFER_TOO_SMALL
:
1517 FallStatus
= EFI_SUCCESS
;
1527 FallStatus
= EFI_DEVICE_ERROR
;
1530 case EFI_INVALID_PARAMETER
:
1531 case EFI_UNSUPPORTED
:
1533 FallStatus
= EFI_DEVICE_ERROR
;
1536 case EFI_DEVICE_ERROR
:
1537 if (AskResetIfError
) {
1538 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1541 FallStatus
= EFI_DEVICE_ERROR
;
1545 if (EFI_ERROR (FallStatus
)) {
1546 if (*NumberOfSenseKeys
!= 0) {
1550 return EFI_DEVICE_ERROR
;
1554 (*NumberOfSenseKeys
) += 1;
1557 // no more sense key or number of sense keys exceeds predefined,
1560 if ((PtrSenseData
->Sense_Key
== EFI_SCSI_SK_NO_SENSE
) ||
1561 (*NumberOfSenseKeys
== ScsiDiskDevice
->SenseDataNumber
)) {
1574 SCSI_DISK_DEV
*ScsiDiskDevice
,
1575 EFI_SCSI_DISK_CAPACITY_DATA
*Capacity
1579 Routine Description:
1581 TODO: Add function description
1585 ScsiDiskDevice - TODO: add argument description
1586 Capacity - TODO: add argument description
1590 TODO: add return values
1594 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= (Capacity
->LastLba3
<< 24) |
1595 (Capacity
->LastLba2
<< 16) |
1596 (Capacity
->LastLba1
<< 8) |
1599 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= TRUE
;
1600 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= (Capacity
->BlockSize3
<< 24) |
1601 (Capacity
->BlockSize2
<< 16) |
1602 (Capacity
->BlockSize1
<< 8) |
1603 Capacity
->BlockSize0
;
1604 if (ScsiDiskDevice
->DeviceType
== EFI_SCSI_TYPE_DISK
) {
1605 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x200;
1608 if (ScsiDiskDevice
->DeviceType
== EFI_SCSI_TYPE_CDROM
) {
1609 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x800;
1615 SCSI_DISK_DEV
*ScsiDiskDevice
1619 Routine Description:
1621 TODO: Add function description
1625 ScsiDiskDevice - TODO: add argument description
1629 TODO: add return values
1633 ScsiDiskDevice
->FixedDevice
= (BOOLEAN
) (ScsiDiskDevice
->InquiryData
.RMB
? 0 : 1);
1634 ScsiDiskDevice
->BlkIoMedia
.RemovableMedia
= (BOOLEAN
) (!ScsiDiskDevice
->FixedDevice
);
1638 ScsiDiskReadSectors (
1639 SCSI_DISK_DEV
*ScsiDiskDevice
,
1642 UINTN NumberOfBlocks
1646 Routine Description:
1648 TODO: Add function description
1652 ScsiDiskDevice - TODO: add argument description
1653 Buffer - TODO: add argument description
1654 Lba - TODO: add argument description
1655 NumberOfBlocks - TODO: add argument description
1659 EFI_DEVICE_ERROR - TODO: Add description for return value
1660 EFI_DEVICE_ERROR - TODO: Add description for return value
1661 EFI_SUCCESS - TODO: Add description for return value
1665 UINTN BlocksRemaining
;
1677 EFI_SCSI_SENSE_DATA
*SenseData
;
1678 UINT8 SenseDataLength
;
1679 UINTN NumberOfSenseKeys
;
1682 SenseDataLength
= 0;
1683 NumberOfSenseKeys
= 0;
1685 Status
= EFI_SUCCESS
;
1687 BlocksRemaining
= NumberOfBlocks
;
1688 BlockSize
= ScsiDiskDevice
->BlkIo
.Media
->BlockSize
;
1690 // limit the data bytes that can be transferred by one Read(10) Command
1695 Lba32
= (UINT32
) Lba
;
1697 while (BlocksRemaining
> 0) {
1699 if (BlocksRemaining
<= MaxBlock
) {
1701 SectorCount
= (UINT16
) BlocksRemaining
;
1704 SectorCount
= MaxBlock
;
1707 ByteCount
= SectorCount
* BlockSize
;
1708 Timeout
= EfiScsiStallSeconds (2);
1711 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1713 Status
= ScsiDiskRead10 (
1724 if (!EFI_ERROR (Status
)) {
1729 return EFI_DEVICE_ERROR
;
1734 if ((Index
== MaxRetry
) && (Status
!= EFI_SUCCESS
)) {
1735 return EFI_DEVICE_ERROR
;
1739 // actual transferred sectors
1741 SectorCount
= ByteCount
/ BlockSize
;
1743 Lba32
+= SectorCount
;
1744 PtrBuffer
= PtrBuffer
+ SectorCount
* BlockSize
;
1745 BlocksRemaining
-= SectorCount
;
1752 ScsiDiskWriteSectors (
1753 SCSI_DISK_DEV
*ScsiDiskDevice
,
1756 UINTN NumberOfBlocks
1760 Routine Description:
1762 TODO: Add function description
1766 ScsiDiskDevice - TODO: add argument description
1767 Buffer - TODO: add argument description
1768 Lba - TODO: add argument description
1769 NumberOfBlocks - TODO: add argument description
1773 EFI_DEVICE_ERROR - TODO: Add description for return value
1774 EFI_DEVICE_ERROR - TODO: Add description for return value
1775 EFI_SUCCESS - TODO: Add description for return value
1779 UINTN BlocksRemaining
;
1791 EFI_SCSI_SENSE_DATA
*SenseData
;
1792 UINT8 SenseDataLength
;
1793 UINTN NumberOfSenseKeys
;
1796 SenseDataLength
= 0;
1797 NumberOfSenseKeys
= 0;
1799 Status
= EFI_SUCCESS
;
1801 BlocksRemaining
= NumberOfBlocks
;
1802 BlockSize
= ScsiDiskDevice
->BlkIo
.Media
->BlockSize
;
1804 // limit the data bytes that can be transferred by one Write(10) Command
1809 Lba32
= (UINT32
) Lba
;
1811 while (BlocksRemaining
> 0) {
1813 if (BlocksRemaining
<= MaxBlock
) {
1815 SectorCount
= (UINT16
) BlocksRemaining
;
1818 SectorCount
= MaxBlock
;
1821 ByteCount
= SectorCount
* BlockSize
;
1822 Timeout
= EfiScsiStallSeconds (2);
1824 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1825 Status
= ScsiDiskWrite10 (
1836 if (!EFI_ERROR (Status
)) {
1841 return EFI_DEVICE_ERROR
;
1845 if ((Index
== MaxRetry
) && (Status
!= EFI_SUCCESS
)) {
1846 return EFI_DEVICE_ERROR
;
1849 // actual transferred sectors
1851 SectorCount
= ByteCount
/ BlockSize
;
1853 Lba32
+= SectorCount
;
1854 PtrBuffer
= PtrBuffer
+ SectorCount
* BlockSize
;
1855 BlocksRemaining
-= SectorCount
;
1863 SCSI_DISK_DEV
*ScsiDiskDevice
,
1865 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1866 UINTN
*NumberOfSenseKeys
,
1875 Routine Description:
1877 TODO: Add function description
1881 ScsiDiskDevice - TODO: add argument description
1882 NeedRetry - TODO: add argument description
1883 SenseDataArray - TODO: add argument description
1884 NumberOfSenseKeys - TODO: add argument description
1885 Timeout - TODO: add argument description
1886 DataBuffer - TODO: add argument description
1887 DataLength - TODO: add argument description
1888 StartLba - TODO: add argument description
1889 SectorSize - TODO: add argument description
1893 TODO: add return values
1897 UINT8 SenseDataLength
;
1899 UINT8 HostAdapterStatus
;
1903 *NumberOfSenseKeys
= 0;
1904 SenseDataLength
= 0;
1905 Status
= SubmitRead10Command (
1906 ScsiDiskDevice
->ScsiIo
,
1922 SCSI_DISK_DEV
*ScsiDiskDevice
,
1924 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1925 UINTN
*NumberOfSenseKeys
,
1934 Routine Description:
1936 TODO: Add function description
1940 ScsiDiskDevice - TODO: add argument description
1941 NeedRetry - TODO: add argument description
1942 SenseDataArray - TODO: add argument description
1943 NumberOfSenseKeys - TODO: add argument description
1944 Timeout - TODO: add argument description
1945 DataBuffer - TODO: add argument description
1946 DataLength - TODO: add argument description
1947 StartLba - TODO: add argument description
1948 SectorSize - TODO: add argument description
1952 TODO: add return values
1957 UINT8 SenseDataLength
;
1958 UINT8 HostAdapterStatus
;
1962 *NumberOfSenseKeys
= 0;
1963 SenseDataLength
= 0;
1964 Status
= SubmitWrite10Command (
1965 ScsiDiskDevice
->ScsiIo
,
1981 IN EFI_SCSI_SENSE_DATA
*SenseData
,
1982 IN UINTN SenseCounts
1986 Routine Description:
1988 TODO: Add function description
1992 SenseData - TODO: add argument description
1993 SenseCounts - TODO: add argument description
1997 TODO: add return values
2001 EFI_SCSI_SENSE_DATA
*SensePtr
;
2006 SensePtr
= SenseData
;
2008 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2011 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2),
2012 // Additional Sense Code is ASC_NO_MEDIA (0x3A)
2014 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_NOT_READY
) &&
2015 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_NO_MEDIA
)) {
2026 ScsiDiskIsMediaError (
2027 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2028 IN UINTN SenseCounts
2032 Routine Description:
2034 TODO: Add function description
2038 SenseData - TODO: add argument description
2039 SenseCounts - TODO: add argument description
2043 TODO: add return values
2047 EFI_SCSI_SENSE_DATA
*SensePtr
;
2052 SensePtr
= SenseData
;
2054 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2056 switch (SensePtr
->Sense_Key
) {
2058 case EFI_SCSI_SK_MEDIUM_ERROR
:
2060 // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)
2062 switch (SensePtr
->Addnl_Sense_Code
) {
2067 case EFI_SCSI_ASC_MEDIA_ERR1
:
2072 case EFI_SCSI_ASC_MEDIA_ERR2
:
2077 case EFI_SCSI_ASC_MEDIA_ERR3
:
2078 case EFI_SCSI_ASC_MEDIA_ERR4
:
2088 case EFI_SCSI_SK_NOT_READY
:
2090 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
2092 switch (SensePtr
->Addnl_Sense_Code
) {
2094 // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)
2096 case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN
:
2116 ScsiDiskIsHardwareError (
2117 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2118 IN UINTN SenseCounts
2122 Routine Description:
2124 TODO: Add function description
2128 SenseData - TODO: add argument description
2129 SenseCounts - TODO: add argument description
2133 TODO: add return values
2137 EFI_SCSI_SENSE_DATA
*SensePtr
;
2142 SensePtr
= SenseData
;
2144 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2147 // Sense Key is EFI_SCSI_SK_HARDWARE_ERROR (0x4)
2149 if (SensePtr
->Sense_Key
== EFI_SCSI_SK_HARDWARE_ERROR
) {
2160 ScsiDiskIsMediaChange (
2161 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2162 IN UINTN SenseCounts
2166 Routine Description:
2168 TODO: Add function description
2172 SenseData - TODO: add argument description
2173 SenseCounts - TODO: add argument description
2177 TODO: add return values
2181 EFI_SCSI_SENSE_DATA
*SensePtr
;
2183 BOOLEAN IsMediaChanged
;
2185 IsMediaChanged
= FALSE
;
2186 SensePtr
= SenseData
;
2188 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2190 // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6),
2191 // Additional sense code is EFI_SCSI_ASC_MEDIA_CHANGE (0x28)
2193 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_UNIT_ATTENTION
) &&
2194 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_MEDIA_CHANGE
)) {
2195 IsMediaChanged
= TRUE
;
2201 return IsMediaChanged
;
2205 ScsiDiskIsResetBefore (
2206 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2207 IN UINTN SenseCounts
2211 Routine Description:
2213 TODO: Add function description
2217 SenseData - TODO: add argument description
2218 SenseCounts - TODO: add argument description
2222 TODO: add return values
2226 EFI_SCSI_SENSE_DATA
*SensePtr
;
2228 BOOLEAN IsResetBefore
;
2230 IsResetBefore
= FALSE
;
2231 SensePtr
= SenseData
;
2233 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2236 // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6)
2237 // Additional Sense Code is EFI_SCSI_ASC_RESET (0x29)
2239 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_UNIT_ATTENTION
) &&
2240 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_RESET
)) {
2241 IsResetBefore
= TRUE
;
2247 return IsResetBefore
;
2251 ScsiDiskIsDriveReady (
2252 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2253 IN UINTN SenseCounts
,
2254 OUT BOOLEAN
*RetryLater
2258 Routine Description:
2260 TODO: Add function description
2264 SenseData - TODO: add argument description
2265 SenseCounts - TODO: add argument description
2266 RetryLater - TODO: add argument description
2270 TODO: add return values
2274 EFI_SCSI_SENSE_DATA
*SensePtr
;
2279 *RetryLater
= FALSE
;
2280 SensePtr
= SenseData
;
2282 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2284 switch (SensePtr
->Sense_Key
) {
2286 case EFI_SCSI_SK_NOT_READY
:
2288 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
2290 switch (SensePtr
->Addnl_Sense_Code
) {
2291 case EFI_SCSI_ASC_NOT_READY
:
2293 // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)
2295 switch (SensePtr
->Addnl_Sense_Code_Qualifier
) {
2296 case EFI_SCSI_ASCQ_IN_PROGRESS
:
2298 // Additional Sense Code Qualifier is
2299 // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)
2307 *RetryLater
= FALSE
;
2328 ScsiDiskHaveSenseKey (
2329 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2330 IN UINTN SenseCounts
2334 Routine Description:
2336 TODO: Add function description
2340 SenseData - TODO: add argument description
2341 SenseCounts - TODO: add argument description
2345 TODO: add return values
2349 EFI_SCSI_SENSE_DATA
*SensePtr
;
2351 BOOLEAN HaveSenseKey
;
2353 if (SenseCounts
== 0) {
2354 HaveSenseKey
= FALSE
;
2356 HaveSenseKey
= TRUE
;
2359 SensePtr
= SenseData
;
2361 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2364 // Sense Key is SK_NO_SENSE (0x0)
2366 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_NO_SENSE
) &&
2368 HaveSenseKey
= FALSE
;
2374 return HaveSenseKey
;
2378 ReleaseScsiDiskDeviceResources (
2379 IN SCSI_DISK_DEV
*ScsiDiskDevice
2383 Routine Description:
2385 TODO: Add function description
2389 ScsiDiskDevice - TODO: add argument description
2393 TODO: add return values
2397 if (ScsiDiskDevice
== NULL
) {
2401 if (ScsiDiskDevice
->SenseData
!= NULL
) {
2402 gBS
->FreePool (ScsiDiskDevice
->SenseData
);
2403 ScsiDiskDevice
->SenseData
= NULL
;
2406 if (ScsiDiskDevice
->ControllerNameTable
!= NULL
) {
2407 FreeUnicodeStringTable (ScsiDiskDevice
->ControllerNameTable
);
2408 ScsiDiskDevice
->ControllerNameTable
= NULL
;
2411 gBS
->FreePool (ScsiDiskDevice
);
2413 ScsiDiskDevice
= NULL
;