]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Sd/SdDxe/SdDxe.c
fc060fdb3465ad7a0f8c1f0aee69e055f56c77e1
[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 - 2017, 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 { // EraseBlock
68 EFI_ERASE_BLOCK_PROTOCOL_REVISION,
69 1,
70 SdEraseBlocks
71 },
72 { // DiskInfo
73 EFI_DISK_INFO_SD_MMC_INTERFACE_GUID,
74 SdDiskInfoInquiry,
75 SdDiskInfoIdentify,
76 SdDiskInfoSenseData,
77 SdDiskInfoWhichIde
78 },
79 { // Queue
80 NULL,
81 NULL
82 },
83 { // Csd
84 0,
85 },
86 { // Cid
87 0,
88 },
89 NULL, // ControllerNameTable
90 { // ModelName
91 0,
92 },
93 NULL // Private
94 };
95
96 /**
97 Decode and print SD CSD Register content.
98
99 @param[in] Csd Pointer to SD_CSD data structure.
100
101 @retval EFI_SUCCESS The function completed successfully
102 **/
103 EFI_STATUS
104 DumpCsd (
105 IN SD_CSD *Csd
106 )
107 {
108 SD_CSD2 *Csd2;
109
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));
127 } else {
128 Csd2 = (SD_CSD2*)(VOID*)Csd;
129 DEBUG((DEBUG_INFO, " Device size 0x%x\n", Csd2->CSizeLow | (Csd->CSizeHigh << 16)));
130 }
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));
143
144 return EFI_SUCCESS;
145 }
146
147 /**
148 Get SD device model name.
149
150 @param[in, out] Device The pointer to the SD_DEVICE data structure.
151 @param[in] Cid Pointer to SD_CID data structure.
152
153 @retval EFI_SUCCESS The function completed successfully
154
155 **/
156 EFI_STATUS
157 GetSdModelName (
158 IN OUT SD_DEVICE *Device,
159 IN SD_CID *Cid
160 )
161 {
162 CHAR8 String[SD_MODEL_NAME_MAX_LEN];
163
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));
170
171 AsciiStrToUnicodeStrS (String, Device->ModelName, sizeof (Device->ModelName) / sizeof (Device->ModelName[0]));
172
173 return EFI_SUCCESS;
174 }
175
176 /**
177 Discover user area partition in the SD device.
178
179 @param[in] Device The pointer to the SD_DEVICE data structure.
180
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.
183
184 **/
185 EFI_STATUS
186 DiscoverUserArea (
187 IN SD_DEVICE *Device
188 )
189 {
190 EFI_STATUS Status;
191 SD_CSD *Csd;
192 SD_CSD2 *Csd2;
193 SD_CID *Cid;
194 UINT64 Capacity;
195 UINT32 DevStatus;
196 UINT16 Rca;
197 UINT32 CSize;
198 UINT32 CSizeMul;
199 UINT32 ReadBlLen;
200
201 //
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.
205 //
206 SdSelect (Device, 0);
207
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));
211 return Status;
212 }
213
214 Csd = &Device->Csd;
215 Status = SdGetCsd (Device, Rca, Csd);
216 if (EFI_ERROR (Status)) {
217 return Status;
218 }
219 DumpCsd (Csd);
220
221 Cid = &Device->Cid;
222 Status = SdGetCid (Device, Rca, Cid);
223 if (EFI_ERROR (Status)) {
224 return Status;
225 }
226 GetSdModelName (Device, Cid);
227
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));
231 return Status;
232 }
233
234 Status = SdSendStatus (Device, Rca, &DevStatus);
235 if (EFI_ERROR (Status)) {
236 return Status;
237 }
238
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);
245 } else {
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);
250 }
251
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;
261
262 if (Csd->EraseBlkEn) {
263 Device->EraseBlock.EraseLengthGranularity = 1;
264 } else {
265 Device->EraseBlock.EraseLengthGranularity = (Csd->SectorSize + 1) * (1 << (Csd->WriteBlLen - 9));
266 }
267
268 return Status;
269 }
270
271 /**
272 Scan SD Bus to discover the device.
273
274 @param[in] Private The SD driver private data structure.
275 @param[in] Slot The slot number to check device present.
276
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
280 of resources.
281 @retval EFI_ALREADY_STARTED The device was discovered before.
282 @retval Others Fail to discover the device.
283
284 **/
285 EFI_STATUS
286 EFIAPI
287 DiscoverSdDevice (
288 IN SD_DRIVER_PRIVATE_DATA *Private,
289 IN UINT8 Slot
290 )
291 {
292 EFI_STATUS Status;
293 SD_DEVICE *Device;
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;
299
300 Device = NULL;
301 DevicePath = NULL;
302 NewDevicePath = NULL;
303 RemainingDevicePath = NULL;
304 PassThru = Private->PassThru;
305
306 //
307 // Build Device Path
308 //
309 Status = PassThru->BuildDevicePath (
310 PassThru,
311 Slot,
312 &DevicePath
313 );
314 if (EFI_ERROR(Status)) {
315 return Status;
316 }
317
318 if (DevicePath->SubType != MSG_SD_DP) {
319 Status = EFI_UNSUPPORTED;
320 goto Error;
321 }
322
323 NewDevicePath = AppendDevicePathNode (
324 Private->ParentDevicePath,
325 DevicePath
326 );
327
328 if (NewDevicePath == NULL) {
329 Status = EFI_OUT_OF_RESOURCES;
330 goto Error;
331 }
332
333 DeviceHandle = NULL;
334 RemainingDevicePath = NewDevicePath;
335 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
336 if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
337 //
338 // The device has been started, directly return to fast boot.
339 //
340 Status = EFI_ALREADY_STARTED;
341 goto Error;
342 }
343
344 //
345 // Allocate buffer to store SD_DEVICE private data.
346 //
347 Device = AllocateCopyPool (sizeof (SD_DEVICE), &mSdDeviceTemplate);
348 if (Device == NULL) {
349 Status = EFI_OUT_OF_RESOURCES;
350 goto Error;
351 }
352
353 Device->DevicePath = NewDevicePath;
354 Device->Slot = Slot;
355 Device->Private = Private;
356 InitializeListHead (&Device->Queue);
357
358 //
359 // Expose user area in the Sd memory card to upper layer.
360 //
361 Status = DiscoverUserArea (Device);
362 if (EFI_ERROR(Status)) {
363 goto Error;
364 }
365
366 Device->ControllerNameTable = NULL;
367 AddUnicodeString2 (
368 "eng",
369 gSdDxeComponentName.SupportedLanguages,
370 &Device->ControllerNameTable,
371 Device->ModelName,
372 TRUE
373 );
374 AddUnicodeString2 (
375 "en",
376 gSdDxeComponentName.SupportedLanguages,
377 &Device->ControllerNameTable,
378 Device->ModelName,
379 FALSE
380 );
381
382 Status = gBS->InstallMultipleProtocolInterfaces (
383 &Device->Handle,
384 &gEfiDevicePathProtocolGuid,
385 Device->DevicePath,
386 &gEfiBlockIoProtocolGuid,
387 &Device->BlockIo,
388 &gEfiBlockIo2ProtocolGuid,
389 &Device->BlockIo2,
390 &gEfiEraseBlockProtocolGuid,
391 &Device->EraseBlock,
392 &gEfiDiskInfoProtocolGuid,
393 &Device->DiskInfo,
394 NULL
395 );
396
397 if (!EFI_ERROR (Status)) {
398 gBS->OpenProtocol (
399 Private->Controller,
400 &gEfiSdMmcPassThruProtocolGuid,
401 (VOID **) &(Private->PassThru),
402 Private->DriverBindingHandle,
403 Device->Handle,
404 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
405 );
406 }
407
408 Error:
409 FreePool (DevicePath);
410
411 if (EFI_ERROR (Status) && (NewDevicePath != NULL)) {
412 FreePool (NewDevicePath);
413 }
414
415 if (EFI_ERROR (Status) && (Device != NULL)) {
416 FreePool (Device);
417 }
418
419 return Status;
420 }
421
422 /**
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.
425
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.
439
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
450 bus driver.
451
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
456 specified by This.
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.
463 **/
464 EFI_STATUS
465 EFIAPI
466 SdDxeDriverBindingSupported (
467 IN EFI_DRIVER_BINDING_PROTOCOL *This,
468 IN EFI_HANDLE Controller,
469 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
470 )
471 {
472 EFI_STATUS Status;
473 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
474 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
475 UINT8 Slot;
476
477 //
478 // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle.
479 //
480 Status = gBS->OpenProtocol (
481 Controller,
482 &gEfiSdMmcPassThruProtocolGuid,
483 (VOID**) &PassThru,
484 This->DriverBindingHandle,
485 Controller,
486 EFI_OPEN_PROTOCOL_BY_DRIVER
487 );
488
489 if (Status == EFI_ALREADY_STARTED) {
490 return EFI_SUCCESS;
491 }
492
493 if (EFI_ERROR (Status)) {
494 return Status;
495 }
496
497 //
498 // Test RemainingDevicePath is valid or not.
499 //
500 if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
501 Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
502 if (EFI_ERROR (Status)) {
503 //
504 // Close the I/O Abstraction(s) used to perform the supported test
505 //
506 gBS->CloseProtocol (
507 Controller,
508 &gEfiSdMmcPassThruProtocolGuid,
509 This->DriverBindingHandle,
510 Controller
511 );
512 return Status;
513 }
514 }
515
516 //
517 // Close the I/O Abstraction(s) used to perform the supported test
518 //
519 gBS->CloseProtocol (
520 Controller,
521 &gEfiSdMmcPassThruProtocolGuid,
522 This->DriverBindingHandle,
523 Controller
524 );
525
526 //
527 // Open the EFI Device Path protocol needed to perform the supported test
528 //
529 Status = gBS->OpenProtocol (
530 Controller,
531 &gEfiDevicePathProtocolGuid,
532 (VOID **) &ParentDevicePath,
533 This->DriverBindingHandle,
534 Controller,
535 EFI_OPEN_PROTOCOL_GET_PROTOCOL
536 );
537 return Status;
538 }
539
540 /**
541 Starts a device controller or a bus controller.
542
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.
552
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
567 driver.
568
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.
573
574 **/
575 EFI_STATUS
576 EFIAPI
577 SdDxeDriverBindingStart (
578 IN EFI_DRIVER_BINDING_PROTOCOL *This,
579 IN EFI_HANDLE Controller,
580 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
581 )
582 {
583 EFI_STATUS Status;
584 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
585 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
586 SD_DRIVER_PRIVATE_DATA *Private;
587 UINT8 Slot;
588
589 Private = NULL;
590 PassThru = NULL;
591 Status = gBS->OpenProtocol (
592 Controller,
593 &gEfiSdMmcPassThruProtocolGuid,
594 (VOID **) &PassThru,
595 This->DriverBindingHandle,
596 Controller,
597 EFI_OPEN_PROTOCOL_BY_DRIVER
598 );
599 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
600 return Status;
601 }
602
603 //
604 // Check EFI_ALREADY_STARTED to reuse the original SD_DRIVER_PRIVATE_DATA.
605 //
606 if (Status != EFI_ALREADY_STARTED) {
607 Private = AllocateZeroPool (sizeof (SD_DRIVER_PRIVATE_DATA));
608 if (Private == NULL) {
609 Status = EFI_OUT_OF_RESOURCES;
610 goto Error;
611 }
612
613 Status = gBS->OpenProtocol (
614 Controller,
615 &gEfiDevicePathProtocolGuid,
616 (VOID **) &ParentDevicePath,
617 This->DriverBindingHandle,
618 Controller,
619 EFI_OPEN_PROTOCOL_GET_PROTOCOL
620 );
621 ASSERT_EFI_ERROR (Status);
622 Private->PassThru = PassThru;
623 Private->Controller = Controller;
624 Private->ParentDevicePath = ParentDevicePath;
625 Private->DriverBindingHandle = This->DriverBindingHandle;
626
627 Status = gBS->InstallProtocolInterface (
628 &Controller,
629 &gEfiCallerIdGuid,
630 EFI_NATIVE_INTERFACE,
631 Private
632 );
633 if (EFI_ERROR (Status)) {
634 goto Error;
635 }
636 } else {
637 Status = gBS->OpenProtocol (
638 Controller,
639 &gEfiCallerIdGuid,
640 (VOID **) &Private,
641 This->DriverBindingHandle,
642 Controller,
643 EFI_OPEN_PROTOCOL_GET_PROTOCOL
644 );
645 if (EFI_ERROR (Status)) {
646 goto Error;
647 }
648 }
649
650 if (RemainingDevicePath == NULL) {
651 Slot = 0xFF;
652 while (TRUE) {
653 Status = PassThru->GetNextSlot (PassThru, &Slot);
654 if (EFI_ERROR (Status)) {
655 //
656 // Cannot find more legal slots.
657 //
658 Status = EFI_SUCCESS;
659 break;
660 }
661
662 Status = DiscoverSdDevice (Private, Slot);
663 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
664 break;
665 }
666 }
667 } else if (!IsDevicePathEnd (RemainingDevicePath)) {
668 Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
669 if (!EFI_ERROR (Status)) {
670 Status = DiscoverSdDevice (Private, Slot);
671 }
672 }
673
674 Error:
675 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
676 gBS->CloseProtocol (
677 Controller,
678 &gEfiSdMmcPassThruProtocolGuid,
679 This->DriverBindingHandle,
680 Controller
681 );
682
683 if (Private != NULL) {
684 gBS->UninstallMultipleProtocolInterfaces (
685 Controller,
686 &gEfiCallerIdGuid,
687 Private,
688 NULL
689 );
690 FreePool (Private);
691 }
692 }
693 return Status;
694 }
695
696 /**
697 Stops a device controller or a bus controller.
698
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.
709
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.
717
718 @retval EFI_SUCCESS The device was stopped.
719 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
720
721 **/
722 EFI_STATUS
723 EFIAPI
724 SdDxeDriverBindingStop (
725 IN EFI_DRIVER_BINDING_PROTOCOL *This,
726 IN EFI_HANDLE Controller,
727 IN UINTN NumberOfChildren,
728 IN EFI_HANDLE *ChildHandleBuffer
729 )
730 {
731 EFI_STATUS Status;
732 BOOLEAN AllChildrenStopped;
733 UINTN Index;
734 SD_DRIVER_PRIVATE_DATA *Private;
735 SD_DEVICE *Device;
736 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
737 EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
738 EFI_BLOCK_IO_PROTOCOL *BlockIo;
739 LIST_ENTRY *Link;
740 LIST_ENTRY *NextLink;
741 SD_REQUEST *Request;
742 EFI_TPL OldTpl;
743
744 if (NumberOfChildren == 0) {
745 Status = gBS->OpenProtocol (
746 Controller,
747 &gEfiCallerIdGuid,
748 (VOID **) &Private,
749 This->DriverBindingHandle,
750 Controller,
751 EFI_OPEN_PROTOCOL_GET_PROTOCOL
752 );
753 if (EFI_ERROR (Status)) {
754 return EFI_DEVICE_ERROR;
755 }
756
757 gBS->UninstallProtocolInterface (
758 Controller,
759 &gEfiCallerIdGuid,
760 Private
761 );
762 gBS->CloseProtocol (
763 Controller,
764 &gEfiSdMmcPassThruProtocolGuid,
765 This->DriverBindingHandle,
766 Controller
767 );
768
769 FreePool (Private);
770
771 return EFI_SUCCESS;
772 }
773
774 AllChildrenStopped = TRUE;
775
776 for (Index = 0; Index < NumberOfChildren; Index++) {
777 BlockIo = NULL;
778 BlockIo2 = NULL;
779 Status = gBS->OpenProtocol (
780 ChildHandleBuffer[Index],
781 &gEfiBlockIoProtocolGuid,
782 (VOID **) &BlockIo,
783 This->DriverBindingHandle,
784 Controller,
785 EFI_OPEN_PROTOCOL_GET_PROTOCOL
786 );
787 if (EFI_ERROR (Status)) {
788 Status = gBS->OpenProtocol (
789 ChildHandleBuffer[Index],
790 &gEfiBlockIo2ProtocolGuid,
791 (VOID **) &BlockIo2,
792 This->DriverBindingHandle,
793 Controller,
794 EFI_OPEN_PROTOCOL_GET_PROTOCOL
795 );
796 if (EFI_ERROR (Status)) {
797 AllChildrenStopped = FALSE;
798 continue;
799 }
800 }
801
802 if (BlockIo != NULL) {
803 Device = SD_DEVICE_DATA_FROM_BLKIO (BlockIo);
804 } else {
805 ASSERT (BlockIo2 != NULL);
806 Device = SD_DEVICE_DATA_FROM_BLKIO2 (BlockIo2);
807 }
808
809 //
810 // Free all on-going async tasks.
811 //
812 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
813 for (Link = GetFirstNode (&Device->Queue);
814 !IsNull (&Device->Queue, Link);
815 Link = NextLink) {
816 NextLink = GetNextNode (&Device->Queue, Link);
817 RemoveEntryList (Link);
818
819 Request = SD_REQUEST_FROM_LINK (Link);
820
821 gBS->CloseEvent (Request->Event);
822 Request->Token->TransactionStatus = EFI_ABORTED;
823
824 if (Request->IsEnd) {
825 gBS->SignalEvent (Request->Token->Event);
826 }
827
828 FreePool (Request);
829 }
830 gBS->RestoreTPL (OldTpl);
831
832 //
833 // Close the child handle
834 //
835 Status = gBS->CloseProtocol (
836 Controller,
837 &gEfiSdMmcPassThruProtocolGuid,
838 This->DriverBindingHandle,
839 ChildHandleBuffer[Index]
840 );
841
842 Status = gBS->UninstallMultipleProtocolInterfaces (
843 ChildHandleBuffer[Index],
844 &gEfiDevicePathProtocolGuid,
845 Device->DevicePath,
846 &gEfiBlockIoProtocolGuid,
847 &Device->BlockIo,
848 &gEfiBlockIo2ProtocolGuid,
849 &Device->BlockIo2,
850 &gEfiEraseBlockProtocolGuid,
851 &Device->EraseBlock,
852 &gEfiDiskInfoProtocolGuid,
853 &Device->DiskInfo,
854 NULL
855 );
856 if (EFI_ERROR (Status)) {
857 AllChildrenStopped = FALSE;
858 gBS->OpenProtocol (
859 Controller,
860 &gEfiSdMmcPassThruProtocolGuid,
861 (VOID **)&PassThru,
862 This->DriverBindingHandle,
863 ChildHandleBuffer[Index],
864 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
865 );
866 } else {
867 FreePool (Device->DevicePath);
868 FreeUnicodeStringTable (Device->ControllerNameTable);
869 FreePool (Device);
870 }
871 }
872
873 if (!AllChildrenStopped) {
874 return EFI_DEVICE_ERROR;
875 }
876
877 return EFI_SUCCESS;
878 }
879
880 /**
881 The user Entry Point for module SdDxe. The user code starts with this function.
882
883 @param[in] ImageHandle The firmware allocated handle for the EFI image.
884 @param[in] SystemTable A pointer to the EFI System Table.
885
886 @retval EFI_SUCCESS The entry point is executed successfully.
887 @retval other Some errors occur when executing this entry point.
888
889 **/
890 EFI_STATUS
891 EFIAPI
892 InitializeSdDxe (
893 IN EFI_HANDLE ImageHandle,
894 IN EFI_SYSTEM_TABLE *SystemTable
895 )
896 {
897 EFI_STATUS Status;
898
899 //
900 // Install driver model protocol(s).
901 //
902 Status = EfiLibInstallDriverBindingComponentName2 (
903 ImageHandle,
904 SystemTable,
905 &gSdDxeDriverBinding,
906 ImageHandle,
907 &gSdDxeComponentName,
908 &gSdDxeComponentName2
909 );
910 ASSERT_EFI_ERROR (Status);
911
912 return Status;
913 }
914