19b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** @file
29b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
39b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyThe definition for SD media device driver model and blkio protocol routines.
49b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
59b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyCopyright (c) 2013-2015 Intel Corporation.
69b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
79b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyThis program and the accompanying materials
89b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyare licensed and made available under the terms and conditions of the BSD License
99b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneywhich accompanies this distribution.  The full text of the license may be found at
109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyhttp://opensource.org/licenses/bsd-license.php
119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/
169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "SDMediaDevice.h"
199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_DRIVER_BINDING_PROTOCOL gSDMediaDeviceDriverBinding = {
229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  SDMediaDeviceSupported,
239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  SDMediaDeviceStart,
249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  SDMediaDeviceStop,
259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  0x20,
269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  NULL,
279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  NULL
289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney};
299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/**
319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Entry point for EFI drivers.
329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  ImageHandle      EFI_HANDLE.
349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  SystemTable      EFI_SYSTEM_TABLE.
359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @retval EFI_SUCCESS      Driver is successfully loaded.
379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @return Others           Failed.
389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/
409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS
419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI
429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyInitializeSDMediaDevice (
439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_HANDLE           ImageHandle,
449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_SYSTEM_TABLE     *SystemTable
459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  )
469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{
479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  return EfiLibInstallDriverBindingComponentName2 (
489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney           ImageHandle,
499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney           SystemTable,
509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney           &gSDMediaDeviceDriverBinding,
519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney           ImageHandle,
529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney           &gSDMediaDeviceName,
539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney           &gSDMediaDeviceName2
549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney           );
559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney}
569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/**
599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Test to see if this driver supports ControllerHandle. Any
609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  ControllerHandle that has BlockIoProtocol installed will be supported.
619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  This                 Protocol instance pointer.
639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  Controller           Handle of device to test.
649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  RemainingDevicePath  Not used.
659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @return EFI_SUCCESS          This driver supports this device.
679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @return EFI_UNSUPPORTED      This driver does not support this device.
689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/
709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS
719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI
729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneySDMediaDeviceSupported (
739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_HANDLE                      Controller,
759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  )
779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{
789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  EFI_STATUS                Status;
799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  EFI_SD_HOST_IO_PROTOCOL   *SDHostIo;
809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  // Test whether there is PCI IO Protocol attached on the controller handle.
839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = gBS->OpenProtocol (
859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  Controller,
869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  &gEfiSDHostIoProtocolGuid,
879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  (VOID **)&SDHostIo,
889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  This->DriverBindingHandle,
899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  Controller,
909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  EFI_OPEN_PROTOCOL_BY_DRIVER
919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  );
929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  gBS->CloseProtocol (
979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         Controller,
989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         &gEfiSDHostIoProtocolGuid,
999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         This->DriverBindingHandle,
1009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         Controller
1019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         );
1029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyExit:
1049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  return Status;
1059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney}
1069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/**
1089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Starting the SD Media Device Driver.
1099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  This                 Protocol instance pointer.
1119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  Controller           Handle of device to test.
1129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  RemainingDevicePath  Not used.
1139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @retval EFI_SUCCESS          This driver supports this device.
1159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @retval EFI_UNSUPPORTED      This driver does not support this device.
1169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error.
1179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                               EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
1189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/
1209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS
1219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI
1229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneySDMediaDeviceStart (
1239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
1249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_HANDLE                      Controller,
1259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
1269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  )
1279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{
1289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  EFI_STATUS                Status;
1299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  EFI_SD_HOST_IO_PROTOCOL   *SDHostIo;
1309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CARD_DATA                 *CardData;
1319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData = NULL;
1339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
1359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  // Open PCI I/O Protocol and save pointer to open protocol
1369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  // in private data area.
1379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
1389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = gBS->OpenProtocol (
1399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  Controller,
1409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  &gEfiSDHostIoProtocolGuid,
1419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  (VOID **) &SDHostIo,
1429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  This->DriverBindingHandle,
1439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  Controller,
1449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  EFI_OPEN_PROTOCOL_BY_DRIVER
1459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  );
1469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
1479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to open gEfiSDHostIoProtocolGuid \r\n"));
1489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
1499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
1509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = SDHostIo->DetectCardAndInitHost (SDHostIo);
1529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
1539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: Fail to DetectCardAndInitHost \r\n"));
1549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
1559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
1569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData = (CARD_DATA*)AllocateZeroPool(sizeof (CARD_DATA));
1589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (CardData == NULL) {
1599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    Status =  EFI_OUT_OF_RESOURCES;
1609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(CARD_DATA) \r\n"));
1619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
1629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
1639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  ASSERT (SDHostIo->HostCapability.BoundarySize >= 4 * 1024);
1659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData->RawBufferPointer = (UINT8*)((UINTN)DMA_MEMORY_TOP);
1669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = gBS->AllocatePages (
1679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  AllocateMaxAddress,
1689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  EfiBootServicesData,
1699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize),
1709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  (EFI_PHYSICAL_ADDRESS *)(&CardData->RawBufferPointer)
1719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  );
1729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (CardData->RawBufferPointer == NULL) {
1749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(2*x) \r\n"));
1759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    Status =  EFI_OUT_OF_RESOURCES;
1769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
1779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
1789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData->AlignedBuffer = CardData->RawBufferPointer - ((UINTN)(CardData->RawBufferPointer) & (SDHostIo->HostCapability.BoundarySize - 1)) + SDHostIo->HostCapability.BoundarySize;
1799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData->Signature = CARD_DATA_SIGNATURE;
1819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData->SDHostIo  = SDHostIo;
1829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = MMCSDCardInit (CardData);
1849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
1859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to MMCSDCardInit \r\n"));
1869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
1879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
1889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: MMCSDCardInit SuccessFul\n"));
1899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (CardData->CardType == CEATACard) {
1919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    Status = CEATABlockIoInit (CardData);
1929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  } else {
1939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    Status = MMCSDBlockIoInit (CardData);
1949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
1959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
1969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
1979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to BlockIoInit \r\n"));
1989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
1999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
2009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: BlockIo is successfully installed\n"));
2019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = gBS->InstallProtocolInterface (
2049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  &Controller,
2059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  &gEfiBlockIoProtocolGuid,
2069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  EFI_NATIVE_INTERFACE,
2079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  &CardData->BlockIo
2089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  );
2099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
2109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to install gEfiBlockIoProtocolGuid \r\n"));
2119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    goto Exit;
2129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
2139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
2159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  // Install the component name protocol
2169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
2179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData->ControllerNameTable = NULL;
2189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  AddUnicodeString2 (
2209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    "eng",
2219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    gSDMediaDeviceName.SupportedLanguages,
2229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    &CardData->ControllerNameTable,
2239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    L"MMC/SD Media Device",
2249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    TRUE
2259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    );
2269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  AddUnicodeString2 (
2279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    "en",
2289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    gSDMediaDeviceName2.SupportedLanguages,
2299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    &CardData->ControllerNameTable,
2309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    L"MMC/SD Media Device",
2319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    FALSE
2329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    );
2339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyExit:
2359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
2369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: End with failure\r\n"));
2379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    if (CardData != NULL) {
2389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney      if (CardData->RawBufferPointer != NULL) {
2399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney        gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize));
2409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney      }
2419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney      FreePool (CardData);
2429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    }
2439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
2449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  return Status;
2469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney}
2479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/**
2509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Stop this driver on ControllerHandle. Support stoping any child handles
2519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  created by this driver.
2529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  This                 Protocol instance pointer.
2549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  Controller           Handle of device to stop driver on.
2559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
2569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @param  ChildHandleBuffer    List of handles for the children we need to stop.
2579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @return EFI_SUCCESS
2599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  @return others
2609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/
2629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS
2639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI
2649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneySDMediaDeviceStop (
2659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_DRIVER_BINDING_PROTOCOL     *This,
2669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_HANDLE                      Controller,
2679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN UINTN                           NumberOfChildren,
2689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  IN EFI_HANDLE                      *ChildHandleBuffer
2699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  )
2709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{
2719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  EFI_STATUS                Status;
2729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CARD_DATA                 *CardData;
2739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  EFI_BLOCK_IO_PROTOCOL     *BlockIo;
2749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
2769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  // First find BlockIo Protocol
2779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
2789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = gBS->OpenProtocol (
2799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  Controller,
2809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  &gEfiBlockIoProtocolGuid,
2819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  (VOID **)&BlockIo,
2829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  This->DriverBindingHandle,
2839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  Controller,
2849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
2859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  );
2869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
2879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    return Status;
2889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
2899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  CardData  = CARD_DATA_FROM_THIS(BlockIo);
2919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
2929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
2939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  // Uninstall Block I/O protocol from the device handle
2949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  //
2959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  Status = gBS->UninstallProtocolInterface (
2969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  Controller,
2979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  &gEfiBlockIoProtocolGuid,
2989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  BlockIo
2999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney                  );
3009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (EFI_ERROR (Status)) {
3019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    return Status;
3029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
3039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
3049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  if (CardData != NULL) {
3059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    if (CardData->RawBufferPointer != NULL) {
3069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney      gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * CardData->SDHostIo->HostCapability.BoundarySize));
3079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    }
3089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    FreeUnicodeStringTable (CardData->ControllerNameTable);
3099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney    FreePool (CardData);
3109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  }
3119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
3129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  gBS->CloseProtocol (
3139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         Controller,
3149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         &gEfiSDHostIoProtocolGuid,
3159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         This->DriverBindingHandle,
3169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         Controller
3179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney         );
3189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
3199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney  return EFI_SUCCESS;
3209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney}
3219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
3229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
3239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney
324