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