/** Finds out all the current Block IO PPIs in the system and add them into private data. @param PrivateData The private data structure that contains recovery module information. @param BlockIo2 Boolean to show whether using BlockIo2 or BlockIo. @retval EFI_SUCCESS The blocks and volumes are updated successfully. **/ EFI_STATUS UpdateBlocksAndVolumes ( IN OUT PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData, IN BOOLEAN BlockIo2 ) { EFI_STATUS Status; EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor; UINTN BlockIoPpiInstance; EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi; EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi; UINTN NumberBlockDevices; UINTN IndexBlockDevice; EFI_PEI_BLOCK_IO_MEDIA Media; EFI_PEI_BLOCK_IO2_MEDIA Media2; EFI_PEI_SERVICES **PeiServices; IndexBlockDevice = 0; BlockIo2Ppi = NULL; BlockIoPpi = NULL; // // Find out all Block Io Ppi instances within the system // Assuming all device Block Io Peims are dispatched already // for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_CD_EXPRESS_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) { if (BlockIo2) { Status = PeiServicesLocatePpi ( &gEfiPeiVirtualBlockIo2PpiGuid, BlockIoPpiInstance, &TempPpiDescriptor, (VOID **) &BlockIo2Ppi ); } else { Status = PeiServicesLocatePpi ( &gEfiPeiVirtualBlockIoPpiGuid, BlockIoPpiInstance, &TempPpiDescriptor, (VOID **) &BlockIoPpi ); } if (EFI_ERROR (Status)) { // // Done with all Block Io Ppis // break; } PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (); if (BlockIo2) { Status = BlockIo2Ppi->GetNumberOfBlockDevices ( PeiServices, BlockIo2Ppi, &NumberBlockDevices ); } else { Status = BlockIoPpi->GetNumberOfBlockDevices ( PeiServices, BlockIoPpi, &NumberBlockDevices ); } if (EFI_ERROR (Status) || (NumberBlockDevices == 0)) { continue; } // // Just retrieve the first block, should emulate all blocks. // for (IndexBlockDevice = 1; IndexBlockDevice <= NumberBlockDevices && PrivateData->CapsuleCount < PEI_CD_EXPRESS_MAX_CAPSULE_NUMBER; IndexBlockDevice ++) { if (BlockIo2) { Status = BlockIo2Ppi->GetBlockDeviceMediaInfo ( PeiServices, BlockIo2Ppi, IndexBlockDevice, &Media2 ); if (EFI_ERROR (Status) || !Media2.MediaPresent || ((Media2.InterfaceType != MSG_ATAPI_DP) && (Media2.InterfaceType != MSG_USB_DP)) || (Media2.BlockSize != PEI_CD_BLOCK_SIZE) ) { continue; } DEBUG ((EFI_D_INFO, "PeiCdExpress InterfaceType is %d\n", Media2.InterfaceType)); DEBUG ((EFI_D_INFO, "PeiCdExpress MediaPresent is %d\n", Media2.MediaPresent)); DEBUG ((EFI_D_INFO, "PeiCdExpress BlockSize is 0x%x\n", Media2.BlockSize)); } else { Status = BlockIoPpi->GetBlockDeviceMediaInfo ( PeiServices, BlockIoPpi, IndexBlockDevice, &Media ); if (EFI_ERROR (Status) || !Media.MediaPresent || ((Media.DeviceType != IdeCDROM) && (Media.DeviceType != UsbMassStorage)) || (Media.BlockSize != PEI_CD_BLOCK_SIZE) ) { continue; } DEBUG ((EFI_D_INFO, "PeiCdExpress DeviceType is %d\n", Media.DeviceType)); DEBUG ((EFI_D_INFO, "PeiCdExpress MediaPresent is %d\n", Media.MediaPresent)); DEBUG ((EFI_D_INFO, "PeiCdExpress BlockSize is 0x%x\n", Media.BlockSize)); } DEBUG ((EFI_D_INFO, "PeiCdExpress Status is %d\n", Status)); DEBUG ((EFI_D_INFO, "IndexBlockDevice is %d\n", IndexBlockDevice)); PrivateData->CapsuleData[PrivateData->CapsuleCount].IndexBlock = IndexBlockDevice; if (BlockIo2) { PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo2 = BlockIo2Ppi; } else { PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo = BlockIoPpi; } Status = FindRecoveryCapsules (PrivateData); DEBUG ((EFI_D_INFO, "Status is %d\n", Status)); if (EFI_ERROR (Status)) { continue; } PrivateData->CapsuleCount++; } } return EFI_SUCCESS; }
/** Discover all the block I/O devices to find the FAT volume. @param PrivateData Global memory map for accessing global variables. @param BlockIo2 Boolean to show whether using BlockIo2 or BlockIo @retval EFI_SUCCESS The function completed successfully. **/ EFI_STATUS UpdateBlocksAndVolumes ( IN OUT PEI_FAT_PRIVATE_DATA *PrivateData, IN BOOLEAN BlockIo2 ) { EFI_STATUS Status; EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor; UINTN BlockIoPpiInstance; EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi; EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi; UINTN NumberBlockDevices; UINTN Index; EFI_PEI_BLOCK_IO_MEDIA Media; EFI_PEI_BLOCK_IO2_MEDIA Media2; PEI_FAT_VOLUME Volume; EFI_PEI_SERVICES **PeiServices; PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (); BlockIo2Ppi = NULL; BlockIoPpi = NULL; // // Clean up caches // for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) { PrivateData->CacheBuffer[Index].Valid = FALSE; } PrivateData->BlockDeviceCount = 0; // // Find out all Block Io Ppi instances within the system // Assuming all device Block Io Peims are dispatched already // for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) { if (BlockIo2) { Status = PeiServicesLocatePpi ( &gEfiPeiVirtualBlockIo2PpiGuid, BlockIoPpiInstance, &TempPpiDescriptor, (VOID **) &BlockIo2Ppi ); } else { Status = PeiServicesLocatePpi ( &gEfiPeiVirtualBlockIoPpiGuid, BlockIoPpiInstance, &TempPpiDescriptor, (VOID **) &BlockIoPpi ); } if (EFI_ERROR (Status)) { // // Done with all Block Io Ppis // break; } if (BlockIo2) { Status = BlockIo2Ppi->GetNumberOfBlockDevices ( PeiServices, BlockIo2Ppi, &NumberBlockDevices ); } else { Status = BlockIoPpi->GetNumberOfBlockDevices ( PeiServices, BlockIoPpi, &NumberBlockDevices ); } if (EFI_ERROR (Status)) { continue; } for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) { if (BlockIo2) { Status = BlockIo2Ppi->GetBlockDeviceMediaInfo ( PeiServices, BlockIo2Ppi, Index, &Media2 ); if (EFI_ERROR (Status) || !Media2.MediaPresent) { continue; } PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo2 = BlockIo2Ppi; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].InterfaceType = Media2.InterfaceType; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media2.LastBlock; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = Media2.BlockSize; } else { Status = BlockIoPpi->GetBlockDeviceMediaInfo ( PeiServices, BlockIoPpi, Index, &Media ); if (EFI_ERROR (Status) || !Media.MediaPresent) { continue; } PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo = BlockIoPpi; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType = Media.DeviceType; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32) Media.BlockSize; } PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0; // // Not used here // PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical = FALSE; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked = FALSE; PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo = (UINT8) Index; PrivateData->BlockDeviceCount++; } } // // Find out all logical devices // FatFindPartitions (PrivateData); // // Build up file system volume array // PrivateData->VolumeCount = 0; for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) { Volume.BlockDeviceNo = Index; Status = FatGetBpbInfo (PrivateData, &Volume); if (Status == EFI_SUCCESS) { // // Add the detected volume to the volume array // CopyMem ( (UINT8 *) &(PrivateData->Volume[PrivateData->VolumeCount]), (UINT8 *) &Volume, sizeof (PEI_FAT_VOLUME) ); PrivateData->VolumeCount += 1; if (PrivateData->VolumeCount >= PEI_FAT_MAX_VOLUME) { break; } } } return EFI_SUCCESS; }