11f43dfd |
1 | /*++\r |
2 | \r |
6db49ee6 |
3 | Copyright (c) 2006 - 2007, Intel Corporation<BR>\r |
4 | All rights reserved. This program and the accompanying materials\r |
5 | are licensed and made available under the terms and conditions of the BSD License\r |
6 | which accompanies this distribution. The full text of the license may be found at\r |
7 | http://opensource.org/licenses/bsd-license.php\r |
8 | \r |
9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
11f43dfd |
11 | \r |
12 | Module Name:\r |
13 | \r |
14 | IsaFloppy.c\r |
15 | \r |
16 | Abstract:\r |
17 | \r |
18 | ISA Floppy Driver\r |
19 | 1. Support two types diskette drive \r |
20 | 1.44M drive and 2.88M drive (and now only support 1.44M)\r |
21 | 2. Support two diskette drives\r |
22 | 3. Use DMA channel 2 to transfer data\r |
23 | 4. Do not use interrupt\r |
24 | 5. Support diskette change line signal and write protect\r |
25 | \r |
26 | conforming to EFI driver model\r |
27 | \r |
28 | Revision History:\r |
29 | \r |
30 | --*/\r |
31 | \r |
32 | #include "IsaFloppy.h"\r |
33 | \r |
34 | LIST_ENTRY gControllerHead = INITIALIZE_LIST_HEAD_VARIABLE(gControllerHead);\r |
35 | \r |
36 | //\r |
37 | // ISA Floppy Driver Binding Protocol\r |
38 | //\r |
39 | EFI_DRIVER_BINDING_PROTOCOL gFdcControllerDriver = {\r |
40 | FdcControllerDriverSupported,\r |
41 | FdcControllerDriverStart,\r |
42 | FdcControllerDriverStop,\r |
43 | 0xa,\r |
44 | NULL,\r |
45 | NULL\r |
46 | };\r |
47 | \r |
99bda0fd |
48 | \r |
49 | /**\r |
50 | The user Entry Point for module IsaFloppy. The user code starts with this function.\r |
51 | \r |
52 | @param[in] ImageHandle The firmware allocated handle for the EFI image. \r |
53 | @param[in] SystemTable A pointer to the EFI System Table.\r |
54 | \r |
55 | @retval EFI_SUCCESS The entry point is executed successfully.\r |
56 | @retval other Some error occurs when executing this entry point.\r |
57 | \r |
58 | **/\r |
59 | EFI_STATUS\r |
60 | EFIAPI\r |
61 | InitializeIsaFloppy(\r |
62 | IN EFI_HANDLE ImageHandle,\r |
63 | IN EFI_SYSTEM_TABLE *SystemTable\r |
64 | )\r |
65 | {\r |
66 | EFI_STATUS Status;\r |
67 | \r |
68 | //\r |
69 | // Install driver model protocol(s).\r |
70 | //\r |
71 | Status = EfiLibInstallAllDriverProtocols (\r |
72 | ImageHandle,\r |
73 | SystemTable,\r |
74 | &gFdcControllerDriver,\r |
75 | ImageHandle,\r |
76 | &gIsaFloppyComponentName,\r |
77 | NULL,\r |
78 | NULL\r |
79 | );\r |
80 | ASSERT_EFI_ERROR (Status);\r |
81 | \r |
82 | \r |
83 | return Status;\r |
84 | }\r |
85 | \r |
86 | \r |
11f43dfd |
87 | EFI_STATUS\r |
88 | EFIAPI\r |
89 | FdcControllerDriverSupported (\r |
90 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r |
91 | IN EFI_HANDLE Controller,\r |
92 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r |
93 | )\r |
94 | /*++\r |
95 | \r |
96 | Routine Description:\r |
97 | \r |
98 | ControllerDriver Protocol Method\r |
99 | \r |
100 | Arguments:\r |
101 | \r |
102 | Returns:\r |
103 | \r |
104 | --*/\r |
105 | // GC_TODO: This - add argument and description to function comment\r |
106 | // GC_TODO: Controller - add argument and description to function comment\r |
107 | // GC_TODO: RemainingDevicePath - add argument and description to function comment\r |
108 | {\r |
109 | EFI_STATUS Status;\r |
110 | EFI_ISA_IO_PROTOCOL *IsaIo;\r |
111 | \r |
112 | //\r |
113 | // Open the ISA I/O Protocol\r |
114 | //\r |
115 | Status = gBS->OpenProtocol (\r |
116 | Controller,\r |
117 | &gEfiIsaIoProtocolGuid,\r |
118 | (VOID **) &IsaIo,\r |
119 | This->DriverBindingHandle,\r |
120 | Controller,\r |
121 | EFI_OPEN_PROTOCOL_BY_DRIVER\r |
122 | );\r |
123 | if (EFI_ERROR (Status)) {\r |
124 | return Status;\r |
125 | }\r |
126 | //\r |
127 | // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller\r |
128 | //\r |
129 | Status = EFI_SUCCESS;\r |
130 | if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) {\r |
131 | Status = EFI_UNSUPPORTED;\r |
132 | }\r |
133 | //\r |
134 | // Close the ISA I/O Protocol\r |
135 | //\r |
136 | gBS->CloseProtocol (\r |
137 | Controller,\r |
138 | &gEfiIsaIoProtocolGuid,\r |
139 | This->DriverBindingHandle,\r |
140 | Controller\r |
141 | );\r |
142 | \r |
143 | return Status;\r |
144 | }\r |
145 | \r |
146 | EFI_STATUS\r |
147 | EFIAPI\r |
148 | FdcControllerDriverStart (\r |
149 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r |
150 | IN EFI_HANDLE Controller,\r |
151 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r |
152 | )\r |
153 | /*++\r |
154 | \r |
155 | Routine Description:\r |
156 | \r |
157 | Arguments:\r |
158 | \r |
159 | Returns:\r |
160 | \r |
161 | --*/\r |
162 | // GC_TODO: This - add argument and description to function comment\r |
163 | // GC_TODO: Controller - add argument and description to function comment\r |
164 | // GC_TODO: RemainingDevicePath - add argument and description to function comment\r |
165 | {\r |
166 | EFI_STATUS Status;\r |
167 | FDC_BLK_IO_DEV *FdcDev;\r |
168 | EFI_ISA_IO_PROTOCOL *IsaIo;\r |
169 | UINTN Index;\r |
170 | LIST_ENTRY *List;\r |
171 | BOOLEAN Found;\r |
172 | EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r |
173 | \r |
174 | FdcDev = NULL;\r |
175 | IsaIo = NULL;\r |
176 | \r |
177 | //\r |
178 | // Open the device path protocol\r |
179 | //\r |
180 | Status = gBS->OpenProtocol (\r |
181 | Controller,\r |
182 | &gEfiDevicePathProtocolGuid,\r |
183 | (VOID **) &ParentDevicePath,\r |
184 | This->DriverBindingHandle,\r |
185 | Controller,\r |
186 | EFI_OPEN_PROTOCOL_BY_DRIVER\r |
187 | );\r |
188 | if (EFI_ERROR (Status)) {\r |
189 | return Status;\r |
190 | }\r |
191 | //\r |
192 | // Report enable progress code\r |
193 | //\r |
194 | REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r |
195 | EFI_PROGRESS_CODE,\r |
196 | EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE,\r |
197 | ParentDevicePath\r |
198 | );\r |
199 | \r |
200 | //\r |
201 | // Open the ISA I/O Protocol\r |
202 | //\r |
203 | Status = gBS->OpenProtocol (\r |
204 | Controller,\r |
205 | &gEfiIsaIoProtocolGuid,\r |
206 | (VOID **) &IsaIo,\r |
207 | This->DriverBindingHandle,\r |
208 | Controller,\r |
209 | EFI_OPEN_PROTOCOL_BY_DRIVER\r |
210 | );\r |
211 | if (EFI_ERROR (Status)) {\r |
212 | goto Done;\r |
213 | }\r |
214 | //\r |
215 | // Allocate the Floppy Disk Controller's Device structure\r |
216 | //\r |
217 | FdcDev = AllocateZeroPool (sizeof (FDC_BLK_IO_DEV));\r |
218 | if (FdcDev == NULL) {\r |
219 | goto Done;\r |
220 | }\r |
221 | //\r |
222 | // Initialize the Floppy Disk Controller's Device structure\r |
223 | //\r |
224 | FdcDev->Signature = FDC_BLK_IO_DEV_SIGNATURE;\r |
225 | FdcDev->Handle = Controller;\r |
226 | FdcDev->IsaIo = IsaIo;\r |
227 | FdcDev->Disk = (EFI_FDC_DISK) IsaIo->ResourceList->Device.UID;\r |
228 | FdcDev->Cache = NULL;\r |
229 | FdcDev->Event = NULL;\r |
230 | FdcDev->ControllerState = NULL;\r |
231 | FdcDev->DevicePath = ParentDevicePath;\r |
232 | \r |
233 | ADD_FLOPPY_NAME (FdcDev);\r |
234 | \r |
235 | //\r |
236 | // Look up the base address of the Floppy Disk Controller\r |
237 | //\r |
238 | for (Index = 0; FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) {\r |
239 | if (FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) {\r |
240 | FdcDev->BaseAddress = (UINT16) FdcDev->IsaIo->ResourceList->ResourceItem[Index].StartRange;\r |
241 | }\r |
242 | }\r |
243 | //\r |
244 | // Maintain the list of controller list\r |
245 | //\r |
246 | Found = FALSE;\r |
247 | List = gControllerHead.ForwardLink;\r |
248 | while (List != &gControllerHead) {\r |
249 | FdcDev->ControllerState = FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List);\r |
250 | if (FdcDev->BaseAddress == FdcDev->ControllerState->BaseAddress) {\r |
251 | Found = TRUE;\r |
252 | break;\r |
253 | }\r |
254 | \r |
255 | List = List->ForwardLink;\r |
256 | }\r |
257 | \r |
258 | if (!Found) {\r |
259 | //\r |
260 | // The Controller is new\r |
261 | //\r |
262 | FdcDev->ControllerState = AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT));\r |
263 | if (FdcDev->ControllerState == NULL) {\r |
264 | goto Done;\r |
265 | }\r |
266 | \r |
267 | FdcDev->ControllerState->Signature = FLOPPY_CONTROLLER_CONTEXT_SIGNATURE;\r |
268 | FdcDev->ControllerState->FddResetPerformed = FALSE;\r |
269 | FdcDev->ControllerState->NeedRecalibrate = FALSE;\r |
270 | FdcDev->ControllerState->BaseAddress = FdcDev->BaseAddress;\r |
271 | FdcDev->ControllerState->NumberOfDrive = 0;\r |
272 | \r |
273 | InsertTailList (&gControllerHead, &FdcDev->ControllerState->Link);\r |
274 | }\r |
275 | //\r |
276 | // Create a timer event for each Floppd Disk Controller.\r |
277 | // This timer event is used to control the motor on and off\r |
278 | //\r |
279 | Status = gBS->CreateEvent (\r |
280 | EVT_TIMER | EVT_NOTIFY_SIGNAL,\r |
281 | TPL_NOTIFY,\r |
282 | FddTimerProc,\r |
283 | FdcDev,\r |
284 | &FdcDev->Event\r |
285 | );\r |
286 | if (EFI_ERROR (Status)) {\r |
287 | goto Done;\r |
288 | }\r |
289 | //\r |
290 | // Reset the Floppy Disk Controller\r |
291 | //\r |
292 | if (!FdcDev->ControllerState->FddResetPerformed) {\r |
293 | FdcDev->ControllerState->FddResetPerformed = TRUE;\r |
294 | FdcDev->ControllerState->FddResetStatus = FddReset (FdcDev);\r |
295 | }\r |
296 | \r |
297 | if (EFI_ERROR (FdcDev->ControllerState->FddResetStatus)) {\r |
298 | Status = EFI_DEVICE_ERROR;\r |
299 | goto Done;\r |
300 | }\r |
301 | \r |
302 | REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r |
303 | EFI_PROGRESS_CODE,\r |
304 | EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT,\r |
305 | ParentDevicePath\r |
306 | );\r |
307 | \r |
308 | //\r |
309 | // Discover the Floppy Drive\r |
310 | //\r |
311 | Status = DiscoverFddDevice (FdcDev);\r |
312 | if (EFI_ERROR (Status)) {\r |
313 | Status = EFI_DEVICE_ERROR;\r |
314 | goto Done;\r |
315 | }\r |
316 | //\r |
317 | // Install protocol interfaces for the serial device.\r |
318 | //\r |
319 | Status = gBS->InstallMultipleProtocolInterfaces (\r |
320 | &Controller,\r |
321 | &gEfiBlockIoProtocolGuid,\r |
322 | &FdcDev->BlkIo,\r |
323 | NULL\r |
324 | );\r |
325 | \r |
326 | FdcDev->ControllerState->NumberOfDrive++;\r |
327 | \r |
328 | Done:\r |
329 | if (EFI_ERROR (Status)) {\r |
330 | \r |
331 | REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r |
332 | EFI_ERROR_CODE | EFI_ERROR_MINOR,\r |
333 | EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR,\r |
334 | ParentDevicePath\r |
335 | );\r |
336 | \r |
337 | //\r |
338 | // Close the device path protocol\r |
339 | //\r |
340 | gBS->CloseProtocol (\r |
341 | Controller,\r |
342 | &gEfiDevicePathProtocolGuid,\r |
343 | This->DriverBindingHandle,\r |
344 | Controller\r |
345 | );\r |
346 | \r |
347 | //\r |
348 | // Close the ISA I/O Protocol\r |
349 | //\r |
350 | if (IsaIo != NULL) {\r |
351 | gBS->CloseProtocol (\r |
352 | Controller,\r |
353 | &gEfiIsaIoProtocolGuid,\r |
354 | This->DriverBindingHandle,\r |
355 | Controller\r |
356 | );\r |
357 | }\r |
358 | //\r |
359 | // If a Floppy Disk Controller Device structure was allocated, then free it\r |
360 | //\r |
361 | if (FdcDev != NULL) {\r |
362 | if (FdcDev->Event != NULL) {\r |
363 | //\r |
364 | // Close the event for turning the motor off\r |
365 | //\r |
366 | gBS->CloseEvent (FdcDev->Event);\r |
367 | }\r |
368 | \r |
369 | FreeUnicodeStringTable (FdcDev->ControllerNameTable);\r |
370 | gBS->FreePool (FdcDev);\r |
371 | }\r |
372 | }\r |
373 | \r |
374 | return Status;\r |
375 | }\r |
376 | \r |
377 | EFI_STATUS\r |
378 | EFIAPI\r |
379 | FdcControllerDriverStop (\r |
380 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r |
381 | IN EFI_HANDLE Controller,\r |
382 | IN UINTN NumberOfChildren,\r |
383 | IN EFI_HANDLE *ChildHandleBuffer\r |
384 | )\r |
385 | /*++\r |
386 | \r |
387 | Routine Description:\r |
388 | \r |
389 | Arguments:\r |
390 | \r |
391 | Returns:\r |
392 | \r |
393 | --*/\r |
394 | // GC_TODO: This - add argument and description to function comment\r |
395 | // GC_TODO: Controller - add argument and description to function comment\r |
396 | // GC_TODO: NumberOfChildren - add argument and description to function comment\r |
397 | // GC_TODO: ChildHandleBuffer - add argument and description to function comment\r |
398 | // GC_TODO: EFI_SUCCESS - add return value to function comment\r |
399 | {\r |
400 | EFI_STATUS Status;\r |
401 | EFI_BLOCK_IO_PROTOCOL *BlkIo;\r |
402 | FDC_BLK_IO_DEV *FdcDev;\r |
403 | \r |
404 | //\r |
405 | // Get the Block I/O Protocol on Controller\r |
406 | //\r |
407 | Status = gBS->OpenProtocol (\r |
408 | Controller,\r |
409 | &gEfiBlockIoProtocolGuid,\r |
410 | (VOID **) &BlkIo,\r |
411 | This->DriverBindingHandle,\r |
412 | Controller,\r |
413 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r |
414 | );\r |
415 | if (EFI_ERROR (Status)) {\r |
416 | return Status;\r |
417 | }\r |
418 | //\r |
419 | // Get the Floppy Disk Controller's Device structure\r |
420 | //\r |
421 | FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo);\r |
422 | \r |
423 | //\r |
424 | // Report disable progress code\r |
425 | //\r |
426 | REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r |
427 | EFI_PROGRESS_CODE,\r |
428 | EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE,\r |
429 | FdcDev->DevicePath\r |
430 | );\r |
431 | \r |
432 | //\r |
433 | // Turn the motor off on the Floppy Disk Controller\r |
434 | //\r |
435 | FddTimerProc (FdcDev->Event, FdcDev);\r |
436 | \r |
437 | //\r |
438 | // Uninstall the Block I/O Protocol\r |
439 | //\r |
440 | Status = gBS->UninstallProtocolInterface (\r |
441 | Controller,\r |
442 | &gEfiBlockIoProtocolGuid,\r |
443 | &FdcDev->BlkIo\r |
444 | );\r |
445 | if (EFI_ERROR (Status)) {\r |
446 | return Status;\r |
447 | }\r |
448 | //\r |
449 | // Close the device path protocol\r |
450 | //\r |
451 | gBS->CloseProtocol (\r |
452 | Controller,\r |
453 | &gEfiDevicePathProtocolGuid,\r |
454 | This->DriverBindingHandle,\r |
455 | Controller\r |
456 | );\r |
457 | \r |
458 | //\r |
459 | // Close the ISA I/O Protocol\r |
460 | //\r |
461 | gBS->CloseProtocol (\r |
462 | Controller,\r |
463 | &gEfiIsaIoProtocolGuid,\r |
464 | This->DriverBindingHandle,\r |
465 | Controller\r |
466 | );\r |
467 | \r |
468 | //\r |
469 | // Free the controller list if needed\r |
470 | //\r |
471 | FdcDev->ControllerState->NumberOfDrive--;\r |
472 | \r |
473 | //\r |
474 | // Close the event for turning the motor off\r |
475 | //\r |
476 | gBS->CloseEvent (FdcDev->Event);\r |
477 | \r |
478 | //\r |
479 | // Free the cache if one was allocated\r |
480 | //\r |
481 | FdcFreeCache (FdcDev);\r |
482 | \r |
483 | //\r |
484 | // Free the Floppy Disk Controller's Device structure\r |
485 | //\r |
486 | FreeUnicodeStringTable (FdcDev->ControllerNameTable);\r |
487 | gBS->FreePool (FdcDev);\r |
488 | \r |
489 | return EFI_SUCCESS;\r |
490 | }\r |