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