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