mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-02 20:44:39 +01:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10414 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			516 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			516 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  ISA Floppy Disk UEFI Driver conforming to the UEFI driver model
 | 
						|
 | 
						|
  1. Support two types diskette drive  
 | 
						|
     1.44M drive and 2.88M drive (and now only support 1.44M)
 | 
						|
  2. Support two diskette drives per floppy disk controller
 | 
						|
  3. Use DMA channel 2 to transfer data
 | 
						|
  4. Do not use interrupt
 | 
						|
  5. Support diskette change line signal and write protect
 | 
						|
  
 | 
						|
Copyright (c) 2006 - 2009, 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 "IsaFloppy.h"
 | 
						|
 | 
						|
LIST_ENTRY  mControllerHead = INITIALIZE_LIST_HEAD_VARIABLE (mControllerHead);
 | 
						|
 | 
						|
//
 | 
						|
// ISA Floppy Driver Binding Protocol
 | 
						|
//
 | 
						|
EFI_DRIVER_BINDING_PROTOCOL gFdcControllerDriver = {
 | 
						|
  FdcControllerDriverSupported,
 | 
						|
  FdcControllerDriverStart,
 | 
						|
  FdcControllerDriverStop,
 | 
						|
  0xa,
 | 
						|
  NULL,
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  The main Entry Point for this driver.
 | 
						|
 | 
						|
  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  
 | 
						|
  @param[in] SystemTable  A pointer to the EFI System Table.
 | 
						|
  
 | 
						|
  @retval EFI_SUCCESS     The entry point is executed successfully.
 | 
						|
  @retval other           Some error occurs when executing this entry point.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InitializeIsaFloppy(
 | 
						|
  IN EFI_HANDLE           ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE     *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Install driver model protocol(s).
 | 
						|
  //
 | 
						|
  Status = EfiLibInstallDriverBindingComponentName2 (
 | 
						|
             ImageHandle,
 | 
						|
             SystemTable,
 | 
						|
             &gFdcControllerDriver,
 | 
						|
             ImageHandle,
 | 
						|
             &gIsaFloppyComponentName,
 | 
						|
             &gIsaFloppyComponentName2
 | 
						|
             );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Test if the controller is a floppy disk drive device
 | 
						|
  
 | 
						|
  @param[in] This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.  
 | 
						|
  @param[in] Controller           The handle of the controller to test.
 | 
						|
  @param[in] RemainingDevicePath  A pointer to the remaining portion of a device path.
 | 
						|
  
 | 
						|
  @retval EFI_SUCCESS             The device is supported by this driver.
 | 
						|
  @retval EFI_ALREADY_STARTED     The device is already being managed by this driver.
 | 
						|
  @retval EFI_ACCESS_DENIED       The device is already being managed by a different driver 
 | 
						|
                                  or an application that requires exclusive access.
 | 
						|
  @retval EFI_UNSUPPORTED         The device is is not supported by this driver.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FdcControllerDriverSupported (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                Status;
 | 
						|
  EFI_ISA_IO_PROTOCOL       *IsaIo;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
 | 
						|
 | 
						|
  //
 | 
						|
  // Ignore the parameter RemainingDevicePath because this is a device driver.
 | 
						|
  //
 | 
						|
 | 
						|
  //
 | 
						|
  // Open the device path protocol
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiDevicePathProtocolGuid,
 | 
						|
                  (VOID **) &ParentDevicePath,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->CloseProtocol (
 | 
						|
         Controller,
 | 
						|
         &gEfiDevicePathProtocolGuid,
 | 
						|
         This->DriverBindingHandle,
 | 
						|
         Controller
 | 
						|
         );
 | 
						|
 | 
						|
  //
 | 
						|
  // Open the ISA I/O Protocol
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiIsaIoProtocolGuid,
 | 
						|
                  (VOID **) &IsaIo,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Use the ISA I/O Protocol to see if Controller is a floppy disk drive device
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Close the ISA I/O Protocol
 | 
						|
  //
 | 
						|
  gBS->CloseProtocol (
 | 
						|
         Controller,
 | 
						|
         &gEfiIsaIoProtocolGuid,
 | 
						|
         This->DriverBindingHandle,
 | 
						|
         Controller
 | 
						|
         );
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Start this driver on Controller.
 | 
						|
 | 
						|
  @param[in] This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
 | 
						|
  @param[in] ControllerHandle      The handle of the controller to start. This handle 
 | 
						|
                                   must support a protocol interface that supplies 
 | 
						|
                                   an I/O abstraction to the driver.
 | 
						|
  @param[in] RemainingDevicePath   A pointer to the remaining portion of a device path. 
 | 
						|
                                   This parameter is ignored by device drivers, and is optional for bus drivers.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS              The device was started.
 | 
						|
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.
 | 
						|
                                   Currently not implemented.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
 | 
						|
  @retval Others                   The driver failded to start the device.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FdcControllerDriverStart (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                Status;
 | 
						|
  FDC_BLK_IO_DEV            *FdcDev;
 | 
						|
  EFI_ISA_IO_PROTOCOL       *IsaIo;
 | 
						|
  UINTN                     Index;
 | 
						|
  LIST_ENTRY                *List;
 | 
						|
  BOOLEAN                   Found;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
 | 
						|
 | 
						|
  FdcDev  = NULL;
 | 
						|
  IsaIo   = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Open the device path protocol
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiDevicePathProtocolGuid,
 | 
						|
                  (VOID **) &ParentDevicePath,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Report enable progress code
 | 
						|
  //
 | 
						|
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | 
						|
    EFI_PROGRESS_CODE,
 | 
						|
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE,
 | 
						|
    ParentDevicePath
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Open the ISA I/O Protocol
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiIsaIoProtocolGuid,
 | 
						|
                  (VOID **) &IsaIo,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Allocate the floppy device's Device structure
 | 
						|
  //
 | 
						|
  FdcDev = AllocateZeroPool (sizeof (FDC_BLK_IO_DEV));
 | 
						|
  if (FdcDev == NULL) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Initialize the floppy device's device structure
 | 
						|
  //
 | 
						|
  FdcDev->Signature       = FDC_BLK_IO_DEV_SIGNATURE;
 | 
						|
  FdcDev->Handle          = Controller;
 | 
						|
  FdcDev->IsaIo           = IsaIo;
 | 
						|
  FdcDev->Disk            = (EFI_FDC_DISK) IsaIo->ResourceList->Device.UID;
 | 
						|
  FdcDev->Cache           = NULL;
 | 
						|
  FdcDev->Event           = NULL;
 | 
						|
  FdcDev->ControllerState = NULL;
 | 
						|
  FdcDev->DevicePath      = ParentDevicePath;
 | 
						|
 | 
						|
  FdcDev->ControllerNameTable = NULL;
 | 
						|
  AddName (FdcDev);
 | 
						|
  
 | 
						|
  //
 | 
						|
  // Look up the base address of the Floppy Disk Controller which controls this floppy device
 | 
						|
  //
 | 
						|
  for (Index = 0; FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) {
 | 
						|
    if (FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) {
 | 
						|
      FdcDev->BaseAddress = (UINT16) FdcDev->IsaIo->ResourceList->ResourceItem[Index].StartRange;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Maintain the list of floppy disk controllers
 | 
						|
  //
 | 
						|
  Found = FALSE;
 | 
						|
  List  = mControllerHead.ForwardLink;
 | 
						|
  while (List != &mControllerHead) {
 | 
						|
    FdcDev->ControllerState = FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List);
 | 
						|
    if (FdcDev->BaseAddress == FdcDev->ControllerState->BaseAddress) {
 | 
						|
      Found = TRUE;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    List = List->ForwardLink;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!Found) {
 | 
						|
    //
 | 
						|
    // A new floppy disk controller controlling this floppy disk drive is found
 | 
						|
    //
 | 
						|
    FdcDev->ControllerState = AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT));
 | 
						|
    if (FdcDev->ControllerState == NULL) {
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    FdcDev->ControllerState->Signature          = FLOPPY_CONTROLLER_CONTEXT_SIGNATURE;
 | 
						|
    FdcDev->ControllerState->FddResetPerformed  = FALSE;
 | 
						|
    FdcDev->ControllerState->NeedRecalibrate    = FALSE;
 | 
						|
    FdcDev->ControllerState->BaseAddress        = FdcDev->BaseAddress;
 | 
						|
    FdcDev->ControllerState->NumberOfDrive      = 0;
 | 
						|
 | 
						|
    InsertTailList (&mControllerHead, &FdcDev->ControllerState->Link);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Create a timer event for each floppy disk drive device.
 | 
						|
  // This timer event is used to control the motor on and off
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEvent (
 | 
						|
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
 | 
						|
                  TPL_NOTIFY,
 | 
						|
                  FddTimerProc,
 | 
						|
                  FdcDev,
 | 
						|
                  &FdcDev->Event
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Reset the Floppy Disk Controller
 | 
						|
  //
 | 
						|
  if (!FdcDev->ControllerState->FddResetPerformed) {
 | 
						|
    FdcDev->ControllerState->FddResetPerformed  = TRUE;
 | 
						|
    FdcDev->ControllerState->FddResetStatus     = FddReset (FdcDev);
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (FdcDev->ControllerState->FddResetStatus)) {
 | 
						|
    Status = EFI_DEVICE_ERROR;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | 
						|
    EFI_PROGRESS_CODE,
 | 
						|
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT,
 | 
						|
    ParentDevicePath
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Discover the Floppy Drive
 | 
						|
  //
 | 
						|
  Status = DiscoverFddDevice (FdcDev);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    Status = EFI_DEVICE_ERROR;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Install protocol interfaces for the serial device.
 | 
						|
  //
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  &Controller,
 | 
						|
                  &gEfiBlockIoProtocolGuid,
 | 
						|
                  &FdcDev->BlkIo,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    FdcDev->ControllerState->NumberOfDrive++;
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
 | 
						|
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | 
						|
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
 | 
						|
      EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR,
 | 
						|
      ParentDevicePath
 | 
						|
      );
 | 
						|
 | 
						|
    //
 | 
						|
    // If a floppy drive device structure was allocated, then free it
 | 
						|
    //
 | 
						|
    if (FdcDev != NULL) {
 | 
						|
      if (FdcDev->Event != NULL) {
 | 
						|
        //
 | 
						|
        // Close the event for turning the motor off
 | 
						|
        //
 | 
						|
        gBS->CloseEvent (FdcDev->Event);
 | 
						|
      }
 | 
						|
 | 
						|
      FreeUnicodeStringTable (FdcDev->ControllerNameTable);
 | 
						|
      FreePool (FdcDev);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Close the ISA I/O Protocol
 | 
						|
    //
 | 
						|
    if (IsaIo != NULL) {
 | 
						|
      gBS->CloseProtocol (
 | 
						|
             Controller,
 | 
						|
             &gEfiIsaIoProtocolGuid,
 | 
						|
             This->DriverBindingHandle,
 | 
						|
             Controller
 | 
						|
             );
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Close the device path protocol
 | 
						|
    //
 | 
						|
    gBS->CloseProtocol (
 | 
						|
           Controller,
 | 
						|
           &gEfiDevicePathProtocolGuid,
 | 
						|
           This->DriverBindingHandle,
 | 
						|
           Controller
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Stop this driver on ControllerHandle.
 | 
						|
 | 
						|
  @param[in] This               A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
 | 
						|
  @param[in] ControllerHandle   A handle to the device being stopped. The handle must 
 | 
						|
                                support a bus specific I/O protocol for the driver 
 | 
						|
                                to use to stop the device.
 | 
						|
  @param[in] NumberOfChildren   The number of child device handles in ChildHandleBuffer.
 | 
						|
  @param[in] ChildHandleBuffer  An array of child handles to be freed. May be NULL 
 | 
						|
                                if NumberOfChildren is 0.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The device was stopped.
 | 
						|
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
FdcControllerDriverStop (
 | 
						|
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN  EFI_HANDLE                   Controller,
 | 
						|
  IN  UINTN                        NumberOfChildren,
 | 
						|
  IN  EFI_HANDLE                   *ChildHandleBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  EFI_BLOCK_IO_PROTOCOL *BlkIo;
 | 
						|
  FDC_BLK_IO_DEV        *FdcDev;
 | 
						|
 | 
						|
  //
 | 
						|
  // Ignore NumberOfChildren since this is a device driver
 | 
						|
  //
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the Block I/O Protocol on Controller
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiBlockIoProtocolGuid,
 | 
						|
                  (VOID **) &BlkIo,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Get the floppy drive device's Device structure
 | 
						|
  //
 | 
						|
  FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo);
 | 
						|
 | 
						|
  //
 | 
						|
  // Report disable progress code
 | 
						|
  //
 | 
						|
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
 | 
						|
    EFI_PROGRESS_CODE,
 | 
						|
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE,
 | 
						|
    FdcDev->DevicePath
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Uninstall the Block I/O Protocol
 | 
						|
  //
 | 
						|
  Status = gBS->UninstallProtocolInterface (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiBlockIoProtocolGuid,
 | 
						|
                  &FdcDev->BlkIo
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Close the event for turning the motor off
 | 
						|
  //
 | 
						|
  gBS->CloseEvent (FdcDev->Event);
 | 
						|
 | 
						|
  //
 | 
						|
  // Turn the motor off on the floppy drive device
 | 
						|
  //
 | 
						|
  FddTimerProc (FdcDev->Event, FdcDev);
 | 
						|
 | 
						|
  //
 | 
						|
  // Close the device path protocol
 | 
						|
  //
 | 
						|
  gBS->CloseProtocol (
 | 
						|
         Controller,
 | 
						|
         &gEfiDevicePathProtocolGuid,
 | 
						|
         This->DriverBindingHandle,
 | 
						|
         Controller
 | 
						|
         );
 | 
						|
 | 
						|
  //
 | 
						|
  // Close the ISA I/O Protocol
 | 
						|
  //
 | 
						|
  gBS->CloseProtocol (
 | 
						|
         Controller,
 | 
						|
         &gEfiIsaIoProtocolGuid,
 | 
						|
         This->DriverBindingHandle,
 | 
						|
         Controller
 | 
						|
         );
 | 
						|
 | 
						|
  //
 | 
						|
  // Free the controller list if needed
 | 
						|
  //
 | 
						|
  FdcDev->ControllerState->NumberOfDrive--;
 | 
						|
 | 
						|
  //
 | 
						|
  // Free the cache if one was allocated
 | 
						|
  //
 | 
						|
  FdcFreeCache (FdcDev);
 | 
						|
 | 
						|
  //
 | 
						|
  // Free the floppy drive device's device structure
 | 
						|
  //
 | 
						|
  FreeUnicodeStringTable (FdcDev->ControllerNameTable);
 | 
						|
  FreePool (FdcDev);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 |