Import IsaFloppy Dxe and Pei in IntelFrameworkModulePkg.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaFloppy / Dxe / IsaFloppy.c
1 /*++
2
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
10 Intel Corporation.
11
12 Module Name:
13
14 IsaFloppy.c
15
16 Abstract:
17
18 ISA Floppy Driver
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
25
26 conforming to EFI driver model
27
28 Revision History:
29
30 --*/
31
32 #include "IsaFloppy.h"
33
34 LIST_ENTRY gControllerHead = INITIALIZE_LIST_HEAD_VARIABLE(gControllerHead);
35
36 //
37 // ISA Floppy Driver Binding Protocol
38 //
39 EFI_DRIVER_BINDING_PROTOCOL gFdcControllerDriver = {
40 FdcControllerDriverSupported,
41 FdcControllerDriverStart,
42 FdcControllerDriverStop,
43 0xa,
44 NULL,
45 NULL
46 };
47
48 EFI_STATUS
49 EFIAPI
50 FdcControllerDriverSupported (
51 IN EFI_DRIVER_BINDING_PROTOCOL *This,
52 IN EFI_HANDLE Controller,
53 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
54 )
55 /*++
56
57 Routine Description:
58
59 ControllerDriver Protocol Method
60
61 Arguments:
62
63 Returns:
64
65 --*/
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
69 {
70 EFI_STATUS Status;
71 EFI_ISA_IO_PROTOCOL *IsaIo;
72
73 //
74 // Open the ISA I/O Protocol
75 //
76 Status = gBS->OpenProtocol (
77 Controller,
78 &gEfiIsaIoProtocolGuid,
79 (VOID **) &IsaIo,
80 This->DriverBindingHandle,
81 Controller,
82 EFI_OPEN_PROTOCOL_BY_DRIVER
83 );
84 if (EFI_ERROR (Status)) {
85 return Status;
86 }
87 //
88 // Use the ISA I/O Protocol to see if Controller is a Floppy Disk Controller
89 //
90 Status = EFI_SUCCESS;
91 if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) {
92 Status = EFI_UNSUPPORTED;
93 }
94 //
95 // Close the ISA I/O Protocol
96 //
97 gBS->CloseProtocol (
98 Controller,
99 &gEfiIsaIoProtocolGuid,
100 This->DriverBindingHandle,
101 Controller
102 );
103
104 return Status;
105 }
106
107 EFI_STATUS
108 EFIAPI
109 FdcControllerDriverStart (
110 IN EFI_DRIVER_BINDING_PROTOCOL *This,
111 IN EFI_HANDLE Controller,
112 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
113 )
114 /*++
115
116 Routine Description:
117
118 Arguments:
119
120 Returns:
121
122 --*/
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
126 {
127 EFI_STATUS Status;
128 FDC_BLK_IO_DEV *FdcDev;
129 EFI_ISA_IO_PROTOCOL *IsaIo;
130 UINTN Index;
131 LIST_ENTRY *List;
132 BOOLEAN Found;
133 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
134
135 FdcDev = NULL;
136 IsaIo = NULL;
137
138 //
139 // Open the device path protocol
140 //
141 Status = gBS->OpenProtocol (
142 Controller,
143 &gEfiDevicePathProtocolGuid,
144 (VOID **) &ParentDevicePath,
145 This->DriverBindingHandle,
146 Controller,
147 EFI_OPEN_PROTOCOL_BY_DRIVER
148 );
149 if (EFI_ERROR (Status)) {
150 return Status;
151 }
152 //
153 // Report enable progress code
154 //
155 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
156 EFI_PROGRESS_CODE,
157 EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE,
158 ParentDevicePath
159 );
160
161 //
162 // Open the ISA I/O Protocol
163 //
164 Status = gBS->OpenProtocol (
165 Controller,
166 &gEfiIsaIoProtocolGuid,
167 (VOID **) &IsaIo,
168 This->DriverBindingHandle,
169 Controller,
170 EFI_OPEN_PROTOCOL_BY_DRIVER
171 );
172 if (EFI_ERROR (Status)) {
173 goto Done;
174 }
175 //
176 // Allocate the Floppy Disk Controller's Device structure
177 //
178 FdcDev = AllocateZeroPool (sizeof (FDC_BLK_IO_DEV));
179 if (FdcDev == NULL) {
180 goto Done;
181 }
182 //
183 // Initialize the Floppy Disk Controller's Device structure
184 //
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;
193
194 ADD_FLOPPY_NAME (FdcDev);
195
196 //
197 // Look up the base address of the Floppy Disk Controller
198 //
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;
202 }
203 }
204 //
205 // Maintain the list of controller list
206 //
207 Found = FALSE;
208 List = gControllerHead.ForwardLink;
209 while (List != &gControllerHead) {
210 FdcDev->ControllerState = FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List);
211 if (FdcDev->BaseAddress == FdcDev->ControllerState->BaseAddress) {
212 Found = TRUE;
213 break;
214 }
215
216 List = List->ForwardLink;
217 }
218
219 if (!Found) {
220 //
221 // The Controller is new
222 //
223 FdcDev->ControllerState = AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT));
224 if (FdcDev->ControllerState == NULL) {
225 goto Done;
226 }
227
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;
233
234 InsertTailList (&gControllerHead, &FdcDev->ControllerState->Link);
235 }
236 //
237 // Create a timer event for each Floppd Disk Controller.
238 // This timer event is used to control the motor on and off
239 //
240 Status = gBS->CreateEvent (
241 EVT_TIMER | EVT_NOTIFY_SIGNAL,
242 TPL_NOTIFY,
243 FddTimerProc,
244 FdcDev,
245 &FdcDev->Event
246 );
247 if (EFI_ERROR (Status)) {
248 goto Done;
249 }
250 //
251 // Reset the Floppy Disk Controller
252 //
253 if (!FdcDev->ControllerState->FddResetPerformed) {
254 FdcDev->ControllerState->FddResetPerformed = TRUE;
255 FdcDev->ControllerState->FddResetStatus = FddReset (FdcDev);
256 }
257
258 if (EFI_ERROR (FdcDev->ControllerState->FddResetStatus)) {
259 Status = EFI_DEVICE_ERROR;
260 goto Done;
261 }
262
263 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
264 EFI_PROGRESS_CODE,
265 EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT,
266 ParentDevicePath
267 );
268
269 //
270 // Discover the Floppy Drive
271 //
272 Status = DiscoverFddDevice (FdcDev);
273 if (EFI_ERROR (Status)) {
274 Status = EFI_DEVICE_ERROR;
275 goto Done;
276 }
277 //
278 // Install protocol interfaces for the serial device.
279 //
280 Status = gBS->InstallMultipleProtocolInterfaces (
281 &Controller,
282 &gEfiBlockIoProtocolGuid,
283 &FdcDev->BlkIo,
284 NULL
285 );
286
287 FdcDev->ControllerState->NumberOfDrive++;
288
289 Done:
290 if (EFI_ERROR (Status)) {
291
292 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
293 EFI_ERROR_CODE | EFI_ERROR_MINOR,
294 EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR,
295 ParentDevicePath
296 );
297
298 //
299 // Close the device path protocol
300 //
301 gBS->CloseProtocol (
302 Controller,
303 &gEfiDevicePathProtocolGuid,
304 This->DriverBindingHandle,
305 Controller
306 );
307
308 //
309 // Close the ISA I/O Protocol
310 //
311 if (IsaIo != NULL) {
312 gBS->CloseProtocol (
313 Controller,
314 &gEfiIsaIoProtocolGuid,
315 This->DriverBindingHandle,
316 Controller
317 );
318 }
319 //
320 // If a Floppy Disk Controller Device structure was allocated, then free it
321 //
322 if (FdcDev != NULL) {
323 if (FdcDev->Event != NULL) {
324 //
325 // Close the event for turning the motor off
326 //
327 gBS->CloseEvent (FdcDev->Event);
328 }
329
330 FreeUnicodeStringTable (FdcDev->ControllerNameTable);
331 gBS->FreePool (FdcDev);
332 }
333 }
334
335 return Status;
336 }
337
338 EFI_STATUS
339 EFIAPI
340 FdcControllerDriverStop (
341 IN EFI_DRIVER_BINDING_PROTOCOL *This,
342 IN EFI_HANDLE Controller,
343 IN UINTN NumberOfChildren,
344 IN EFI_HANDLE *ChildHandleBuffer
345 )
346 /*++
347
348 Routine Description:
349
350 Arguments:
351
352 Returns:
353
354 --*/
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
360 {
361 EFI_STATUS Status;
362 EFI_BLOCK_IO_PROTOCOL *BlkIo;
363 FDC_BLK_IO_DEV *FdcDev;
364
365 //
366 // Get the Block I/O Protocol on Controller
367 //
368 Status = gBS->OpenProtocol (
369 Controller,
370 &gEfiBlockIoProtocolGuid,
371 (VOID **) &BlkIo,
372 This->DriverBindingHandle,
373 Controller,
374 EFI_OPEN_PROTOCOL_GET_PROTOCOL
375 );
376 if (EFI_ERROR (Status)) {
377 return Status;
378 }
379 //
380 // Get the Floppy Disk Controller's Device structure
381 //
382 FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo);
383
384 //
385 // Report disable progress code
386 //
387 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
388 EFI_PROGRESS_CODE,
389 EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE,
390 FdcDev->DevicePath
391 );
392
393 //
394 // Turn the motor off on the Floppy Disk Controller
395 //
396 FddTimerProc (FdcDev->Event, FdcDev);
397
398 //
399 // Uninstall the Block I/O Protocol
400 //
401 Status = gBS->UninstallProtocolInterface (
402 Controller,
403 &gEfiBlockIoProtocolGuid,
404 &FdcDev->BlkIo
405 );
406 if (EFI_ERROR (Status)) {
407 return Status;
408 }
409 //
410 // Close the device path protocol
411 //
412 gBS->CloseProtocol (
413 Controller,
414 &gEfiDevicePathProtocolGuid,
415 This->DriverBindingHandle,
416 Controller
417 );
418
419 //
420 // Close the ISA I/O Protocol
421 //
422 gBS->CloseProtocol (
423 Controller,
424 &gEfiIsaIoProtocolGuid,
425 This->DriverBindingHandle,
426 Controller
427 );
428
429 //
430 // Free the controller list if needed
431 //
432 FdcDev->ControllerState->NumberOfDrive--;
433
434 //
435 // Close the event for turning the motor off
436 //
437 gBS->CloseEvent (FdcDev->Event);
438
439 //
440 // Free the cache if one was allocated
441 //
442 FdcFreeCache (FdcDev);
443
444 //
445 // Free the Floppy Disk Controller's Device structure
446 //
447 FreeUnicodeStringTable (FdcDev->ControllerNameTable);
448 gBS->FreePool (FdcDev);
449
450 return EFI_SUCCESS;
451 }