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.
22 EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding
= {
23 ScsiDiskDriverBindingSupported
,
24 ScsiDiskDriverBindingStart
,
25 ScsiDiskDriverBindingStop
,
33 ScsiDiskDriverBindingSupported (
34 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
35 IN EFI_HANDLE Controller
,
36 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
47 // TODO: This - add argument and description to function comment
48 // TODO: Controller - add argument and description to function comment
49 // TODO: RemainingDevicePath - add argument and description to function comment
52 EFI_SCSI_IO_PROTOCOL
*ScsiIo
;
55 Status
= gBS
->OpenProtocol (
57 &gEfiScsiIoProtocolGuid
,
59 This
->DriverBindingHandle
,
61 EFI_OPEN_PROTOCOL_BY_DRIVER
63 if (EFI_ERROR (Status
)) {
67 Status
= ScsiIo
->GetDeviceType (ScsiIo
, &DeviceType
);
68 if (!EFI_ERROR (Status
)) {
69 if ((DeviceType
== EFI_SCSI_TYPE_DISK
) || (DeviceType
== EFI_SCSI_TYPE_CDROM
)) {
72 Status
= EFI_UNSUPPORTED
;
78 &gEfiScsiIoProtocolGuid
,
79 This
->DriverBindingHandle
,
87 ScsiDiskDriverBindingStart (
88 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
89 IN EFI_HANDLE Controller
,
90 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
101 // TODO: This - add argument and description to function comment
102 // TODO: Controller - add argument and description to function comment
103 // TODO: RemainingDevicePath - add argument and description to function comment
104 // TODO: EFI_DEVICE_ERROR - add return value to function comment
105 // TODO: EFI_SUCCESS - add return value to function comment
108 EFI_SCSI_IO_PROTOCOL
*ScsiIo
;
109 SCSI_DISK_DEV
*ScsiDiskDevice
;
115 Status
= gBS
->AllocatePool (
117 sizeof (SCSI_DISK_DEV
),
118 (VOID
**) &ScsiDiskDevice
120 if (EFI_ERROR (Status
)) {
124 ZeroMem (ScsiDiskDevice
, sizeof (SCSI_DISK_DEV
));
126 Status
= gBS
->OpenProtocol (
128 &gEfiScsiIoProtocolGuid
,
130 This
->DriverBindingHandle
,
132 EFI_OPEN_PROTOCOL_BY_DRIVER
134 if (EFI_ERROR (Status
)) {
135 gBS
->FreePool (ScsiDiskDevice
);
139 ScsiDiskDevice
->Signature
= SCSI_DISK_DEV_SIGNATURE
;
140 ScsiDiskDevice
->ScsiIo
= ScsiIo
;
141 ScsiDiskDevice
->BlkIo
.Media
= &ScsiDiskDevice
->BlkIoMedia
;
142 ScsiDiskDevice
->BlkIo
.Reset
= ScsiDiskReset
;
143 ScsiDiskDevice
->BlkIo
.ReadBlocks
= ScsiDiskReadBlocks
;
144 ScsiDiskDevice
->BlkIo
.WriteBlocks
= ScsiDiskWriteBlocks
;
145 ScsiDiskDevice
->BlkIo
.FlushBlocks
= ScsiDiskFlushBlocks
;
146 ScsiDiskDevice
->Handle
= Controller
;
148 ScsiIo
->GetDeviceType (ScsiIo
, &(ScsiDiskDevice
->DeviceType
));
149 switch (ScsiDiskDevice
->DeviceType
) {
150 case EFI_SCSI_TYPE_DISK
:
151 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x200;
154 case EFI_SCSI_TYPE_CDROM
:
155 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x800;
159 // The Sense Data Array's initial size is 6
161 ScsiDiskDevice
->SenseDataNumber
= 6;
162 Status
= gBS
->AllocatePool (
164 sizeof (EFI_SCSI_SENSE_DATA
) * ScsiDiskDevice
->SenseDataNumber
,
165 (VOID
**) &(ScsiDiskDevice
->SenseData
)
167 if (EFI_ERROR (Status
)) {
170 &gEfiScsiIoProtocolGuid
,
171 This
->DriverBindingHandle
,
174 gBS
->FreePool (ScsiDiskDevice
);
179 ScsiDiskDevice
->SenseData
,
180 sizeof (EFI_SCSI_SENSE_DATA
) * ScsiDiskDevice
->SenseDataNumber
184 // Retrive device information
187 for (Index
= 0; Index
< MaxRetry
; Index
++) {
188 Status
= ScsiDiskInquiryDevice (ScsiDiskDevice
, &NeedRetry
);
189 if (!EFI_ERROR (Status
)) {
194 gBS
->FreePool (ScsiDiskDevice
->SenseData
);
197 &gEfiScsiIoProtocolGuid
,
198 This
->DriverBindingHandle
,
201 gBS
->FreePool (ScsiDiskDevice
);
202 return EFI_DEVICE_ERROR
;
206 // The second parameter "TRUE" means must
207 // retrieve media capacity
209 Status
= ScsiDiskDetectMedia (ScsiDiskDevice
, TRUE
, &Temp
);
210 if (!EFI_ERROR (Status
)) {
211 Status
= gBS
->InstallMultipleProtocolInterfaces (
213 &gEfiBlockIoProtocolGuid
,
214 &ScsiDiskDevice
->BlkIo
,
219 if (EFI_ERROR (Status
)) {
220 gBS
->FreePool (ScsiDiskDevice
->SenseData
);
223 &gEfiScsiIoProtocolGuid
,
224 This
->DriverBindingHandle
,
227 gBS
->FreePool (ScsiDiskDevice
);
231 ScsiDiskDevice
->ControllerNameTable
= NULL
;
234 gScsiDiskComponentName
.SupportedLanguages
,
235 &ScsiDiskDevice
->ControllerNameTable
,
236 (CHAR16
*) L
"SCSI Disk Device"
245 ScsiDiskDriverBindingStop (
246 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
247 IN EFI_HANDLE Controller
,
248 IN UINTN NumberOfChildren
,
249 IN EFI_HANDLE
*ChildHandleBuffer
260 // TODO: This - add argument and description to function comment
261 // TODO: Controller - add argument and description to function comment
262 // TODO: NumberOfChildren - add argument and description to function comment
263 // TODO: ChildHandleBuffer - add argument and description to function comment
264 // TODO: EFI_SUCCESS - add return value to function comment
266 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
267 SCSI_DISK_DEV
*ScsiDiskDevice
;
270 Status
= gBS
->OpenProtocol (
272 &gEfiBlockIoProtocolGuid
,
274 This
->DriverBindingHandle
,
276 EFI_OPEN_PROTOCOL_GET_PROTOCOL
278 if (EFI_ERROR (Status
)) {
282 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (BlkIo
);
283 Status
= gBS
->UninstallProtocolInterface (
285 &gEfiBlockIoProtocolGuid
,
286 &ScsiDiskDevice
->BlkIo
288 if (!EFI_ERROR (Status
)) {
291 &gEfiScsiIoProtocolGuid
,
292 This
->DriverBindingHandle
,
296 ReleaseScsiDiskDeviceResources (ScsiDiskDevice
);
307 // Block I/O Protocol Interface
313 IN EFI_BLOCK_IO_PROTOCOL
*This
,
314 IN BOOLEAN ExtendedVerification
320 TODO: Add function description
324 This - TODO: add argument description
325 ExtendedVerification - TODO: add argument description
329 TODO: add return values
333 SCSI_DISK_DEV
*ScsiDiskDevice
;
336 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (This
);
338 Status
= ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
340 if (!ExtendedVerification
) {
344 Status
= ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
352 IN EFI_BLOCK_IO_PROTOCOL
*This
,
362 TODO: Add function description
366 This - TODO: add argument description
367 MediaId - TODO: add argument description
368 LBA - TODO: add argument description
369 BufferSize - TODO: add argument description
370 Buffer - TODO: add argument description
374 EFI_INVALID_PARAMETER - TODO: Add description for return value
375 EFI_SUCCESS - TODO: Add description for return value
376 EFI_DEVICE_ERROR - TODO: Add description for return value
377 EFI_NO_MEDIA - TODO: Add description for return value
378 EFI_MEDIA_CHANGED - TODO: Add description for return value
379 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
380 EFI_INVALID_PARAMETER - TODO: Add description for return value
381 EFI_INVALID_PARAMETER - TODO: Add description for return value
382 EFI_INVALID_PARAMETER - TODO: Add description for return value
386 SCSI_DISK_DEV
*ScsiDiskDevice
;
387 EFI_BLOCK_IO_MEDIA
*Media
;
390 UINTN NumberOfBlocks
;
395 return EFI_INVALID_PARAMETER
;
398 if (BufferSize
== 0) {
402 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (This
);
404 if (!IsDeviceFixed (ScsiDiskDevice
)) {
406 Status
= ScsiDiskDetectMedia (ScsiDiskDevice
, FALSE
, &MediaChange
);
407 if (EFI_ERROR (Status
)) {
408 return EFI_DEVICE_ERROR
;
412 gBS
->ReinstallProtocolInterface (
413 ScsiDiskDevice
->Handle
,
414 &gEfiBlockIoProtocolGuid
,
415 &ScsiDiskDevice
->BlkIo
,
416 &ScsiDiskDevice
->BlkIo
421 // Get the intrinsic block size
423 Media
= ScsiDiskDevice
->BlkIo
.Media
;
424 BlockSize
= Media
->BlockSize
;
426 NumberOfBlocks
= BufferSize
/ BlockSize
;
428 if (!(Media
->MediaPresent
)) {
432 if (MediaId
!= Media
->MediaId
) {
433 return EFI_MEDIA_CHANGED
;
436 if (BufferSize
% BlockSize
!= 0) {
437 return EFI_BAD_BUFFER_SIZE
;
440 if (LBA
> Media
->LastBlock
) {
441 return EFI_INVALID_PARAMETER
;
444 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
445 return EFI_INVALID_PARAMETER
;
448 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
449 return EFI_INVALID_PARAMETER
;
453 // if all the parameters are valid, then perform read sectors command
454 // to transfer data from device to host.
456 Status
= ScsiDiskReadSectors (ScsiDiskDevice
, Buffer
, LBA
, NumberOfBlocks
);
463 ScsiDiskWriteBlocks (
464 IN EFI_BLOCK_IO_PROTOCOL
*This
,
474 TODO: Add function description
478 This - TODO: add argument description
479 MediaId - TODO: add argument description
480 LBA - TODO: add argument description
481 BufferSize - TODO: add argument description
482 Buffer - TODO: add argument description
486 EFI_INVALID_PARAMETER - TODO: Add description for return value
487 EFI_SUCCESS - TODO: Add description for return value
488 EFI_DEVICE_ERROR - TODO: Add description for return value
489 EFI_NO_MEDIA - TODO: Add description for return value
490 EFI_MEDIA_CHANGED - TODO: Add description for return value
491 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
492 EFI_INVALID_PARAMETER - TODO: Add description for return value
493 EFI_INVALID_PARAMETER - TODO: Add description for return value
494 EFI_INVALID_PARAMETER - TODO: Add description for return value
498 SCSI_DISK_DEV
*ScsiDiskDevice
;
499 EFI_BLOCK_IO_MEDIA
*Media
;
502 UINTN NumberOfBlocks
;
507 return EFI_INVALID_PARAMETER
;
510 if (BufferSize
== 0) {
514 ScsiDiskDevice
= SCSI_DISK_DEV_FROM_THIS (This
);
516 if (!IsDeviceFixed (ScsiDiskDevice
)) {
518 Status
= ScsiDiskDetectMedia (ScsiDiskDevice
, FALSE
, &MediaChange
);
519 if (EFI_ERROR (Status
)) {
520 return EFI_DEVICE_ERROR
;
524 gBS
->ReinstallProtocolInterface (
525 ScsiDiskDevice
->Handle
,
526 &gEfiBlockIoProtocolGuid
,
527 &ScsiDiskDevice
->BlkIo
,
528 &ScsiDiskDevice
->BlkIo
533 // Get the intrinsic block size
535 Media
= ScsiDiskDevice
->BlkIo
.Media
;
536 BlockSize
= Media
->BlockSize
;
538 NumberOfBlocks
= BufferSize
/ BlockSize
;
540 if (!(Media
->MediaPresent
)) {
544 if (MediaId
!= Media
->MediaId
) {
545 return EFI_MEDIA_CHANGED
;
548 if (BufferSize
% BlockSize
!= 0) {
549 return EFI_BAD_BUFFER_SIZE
;
552 if (LBA
> Media
->LastBlock
) {
553 return EFI_INVALID_PARAMETER
;
556 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
557 return EFI_INVALID_PARAMETER
;
560 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
561 return EFI_INVALID_PARAMETER
;
564 // if all the parameters are valid, then perform read sectors command
565 // to transfer data from device to host.
567 Status
= ScsiDiskWriteSectors (ScsiDiskDevice
, Buffer
, LBA
, NumberOfBlocks
);
574 ScsiDiskFlushBlocks (
575 IN EFI_BLOCK_IO_PROTOCOL
*This
581 TODO: Add function description
585 This - TODO: add argument description
589 EFI_SUCCESS - TODO: Add description for return value
600 ScsiDiskDetectMedia (
601 SCSI_DISK_DEV
*ScsiDiskDevice
,
602 BOOLEAN MustReadCapacity
,
609 TODO: Add function description
613 ScsiDiskDevice - TODO: add argument description
614 MustReadCapacity - TODO: add argument description
615 MediaChange - TODO: add argument description
619 EFI_DEVICE_ERROR - TODO: Add description for return value
620 EFI_DEVICE_ERROR - TODO: Add description for return value
621 EFI_DEVICE_ERROR - TODO: Add description for return value
622 EFI_SUCCESS - TODO: Add description for return value
627 EFI_STATUS ReadCapacityStatus
;
628 EFI_SCSI_SENSE_DATA
*SenseData
;
629 UINTN NumberOfSenseKeys
;
631 BOOLEAN NeedReadCapacity
;
634 EFI_BLOCK_IO_MEDIA OldMedia
;
637 Status
= EFI_SUCCESS
;
638 ReadCapacityStatus
= EFI_SUCCESS
;
640 NumberOfSenseKeys
= 0;
641 NeedReadCapacity
= FALSE
;
642 CopyMem (&OldMedia
, ScsiDiskDevice
->BlkIo
.Media
, sizeof (OldMedia
));
643 // OldMedia = *(ScsiDiskDevice->BlkIo.Media);
645 *MediaChange
= FALSE
;
648 for (Index
= 0; Index
< MaxRetry
; Index
++) {
649 Status
= ScsiDiskTestUnitReady (
655 if (!EFI_ERROR (Status
)) {
664 if ((Index
== MaxRetry
) && EFI_ERROR (Status
)) {
665 return EFI_DEVICE_ERROR
;
668 Status
= DetectMediaParsingSenseKeys (
674 if (EFI_ERROR (Status
)) {
678 // ACTION_NO_ACTION: need not read capacity
679 // other action code: need read capacity
681 if (Action
== ACTION_NO_ACTION
) {
682 NeedReadCapacity
= FALSE
;
684 NeedReadCapacity
= TRUE
;
688 // either NeedReadCapacity is TRUE, or MustReadCapacity is TRUE,
689 // retrieve capacity via Read Capacity command
691 if (NeedReadCapacity
|| MustReadCapacity
) {
694 // retrieve media information
697 for (Index
= 0; Index
< MaxRetry
; Index
++) {
699 ReadCapacityStatus
= ScsiDiskReadCapacity (
705 if (EFI_ERROR (ReadCapacityStatus
) && !NeedRetry
) {
706 return EFI_DEVICE_ERROR
;
709 // analyze sense key to action
711 Status
= DetectMediaParsingSenseKeys (
718 // if Status is error, it may indicate crisis error,
719 // so return without retry.
721 if (EFI_ERROR (Status
)) {
726 case ACTION_NO_ACTION
:
733 case ACTION_RETRY_COMMAND_LATER
:
735 // retry the ReadCapacity later and continuously, until the condition
736 // no longer emerges.
737 // stall time is 100000us, or say 0.1 second.
745 // other cases, just retry the command
751 if ((Index
== MaxRetry
) && EFI_ERROR (ReadCapacityStatus
)) {
752 return EFI_DEVICE_ERROR
;
756 if (ScsiDiskDevice
->BlkIo
.Media
->MediaId
!= OldMedia
.MediaId
) {
758 // Media change information got from the device
763 if (ScsiDiskDevice
->BlkIo
.Media
->ReadOnly
!= OldMedia
.ReadOnly
) {
765 ScsiDiskDevice
->BlkIo
.Media
->MediaId
+= 1;
768 if (ScsiDiskDevice
->BlkIo
.Media
->BlockSize
!= OldMedia
.BlockSize
) {
770 ScsiDiskDevice
->BlkIo
.Media
->MediaId
+= 1;
773 if (ScsiDiskDevice
->BlkIo
.Media
->LastBlock
!= OldMedia
.LastBlock
) {
775 ScsiDiskDevice
->BlkIo
.Media
->MediaId
+= 1;
778 if (ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
!= OldMedia
.MediaPresent
) {
779 if (ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
) {
781 // when change from no media to media present, reset the MediaId to 1.
783 ScsiDiskDevice
->BlkIo
.Media
->MediaId
= 1;
786 // when no media, reset the MediaId to zero.
788 ScsiDiskDevice
->BlkIo
.Media
->MediaId
= 0;
798 ScsiDiskInquiryDevice (
799 SCSI_DISK_DEV
*ScsiDiskDevice
,
806 TODO: Add function description
810 ScsiDiskDevice - TODO: add argument description
811 NeedRetry - TODO: add argument description
815 EFI_SUCCESS - TODO: Add description for return value
816 EFI_DEVICE_ERROR - TODO: Add description for return value
817 EFI_DEVICE_ERROR - TODO: Add description for return value
818 EFI_DEVICE_ERROR - TODO: Add description for return value
819 EFI_DEVICE_ERROR - TODO: Add description for return value
820 EFI_DEVICE_ERROR - TODO: Add description for return value
821 EFI_DEVICE_ERROR - TODO: Add description for return value
822 EFI_DEVICE_ERROR - TODO: Add description for return value
823 EFI_DEVICE_ERROR - TODO: Add description for return value
824 EFI_DEVICE_ERROR - TODO: Add description for return value
828 UINT32 InquiryDataLength
;
829 UINT8 SenseDataLength
;
830 UINT8 HostAdapterStatus
;
832 EFI_SCSI_SENSE_DATA
*SenseDataArray
;
833 UINTN NumberOfSenseKeys
;
838 InquiryDataLength
= sizeof (EFI_SCSI_INQUIRY_DATA
);
841 Status
= SubmitInquiryCommand (
842 ScsiDiskDevice
->ScsiIo
,
843 EfiScsiStallSeconds (1),
848 (VOID
*) &(ScsiDiskDevice
->InquiryData
),
852 if ((Status
== EFI_SUCCESS
) || (Status
== EFI_WARN_BUFFER_TOO_SMALL
)) {
854 // no need to check HostAdapterStatus and TargetStatus
856 ParseInquiryData (ScsiDiskDevice
);
858 } else if (Status
== EFI_NOT_READY
) {
860 // no need to check HostAdapterStatus and TargetStatus
863 return EFI_DEVICE_ERROR
;
864 } else if ((Status
== EFI_INVALID_PARAMETER
) || (Status
== EFI_UNSUPPORTED
)) {
866 // no need to check HostAdapterStatus and TargetStatus
869 return EFI_DEVICE_ERROR
;
872 // go ahead to check HostAdapterStatus and TargetStatus
873 // (EFI_TIMEOUT, EFI_DEVICE_ERROR)
875 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
876 if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
878 return EFI_DEVICE_ERROR
;
879 } else if (Status
== EFI_DEVICE_ERROR
) {
881 // reset the scsi channel
883 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
885 return EFI_DEVICE_ERROR
;
888 Status
= CheckTargetStatus (TargetStatus
);
889 if (Status
== EFI_NOT_READY
) {
891 // reset the scsi device
893 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
895 return EFI_DEVICE_ERROR
;
896 } else if (Status
== EFI_DEVICE_ERROR
) {
898 return EFI_DEVICE_ERROR
;
902 // if goes here, meant SubmitInquiryCommand() failed.
903 // if ScsiDiskRequestSenseKeys() succeeds at last,
904 // better retry SubmitInquiryCommand(). (by setting *NeedRetry = TRUE)
907 for (Index
= 0; Index
< MaxRetry
; Index
++) {
909 Status
= ScsiDiskRequestSenseKeys (
916 if (!EFI_ERROR (Status
)) {
918 return EFI_DEVICE_ERROR
;
922 return EFI_DEVICE_ERROR
;
926 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
927 // set *NeedRetry = FALSE to avoid the outside caller try again.
930 return EFI_DEVICE_ERROR
;
934 ScsiDiskTestUnitReady (
935 SCSI_DISK_DEV
*ScsiDiskDevice
,
937 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
938 UINTN
*NumberOfSenseKeys
940 // TODO: function comment should start with '/*++'
942 When Test Unit Ready command succeeds,
943 retrieve Sense Keys via Request Sense;
944 When Test Unit Ready command encounters any error caused by host adapter or
945 target, return error without retrieving Sense Keys.
947 // TODO: function comment should end with '--*/'
948 // TODO: function comment is missing 'Routine Description:'
949 // TODO: function comment is missing 'Arguments:'
950 // TODO: function comment is missing 'Returns:'
951 // TODO: ScsiDiskDevice - add argument and description to function comment
952 // TODO: NeedRetry - add argument and description to function comment
953 // TODO: SenseDataArray - add argument and description to function comment
954 // TODO: NumberOfSenseKeys - add argument and description to function comment
955 // TODO: EFI_DEVICE_ERROR - add return value to function comment
956 // TODO: EFI_DEVICE_ERROR - add return value to function comment
957 // TODO: EFI_DEVICE_ERROR - add return value to function comment
958 // TODO: EFI_DEVICE_ERROR - add return value to function comment
959 // TODO: EFI_DEVICE_ERROR - add return value to function comment
960 // TODO: EFI_DEVICE_ERROR - add return value to function comment
961 // TODO: EFI_SUCCESS - add return value to function comment
962 // TODO: EFI_DEVICE_ERROR - add return value to function comment
963 // TODO: EFI_DEVICE_ERROR - add return value to function comment
966 UINT8 SenseDataLength
;
967 UINT8 HostAdapterStatus
;
973 *NumberOfSenseKeys
= 0;
976 // Parameter 3 and 4: do not require sense data, retrieve it when needed.
978 Status
= SubmitTestUnitReadyCommand (
979 ScsiDiskDevice
->ScsiIo
,
980 EfiScsiStallSeconds (1),
986 if (Status
== EFI_NOT_READY
) {
988 // no need to check HostAdapterStatus and TargetStatus
991 return EFI_DEVICE_ERROR
;
992 } else if ((Status
== EFI_INVALID_PARAMETER
) || (Status
== EFI_UNSUPPORTED
)) {
994 // no need to check HostAdapterStatus and TargetStatus
997 return EFI_DEVICE_ERROR
;
1000 // go ahead to check HostAdapterStatus and TargetStatus
1002 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
1003 if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
1005 return EFI_DEVICE_ERROR
;
1006 } else if (Status
== EFI_DEVICE_ERROR
) {
1008 // reset the scsi channel
1010 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
1012 return EFI_DEVICE_ERROR
;
1015 Status
= CheckTargetStatus (TargetStatus
);
1016 if (Status
== EFI_NOT_READY
) {
1018 // reset the scsi device
1020 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1022 return EFI_DEVICE_ERROR
;
1023 } else if (Status
== EFI_DEVICE_ERROR
) {
1025 return EFI_DEVICE_ERROR
;
1029 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1031 Status
= ScsiDiskRequestSenseKeys (
1038 if (!EFI_ERROR (Status
)) {
1043 return EFI_DEVICE_ERROR
;
1047 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
1048 // set *NeedRetry = FALSE to avoid the outside caller try again.
1051 return EFI_DEVICE_ERROR
;
1055 DetectMediaParsingSenseKeys (
1056 SCSI_DISK_DEV
*ScsiDiskDevice
,
1057 EFI_SCSI_SENSE_DATA
*SenseData
,
1058 UINTN NumberOfSenseKeys
,
1063 Routine Description:
1065 TODO: Add function description
1069 ScsiDiskDevice - TODO: add argument description
1070 SenseData - TODO: add argument description
1071 NumberOfSenseKeys - TODO: add argument description
1072 Action - TODO: add argument description
1076 EFI_SUCCESS - TODO: Add description for return value
1077 EFI_SUCCESS - TODO: Add description for return value
1078 EFI_SUCCESS - TODO: Add description for return value
1079 EFI_SUCCESS - TODO: Add description for return value
1080 EFI_DEVICE_ERROR - TODO: Add description for return value
1081 EFI_DEVICE_ERROR - TODO: Add description for return value
1082 EFI_SUCCESS - TODO: Add description for return value
1083 EFI_DEVICE_ERROR - TODO: Add description for return value
1084 EFI_SUCCESS - TODO: Add description for return value
1091 // Default is to read capacity, unless..
1093 *Action
= ACTION_READ_CAPACITY
;
1095 if (NumberOfSenseKeys
== 0) {
1096 *Action
= ACTION_NO_ACTION
;
1100 if (!ScsiDiskHaveSenseKey (SenseData
, NumberOfSenseKeys
)) {
1102 // No Sense Key returned from last submitted command
1104 *Action
= ACTION_NO_ACTION
;
1108 if (ScsiDiskIsNoMedia (SenseData
, NumberOfSenseKeys
)) {
1109 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= FALSE
;
1110 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= 0;
1111 *Action
= ACTION_NO_ACTION
;
1115 if (ScsiDiskIsMediaChange (SenseData
, NumberOfSenseKeys
)) {
1116 ScsiDiskDevice
->BlkIo
.Media
->MediaId
++;
1120 if (ScsiDiskIsMediaError (SenseData
, NumberOfSenseKeys
)) {
1121 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= FALSE
;
1122 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= 0;
1123 return EFI_DEVICE_ERROR
;
1126 if (ScsiDiskIsHardwareError (SenseData
, NumberOfSenseKeys
)) {
1127 return EFI_DEVICE_ERROR
;
1130 if (!ScsiDiskIsDriveReady (SenseData
, NumberOfSenseKeys
, &RetryLater
)) {
1132 *Action
= ACTION_RETRY_COMMAND_LATER
;
1136 return EFI_DEVICE_ERROR
;
1143 ScsiDiskReadCapacity (
1144 SCSI_DISK_DEV
*ScsiDiskDevice
,
1146 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1147 UINTN
*NumberOfSenseKeys
1151 Routine Description:
1153 TODO: Add function description
1157 ScsiDiskDevice - TODO: add argument description
1158 NeedRetry - TODO: add argument description
1159 SenseDataArray - TODO: add argument description
1160 NumberOfSenseKeys - TODO: add argument description
1164 EFI_SUCCESS - TODO: Add description for return value
1165 EFI_DEVICE_ERROR - TODO: Add description for return value
1166 EFI_DEVICE_ERROR - TODO: Add description for return value
1167 EFI_DEVICE_ERROR - TODO: Add description for return value
1168 EFI_DEVICE_ERROR - TODO: Add description for return value
1169 EFI_DEVICE_ERROR - TODO: Add description for return value
1170 EFI_DEVICE_ERROR - TODO: Add description for return value
1171 EFI_DEVICE_ERROR - TODO: Add description for return value
1172 EFI_DEVICE_ERROR - TODO: Add description for return value
1173 EFI_DEVICE_ERROR - TODO: Add description for return value
1177 EFI_SCSI_DISK_CAPACITY_DATA CapacityData
;
1179 UINT8 HostAdapterStatus
;
1181 EFI_STATUS CommandStatus
;
1185 UINT8 SenseDataLength
;
1187 SenseDataLength
= 0;
1188 ZeroMem (&CapacityData
, sizeof (EFI_SCSI_DISK_CAPACITY_DATA
));
1189 DataLength
= sizeof (EFI_SCSI_DISK_CAPACITY_DATA
);
1191 *NumberOfSenseKeys
= 0;
1194 // submit Read Capacity Command. in this call,not request sense data
1196 CommandStatus
= SubmitReadCapacityCommand (
1197 ScsiDiskDevice
->ScsiIo
,
1198 EfiScsiStallSeconds (1),
1203 (VOID
*) &CapacityData
,
1207 if (CommandStatus
== EFI_SUCCESS
) {
1209 // no need to check HostAdapterStatus and TargetStatus
1211 GetMediaInfo (ScsiDiskDevice
, &CapacityData
);
1213 } else if (CommandStatus
== EFI_NOT_READY
) {
1215 // no need to check HostAdapterStatus and TargetStatus
1218 return EFI_DEVICE_ERROR
;
1219 } else if ((CommandStatus
== EFI_INVALID_PARAMETER
) || (CommandStatus
== EFI_UNSUPPORTED
)) {
1221 // no need to check HostAdapterStatus and TargetStatus
1224 return EFI_DEVICE_ERROR
;
1227 // go ahead to check HostAdapterStatus and TargetStatus
1228 // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)
1231 Status
= CheckHostAdapterStatus (HostAdapterStatus
);
1232 if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
1234 return EFI_DEVICE_ERROR
;
1235 } else if (Status
== EFI_DEVICE_ERROR
) {
1237 // reset the scsi channel
1239 ScsiDiskDevice
->ScsiIo
->ResetBus (ScsiDiskDevice
->ScsiIo
);
1241 return EFI_DEVICE_ERROR
;
1244 Status
= CheckTargetStatus (TargetStatus
);
1245 if (Status
== EFI_NOT_READY
) {
1247 // reset the scsi device
1249 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1251 return EFI_DEVICE_ERROR
;
1252 } else if (Status
== EFI_DEVICE_ERROR
) {
1254 return EFI_DEVICE_ERROR
;
1258 // if goes here, meant SubmitReadCapacityCommand() failed.
1259 // if ScsiDiskRequestSenseKeys() succeeds at last,
1260 // better retry SubmitReadCapacityCommand(). (by setting *NeedRetry = TRUE)
1263 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1265 Status
= ScsiDiskRequestSenseKeys (
1272 if (!EFI_ERROR (Status
)) {
1274 return EFI_DEVICE_ERROR
;
1278 return EFI_DEVICE_ERROR
;
1282 // ScsiDiskRequestSenseKeys() failed after several rounds of retry.
1283 // set *NeedRetry = FALSE to avoid the outside caller try again.
1286 return EFI_DEVICE_ERROR
;
1290 CheckHostAdapterStatus (
1291 UINT8 HostAdapterStatus
1295 Routine Description:
1297 TODO: Add function description
1301 HostAdapterStatus - TODO: add argument description
1305 EFI_SUCCESS - TODO: Add description for return value
1306 EFI_TIMEOUT - TODO: Add description for return value
1307 EFI_NOT_READY - TODO: Add description for return value
1308 EFI_DEVICE_ERROR - TODO: Add description for return value
1309 EFI_SUCCESS - TODO: Add description for return value
1313 switch (HostAdapterStatus
) {
1314 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK
:
1317 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT
:
1318 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT
:
1319 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND
:
1322 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT
:
1323 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR
:
1324 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED
:
1325 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN
:
1326 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET
:
1327 return EFI_NOT_READY
;
1329 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE
:
1330 case EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR
:
1331 return EFI_DEVICE_ERROR
;
1344 Routine Description:
1346 TODO: Add function description
1350 TargetStatus - TODO: add argument description
1354 EFI_SUCCESS - TODO: Add description for return value
1355 EFI_NOT_READY - TODO: Add description for return value
1356 EFI_DEVICE_ERROR - TODO: Add description for return value
1357 EFI_SUCCESS - TODO: Add description for return value
1361 switch (TargetStatus
) {
1362 case EFI_SCSI_IO_STATUS_TARGET_GOOD
:
1363 case EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION
:
1364 case EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET
:
1367 case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE
:
1368 case EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET
:
1369 case EFI_SCSI_IO_STATUS_TARGET_BUSY
:
1370 case EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED
:
1371 case EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL
:
1372 return EFI_NOT_READY
;
1374 case EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT
:
1375 return EFI_DEVICE_ERROR
;
1384 ScsiDiskRequestSenseKeys (
1385 SCSI_DISK_DEV
*ScsiDiskDevice
,
1387 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1388 UINTN
*NumberOfSenseKeys
,
1389 BOOLEAN AskResetIfError
1391 // TODO: function comment should start with '/*++'
1393 Retrieve all sense keys from the device.
1394 When encountering error during the process,
1395 if retrieve sense keys before error encounterred,
1396 return the sense keys with return status set to EFI_SUCCESS,
1397 and NeedRetry set to FALSE; otherwize, return the proper return
1400 // TODO: function comment should end with '--*/'
1401 // TODO: function comment is missing 'Routine Description:'
1402 // TODO: function comment is missing 'Arguments:'
1403 // TODO: function comment is missing 'Returns:'
1404 // TODO: ScsiDiskDevice - add argument and description to function comment
1405 // TODO: NeedRetry - add argument and description to function comment
1406 // TODO: SenseDataArray - add argument and description to function comment
1407 // TODO: NumberOfSenseKeys - add argument and description to function comment
1408 // TODO: AskResetIfError - add argument and description to function comment
1409 // TODO: EFI_SUCCESS - add return value to function comment
1410 // TODO: EFI_DEVICE_ERROR - add return value to function comment
1411 // TODO: EFI_SUCCESS - add return value to function comment
1413 EFI_SCSI_SENSE_DATA
*PtrSenseData
;
1414 UINT8 SenseDataLength
;
1417 EFI_STATUS FallStatus
;
1418 UINT8 HostAdapterStatus
;
1421 FallStatus
= EFI_SUCCESS
;
1422 SenseDataLength
= sizeof (EFI_SCSI_SENSE_DATA
);
1425 ScsiDiskDevice
->SenseData
,
1426 sizeof (EFI_SCSI_SENSE_DATA
) * (ScsiDiskDevice
->SenseDataNumber
)
1429 *NumberOfSenseKeys
= 0;
1430 *SenseDataArray
= ScsiDiskDevice
->SenseData
;
1431 PtrSenseData
= ScsiDiskDevice
->SenseData
;
1433 for (SenseReq
= TRUE
; SenseReq
;) {
1435 Status
= SubmitRequestSenseCommand (
1436 ScsiDiskDevice
->ScsiIo
,
1437 EfiScsiStallSeconds (2),
1443 if ((Status
== EFI_SUCCESS
) || (Status
== EFI_WARN_BUFFER_TOO_SMALL
)) {
1444 FallStatus
= EFI_SUCCESS
;
1445 } else if ((Status
== EFI_TIMEOUT
) || (Status
== EFI_NOT_READY
)) {
1447 FallStatus
= EFI_DEVICE_ERROR
;
1448 } else if ((Status
== EFI_INVALID_PARAMETER
) || (Status
== EFI_UNSUPPORTED
)) {
1450 FallStatus
= EFI_DEVICE_ERROR
;
1451 } else if (Status
== EFI_DEVICE_ERROR
) {
1452 if (AskResetIfError
) {
1453 ScsiDiskDevice
->ScsiIo
->ResetDevice (ScsiDiskDevice
->ScsiIo
);
1456 FallStatus
= EFI_DEVICE_ERROR
;
1459 if (EFI_ERROR (FallStatus
)) {
1460 if (*NumberOfSenseKeys
!= 0) {
1464 return EFI_DEVICE_ERROR
;
1468 (*NumberOfSenseKeys
) += 1;
1471 // no more sense key or number of sense keys exceeds predefined,
1474 if ((PtrSenseData
->Sense_Key
== EFI_SCSI_SK_NO_SENSE
) ||
1475 (*NumberOfSenseKeys
== ScsiDiskDevice
->SenseDataNumber
)) {
1488 SCSI_DISK_DEV
*ScsiDiskDevice
,
1489 EFI_SCSI_DISK_CAPACITY_DATA
*Capacity
1493 Routine Description:
1495 TODO: Add function description
1499 ScsiDiskDevice - TODO: add argument description
1500 Capacity - TODO: add argument description
1504 TODO: add return values
1508 ScsiDiskDevice
->BlkIo
.Media
->LastBlock
= (Capacity
->LastLba3
<< 24) |
1509 (Capacity
->LastLba2
<< 16) |
1510 (Capacity
->LastLba1
<< 8) |
1513 ScsiDiskDevice
->BlkIo
.Media
->MediaPresent
= TRUE
;
1514 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= (Capacity
->BlockSize3
<< 24) |
1515 (Capacity
->BlockSize2
<< 16) |
1516 (Capacity
->BlockSize1
<< 8) |
1517 Capacity
->BlockSize0
;
1518 if (ScsiDiskDevice
->DeviceType
== EFI_SCSI_TYPE_DISK
) {
1519 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x200;
1522 if (ScsiDiskDevice
->DeviceType
== EFI_SCSI_TYPE_CDROM
) {
1523 ScsiDiskDevice
->BlkIo
.Media
->BlockSize
= 0x800;
1529 SCSI_DISK_DEV
*ScsiDiskDevice
1533 Routine Description:
1535 TODO: Add function description
1539 ScsiDiskDevice - TODO: add argument description
1543 TODO: add return values
1547 ScsiDiskDevice
->FixedDevice
= (BOOLEAN
) (ScsiDiskDevice
->InquiryData
.RMB
? 0 : 1);
1548 ScsiDiskDevice
->BlkIoMedia
.RemovableMedia
= (BOOLEAN
) (!ScsiDiskDevice
->FixedDevice
);
1552 ScsiDiskReadSectors (
1553 SCSI_DISK_DEV
*ScsiDiskDevice
,
1556 UINTN NumberOfBlocks
1560 Routine Description:
1562 TODO: Add function description
1566 ScsiDiskDevice - TODO: add argument description
1567 Buffer - TODO: add argument description
1568 Lba - TODO: add argument description
1569 NumberOfBlocks - TODO: add argument description
1573 EFI_DEVICE_ERROR - TODO: Add description for return value
1574 EFI_DEVICE_ERROR - TODO: Add description for return value
1575 EFI_SUCCESS - TODO: Add description for return value
1579 UINTN BlocksRemaining
;
1591 EFI_SCSI_SENSE_DATA
*SenseData
;
1592 UINTN NumberOfSenseKeys
;
1595 NumberOfSenseKeys
= 0;
1597 Status
= EFI_SUCCESS
;
1599 BlocksRemaining
= NumberOfBlocks
;
1600 BlockSize
= ScsiDiskDevice
->BlkIo
.Media
->BlockSize
;
1602 // limit the data bytes that can be transferred by one Read(10) Command
1607 Lba32
= (UINT32
) Lba
;
1609 while (BlocksRemaining
> 0) {
1611 if (BlocksRemaining
<= MaxBlock
) {
1613 SectorCount
= (UINT16
) BlocksRemaining
;
1616 SectorCount
= MaxBlock
;
1619 ByteCount
= SectorCount
* BlockSize
;
1620 Timeout
= EfiScsiStallSeconds (2);
1623 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1625 Status
= ScsiDiskRead10 (
1636 if (!EFI_ERROR (Status
)) {
1641 return EFI_DEVICE_ERROR
;
1646 if ((Index
== MaxRetry
) && (Status
!= EFI_SUCCESS
)) {
1647 return EFI_DEVICE_ERROR
;
1651 // actual transferred sectors
1653 SectorCount
= ByteCount
/ BlockSize
;
1655 Lba32
+= SectorCount
;
1656 PtrBuffer
= PtrBuffer
+ SectorCount
* BlockSize
;
1657 BlocksRemaining
-= SectorCount
;
1664 ScsiDiskWriteSectors (
1665 SCSI_DISK_DEV
*ScsiDiskDevice
,
1668 UINTN NumberOfBlocks
1672 Routine Description:
1674 TODO: Add function description
1678 ScsiDiskDevice - TODO: add argument description
1679 Buffer - TODO: add argument description
1680 Lba - TODO: add argument description
1681 NumberOfBlocks - TODO: add argument description
1685 EFI_DEVICE_ERROR - TODO: Add description for return value
1686 EFI_DEVICE_ERROR - TODO: Add description for return value
1687 EFI_SUCCESS - TODO: Add description for return value
1691 UINTN BlocksRemaining
;
1703 EFI_SCSI_SENSE_DATA
*SenseData
;
1704 UINTN NumberOfSenseKeys
;
1707 NumberOfSenseKeys
= 0;
1709 Status
= EFI_SUCCESS
;
1711 BlocksRemaining
= NumberOfBlocks
;
1712 BlockSize
= ScsiDiskDevice
->BlkIo
.Media
->BlockSize
;
1714 // limit the data bytes that can be transferred by one Write(10) Command
1719 Lba32
= (UINT32
) Lba
;
1721 while (BlocksRemaining
> 0) {
1723 if (BlocksRemaining
<= MaxBlock
) {
1725 SectorCount
= (UINT16
) BlocksRemaining
;
1728 SectorCount
= MaxBlock
;
1731 ByteCount
= SectorCount
* BlockSize
;
1732 Timeout
= EfiScsiStallSeconds (2);
1734 for (Index
= 0; Index
< MaxRetry
; Index
++) {
1735 Status
= ScsiDiskWrite10 (
1746 if (!EFI_ERROR (Status
)) {
1751 return EFI_DEVICE_ERROR
;
1755 if ((Index
== MaxRetry
) && (Status
!= EFI_SUCCESS
)) {
1756 return EFI_DEVICE_ERROR
;
1759 // actual transferred sectors
1761 SectorCount
= ByteCount
/ BlockSize
;
1763 Lba32
+= SectorCount
;
1764 PtrBuffer
= PtrBuffer
+ SectorCount
* BlockSize
;
1765 BlocksRemaining
-= SectorCount
;
1773 SCSI_DISK_DEV
*ScsiDiskDevice
,
1775 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1776 UINTN
*NumberOfSenseKeys
,
1785 Routine Description:
1787 TODO: Add function description
1791 ScsiDiskDevice - TODO: add argument description
1792 NeedRetry - TODO: add argument description
1793 SenseDataArray - TODO: add argument description
1794 NumberOfSenseKeys - TODO: add argument description
1795 Timeout - TODO: add argument description
1796 DataBuffer - TODO: add argument description
1797 DataLength - TODO: add argument description
1798 StartLba - TODO: add argument description
1799 SectorSize - TODO: add argument description
1803 TODO: add return values
1807 UINT8 SenseDataLength
;
1809 UINT8 HostAdapterStatus
;
1813 *NumberOfSenseKeys
= 0;
1814 SenseDataLength
= 0;
1815 Status
= SubmitRead10Command (
1816 ScsiDiskDevice
->ScsiIo
,
1832 SCSI_DISK_DEV
*ScsiDiskDevice
,
1834 EFI_SCSI_SENSE_DATA
**SenseDataArray
,
1835 UINTN
*NumberOfSenseKeys
,
1844 Routine Description:
1846 TODO: Add function description
1850 ScsiDiskDevice - TODO: add argument description
1851 NeedRetry - TODO: add argument description
1852 SenseDataArray - TODO: add argument description
1853 NumberOfSenseKeys - TODO: add argument description
1854 Timeout - TODO: add argument description
1855 DataBuffer - TODO: add argument description
1856 DataLength - TODO: add argument description
1857 StartLba - TODO: add argument description
1858 SectorSize - TODO: add argument description
1862 TODO: add return values
1867 UINT8 SenseDataLength
;
1868 UINT8 HostAdapterStatus
;
1872 *NumberOfSenseKeys
= 0;
1873 SenseDataLength
= 0;
1874 Status
= SubmitWrite10Command (
1875 ScsiDiskDevice
->ScsiIo
,
1891 IN EFI_SCSI_SENSE_DATA
*SenseData
,
1892 IN UINTN SenseCounts
1896 Routine Description:
1898 TODO: Add function description
1902 SenseData - TODO: add argument description
1903 SenseCounts - TODO: add argument description
1907 TODO: add return values
1911 EFI_SCSI_SENSE_DATA
*SensePtr
;
1916 SensePtr
= SenseData
;
1918 for (Index
= 0; Index
< SenseCounts
; Index
++) {
1921 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2),
1922 // Additional Sense Code is ASC_NO_MEDIA (0x3A)
1924 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_NOT_READY
) &&
1925 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_NO_MEDIA
)) {
1936 ScsiDiskIsMediaError (
1937 IN EFI_SCSI_SENSE_DATA
*SenseData
,
1938 IN UINTN SenseCounts
1942 Routine Description:
1944 TODO: Add function description
1948 SenseData - TODO: add argument description
1949 SenseCounts - TODO: add argument description
1953 TODO: add return values
1957 EFI_SCSI_SENSE_DATA
*SensePtr
;
1962 SensePtr
= SenseData
;
1964 for (Index
= 0; Index
< SenseCounts
; Index
++) {
1966 switch (SensePtr
->Sense_Key
) {
1968 case EFI_SCSI_SK_MEDIUM_ERROR
:
1970 // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)
1972 switch (SensePtr
->Addnl_Sense_Code
) {
1977 case EFI_SCSI_ASC_MEDIA_ERR1
:
1982 case EFI_SCSI_ASC_MEDIA_ERR2
:
1987 case EFI_SCSI_ASC_MEDIA_ERR3
:
1988 case EFI_SCSI_ASC_MEDIA_ERR4
:
1998 case EFI_SCSI_SK_NOT_READY
:
2000 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
2002 switch (SensePtr
->Addnl_Sense_Code
) {
2004 // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)
2006 case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN
:
2026 ScsiDiskIsHardwareError (
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
++) {
2057 // Sense Key is EFI_SCSI_SK_HARDWARE_ERROR (0x4)
2059 if (SensePtr
->Sense_Key
== EFI_SCSI_SK_HARDWARE_ERROR
) {
2070 ScsiDiskIsMediaChange (
2071 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2072 IN UINTN SenseCounts
2076 Routine Description:
2078 TODO: Add function description
2082 SenseData - TODO: add argument description
2083 SenseCounts - TODO: add argument description
2087 TODO: add return values
2091 EFI_SCSI_SENSE_DATA
*SensePtr
;
2093 BOOLEAN IsMediaChanged
;
2095 IsMediaChanged
= FALSE
;
2096 SensePtr
= SenseData
;
2098 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2100 // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6),
2101 // Additional sense code is EFI_SCSI_ASC_MEDIA_CHANGE (0x28)
2103 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_UNIT_ATTENTION
) &&
2104 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_MEDIA_CHANGE
)) {
2105 IsMediaChanged
= TRUE
;
2111 return IsMediaChanged
;
2115 ScsiDiskIsResetBefore (
2116 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2117 IN UINTN SenseCounts
2121 Routine Description:
2123 TODO: Add function description
2127 SenseData - TODO: add argument description
2128 SenseCounts - TODO: add argument description
2132 TODO: add return values
2136 EFI_SCSI_SENSE_DATA
*SensePtr
;
2138 BOOLEAN IsResetBefore
;
2140 IsResetBefore
= FALSE
;
2141 SensePtr
= SenseData
;
2143 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2146 // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6)
2147 // Additional Sense Code is EFI_SCSI_ASC_RESET (0x29)
2149 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_UNIT_ATTENTION
) &&
2150 (SensePtr
->Addnl_Sense_Code
== EFI_SCSI_ASC_RESET
)) {
2151 IsResetBefore
= TRUE
;
2157 return IsResetBefore
;
2161 ScsiDiskIsDriveReady (
2162 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2163 IN UINTN SenseCounts
,
2164 OUT BOOLEAN
*RetryLater
2168 Routine Description:
2170 TODO: Add function description
2174 SenseData - TODO: add argument description
2175 SenseCounts - TODO: add argument description
2176 RetryLater - TODO: add argument description
2180 TODO: add return values
2184 EFI_SCSI_SENSE_DATA
*SensePtr
;
2189 *RetryLater
= FALSE
;
2190 SensePtr
= SenseData
;
2192 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2194 switch (SensePtr
->Sense_Key
) {
2196 case EFI_SCSI_SK_NOT_READY
:
2198 // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)
2200 switch (SensePtr
->Addnl_Sense_Code
) {
2201 case EFI_SCSI_ASC_NOT_READY
:
2203 // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)
2205 switch (SensePtr
->Addnl_Sense_Code_Qualifier
) {
2206 case EFI_SCSI_ASCQ_IN_PROGRESS
:
2208 // Additional Sense Code Qualifier is
2209 // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)
2217 *RetryLater
= FALSE
;
2238 ScsiDiskHaveSenseKey (
2239 IN EFI_SCSI_SENSE_DATA
*SenseData
,
2240 IN UINTN SenseCounts
2244 Routine Description:
2246 TODO: Add function description
2250 SenseData - TODO: add argument description
2251 SenseCounts - TODO: add argument description
2255 TODO: add return values
2259 EFI_SCSI_SENSE_DATA
*SensePtr
;
2261 BOOLEAN HaveSenseKey
;
2263 if (SenseCounts
== 0) {
2264 HaveSenseKey
= FALSE
;
2266 HaveSenseKey
= TRUE
;
2269 SensePtr
= SenseData
;
2271 for (Index
= 0; Index
< SenseCounts
; Index
++) {
2274 // Sense Key is SK_NO_SENSE (0x0)
2276 if ((SensePtr
->Sense_Key
== EFI_SCSI_SK_NO_SENSE
) &&
2278 HaveSenseKey
= FALSE
;
2284 return HaveSenseKey
;
2288 ReleaseScsiDiskDeviceResources (
2289 IN SCSI_DISK_DEV
*ScsiDiskDevice
2293 Routine Description:
2295 TODO: Add function description
2299 ScsiDiskDevice - TODO: add argument description
2303 TODO: add return values
2307 if (ScsiDiskDevice
== NULL
) {
2311 if (ScsiDiskDevice
->SenseData
!= NULL
) {
2312 gBS
->FreePool (ScsiDiskDevice
->SenseData
);
2313 ScsiDiskDevice
->SenseData
= NULL
;
2316 if (ScsiDiskDevice
->ControllerNameTable
!= NULL
) {
2317 FreeUnicodeStringTable (ScsiDiskDevice
->ControllerNameTable
);
2318 ScsiDiskDevice
->ControllerNameTable
= NULL
;
2321 gBS
->FreePool (ScsiDiskDevice
);
2323 ScsiDiskDevice
= NULL
;