--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR> \r
+This software and associated documentation (if any) is furnished\r
+under a license and may only be used or copied in accordance\r
+with the terms of the license. Except as permitted by such\r
+license, no part of this software or documentation may be\r
+reproduced, stored in a retrieval system, or transmitted in any\r
+form or by any means without the express written consent of\r
+Intel Corporation.\r
+\r
+Module Name:\r
+\r
+ IsaFloppy.c\r
+\r
+Abstract:\r
+\r
+ ISA Floppy Driver\r
+ 1. Support two types diskette drive \r
+ 1.44M drive and 2.88M drive (and now only support 1.44M)\r
+ 2. Support two diskette drives\r
+ 3. Use DMA channel 2 to transfer data\r
+ 4. Do not use interrupt\r
+ 5. Support diskette change line signal and write protect\r
+ \r
+ conforming to EFI driver model\r
+\r
+Revision History:\r
+\r
+--*/\r
+\r
+#include "IsaFloppy.h"\r
+\r
+LIST_ENTRY gControllerHead = INITIALIZE_LIST_HEAD_VARIABLE(gControllerHead);\r
+\r
+//\r
+// ISA Floppy Driver Binding Protocol\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gFdcControllerDriver = {\r
+ FdcControllerDriverSupported,\r
+ FdcControllerDriverStart,\r
+ FdcControllerDriverStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FdcControllerDriverSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ ControllerDriver Protocol Method\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// GC_TODO: This - add argument and description to function comment\r
+// GC_TODO: Controller - add argument and description to function comment\r
+// GC_TODO: RemainingDevicePath - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ISA_IO_PROTOCOL *IsaIo;\r
+\r
+ //\r
+ // Open the ISA I/O Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ (VOID **) &IsaIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Close the ISA I/O Protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FdcControllerDriverStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+// GC_TODO: This - add argument and description to function comment\r
+// GC_TODO: Controller - add argument and description to function comment\r
+// GC_TODO: RemainingDevicePath - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ FDC_BLK_IO_DEV *FdcDev;\r
+ EFI_ISA_IO_PROTOCOL *IsaIo;\r
+ UINTN Index;\r
+ LIST_ENTRY *List;\r
+ BOOLEAN Found;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+\r
+ FdcDev = NULL;\r
+ IsaIo = NULL;\r
+\r
+ //\r
+ // Open the device path protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Report enable progress code\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE,\r
+ ParentDevicePath\r
+ );\r
+\r
+ //\r
+ // Open the ISA I/O Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ (VOID **) &IsaIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // Allocate the Floppy Disk Controller's Device structure\r
+ //\r
+ FdcDev = AllocateZeroPool (sizeof (FDC_BLK_IO_DEV));\r
+ if (FdcDev == NULL) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // Initialize the Floppy Disk Controller's Device structure\r
+ //\r
+ FdcDev->Signature = FDC_BLK_IO_DEV_SIGNATURE;\r
+ FdcDev->Handle = Controller;\r
+ FdcDev->IsaIo = IsaIo;\r
+ FdcDev->Disk = (EFI_FDC_DISK) IsaIo->ResourceList->Device.UID;\r
+ FdcDev->Cache = NULL;\r
+ FdcDev->Event = NULL;\r
+ FdcDev->ControllerState = NULL;\r
+ FdcDev->DevicePath = ParentDevicePath;\r
+\r
+ ADD_FLOPPY_NAME (FdcDev);\r
+ \r
+ //\r
+ // Look up the base address of the Floppy Disk Controller\r
+ //\r
+ for (Index = 0; FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) {\r
+ if (FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) {\r
+ FdcDev->BaseAddress = (UINT16) FdcDev->IsaIo->ResourceList->ResourceItem[Index].StartRange;\r
+ }\r
+ }\r
+ //\r
+ // Maintain the list of controller list\r
+ //\r
+ Found = FALSE;\r
+ List = gControllerHead.ForwardLink;\r
+ while (List != &gControllerHead) {\r
+ FdcDev->ControllerState = FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List);\r
+ if (FdcDev->BaseAddress == FdcDev->ControllerState->BaseAddress) {\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+\r
+ List = List->ForwardLink;\r
+ }\r
+\r
+ if (!Found) {\r
+ //\r
+ // The Controller is new\r
+ //\r
+ FdcDev->ControllerState = AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT));\r
+ if (FdcDev->ControllerState == NULL) {\r
+ goto Done;\r
+ }\r
+\r
+ FdcDev->ControllerState->Signature = FLOPPY_CONTROLLER_CONTEXT_SIGNATURE;\r
+ FdcDev->ControllerState->FddResetPerformed = FALSE;\r
+ FdcDev->ControllerState->NeedRecalibrate = FALSE;\r
+ FdcDev->ControllerState->BaseAddress = FdcDev->BaseAddress;\r
+ FdcDev->ControllerState->NumberOfDrive = 0;\r
+\r
+ InsertTailList (&gControllerHead, &FdcDev->ControllerState->Link);\r
+ }\r
+ //\r
+ // Create a timer event for each Floppd Disk Controller.\r
+ // This timer event is used to control the motor on and off\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ FddTimerProc,\r
+ FdcDev,\r
+ &FdcDev->Event\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // Reset the Floppy Disk Controller\r
+ //\r
+ if (!FdcDev->ControllerState->FddResetPerformed) {\r
+ FdcDev->ControllerState->FddResetPerformed = TRUE;\r
+ FdcDev->ControllerState->FddResetStatus = FddReset (FdcDev);\r
+ }\r
+\r
+ if (EFI_ERROR (FdcDev->ControllerState->FddResetStatus)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT,\r
+ ParentDevicePath\r
+ );\r
+\r
+ //\r
+ // Discover the Floppy Drive\r
+ //\r
+ Status = DiscoverFddDevice (FdcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Install protocol interfaces for the serial device.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &FdcDev->BlkIo,\r
+ NULL\r
+ );\r
+\r
+ FdcDev->ControllerState->NumberOfDrive++;\r
+\r
+Done:\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR,\r
+ ParentDevicePath\r
+ );\r
+\r
+ //\r
+ // Close the device path protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ //\r
+ // Close the ISA I/O Protocol\r
+ //\r
+ if (IsaIo != NULL) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
+ //\r
+ // If a Floppy Disk Controller Device structure was allocated, then free it\r
+ //\r
+ if (FdcDev != NULL) {\r
+ if (FdcDev->Event != NULL) {\r
+ //\r
+ // Close the event for turning the motor off\r
+ //\r
+ gBS->CloseEvent (FdcDev->Event);\r
+ }\r
+\r
+ FreeUnicodeStringTable (FdcDev->ControllerNameTable);\r
+ gBS->FreePool (FdcDev);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FdcControllerDriverStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+\r
+ Arguments:\r
+\r
+ Returns:\r
+\r
+--*/\r
+// GC_TODO: This - add argument and description to function comment\r
+// GC_TODO: Controller - add argument and description to function comment\r
+// GC_TODO: NumberOfChildren - add argument and description to function comment\r
+// GC_TODO: ChildHandleBuffer - add argument and description to function comment\r
+// GC_TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
+ FDC_BLK_IO_DEV *FdcDev;\r
+\r
+ //\r
+ // Get the Block I/O Protocol on Controller\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiBlockIoProtocolGuid,\r
+ (VOID **) &BlkIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Get the Floppy Disk Controller's Device structure\r
+ //\r
+ FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo);\r
+\r
+ //\r
+ // Report disable progress code\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE,\r
+ FdcDev->DevicePath\r
+ );\r
+\r
+ //\r
+ // Turn the motor off on the Floppy Disk Controller\r
+ //\r
+ FddTimerProc (FdcDev->Event, FdcDev);\r
+\r
+ //\r
+ // Uninstall the Block I/O Protocol\r
+ //\r
+ Status = gBS->UninstallProtocolInterface (\r
+ Controller,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &FdcDev->BlkIo\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Close the device path protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ //\r
+ // Close the ISA I/O Protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIsaIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ //\r
+ // Free the controller list if needed\r
+ //\r
+ FdcDev->ControllerState->NumberOfDrive--;\r
+\r
+ //\r
+ // Close the event for turning the motor off\r
+ //\r
+ gBS->CloseEvent (FdcDev->Event);\r
+\r
+ //\r
+ // Free the cache if one was allocated\r
+ //\r
+ FdcFreeCache (FdcDev);\r
+\r
+ //\r
+ // Free the Floppy Disk Controller's Device structure\r
+ //\r
+ FreeUnicodeStringTable (FdcDev->ControllerNameTable);\r
+ gBS->FreePool (FdcDev);\r
+\r
+ return EFI_SUCCESS;\r
+}\r