1 /** @file
2   The EmmcDxe driver is used to manage the EMMC device.
3 
4   It produces BlockIo, BlockIo2 and StorageSecurity protocols to allow upper layer
5   access the EMMC 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 "EmmcDxe.h"
19 
20 //
21 // EmmcDxe Driver Binding Protocol Instance
22 //
23 EFI_DRIVER_BINDING_PROTOCOL gEmmcDxeDriverBinding = {
24   EmmcDxeDriverBindingSupported,
25   EmmcDxeDriverBindingStart,
26   EmmcDxeDriverBindingStop,
27   0x10,
28   NULL,
29   NULL
30 };
31 
32 //
33 // Template for Emmc Partitions.
34 //
35 EMMC_PARTITION mEmmcPartitionTemplate = {
36   EMMC_PARTITION_SIGNATURE,    // Signature
37   FALSE,                       // Enable
38   EmmcPartitionUnknown,        // PartitionType
39   NULL,                        // Handle
40   NULL,                        // DevicePath
41   {                            // BlockIo
42     EFI_BLOCK_IO_PROTOCOL_REVISION,
43     NULL,
44     EmmcReset,
45     EmmcReadBlocks,
46     EmmcWriteBlocks,
47     EmmcFlushBlocks
48   },
49   {                            // BlockIo2
50     NULL,
51     EmmcResetEx,
52     EmmcReadBlocksEx,
53     EmmcWriteBlocksEx,
54     EmmcFlushBlocksEx
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   {                            // StorageSecurity
68     EmmcSecurityProtocolIn,
69     EmmcSecurityProtocolOut
70   },
71   {                            // EraseBlock
72     EFI_ERASE_BLOCK_PROTOCOL_REVISION,
73     1,
74     EmmcEraseBlocks
75   },
76   {
77     NULL,
78     NULL
79   },
80   NULL                         // Device
81 };
82 
83 /**
84   Decode and print EMMC CSD Register content.
85 
86   @param[in] Csd           Pointer to EMMC_CSD data structure.
87 
88   @retval EFI_SUCCESS      The function completed successfully
89 **/
90 EFI_STATUS
DumpCsd(IN EMMC_CSD * Csd)91 DumpCsd (
92   IN EMMC_CSD  *Csd
93   )
94 {
95   DEBUG((DEBUG_INFO, "== Dump Emmc Csd Register==\n"));
96   DEBUG((DEBUG_INFO, "  CSD structure                    0x%x\n", Csd->CsdStructure));
97   DEBUG((DEBUG_INFO, "  System specification version     0x%x\n", Csd->SpecVers));
98   DEBUG((DEBUG_INFO, "  Data read access-time 1          0x%x\n", Csd->Taac));
99   DEBUG((DEBUG_INFO, "  Data read access-time 2          0x%x\n", Csd->Nsac));
100   DEBUG((DEBUG_INFO, "  Max. bus clock frequency         0x%x\n", Csd->TranSpeed));
101   DEBUG((DEBUG_INFO, "  Device command classes           0x%x\n", Csd->Ccc));
102   DEBUG((DEBUG_INFO, "  Max. read data block length      0x%x\n", Csd->ReadBlLen));
103   DEBUG((DEBUG_INFO, "  Partial blocks for read allowed  0x%x\n", Csd->ReadBlPartial));
104   DEBUG((DEBUG_INFO, "  Write block misalignment         0x%x\n", Csd->WriteBlkMisalign));
105   DEBUG((DEBUG_INFO, "  Read block misalignment          0x%x\n", Csd->ReadBlkMisalign));
106   DEBUG((DEBUG_INFO, "  DSR implemented                  0x%x\n", Csd->DsrImp));
107   DEBUG((DEBUG_INFO, "  Device size                      0x%x\n", Csd->CSizeLow | (Csd->CSizeHigh << 2)));
108   DEBUG((DEBUG_INFO, "  Max. read current @ VDD min      0x%x\n", Csd->VddRCurrMin));
109   DEBUG((DEBUG_INFO, "  Max. read current @ VDD max      0x%x\n", Csd->VddRCurrMax));
110   DEBUG((DEBUG_INFO, "  Max. write current @ VDD min     0x%x\n", Csd->VddWCurrMin));
111   DEBUG((DEBUG_INFO, "  Max. write current @ VDD max     0x%x\n", Csd->VddWCurrMax));
112   DEBUG((DEBUG_INFO, "  Device size multiplier           0x%x\n", Csd->CSizeMult));
113   DEBUG((DEBUG_INFO, "  Erase group size                 0x%x\n", Csd->EraseGrpSize));
114   DEBUG((DEBUG_INFO, "  Erase group size multiplier      0x%x\n", Csd->EraseGrpMult));
115   DEBUG((DEBUG_INFO, "  Write protect group size         0x%x\n", Csd->WpGrpSize));
116   DEBUG((DEBUG_INFO, "  Write protect group enable       0x%x\n", Csd->WpGrpEnable));
117   DEBUG((DEBUG_INFO, "  Manufacturer default ECC         0x%x\n", Csd->DefaultEcc));
118   DEBUG((DEBUG_INFO, "  Write speed factor               0x%x\n", Csd->R2WFactor));
119   DEBUG((DEBUG_INFO, "  Max. write data block length     0x%x\n", Csd->WriteBlLen));
120   DEBUG((DEBUG_INFO, "  Partial blocks for write allowed 0x%x\n", Csd->WriteBlPartial));
121   DEBUG((DEBUG_INFO, "  Content protection application   0x%x\n", Csd->ContentProtApp));
122   DEBUG((DEBUG_INFO, "  File format group                0x%x\n", Csd->FileFormatGrp));
123   DEBUG((DEBUG_INFO, "  Copy flag (OTP)                  0x%x\n", Csd->Copy));
124   DEBUG((DEBUG_INFO, "  Permanent write protection       0x%x\n", Csd->PermWriteProtect));
125   DEBUG((DEBUG_INFO, "  Temporary write protection       0x%x\n", Csd->TmpWriteProtect));
126   DEBUG((DEBUG_INFO, "  File format                      0x%x\n", Csd->FileFormat));
127   DEBUG((DEBUG_INFO, "  ECC code                         0x%x\n", Csd->Ecc));
128 
129   return EFI_SUCCESS;
130 }
131 
132 /**
133   Decode and print EMMC EXT_CSD Register content.
134 
135   @param[in] ExtCsd           Pointer to the EMMC_EXT_CSD data structure.
136 
137   @retval EFI_SUCCESS         The function completed successfully
138 **/
139 EFI_STATUS
DumpExtCsd(IN EMMC_EXT_CSD * ExtCsd)140 DumpExtCsd (
141   IN EMMC_EXT_CSD  *ExtCsd
142   )
143 {
144   DEBUG((DEBUG_INFO, "==Dump Emmc ExtCsd Register==\n"));
145   DEBUG((DEBUG_INFO, "  Supported Command Sets                 0x%x\n", ExtCsd->CmdSet));
146   DEBUG((DEBUG_INFO, "  HPI features                           0x%x\n", ExtCsd->HpiFeatures));
147   DEBUG((DEBUG_INFO, "  Background operations support          0x%x\n", ExtCsd->BkOpsSupport));
148   DEBUG((DEBUG_INFO, "  Background operations status           0x%x\n", ExtCsd->BkopsStatus));
149   DEBUG((DEBUG_INFO, "  Number of correctly programmed sectors 0x%x\n", *((UINT32*)&ExtCsd->CorrectlyPrgSectorsNum[0])));
150   DEBUG((DEBUG_INFO, "  Initialization time after partitioning 0x%x\n", ExtCsd->IniTimeoutAp));
151   DEBUG((DEBUG_INFO, "  TRIM Multiplier                        0x%x\n", ExtCsd->TrimMult));
152   DEBUG((DEBUG_INFO, "  Secure Feature support                 0x%x\n", ExtCsd->SecFeatureSupport));
153   DEBUG((DEBUG_INFO, "  Secure Erase Multiplier                0x%x\n", ExtCsd->SecEraseMult));
154   DEBUG((DEBUG_INFO, "  Secure TRIM Multiplier                 0x%x\n", ExtCsd->SecTrimMult));
155   DEBUG((DEBUG_INFO, "  Boot information                       0x%x\n", ExtCsd->BootInfo));
156   DEBUG((DEBUG_INFO, "  Boot partition size                    0x%x\n", ExtCsd->BootSizeMult));
157   DEBUG((DEBUG_INFO, "  Access size                            0x%x\n", ExtCsd->AccSize));
158   DEBUG((DEBUG_INFO, "  High-capacity erase unit size          0x%x\n", ExtCsd->HcEraseGrpSize));
159   DEBUG((DEBUG_INFO, "  High-capacity erase timeout            0x%x\n", ExtCsd->EraseTimeoutMult));
160   DEBUG((DEBUG_INFO, "  Reliable write sector count            0x%x\n", ExtCsd->RelWrSecC));
161   DEBUG((DEBUG_INFO, "  High-capacity write protect group size 0x%x\n", ExtCsd->HcWpGrpSize));
162   DEBUG((DEBUG_INFO, "  Sleep/awake timeout                    0x%x\n", ExtCsd->SATimeout));
163   DEBUG((DEBUG_INFO, "  Sector Count                           0x%x\n", *((UINT32*)&ExtCsd->SecCount[0])));
164   DEBUG((DEBUG_INFO, "  Partition switching timing             0x%x\n", ExtCsd->PartitionSwitchTime));
165   DEBUG((DEBUG_INFO, "  Out-of-interrupt busy timing           0x%x\n", ExtCsd->OutOfInterruptTime));
166   DEBUG((DEBUG_INFO, "  I/O Driver Strength                    0x%x\n", ExtCsd->DriverStrength));
167   DEBUG((DEBUG_INFO, "  Device type                            0x%x\n", ExtCsd->DeviceType));
168   DEBUG((DEBUG_INFO, "  CSD STRUCTURE                          0x%x\n", ExtCsd->CsdStructure));
169   DEBUG((DEBUG_INFO, "  Extended CSD revision                  0x%x\n", ExtCsd->ExtCsdRev));
170   DEBUG((DEBUG_INFO, "  Command set                            0x%x\n", ExtCsd->CmdSet));
171   DEBUG((DEBUG_INFO, "  Command set revision                   0x%x\n", ExtCsd->CmdSetRev));
172   DEBUG((DEBUG_INFO, "  Power class                            0x%x\n", ExtCsd->PowerClass));
173   DEBUG((DEBUG_INFO, "  High-speed interface timing            0x%x\n", ExtCsd->HsTiming));
174   DEBUG((DEBUG_INFO, "  Bus width mode                         0x%x\n", ExtCsd->BusWidth));
175   DEBUG((DEBUG_INFO, "  Erased memory content                  0x%x\n", ExtCsd->ErasedMemCont));
176   DEBUG((DEBUG_INFO, "  Partition configuration                0x%x\n", ExtCsd->PartitionConfig));
177   DEBUG((DEBUG_INFO, "  Boot config protection                 0x%x\n", ExtCsd->BootConfigProt));
178   DEBUG((DEBUG_INFO, "  Boot bus Conditions                    0x%x\n", ExtCsd->BootBusConditions));
179   DEBUG((DEBUG_INFO, "  High-density erase group definition    0x%x\n", ExtCsd->EraseGroupDef));
180   DEBUG((DEBUG_INFO, "  Boot write protection status register  0x%x\n", ExtCsd->BootWpStatus));
181   DEBUG((DEBUG_INFO, "  Boot area write protection register    0x%x\n", ExtCsd->BootWp));
182   DEBUG((DEBUG_INFO, "  User area write protection register    0x%x\n", ExtCsd->UserWp));
183   DEBUG((DEBUG_INFO, "  FW configuration                       0x%x\n", ExtCsd->FwConfig));
184   DEBUG((DEBUG_INFO, "  RPMB Size                              0x%x\n", ExtCsd->RpmbSizeMult));
185   DEBUG((DEBUG_INFO, "  H/W reset function                     0x%x\n", ExtCsd->RstFunction));
186   DEBUG((DEBUG_INFO, "  Partitioning Support                   0x%x\n", ExtCsd->PartitioningSupport));
187   DEBUG((DEBUG_INFO, "  Max Enhanced Area Size                 0x%02x%02x%02x\n", \
188                         ExtCsd->MaxEnhSizeMult[2], ExtCsd->MaxEnhSizeMult[1], ExtCsd->MaxEnhSizeMult[0]));
189   DEBUG((DEBUG_INFO, "  Partitions attribute                   0x%x\n", ExtCsd->PartitionsAttribute));
190   DEBUG((DEBUG_INFO, "  Partitioning Setting                   0x%x\n", ExtCsd->PartitionSettingCompleted));
191   DEBUG((DEBUG_INFO, "  General Purpose Partition 1 Size       0x%02x%02x%02x\n", \
192                         ExtCsd->GpSizeMult[2], ExtCsd->GpSizeMult[1], ExtCsd->GpSizeMult[0]));
193   DEBUG((DEBUG_INFO, "  General Purpose Partition 2 Size       0x%02x%02x%02x\n", \
194                         ExtCsd->GpSizeMult[5], ExtCsd->GpSizeMult[4], ExtCsd->GpSizeMult[3]));
195   DEBUG((DEBUG_INFO, "  General Purpose Partition 3 Size       0x%02x%02x%02x\n", \
196                         ExtCsd->GpSizeMult[8], ExtCsd->GpSizeMult[7], ExtCsd->GpSizeMult[6]));
197   DEBUG((DEBUG_INFO, "  General Purpose Partition 4 Size       0x%02x%02x%02x\n", \
198                         ExtCsd->GpSizeMult[11], ExtCsd->GpSizeMult[10], ExtCsd->GpSizeMult[9]));
199   DEBUG((DEBUG_INFO, "  Enhanced User Data Area Size           0x%02x%02x%02x\n", \
200                         ExtCsd->EnhSizeMult[2], ExtCsd->EnhSizeMult[1], ExtCsd->EnhSizeMult[0]));
201   DEBUG((DEBUG_INFO, "  Enhanced User Data Start Address       0x%x\n", *((UINT32*)&ExtCsd->EnhStartAddr[0])));
202   DEBUG((DEBUG_INFO, "  Bad Block Management mode              0x%x\n", ExtCsd->SecBadBlkMgmnt));
203   DEBUG((DEBUG_INFO, "  Native sector size                     0x%x\n", ExtCsd->NativeSectorSize));
204   DEBUG((DEBUG_INFO, "  Sector size emulation                  0x%x\n", ExtCsd->UseNativeSector));
205   DEBUG((DEBUG_INFO, "  Sector size                            0x%x\n", ExtCsd->DataSectorSize));
206 
207   return EFI_SUCCESS;
208 }
209 
210 /**
211   Get EMMC device model name.
212 
213   @param[in, out] Device   The pointer to the EMMC_DEVICE data structure.
214   @param[in]      Cid      Pointer to EMMC_CID data structure.
215 
216   @retval EFI_SUCCESS      The function completed successfully
217 
218 **/
219 EFI_STATUS
GetEmmcModelName(IN OUT EMMC_DEVICE * Device,IN EMMC_CID * Cid)220 GetEmmcModelName (
221   IN OUT EMMC_DEVICE         *Device,
222   IN     EMMC_CID            *Cid
223   )
224 {
225   CHAR8  String[EMMC_MODEL_NAME_MAX_LEN];
226 
227   ZeroMem (String, sizeof (String));
228   CopyMem (String, &Cid->OemId, sizeof (Cid->OemId));
229   String[sizeof (Cid->OemId)] = ' ';
230   CopyMem (String + sizeof (Cid->OemId) + 1, Cid->ProductName, sizeof (Cid->ProductName));
231   String[sizeof (Cid->OemId) + sizeof (Cid->ProductName)] = ' ';
232   CopyMem (String + sizeof (Cid->OemId) + sizeof (Cid->ProductName) + 1, Cid->ProductSerialNumber, sizeof (Cid->ProductSerialNumber));
233 
234   AsciiStrToUnicodeStrS (String, Device->ModelName, sizeof (Device->ModelName) / sizeof (Device->ModelName[0]));
235 
236   return EFI_SUCCESS;
237 }
238 
239 /**
240   Discover all partitions in the EMMC device.
241 
242   @param[in] Device          The pointer to the EMMC_DEVICE data structure.
243 
244   @retval EFI_SUCCESS        All the partitions in the device are successfully enumerated.
245   @return Others             Some error occurs when enumerating the partitions.
246 
247 **/
248 EFI_STATUS
DiscoverAllPartitions(IN EMMC_DEVICE * Device)249 DiscoverAllPartitions (
250   IN EMMC_DEVICE             *Device
251   )
252 {
253   EFI_STATUS                        Status;
254   EMMC_PARTITION                    *Partition;
255   EMMC_CSD                          *Csd;
256   EMMC_CID                          *Cid;
257   EMMC_EXT_CSD                      *ExtCsd;
258   UINT8                             Slot;
259   UINT64                            Capacity;
260   UINT32                            DevStatus;
261   UINT8                             Index;
262   UINT32                            SecCount;
263   UINT32                            GpSizeMult;
264 
265   Slot     = Device->Slot;
266 
267   Status = EmmcSendStatus (Device, Slot + 1, &DevStatus);
268   if (EFI_ERROR (Status)) {
269     return Status;
270   }
271   //
272   // Deselect the device to force it enter stby mode before getting CSD
273   // register content.
274   // Note here we don't judge return status as some EMMC devices return
275   // error but the state has been stby.
276   //
277   EmmcSelect (Device, 0);
278 
279   Status = EmmcSendStatus (Device, Slot + 1, &DevStatus);
280   if (EFI_ERROR (Status)) {
281     return Status;
282   }
283 
284   Csd    = &Device->Csd;
285   Status = EmmcGetCsd (Device, Slot + 1, Csd);
286   if (EFI_ERROR (Status)) {
287     return Status;
288   }
289   DumpCsd (Csd);
290 
291   if ((Csd->CSizeLow | Csd->CSizeHigh << 2) == 0xFFF) {
292     Device->SectorAddressing = TRUE;
293   } else {
294     Device->SectorAddressing = FALSE;
295   }
296 
297   Cid    = &Device->Cid;
298   Status = EmmcGetCid (Device, Slot + 1, Cid);
299   if (EFI_ERROR (Status)) {
300     return Status;
301   }
302 
303   Status = EmmcSelect (Device, Slot + 1);
304   if (EFI_ERROR (Status)) {
305     return Status;
306   }
307 
308   ExtCsd = &Device->ExtCsd;
309   Status = EmmcGetExtCsd (Device, ExtCsd);
310   if (EFI_ERROR (Status)) {
311     return Status;
312   }
313   DumpExtCsd (ExtCsd);
314 
315   if (ExtCsd->ExtCsdRev < 5) {
316     DEBUG ((EFI_D_ERROR, "The EMMC device version is too low, we don't support!!!\n"));
317     return EFI_UNSUPPORTED;
318   }
319 
320   if ((ExtCsd->PartitioningSupport & BIT0) != BIT0) {
321     DEBUG ((EFI_D_ERROR, "The EMMC device doesn't support Partition Feature!!!\n"));
322     return EFI_UNSUPPORTED;
323   }
324 
325   for (Index = 0; Index < EMMC_MAX_PARTITIONS; Index++) {
326     Partition = &Device->Partition[Index];
327     CopyMem (Partition, &mEmmcPartitionTemplate, sizeof (EMMC_PARTITION));
328     Partition->Device             = Device;
329     InitializeListHead (&Partition->Queue);
330     Partition->BlockIo.Media      = &Partition->BlockMedia;
331     Partition->BlockIo2.Media     = &Partition->BlockMedia;
332     Partition->PartitionType      = Index;
333     Partition->BlockMedia.IoAlign = Device->Private->PassThru->IoAlign;
334     Partition->BlockMedia.BlockSize      = 0x200;
335     Partition->BlockMedia.LastBlock      = 0x00;
336     Partition->BlockMedia.RemovableMedia = FALSE;
337     Partition->BlockMedia.MediaPresent     = TRUE;
338     Partition->BlockMedia.LogicalPartition = FALSE;
339 
340     switch (Index) {
341       case EmmcPartitionUserData:
342         SecCount = *(UINT32*)&ExtCsd->SecCount;
343         Capacity = MultU64x32 ((UINT64) SecCount, 0x200);
344         break;
345       case EmmcPartitionBoot1:
346       case EmmcPartitionBoot2:
347         Capacity = ExtCsd->BootSizeMult * SIZE_128KB;
348         break;
349       case EmmcPartitionRPMB:
350         Capacity = ExtCsd->RpmbSizeMult * SIZE_128KB;
351         break;
352       case EmmcPartitionGP1:
353         GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[0] | (ExtCsd->GpSizeMult[1] << 8) | (ExtCsd->GpSizeMult[2] << 16));
354         Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB);
355         break;
356       case EmmcPartitionGP2:
357         GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[3] | (ExtCsd->GpSizeMult[4] << 8) | (ExtCsd->GpSizeMult[5] << 16));
358         Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB);
359         break;
360       case EmmcPartitionGP3:
361         GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[6] | (ExtCsd->GpSizeMult[7] << 8) | (ExtCsd->GpSizeMult[8] << 16));
362         Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB);
363         break;
364       case EmmcPartitionGP4:
365         GpSizeMult = (UINT32)(ExtCsd->GpSizeMult[9] | (ExtCsd->GpSizeMult[10] << 8) | (ExtCsd->GpSizeMult[11] << 16));
366         Capacity = MultU64x32 (MultU64x32 (MultU64x32 ((UINT64)GpSizeMult, ExtCsd->HcWpGrpSize), ExtCsd->HcEraseGrpSize), SIZE_512KB);
367         break;
368       default:
369         ASSERT (FALSE);
370         return EFI_INVALID_PARAMETER;
371     }
372 
373     if (Capacity != 0) {
374       Partition->Enable = TRUE;
375       Partition->BlockMedia.LastBlock = DivU64x32 (Capacity, Partition->BlockMedia.BlockSize) - 1;
376     }
377 
378     if ((ExtCsd->EraseGroupDef & BIT0) == 0) {
379       if (Csd->WriteBlLen < 9) {
380         Partition->EraseBlock.EraseLengthGranularity = 1;
381       } else {
382         Partition->EraseBlock.EraseLengthGranularity = (Csd->EraseGrpMult + 1) * (Csd->EraseGrpSize + 1) * (1 << (Csd->WriteBlLen - 9));
383       }
384     } else {
385       Partition->EraseBlock.EraseLengthGranularity = 1024 * ExtCsd->HcEraseGrpSize;
386     }
387   }
388 
389   return EFI_SUCCESS;
390 }
391 
392 /**
393   Install BlkIo, BlkIo2 and Ssp protocols for the specified partition in the EMMC device.
394 
395   @param[in] Device          The pointer to the EMMC_DEVICE data structure.
396   @param[in] Index           The index of the partition.
397 
398   @retval EFI_SUCCESS        The protocols are installed successfully.
399   @retval Others             Some error occurs when installing the protocols.
400 
401 **/
402 EFI_STATUS
InstallProtocolOnPartition(IN EMMC_DEVICE * Device,IN UINT8 Index)403 InstallProtocolOnPartition (
404   IN EMMC_DEVICE             *Device,
405   IN UINT8                   Index
406   )
407 {
408   EFI_STATUS                        Status;
409   EMMC_PARTITION                    *Partition;
410   CONTROLLER_DEVICE_PATH            ControlNode;
411   EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
412   EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
413   EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath;
414   EFI_HANDLE                        DeviceHandle;
415 
416   //
417   // Build device path
418   //
419   ParentDevicePath = Device->DevicePath;
420 
421   ControlNode.Header.Type    = HARDWARE_DEVICE_PATH;
422   ControlNode.Header.SubType = HW_CONTROLLER_DP;
423   SetDevicePathNodeLength (&ControlNode.Header, sizeof (CONTROLLER_DEVICE_PATH));
424   ControlNode.ControllerNumber = Index;
425 
426   DevicePath = AppendDevicePathNode (ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&ControlNode);
427   if (DevicePath == NULL) {
428     Status = EFI_OUT_OF_RESOURCES;
429     goto Error;
430   }
431 
432   DeviceHandle = NULL;
433   RemainingDevicePath = DevicePath;
434   Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
435   if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
436     Status = EFI_ALREADY_STARTED;
437     goto Error;
438   }
439 
440   Partition = &Device->Partition[Index];
441   Partition->DevicePath = DevicePath;
442   if (Partition->Enable) {
443     //
444     // Install BlkIo/BlkIo2/Ssp for the specified partition
445     //
446     if (Partition->PartitionType != EmmcPartitionRPMB) {
447       Status = gBS->InstallMultipleProtocolInterfaces (
448                       &Partition->Handle,
449                       &gEfiDevicePathProtocolGuid,
450                       Partition->DevicePath,
451                       &gEfiBlockIoProtocolGuid,
452                       &Partition->BlockIo,
453                       &gEfiBlockIo2ProtocolGuid,
454                       &Partition->BlockIo2,
455                       &gEfiEraseBlockProtocolGuid,
456                       &Partition->EraseBlock,
457                       NULL
458                       );
459       if (EFI_ERROR (Status)) {
460         goto Error;
461       }
462 
463       if (((Partition->PartitionType == EmmcPartitionUserData) ||
464           (Partition->PartitionType == EmmcPartitionBoot1) ||
465           (Partition->PartitionType == EmmcPartitionBoot2)) &&
466           ((Device->Csd.Ccc & BIT10) != 0)) {
467         Status = gBS->InstallProtocolInterface (
468                         &Partition->Handle,
469                         &gEfiStorageSecurityCommandProtocolGuid,
470                         EFI_NATIVE_INTERFACE,
471                         &Partition->StorageSecurity
472                         );
473         if (EFI_ERROR (Status)) {
474           gBS->UninstallMultipleProtocolInterfaces (
475                  &Partition->Handle,
476                  &gEfiDevicePathProtocolGuid,
477                  Partition->DevicePath,
478                  &gEfiBlockIoProtocolGuid,
479                  &Partition->BlockIo,
480                  &gEfiBlockIo2ProtocolGuid,
481                  &Partition->BlockIo2,
482                  &gEfiEraseBlockProtocolGuid,
483                  &Partition->EraseBlock,
484                  NULL
485                  );
486           goto Error;
487         }
488       }
489 
490       gBS->OpenProtocol (
491              Device->Private->Controller,
492              &gEfiSdMmcPassThruProtocolGuid,
493              (VOID **) &(Device->Private->PassThru),
494              Device->Private->DriverBindingHandle,
495              Partition->Handle,
496              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
497              );
498     }
499 
500   } else {
501     Status = EFI_INVALID_PARAMETER;
502   }
503 
504 Error:
505   if (EFI_ERROR (Status) && (DevicePath != NULL)) {
506     FreePool (DevicePath);
507   }
508 
509   return Status;
510 }
511 
512 /**
513   Scan EMMC Bus to discover the device.
514 
515   @param[in]  Private             The EMMC driver private data structure.
516   @param[in]  Slot                The slot number to check device present.
517   @param[in]  RemainingDevicePath The pointer to the remaining device path.
518 
519   @retval EFI_SUCCESS             Successfully to discover the device and attach
520                                   SdMmcIoProtocol to it.
521   @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack
522                                   of resources.
523   @retval EFI_ALREADY_STARTED     The device was discovered before.
524   @retval Others                  Fail to discover the device.
525 
526 **/
527 EFI_STATUS
528 EFIAPI
DiscoverEmmcDevice(IN EMMC_DRIVER_PRIVATE_DATA * Private,IN UINT8 Slot,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)529 DiscoverEmmcDevice (
530   IN  EMMC_DRIVER_PRIVATE_DATA    *Private,
531   IN  UINT8                       Slot,
532   IN  EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
533   )
534 {
535   EFI_STATUS                      Status;
536   EMMC_DEVICE                     *Device;
537   EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
538   EFI_DEVICE_PATH_PROTOCOL        *NewDevicePath;
539   EFI_DEVICE_PATH_PROTOCOL        *RemainingEmmcDevPath;
540   EFI_DEV_PATH                    *Node;
541   EFI_HANDLE                      DeviceHandle;
542   EFI_SD_MMC_PASS_THRU_PROTOCOL   *PassThru;
543   UINT8                           Index;
544 
545   Device              = NULL;
546   DevicePath          = NULL;
547   NewDevicePath       = NULL;
548   RemainingDevicePath = NULL;
549   PassThru = Private->PassThru;
550   Device   = &Private->Device[Slot];
551 
552   //
553   // Build Device Path to check if the EMMC device present at the slot.
554   //
555   Status = PassThru->BuildDevicePath (
556                        PassThru,
557                        Slot,
558                        &DevicePath
559                        );
560   if (EFI_ERROR(Status)) {
561     return Status;
562   }
563 
564   if (DevicePath->SubType != MSG_EMMC_DP) {
565     Status = EFI_UNSUPPORTED;
566     goto Error;
567   }
568 
569   NewDevicePath = AppendDevicePathNode (
570                     Private->ParentDevicePath,
571                     DevicePath
572                     );
573   if (NewDevicePath == NULL) {
574     Status = EFI_OUT_OF_RESOURCES;
575     goto Error;
576   }
577 
578   DeviceHandle         = NULL;
579   RemainingEmmcDevPath = NewDevicePath;
580   Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingEmmcDevPath, &DeviceHandle);
581   //
582   // The device path to the EMMC device doesn't exist. It means the corresponding device private data hasn't been initialized.
583   //
584   if (EFI_ERROR (Status) || (DeviceHandle == NULL) || !IsDevicePathEnd (RemainingEmmcDevPath)) {
585     Device->DevicePath = NewDevicePath;
586     Device->Slot       = Slot;
587     Device->Private    = Private;
588     //
589     // Expose user area in the Sd memory card to upper layer.
590     //
591     Status = DiscoverAllPartitions (Device);
592     if (EFI_ERROR(Status)) {
593       FreePool (NewDevicePath);
594       goto Error;
595     }
596 
597     Status = gBS->InstallProtocolInterface (
598                     &Device->Handle,
599                     &gEfiDevicePathProtocolGuid,
600                     EFI_NATIVE_INTERFACE,
601                     Device->DevicePath
602                     );
603     if (EFI_ERROR(Status)) {
604       FreePool (NewDevicePath);
605       goto Error;
606     }
607 
608     Device->ControllerNameTable = NULL;
609     GetEmmcModelName (Device, &Device->Cid);
610     AddUnicodeString2 (
611       "eng",
612       gEmmcDxeComponentName.SupportedLanguages,
613       &Device->ControllerNameTable,
614       Device->ModelName,
615       TRUE
616       );
617     AddUnicodeString2 (
618       "en",
619       gEmmcDxeComponentName.SupportedLanguages,
620       &Device->ControllerNameTable,
621       Device->ModelName,
622       FALSE
623       );
624   }
625 
626   if (RemainingDevicePath == NULL) {
627     //
628     // Expose all partitions in the Emmc device to upper layer.
629     //
630     for (Index = 0; Index < EMMC_MAX_PARTITIONS; Index++) {
631       InstallProtocolOnPartition (Device, Index);
632     }
633   } else if (!IsDevicePathEnd (RemainingDevicePath)) {
634     //
635     // Enumerate the specified partition
636     //
637     Node = (EFI_DEV_PATH *) RemainingDevicePath;
638     if ((DevicePathType (&Node->DevPath) != HARDWARE_DEVICE_PATH) ||
639         (DevicePathSubType (&Node->DevPath) != HW_CONTROLLER_DP) ||
640         (DevicePathNodeLength (&Node->DevPath) != sizeof (CONTROLLER_DEVICE_PATH))) {
641       Status = EFI_INVALID_PARAMETER;
642       goto Error;
643     }
644 
645     Index = (UINT8)Node->Controller.ControllerNumber;
646     if (Index >= EMMC_MAX_PARTITIONS) {
647       Status = EFI_INVALID_PARAMETER;
648       goto Error;
649     }
650 
651     Status = InstallProtocolOnPartition (Device, Index);
652   }
653 
654 Error:
655   FreePool (DevicePath);
656 
657   return Status;
658 }
659 
660 /**
661   Tests to see if this driver supports a given controller. If a child device is provided,
662   it further tests to see if this driver supports creating a handle for the specified child device.
663 
664   This function checks to see if the driver specified by This supports the device specified by
665   ControllerHandle. Drivers will typically use the device path attached to
666   ControllerHandle and/or the services from the bus I/O abstraction attached to
667   ControllerHandle to determine if the driver supports ControllerHandle. This function
668   may be called many times during platform initialization. In order to reduce boot times, the tests
669   performed by this function must be very small, and take as little time as possible to execute. This
670   function must not change the state of any hardware devices, and this function must be aware that the
671   device specified by ControllerHandle may already be managed by the same driver or a
672   different driver. This function must match its calls to AllocatePages() with FreePages(),
673   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
674   Since ControllerHandle may have been previously started by the same driver, if a protocol is
675   already in the opened state, then it must not be closed with CloseProtocol(). This is required
676   to guarantee the state of ControllerHandle is not modified by this function.
677 
678   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
679   @param[in]  ControllerHandle     The handle of the controller to test. This handle
680                                    must support a protocol interface that supplies
681                                    an I/O abstraction to the driver.
682   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
683                                    parameter is ignored by device drivers, and is optional for bus
684                                    drivers. For bus drivers, if this parameter is not NULL, then
685                                    the bus driver must determine if the bus controller specified
686                                    by ControllerHandle and the child controller specified
687                                    by RemainingDevicePath are both supported by this
688                                    bus driver.
689 
690   @retval EFI_SUCCESS              The device specified by ControllerHandle and
691                                    RemainingDevicePath is supported by the driver specified by This.
692   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
693                                    RemainingDevicePath is already being managed by the driver
694                                    specified by This.
695   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
696                                    RemainingDevicePath is already being managed by a different
697                                    driver or an application that requires exclusive access.
698                                    Currently not implemented.
699   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
700                                    RemainingDevicePath is not supported by the driver specified by This.
701 **/
702 EFI_STATUS
703 EFIAPI
EmmcDxeDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)704 EmmcDxeDriverBindingSupported (
705   IN EFI_DRIVER_BINDING_PROTOCOL   *This,
706   IN EFI_HANDLE                    Controller,
707   IN EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
708   )
709 {
710   EFI_STATUS                       Status;
711   EFI_DEVICE_PATH_PROTOCOL         *ParentDevicePath;
712   EFI_SD_MMC_PASS_THRU_PROTOCOL    *PassThru;
713   UINT8                            Slot;
714 
715   //
716   // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle.
717   //
718   Status = gBS->OpenProtocol (
719                   Controller,
720                   &gEfiSdMmcPassThruProtocolGuid,
721                   (VOID**) &PassThru,
722                   This->DriverBindingHandle,
723                   Controller,
724                   EFI_OPEN_PROTOCOL_BY_DRIVER
725                   );
726 
727   if (Status == EFI_ALREADY_STARTED) {
728     return EFI_SUCCESS;
729   }
730 
731   if (EFI_ERROR (Status)) {
732     return Status;
733   }
734 
735   //
736   // Test RemainingDevicePath is valid or not.
737   //
738   if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
739     Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
740     if (EFI_ERROR (Status)) {
741       //
742       // Close the I/O Abstraction(s) used to perform the supported test
743       //
744       gBS->CloseProtocol (
745              Controller,
746              &gEfiSdMmcPassThruProtocolGuid,
747              This->DriverBindingHandle,
748              Controller
749              );
750       return Status;
751     }
752   }
753 
754   //
755   // Close the I/O Abstraction(s) used to perform the supported test
756   //
757   gBS->CloseProtocol (
758          Controller,
759          &gEfiSdMmcPassThruProtocolGuid,
760          This->DriverBindingHandle,
761          Controller
762          );
763 
764   //
765   // Open the EFI Device Path protocol needed to perform the supported test
766   //
767   Status = gBS->OpenProtocol (
768                   Controller,
769                   &gEfiDevicePathProtocolGuid,
770                   (VOID **) &ParentDevicePath,
771                   This->DriverBindingHandle,
772                   Controller,
773                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
774                   );
775   return Status;
776 }
777 
778 /**
779   Starts a device controller or a bus controller.
780 
781   The Start() function is designed to be invoked from the EFI boot service ConnectController().
782   As a result, much of the error checking on the parameters to Start() has been moved into this
783   common boot service. It is legal to call Start() from other locations,
784   but the following calling restrictions must be followed or the system behavior will not be deterministic.
785   1. ControllerHandle must be a valid EFI_HANDLE.
786   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
787      EFI_DEVICE_PATH_PROTOCOL.
788   3. Prior to calling Start(), the Supported() function for the driver specified by This must
789      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
790 
791   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
792   @param[in]  ControllerHandle     The handle of the controller to start. This handle
793                                    must support a protocol interface that supplies
794                                    an I/O abstraction to the driver.
795   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
796                                    parameter is ignored by device drivers, and is optional for bus
797                                    drivers. For a bus driver, if this parameter is NULL, then handles
798                                    for all the children of Controller are created by this driver.
799                                    If this parameter is not NULL and the first Device Path Node is
800                                    not the End of Device Path Node, then only the handle for the
801                                    child device specified by the first Device Path Node of
802                                    RemainingDevicePath is created by this driver.
803                                    If the first Device Path Node of RemainingDevicePath is
804                                    the End of Device Path Node, no child handle is created by this
805                                    driver.
806 
807   @retval EFI_SUCCESS              The device was started.
808   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
809   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
810   @retval Others                   The driver failded to start the device.
811 
812 **/
813 EFI_STATUS
814 EFIAPI
EmmcDxeDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)815 EmmcDxeDriverBindingStart (
816   IN EFI_DRIVER_BINDING_PROTOCOL   *This,
817   IN EFI_HANDLE                    Controller,
818   IN EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
819   )
820 {
821   EFI_STATUS                       Status;
822   EFI_SD_MMC_PASS_THRU_PROTOCOL    *PassThru;
823   EFI_DEVICE_PATH_PROTOCOL         *ParentDevicePath;
824   EMMC_DRIVER_PRIVATE_DATA         *Private;
825   UINT8                            Slot;
826 
827   Private  = NULL;
828   PassThru = NULL;
829   Status = gBS->OpenProtocol (
830                   Controller,
831                   &gEfiSdMmcPassThruProtocolGuid,
832                   (VOID **) &PassThru,
833                   This->DriverBindingHandle,
834                   Controller,
835                   EFI_OPEN_PROTOCOL_BY_DRIVER
836                   );
837   if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
838     return Status;
839   }
840 
841   //
842   // Check EFI_ALREADY_STARTED to reuse the original EMMC_DRIVER_PRIVATE_DATA.
843   //
844   if (Status != EFI_ALREADY_STARTED) {
845     Private = AllocateZeroPool (sizeof (EMMC_DRIVER_PRIVATE_DATA));
846     if (Private == NULL) {
847       Status = EFI_OUT_OF_RESOURCES;
848       goto Error;
849     }
850 
851     Status = gBS->OpenProtocol (
852                     Controller,
853                     &gEfiDevicePathProtocolGuid,
854                     (VOID **) &ParentDevicePath,
855                     This->DriverBindingHandle,
856                     Controller,
857                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
858                     );
859     ASSERT_EFI_ERROR (Status);
860     Private->PassThru            = PassThru;
861     Private->Controller          = Controller;
862     Private->ParentDevicePath    = ParentDevicePath;
863     Private->DriverBindingHandle = This->DriverBindingHandle;
864 
865     Status = gBS->InstallProtocolInterface (
866                     &Controller,
867                     &gEfiCallerIdGuid,
868                     EFI_NATIVE_INTERFACE,
869                     Private
870                     );
871     if (EFI_ERROR (Status)) {
872       goto Error;
873     }
874   } else {
875     Status = gBS->OpenProtocol (
876                     Controller,
877                     &gEfiCallerIdGuid,
878                     (VOID **) &Private,
879                     This->DriverBindingHandle,
880                     Controller,
881                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
882                     );
883     if (EFI_ERROR (Status)) {
884       goto Error;
885     }
886   }
887 
888   if (RemainingDevicePath == NULL) {
889     Slot = 0xFF;
890     while (TRUE) {
891       Status = PassThru->GetNextSlot (PassThru, &Slot);
892       if (EFI_ERROR (Status)) {
893         //
894         // Cannot find more legal slots.
895         //
896         Status = EFI_SUCCESS;
897         break;
898       }
899 
900       Status = DiscoverEmmcDevice (Private, Slot, NULL);
901       if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
902         break;
903       }
904     }
905   } else if (!IsDevicePathEnd (RemainingDevicePath)) {
906     Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
907     if (!EFI_ERROR (Status)) {
908       Status = DiscoverEmmcDevice (Private, Slot, NextDevicePathNode (RemainingDevicePath));
909     }
910   }
911 
912 Error:
913   if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
914     gBS->CloseProtocol (
915            Controller,
916            &gEfiSdMmcPassThruProtocolGuid,
917            This->DriverBindingHandle,
918            Controller
919            );
920 
921     if (Private != NULL) {
922       gBS->UninstallMultipleProtocolInterfaces (
923              Controller,
924              &gEfiCallerIdGuid,
925              Private,
926              NULL
927              );
928       FreePool (Private);
929     }
930   }
931   return Status;
932 }
933 
934 /**
935   Stops a device controller or a bus controller.
936 
937   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
938   As a result, much of the error checking on the parameters to Stop() has been moved
939   into this common boot service. It is legal to call Stop() from other locations,
940   but the following calling restrictions must be followed or the system behavior will not be deterministic.
941   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
942      same driver's Start() function.
943   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
944      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
945      Start() function, and the Start() function must have called OpenProtocol() on
946      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
947 
948   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
949   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
950                                 support a bus specific I/O protocol for the driver
951                                 to use to stop the device.
952   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
953   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
954                                 if NumberOfChildren is 0.
955 
956   @retval EFI_SUCCESS           The device was stopped.
957   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
958 
959 **/
960 EFI_STATUS
961 EFIAPI
EmmcDxeDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)962 EmmcDxeDriverBindingStop (
963   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
964   IN  EFI_HANDLE                      Controller,
965   IN  UINTN                           NumberOfChildren,
966   IN  EFI_HANDLE                      *ChildHandleBuffer
967   )
968 {
969   EFI_STATUS                             Status;
970   BOOLEAN                                AllChildrenStopped;
971   UINTN                                  Index;
972   EFI_DEVICE_PATH_PROTOCOL               *DevicePath;
973   EMMC_DRIVER_PRIVATE_DATA               *Private;
974   EMMC_DEVICE                            *Device;
975   EMMC_PARTITION                         *Partition;
976   EFI_BLOCK_IO_PROTOCOL                  *BlockIo;
977   EFI_BLOCK_IO2_PROTOCOL                 *BlockIo2;
978   EFI_STORAGE_SECURITY_COMMAND_PROTOCOL  *StorageSecurity;
979   LIST_ENTRY                             *Link;
980   LIST_ENTRY                             *NextLink;
981   EMMC_REQUEST                           *Request;
982 
983   BlockIo  = NULL;
984   BlockIo2 = NULL;
985   if (NumberOfChildren == 0) {
986     Status = gBS->OpenProtocol (
987                     Controller,
988                     &gEfiCallerIdGuid,
989                     (VOID **) &Private,
990                     This->DriverBindingHandle,
991                     Controller,
992                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
993                     );
994     if (EFI_ERROR (Status)) {
995       return EFI_DEVICE_ERROR;
996     }
997 
998     for (Index = 0; Index < EMMC_MAX_DEVICES; Index++) {
999       Device = &Private->Device[Index];
1000       Status = gBS->OpenProtocol (
1001                       Device->Handle,
1002                       &gEfiDevicePathProtocolGuid,
1003                       (VOID **) &DevicePath,
1004                       This->DriverBindingHandle,
1005                       Controller,
1006                       EFI_OPEN_PROTOCOL_GET_PROTOCOL
1007                       );
1008       if (EFI_ERROR (Status)) {
1009         continue;
1010       }
1011       ASSERT (DevicePath == Device->DevicePath);
1012       gBS->UninstallProtocolInterface (
1013              Device->Handle,
1014              &gEfiDevicePathProtocolGuid,
1015              DevicePath
1016              );
1017       FreePool (Device->DevicePath);
1018     }
1019 
1020     gBS->UninstallProtocolInterface (
1021           Controller,
1022           &gEfiCallerIdGuid,
1023           Private
1024           );
1025     gBS->CloseProtocol (
1026           Controller,
1027           &gEfiSdMmcPassThruProtocolGuid,
1028           This->DriverBindingHandle,
1029           Controller
1030           );
1031     FreePool (Private);
1032 
1033     return EFI_SUCCESS;
1034   }
1035 
1036   AllChildrenStopped = TRUE;
1037 
1038   for (Index = 0; Index < NumberOfChildren; Index++) {
1039     Status = gBS->OpenProtocol (
1040                     ChildHandleBuffer[Index],
1041                     &gEfiBlockIoProtocolGuid,
1042                     (VOID **) &BlockIo,
1043                     This->DriverBindingHandle,
1044                     Controller,
1045                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
1046                     );
1047     if (EFI_ERROR (Status)) {
1048       Status = gBS->OpenProtocol (
1049                       ChildHandleBuffer[Index],
1050                       &gEfiBlockIo2ProtocolGuid,
1051                       (VOID **) &BlockIo2,
1052                       This->DriverBindingHandle,
1053                       Controller,
1054                       EFI_OPEN_PROTOCOL_GET_PROTOCOL
1055                       );
1056       if (EFI_ERROR (Status)) {
1057         AllChildrenStopped = FALSE;
1058         continue;
1059       }
1060     }
1061 
1062     if (BlockIo != NULL) {
1063       Partition = EMMC_PARTITION_DATA_FROM_BLKIO (BlockIo);
1064     } else {
1065       ASSERT (BlockIo2 != NULL);
1066       Partition = EMMC_PARTITION_DATA_FROM_BLKIO2 (BlockIo2);
1067     }
1068 
1069     for (Link = GetFirstNode (&Partition->Queue);
1070          !IsNull (&Partition->Queue, Link);
1071          Link = NextLink) {
1072       NextLink = GetNextNode (&Partition->Queue, Link);
1073 
1074       RemoveEntryList (Link);
1075       Request = EMMC_REQUEST_FROM_LINK (Link);
1076 
1077       gBS->CloseEvent (Request->Event);
1078       Request->Token->TransactionStatus = EFI_ABORTED;
1079 
1080       if (Request->IsEnd) {
1081         gBS->SignalEvent (Request->Token->Event);
1082       }
1083 
1084       FreePool (Request);
1085     }
1086 
1087     //
1088     // Close the child handle
1089     //
1090     Status = gBS->CloseProtocol (
1091                     Controller,
1092                     &gEfiSdMmcPassThruProtocolGuid,
1093                     This->DriverBindingHandle,
1094                     ChildHandleBuffer[Index]
1095                     );
1096 
1097     Status = gBS->UninstallMultipleProtocolInterfaces (
1098                     ChildHandleBuffer[Index],
1099                     &gEfiDevicePathProtocolGuid,
1100                     Partition->DevicePath,
1101                     &gEfiBlockIoProtocolGuid,
1102                     &Partition->BlockIo,
1103                     &gEfiBlockIo2ProtocolGuid,
1104                     &Partition->BlockIo2,
1105                     &gEfiEraseBlockProtocolGuid,
1106                     &Partition->EraseBlock,
1107                     NULL
1108                     );
1109     if (EFI_ERROR (Status)) {
1110       AllChildrenStopped = FALSE;
1111       gBS->OpenProtocol (
1112              Controller,
1113              &gEfiSdMmcPassThruProtocolGuid,
1114              (VOID **)&Partition->Device->Private->PassThru,
1115              This->DriverBindingHandle,
1116              ChildHandleBuffer[Index],
1117              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1118              );
1119       continue;
1120     }
1121 
1122     //
1123     // If Storage Security Command Protocol is installed, then uninstall this protocol.
1124     //
1125     Status = gBS->OpenProtocol (
1126                     ChildHandleBuffer[Index],
1127                     &gEfiStorageSecurityCommandProtocolGuid,
1128                     (VOID **) &StorageSecurity,
1129                     This->DriverBindingHandle,
1130                     Controller,
1131                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
1132                     );
1133 
1134     if (!EFI_ERROR (Status)) {
1135       Status = gBS->UninstallProtocolInterface (
1136                       ChildHandleBuffer[Index],
1137                       &gEfiStorageSecurityCommandProtocolGuid,
1138                       &Partition->StorageSecurity
1139                       );
1140       if (EFI_ERROR (Status)) {
1141         gBS->OpenProtocol (
1142           Controller,
1143           &gEfiSdMmcPassThruProtocolGuid,
1144           (VOID **) &Partition->Device->Private->PassThru,
1145           This->DriverBindingHandle,
1146           ChildHandleBuffer[Index],
1147           EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1148           );
1149         AllChildrenStopped = FALSE;
1150         continue;
1151       }
1152     }
1153 
1154     FreePool (Partition->DevicePath);
1155   }
1156 
1157   if (!AllChildrenStopped) {
1158     return EFI_DEVICE_ERROR;
1159   }
1160 
1161   return EFI_SUCCESS;
1162 }
1163 
1164 /**
1165   The user Entry Point for module EmmcDxe. The user code starts with this function.
1166 
1167   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
1168   @param[in] SystemTable    A pointer to the EFI System Table.
1169 
1170   @retval EFI_SUCCESS       The entry point is executed successfully.
1171   @retval other             Some errors occur when executing this entry point.
1172 
1173 **/
1174 EFI_STATUS
1175 EFIAPI
InitializeEmmcDxe(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)1176 InitializeEmmcDxe (
1177   IN EFI_HANDLE           ImageHandle,
1178   IN EFI_SYSTEM_TABLE     *SystemTable
1179   )
1180 {
1181   EFI_STATUS              Status;
1182 
1183   //
1184   // Install driver model protocol(s).
1185   //
1186   Status = EfiLibInstallDriverBindingComponentName2 (
1187              ImageHandle,
1188              SystemTable,
1189              &gEmmcDxeDriverBinding,
1190              ImageHandle,
1191              &gEmmcDxeComponentName,
1192              &gEmmcDxeComponentName2
1193              );
1194   ASSERT_EFI_ERROR (Status);
1195 
1196   return Status;
1197 }
1198 
1199