3 Copyright (c) 2006 - 2007, Intel Corporation<BR>
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
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 The user Entry Point for module IsaFloppy. The user code starts with this function.
52 @param[in] ImageHandle The firmware allocated handle for the EFI image.
53 @param[in] SystemTable A pointer to the EFI System Table.
55 @retval EFI_SUCCESS The entry point is executed successfully.
56 @retval other Some error occurs when executing this entry point.
62 IN EFI_HANDLE ImageHandle
,
63 IN EFI_SYSTEM_TABLE
*SystemTable
69 // Install driver model protocol(s).
71 Status
= EfiLibInstallAllDriverProtocols (
74 &gFdcControllerDriver
,
76 &gIsaFloppyComponentName
,
80 ASSERT_EFI_ERROR (Status
);
89 FdcControllerDriverSupported (
90 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
91 IN EFI_HANDLE Controller
,
92 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
98 ControllerDriver Protocol Method
105 // GC_TODO: This - add argument and description to function comment
106 // GC_TODO: Controller - add argument and description to function comment
107 // GC_TODO: RemainingDevicePath - add argument and description to function comment
110 EFI_ISA_IO_PROTOCOL
*IsaIo
;
113 // Open the ISA I/O Protocol
115 Status
= gBS
->OpenProtocol (
117 &gEfiIsaIoProtocolGuid
,
119 This
->DriverBindingHandle
,
121 EFI_OPEN_PROTOCOL_BY_DRIVER
123 if (EFI_ERROR (Status
)) {
127 // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller
129 Status
= EFI_SUCCESS
;
130 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x604)) {
131 Status
= EFI_UNSUPPORTED
;
134 // Close the ISA I/O Protocol
138 &gEfiIsaIoProtocolGuid
,
139 This
->DriverBindingHandle
,
148 FdcControllerDriverStart (
149 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
150 IN EFI_HANDLE Controller
,
151 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
162 // GC_TODO: This - add argument and description to function comment
163 // GC_TODO: Controller - add argument and description to function comment
164 // GC_TODO: RemainingDevicePath - add argument and description to function comment
167 FDC_BLK_IO_DEV
*FdcDev
;
168 EFI_ISA_IO_PROTOCOL
*IsaIo
;
172 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
178 // Open the device path protocol
180 Status
= gBS
->OpenProtocol (
182 &gEfiDevicePathProtocolGuid
,
183 (VOID
**) &ParentDevicePath
,
184 This
->DriverBindingHandle
,
186 EFI_OPEN_PROTOCOL_BY_DRIVER
188 if (EFI_ERROR (Status
)) {
192 // Report enable progress code
194 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
196 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_ENABLE
,
201 // Open the ISA I/O Protocol
203 Status
= gBS
->OpenProtocol (
205 &gEfiIsaIoProtocolGuid
,
207 This
->DriverBindingHandle
,
209 EFI_OPEN_PROTOCOL_BY_DRIVER
211 if (EFI_ERROR (Status
)) {
215 // Allocate the Floppy Disk Controller's Device structure
217 FdcDev
= AllocateZeroPool (sizeof (FDC_BLK_IO_DEV
));
218 if (FdcDev
== NULL
) {
222 // Initialize the Floppy Disk Controller's Device structure
224 FdcDev
->Signature
= FDC_BLK_IO_DEV_SIGNATURE
;
225 FdcDev
->Handle
= Controller
;
226 FdcDev
->IsaIo
= IsaIo
;
227 FdcDev
->Disk
= (EFI_FDC_DISK
) IsaIo
->ResourceList
->Device
.UID
;
228 FdcDev
->Cache
= NULL
;
229 FdcDev
->Event
= NULL
;
230 FdcDev
->ControllerState
= NULL
;
231 FdcDev
->DevicePath
= ParentDevicePath
;
233 ADD_FLOPPY_NAME (FdcDev
);
236 // Look up the base address of the Floppy Disk Controller
238 for (Index
= 0; FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
!= EfiIsaAcpiResourceEndOfList
; Index
++) {
239 if (FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].Type
== EfiIsaAcpiResourceIo
) {
240 FdcDev
->BaseAddress
= (UINT16
) FdcDev
->IsaIo
->ResourceList
->ResourceItem
[Index
].StartRange
;
244 // Maintain the list of controller list
247 List
= gControllerHead
.ForwardLink
;
248 while (List
!= &gControllerHead
) {
249 FdcDev
->ControllerState
= FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List
);
250 if (FdcDev
->BaseAddress
== FdcDev
->ControllerState
->BaseAddress
) {
255 List
= List
->ForwardLink
;
260 // The Controller is new
262 FdcDev
->ControllerState
= AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT
));
263 if (FdcDev
->ControllerState
== NULL
) {
267 FdcDev
->ControllerState
->Signature
= FLOPPY_CONTROLLER_CONTEXT_SIGNATURE
;
268 FdcDev
->ControllerState
->FddResetPerformed
= FALSE
;
269 FdcDev
->ControllerState
->NeedRecalibrate
= FALSE
;
270 FdcDev
->ControllerState
->BaseAddress
= FdcDev
->BaseAddress
;
271 FdcDev
->ControllerState
->NumberOfDrive
= 0;
273 InsertTailList (&gControllerHead
, &FdcDev
->ControllerState
->Link
);
276 // Create a timer event for each Floppd Disk Controller.
277 // This timer event is used to control the motor on and off
279 Status
= gBS
->CreateEvent (
280 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
286 if (EFI_ERROR (Status
)) {
290 // Reset the Floppy Disk Controller
292 if (!FdcDev
->ControllerState
->FddResetPerformed
) {
293 FdcDev
->ControllerState
->FddResetPerformed
= TRUE
;
294 FdcDev
->ControllerState
->FddResetStatus
= FddReset (FdcDev
);
297 if (EFI_ERROR (FdcDev
->ControllerState
->FddResetStatus
)) {
298 Status
= EFI_DEVICE_ERROR
;
302 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
304 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_PRESENCE_DETECT
,
309 // Discover the Floppy Drive
311 Status
= DiscoverFddDevice (FdcDev
);
312 if (EFI_ERROR (Status
)) {
313 Status
= EFI_DEVICE_ERROR
;
317 // Install protocol interfaces for the serial device.
319 Status
= gBS
->InstallMultipleProtocolInterfaces (
321 &gEfiBlockIoProtocolGuid
,
326 FdcDev
->ControllerState
->NumberOfDrive
++;
329 if (EFI_ERROR (Status
)) {
331 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
332 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
333 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_EC_CONTROLLER_ERROR
,
338 // Close the device path protocol
342 &gEfiDevicePathProtocolGuid
,
343 This
->DriverBindingHandle
,
348 // Close the ISA I/O Protocol
353 &gEfiIsaIoProtocolGuid
,
354 This
->DriverBindingHandle
,
359 // If a Floppy Disk Controller Device structure was allocated, then free it
361 if (FdcDev
!= NULL
) {
362 if (FdcDev
->Event
!= NULL
) {
364 // Close the event for turning the motor off
366 gBS
->CloseEvent (FdcDev
->Event
);
369 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
370 gBS
->FreePool (FdcDev
);
379 FdcControllerDriverStop (
380 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
381 IN EFI_HANDLE Controller
,
382 IN UINTN NumberOfChildren
,
383 IN EFI_HANDLE
*ChildHandleBuffer
394 // GC_TODO: This - add argument and description to function comment
395 // GC_TODO: Controller - add argument and description to function comment
396 // GC_TODO: NumberOfChildren - add argument and description to function comment
397 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
398 // GC_TODO: EFI_SUCCESS - add return value to function comment
401 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
402 FDC_BLK_IO_DEV
*FdcDev
;
405 // Get the Block I/O Protocol on Controller
407 Status
= gBS
->OpenProtocol (
409 &gEfiBlockIoProtocolGuid
,
411 This
->DriverBindingHandle
,
413 EFI_OPEN_PROTOCOL_GET_PROTOCOL
415 if (EFI_ERROR (Status
)) {
419 // Get the Floppy Disk Controller's Device structure
421 FdcDev
= FDD_BLK_IO_FROM_THIS (BlkIo
);
424 // Report disable progress code
426 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
428 EFI_PERIPHERAL_REMOVABLE_MEDIA
| EFI_P_PC_DISABLE
,
433 // Turn the motor off on the Floppy Disk Controller
435 FddTimerProc (FdcDev
->Event
, FdcDev
);
438 // Uninstall the Block I/O Protocol
440 Status
= gBS
->UninstallProtocolInterface (
442 &gEfiBlockIoProtocolGuid
,
445 if (EFI_ERROR (Status
)) {
449 // Close the device path protocol
453 &gEfiDevicePathProtocolGuid
,
454 This
->DriverBindingHandle
,
459 // Close the ISA I/O Protocol
463 &gEfiIsaIoProtocolGuid
,
464 This
->DriverBindingHandle
,
469 // Free the controller list if needed
471 FdcDev
->ControllerState
->NumberOfDrive
--;
474 // Close the event for turning the motor off
476 gBS
->CloseEvent (FdcDev
->Event
);
479 // Free the cache if one was allocated
481 FdcFreeCache (FdcDev
);
484 // Free the Floppy Disk Controller's Device structure
486 FreeUnicodeStringTable (FdcDev
->ControllerNameTable
);
487 gBS
->FreePool (FdcDev
);