3 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "EmmcBlockIoPei.h"
11 // Template for EMMC HC Slot Data.
13 EMMC_PEIM_HC_SLOT gEmmcHcSlotTemplate
= {
14 EMMC_PEIM_SLOT_SIG
, // Signature
102 TRUE
, // SectorAddressing
107 // Template for EMMC HC Private Data.
109 EMMC_PEIM_HC_PRIVATE_DATA gEmmcHcPrivateTemplate
= {
110 EMMC_PEIM_SIG
, // Signature
113 EmmcBlockIoPeimGetDeviceNo
,
114 EmmcBlockIoPeimGetMediaInfo
,
115 EmmcBlockIoPeimReadBlocks
118 EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION
,
119 EmmcBlockIoPeimGetDeviceNo2
,
120 EmmcBlockIoPeimGetMediaInfo2
,
121 EmmcBlockIoPeimReadBlocks2
124 EFI_PEI_PPI_DESCRIPTOR_PPI
,
125 &gEfiPeiVirtualBlockIoPpiGuid
,
129 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
130 &gEfiPeiVirtualBlockIo2PpiGuid
,
133 { // EndOfPeiNotifyList
134 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
135 &gEfiEndOfPeiSignalPpiGuid
,
136 EmmcBlockIoPeimEndOfPei
159 0 // TotalBlkIoDevices
163 Gets the count of block I/O devices that one specific block driver detects.
165 This function is used for getting the count of block I/O devices that one
166 specific block driver detects. To the PEI ATAPI driver, it returns the number
167 of all the detected ATAPI devices it detects during the enumeration process.
168 To the PEI legacy floppy driver, it returns the number of all the legacy
169 devices it finds during its enumeration process. If no device is detected,
170 then the function will return zero.
172 @param[in] PeiServices General-purpose services that are available
174 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
176 @param[out] NumberBlockDevices The number of block I/O devices discovered.
178 @retval EFI_SUCCESS The operation performed successfully.
183 EmmcBlockIoPeimGetDeviceNo (
184 IN EFI_PEI_SERVICES
**PeiServices
,
185 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI
*This
,
186 OUT UINTN
*NumberBlockDevices
189 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
191 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This
);
192 *NumberBlockDevices
= Private
->TotalBlkIoDevices
;
197 Gets a block device's media information.
199 This function will provide the caller with the specified block device's media
200 information. If the media changes, calling this function will update the media
201 information accordingly.
203 @param[in] PeiServices General-purpose services that are available to every
205 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
206 @param[in] DeviceIndex Specifies the block device to which the function wants
207 to talk. Because the driver that implements Block I/O
208 PPIs will manage multiple block devices, the PPIs that
209 want to talk to a single device must specify the
210 device index that was assigned during the enumeration
211 process. This index is a number from one to
213 @param[out] MediaInfo The media information of the specified block media.
214 The caller is responsible for the ownership of this
218 The MediaInfo structure describes an enumeration of possible block device
219 types. This enumeration exists because no device paths are actually passed
220 across interfaces that describe the type or class of hardware that is publishing
221 the block I/O interface. This enumeration will allow for policy decisions
222 in the Recovery PEIM, such as "Try to recover from legacy floppy first,
223 LS-120 second, CD-ROM third." If there are multiple partitions abstracted
224 by a given device type, they should be reported in ascending order; this
225 order also applies to nested partitions, such as legacy MBR, where the
226 outermost partitions would have precedence in the reporting order. The
227 same logic applies to systems such as IDE that have precedence relationships
228 like "Master/Slave" or "Primary/Secondary". The master device should be
229 reported first, the slave second.
231 @retval EFI_SUCCESS Media information about the specified block device
232 was obtained successfully.
233 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
239 EmmcBlockIoPeimGetMediaInfo (
240 IN EFI_PEI_SERVICES
**PeiServices
,
241 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI
*This
,
242 IN UINTN DeviceIndex
,
243 OUT EFI_PEI_BLOCK_IO_MEDIA
*MediaInfo
246 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
253 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This
);
255 if ((DeviceIndex
== 0) || (DeviceIndex
> Private
->TotalBlkIoDevices
)) {
256 return EFI_INVALID_PARAMETER
;
261 for (SlotNum
= 0; SlotNum
< Private
->SlotNum
; SlotNum
++) {
262 for (MediaNum
= 0; MediaNum
< Private
->Slot
[SlotNum
].MediaNum
; MediaNum
++) {
264 if (Location
== DeviceIndex
) {
275 MediaInfo
->DeviceType
= EMMC
;
276 MediaInfo
->MediaPresent
= TRUE
;
277 MediaInfo
->LastBlock
= (UINTN
)Private
->Slot
[SlotNum
].Media
[MediaNum
].LastBlock
;
278 MediaInfo
->BlockSize
= Private
->Slot
[SlotNum
].Media
[MediaNum
].BlockSize
;
284 Reads the requested number of blocks from the specified block device.
286 The function reads the requested number of blocks from the device. All the
287 blocks are read, or an error is returned. If there is no media in the device,
288 the function returns EFI_NO_MEDIA.
290 @param[in] PeiServices General-purpose services that are available to
292 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
293 @param[in] DeviceIndex Specifies the block device to which the function wants
294 to talk. Because the driver that implements Block I/O
295 PPIs will manage multiple block devices, PPIs that
296 want to talk to a single device must specify the device
297 index that was assigned during the enumeration process.
298 This index is a number from one to NumberBlockDevices.
299 @param[in] StartLBA The starting logical block address (LBA) to read from
301 @param[in] BufferSize The size of the Buffer in bytes. This number must be
302 a multiple of the intrinsic block size of the device.
303 @param[out] Buffer A pointer to the destination buffer for the data.
304 The caller is responsible for the ownership of the
307 @retval EFI_SUCCESS The data was read correctly from the device.
308 @retval EFI_DEVICE_ERROR The device reported an error while attempting
309 to perform the read operation.
310 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
311 valid, or the buffer is not properly aligned.
312 @retval EFI_NO_MEDIA There is no media in the device.
313 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
314 the intrinsic block size of the device.
319 EmmcBlockIoPeimReadBlocks (
320 IN EFI_PEI_SERVICES
**PeiServices
,
321 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI
*This
,
322 IN UINTN DeviceIndex
,
323 IN EFI_PEI_LBA StartLBA
,
330 UINTN NumberOfBlocks
;
331 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
335 UINT8 PartitionConfig
;
340 Status
= EFI_SUCCESS
;
342 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This
);
347 if (Buffer
== NULL
) {
348 return EFI_INVALID_PARAMETER
;
351 if (BufferSize
== 0) {
355 if ((DeviceIndex
== 0) || (DeviceIndex
> Private
->TotalBlkIoDevices
)) {
356 return EFI_INVALID_PARAMETER
;
361 for (SlotNum
= 0; SlotNum
< Private
->SlotNum
; SlotNum
++) {
362 for (MediaNum
= 0; MediaNum
< Private
->Slot
[SlotNum
].MediaNum
; MediaNum
++) {
364 if (Location
== DeviceIndex
) {
375 BlockSize
= Private
->Slot
[SlotNum
].Media
[MediaNum
].BlockSize
;
376 if (BufferSize
% BlockSize
!= 0) {
377 return EFI_BAD_BUFFER_SIZE
;
380 if (StartLBA
> Private
->Slot
[SlotNum
].Media
[MediaNum
].LastBlock
) {
381 return EFI_INVALID_PARAMETER
;
384 NumberOfBlocks
= BufferSize
/ BlockSize
;
387 // Check if needs to switch partition access.
389 PartitionConfig
= Private
->Slot
[SlotNum
].ExtCsd
.PartitionConfig
;
390 if ((PartitionConfig
& 0x7) != Private
->Slot
[SlotNum
].PartitionType
[MediaNum
]) {
391 PartitionConfig
&= (UINT8
) ~0x7;
392 PartitionConfig
|= Private
->Slot
[SlotNum
].PartitionType
[MediaNum
];
393 Status
= EmmcPeimSwitch (
394 &Private
->Slot
[SlotNum
],
396 OFFSET_OF (EMMC_EXT_CSD
, PartitionConfig
),
400 if (EFI_ERROR (Status
)) {
404 Private
->Slot
[SlotNum
].ExtCsd
.PartitionConfig
= PartitionConfig
;
408 // Start to execute data transfer. The max block number in single cmd is 65535 blocks.
410 Remaining
= NumberOfBlocks
;
413 while (Remaining
> 0) {
414 if (Remaining
<= MaxBlock
) {
415 NumberOfBlocks
= Remaining
;
417 NumberOfBlocks
= MaxBlock
;
420 Status
= EmmcPeimSetBlkCount (&Private
->Slot
[SlotNum
], (UINT16
)NumberOfBlocks
);
421 if (EFI_ERROR (Status
)) {
425 BufferSize
= NumberOfBlocks
* BlockSize
;
426 Status
= EmmcPeimRwMultiBlocks (&Private
->Slot
[SlotNum
], StartLBA
, BlockSize
, Buffer
, BufferSize
, TRUE
);
427 if (EFI_ERROR (Status
)) {
431 StartLBA
+= NumberOfBlocks
;
432 Buffer
= (UINT8
*)Buffer
+ BufferSize
;
433 Remaining
-= NumberOfBlocks
;
440 Gets the count of block I/O devices that one specific block driver detects.
442 This function is used for getting the count of block I/O devices that one
443 specific block driver detects. To the PEI ATAPI driver, it returns the number
444 of all the detected ATAPI devices it detects during the enumeration process.
445 To the PEI legacy floppy driver, it returns the number of all the legacy
446 devices it finds during its enumeration process. If no device is detected,
447 then the function will return zero.
449 @param[in] PeiServices General-purpose services that are available
451 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI
453 @param[out] NumberBlockDevices The number of block I/O devices discovered.
455 @retval EFI_SUCCESS The operation performed successfully.
460 EmmcBlockIoPeimGetDeviceNo2 (
461 IN EFI_PEI_SERVICES
**PeiServices
,
462 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI
*This
,
463 OUT UINTN
*NumberBlockDevices
466 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
468 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This
);
469 *NumberBlockDevices
= Private
->TotalBlkIoDevices
;
475 Gets a block device's media information.
477 This function will provide the caller with the specified block device's media
478 information. If the media changes, calling this function will update the media
479 information accordingly.
481 @param[in] PeiServices General-purpose services that are available to every
483 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
484 @param[in] DeviceIndex Specifies the block device to which the function wants
485 to talk. Because the driver that implements Block I/O
486 PPIs will manage multiple block devices, the PPIs that
487 want to talk to a single device must specify the
488 device index that was assigned during the enumeration
489 process. This index is a number from one to
491 @param[out] MediaInfo The media information of the specified block media.
492 The caller is responsible for the ownership of this
496 The MediaInfo structure describes an enumeration of possible block device
497 types. This enumeration exists because no device paths are actually passed
498 across interfaces that describe the type or class of hardware that is publishing
499 the block I/O interface. This enumeration will allow for policy decisions
500 in the Recovery PEIM, such as "Try to recover from legacy floppy first,
501 LS-120 second, CD-ROM third." If there are multiple partitions abstracted
502 by a given device type, they should be reported in ascending order; this
503 order also applies to nested partitions, such as legacy MBR, where the
504 outermost partitions would have precedence in the reporting order. The
505 same logic applies to systems such as IDE that have precedence relationships
506 like "Master/Slave" or "Primary/Secondary". The master device should be
507 reported first, the slave second.
509 @retval EFI_SUCCESS Media information about the specified block device
510 was obtained successfully.
511 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
517 EmmcBlockIoPeimGetMediaInfo2 (
518 IN EFI_PEI_SERVICES
**PeiServices
,
519 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI
*This
,
520 IN UINTN DeviceIndex
,
521 OUT EFI_PEI_BLOCK_IO2_MEDIA
*MediaInfo
525 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
526 EFI_PEI_BLOCK_IO_MEDIA Media
;
533 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This
);
535 Status
= EmmcBlockIoPeimGetMediaInfo (
541 if (EFI_ERROR (Status
)) {
547 for (SlotNum
= 0; SlotNum
< Private
->SlotNum
; SlotNum
++) {
548 for (MediaNum
= 0; MediaNum
< Private
->Slot
[SlotNum
].MediaNum
; MediaNum
++) {
550 if (Location
== DeviceIndex
) {
561 CopyMem (MediaInfo
, &(Private
->Slot
[SlotNum
].Media
[MediaNum
]), sizeof (EFI_PEI_BLOCK_IO2_MEDIA
));
566 Reads the requested number of blocks from the specified block device.
568 The function reads the requested number of blocks from the device. All the
569 blocks are read, or an error is returned. If there is no media in the device,
570 the function returns EFI_NO_MEDIA.
572 @param[in] PeiServices General-purpose services that are available to
574 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
575 @param[in] DeviceIndex Specifies the block device to which the function wants
576 to talk. Because the driver that implements Block I/O
577 PPIs will manage multiple block devices, PPIs that
578 want to talk to a single device must specify the device
579 index that was assigned during the enumeration process.
580 This index is a number from one to NumberBlockDevices.
581 @param[in] StartLBA The starting logical block address (LBA) to read from
583 @param[in] BufferSize The size of the Buffer in bytes. This number must be
584 a multiple of the intrinsic block size of the device.
585 @param[out] Buffer A pointer to the destination buffer for the data.
586 The caller is responsible for the ownership of the
589 @retval EFI_SUCCESS The data was read correctly from the device.
590 @retval EFI_DEVICE_ERROR The device reported an error while attempting
591 to perform the read operation.
592 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
593 valid, or the buffer is not properly aligned.
594 @retval EFI_NO_MEDIA There is no media in the device.
595 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
596 the intrinsic block size of the device.
601 EmmcBlockIoPeimReadBlocks2 (
602 IN EFI_PEI_SERVICES
**PeiServices
,
603 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI
*This
,
604 IN UINTN DeviceIndex
,
605 IN EFI_PEI_LBA StartLBA
,
611 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
613 Status
= EFI_SUCCESS
;
614 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This
);
616 Status
= EmmcBlockIoPeimReadBlocks (
628 One notified function to cleanup the allocated DMA buffers at the end of PEI.
630 @param[in] PeiServices Pointer to PEI Services Table.
631 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification
632 event that caused this function to execute.
633 @param[in] Ppi Pointer to the PPI data associated with this function.
635 @retval EFI_SUCCESS The function completes successfully
640 EmmcBlockIoPeimEndOfPei (
641 IN EFI_PEI_SERVICES
**PeiServices
,
642 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
646 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
648 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor
);
650 if ((Private
->Pool
!= NULL
) && (Private
->Pool
->Head
!= NULL
)) {
651 EmmcPeimFreeMemPool (Private
->Pool
);
658 The user code starts with this function.
660 @param FileHandle Handle of the file being invoked.
661 @param PeiServices Describes the list of possible PEI Services.
663 @retval EFI_SUCCESS The driver is successfully initialized.
664 @retval Others Can't initialize the driver.
669 InitializeEmmcBlockIoPeim (
670 IN EFI_PEI_FILE_HANDLE FileHandle
,
671 IN CONST EFI_PEI_SERVICES
**PeiServices
675 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
676 EDKII_SD_MMC_HOST_CONTROLLER_PPI
*SdMmcHcPpi
;
678 UINT32 PartitionIndex
;
685 EMMC_EXT_CSD
*ExtCsd
;
686 EMMC_HC_SLOT_CAP Capability
;
687 EMMC_PEIM_HC_SLOT
*Slot
;
692 // Shadow this PEIM to run from memory
694 if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle
))) {
699 // locate Emmc host controller PPI
701 Status
= PeiServicesLocatePpi (
702 &gEdkiiPeiSdMmcHostControllerPpiGuid
,
707 if (EFI_ERROR (Status
)) {
708 return EFI_DEVICE_ERROR
;
716 Status
= SdMmcHcPpi
->GetSdMmcHcMmioBar (SdMmcHcPpi
, Controller
, &MmioBase
, &BarNum
);
718 // When status is error, meant no controller is found
720 if (EFI_ERROR (Status
)) {
729 Private
= AllocateCopyPool (sizeof (EMMC_PEIM_HC_PRIVATE_DATA
), &gEmmcHcPrivateTemplate
);
730 if (Private
== NULL
) {
731 Status
= EFI_OUT_OF_RESOURCES
;
735 Private
->BlkIoPpiList
.Ppi
= (VOID
*)&Private
->BlkIoPpi
;
736 Private
->BlkIo2PpiList
.Ppi
= (VOID
*)&Private
->BlkIo2Ppi
;
738 // Initialize the memory pool which will be used in all transactions.
740 Status
= EmmcPeimInitMemPool (Private
);
741 if (EFI_ERROR (Status
)) {
742 Status
= EFI_OUT_OF_RESOURCES
;
746 for (Index
= 0; Index
< BarNum
; Index
++) {
747 Status
= EmmcPeimHcGetCapability (MmioBase
[Index
], &Capability
);
748 if (EFI_ERROR (Status
)) {
752 if (Capability
.SlotType
!= 0x1) {
753 DEBUG ((DEBUG_INFO
, "The slot at 0x%x is not embedded slot type\n", MmioBase
[Index
]));
754 Status
= EFI_UNSUPPORTED
;
758 Status
= EmmcPeimHcReset (MmioBase
[Index
]);
759 if (EFI_ERROR (Status
)) {
763 Status
= EmmcPeimHcCardDetect (MmioBase
[Index
]);
764 if (EFI_ERROR (Status
)) {
768 Status
= EmmcPeimHcInitHost (MmioBase
[Index
]);
769 if (EFI_ERROR (Status
)) {
773 SlotNum
= Private
->SlotNum
;
774 Slot
= &Private
->Slot
[SlotNum
];
775 CopyMem (Slot
, &gEmmcHcSlotTemplate
, sizeof (EMMC_PEIM_HC_SLOT
));
776 Slot
->Private
= Private
;
777 Slot
->EmmcHcBase
= MmioBase
[Index
];
778 CopyMem (&Slot
->Capability
, &Capability
, sizeof (Capability
));
780 Status
= EmmcPeimIdentification (Slot
);
781 if (EFI_ERROR (Status
)) {
785 ExtCsd
= &Slot
->ExtCsd
;
786 if (ExtCsd
->ExtCsdRev
< 5) {
787 DEBUG ((DEBUG_ERROR
, "The EMMC device version is too low, we don't support!!!\n"));
788 Status
= EFI_UNSUPPORTED
;
792 if ((ExtCsd
->PartitioningSupport
& BIT0
) != BIT0
) {
793 DEBUG ((DEBUG_ERROR
, "The EMMC device doesn't support Partition Feature!!!\n"));
794 Status
= EFI_UNSUPPORTED
;
798 for (PartitionIndex
= 0; PartitionIndex
< EMMC_PEIM_MAX_PARTITIONS
; PartitionIndex
++) {
799 switch (PartitionIndex
) {
800 case EmmcPartitionUserData
:
801 SecCount
= *(UINT32
*)&ExtCsd
->SecCount
;
802 Capacity
= MultU64x32 ((UINT64
)SecCount
, 0x200);
804 case EmmcPartitionBoot1
:
805 case EmmcPartitionBoot2
:
806 Capacity
= ExtCsd
->BootSizeMult
* SIZE_128KB
;
808 case EmmcPartitionRPMB
:
809 Capacity
= ExtCsd
->RpmbSizeMult
* SIZE_128KB
;
811 case EmmcPartitionGP1
:
812 GpSizeMult
= (ExtCsd
->GpSizeMult
[0] | (ExtCsd
->GpSizeMult
[1] << 8) | (ExtCsd
->GpSizeMult
[2] << 16));
813 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
815 case EmmcPartitionGP2
:
816 GpSizeMult
= (ExtCsd
->GpSizeMult
[3] | (ExtCsd
->GpSizeMult
[4] << 8) | (ExtCsd
->GpSizeMult
[5] << 16));
817 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
819 case EmmcPartitionGP3
:
820 GpSizeMult
= (ExtCsd
->GpSizeMult
[6] | (ExtCsd
->GpSizeMult
[7] << 8) | (ExtCsd
->GpSizeMult
[8] << 16));
821 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
823 case EmmcPartitionGP4
:
824 GpSizeMult
= (ExtCsd
->GpSizeMult
[9] | (ExtCsd
->GpSizeMult
[10] << 8) | (ExtCsd
->GpSizeMult
[11] << 16));
825 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
832 MediaNum
= Slot
->MediaNum
;
834 Slot
->Media
[MediaNum
].LastBlock
= DivU64x32 (Capacity
, Slot
->Media
[MediaNum
].BlockSize
) - 1;
835 Slot
->PartitionType
[MediaNum
] = PartitionIndex
;
836 Private
->TotalBlkIoDevices
++;
846 if (!EFI_ERROR (Status
)) {
847 PeiServicesInstallPpi (&Private
->BlkIoPpiList
);
848 PeiServicesNotifyPpi (&Private
->EndOfPeiNotifyList
);
850 if (Private
->Pool
->Head
!= NULL
) {
851 EmmcPeimFreeMemPool (Private
->Pool
);