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