Home | History | Annotate | Download | only in SDMediaDeviceDxe
      1 /** @file
      2 
      3 The definition for SD media device driver model and blkio protocol routines.
      4 
      5 Copyright (c) 2013-2015 Intel Corporation.
      6 
      7 This program and the accompanying materials
      8 are licensed and made available under the terms and conditions of the BSD License
      9 which accompanies this distribution.  The full text of the license may be found at
     10 http://opensource.org/licenses/bsd-license.php
     11 
     12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 
     18 #include "SDMediaDevice.h"
     19 
     20 
     21 EFI_DRIVER_BINDING_PROTOCOL gSDMediaDeviceDriverBinding = {
     22   SDMediaDeviceSupported,
     23   SDMediaDeviceStart,
     24   SDMediaDeviceStop,
     25   0x20,
     26   NULL,
     27   NULL
     28 };
     29 
     30 /**
     31   Entry point for EFI drivers.
     32 
     33   @param  ImageHandle      EFI_HANDLE.
     34   @param  SystemTable      EFI_SYSTEM_TABLE.
     35 
     36   @retval EFI_SUCCESS      Driver is successfully loaded.
     37   @return Others           Failed.
     38 
     39 **/
     40 EFI_STATUS
     41 EFIAPI
     42 InitializeSDMediaDevice (
     43   IN EFI_HANDLE           ImageHandle,
     44   IN EFI_SYSTEM_TABLE     *SystemTable
     45   )
     46 {
     47   return EfiLibInstallDriverBindingComponentName2 (
     48            ImageHandle,
     49            SystemTable,
     50            &gSDMediaDeviceDriverBinding,
     51            ImageHandle,
     52            &gSDMediaDeviceName,
     53            &gSDMediaDeviceName2
     54            );
     55 }
     56 
     57 
     58 /**
     59   Test to see if this driver supports ControllerHandle. Any
     60   ControllerHandle that has BlockIoProtocol installed will be supported.
     61 
     62   @param  This                 Protocol instance pointer.
     63   @param  Controller           Handle of device to test.
     64   @param  RemainingDevicePath  Not used.
     65 
     66   @return EFI_SUCCESS          This driver supports this device.
     67   @return EFI_UNSUPPORTED      This driver does not support this device.
     68 
     69 **/
     70 EFI_STATUS
     71 EFIAPI
     72 SDMediaDeviceSupported (
     73   IN EFI_DRIVER_BINDING_PROTOCOL     *This,
     74   IN EFI_HANDLE                      Controller,
     75   IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
     76   )
     77 {
     78   EFI_STATUS                Status;
     79   EFI_SD_HOST_IO_PROTOCOL   *SDHostIo;
     80 
     81   //
     82   // Test whether there is PCI IO Protocol attached on the controller handle.
     83   //
     84   Status = gBS->OpenProtocol (
     85                   Controller,
     86                   &gEfiSDHostIoProtocolGuid,
     87                   (VOID **)&SDHostIo,
     88                   This->DriverBindingHandle,
     89                   Controller,
     90                   EFI_OPEN_PROTOCOL_BY_DRIVER
     91                   );
     92   if (EFI_ERROR (Status)) {
     93     goto Exit;
     94   }
     95 
     96   gBS->CloseProtocol (
     97          Controller,
     98          &gEfiSDHostIoProtocolGuid,
     99          This->DriverBindingHandle,
    100          Controller
    101          );
    102 
    103 Exit:
    104   return Status;
    105 }
    106 
    107 /**
    108   Starting the SD Media Device Driver.
    109 
    110   @param  This                 Protocol instance pointer.
    111   @param  Controller           Handle of device to test.
    112   @param  RemainingDevicePath  Not used.
    113 
    114   @retval EFI_SUCCESS          This driver supports this device.
    115   @retval EFI_UNSUPPORTED      This driver does not support this device.
    116   @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error.
    117                                EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
    118 
    119 **/
    120 EFI_STATUS
    121 EFIAPI
    122 SDMediaDeviceStart (
    123   IN EFI_DRIVER_BINDING_PROTOCOL     *This,
    124   IN EFI_HANDLE                      Controller,
    125   IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
    126   )
    127 {
    128   EFI_STATUS                Status;
    129   EFI_SD_HOST_IO_PROTOCOL   *SDHostIo;
    130   CARD_DATA                 *CardData;
    131 
    132   CardData = NULL;
    133 
    134   //
    135   // Open PCI I/O Protocol and save pointer to open protocol
    136   // in private data area.
    137   //
    138   Status = gBS->OpenProtocol (
    139                   Controller,
    140                   &gEfiSDHostIoProtocolGuid,
    141                   (VOID **) &SDHostIo,
    142                   This->DriverBindingHandle,
    143                   Controller,
    144                   EFI_OPEN_PROTOCOL_BY_DRIVER
    145                   );
    146   if (EFI_ERROR (Status)) {
    147     DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to open gEfiSDHostIoProtocolGuid \r\n"));
    148     goto Exit;
    149   }
    150 
    151   Status = SDHostIo->DetectCardAndInitHost (SDHostIo);
    152   if (EFI_ERROR (Status)) {
    153     DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: Fail to DetectCardAndInitHost \r\n"));
    154     goto Exit;
    155   }
    156 
    157   CardData = (CARD_DATA*)AllocateZeroPool(sizeof (CARD_DATA));
    158   if (CardData == NULL) {
    159     Status =  EFI_OUT_OF_RESOURCES;
    160     DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(CARD_DATA) \r\n"));
    161     goto Exit;
    162   }
    163 
    164   ASSERT (SDHostIo->HostCapability.BoundarySize >= 4 * 1024);
    165   CardData->RawBufferPointer = (UINT8*)((UINTN)DMA_MEMORY_TOP);
    166   Status = gBS->AllocatePages (
    167                   AllocateMaxAddress,
    168                   EfiBootServicesData,
    169                   EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize),
    170                   (EFI_PHYSICAL_ADDRESS *)(&CardData->RawBufferPointer)
    171                   );
    172 
    173   if (CardData->RawBufferPointer == NULL) {
    174     DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(2*x) \r\n"));
    175     Status =  EFI_OUT_OF_RESOURCES;
    176     goto Exit;
    177   }
    178   CardData->AlignedBuffer = CardData->RawBufferPointer - ((UINTN)(CardData->RawBufferPointer) & (SDHostIo->HostCapability.BoundarySize - 1)) + SDHostIo->HostCapability.BoundarySize;
    179 
    180   CardData->Signature = CARD_DATA_SIGNATURE;
    181   CardData->SDHostIo  = SDHostIo;
    182 
    183   Status = MMCSDCardInit (CardData);
    184   if (EFI_ERROR (Status)) {
    185     DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to MMCSDCardInit \r\n"));
    186     goto Exit;
    187   }
    188   DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: MMCSDCardInit SuccessFul\n"));
    189 
    190   if (CardData->CardType == CEATACard) {
    191     Status = CEATABlockIoInit (CardData);
    192   } else {
    193     Status = MMCSDBlockIoInit (CardData);
    194   }
    195 
    196   if (EFI_ERROR (Status)) {
    197     DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to BlockIoInit \r\n"));
    198     goto Exit;
    199   }
    200   DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: BlockIo is successfully installed\n"));
    201 
    202 
    203   Status = gBS->InstallProtocolInterface (
    204                   &Controller,
    205                   &gEfiBlockIoProtocolGuid,
    206                   EFI_NATIVE_INTERFACE,
    207                   &CardData->BlockIo
    208                   );
    209   if (EFI_ERROR (Status)) {
    210     DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to install gEfiBlockIoProtocolGuid \r\n"));
    211     goto Exit;
    212   }
    213 
    214   //
    215   // Install the component name protocol
    216   //
    217   CardData->ControllerNameTable = NULL;
    218 
    219   AddUnicodeString2 (
    220     "eng",
    221     gSDMediaDeviceName.SupportedLanguages,
    222     &CardData->ControllerNameTable,
    223     L"MMC/SD Media Device",
    224     TRUE
    225     );
    226   AddUnicodeString2 (
    227     "en",
    228     gSDMediaDeviceName2.SupportedLanguages,
    229     &CardData->ControllerNameTable,
    230     L"MMC/SD Media Device",
    231     FALSE
    232     );
    233 
    234 Exit:
    235   if (EFI_ERROR (Status)) {
    236     DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: End with failure\r\n"));
    237     if (CardData != NULL) {
    238       if (CardData->RawBufferPointer != NULL) {
    239         gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize));
    240       }
    241       FreePool (CardData);
    242     }
    243   }
    244 
    245   return Status;
    246 }
    247 
    248 
    249 /**
    250   Stop this driver on ControllerHandle. Support stoping any child handles
    251   created by this driver.
    252 
    253   @param  This                 Protocol instance pointer.
    254   @param  Controller           Handle of device to stop driver on.
    255   @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
    256   @param  ChildHandleBuffer    List of handles for the children we need to stop.
    257 
    258   @return EFI_SUCCESS
    259   @return others
    260 
    261 **/
    262 EFI_STATUS
    263 EFIAPI
    264 SDMediaDeviceStop (
    265   IN EFI_DRIVER_BINDING_PROTOCOL     *This,
    266   IN EFI_HANDLE                      Controller,
    267   IN UINTN                           NumberOfChildren,
    268   IN EFI_HANDLE                      *ChildHandleBuffer
    269   )
    270 {
    271   EFI_STATUS                Status;
    272   CARD_DATA                 *CardData;
    273   EFI_BLOCK_IO_PROTOCOL     *BlockIo;
    274 
    275   //
    276   // First find BlockIo Protocol
    277   //
    278   Status = gBS->OpenProtocol (
    279                   Controller,
    280                   &gEfiBlockIoProtocolGuid,
    281                   (VOID **)&BlockIo,
    282                   This->DriverBindingHandle,
    283                   Controller,
    284                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    285                   );
    286   if (EFI_ERROR (Status)) {
    287     return Status;
    288   }
    289 
    290   CardData  = CARD_DATA_FROM_THIS(BlockIo);
    291 
    292   //
    293   // Uninstall Block I/O protocol from the device handle
    294   //
    295   Status = gBS->UninstallProtocolInterface (
    296                   Controller,
    297                   &gEfiBlockIoProtocolGuid,
    298                   BlockIo
    299                   );
    300   if (EFI_ERROR (Status)) {
    301     return Status;
    302   }
    303 
    304   if (CardData != NULL) {
    305     if (CardData->RawBufferPointer != NULL) {
    306       gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * CardData->SDHostIo->HostCapability.BoundarySize));
    307     }
    308     FreeUnicodeStringTable (CardData->ControllerNameTable);
    309     FreePool (CardData);
    310   }
    311 
    312   gBS->CloseProtocol (
    313          Controller,
    314          &gEfiSDHostIoProtocolGuid,
    315          This->DriverBindingHandle,
    316          Controller
    317          );
    318 
    319   return EFI_SUCCESS;
    320 }
    321 
    322 
    323 
    324