]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.c
Vlv2TbltDevicePkg: fix ASSERT_EFI_ERROR() typos
[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 { // 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
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
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
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
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
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 Status = gBS->InstallMultipleProtocolInterfaces (
447 &Partition->Handle,
448 &gEfiDevicePathProtocolGuid,
449 Partition->DevicePath,
450 &gEfiBlockIoProtocolGuid,
451 &Partition->BlockIo,
452 &gEfiBlockIo2ProtocolGuid,
453 &Partition->BlockIo2,
454 NULL
455 );
456 if (EFI_ERROR (Status)) {
457 goto Error;
458 }
459
460 if (Partition->PartitionType != EmmcPartitionRPMB) {
461 Status = gBS->InstallProtocolInterface (
462 &Partition->Handle,
463 &gEfiEraseBlockProtocolGuid,
464 EFI_NATIVE_INTERFACE,
465 &Partition->EraseBlock
466 );
467 if (EFI_ERROR (Status)) {
468 gBS->UninstallMultipleProtocolInterfaces (
469 &Partition->Handle,
470 &gEfiDevicePathProtocolGuid,
471 Partition->DevicePath,
472 &gEfiBlockIoProtocolGuid,
473 &Partition->BlockIo,
474 &gEfiBlockIo2ProtocolGuid,
475 &Partition->BlockIo2,
476 NULL
477 );
478 goto Error;
479 }
480 }
481
482 if (((Partition->PartitionType == EmmcPartitionUserData) ||
483 (Partition->PartitionType == EmmcPartitionBoot1) ||
484 (Partition->PartitionType == EmmcPartitionBoot2)) &&
485 ((Device->Csd.Ccc & BIT10) != 0)) {
486 Status = gBS->InstallProtocolInterface (
487 &Partition->Handle,
488 &gEfiStorageSecurityCommandProtocolGuid,
489 EFI_NATIVE_INTERFACE,
490 &Partition->StorageSecurity
491 );
492 if (EFI_ERROR (Status)) {
493 gBS->UninstallMultipleProtocolInterfaces (
494 &Partition->Handle,
495 &gEfiDevicePathProtocolGuid,
496 Partition->DevicePath,
497 &gEfiBlockIoProtocolGuid,
498 &Partition->BlockIo,
499 &gEfiBlockIo2ProtocolGuid,
500 &Partition->BlockIo2,
501 &gEfiEraseBlockProtocolGuid,
502 &Partition->EraseBlock,
503 NULL
504 );
505 goto Error;
506 }
507 }
508
509 gBS->OpenProtocol (
510 Device->Private->Controller,
511 &gEfiSdMmcPassThruProtocolGuid,
512 (VOID **) &(Device->Private->PassThru),
513 Device->Private->DriverBindingHandle,
514 Partition->Handle,
515 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
516 );
517 } else {
518 Status = EFI_INVALID_PARAMETER;
519 }
520
521 Error:
522 if (EFI_ERROR (Status) && (DevicePath != NULL)) {
523 FreePool (DevicePath);
524 }
525
526 return Status;
527 }
528
529 /**
530 Scan EMMC Bus to discover the device.
531
532 @param[in] Private The EMMC driver private data structure.
533 @param[in] Slot The slot number to check device present.
534 @param[in] RemainingDevicePath The pointer to the remaining device path.
535
536 @retval EFI_SUCCESS Successfully to discover the device and attach
537 SdMmcIoProtocol to it.
538 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
539 of resources.
540 @retval EFI_ALREADY_STARTED The device was discovered before.
541 @retval Others Fail to discover the device.
542
543 **/
544 EFI_STATUS
545 EFIAPI
546 DiscoverEmmcDevice (
547 IN EMMC_DRIVER_PRIVATE_DATA *Private,
548 IN UINT8 Slot,
549 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
550 )
551 {
552 EFI_STATUS Status;
553 EMMC_DEVICE *Device;
554 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
555 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
556 EFI_DEVICE_PATH_PROTOCOL *RemainingEmmcDevPath;
557 EFI_DEV_PATH *Node;
558 EFI_HANDLE DeviceHandle;
559 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
560 UINT8 Index;
561
562 Device = NULL;
563 DevicePath = NULL;
564 NewDevicePath = NULL;
565 RemainingDevicePath = NULL;
566 PassThru = Private->PassThru;
567 Device = &Private->Device[Slot];
568
569 //
570 // Build Device Path to check if the EMMC device present at the slot.
571 //
572 Status = PassThru->BuildDevicePath (
573 PassThru,
574 Slot,
575 &DevicePath
576 );
577 if (EFI_ERROR(Status)) {
578 return Status;
579 }
580
581 if (DevicePath->SubType != MSG_EMMC_DP) {
582 Status = EFI_UNSUPPORTED;
583 goto Error;
584 }
585
586 NewDevicePath = AppendDevicePathNode (
587 Private->ParentDevicePath,
588 DevicePath
589 );
590 if (NewDevicePath == NULL) {
591 Status = EFI_OUT_OF_RESOURCES;
592 goto Error;
593 }
594
595 DeviceHandle = NULL;
596 RemainingEmmcDevPath = NewDevicePath;
597 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingEmmcDevPath, &DeviceHandle);
598 //
599 // The device path to the EMMC device doesn't exist. It means the corresponding device private data hasn't been initialized.
600 //
601 if (EFI_ERROR (Status) || (DeviceHandle == NULL) || !IsDevicePathEnd (RemainingEmmcDevPath)) {
602 Device->DevicePath = NewDevicePath;
603 Device->Slot = Slot;
604 Device->Private = Private;
605 //
606 // Expose user area in the Sd memory card to upper layer.
607 //
608 Status = DiscoverAllPartitions (Device);
609 if (EFI_ERROR(Status)) {
610 FreePool (NewDevicePath);
611 goto Error;
612 }
613
614 Status = gBS->InstallProtocolInterface (
615 &Device->Handle,
616 &gEfiDevicePathProtocolGuid,
617 EFI_NATIVE_INTERFACE,
618 Device->DevicePath
619 );
620 if (EFI_ERROR(Status)) {
621 FreePool (NewDevicePath);
622 goto Error;
623 }
624
625 Device->ControllerNameTable = NULL;
626 GetEmmcModelName (Device, &Device->Cid);
627 AddUnicodeString2 (
628 "eng",
629 gEmmcDxeComponentName.SupportedLanguages,
630 &Device->ControllerNameTable,
631 Device->ModelName,
632 TRUE
633 );
634 AddUnicodeString2 (
635 "en",
636 gEmmcDxeComponentName.SupportedLanguages,
637 &Device->ControllerNameTable,
638 Device->ModelName,
639 FALSE
640 );
641 }
642
643 if (RemainingDevicePath == NULL) {
644 //
645 // Expose all partitions in the Emmc device to upper layer.
646 //
647 for (Index = 0; Index < EMMC_MAX_PARTITIONS; Index++) {
648 InstallProtocolOnPartition (Device, Index);
649 }
650 } else if (!IsDevicePathEnd (RemainingDevicePath)) {
651 //
652 // Enumerate the specified partition
653 //
654 Node = (EFI_DEV_PATH *) RemainingDevicePath;
655 if ((DevicePathType (&Node->DevPath) != HARDWARE_DEVICE_PATH) ||
656 (DevicePathSubType (&Node->DevPath) != HW_CONTROLLER_DP) ||
657 (DevicePathNodeLength (&Node->DevPath) != sizeof (CONTROLLER_DEVICE_PATH))) {
658 Status = EFI_INVALID_PARAMETER;
659 goto Error;
660 }
661
662 Index = (UINT8)Node->Controller.ControllerNumber;
663 if (Index >= EMMC_MAX_PARTITIONS) {
664 Status = EFI_INVALID_PARAMETER;
665 goto Error;
666 }
667
668 Status = InstallProtocolOnPartition (Device, Index);
669 }
670
671 Error:
672 FreePool (DevicePath);
673
674 return Status;
675 }
676
677 /**
678 Tests to see if this driver supports a given controller. If a child device is provided,
679 it further tests to see if this driver supports creating a handle for the specified child device.
680
681 This function checks to see if the driver specified by This supports the device specified by
682 ControllerHandle. Drivers will typically use the device path attached to
683 ControllerHandle and/or the services from the bus I/O abstraction attached to
684 ControllerHandle to determine if the driver supports ControllerHandle. This function
685 may be called many times during platform initialization. In order to reduce boot times, the tests
686 performed by this function must be very small, and take as little time as possible to execute. This
687 function must not change the state of any hardware devices, and this function must be aware that the
688 device specified by ControllerHandle may already be managed by the same driver or a
689 different driver. This function must match its calls to AllocatePages() with FreePages(),
690 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
691 Since ControllerHandle may have been previously started by the same driver, if a protocol is
692 already in the opened state, then it must not be closed with CloseProtocol(). This is required
693 to guarantee the state of ControllerHandle is not modified by this function.
694
695 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
696 @param[in] ControllerHandle The handle of the controller to test. This handle
697 must support a protocol interface that supplies
698 an I/O abstraction to the driver.
699 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
700 parameter is ignored by device drivers, and is optional for bus
701 drivers. For bus drivers, if this parameter is not NULL, then
702 the bus driver must determine if the bus controller specified
703 by ControllerHandle and the child controller specified
704 by RemainingDevicePath are both supported by this
705 bus driver.
706
707 @retval EFI_SUCCESS The device specified by ControllerHandle and
708 RemainingDevicePath is supported by the driver specified by This.
709 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
710 RemainingDevicePath is already being managed by the driver
711 specified by This.
712 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
713 RemainingDevicePath is already being managed by a different
714 driver or an application that requires exclusive access.
715 Currently not implemented.
716 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
717 RemainingDevicePath is not supported by the driver specified by This.
718 **/
719 EFI_STATUS
720 EFIAPI
721 EmmcDxeDriverBindingSupported (
722 IN EFI_DRIVER_BINDING_PROTOCOL *This,
723 IN EFI_HANDLE Controller,
724 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
725 )
726 {
727 EFI_STATUS Status;
728 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
729 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
730 UINT8 Slot;
731
732 //
733 // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle.
734 //
735 Status = gBS->OpenProtocol (
736 Controller,
737 &gEfiSdMmcPassThruProtocolGuid,
738 (VOID**) &PassThru,
739 This->DriverBindingHandle,
740 Controller,
741 EFI_OPEN_PROTOCOL_BY_DRIVER
742 );
743
744 if (Status == EFI_ALREADY_STARTED) {
745 return EFI_SUCCESS;
746 }
747
748 if (EFI_ERROR (Status)) {
749 return Status;
750 }
751
752 //
753 // Test RemainingDevicePath is valid or not.
754 //
755 if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
756 Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
757 if (EFI_ERROR (Status)) {
758 //
759 // Close the I/O Abstraction(s) used to perform the supported test
760 //
761 gBS->CloseProtocol (
762 Controller,
763 &gEfiSdMmcPassThruProtocolGuid,
764 This->DriverBindingHandle,
765 Controller
766 );
767 return Status;
768 }
769 }
770
771 //
772 // Close the I/O Abstraction(s) used to perform the supported test
773 //
774 gBS->CloseProtocol (
775 Controller,
776 &gEfiSdMmcPassThruProtocolGuid,
777 This->DriverBindingHandle,
778 Controller
779 );
780
781 //
782 // Open the EFI Device Path protocol needed to perform the supported test
783 //
784 Status = gBS->OpenProtocol (
785 Controller,
786 &gEfiDevicePathProtocolGuid,
787 (VOID **) &ParentDevicePath,
788 This->DriverBindingHandle,
789 Controller,
790 EFI_OPEN_PROTOCOL_GET_PROTOCOL
791 );
792 return Status;
793 }
794
795 /**
796 Starts a device controller or a bus controller.
797
798 The Start() function is designed to be invoked from the EFI boot service ConnectController().
799 As a result, much of the error checking on the parameters to Start() has been moved into this
800 common boot service. It is legal to call Start() from other locations,
801 but the following calling restrictions must be followed or the system behavior will not be deterministic.
802 1. ControllerHandle must be a valid EFI_HANDLE.
803 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
804 EFI_DEVICE_PATH_PROTOCOL.
805 3. Prior to calling Start(), the Supported() function for the driver specified by This must
806 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
807
808 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
809 @param[in] ControllerHandle The handle of the controller to start. This handle
810 must support a protocol interface that supplies
811 an I/O abstraction to the driver.
812 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
813 parameter is ignored by device drivers, and is optional for bus
814 drivers. For a bus driver, if this parameter is NULL, then handles
815 for all the children of Controller are created by this driver.
816 If this parameter is not NULL and the first Device Path Node is
817 not the End of Device Path Node, then only the handle for the
818 child device specified by the first Device Path Node of
819 RemainingDevicePath is created by this driver.
820 If the first Device Path Node of RemainingDevicePath is
821 the End of Device Path Node, no child handle is created by this
822 driver.
823
824 @retval EFI_SUCCESS The device was started.
825 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
826 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
827 @retval Others The driver failded to start the device.
828
829 **/
830 EFI_STATUS
831 EFIAPI
832 EmmcDxeDriverBindingStart (
833 IN EFI_DRIVER_BINDING_PROTOCOL *This,
834 IN EFI_HANDLE Controller,
835 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
836 )
837 {
838 EFI_STATUS Status;
839 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
840 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
841 EMMC_DRIVER_PRIVATE_DATA *Private;
842 UINT8 Slot;
843
844 Private = NULL;
845 PassThru = NULL;
846 Status = gBS->OpenProtocol (
847 Controller,
848 &gEfiSdMmcPassThruProtocolGuid,
849 (VOID **) &PassThru,
850 This->DriverBindingHandle,
851 Controller,
852 EFI_OPEN_PROTOCOL_BY_DRIVER
853 );
854 if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
855 return Status;
856 }
857
858 //
859 // Check EFI_ALREADY_STARTED to reuse the original EMMC_DRIVER_PRIVATE_DATA.
860 //
861 if (Status != EFI_ALREADY_STARTED) {
862 Private = AllocateZeroPool (sizeof (EMMC_DRIVER_PRIVATE_DATA));
863 if (Private == NULL) {
864 Status = EFI_OUT_OF_RESOURCES;
865 goto Error;
866 }
867
868 Status = gBS->OpenProtocol (
869 Controller,
870 &gEfiDevicePathProtocolGuid,
871 (VOID **) &ParentDevicePath,
872 This->DriverBindingHandle,
873 Controller,
874 EFI_OPEN_PROTOCOL_GET_PROTOCOL
875 );
876 ASSERT_EFI_ERROR (Status);
877 Private->PassThru = PassThru;
878 Private->Controller = Controller;
879 Private->ParentDevicePath = ParentDevicePath;
880 Private->DriverBindingHandle = This->DriverBindingHandle;
881
882 Status = gBS->InstallProtocolInterface (
883 &Controller,
884 &gEfiCallerIdGuid,
885 EFI_NATIVE_INTERFACE,
886 Private
887 );
888 if (EFI_ERROR (Status)) {
889 goto Error;
890 }
891 } else {
892 Status = gBS->OpenProtocol (
893 Controller,
894 &gEfiCallerIdGuid,
895 (VOID **) &Private,
896 This->DriverBindingHandle,
897 Controller,
898 EFI_OPEN_PROTOCOL_GET_PROTOCOL
899 );
900 if (EFI_ERROR (Status)) {
901 goto Error;
902 }
903 }
904
905 if (RemainingDevicePath == NULL) {
906 Slot = 0xFF;
907 while (TRUE) {
908 Status = PassThru->GetNextSlot (PassThru, &Slot);
909 if (EFI_ERROR (Status)) {
910 //
911 // Cannot find more legal slots.
912 //
913 Status = EFI_SUCCESS;
914 break;
915 }
916
917 Status = DiscoverEmmcDevice (Private, Slot, NULL);
918 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
919 break;
920 }
921 }
922 } else if (!IsDevicePathEnd (RemainingDevicePath)) {
923 Status = PassThru->GetSlotNumber (PassThru, RemainingDevicePath, &Slot);
924 if (!EFI_ERROR (Status)) {
925 Status = DiscoverEmmcDevice (Private, Slot, NextDevicePathNode (RemainingDevicePath));
926 }
927 }
928
929 Error:
930 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
931 gBS->CloseProtocol (
932 Controller,
933 &gEfiSdMmcPassThruProtocolGuid,
934 This->DriverBindingHandle,
935 Controller
936 );
937
938 if (Private != NULL) {
939 gBS->UninstallMultipleProtocolInterfaces (
940 Controller,
941 &gEfiCallerIdGuid,
942 Private,
943 NULL
944 );
945 FreePool (Private);
946 }
947 }
948 return Status;
949 }
950
951 /**
952 Stops a device controller or a bus controller.
953
954 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
955 As a result, much of the error checking on the parameters to Stop() has been moved
956 into this common boot service. It is legal to call Stop() from other locations,
957 but the following calling restrictions must be followed or the system behavior will not be deterministic.
958 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
959 same driver's Start() function.
960 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
961 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
962 Start() function, and the Start() function must have called OpenProtocol() on
963 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
964
965 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
966 @param[in] ControllerHandle A handle to the device being stopped. The handle must
967 support a bus specific I/O protocol for the driver
968 to use to stop the device.
969 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
970 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
971 if NumberOfChildren is 0.
972
973 @retval EFI_SUCCESS The device was stopped.
974 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
975
976 **/
977 EFI_STATUS
978 EFIAPI
979 EmmcDxeDriverBindingStop (
980 IN EFI_DRIVER_BINDING_PROTOCOL *This,
981 IN EFI_HANDLE Controller,
982 IN UINTN NumberOfChildren,
983 IN EFI_HANDLE *ChildHandleBuffer
984 )
985 {
986 EFI_STATUS Status;
987 BOOLEAN AllChildrenStopped;
988 UINTN Index;
989 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
990 EMMC_DRIVER_PRIVATE_DATA *Private;
991 EMMC_DEVICE *Device;
992 EMMC_PARTITION *Partition;
993 EFI_BLOCK_IO_PROTOCOL *BlockIo;
994 EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
995 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurity;
996 EFI_ERASE_BLOCK_PROTOCOL *EraseBlock;
997 LIST_ENTRY *Link;
998 LIST_ENTRY *NextLink;
999 EMMC_REQUEST *Request;
1000
1001 BlockIo = NULL;
1002 BlockIo2 = NULL;
1003 if (NumberOfChildren == 0) {
1004 Status = gBS->OpenProtocol (
1005 Controller,
1006 &gEfiCallerIdGuid,
1007 (VOID **) &Private,
1008 This->DriverBindingHandle,
1009 Controller,
1010 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1011 );
1012 if (EFI_ERROR (Status)) {
1013 return EFI_DEVICE_ERROR;
1014 }
1015
1016 for (Index = 0; Index < EMMC_MAX_DEVICES; Index++) {
1017 Device = &Private->Device[Index];
1018 Status = gBS->OpenProtocol (
1019 Device->Handle,
1020 &gEfiDevicePathProtocolGuid,
1021 (VOID **) &DevicePath,
1022 This->DriverBindingHandle,
1023 Controller,
1024 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1025 );
1026 if (EFI_ERROR (Status)) {
1027 continue;
1028 }
1029 ASSERT (DevicePath == Device->DevicePath);
1030 gBS->UninstallProtocolInterface (
1031 Device->Handle,
1032 &gEfiDevicePathProtocolGuid,
1033 DevicePath
1034 );
1035 FreePool (Device->DevicePath);
1036 }
1037
1038 gBS->UninstallProtocolInterface (
1039 Controller,
1040 &gEfiCallerIdGuid,
1041 Private
1042 );
1043 gBS->CloseProtocol (
1044 Controller,
1045 &gEfiSdMmcPassThruProtocolGuid,
1046 This->DriverBindingHandle,
1047 Controller
1048 );
1049 FreePool (Private);
1050
1051 return EFI_SUCCESS;
1052 }
1053
1054 AllChildrenStopped = TRUE;
1055
1056 for (Index = 0; Index < NumberOfChildren; Index++) {
1057 Status = gBS->OpenProtocol (
1058 ChildHandleBuffer[Index],
1059 &gEfiBlockIoProtocolGuid,
1060 (VOID **) &BlockIo,
1061 This->DriverBindingHandle,
1062 Controller,
1063 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1064 );
1065 if (EFI_ERROR (Status)) {
1066 Status = gBS->OpenProtocol (
1067 ChildHandleBuffer[Index],
1068 &gEfiBlockIo2ProtocolGuid,
1069 (VOID **) &BlockIo2,
1070 This->DriverBindingHandle,
1071 Controller,
1072 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1073 );
1074 if (EFI_ERROR (Status)) {
1075 AllChildrenStopped = FALSE;
1076 continue;
1077 }
1078 }
1079
1080 if (BlockIo != NULL) {
1081 Partition = EMMC_PARTITION_DATA_FROM_BLKIO (BlockIo);
1082 } else {
1083 ASSERT (BlockIo2 != NULL);
1084 Partition = EMMC_PARTITION_DATA_FROM_BLKIO2 (BlockIo2);
1085 }
1086
1087 for (Link = GetFirstNode (&Partition->Queue);
1088 !IsNull (&Partition->Queue, Link);
1089 Link = NextLink) {
1090 NextLink = GetNextNode (&Partition->Queue, Link);
1091
1092 RemoveEntryList (Link);
1093 Request = EMMC_REQUEST_FROM_LINK (Link);
1094
1095 gBS->CloseEvent (Request->Event);
1096 Request->Token->TransactionStatus = EFI_ABORTED;
1097
1098 if (Request->IsEnd) {
1099 gBS->SignalEvent (Request->Token->Event);
1100 }
1101
1102 FreePool (Request);
1103 }
1104
1105 //
1106 // Close the child handle
1107 //
1108 Status = gBS->CloseProtocol (
1109 Controller,
1110 &gEfiSdMmcPassThruProtocolGuid,
1111 This->DriverBindingHandle,
1112 ChildHandleBuffer[Index]
1113 );
1114
1115 Status = gBS->UninstallMultipleProtocolInterfaces (
1116 ChildHandleBuffer[Index],
1117 &gEfiDevicePathProtocolGuid,
1118 Partition->DevicePath,
1119 &gEfiBlockIoProtocolGuid,
1120 &Partition->BlockIo,
1121 &gEfiBlockIo2ProtocolGuid,
1122 &Partition->BlockIo2,
1123 NULL
1124 );
1125 if (EFI_ERROR (Status)) {
1126 AllChildrenStopped = FALSE;
1127 gBS->OpenProtocol (
1128 Controller,
1129 &gEfiSdMmcPassThruProtocolGuid,
1130 (VOID **)&Partition->Device->Private->PassThru,
1131 This->DriverBindingHandle,
1132 ChildHandleBuffer[Index],
1133 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1134 );
1135 continue;
1136 }
1137
1138 //
1139 // If Erase Block Protocol is installed, then uninstall this protocol.
1140 //
1141 Status = gBS->OpenProtocol (
1142 ChildHandleBuffer[Index],
1143 &gEfiEraseBlockProtocolGuid,
1144 (VOID **) &EraseBlock,
1145 This->DriverBindingHandle,
1146 Controller,
1147 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1148 );
1149
1150 if (!EFI_ERROR (Status)) {
1151 Status = gBS->UninstallProtocolInterface (
1152 ChildHandleBuffer[Index],
1153 &gEfiEraseBlockProtocolGuid,
1154 &Partition->EraseBlock
1155 );
1156 if (EFI_ERROR (Status)) {
1157 gBS->OpenProtocol (
1158 Controller,
1159 &gEfiSdMmcPassThruProtocolGuid,
1160 (VOID **) &Partition->Device->Private->PassThru,
1161 This->DriverBindingHandle,
1162 ChildHandleBuffer[Index],
1163 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1164 );
1165 AllChildrenStopped = FALSE;
1166 continue;
1167 }
1168 }
1169
1170 //
1171 // If Storage Security Command Protocol is installed, then uninstall this protocol.
1172 //
1173 Status = gBS->OpenProtocol (
1174 ChildHandleBuffer[Index],
1175 &gEfiStorageSecurityCommandProtocolGuid,
1176 (VOID **) &StorageSecurity,
1177 This->DriverBindingHandle,
1178 Controller,
1179 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1180 );
1181
1182 if (!EFI_ERROR (Status)) {
1183 Status = gBS->UninstallProtocolInterface (
1184 ChildHandleBuffer[Index],
1185 &gEfiStorageSecurityCommandProtocolGuid,
1186 &Partition->StorageSecurity
1187 );
1188 if (EFI_ERROR (Status)) {
1189 gBS->OpenProtocol (
1190 Controller,
1191 &gEfiSdMmcPassThruProtocolGuid,
1192 (VOID **) &Partition->Device->Private->PassThru,
1193 This->DriverBindingHandle,
1194 ChildHandleBuffer[Index],
1195 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1196 );
1197 AllChildrenStopped = FALSE;
1198 continue;
1199 }
1200 }
1201
1202 FreePool (Partition->DevicePath);
1203 }
1204
1205 if (!AllChildrenStopped) {
1206 return EFI_DEVICE_ERROR;
1207 }
1208
1209 return EFI_SUCCESS;
1210 }
1211
1212 /**
1213 The user Entry Point for module EmmcDxe. The user code starts with this function.
1214
1215 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1216 @param[in] SystemTable A pointer to the EFI System Table.
1217
1218 @retval EFI_SUCCESS The entry point is executed successfully.
1219 @retval other Some errors occur when executing this entry point.
1220
1221 **/
1222 EFI_STATUS
1223 EFIAPI
1224 InitializeEmmcDxe (
1225 IN EFI_HANDLE ImageHandle,
1226 IN EFI_SYSTEM_TABLE *SystemTable
1227 )
1228 {
1229 EFI_STATUS Status;
1230
1231 //
1232 // Install driver model protocol(s).
1233 //
1234 Status = EfiLibInstallDriverBindingComponentName2 (
1235 ImageHandle,
1236 SystemTable,
1237 &gEmmcDxeDriverBinding,
1238 ImageHandle,
1239 &gEmmcDxeComponentName,
1240 &gEmmcDxeComponentName2
1241 );
1242 ASSERT_EFI_ERROR (Status);
1243
1244 return Status;
1245 }
1246