3 Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
19 1. Support two types diskette drive
20 1.44M drive and 2.88M drive (and now only support 1.44M)
21 2. Support two diskette drives
22 3. Use DMA channel 2 to transfer data
23 4. Do not use interrupt
24 5. Support diskette change line signal and write protect
26 conforming to EFI driver model
32 #include "IsaFloppy.h"
34 LIST_ENTRY gControllerHead
= INITIALIZE_LIST_HEAD_VARIABLE(gControllerHead
);
37 // ISA Floppy Driver Binding Protocol
39 EFI_DRIVER_BINDING_PROTOCOL gFdcControllerDriver
= {
40 FdcControllerDriverSupported
,
41 FdcControllerDriverStart
,
42 FdcControllerDriverStop
,
50 FdcControllerDriverSupported (
51 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
52 IN EFI_HANDLE Controller
,
53 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
59 ControllerDriver Protocol Method
66 // GC_TODO: This - add argument and description to function comment
67 // GC_TODO: Controller - add argument and description to function comment
68 // GC_TODO: RemainingDevicePath - add argument and description to function comment
71 EFI_ISA_IO_PROTOCOL
*IsaIo
;
74 // Open the ISA I/O Protocol
76 Status
= gBS
->OpenProtocol (
78 &gEfiIsaIoProtocolGuid
,
80 This
->DriverBindingHandle
,
82 EFI_OPEN_PROTOCOL_BY_DRIVER
84 if (EFI_ERROR (Status
)) {
88 // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller
91 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x604)) {
92 Status
= EFI_UNSUPPORTED
;
95 // Close the ISA I/O Protocol
99 &gEfiIsaIoProtocolGuid
,
100 This
->DriverBindingHandle
,
109 FdcControllerDriverStart (
110 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
111 IN EFI_HANDLE Controller
,
112 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
123 // GC_TODO: This - add argument and description to function comment
124 // GC_TODO: Controller - add argument and description to function comment
125 // GC_TODO: RemainingDevicePath - add argument and description to function comment
128 FDC_BLK_IO_DEV
*FdcDev
;
129 EFI_ISA_IO_PROTOCOL
*IsaIo
;
133 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
139 // Open the device path protocol
141 Status
= gBS
->OpenProtocol (
143 &gEfiDevicePathProtocolGuid
,
144 (VOID
**) &ParentDevicePath
,
145 This
->DriverBindingHandle
,
147 EFI_OPEN_PROTOCOL_BY_DRIVER
149 if (EFI_ERROR (Status
)) {
153 // Report enable progress code
155 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
157 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
,
162 // Open the ISA I/O Protocol
164 Status
= gBS
->OpenProtocol (
166 &gEfiIsaIoProtocolGuid
,
168 This
->DriverBindingHandle
,
170 EFI_OPEN_PROTOCOL_BY_DRIVER
172 if (EFI_ERROR (Status
)) {
176 // Allocate the Floppy Disk Controller's Device structure
178 FdcDev
= AllocateZeroPool (sizeof (FDC_BLK_IO_DEV
));
179 if (FdcDev
== NULL
) {
183 // Initialize the Floppy Disk Controller's Device structure
185 FdcDev
->Signature
= FDC_BLK_IO_DEV_SIGNATURE
;
186 FdcDev
->Handle
= Controller
;
187 FdcDev
->IsaIo
= IsaIo
;
188 FdcDev
->Disk
= (EFI_FDC_DISK
) IsaIo
->ResourceList
->Device
.UID
;
189 FdcDev
->Cache
= NULL
;
190 FdcDev
->Event
= NULL
;
191 FdcDev
->ControllerState
= NULL
;
192 FdcDev
->DevicePath
= ParentDevicePath
;
194 ADD_FLOPPY_NAME (FdcDev
);
197 // Look up the base address of the Floppy Disk Controller
199 for (Index
= 0; FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
200 if (FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
201 FdcDev
->BaseAddress
= (UINT16
) FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
205 // Maintain the list of controller list
208 List
= gControllerHead
.ForwardLink
;
209 while (List
!= &gControllerHead
) {
210 FdcDev
->ControllerState
= FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List
);
211 if (FdcDev
->BaseAddress
== FdcDev
->ControllerState
->BaseAddress
) {
216 List
= List
->ForwardLink
;
221 // The Controller is new
223 FdcDev
->ControllerState
= AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT
));
224 if (FdcDev
->ControllerState
== NULL
) {
228 FdcDev
->ControllerState
->Signature
= FLOPPY_CONTROLLER_CONTEXT_SIGNATURE
;
229 FdcDev
->ControllerState
->FddResetPerformed
= FALSE
;
230 FdcDev
->ControllerState
->NeedRecalibrate
= FALSE
;
231 FdcDev
->ControllerState
->BaseAddress
= FdcDev
->BaseAddress
;
232 FdcDev
->ControllerState
->NumberOfDrive
= 0;
234 InsertTailList (&gControllerHead
, &FdcDev
->ControllerState
->Link
);
237 // Create a timer event for each Floppd Disk Controller.
238 // This timer event is used to control the motor on and off
240 Status
= gBS
->CreateEvent (
241 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
247 if (EFI_ERROR (Status
)) {
251 // Reset the Floppy Disk Controller
253 if (!FdcDev
->ControllerState
->FddResetPerformed
) {
254 FdcDev
->ControllerState
->FddResetPerformed
= TRUE
;
255 FdcDev
->ControllerState
->FddResetStatus
= FddReset (FdcDev
);
258 if (EFI_ERROR (FdcDev
->ControllerState
->FddResetStatus
)) {
259 Status
= EFI_DEVICE_ERROR
;
263 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
265 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_PRESENCE_DETECT
,
270 // Discover the Floppy Drive
272 Status
= DiscoverFddDevice (FdcDev
);
273 if (EFI_ERROR (Status
)) {
274 Status
= EFI_DEVICE_ERROR
;
278 // Install protocol interfaces for the serial device.
280 Status
= gBS
->InstallMultipleProtocolInterfaces (
282 &gEfiBlockIoProtocolGuid
,
287 FdcDev
->ControllerState
->NumberOfDrive
++;
290 if (EFI_ERROR (Status
)) {
292 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
293 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
294 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_CONTROLLER_ERROR
,
299 // Close the device path protocol
303 &gEfiDevicePathProtocolGuid
,
304 This
->DriverBindingHandle
,
309 // Close the ISA I/O Protocol
314 &gEfiIsaIoProtocolGuid
,
315 This
->DriverBindingHandle
,
320 // If a Floppy Disk Controller Device structure was allocated, then free it
322 if (FdcDev
!= NULL
) {
323 if (FdcDev
->Event
!= NULL
) {
325 // Close the event for turning the motor off
327 gBS
->CloseEvent (FdcDev
->Event
);
330 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
331 gBS
->FreePool (FdcDev
);
340 FdcControllerDriverStop (
341 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
342 IN EFI_HANDLE Controller
,
343 IN UINTN NumberOfChildren
,
344 IN EFI_HANDLE
*ChildHandleBuffer
355 // GC_TODO: This - add argument and description to function comment
356 // GC_TODO: Controller - add argument and description to function comment
357 // GC_TODO: NumberOfChildren - add argument and description to function comment
358 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
359 // GC_TODO: EFI_SUCCESS - add return value to function comment
362 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
363 FDC_BLK_IO_DEV
*FdcDev
;
366 // Get the Block I/O Protocol on Controller
368 Status
= gBS
->OpenProtocol (
370 &gEfiBlockIoProtocolGuid
,
372 This
->DriverBindingHandle
,
374 EFI_OPEN_PROTOCOL_GET_PROTOCOL
376 if (EFI_ERROR (Status
)) {
380 // Get the Floppy Disk Controller's Device structure
382 FdcDev
= FDD_BLK_IO_FROM_THIS (BlkIo
);
385 // Report disable progress code
387 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
389 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
,
394 // Turn the motor off on the Floppy Disk Controller
396 FddTimerProc (FdcDev
->Event
, FdcDev
);
399 // Uninstall the Block I/O Protocol
401 Status
= gBS
->UninstallProtocolInterface (
403 &gEfiBlockIoProtocolGuid
,
406 if (EFI_ERROR (Status
)) {
410 // Close the device path protocol
414 &gEfiDevicePathProtocolGuid
,
415 This
->DriverBindingHandle
,
420 // Close the ISA I/O Protocol
424 &gEfiIsaIoProtocolGuid
,
425 This
->DriverBindingHandle
,
430 // Free the controller list if needed
432 FdcDev
->ControllerState
->NumberOfDrive
--;
435 // Close the event for turning the motor off
437 gBS
->CloseEvent (FdcDev
->Event
);
440 // Free the cache if one was allocated
442 FdcFreeCache (FdcDev
);
445 // Free the Floppy Disk Controller's Device structure
447 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
448 gBS
->FreePool (FdcDev
);