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
= EfiLibInstallAllDriverProtocols (
65 &gFdcControllerDriver
,
67 &gIsaFloppyComponentName
,
71 ASSERT_EFI_ERROR (Status
);
80 FdcControllerDriverSupported (
81 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
82 IN EFI_HANDLE Controller
,
83 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
89 ControllerDriver Protocol Method
96 // GC_TODO: This - add argument and description to function comment
97 // GC_TODO: Controller - add argument and description to function comment
98 // GC_TODO: RemainingDevicePath - add argument and description to function comment
101 EFI_ISA_IO_PROTOCOL
*IsaIo
;
104 // Open the ISA I/O Protocol
106 Status
= gBS
->OpenProtocol (
108 &gEfiIsaIoProtocolGuid
,
110 This
->DriverBindingHandle
,
112 EFI_OPEN_PROTOCOL_BY_DRIVER
114 if (EFI_ERROR (Status
)) {
118 // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller
120 Status
= EFI_SUCCESS
;
121 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x604)) {
122 Status
= EFI_UNSUPPORTED
;
125 // Close the ISA I/O Protocol
129 &gEfiIsaIoProtocolGuid
,
130 This
->DriverBindingHandle
,
139 FdcControllerDriverStart (
140 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
141 IN EFI_HANDLE Controller
,
142 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
153 // GC_TODO: This - add argument and description to function comment
154 // GC_TODO: Controller - add argument and description to function comment
155 // GC_TODO: RemainingDevicePath - add argument and description to function comment
158 FDC_BLK_IO_DEV
*FdcDev
;
159 EFI_ISA_IO_PROTOCOL
*IsaIo
;
163 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
169 // Open the device path protocol
171 Status
= gBS
->OpenProtocol (
173 &gEfiDevicePathProtocolGuid
,
174 (VOID
**) &ParentDevicePath
,
175 This
->DriverBindingHandle
,
177 EFI_OPEN_PROTOCOL_BY_DRIVER
179 if (EFI_ERROR (Status
)) {
183 // Report enable progress code
185 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
187 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
,
192 // Open the ISA I/O Protocol
194 Status
= gBS
->OpenProtocol (
196 &gEfiIsaIoProtocolGuid
,
198 This
->DriverBindingHandle
,
200 EFI_OPEN_PROTOCOL_BY_DRIVER
202 if (EFI_ERROR (Status
)) {
206 // Allocate the Floppy Disk Controller's Device structure
208 FdcDev
= AllocateZeroPool (sizeof (FDC_BLK_IO_DEV
));
209 if (FdcDev
== NULL
) {
213 // Initialize the Floppy Disk Controller's Device structure
215 FdcDev
->Signature
= FDC_BLK_IO_DEV_SIGNATURE
;
216 FdcDev
->Handle
= Controller
;
217 FdcDev
->IsaIo
= IsaIo
;
218 FdcDev
->Disk
= (EFI_FDC_DISK
) IsaIo
->ResourceList
->Device
.UID
;
219 FdcDev
->Cache
= NULL
;
220 FdcDev
->Event
= NULL
;
221 FdcDev
->ControllerState
= NULL
;
222 FdcDev
->DevicePath
= ParentDevicePath
;
224 ADD_FLOPPY_NAME (FdcDev
);
227 // Look up the base address of the Floppy Disk Controller
229 for (Index
= 0; FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
230 if (FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
231 FdcDev
->BaseAddress
= (UINT16
) FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
235 // Maintain the list of controller list
238 List
= gControllerHead
.ForwardLink
;
239 while (List
!= &gControllerHead
) {
240 FdcDev
->ControllerState
= FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List
);
241 if (FdcDev
->BaseAddress
== FdcDev
->ControllerState
->BaseAddress
) {
246 List
= List
->ForwardLink
;
251 // The Controller is new
253 FdcDev
->ControllerState
= AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT
));
254 if (FdcDev
->ControllerState
== NULL
) {
258 FdcDev
->ControllerState
->Signature
= FLOPPY_CONTROLLER_CONTEXT_SIGNATURE
;
259 FdcDev
->ControllerState
->FddResetPerformed
= FALSE
;
260 FdcDev
->ControllerState
->NeedRecalibrate
= FALSE
;
261 FdcDev
->ControllerState
->BaseAddress
= FdcDev
->BaseAddress
;
262 FdcDev
->ControllerState
->NumberOfDrive
= 0;
264 InsertTailList (&gControllerHead
, &FdcDev
->ControllerState
->Link
);
267 // Create a timer event for each Floppd Disk Controller.
268 // This timer event is used to control the motor on and off
270 Status
= gBS
->CreateEvent (
271 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
277 if (EFI_ERROR (Status
)) {
281 // Reset the Floppy Disk Controller
283 if (!FdcDev
->ControllerState
->FddResetPerformed
) {
284 FdcDev
->ControllerState
->FddResetPerformed
= TRUE
;
285 FdcDev
->ControllerState
->FddResetStatus
= FddReset (FdcDev
);
288 if (EFI_ERROR (FdcDev
->ControllerState
->FddResetStatus
)) {
289 Status
= EFI_DEVICE_ERROR
;
293 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
295 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_PRESENCE_DETECT
,
300 // Discover the Floppy Drive
302 Status
= DiscoverFddDevice (FdcDev
);
303 if (EFI_ERROR (Status
)) {
304 Status
= EFI_DEVICE_ERROR
;
308 // Install protocol interfaces for the serial device.
310 Status
= gBS
->InstallMultipleProtocolInterfaces (
312 &gEfiBlockIoProtocolGuid
,
317 FdcDev
->ControllerState
->NumberOfDrive
++;
320 if (EFI_ERROR (Status
)) {
322 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
323 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
324 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_CONTROLLER_ERROR
,
329 // Close the device path protocol
333 &gEfiDevicePathProtocolGuid
,
334 This
->DriverBindingHandle
,
339 // Close the ISA I/O Protocol
344 &gEfiIsaIoProtocolGuid
,
345 This
->DriverBindingHandle
,
350 // If a Floppy Disk Controller Device structure was allocated, then free it
352 if (FdcDev
!= NULL
) {
353 if (FdcDev
->Event
!= NULL
) {
355 // Close the event for turning the motor off
357 gBS
->CloseEvent (FdcDev
->Event
);
360 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
361 gBS
->FreePool (FdcDev
);
370 FdcControllerDriverStop (
371 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
372 IN EFI_HANDLE Controller
,
373 IN UINTN NumberOfChildren
,
374 IN EFI_HANDLE
*ChildHandleBuffer
385 // GC_TODO: This - add argument and description to function comment
386 // GC_TODO: Controller - add argument and description to function comment
387 // GC_TODO: NumberOfChildren - add argument and description to function comment
388 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
389 // GC_TODO: EFI_SUCCESS - add return value to function comment
392 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
393 FDC_BLK_IO_DEV
*FdcDev
;
396 // Get the Block I/O Protocol on Controller
398 Status
= gBS
->OpenProtocol (
400 &gEfiBlockIoProtocolGuid
,
402 This
->DriverBindingHandle
,
404 EFI_OPEN_PROTOCOL_GET_PROTOCOL
406 if (EFI_ERROR (Status
)) {
410 // Get the Floppy Disk Controller's Device structure
412 FdcDev
= FDD_BLK_IO_FROM_THIS (BlkIo
);
415 // Report disable progress code
417 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
419 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
,
424 // Turn the motor off on the Floppy Disk Controller
426 FddTimerProc (FdcDev
->Event
, FdcDev
);
429 // Uninstall the Block I/O Protocol
431 Status
= gBS
->UninstallProtocolInterface (
433 &gEfiBlockIoProtocolGuid
,
436 if (EFI_ERROR (Status
)) {
440 // Close the device path protocol
444 &gEfiDevicePathProtocolGuid
,
445 This
->DriverBindingHandle
,
450 // Close the ISA I/O Protocol
454 &gEfiIsaIoProtocolGuid
,
455 This
->DriverBindingHandle
,
460 // Free the controller list if needed
462 FdcDev
->ControllerState
->NumberOfDrive
--;
465 // Close the event for turning the motor off
467 gBS
->CloseEvent (FdcDev
->Event
);
470 // Free the cache if one was allocated
472 FdcFreeCache (FdcDev
);
475 // Free the Floppy Disk Controller's Device structure
477 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
478 gBS
->FreePool (FdcDev
);