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