git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10439 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			527 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			527 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  The driver wrappers BlockMmio protocol instances to produce
 | 
						|
  Block I/O Protocol instances.
 | 
						|
 | 
						|
  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
 | 
						|
  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 "BlockIo.h"
 | 
						|
 | 
						|
EFI_DRIVER_BINDING_PROTOCOL gBlockIoDriverBinding = {
 | 
						|
  BlockIoDriverBindingSupported,
 | 
						|
  BlockIoDriverBindingStart,
 | 
						|
  BlockIoDriverBindingStop,
 | 
						|
  0x11,
 | 
						|
  NULL,
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Reset the block device.
 | 
						|
 | 
						|
  This function implements EFI_BLOCK_IO_PROTOCOL.Reset(). 
 | 
						|
  It resets the block device hardware.
 | 
						|
  ExtendedVerification is ignored in this implementation.
 | 
						|
 | 
						|
  @param  This                   Indicates a pointer to the calling context.
 | 
						|
  @param  ExtendedVerification   Indicates that the driver may perform a more exhaustive
 | 
						|
                                 verification operation of the device during reset.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The block device was reset.
 | 
						|
  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly and could not be reset.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockIoReset (
 | 
						|
  IN EFI_BLOCK_IO_PROTOCOL    *This,
 | 
						|
  IN BOOLEAN                  ExtendedVerification
 | 
						|
  )
 | 
						|
{
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reads the requested number of blocks from the device.
 | 
						|
 | 
						|
  This function implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks(). 
 | 
						|
  It reads the requested number of blocks from the device.
 | 
						|
  All the blocks are read, or an error is returned.
 | 
						|
 | 
						|
  @param  This                   Indicates a pointer to the calling context.
 | 
						|
  @param  ReadData               If TRUE then read data.  If FALSE then write data.
 | 
						|
  @param  MediaId                The media ID that the read request is for.
 | 
						|
  @param  Lba                    The starting logical block address to read from on the device.
 | 
						|
  @param  BufferSize             The size of the Buffer in bytes.
 | 
						|
                                 This must be a multiple of the intrinsic block size of the device.
 | 
						|
  @param  Buffer                 A pointer to the destination buffer for the data. The caller is
 | 
						|
                                 responsible for either having implicit or explicit ownership of the buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The data was read correctly from the device.
 | 
						|
  @retval EFI_DEVICE_ERROR       The device reported an error while attempting to perform the read operation.
 | 
						|
  @retval EFI_NO_MEDIA           There is no media in the device.
 | 
						|
  @retval EFI_MEDIA_CHANGED      The MediaId is not for the current media.
 | 
						|
  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the intrinsic block size of the device.
 | 
						|
  @retval EFI_INVALID_PARAMETER  The read request contains LBAs that are not valid,
 | 
						|
                                 or the buffer is not on proper alignment.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
ReadOrWriteBlocks (
 | 
						|
  IN EFI_BLOCK_IO_PROTOCOL    *This,
 | 
						|
  IN BOOLEAN                  ReadData,
 | 
						|
  IN UINT32                   MediaId,
 | 
						|
  IN EFI_LBA                  Lba,
 | 
						|
  IN UINTN                    BufferSize,
 | 
						|
  OUT VOID                    *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  BLOCK_MMIO_TO_BLOCK_IO_DEVICE *Private;
 | 
						|
  UINTN                         TotalBlock;
 | 
						|
  EFI_BLOCK_IO_MEDIA            *Media;
 | 
						|
  UINT64                        Address;
 | 
						|
  UINTN                         Count;
 | 
						|
  EFI_CPU_IO_PROTOCOL_IO_MEM    CpuAccessFunction;
 | 
						|
 | 
						|
  //
 | 
						|
  // First, validate the parameters
 | 
						|
  //
 | 
						|
  if ((Buffer == NULL) || (BufferSize == 0)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get private data structure
 | 
						|
  //
 | 
						|
  Private = PRIVATE_FROM_BLOCK_IO (This);
 | 
						|
  Media   = Private->BlockMmio->Media;
 | 
						|
 | 
						|
  //
 | 
						|
  // BufferSize must be a multiple of the intrinsic block size of the device.
 | 
						|
  //
 | 
						|
  if (ModU64x32 (BufferSize, Media->BlockSize) != 0) {
 | 
						|
    return EFI_BAD_BUFFER_SIZE;
 | 
						|
  }
 | 
						|
 | 
						|
  TotalBlock = (UINTN) DivU64x32 (BufferSize, Media->BlockSize);
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure the range to read is valid.
 | 
						|
  //
 | 
						|
  if (Lba + TotalBlock - 1 > Media->LastBlock) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!(Media->MediaPresent)) {
 | 
						|
    return EFI_NO_MEDIA;
 | 
						|
  }
 | 
						|
 | 
						|
  if (MediaId != Media->MediaId) {
 | 
						|
    return EFI_MEDIA_CHANGED;
 | 
						|
  }
 | 
						|
 | 
						|
  Address = Private->BlockMmio->BaseAddress;
 | 
						|
  Address += MultU64x32 (Lba, Media->BlockSize);
 | 
						|
 | 
						|
  Count = BufferSize >> 3;
 | 
						|
 | 
						|
  if (ReadData) {
 | 
						|
    CpuAccessFunction = Private->CpuIo->Mem.Read;
 | 
						|
  } else {
 | 
						|
    CpuAccessFunction = Private->CpuIo->Mem.Write;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = (CpuAccessFunction) (
 | 
						|
             Private->CpuIo,
 | 
						|
             EfiCpuIoWidthUint64,
 | 
						|
             Address,
 | 
						|
             Count,
 | 
						|
             Buffer
 | 
						|
             );
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Reads the requested number of blocks from the device.
 | 
						|
 | 
						|
  This function implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks(). 
 | 
						|
  It reads the requested number of blocks from the device.
 | 
						|
  All the blocks are read, or an error is returned.
 | 
						|
 | 
						|
  @param  This                   Indicates a pointer to the calling context.
 | 
						|
  @param  MediaId                The media ID that the read request is for.
 | 
						|
  @param  Lba                    The starting logical block address to read from on the device.
 | 
						|
  @param  BufferSize             The size of the Buffer in bytes.
 | 
						|
                                 This must be a multiple of the intrinsic block size of the device.
 | 
						|
  @param  Buffer                 A pointer to the destination buffer for the data. The caller is
 | 
						|
                                 responsible for either having implicit or explicit ownership of the buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The data was read correctly from the device.
 | 
						|
  @retval EFI_DEVICE_ERROR       The device reported an error while attempting to perform the read operation.
 | 
						|
  @retval EFI_NO_MEDIA           There is no media in the device.
 | 
						|
  @retval EFI_MEDIA_CHANGED      The MediaId is not for the current media.
 | 
						|
  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the intrinsic block size of the device.
 | 
						|
  @retval EFI_INVALID_PARAMETER  The read request contains LBAs that are not valid,
 | 
						|
                                 or the buffer is not on proper alignment.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockIoReadBlocks (
 | 
						|
  IN EFI_BLOCK_IO_PROTOCOL    *This,
 | 
						|
  IN UINT32                   MediaId,
 | 
						|
  IN EFI_LBA                  Lba,
 | 
						|
  IN UINTN                    BufferSize,
 | 
						|
  OUT VOID                    *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  DEBUG ((EFI_D_INFO, "BlockIo (MMIO) ReadBlocks: lba=0x%lx, size=0x%x\n", Lba, BufferSize));
 | 
						|
  return ReadOrWriteBlocks (
 | 
						|
    This,
 | 
						|
    TRUE,
 | 
						|
    MediaId,
 | 
						|
    Lba,
 | 
						|
    BufferSize,
 | 
						|
    Buffer
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Writes a specified number of blocks to the device.
 | 
						|
 | 
						|
  This function implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks(). 
 | 
						|
  It writes a specified number of blocks to the device.
 | 
						|
  All blocks are written, or an error is returned.
 | 
						|
 | 
						|
  @param  This                   Indicates a pointer to the calling context.
 | 
						|
  @param  MediaId                The media ID that the write request is for.
 | 
						|
  @param  Lba                    The starting logical block address to be written.
 | 
						|
  @param  BufferSize             The size of the Buffer in bytes.
 | 
						|
                                 This must be a multiple of the intrinsic block size of the device.
 | 
						|
  @param  Buffer                 Pointer to the source buffer for the data.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The data were written correctly to the device.
 | 
						|
  @retval EFI_WRITE_PROTECTED    The device cannot be written to.
 | 
						|
  @retval EFI_NO_MEDIA           There is no media in the device.
 | 
						|
  @retval EFI_MEDIA_CHANGED      The MediaId is not for the current media.
 | 
						|
  @retval EFI_DEVICE_ERROR       The device reported an error while attempting to perform the write operation.
 | 
						|
  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the intrinsic
 | 
						|
                                 block size of the device.
 | 
						|
  @retval EFI_INVALID_PARAMETER  The write request contains LBAs that are not valid,
 | 
						|
                                 or the buffer is not on proper alignment.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockIoWriteBlocks (
 | 
						|
  IN EFI_BLOCK_IO_PROTOCOL    *This,
 | 
						|
  IN UINT32                   MediaId,
 | 
						|
  IN EFI_LBA                  Lba,
 | 
						|
  IN UINTN                    BufferSize,
 | 
						|
  IN VOID                     *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  DEBUG ((EFI_D_INFO, "BlockIo (MMIO) WriteBlocks: lba=0x%lx, size=0x%x\n", Lba, BufferSize));
 | 
						|
  return ReadOrWriteBlocks (
 | 
						|
    This,
 | 
						|
    FALSE,
 | 
						|
    MediaId,
 | 
						|
    Lba,
 | 
						|
    BufferSize,
 | 
						|
    Buffer
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Flushes all modified data to a physical block device.
 | 
						|
 | 
						|
  @param  This                   Indicates a pointer to the calling context.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            All outstanding data were written correctly to the device.
 | 
						|
  @retval EFI_DEVICE_ERROR       The device reported an error while attempting to write data.
 | 
						|
  @retval EFI_NO_MEDIA           There is no media in the device.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockIoFlushBlocks (
 | 
						|
  IN EFI_BLOCK_IO_PROTOCOL  *This
 | 
						|
  )
 | 
						|
{
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize data for device that does not support multiple LUNSs.
 | 
						|
 | 
						|
  @param  This            The Driver Binding Protocol instance.
 | 
						|
  @param  Controller      The device to initialize.
 | 
						|
  @param  BlockMmio       Pointer to USB_MASS_TRANSPORT.
 | 
						|
  @param  Context         Parameter for USB_MASS_DEVICE.Context.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS     Initialization succeeds.
 | 
						|
  @retval Other           Initialization fails.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
BlockIoInit (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL   *This,
 | 
						|
  IN EFI_HANDLE                    Controller
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                     Status;
 | 
						|
  BLOCK_MMIO_TO_BLOCK_IO_DEVICE  *Private;
 | 
						|
  BLOCK_MMIO_PROTOCOL            *BlockMmio;
 | 
						|
 | 
						|
  Private = (BLOCK_MMIO_TO_BLOCK_IO_DEVICE*) AllocateZeroPool (sizeof (Private));
 | 
						|
  ASSERT (Private != NULL);
 | 
						|
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiCpuIo2ProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID **) &(Private->CpuIo)
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gBlockMmioProtocolGuid,
 | 
						|
                  (VOID **) &BlockMmio,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((EFI_D_ERROR, "BlockIoInit: OpenBlockMmioProtocol By Driver (%r)\n", Status));
 | 
						|
    goto ON_ERROR;
 | 
						|
  }
 | 
						|
  DEBUG ((EFI_D_INFO, "BlockMmio: 0x%x\n", BlockMmio));
 | 
						|
  DEBUG ((EFI_D_INFO, "BlockMmio->Media->LastBlock: 0x%lx\n", BlockMmio->Media->LastBlock));
 | 
						|
  
 | 
						|
  Private->Signature            = BLOCK_MMIO_TO_BLOCK_IO_SIGNATURE;
 | 
						|
  Private->Controller           = Controller;
 | 
						|
  Private->BlockMmio            = BlockMmio;
 | 
						|
  Private->BlockIo.Media        = BlockMmio->Media;
 | 
						|
  Private->BlockIo.Reset        = BlockIoReset;
 | 
						|
  Private->BlockIo.ReadBlocks   = BlockIoReadBlocks;
 | 
						|
  Private->BlockIo.WriteBlocks  = BlockIoWriteBlocks;
 | 
						|
  Private->BlockIo.FlushBlocks  = BlockIoFlushBlocks;
 | 
						|
 | 
						|
  DEBUG ((EFI_D_INFO, "Private->BlockIo.Media->LastBlock: 0x%lx\n", Private->BlockIo.Media->LastBlock));
 | 
						|
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &Controller,
 | 
						|
                  &gEfiBlockIoProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &Private->BlockIo
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto ON_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
 | 
						|
ON_ERROR:
 | 
						|
  if (Private != NULL) {
 | 
						|
    FreePool (Private);
 | 
						|
  }
 | 
						|
  if (BlockMmio != NULL) {
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Controller,
 | 
						|
           &gBlockMmioProtocolGuid,
 | 
						|
           This->DriverBindingHandle,
 | 
						|
           Controller
 | 
						|
           );
 | 
						|
  }
 | 
						|
  return Status;  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Check whether the controller is a supported USB mass storage.
 | 
						|
 | 
						|
  @param  This                   The USB mass storage driver binding protocol.
 | 
						|
  @param  Controller             The controller handle to check.
 | 
						|
  @param  RemainingDevicePath    The remaining device path.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The driver supports this controller.
 | 
						|
  @retval other                  This device isn't supported.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockIoDriverBindingSupported (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  BLOCK_MMIO_PROTOCOL           *BlockMmio;
 | 
						|
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gBlockMmioProtocolGuid,
 | 
						|
                  (VOID **) &BlockMmio,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->CloseProtocol (
 | 
						|
         Controller,
 | 
						|
         &gBlockMmioProtocolGuid,
 | 
						|
         This->DriverBindingHandle,
 | 
						|
         Controller
 | 
						|
         );
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Starts the USB mass storage device with this driver.
 | 
						|
 | 
						|
  This function consumes USB I/O Portocol, intializes USB mass storage device,
 | 
						|
  installs Block I/O Protocol, and submits Asynchronous Interrupt
 | 
						|
  Transfer to manage the USB mass storage device.
 | 
						|
 | 
						|
  @param  This                  The USB mass storage driver binding protocol.
 | 
						|
  @param  Controller            The USB mass storage device to start on
 | 
						|
  @param  RemainingDevicePath   The remaining device path.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           This driver supports this device.
 | 
						|
  @retval EFI_UNSUPPORTED       This driver does not support this device.
 | 
						|
  @retval EFI_DEVICE_ERROR      This driver cannot be started due to device Error.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  Can't allocate memory resources.
 | 
						|
  @retval EFI_ALREADY_STARTED   This driver has been started.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockIoDriverBindingStart (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  
 | 
						|
  Status = BlockIoInit (This, Controller);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((EFI_D_ERROR, "BlockIoDriverBindingStart: BlockIoInit (%r)\n", Status));
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG ((EFI_D_INIT, "BlockIoDriverBindingStart: Successfully started\n"));
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Stop controlling the device.
 | 
						|
 | 
						|
  @param  This                   The USB mass storage driver binding
 | 
						|
  @param  Controller             The device controller controlled by the driver.
 | 
						|
  @param  NumberOfChildren       The number of children of this device
 | 
						|
  @param  ChildHandleBuffer      The buffer of children handle.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The driver stopped from controlling the device.
 | 
						|
  @retval EFI_DEVICE_ERROR       The device could not be stopped due to a device error.
 | 
						|
  @retval EFI_UNSUPPORTED        Block I/O Protocol is not installed on Controller.
 | 
						|
  @retval Others                 Failed to stop the driver
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockIoDriverBindingStop (
 | 
						|
  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
 | 
						|
  IN  EFI_HANDLE                  Controller,
 | 
						|
  IN  UINTN                       NumberOfChildren,
 | 
						|
  IN  EFI_HANDLE                  *ChildHandleBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  BLOCK_MMIO_TO_BLOCK_IO_DEVICE *Private;
 | 
						|
 | 
						|
  Private = PRIVATE_FROM_BLOCK_IO (This);
 | 
						|
 | 
						|
  //
 | 
						|
  // Uninstall Block I/O protocol from the device handle,
 | 
						|
  // then call the transport protocol to stop itself.
 | 
						|
  //
 | 
						|
  Status = gBS->UninstallProtocolInterface (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiBlockIoProtocolGuid,
 | 
						|
                  &Private->BlockIo
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->CloseProtocol (
 | 
						|
        Controller,
 | 
						|
        &gBlockMmioProtocolGuid,
 | 
						|
        This->DriverBindingHandle,
 | 
						|
        Controller
 | 
						|
        );
 | 
						|
 | 
						|
  FreePool (Private);
 | 
						|
  
 | 
						|
  DEBUG ((EFI_D_INFO, "Successfully stopped BlockIo on BlockMmio\n"));
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Entrypoint of Block MMIO to Block IO Driver.
 | 
						|
 | 
						|
  This function is the entrypoint of USB Mass Storage Driver. It installs Driver Binding
 | 
						|
  Protocol together with Component Name Protocols.
 | 
						|
 | 
						|
  @param  ImageHandle       The firmware allocated handle for the EFI image.
 | 
						|
  @param  SystemTable       A pointer to the EFI System Table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The entry point is executed successfully.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
BlockMmioToBlockIoEntryPoint (
 | 
						|
  IN EFI_HANDLE               ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE         *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Install driver binding protocol
 | 
						|
  //
 | 
						|
  Status = EfiLibInstallDriverBindingComponentName2 (
 | 
						|
             ImageHandle,
 | 
						|
             SystemTable,
 | 
						|
             &gBlockIoDriverBinding,
 | 
						|
             ImageHandle,
 | 
						|
             &gBlockMmioToBlockIoComponentName,
 | 
						|
             &gBlockMmioToBlockIoComponentName2
 | 
						|
             );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |