EmbeddedPkg: Move Universal/MmcDxe from ArmPkg to EmbeddedPkg
The MmcDxe is not ARM architecture specific. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11725 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
387
EmbeddedPkg/Universal/MmcDxe/Mmc.c
Normal file
387
EmbeddedPkg/Universal/MmcDxe/Mmc.c
Normal file
@@ -0,0 +1,387 @@
|
||||
/** @file
|
||||
Main file of the MMC Dxe driver. The driver entrypoint is defined into this file.
|
||||
|
||||
Copyright (c) 2011, ARM Limited. All rights reserved.
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <Protocol/DevicePath.h>
|
||||
#include <Protocol/MmcHost.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include "Mmc.h"
|
||||
|
||||
EFI_BLOCK_IO_MEDIA mMmcMediaTemplate = {
|
||||
SIGNATURE_32('m','m','c','o'), // MediaId
|
||||
TRUE, // RemovableMedia
|
||||
FALSE, // MediaPresent
|
||||
FALSE, // LogicalPartition
|
||||
FALSE, // ReadOnly
|
||||
FALSE, // WriteCaching
|
||||
512, // BlockSize
|
||||
4, // IoAlign
|
||||
0, // Pad
|
||||
0 // LastBlock
|
||||
};
|
||||
|
||||
//
|
||||
// This device structure is serviced as a header.
|
||||
// Its next field points to the first root bridge device node.
|
||||
//
|
||||
LIST_ENTRY mMmcHostPool;
|
||||
|
||||
/**
|
||||
Initialize the MMC Host Pool to support multiple MMC devices
|
||||
**/
|
||||
VOID
|
||||
InitializeMmcHostPool (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
InitializeListHead (&mMmcHostPool);
|
||||
}
|
||||
|
||||
/**
|
||||
Insert a new Mmc Host controller to the pool
|
||||
**/
|
||||
VOID
|
||||
InsertMmcHost (
|
||||
IN MMC_HOST_INSTANCE *MmcHostInstance
|
||||
)
|
||||
{
|
||||
InsertTailList (&mMmcHostPool, &(MmcHostInstance->Link));
|
||||
}
|
||||
|
||||
/*
|
||||
Remove a new Mmc Host controller to the pool
|
||||
*/
|
||||
VOID
|
||||
RemoveMmcHost (
|
||||
IN MMC_HOST_INSTANCE *MmcHostInstance
|
||||
)
|
||||
{
|
||||
RemoveEntryList (&(MmcHostInstance->Link));
|
||||
}
|
||||
|
||||
MMC_HOST_INSTANCE* CreateMmcHostInstance(
|
||||
IN EFI_MMC_HOST_PROTOCOL* MmcHost
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MMC_HOST_INSTANCE* MmcHostInstance;
|
||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
|
||||
MmcHostInstance = AllocateZeroPool (sizeof (MMC_HOST_INSTANCE));
|
||||
if (MmcHostInstance == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MmcHostInstance->Signature = MMC_HOST_INSTANCE_SIGNATURE;
|
||||
|
||||
MmcHostInstance->State = MmcHwInitializationState;
|
||||
|
||||
MmcHostInstance->BlockIo.Media = AllocateCopyPool (sizeof(EFI_BLOCK_IO_MEDIA), &mMmcMediaTemplate);
|
||||
if (MmcHostInstance->BlockIo.Media == NULL) {
|
||||
goto FREE_INSTANCE;
|
||||
}
|
||||
|
||||
MmcHostInstance->BlockIo.Revision = EFI_BLOCK_IO_INTERFACE_REVISION;
|
||||
MmcHostInstance->BlockIo.Reset = MmcReset;
|
||||
MmcHostInstance->BlockIo.ReadBlocks = MmcReadBlocks;
|
||||
MmcHostInstance->BlockIo.WriteBlocks = MmcWriteBlocks;
|
||||
MmcHostInstance->BlockIo.FlushBlocks = MmcFlushBlocks;
|
||||
|
||||
MmcHostInstance->MmcHost = MmcHost;
|
||||
|
||||
// Create DevicePath for the new MMC Host
|
||||
Status = MmcHost->BuildDevicePath(&NewDevicePathNode);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FREE_MEDIA;
|
||||
}
|
||||
|
||||
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
|
||||
if (DevicePath == NULL) {
|
||||
goto FREE_MEDIA;
|
||||
}
|
||||
|
||||
SetDevicePathEndNode (DevicePath);
|
||||
MmcHostInstance->DevicePath = AppendDevicePathNode (DevicePath, NewDevicePathNode);
|
||||
|
||||
// Publish BlockIO protocol interface
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&MmcHostInstance->MmcHandle,
|
||||
&gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo),
|
||||
&gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
goto FREE_DEVICE_PATH;
|
||||
}
|
||||
|
||||
return MmcHostInstance;
|
||||
|
||||
FREE_DEVICE_PATH:
|
||||
FreePool(DevicePath);
|
||||
|
||||
FREE_MEDIA:
|
||||
FreePool(MmcHostInstance->BlockIo.Media);
|
||||
|
||||
FREE_INSTANCE:
|
||||
FreePool(MmcHostInstance);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EFI_STATUS DestroyMmcHostInstance(
|
||||
IN MMC_HOST_INSTANCE* MmcHostInstance
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Uninstall Protocol Interfaces
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces(
|
||||
MmcHostInstance->MmcHandle,
|
||||
&gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo),
|
||||
&gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Free Memory allocated for the instance
|
||||
if (MmcHostInstance->BlockIo.Media) {
|
||||
FreePool(MmcHostInstance->BlockIo.Media);
|
||||
}
|
||||
FreePool (MmcHostInstance);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function checks if the controller implement the Mmc Host and the Device Path Protocols
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmcDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
//EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||
EFI_MMC_HOST_PROTOCOL *MmcHost;
|
||||
EFI_DEV_PATH_PTR Node;
|
||||
|
||||
//
|
||||
// Check RemainingDevicePath validation
|
||||
//
|
||||
if (RemainingDevicePath != NULL) {
|
||||
//
|
||||
// Check if RemainingDevicePath is the End of Device Path Node,
|
||||
// if yes, go on checking other conditions
|
||||
//
|
||||
if (!IsDevicePathEnd (RemainingDevicePath)) {
|
||||
//
|
||||
// If RemainingDevicePath isn't the End of Device Path Node,
|
||||
// check its validation
|
||||
//
|
||||
Node.DevPath = RemainingDevicePath;
|
||||
if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
|
||||
Node.DevPath->SubType != HW_VENDOR_DP ||
|
||||
DevicePathNodeLength(Node.DevPath) != sizeof(VENDOR_DEVICE_PATH)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check if Mmc Host protocol is installed by platform
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
&gEfiMmcHostProtocolGuid,
|
||||
(VOID **) &MmcHost,
|
||||
This->DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (Status == EFI_ALREADY_STARTED) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Close the Mmc Host used to perform the supported test
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiMmcHostProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmcDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MMC_HOST_INSTANCE *MmcHostInstance;
|
||||
EFI_MMC_HOST_PROTOCOL *MmcHost;
|
||||
|
||||
//
|
||||
// Check RemainingDevicePath validation
|
||||
//
|
||||
if (RemainingDevicePath != NULL) {
|
||||
//
|
||||
// Check if RemainingDevicePath is the End of Device Path Node,
|
||||
// if yes, return EFI_SUCCESS
|
||||
//
|
||||
if (IsDevicePathEnd (RemainingDevicePath)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get the Mmc Host protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
&gEfiMmcHostProtocolGuid,
|
||||
(VOID **) &MmcHost,
|
||||
This->DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_ALREADY_STARTED) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
MmcHostInstance = CreateMmcHostInstance(MmcHost);
|
||||
if (MmcHostInstance != NULL) {
|
||||
// Add the handle to the pool
|
||||
InsertMmcHost (MmcHostInstance);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmcDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
LIST_ENTRY *CurrentLink;
|
||||
MMC_HOST_INSTANCE *MmcHostInstance;
|
||||
|
||||
MMC_TRACE("MmcDriverBindingStop()");
|
||||
|
||||
// For each MMC instance
|
||||
CurrentLink = mMmcHostPool.ForwardLink;
|
||||
while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {
|
||||
MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink);
|
||||
ASSERT(MmcHostInstance != NULL);
|
||||
|
||||
// Close gEfiMmcHostProtocolGuid
|
||||
Status = gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiMmcHostProtocolGuid,(VOID **) &MmcHostInstance->MmcHost,
|
||||
This->DriverBindingHandle
|
||||
);
|
||||
|
||||
// Remove MMC Host Instance from the pool
|
||||
RemoveMmcHost (MmcHostInstance);
|
||||
|
||||
// Destroy MmcHostInstance
|
||||
DestroyMmcHostInstance (MmcHostInstance);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = {
|
||||
MmcDriverBindingSupported,
|
||||
MmcDriverBindingStart,
|
||||
MmcDriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmcDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Initializes MMC Host pool
|
||||
//
|
||||
InitializeMmcHostPool ();
|
||||
|
||||
//
|
||||
// Install driver model protocol(s).
|
||||
//
|
||||
Status = EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gMmcDriverBinding,
|
||||
ImageHandle,
|
||||
&gMmcComponentName,
|
||||
&gMmcComponentName2
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Install driver diagnostics
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ImageHandle,
|
||||
&gEfiDriverDiagnostics2ProtocolGuid,&gMmcDriverDiagnostics2,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
Reference in New Issue
Block a user