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