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