]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Sd/SdDxe/SdDxe.c
MdeModulePkg/SdMmc: Add EDKII SD/MMC stack
[mirror_edk2.git] / MdeModulePkg / Bus / Sd / SdDxe / SdDxe.c
1 /** @file
2 The SdDxe driver is used to manage the SD memory card device.
3
4 It produces BlockIo and BlockIo2 protocols to allow upper layer
5 access the SD memory card device.
6
7 Copyright (c) 2015 - 2016, 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
12
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.
15
16 **/
17
18 #include "SdDxe.h"
19
20 //
21 // SdDxe Driver Binding Protocol Instance
22 //
23 EFI_DRIVER_BINDING_PROTOCOL gSdDxeDriverBinding = {
24 SdDxeDriverBindingSupported,
25 SdDxeDriverBindingStart,
26 SdDxeDriverBindingStop,
27 0x10,
28 NULL,
29 NULL
30 };
31
32 //
33 // Template for SD_DEVICE data structure.
34 //
35 SD_DEVICE mSdDeviceTemplate = {
36 SD_DEVICE_SIGNATURE, // Signature
37 NULL, // Handle
38 NULL, // DevicePath
39 0xFF, // Slot
40 FALSE, // SectorAddressing
41 { // BlockIo
42 EFI_BLOCK_IO_PROTOCOL_REVISION,
43 NULL,
44 SdReset,
45 SdReadBlocks,
46 SdWriteBlocks,
47 SdFlushBlocks
48 },
49 { // BlockIo2
50 NULL,
51 SdResetEx,
52 SdReadBlocksEx,
53 SdWriteBlocksEx,
54 SdFlushBlocksEx
55 },
56 { // BlockMedia
57 0, // MediaId
58 FALSE, // RemovableMedia
59 TRUE, // MediaPresent
60 FALSE, // LogicPartition
61 FALSE, // ReadOnly
62 FALSE, // WritingCache
63 0x200, // BlockSize
64 0, // IoAlign
65 0 // LastBlock
66 },
67 { // Queue
68 NULL,
69 NULL
70 },
71 { // Csd
72 0,
73 },
74 { // Cid
75 0,
76 },
77 NULL, // ControllerNameTable
78 { // ModelName
79 0,
80 },
81 NULL // Private
82 };
83
84 /**
85 Decode and print SD CSD Register content.
86
87 @param[in] Csd Pointer to SD_CSD data structure.
88
89 @retval EFI_SUCCESS The function completed successfully
90 **/
91 EFI_STATUS
92 DumpCsd (
93 IN SD_CSD *Csd
94 )
95 {
96 SD_CSD2 *Csd2;
97
98 DEBUG((DEBUG_INFO, "== Dump Sd Csd Register==\n"));
99 DEBUG((DEBUG_INFO, " CSD structure 0x%x\n", Csd->CsdStructure));
100 DEBUG((DEBUG_INFO, " Data read access-time 1 0x%x\n", Csd->Taac));
101 DEBUG((DEBUG_INFO, " Data read access-time 2 0x%x\n", Csd->Nsac));
102 DEBUG((DEBUG_INFO, " Max. bus clock frequency 0x%x\n", Csd->TranSpeed));
103 DEBUG((DEBUG_INFO, " Device command classes 0x%x\n", Csd->Ccc));
104 DEBUG((DEBUG_INFO, " Max. read data block length 0x%x\n", Csd->ReadBlLen));
105 DEBUG((DEBUG_INFO, " Partial blocks for read allowed 0x%x\n", Csd->ReadBlPartial));
106 DEBUG((DEBUG_INFO, " Write block misalignment 0x%x\n", Csd->WriteBlkMisalign));
107 DEBUG((DEBUG_INFO, " Read block misalignment 0x%x\n", Csd->ReadBlkMisalign));
108 DEBUG((DEBUG_INFO, " DSR implemented 0x%x\n", Csd->DsrImp));
109 if (Csd->CsdStructure == 0) {
110 DEBUG((DEBUG_INFO, " Device size 0x%x\n", Csd->CSizeLow | (Csd->CSizeHigh << 2)));
111 DEBUG((DEBUG_INFO, " Max. read current @ VDD min 0x%x\n", Csd->VddRCurrMin));
112 DEBUG((DEBUG_INFO, " Max. read current @ VDD max 0x%x\n", Csd->VddRCurrMax));
113 DEBUG((DEBUG_INFO, " Max. write current @ VDD min 0x%x\n", Csd->VddWCurrMin));
114 DEBUG((DEBUG_INFO, " Max. write current @ VDD max 0x%x\n", Csd->VddWCurrMax));
115 } else {
116 Csd2 = (SD_CSD2*)(VOID*)Csd;
117 DEBUG((DEBUG_INFO, " Device size 0x%x\n", Csd2->CSizeLow | (Csd->CSizeHigh << 16)));
118 }
119 DEBUG((DEBUG_INFO, " Erase sector size 0x%x\n", Csd->SectorSize));
120 DEBUG((DEBUG_INFO, " Erase single block enable 0x%x\n", Csd->EraseBlkEn));
121 DEBUG((DEBUG_INFO, " Write protect group size 0x%x\n", Csd->WpGrpSize));
122 DEBUG((DEBUG_INFO, " Write protect group enable 0x%x\n", Csd->WpGrpEnable));
123 DEBUG((DEBUG_INFO, " Write speed factor 0x%x\n", Csd->R2WFactor));
124 DEBUG((DEBUG_INFO, " Max. write data block length 0x%x\n", Csd->WriteBlLen));
125 DEBUG((DEBUG_INFO, " Partial blocks for write allowed 0x%x\n", Csd->WriteBlPartial));
126 DEBUG((DEBUG_INFO, " File format group 0x%x\n", Csd->FileFormatGrp));
127 DEBUG((DEBUG_INFO, " Copy flag (OTP) 0x%x\n", Csd->Copy));
128 DEBUG((DEBUG_INFO, " Permanent write protection 0x%x\n", Csd->PermWriteProtect));
129 DEBUG((DEBUG_INFO, " Temporary write protection 0x%x\n", Csd->TmpWriteProtect));
130 DEBUG((DEBUG_INFO, " File format 0x%x\n", Csd->FileFormat));
131
132 return EFI_SUCCESS;
133 }
134
135 /**
136 Get SD device model name.
137
138 @param[in, out] Device The pointer to the SD_DEVICE data structure.
139 @param[in] Cid Pointer to SD_CID data structure.
140
141 @retval EFI_SUCCESS The function completed successfully
142
143 **/
144 EFI_STATUS
145 GetSdModelName (
146 IN OUT SD_DEVICE *Device,
147 IN SD_CID *Cid
148 )
149 {
150 CHAR8 String[SD_MODEL_NAME_MAX_LEN];
151
152 ZeroMem (String, sizeof (String));
153 CopyMem (String, Cid->OemId, sizeof (Cid->OemId));
154 String[sizeof (Cid->OemId)] = ' ';
155 CopyMem (String + sizeof (Cid->OemId) + 1, Cid->ProductName, sizeof (Cid->ProductName));
156 String[sizeof (Cid->OemId) + sizeof (Cid->ProductName)] = ' ';
157 CopyMem (String + sizeof (Cid->OemId) + sizeof (Cid->ProductName) + 1, Cid->ProductSerialNumber, sizeof (Cid->ProductSerialNumber));
158
159 AsciiStrToUnicodeStr (String, Device->ModelName);
160
161 return EFI_SUCCESS;
162 }
163
164 /**
165 Discover user area partition in the SD device.
166
167 @param[in] Device The pointer to the SD_DEVICE data structure.
168
169 @retval EFI_SUCCESS The user area partition in the SD device is successfully identified.
170 @return Others Some error occurs when identifying the user area.
171
172 **/
173 EFI_STATUS
174 DiscoverUserArea (
175 IN SD_DEVICE *Device
176 )
177 {
178 EFI_STATUS Status;
179 SD_CSD *Csd;
180 SD_CSD2 *Csd2;
181 SD_CID *Cid;
182 UINT64 Capacity;
183 UINT32 DevStatus;
184 UINT16 Rca;
185 UINT32 CSize;
186 UINT32 CSizeMul;
187 UINT32 ReadBlLen;
188
189 //
190 // Deselect the device to force it enter stby mode.
191 // Note here we don't judge return status as some SD devices return
192 // error but the state has been stby.
193 //
194 SdSelect (Device, 0);
195
196 Status = SdSetRca (Device, &Rca);
197 if (EFI_ERROR (Status)) {
198 DEBUG ((EFI_D_ERROR, "DiscoverUserArea(): Assign new Rca = 0x%x fails with %r\n", Rca, Status));
199 return Status;
200 }
201
202 Csd = &Device->Csd;
203 Status = SdGetCsd (Device, Rca, Csd);
204 if (EFI_ERROR (Status)) {
205 return Status;
206 }
207 DumpCsd (Csd);
208
209 Cid = &Device->Cid;
210 Status = SdGetCid (Device, Rca, Cid);
211 if (EFI_ERROR (Status)) {
212 return Status;
213 }
214 GetSdModelName (Device, Cid);
215
216 Status = SdSelect (Device, Rca);
217 if (EFI_ERROR (Status)) {
218 DEBUG ((EFI_D_ERROR, "DiscoverUserArea(): Reselect the device 0x%x fails with %r\n", Rca, Status));
219 return Status;
220 }
221
222 Status = SdSendStatus (Device, Rca, &DevStatus);
223 if (EFI_ERROR (Status)) {
224 return Status;
225 }
226
227 if (Csd->CsdStructure == 0) {
228 Device->SectorAddressing = FALSE;
229 CSize = (Csd->CSizeHigh << 2 | Csd->CSizeLow) + 1;
230 CSizeMul = (1 << (Csd->CSizeMul + 2));
231 ReadBlLen = (1 << (Csd->ReadBlLen));
232 Capacity = MultU64x32 (MultU64x32 ((UINT64)CSize, CSizeMul), ReadBlLen);
233 } else {
234 Device->SectorAddressing = TRUE;
235 Csd2 = (SD_CSD2*)(VOID*)Csd;
236 CSize = (Csd2->CSizeHigh << 16 | Csd2->CSizeLow) + 1;
237 Capacity = MultU64x32 ((UINT64)CSize, SIZE_512KB);
238 }
239
240 Device->BlockIo.Media = &Device->BlockMedia;
241 Device->BlockIo2.Media = &Device->BlockMedia;
242 Device->BlockMedia.IoAlign = Device->Private->PassThru->IoAlign;
243 Device->BlockMedia.BlockSize = 0x200;
244 Device->BlockMedia.LastBlock = 0x00;
245 Device->BlockMedia.RemovableMedia = TRUE;
246 Device->BlockMedia.MediaPresent = TRUE;
247 Device->BlockMedia.LogicalPartition = FALSE;
248 Device->BlockMedia.LastBlock = DivU64x32 (Capacity, Device->BlockMedia.BlockSize) - 1;
249
250 return Status;
251 }
252
253 /**
254 Scan SD Bus to discover the device.
255
256 @param[in] Private The SD driver private data structure.
257 @param[in] Slot The slot number to check device present.
258
259 @retval EFI_SUCCESS Successfully to discover the device and attach
260 SdMmcIoProtocol to it.
261 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
262 of resources.
263 @retval EFI_ALREADY_STARTED The device was discovered before.
264 @retval Others Fail to discover the device.
265
266 **/
267 EFI_STATUS
268 EFIAPI
269 DiscoverSdDevice (
270 IN SD_DRIVER_PRIVATE_DATA *Private,
271 IN UINT8 Slot
272 )
273 {
274 EFI_STATUS Status;
275 SD_DEVICE *Device;
276 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
277 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
278 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
279 EFI_HANDLE DeviceHandle;
280 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
281
282 Device = NULL;
283 DevicePath = NULL;
284 NewDevicePath = NULL;
285 RemainingDevicePath = NULL;
286 PassThru = Private->PassThru;
287
288 //
289 // Build Device Path
290 //
291 Status = PassThru->BuildDevicePath (
292 PassThru,
293 Slot,
294 &DevicePath
295 );
296 if (EFI_ERROR(Status)) {
297 return Status;
298 }
299
300 if (DevicePath->SubType != MSG_SD_DP) {
301 Status = EFI_UNSUPPORTED;
302 goto Error;
303 }
304
305 NewDevicePath = AppendDevicePathNode (
306 Private->ParentDevicePath,
307 DevicePath
308 );
309
310 if (NewDevicePath == NULL) {
311 Status = EFI_OUT_OF_RESOURCES;
312 goto Error;
313 }
314
315 DeviceHandle = NULL;
316 RemainingDevicePath = NewDevicePath;
317 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
318 if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
319 //
320 // The device has been started, directly return to fast boot.
321 //
322 Status = EFI_ALREADY_STARTED;
323 goto Error;
324 }
325
326 //
327 // Allocate buffer to store SD_DEVICE private data.
328 //
329 Device = AllocateCopyPool (sizeof (SD_DEVICE), &mSdDeviceTemplate);
330 if (Device == NULL) {
331 Status = EFI_OUT_OF_RESOURCES;
332 goto Error;
333 }
334
335 Device->DevicePath = NewDevicePath;
336 Device->Slot = Slot;
337 Device->Private = Private;
338 InitializeListHead (&Device->Queue);
339
340 //
341 // Expose user area in the Sd memory card to upper layer.
342 //
343 Status = DiscoverUserArea (Device);
344 if (EFI_ERROR(Status)) {
345 goto Error;
346 }
347
348 Device->ControllerNameTable = NULL;
349 AddUnicodeString2 (
350 "eng",
351 gSdDxeComponentName.SupportedLanguages,
352 &Device->ControllerNameTable,
353 Device->ModelName,
354 TRUE
355 );
356 AddUnicodeString2 (
357 "en",
358 gSdDxeComponentName.SupportedLanguages,
359 &Device->ControllerNameTable,
360 Device->ModelName,
361 FALSE
362 );
363
364 Status = gBS->InstallMultipleProtocolInterfaces (
365 &Device->Handle,
366 &gEfiDevicePathProtocolGuid,
367 Device->DevicePath,
368 &gEfiBlockIoProtocolGuid,
369 &Device->BlockIo,
370 &gEfiBlockIo2ProtocolGuid,
371 &Device->BlockIo2,
372 NULL
373 );
374
375 if (!EFI_ERROR (Status)) {
376 gBS->OpenProtocol (
377 Private->Controller,
378 &gEfiSdMmcPassThruProtocolGuid,
379 (VOID **) &(Private->PassThru),
380 Private->DriverBindingHandle,
381 Device->Handle,
382 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
383 );
384 }
385
386 Error:
387 FreePool (DevicePath);
388
389 if (EFI_ERROR (Status) && (NewDevicePath != NULL)) {
390 FreePool (NewDevicePath);
391 }
392
393 if (EFI_ERROR (Status) && (Device != NULL)) {
394 FreePool (Device);
395 }
396
397 return Status;
398 }
399
400 /**
401 Tests to see if this driver supports a given controller. If a child device is provided,
402 it further tests to see if this driver supports creating a handle for the specified child device.
403
404 This function checks to see if the driver specified by This supports the device specified by
405 ControllerHandle. Drivers will typically use the device path attached to
406 ControllerHandle and/or the services from the bus I/O abstraction attached to
407 ControllerHandle to determine if the driver supports ControllerHandle. This function
408 may be called many times during platform initialization. In order to reduce boot times, the tests
409 performed by this function must be very small, and take as little time as possible to execute. This
410 function must not change the state of any hardware devices, and this function must be aware that the
411 device specified by ControllerHandle may already be managed by the same driver or a
412 different driver. This function must match its calls to AllocatePages() with FreePages(),
413 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
414 Since ControllerHandle may have been previously started by the same driver, if a protocol is
415 already in the opened state, then it must not be closed with CloseProtocol(). This is required
416 to guarantee the state of ControllerHandle is not modified by this function.
417
418 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
419 @param[in] ControllerHandle The handle of the controller to test. This handle
420 must support a protocol interface that supplies
421 an I/O abstraction to the driver.
422 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
423 parameter is ignored by device drivers, and is optional for bus
424 drivers. For bus drivers, if this parameter is not NULL, then
425 the bus driver must determine if the bus controller specified
426 by ControllerHandle and the child controller specified
427 by RemainingDevicePath are both supported by this
428 bus driver.
429
430 @retval EFI_SUCCESS The device specified by ControllerHandle and
431 RemainingDevicePath is supported by the driver specified by This.
432 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
433 RemainingDevicePath is already being managed by the driver
434 specified by This.
435 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
436 RemainingDevicePath is already being managed by a different
437 driver or an application that requires exclusive access.
438 Currently not implemented.
439 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
440 RemainingDevicePath is not supported by the driver specified by This.
441 **/
442 EFI_STATUS
443 EFIAPI
444 SdDxeDriverBindingSupported (
445 IN EFI_DRIVER_BINDING_PROTOCOL *This,
446 IN EFI_HANDLE Controller,
447 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
448 )
449 {
450 EFI_STATUS Status;
451 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
452 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
453 UINT8 Slot;
454
455 //
456 // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle.
457 //
458 Status = gBS->OpenProtocol (
459 Controller,
460 &gEfiSdMmcPassThruProtocolGuid,
461 (VOID**) &PassThru,
462 This->DriverBindingHandle,
463 Controller,
464 EFI_OPEN_PROTOCOL_BY_DRIVER
465 );
466
467 if (Status == EFI_ALREADY_STARTED) {
468 return EFI_SUCCESS;
469 }
470
471 if (EFI_ERROR (Status)) {
472 return Status;
473 }
474
475 //
476 // Test RemainingDevicePath is valid or not.
477 //
478 if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
479 Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
480 if (EFI_ERROR (Status)) {
481 //
482 // Close the I/O Abstraction(s) used to perform the supported test
483 //
484 gBS->CloseProtocol (
485 Controller,
486 &gEfiSdMmcPassThruProtocolGuid,
487 This->DriverBindingHandle,
488 Controller
489 );
490 return Status;
491 }
492 }
493
494 //
495 // Close the I/O Abstraction(s) used to perform the supported test
496 //
497 gBS->CloseProtocol (
498 Controller,
499 &gEfiSdMmcPassThruProtocolGuid,
500 This->DriverBindingHandle,
501 Controller
502 );
503
504 //
505 // Open the EFI Device Path protocol needed to perform the supported test
506 //
507 Status = gBS->OpenProtocol (
508 Controller,
509 &gEfiDevicePathProtocolGuid,
510 (VOID **) &ParentDevicePath,
511 This->DriverBindingHandle,
512 Controller,
513 EFI_OPEN_PROTOCOL_GET_PROTOCOL
514 );
515 return Status;
516 }
517
518 /**
519 Starts a device controller or a bus controller.
520
521 The Start() function is designed to be invoked from the EFI boot service ConnectController().
522 As a result, much of the error checking on the parameters to Start() has been moved into this
523 common boot service. It is legal to call Start() from other locations,
524 but the following calling restrictions must be followed or the system behavior will not be deterministic.
525 1. ControllerHandle must be a valid EFI_HANDLE.
526 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
527 EFI_DEVICE_PATH_PROTOCOL.
528 3. Prior to calling Start(), the Supported() function for the driver specified by This must
529 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
530
531 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
532 @param[in] ControllerHandle The handle of the controller to start. This handle
533 must support a protocol interface that supplies
534 an I/O abstraction to the driver.
535 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
536 parameter is ignored by device drivers, and is optional for bus
537 drivers. For a bus driver, if this parameter is NULL, then handles
538 for all the children of Controller are created by this driver.
539 If this parameter is not NULL and the first Device Path Node is
540 not the End of Device Path Node, then only the handle for the
541 child device specified by the first Device Path Node of
542 RemainingDevicePath is created by this driver.
543 If the first Device Path Node of RemainingDevicePath is
544 the End of Device Path Node, no child handle is created by this
545 driver.
546
547 @retval EFI_SUCCESS The device was started.
548 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
549 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
550 @retval Others The driver failded to start the device.
551
552 **/
553 EFI_STATUS
554 EFIAPI
555 SdDxeDriverBindingStart (
556 IN EFI_DRIVER_BINDING_PROTOCOL *This,
557 IN EFI_HANDLE Controller,
558 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
559 )
560 {
561 EFI_STATUS Status;
562 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
563 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
564 SD_DRIVER_PRIVATE_DATA *Private;
565 UINT8 Slot;
566
567 Private = NULL;
568 PassThru = NULL;
569 Status = gBS->OpenProtocol (
570 Controller,
571 &gEfiSdMmcPassThruProtocolGuid,
572 (VOID **) &PassThru,
573 This->DriverBindingHandle,
574 Controller,
575 EFI_OPEN_PROTOCOL_BY_DRIVER
576 );
577 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
578 return Status;
579 }
580
581 //
582 // Check EFI_ALREADY_STARTED to reuse the original SD_DRIVER_PRIVATE_DATA.
583 //
584 if (Status != EFI_ALREADY_STARTED) {
585 Private = AllocateZeroPool (sizeof (SD_DRIVER_PRIVATE_DATA));
586 if (Private == NULL) {
587 Status = EFI_OUT_OF_RESOURCES;
588 goto Error;
589 }
590
591 Status = gBS->OpenProtocol (
592 Controller,
593 &gEfiDevicePathProtocolGuid,
594 (VOID **) &ParentDevicePath,
595 This->DriverBindingHandle,
596 Controller,
597 EFI_OPEN_PROTOCOL_GET_PROTOCOL
598 );
599 ASSERT_EFI_ERROR (Status);
600 Private->PassThru = PassThru;
601 Private->Controller = Controller;
602 Private->ParentDevicePath = ParentDevicePath;
603 Private->DriverBindingHandle = This->DriverBindingHandle;
604
605 Status = gBS->InstallProtocolInterface (
606 &Controller,
607 &gEfiCallerIdGuid,
608 EFI_NATIVE_INTERFACE,
609 Private
610 );
611 if (EFI_ERROR (Status)) {
612 goto Error;
613 }
614 } else {
615 Status = gBS->OpenProtocol (
616 Controller,
617 &gEfiCallerIdGuid,
618 (VOID **) &Private,
619 This->DriverBindingHandle,
620 Controller,
621 EFI_OPEN_PROTOCOL_GET_PROTOCOL
622 );
623 if (EFI_ERROR (Status)) {
624 goto Error;
625 }
626 }
627
628 if (RemainingDevicePath == NULL) {
629 Slot = 0xFF;
630 while (TRUE) {
631 Status = PassThru->GetNextSlot (PassThru, &Slot);
632 if (EFI_ERROR (Status)) {
633 //
634 // Cannot find more legal slots.
635 //
636 Status = EFI_SUCCESS;
637 break;
638 }
639
640 Status = DiscoverSdDevice (Private, Slot);
641 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
642 break;
643 }
644 }
645 } else if (!IsDevicePathEnd (RemainingDevicePath)) {
646 Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
647 if (!EFI_ERROR (Status)) {
648 Status = DiscoverSdDevice (Private, Slot);
649 }
650 }
651
652 Error:
653 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
654 gBS->CloseProtocol (
655 Controller,
656 &gEfiSdMmcPassThruProtocolGuid,
657 This->DriverBindingHandle,
658 Controller
659 );
660
661 if (Private != NULL) {
662 gBS->UninstallMultipleProtocolInterfaces (
663 Controller,
664 &gEfiCallerIdGuid,
665 Private,
666 NULL
667 );
668 FreePool (Private);
669 }
670 }
671 return Status;
672 }
673
674 /**
675 Stops a device controller or a bus controller.
676
677 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
678 As a result, much of the error checking on the parameters to Stop() has been moved
679 into this common boot service. It is legal to call Stop() from other locations,
680 but the following calling restrictions must be followed or the system behavior will not be deterministic.
681 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
682 same driver's Start() function.
683 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
684 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
685 Start() function, and the Start() function must have called OpenProtocol() on
686 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
687
688 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
689 @param[in] ControllerHandle A handle to the device being stopped. The handle must
690 support a bus specific I/O protocol for the driver
691 to use to stop the device.
692 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
693 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
694 if NumberOfChildren is 0.
695
696 @retval EFI_SUCCESS The device was stopped.
697 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
698
699 **/
700 EFI_STATUS
701 EFIAPI
702 SdDxeDriverBindingStop (
703 IN EFI_DRIVER_BINDING_PROTOCOL *This,
704 IN EFI_HANDLE Controller,
705 IN UINTN NumberOfChildren,
706 IN EFI_HANDLE *ChildHandleBuffer
707 )
708 {
709 EFI_STATUS Status;
710 BOOLEAN AllChildrenStopped;
711 UINTN Index;
712 SD_DRIVER_PRIVATE_DATA *Private;
713 SD_DEVICE *Device;
714 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
715 EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
716 EFI_BLOCK_IO_PROTOCOL *BlockIo;
717 LIST_ENTRY *Link;
718 LIST_ENTRY *NextLink;
719 SD_REQUEST *Request;
720 EFI_TPL OldTpl;
721
722 if (NumberOfChildren == 0) {
723 Status = gBS->OpenProtocol (
724 Controller,
725 &gEfiCallerIdGuid,
726 (VOID **) &Private,
727 This->DriverBindingHandle,
728 Controller,
729 EFI_OPEN_PROTOCOL_GET_PROTOCOL
730 );
731 if (EFI_ERROR (Status)) {
732 return EFI_DEVICE_ERROR;
733 }
734
735 gBS->UninstallProtocolInterface (
736 Controller,
737 &gEfiCallerIdGuid,
738 Private
739 );
740 gBS->CloseProtocol (
741 Controller,
742 &gEfiSdMmcPassThruProtocolGuid,
743 This->DriverBindingHandle,
744 Controller
745 );
746
747 FreePool (Private);
748
749 return EFI_SUCCESS;
750 }
751
752 AllChildrenStopped = TRUE;
753
754 for (Index = 0; Index < NumberOfChildren; Index++) {
755 BlockIo = NULL;
756 BlockIo2 = NULL;
757 Status = gBS->OpenProtocol (
758 ChildHandleBuffer[Index],
759 &gEfiBlockIoProtocolGuid,
760 (VOID **) &BlockIo,
761 This->DriverBindingHandle,
762 Controller,
763 EFI_OPEN_PROTOCOL_GET_PROTOCOL
764 );
765 if (EFI_ERROR (Status)) {
766 Status = gBS->OpenProtocol (
767 ChildHandleBuffer[Index],
768 &gEfiBlockIo2ProtocolGuid,
769 (VOID **) &BlockIo2,
770 This->DriverBindingHandle,
771 Controller,
772 EFI_OPEN_PROTOCOL_GET_PROTOCOL
773 );
774 if (EFI_ERROR (Status)) {
775 AllChildrenStopped = FALSE;
776 continue;
777 }
778 }
779
780 if (BlockIo != NULL) {
781 Device = SD_DEVICE_DATA_FROM_BLKIO (BlockIo);
782 } else {
783 ASSERT (BlockIo2 != NULL);
784 Device = SD_DEVICE_DATA_FROM_BLKIO2 (BlockIo2);
785 }
786
787 //
788 // Free all on-going async tasks.
789 //
790 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
791 for (Link = GetFirstNode (&Device->Queue);
792 !IsNull (&Device->Queue, Link);
793 Link = NextLink) {
794 NextLink = GetNextNode (&Device->Queue, Link);
795 RemoveEntryList (Link);
796
797 Request = SD_REQUEST_FROM_LINK (Link);
798
799 gBS->CloseEvent (Request->Event);
800 Request->Token->TransactionStatus = EFI_ABORTED;
801
802 if (Request->IsEnd) {
803 gBS->SignalEvent (Request->Token->Event);
804 }
805
806 FreePool (Request);
807 }
808 gBS->RestoreTPL (OldTpl);
809
810 //
811 // Close the child handle
812 //
813 Status = gBS->CloseProtocol (
814 Controller,
815 &gEfiSdMmcPassThruProtocolGuid,
816 This->DriverBindingHandle,
817 ChildHandleBuffer[Index]
818 );
819
820 Status = gBS->UninstallMultipleProtocolInterfaces (
821 ChildHandleBuffer[Index],
822 &gEfiDevicePathProtocolGuid,
823 Device->DevicePath,
824 &gEfiBlockIoProtocolGuid,
825 &Device->BlockIo,
826 &gEfiBlockIo2ProtocolGuid,
827 &Device->BlockIo2,
828 NULL
829 );
830 if (EFI_ERROR (Status)) {
831 AllChildrenStopped = FALSE;
832 gBS->OpenProtocol (
833 Controller,
834 &gEfiSdMmcPassThruProtocolGuid,
835 (VOID **)&PassThru,
836 This->DriverBindingHandle,
837 ChildHandleBuffer[Index],
838 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
839 );
840 } else {
841 FreePool (Device->DevicePath);
842 FreeUnicodeStringTable (Device->ControllerNameTable);
843 FreePool (Device);
844 }
845 }
846
847 if (!AllChildrenStopped) {
848 return EFI_DEVICE_ERROR;
849 }
850
851 return EFI_SUCCESS;
852 }
853
854 /**
855 The user Entry Point for module SdDxe. The user code starts with this function.
856
857 @param[in] ImageHandle The firmware allocated handle for the EFI image.
858 @param[in] SystemTable A pointer to the EFI System Table.
859
860 @retval EFI_SUCCESS The entry point is executed successfully.
861 @retval other Some errors occur when executing this entry point.
862
863 **/
864 EFI_STATUS
865 EFIAPI
866 InitializeSdDxe (
867 IN EFI_HANDLE ImageHandle,
868 IN EFI_SYSTEM_TABLE *SystemTable
869 )
870 {
871 EFI_STATUS Status;
872
873 //
874 // Install driver model protocol(s).
875 //
876 Status = EfiLibInstallDriverBindingComponentName2 (
877 ImageHandle,
878 SystemTable,
879 &gSdDxeDriverBinding,
880 ImageHandle,
881 &gSdDxeComponentName,
882 &gSdDxeComponentName2
883 );
884 ASSERT_EFI_ERROR (Status);
885
886 return Status;
887 }
888