3 1. Support two types diskette drive
4 1.44M drive and 2.88M drive (and now only support 1.44M)
5 2. Support two diskette drives
6 3. Use DMA channel 2 to transfer data
7 4. Do not use interrupt
8 5. Support diskette change line signal and write protect
10 conforming to EFI driver model
12 Copyright (c) 2006 - 2007, Intel Corporation.<BR>
13 All rights reserved. This program and the accompanying materials
14 are licensed and made available under the terms and conditions of the BSD License
15 which accompanies this distribution. The full text of the license may be found at
16 http://opensource.org/licenses/bsd-license.php
18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 #include "IsaFloppy.h"
25 LIST_ENTRY gControllerHead
= INITIALIZE_LIST_HEAD_VARIABLE(gControllerHead
);
28 // ISA Floppy Driver Binding Protocol
30 EFI_DRIVER_BINDING_PROTOCOL gFdcControllerDriver
= {
31 FdcControllerDriverSupported
,
32 FdcControllerDriverStart
,
33 FdcControllerDriverStop
,
41 The user Entry Point for module IsaFloppy. The user code starts with this function.
43 @param[in] ImageHandle The firmware allocated handle for the EFI image.
44 @param[in] SystemTable A pointer to the EFI System Table.
46 @retval EFI_SUCCESS The entry point is executed successfully.
47 @retval other Some error occurs when executing this entry point.
53 IN EFI_HANDLE ImageHandle
,
54 IN EFI_SYSTEM_TABLE
*SystemTable
60 // Install driver model protocol(s).
62 Status
= EfiLibInstallDriverBindingComponentName2 (
65 &gFdcControllerDriver
,
67 &gIsaFloppyComponentName
,
68 &gIsaFloppyComponentName2
70 ASSERT_EFI_ERROR (Status
);
77 Test controller is a Floppy Disk Controller
79 @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
80 @param Controller driver's controller
81 @param RemainingDevicePath children device path
83 @retval EFI_UNSUPPORTED controller is not floppy disk
84 @retval EFI_SUCCESS controller is floppy disk
88 FdcControllerDriverSupported (
89 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
90 IN EFI_HANDLE Controller
,
91 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
95 EFI_ISA_IO_PROTOCOL
*IsaIo
;
98 // Open the ISA I/O Protocol
100 Status
= gBS
->OpenProtocol (
102 &gEfiIsaIoProtocolGuid
,
104 This
->DriverBindingHandle
,
106 EFI_OPEN_PROTOCOL_BY_DRIVER
108 if (EFI_ERROR (Status
)) {
112 // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller
114 Status
= EFI_SUCCESS
;
115 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x604)) {
116 Status
= EFI_UNSUPPORTED
;
119 // Close the ISA I/O Protocol
123 &gEfiIsaIoProtocolGuid
,
124 This
->DriverBindingHandle
,
132 Create floppy control instance on controller.
134 @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
135 @param Controller driver controller handle
136 @param RemainingDevicePath Children's device path
138 @retval whether success to create floppy control instance.
142 FdcControllerDriverStart (
143 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
144 IN EFI_HANDLE Controller
,
145 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
149 FDC_BLK_IO_DEV
*FdcDev
;
150 EFI_ISA_IO_PROTOCOL
*IsaIo
;
154 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
160 // Open the device path protocol
162 Status
= gBS
->OpenProtocol (
164 &gEfiDevicePathProtocolGuid
,
165 (VOID
**) &ParentDevicePath
,
166 This
->DriverBindingHandle
,
168 EFI_OPEN_PROTOCOL_BY_DRIVER
170 if (EFI_ERROR (Status
)) {
174 // Report enable progress code
176 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
178 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
,
183 // Open the ISA I/O Protocol
185 Status
= gBS
->OpenProtocol (
187 &gEfiIsaIoProtocolGuid
,
189 This
->DriverBindingHandle
,
191 EFI_OPEN_PROTOCOL_BY_DRIVER
193 if (EFI_ERROR (Status
)) {
197 // Allocate the Floppy Disk Controller's Device structure
199 FdcDev
= AllocateZeroPool (sizeof (FDC_BLK_IO_DEV
));
200 if (FdcDev
== NULL
) {
204 // Initialize the Floppy Disk Controller's Device structure
206 FdcDev
->Signature
= FDC_BLK_IO_DEV_SIGNATURE
;
207 FdcDev
->Handle
= Controller
;
208 FdcDev
->IsaIo
= IsaIo
;
209 FdcDev
->Disk
= (EFI_FDC_DISK
) IsaIo
->ResourceList
->Device
.UID
;
210 FdcDev
->Cache
= NULL
;
211 FdcDev
->Event
= NULL
;
212 FdcDev
->ControllerState
= NULL
;
213 FdcDev
->DevicePath
= ParentDevicePath
;
215 ADD_FLOPPY_NAME (FdcDev
);
218 // Look up the base address of the Floppy Disk Controller
220 for (Index
= 0; FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
221 if (FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
222 FdcDev
->BaseAddress
= (UINT16
) FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
226 // Maintain the list of controller list
229 List
= gControllerHead
.ForwardLink
;
230 while (List
!= &gControllerHead
) {
231 FdcDev
->ControllerState
= FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List
);
232 if (FdcDev
->BaseAddress
== FdcDev
->ControllerState
->BaseAddress
) {
237 List
= List
->ForwardLink
;
242 // The Controller is new
244 FdcDev
->ControllerState
= AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT
));
245 if (FdcDev
->ControllerState
== NULL
) {
249 FdcDev
->ControllerState
->Signature
= FLOPPY_CONTROLLER_CONTEXT_SIGNATURE
;
250 FdcDev
->ControllerState
->FddResetPerformed
= FALSE
;
251 FdcDev
->ControllerState
->NeedRecalibrate
= FALSE
;
252 FdcDev
->ControllerState
->BaseAddress
= FdcDev
->BaseAddress
;
253 FdcDev
->ControllerState
->NumberOfDrive
= 0;
255 InsertTailList (&gControllerHead
, &FdcDev
->ControllerState
->Link
);
258 // Create a timer event for each Floppd Disk Controller.
259 // This timer event is used to control the motor on and off
261 Status
= gBS
->CreateEvent (
262 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
268 if (EFI_ERROR (Status
)) {
272 // Reset the Floppy Disk Controller
274 if (!FdcDev
->ControllerState
->FddResetPerformed
) {
275 FdcDev
->ControllerState
->FddResetPerformed
= TRUE
;
276 FdcDev
->ControllerState
->FddResetStatus
= FddReset (FdcDev
);
279 if (EFI_ERROR (FdcDev
->ControllerState
->FddResetStatus
)) {
280 Status
= EFI_DEVICE_ERROR
;
284 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
286 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_PRESENCE_DETECT
,
291 // Discover the Floppy Drive
293 Status
= DiscoverFddDevice (FdcDev
);
294 if (EFI_ERROR (Status
)) {
295 Status
= EFI_DEVICE_ERROR
;
299 // Install protocol interfaces for the serial device.
301 Status
= gBS
->InstallMultipleProtocolInterfaces (
303 &gEfiBlockIoProtocolGuid
,
308 FdcDev
->ControllerState
->NumberOfDrive
++;
311 if (EFI_ERROR (Status
)) {
313 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
314 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
315 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_CONTROLLER_ERROR
,
320 // Close the device path protocol
324 &gEfiDevicePathProtocolGuid
,
325 This
->DriverBindingHandle
,
330 // Close the ISA I/O Protocol
335 &gEfiIsaIoProtocolGuid
,
336 This
->DriverBindingHandle
,
341 // If a Floppy Disk Controller Device structure was allocated, then free it
343 if (FdcDev
!= NULL
) {
344 if (FdcDev
->Event
!= NULL
) {
346 // Close the event for turning the motor off
348 gBS
->CloseEvent (FdcDev
->Event
);
351 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
352 gBS
->FreePool (FdcDev
);
360 Stop this driver on ControllerHandle. Support stoping any child handles
361 created by this driver.
363 @param This Protocol instance pointer.
364 @param Controller Handle of device to stop driver on
365 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
366 children is zero stop the entire bus driver.
367 @param ChildHandleBuffer List of Child Handles to Stop.
369 @retval EFI_SUCCESS This driver is removed ControllerHandle
370 @retval other This driver was not removed from this device
375 FdcControllerDriverStop (
376 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
377 IN EFI_HANDLE Controller
,
378 IN UINTN NumberOfChildren
,
379 IN EFI_HANDLE
*ChildHandleBuffer
383 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
384 FDC_BLK_IO_DEV
*FdcDev
;
387 // Get the Block I/O Protocol on Controller
389 Status
= gBS
->OpenProtocol (
391 &gEfiBlockIoProtocolGuid
,
393 This
->DriverBindingHandle
,
395 EFI_OPEN_PROTOCOL_GET_PROTOCOL
397 if (EFI_ERROR (Status
)) {
401 // Get the Floppy Disk Controller's Device structure
403 FdcDev
= FDD_BLK_IO_FROM_THIS (BlkIo
);
406 // Report disable progress code
408 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
410 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
,
415 // Turn the motor off on the Floppy Disk Controller
417 FddTimerProc (FdcDev
->Event
, FdcDev
);
420 // Uninstall the Block I/O Protocol
422 Status
= gBS
->UninstallProtocolInterface (
424 &gEfiBlockIoProtocolGuid
,
427 if (EFI_ERROR (Status
)) {
431 // Close the device path protocol
435 &gEfiDevicePathProtocolGuid
,
436 This
->DriverBindingHandle
,
441 // Close the ISA I/O Protocol
445 &gEfiIsaIoProtocolGuid
,
446 This
->DriverBindingHandle
,
451 // Free the controller list if needed
453 FdcDev
->ControllerState
->NumberOfDrive
--;
456 // Close the event for turning the motor off
458 gBS
->CloseEvent (FdcDev
->Event
);
461 // Free the cache if one was allocated
463 FdcFreeCache (FdcDev
);
466 // Free the Floppy Disk Controller's Device structure
468 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
469 gBS
->FreePool (FdcDev
);