2 The SdDxe driver is used to manage the SD memory card device.
4 It produces BlockIo and BlockIo2 protocols to allow upper layer
5 access the SD memory card device.
7 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 // SdDxe Driver Binding Protocol Instance
23 EFI_DRIVER_BINDING_PROTOCOL gSdDxeDriverBinding
= {
24 SdDxeDriverBindingSupported
,
25 SdDxeDriverBindingStart
,
26 SdDxeDriverBindingStop
,
33 // Template for SD_DEVICE data structure.
35 SD_DEVICE mSdDeviceTemplate
= {
36 SD_DEVICE_SIGNATURE
, // Signature
40 FALSE
, // SectorAddressing
42 EFI_BLOCK_IO_PROTOCOL_REVISION
,
58 FALSE
, // RemovableMedia
60 FALSE
, // LogicPartition
62 FALSE
, // WritingCache
68 EFI_ERASE_BLOCK_PROTOCOL_REVISION
,
73 EFI_DISK_INFO_SD_MMC_INTERFACE_GUID
,
89 NULL
, // ControllerNameTable
97 Decode and print SD CSD Register content.
99 @param[in] Csd Pointer to SD_CSD data structure.
101 @retval EFI_SUCCESS The function completed successfully
110 DEBUG((DEBUG_INFO
, "== Dump Sd Csd Register==\n"));
111 DEBUG((DEBUG_INFO
, " CSD structure 0x%x\n", Csd
->CsdStructure
));
112 DEBUG((DEBUG_INFO
, " Data read access-time 1 0x%x\n", Csd
->Taac
));
113 DEBUG((DEBUG_INFO
, " Data read access-time 2 0x%x\n", Csd
->Nsac
));
114 DEBUG((DEBUG_INFO
, " Max. bus clock frequency 0x%x\n", Csd
->TranSpeed
));
115 DEBUG((DEBUG_INFO
, " Device command classes 0x%x\n", Csd
->Ccc
));
116 DEBUG((DEBUG_INFO
, " Max. read data block length 0x%x\n", Csd
->ReadBlLen
));
117 DEBUG((DEBUG_INFO
, " Partial blocks for read allowed 0x%x\n", Csd
->ReadBlPartial
));
118 DEBUG((DEBUG_INFO
, " Write block misalignment 0x%x\n", Csd
->WriteBlkMisalign
));
119 DEBUG((DEBUG_INFO
, " Read block misalignment 0x%x\n", Csd
->ReadBlkMisalign
));
120 DEBUG((DEBUG_INFO
, " DSR implemented 0x%x\n", Csd
->DsrImp
));
121 if (Csd
->CsdStructure
== 0) {
122 DEBUG((DEBUG_INFO
, " Device size 0x%x\n", Csd
->CSizeLow
| (Csd
->CSizeHigh
<< 2)));
123 DEBUG((DEBUG_INFO
, " Max. read current @ VDD min 0x%x\n", Csd
->VddRCurrMin
));
124 DEBUG((DEBUG_INFO
, " Max. read current @ VDD max 0x%x\n", Csd
->VddRCurrMax
));
125 DEBUG((DEBUG_INFO
, " Max. write current @ VDD min 0x%x\n", Csd
->VddWCurrMin
));
126 DEBUG((DEBUG_INFO
, " Max. write current @ VDD max 0x%x\n", Csd
->VddWCurrMax
));
128 Csd2
= (SD_CSD2
*)(VOID
*)Csd
;
129 DEBUG((DEBUG_INFO
, " Device size 0x%x\n", Csd2
->CSizeLow
| (Csd
->CSizeHigh
<< 16)));
131 DEBUG((DEBUG_INFO
, " Erase sector size 0x%x\n", Csd
->SectorSize
));
132 DEBUG((DEBUG_INFO
, " Erase single block enable 0x%x\n", Csd
->EraseBlkEn
));
133 DEBUG((DEBUG_INFO
, " Write protect group size 0x%x\n", Csd
->WpGrpSize
));
134 DEBUG((DEBUG_INFO
, " Write protect group enable 0x%x\n", Csd
->WpGrpEnable
));
135 DEBUG((DEBUG_INFO
, " Write speed factor 0x%x\n", Csd
->R2WFactor
));
136 DEBUG((DEBUG_INFO
, " Max. write data block length 0x%x\n", Csd
->WriteBlLen
));
137 DEBUG((DEBUG_INFO
, " Partial blocks for write allowed 0x%x\n", Csd
->WriteBlPartial
));
138 DEBUG((DEBUG_INFO
, " File format group 0x%x\n", Csd
->FileFormatGrp
));
139 DEBUG((DEBUG_INFO
, " Copy flag (OTP) 0x%x\n", Csd
->Copy
));
140 DEBUG((DEBUG_INFO
, " Permanent write protection 0x%x\n", Csd
->PermWriteProtect
));
141 DEBUG((DEBUG_INFO
, " Temporary write protection 0x%x\n", Csd
->TmpWriteProtect
));
142 DEBUG((DEBUG_INFO
, " File format 0x%x\n", Csd
->FileFormat
));
148 Get SD device model name.
150 @param[in, out] Device The pointer to the SD_DEVICE data structure.
151 @param[in] Cid Pointer to SD_CID data structure.
153 @retval EFI_SUCCESS The function completed successfully
158 IN OUT SD_DEVICE
*Device
,
162 CHAR8 String
[SD_MODEL_NAME_MAX_LEN
];
164 ZeroMem (String
, sizeof (String
));
165 CopyMem (String
, Cid
->OemId
, sizeof (Cid
->OemId
));
166 String
[sizeof (Cid
->OemId
)] = ' ';
167 CopyMem (String
+ sizeof (Cid
->OemId
) + 1, Cid
->ProductName
, sizeof (Cid
->ProductName
));
168 String
[sizeof (Cid
->OemId
) + sizeof (Cid
->ProductName
)] = ' ';
169 CopyMem (String
+ sizeof (Cid
->OemId
) + sizeof (Cid
->ProductName
) + 1, Cid
->ProductSerialNumber
, sizeof (Cid
->ProductSerialNumber
));
171 AsciiStrToUnicodeStrS (String
, Device
->ModelName
, sizeof (Device
->ModelName
) / sizeof (Device
->ModelName
[0]));
177 Discover user area partition in the SD device.
179 @param[in] Device The pointer to the SD_DEVICE data structure.
181 @retval EFI_SUCCESS The user area partition in the SD device is successfully identified.
182 @return Others Some error occurs when identifying the user area.
202 // Deselect the device to force it enter stby mode.
203 // Note here we don't judge return status as some SD devices return
204 // error but the state has been stby.
206 SdSelect (Device
, 0);
208 Status
= SdSetRca (Device
, &Rca
);
209 if (EFI_ERROR (Status
)) {
210 DEBUG ((EFI_D_ERROR
, "DiscoverUserArea(): Assign new Rca = 0x%x fails with %r\n", Rca
, Status
));
215 Status
= SdGetCsd (Device
, Rca
, Csd
);
216 if (EFI_ERROR (Status
)) {
222 Status
= SdGetCid (Device
, Rca
, Cid
);
223 if (EFI_ERROR (Status
)) {
226 GetSdModelName (Device
, Cid
);
228 Status
= SdSelect (Device
, Rca
);
229 if (EFI_ERROR (Status
)) {
230 DEBUG ((EFI_D_ERROR
, "DiscoverUserArea(): Reselect the device 0x%x fails with %r\n", Rca
, Status
));
234 Status
= SdSendStatus (Device
, Rca
, &DevStatus
);
235 if (EFI_ERROR (Status
)) {
239 if (Csd
->CsdStructure
== 0) {
240 Device
->SectorAddressing
= FALSE
;
241 CSize
= (Csd
->CSizeHigh
<< 2 | Csd
->CSizeLow
) + 1;
242 CSizeMul
= (1 << (Csd
->CSizeMul
+ 2));
243 ReadBlLen
= (1 << (Csd
->ReadBlLen
));
244 Capacity
= MultU64x32 (MultU64x32 ((UINT64
)CSize
, CSizeMul
), ReadBlLen
);
246 Device
->SectorAddressing
= TRUE
;
247 Csd2
= (SD_CSD2
*)(VOID
*)Csd
;
248 CSize
= (Csd2
->CSizeHigh
<< 16 | Csd2
->CSizeLow
) + 1;
249 Capacity
= MultU64x32 ((UINT64
)CSize
, SIZE_512KB
);
252 Device
->BlockIo
.Media
= &Device
->BlockMedia
;
253 Device
->BlockIo2
.Media
= &Device
->BlockMedia
;
254 Device
->BlockMedia
.IoAlign
= Device
->Private
->PassThru
->IoAlign
;
255 Device
->BlockMedia
.BlockSize
= 0x200;
256 Device
->BlockMedia
.LastBlock
= 0x00;
257 Device
->BlockMedia
.RemovableMedia
= TRUE
;
258 Device
->BlockMedia
.MediaPresent
= TRUE
;
259 Device
->BlockMedia
.LogicalPartition
= FALSE
;
260 Device
->BlockMedia
.LastBlock
= DivU64x32 (Capacity
, Device
->BlockMedia
.BlockSize
) - 1;
262 if (Csd
->EraseBlkEn
) {
263 Device
->EraseBlock
.EraseLengthGranularity
= 1;
265 Device
->EraseBlock
.EraseLengthGranularity
= (Csd
->SectorSize
+ 1) * (1 << (Csd
->WriteBlLen
- 9));
272 Scan SD Bus to discover the device.
274 @param[in] Private The SD driver private data structure.
275 @param[in] Slot The slot number to check device present.
277 @retval EFI_SUCCESS Successfully to discover the device and attach
278 SdMmcIoProtocol to it.
279 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
281 @retval EFI_ALREADY_STARTED The device was discovered before.
282 @retval Others Fail to discover the device.
288 IN SD_DRIVER_PRIVATE_DATA
*Private
,
294 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
295 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
296 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
297 EFI_HANDLE DeviceHandle
;
298 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
302 NewDevicePath
= NULL
;
303 RemainingDevicePath
= NULL
;
304 PassThru
= Private
->PassThru
;
309 Status
= PassThru
->BuildDevicePath (
314 if (EFI_ERROR(Status
)) {
318 if (DevicePath
->SubType
!= MSG_SD_DP
) {
319 Status
= EFI_UNSUPPORTED
;
323 NewDevicePath
= AppendDevicePathNode (
324 Private
->ParentDevicePath
,
328 if (NewDevicePath
== NULL
) {
329 Status
= EFI_OUT_OF_RESOURCES
;
334 RemainingDevicePath
= NewDevicePath
;
335 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
, &RemainingDevicePath
, &DeviceHandle
);
336 if (!EFI_ERROR (Status
) && (DeviceHandle
!= NULL
) && IsDevicePathEnd(RemainingDevicePath
)) {
338 // The device has been started, directly return to fast boot.
340 Status
= EFI_ALREADY_STARTED
;
345 // Allocate buffer to store SD_DEVICE private data.
347 Device
= AllocateCopyPool (sizeof (SD_DEVICE
), &mSdDeviceTemplate
);
348 if (Device
== NULL
) {
349 Status
= EFI_OUT_OF_RESOURCES
;
353 Device
->DevicePath
= NewDevicePath
;
355 Device
->Private
= Private
;
356 InitializeListHead (&Device
->Queue
);
359 // Expose user area in the Sd memory card to upper layer.
361 Status
= DiscoverUserArea (Device
);
362 if (EFI_ERROR(Status
)) {
366 Device
->ControllerNameTable
= NULL
;
369 gSdDxeComponentName
.SupportedLanguages
,
370 &Device
->ControllerNameTable
,
376 gSdDxeComponentName2
.SupportedLanguages
,
377 &Device
->ControllerNameTable
,
382 Status
= gBS
->InstallMultipleProtocolInterfaces (
384 &gEfiDevicePathProtocolGuid
,
386 &gEfiBlockIoProtocolGuid
,
388 &gEfiBlockIo2ProtocolGuid
,
390 &gEfiEraseBlockProtocolGuid
,
392 &gEfiDiskInfoProtocolGuid
,
397 if (!EFI_ERROR (Status
)) {
400 &gEfiSdMmcPassThruProtocolGuid
,
401 (VOID
**) &(Private
->PassThru
),
402 Private
->DriverBindingHandle
,
404 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
409 FreePool (DevicePath
);
411 if (EFI_ERROR (Status
) && (NewDevicePath
!= NULL
)) {
412 FreePool (NewDevicePath
);
415 if (EFI_ERROR (Status
) && (Device
!= NULL
)) {
423 Tests to see if this driver supports a given controller. If a child device is provided,
424 it further tests to see if this driver supports creating a handle for the specified child device.
426 This function checks to see if the driver specified by This supports the device specified by
427 ControllerHandle. Drivers will typically use the device path attached to
428 ControllerHandle and/or the services from the bus I/O abstraction attached to
429 ControllerHandle to determine if the driver supports ControllerHandle. This function
430 may be called many times during platform initialization. In order to reduce boot times, the tests
431 performed by this function must be very small, and take as little time as possible to execute. This
432 function must not change the state of any hardware devices, and this function must be aware that the
433 device specified by ControllerHandle may already be managed by the same driver or a
434 different driver. This function must match its calls to AllocatePages() with FreePages(),
435 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
436 Since ControllerHandle may have been previously started by the same driver, if a protocol is
437 already in the opened state, then it must not be closed with CloseProtocol(). This is required
438 to guarantee the state of ControllerHandle is not modified by this function.
440 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
441 @param[in] ControllerHandle The handle of the controller to test. This handle
442 must support a protocol interface that supplies
443 an I/O abstraction to the driver.
444 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
445 parameter is ignored by device drivers, and is optional for bus
446 drivers. For bus drivers, if this parameter is not NULL, then
447 the bus driver must determine if the bus controller specified
448 by ControllerHandle and the child controller specified
449 by RemainingDevicePath are both supported by this
452 @retval EFI_SUCCESS The device specified by ControllerHandle and
453 RemainingDevicePath is supported by the driver specified by This.
454 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
455 RemainingDevicePath is already being managed by the driver
457 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
458 RemainingDevicePath is already being managed by a different
459 driver or an application that requires exclusive access.
460 Currently not implemented.
461 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
462 RemainingDevicePath is not supported by the driver specified by This.
466 SdDxeDriverBindingSupported (
467 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
468 IN EFI_HANDLE Controller
,
469 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
473 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
474 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
478 // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle.
480 Status
= gBS
->OpenProtocol (
482 &gEfiSdMmcPassThruProtocolGuid
,
484 This
->DriverBindingHandle
,
486 EFI_OPEN_PROTOCOL_BY_DRIVER
489 if (Status
== EFI_ALREADY_STARTED
) {
493 if (EFI_ERROR (Status
)) {
498 // Test RemainingDevicePath is valid or not.
500 if ((RemainingDevicePath
!= NULL
) && !IsDevicePathEnd (RemainingDevicePath
)) {
501 Status
= PassThru
->GetSlotNumber (PassThru
, RemainingDevicePath
, &Slot
);
502 if (EFI_ERROR (Status
)) {
504 // Close the I/O Abstraction(s) used to perform the supported test
508 &gEfiSdMmcPassThruProtocolGuid
,
509 This
->DriverBindingHandle
,
517 // Close the I/O Abstraction(s) used to perform the supported test
521 &gEfiSdMmcPassThruProtocolGuid
,
522 This
->DriverBindingHandle
,
527 // Open the EFI Device Path protocol needed to perform the supported test
529 Status
= gBS
->OpenProtocol (
531 &gEfiDevicePathProtocolGuid
,
532 (VOID
**) &ParentDevicePath
,
533 This
->DriverBindingHandle
,
535 EFI_OPEN_PROTOCOL_GET_PROTOCOL
541 Starts a device controller or a bus controller.
543 The Start() function is designed to be invoked from the EFI boot service ConnectController().
544 As a result, much of the error checking on the parameters to Start() has been moved into this
545 common boot service. It is legal to call Start() from other locations,
546 but the following calling restrictions must be followed or the system behavior will not be deterministic.
547 1. ControllerHandle must be a valid EFI_HANDLE.
548 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
549 EFI_DEVICE_PATH_PROTOCOL.
550 3. Prior to calling Start(), the Supported() function for the driver specified by This must
551 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
553 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
554 @param[in] ControllerHandle The handle of the controller to start. This handle
555 must support a protocol interface that supplies
556 an I/O abstraction to the driver.
557 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
558 parameter is ignored by device drivers, and is optional for bus
559 drivers. For a bus driver, if this parameter is NULL, then handles
560 for all the children of Controller are created by this driver.
561 If this parameter is not NULL and the first Device Path Node is
562 not the End of Device Path Node, then only the handle for the
563 child device specified by the first Device Path Node of
564 RemainingDevicePath is created by this driver.
565 If the first Device Path Node of RemainingDevicePath is
566 the End of Device Path Node, no child handle is created by this
569 @retval EFI_SUCCESS The device was started.
570 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
571 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
572 @retval Others The driver failded to start the device.
577 SdDxeDriverBindingStart (
578 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
579 IN EFI_HANDLE Controller
,
580 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
584 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
585 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
586 SD_DRIVER_PRIVATE_DATA
*Private
;
591 Status
= gBS
->OpenProtocol (
593 &gEfiSdMmcPassThruProtocolGuid
,
595 This
->DriverBindingHandle
,
597 EFI_OPEN_PROTOCOL_BY_DRIVER
599 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
604 // Check EFI_ALREADY_STARTED to reuse the original SD_DRIVER_PRIVATE_DATA.
606 if (Status
!= EFI_ALREADY_STARTED
) {
607 Private
= AllocateZeroPool (sizeof (SD_DRIVER_PRIVATE_DATA
));
608 if (Private
== NULL
) {
609 Status
= EFI_OUT_OF_RESOURCES
;
613 Status
= gBS
->OpenProtocol (
615 &gEfiDevicePathProtocolGuid
,
616 (VOID
**) &ParentDevicePath
,
617 This
->DriverBindingHandle
,
619 EFI_OPEN_PROTOCOL_GET_PROTOCOL
621 ASSERT_EFI_ERROR (Status
);
622 Private
->PassThru
= PassThru
;
623 Private
->Controller
= Controller
;
624 Private
->ParentDevicePath
= ParentDevicePath
;
625 Private
->DriverBindingHandle
= This
->DriverBindingHandle
;
627 Status
= gBS
->InstallProtocolInterface (
630 EFI_NATIVE_INTERFACE
,
633 if (EFI_ERROR (Status
)) {
637 Status
= gBS
->OpenProtocol (
641 This
->DriverBindingHandle
,
643 EFI_OPEN_PROTOCOL_GET_PROTOCOL
645 if (EFI_ERROR (Status
)) {
650 if (RemainingDevicePath
== NULL
) {
653 Status
= PassThru
->GetNextSlot (PassThru
, &Slot
);
654 if (EFI_ERROR (Status
)) {
656 // Cannot find more legal slots.
658 Status
= EFI_SUCCESS
;
662 Status
= DiscoverSdDevice (Private
, Slot
);
663 if (EFI_ERROR (Status
) && (Status
!= EFI_ALREADY_STARTED
)) {
667 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
668 Status
= PassThru
->GetSlotNumber (PassThru
, RemainingDevicePath
, &Slot
);
669 if (!EFI_ERROR (Status
)) {
670 Status
= DiscoverSdDevice (Private
, Slot
);
675 if (EFI_ERROR (Status
) && (Status
!= EFI_ALREADY_STARTED
)) {
678 &gEfiSdMmcPassThruProtocolGuid
,
679 This
->DriverBindingHandle
,
683 if (Private
!= NULL
) {
684 gBS
->UninstallMultipleProtocolInterfaces (
697 Stops a device controller or a bus controller.
699 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
700 As a result, much of the error checking on the parameters to Stop() has been moved
701 into this common boot service. It is legal to call Stop() from other locations,
702 but the following calling restrictions must be followed or the system behavior will not be deterministic.
703 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
704 same driver's Start() function.
705 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
706 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
707 Start() function, and the Start() function must have called OpenProtocol() on
708 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
710 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
711 @param[in] ControllerHandle A handle to the device being stopped. The handle must
712 support a bus specific I/O protocol for the driver
713 to use to stop the device.
714 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
715 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
716 if NumberOfChildren is 0.
718 @retval EFI_SUCCESS The device was stopped.
719 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
724 SdDxeDriverBindingStop (
725 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
726 IN EFI_HANDLE Controller
,
727 IN UINTN NumberOfChildren
,
728 IN EFI_HANDLE
*ChildHandleBuffer
732 BOOLEAN AllChildrenStopped
;
734 SD_DRIVER_PRIVATE_DATA
*Private
;
736 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
737 EFI_BLOCK_IO2_PROTOCOL
*BlockIo2
;
738 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
740 LIST_ENTRY
*NextLink
;
744 if (NumberOfChildren
== 0) {
745 Status
= gBS
->OpenProtocol (
749 This
->DriverBindingHandle
,
751 EFI_OPEN_PROTOCOL_GET_PROTOCOL
753 if (EFI_ERROR (Status
)) {
754 return EFI_DEVICE_ERROR
;
757 gBS
->UninstallProtocolInterface (
764 &gEfiSdMmcPassThruProtocolGuid
,
765 This
->DriverBindingHandle
,
774 AllChildrenStopped
= TRUE
;
776 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
779 Status
= gBS
->OpenProtocol (
780 ChildHandleBuffer
[Index
],
781 &gEfiBlockIoProtocolGuid
,
783 This
->DriverBindingHandle
,
785 EFI_OPEN_PROTOCOL_GET_PROTOCOL
787 if (EFI_ERROR (Status
)) {
788 Status
= gBS
->OpenProtocol (
789 ChildHandleBuffer
[Index
],
790 &gEfiBlockIo2ProtocolGuid
,
792 This
->DriverBindingHandle
,
794 EFI_OPEN_PROTOCOL_GET_PROTOCOL
796 if (EFI_ERROR (Status
)) {
797 AllChildrenStopped
= FALSE
;
802 if (BlockIo
!= NULL
) {
803 Device
= SD_DEVICE_DATA_FROM_BLKIO (BlockIo
);
805 ASSERT (BlockIo2
!= NULL
);
806 Device
= SD_DEVICE_DATA_FROM_BLKIO2 (BlockIo2
);
810 // Free all on-going async tasks.
812 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
813 for (Link
= GetFirstNode (&Device
->Queue
);
814 !IsNull (&Device
->Queue
, Link
);
816 NextLink
= GetNextNode (&Device
->Queue
, Link
);
817 RemoveEntryList (Link
);
819 Request
= SD_REQUEST_FROM_LINK (Link
);
821 gBS
->CloseEvent (Request
->Event
);
822 Request
->Token
->TransactionStatus
= EFI_ABORTED
;
824 if (Request
->IsEnd
) {
825 gBS
->SignalEvent (Request
->Token
->Event
);
830 gBS
->RestoreTPL (OldTpl
);
833 // Close the child handle
835 Status
= gBS
->CloseProtocol (
837 &gEfiSdMmcPassThruProtocolGuid
,
838 This
->DriverBindingHandle
,
839 ChildHandleBuffer
[Index
]
842 Status
= gBS
->UninstallMultipleProtocolInterfaces (
843 ChildHandleBuffer
[Index
],
844 &gEfiDevicePathProtocolGuid
,
846 &gEfiBlockIoProtocolGuid
,
848 &gEfiBlockIo2ProtocolGuid
,
850 &gEfiEraseBlockProtocolGuid
,
852 &gEfiDiskInfoProtocolGuid
,
856 if (EFI_ERROR (Status
)) {
857 AllChildrenStopped
= FALSE
;
860 &gEfiSdMmcPassThruProtocolGuid
,
862 This
->DriverBindingHandle
,
863 ChildHandleBuffer
[Index
],
864 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
867 FreePool (Device
->DevicePath
);
868 FreeUnicodeStringTable (Device
->ControllerNameTable
);
873 if (!AllChildrenStopped
) {
874 return EFI_DEVICE_ERROR
;
881 The user Entry Point for module SdDxe. The user code starts with this function.
883 @param[in] ImageHandle The firmware allocated handle for the EFI image.
884 @param[in] SystemTable A pointer to the EFI System Table.
886 @retval EFI_SUCCESS The entry point is executed successfully.
887 @retval other Some errors occur when executing this entry point.
893 IN EFI_HANDLE ImageHandle
,
894 IN EFI_SYSTEM_TABLE
*SystemTable
900 // Install driver model protocol(s).
902 Status
= EfiLibInstallDriverBindingComponentName2 (
905 &gSdDxeDriverBinding
,
907 &gSdDxeComponentName
,
908 &gSdDxeComponentName2
910 ASSERT_EFI_ERROR (Status
);