1 /** @file
2   Include file for ISA Floppy Driver
3 
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #ifndef _ISA_FLOPPY_H_
16 #define _ISA_FLOPPY_H_
17 
18 #include <Uefi.h>
19 
20 #include <Protocol/BlockIo.h>
21 #include <Protocol/IsaIo.h>
22 #include <Protocol/DevicePath.h>
23 #include <Guid/StatusCodeDataTypeId.h>
24 
25 #include <Library/TimerLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/UefiDriverEntryPoint.h>
28 #include <Library/BaseLib.h>
29 #include <Library/UefiLib.h>
30 #include <Library/BaseMemoryLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/UefiBootServicesTableLib.h>
33 #include <Library/ReportStatusCodeLib.h>
34 #include <Library/PcdLib.h>
35 
36 extern EFI_DRIVER_BINDING_PROTOCOL  gFdcControllerDriver;
37 
38 #define STALL_1_SECOND  1000000
39 #define STALL_1_MSECOND 1000
40 
41 #define DATA_IN         1
42 #define DATA_OUT        0
43 #define READ            0
44 #define WRITE           1
45 
46 //
47 // Internal Data Structures
48 //
49 #define FDC_BLK_IO_DEV_SIGNATURE            SIGNATURE_32 ('F', 'B', 'I', 'O')
50 #define FLOPPY_CONTROLLER_CONTEXT_SIGNATURE SIGNATURE_32 ('F', 'D', 'C', 'C')
51 
52 typedef enum {
53   FdcDisk0   = 0,
54   FdcDisk1   = 1,
55   FdcMaxDisk = 2
56 } EFI_FDC_DISK;
57 
58 typedef struct {
59   UINT32          Signature;
60   LIST_ENTRY      Link;
61   BOOLEAN         FddResetPerformed;
62   EFI_STATUS      FddResetStatus;
63   BOOLEAN         NeedRecalibrate;
64   UINT8           NumberOfDrive;
65   UINT16          BaseAddress;
66 } FLOPPY_CONTROLLER_CONTEXT;
67 
68 typedef struct {
69   UINTN                                     Signature;
70   EFI_HANDLE                                Handle;
71   EFI_BLOCK_IO_PROTOCOL                     BlkIo;
72   EFI_BLOCK_IO_MEDIA                        BlkMedia;
73 
74   EFI_ISA_IO_PROTOCOL                       *IsaIo;
75 
76   UINT16                                    BaseAddress;
77 
78   EFI_FDC_DISK                              Disk;
79   UINT8                                     PresentCylinderNumber;
80   UINT8                                     *Cache;
81 
82   EFI_EVENT                                 Event;
83   EFI_UNICODE_STRING_TABLE                  *ControllerNameTable;
84   FLOPPY_CONTROLLER_CONTEXT                 *ControllerState;
85 
86   EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
87 } FDC_BLK_IO_DEV;
88 
89 #include "ComponentName.h"
90 
91 #define FDD_BLK_IO_FROM_THIS(a) CR (a, FDC_BLK_IO_DEV, BlkIo, FDC_BLK_IO_DEV_SIGNATURE)
92 #define FLOPPY_CONTROLLER_FROM_LIST_ENTRY(a) \
93           CR (a, \
94               FLOPPY_CONTROLLER_CONTEXT, \
95               Link, \
96               FLOPPY_CONTROLLER_CONTEXT_SIGNATURE \
97               )
98 
99 #define DISK_1440K_EOT            0x12
100 #define DISK_1440K_GPL            0x1b
101 #define DISK_1440K_DTL            0xff
102 #define DISK_1440K_NUMBER         0x02
103 #define DISK_1440K_MAXTRACKNUM    0x4f
104 #define DISK_1440K_BYTEPERSECTOR  512
105 
106 typedef struct {
107   UINT8 CommandCode;
108   UINT8 DiskHeadSel;
109   UINT8 Cylinder;
110   UINT8 Head;
111   UINT8 Sector;
112   UINT8 Number;
113   UINT8 EndOfTrack;
114   UINT8 GapLength;
115   UINT8 DataLength;
116 } FDD_COMMAND_PACKET1;
117 
118 typedef struct {
119   UINT8 CommandCode;
120   UINT8 DiskHeadSel;
121 } FDD_COMMAND_PACKET2;
122 
123 typedef struct {
124   UINT8 CommandCode;
125   UINT8 SrtHut;
126   UINT8 HltNd;
127 } FDD_SPECIFY_CMD;
128 
129 typedef struct {
130   UINT8 CommandCode;
131   UINT8 DiskHeadSel;
132   UINT8 NewCylinder;
133 } FDD_SEEK_CMD;
134 
135 typedef struct {
136   UINT8 CommandCode;
137   UINT8 DiskHeadSel;
138   UINT8 Cylinder;
139   UINT8 Head;
140   UINT8 Sector;
141   UINT8 EndOfTrack;
142   UINT8 GapLength;
143   UINT8 ScanTestPause;
144 } FDD_SCAN_CMD;
145 
146 typedef struct {
147   UINT8 Status0;
148   UINT8 Status1;
149   UINT8 Status2;
150   UINT8 Cylinder;
151   UINT8 Head;
152   UINT8 Sector;
153   UINT8 Number;
154 } FDD_RESULT_PACKET;
155 
156 //
157 // FDC Registers
158 //
159 //
160 // Digital Output Register address offset
161 //
162 #define FDC_REGISTER_DOR  2
163 
164 //
165 // Main Status Register address offset
166 //
167 #define FDC_REGISTER_MSR  4
168 
169 //
170 // Data Register address offset
171 //
172 #define FDC_REGISTER_DTR  5
173 
174 //
175 // Configuration Control Register(data rate select) address offset
176 //
177 #define FDC_REGISTER_CCR  7
178 
179 //
180 // Digital Input Register(diskchange) address offset
181 //
182 #define FDC_REGISTER_DIR  7
183 
184 
185 //
186 // FDC Register Bit Definitions
187 //
188 //
189 // Digital Out Register(WO)
190 //
191 //
192 // Select Drive: 0=A 1=B
193 //
194 #define SELECT_DRV  BIT0
195 
196 //
197 // Reset FDC
198 //
199 #define RESET_FDC BIT2
200 
201 //
202 // Enable Int & DMA
203 //
204 #define INT_DMA_ENABLE  BIT3
205 
206 //
207 // Turn On Drive A Motor
208 //
209 #define DRVA_MOTOR_ON BIT4
210 
211 //
212 // Turn On Drive B Motor
213 //
214 #define DRVB_MOTOR_ON BIT5
215 
216 //
217 // Main Status Register(RO)
218 //
219 //
220 // Drive A Busy
221 //
222 #define MSR_DAB BIT0
223 
224 //
225 // Drive B Busy
226 //
227 #define MSR_DBB BIT1
228 
229 //
230 // FDC Busy
231 //
232 #define MSR_CB  BIT4
233 
234 //
235 // Non-DMA Mode
236 //
237 #define MSR_NDM BIT5
238 
239 //
240 // Data Input/Output
241 //
242 #define MSR_DIO BIT6
243 
244 //
245 // Request For Master
246 //
247 #define MSR_RQM BIT7
248 
249 //
250 // Configuration Control Register(WO)
251 //
252 //
253 // Data Rate select
254 //
255 #define CCR_DRC (BIT0 | BIT1)
256 
257 //
258 // Digital Input Register(RO)
259 //
260 //
261 // Disk change line
262 //
263 #define DIR_DCL BIT7
264 //
265 // #define CCR_DCL         BIT7      // Diskette change
266 //
267 // 500K
268 //
269 #define DRC_500KBS  0x0
270 
271 //
272 // 300K
273 //
274 #define DRC_300KBS  0x01
275 
276 //
277 // 250K
278 //
279 #define DRC_250KBS  0x02
280 
281 //
282 // FDC Command Code
283 //
284 #define READ_DATA_CMD         0x06
285 #define WRITE_DATA_CMD        0x05
286 #define WRITE_DEL_DATA_CMD    0x09
287 #define READ_DEL_DATA_CMD     0x0C
288 #define READ_TRACK_CMD        0x02
289 #define READ_ID_CMD           0x0A
290 #define FORMAT_TRACK_CMD      0x0D
291 #define SCAN_EQU_CMD          0x11
292 #define SCAN_LOW_EQU_CMD      0x19
293 #define SCAN_HIGH_EQU_CMD     0x1D
294 #define SEEK_CMD              0x0F
295 #define RECALIBRATE_CMD       0x07
296 #define SENSE_INT_STATUS_CMD  0x08
297 #define SPECIFY_CMD           0x03
298 #define SENSE_DRV_STATUS_CMD  0x04
299 
300 //
301 // CMD_MT: Multi_Track Selector
302 // when set , this flag selects the multi-track operating mode.
303 // In this mode, the FDC treats a complete cylinder under head0 and 1
304 // as a single track
305 //
306 #define CMD_MT  BIT7
307 
308 //
309 // CMD_MFM: MFM/FM Mode Selector
310 // A one selects the double density(MFM) mode
311 // A zero selects single density (FM) mode
312 //
313 #define CMD_MFM BIT6
314 
315 //
316 // CMD_SK: Skip Flag
317 // When set to 1, sectors containing a deleted data address mark will
318 // automatically be skipped during the execution of Read Data.
319 // When set to 0, the sector is read or written the same as the read and
320 // write commands.
321 //
322 #define CMD_SK  BIT5
323 
324 //
325 // FDC Status Register Bit Definitions
326 //
327 //
328 // Status Register 0
329 //
330 //
331 // Interrupt Code
332 //
333 #define STS0_IC (BIT7 | BIT6)
334 
335 //
336 // Seek End: the FDC completed a seek or recalibrate command
337 //
338 #define STS0_SE BIT5
339 
340 //
341 // Equipment Check
342 //
343 #define STS0_EC BIT4
344 
345 //
346 // Not Ready(unused), this bit is always 0
347 //
348 #define STS0_NR BIT3
349 
350 //
351 // Head Address: the current head address
352 //
353 #define STS0_HA BIT2
354 
355 //
356 // STS0_US1 & STS0_US0: Drive Select(the current selected drive)
357 //
358 //
359 // Unit Select1
360 //
361 #define STS0_US1  BIT1
362 
363 //
364 // Unit Select0
365 //
366 #define STS0_US0  BIT0
367 
368 //
369 // Status Register 1
370 //
371 //
372 // End of Cylinder
373 //
374 #define STS1_EN BIT7
375 
376 //
377 // BIT6 is unused
378 //
379 //
380 // Data Error: The FDC detected a CRC error in either the ID field or
381 // data field of a sector
382 //
383 #define STS1_DE BIT5
384 
385 //
386 // Overrun/Underrun: Becomes set if FDC does not receive CPU or DMA service
387 // within the required time interval
388 //
389 #define STS1_OR BIT4
390 
391 //
392 // BIT3 is unused
393 //
394 //
395 // No data
396 //
397 #define STS1_ND BIT2
398 
399 //
400 // Not Writable
401 //
402 #define STS1_NW BIT1
403 
404 //
405 // Missing Address Mark
406 //
407 #define STS1_MA BIT0
408 
409 //
410 // Control Mark
411 //
412 #define STS2_CM BIT6
413 
414 //
415 // Data Error in Data Field: The FDC detected a CRC error in the data field
416 //
417 #define STS2_DD BIT5
418 
419 //
420 // Wrong Cylinder: The track address from sector ID field is different from
421 // the track address maintained inside FDC
422 //
423 #define STS2_WC BIT4
424 
425 //
426 // Bad Cylinder
427 //
428 #define STS2_BC BIT1
429 
430 //
431 // Missing Address Mark in Data Field
432 //
433 #define STS2_MD BIT0
434 
435 //
436 // Write Protected
437 //
438 #define STS3_WP BIT6
439 
440 //
441 // Track 0
442 //
443 #define STS3_T0 BIT4
444 
445 //
446 // Head Address
447 //
448 #define STS3_HD BIT2
449 
450 //
451 // STS3_US1 & STS3_US0 : Drive Select
452 //
453 #define STS3_US1  BIT1
454 #define STS3_US0  BIT0
455 
456 //
457 // Status Register 0 Interrupt Code Description
458 //
459 //
460 // Normal Termination of Command
461 //
462 #define IC_NT 0x0
463 
464 //
465 // Abnormal Termination of Command
466 //
467 #define IC_AT 0x40
468 
469 //
470 // Invalid Command
471 //
472 #define IC_IC 0x80
473 
474 //
475 // Abnormal Termination caused by Polling
476 //
477 #define IC_ATRC 0xC0
478 
479 //
480 // EFI Driver Binding Protocol Functions
481 //
482 
483 /**
484   Test controller is a floppy disk drive device
485 
486   @param[in] This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
487   @param[in] Controller           The handle of the controller to test.
488   @param[in] RemainingDevicePath  A pointer to the remaining portion of a device path.
489 
490   @retval EFI_SUCCESS             The device is supported by this driver.
491   @retval EFI_ALREADY_STARTED     The device is already being managed by this driver.
492   @retval EFI_ACCESS_DENIED       The device is already being managed by a different driver
493                                   or an application that requires exclusive access.
494 **/
495 EFI_STATUS
496 EFIAPI
497 FdcControllerDriverSupported (
498   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
499   IN EFI_HANDLE                   Controller,
500   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
501   );
502 
503 /**
504   Start this driver on Controller.
505 
506   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
507   @param[in]  ControllerHandle     The handle of the controller to start. This handle
508                                    must support a protocol interface that supplies
509                                    an I/O abstraction to the driver.
510   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.
511                                    This parameter is ignored by device drivers, and is optional for bus drivers.
512 
513   @retval EFI_SUCCESS              The device was started.
514   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.
515                                    Currently not implemented.
516   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
517   @retval Others                   The driver failded to start the device.
518 **/
519 EFI_STATUS
520 EFIAPI
521 FdcControllerDriverStart (
522   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
523   IN EFI_HANDLE                   Controller,
524   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
525   );
526 
527 /**
528   Stop this driver on ControllerHandle.
529 
530   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
531   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
532                                 support a bus specific I/O protocol for the driver
533                                 to use to stop the device.
534   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
535   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
536                                 if NumberOfChildren is 0.
537 
538   @retval EFI_SUCCESS           The device was stopped.
539   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
540 **/
541 EFI_STATUS
542 EFIAPI
543 FdcControllerDriverStop (
544   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
545   IN EFI_HANDLE                   Controller,
546   IN UINTN                        NumberOfChildren,
547   IN EFI_HANDLE                   *ChildHandleBuffer
548   );
549 
550 //
551 // EFI Block I/O Protocol Functions
552 //
553 
554 /**
555   Reset the Floppy Logic Drive, call the FddReset function.
556 
557   @param This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface
558   @param ExtendedVerification BOOLEAN: Indicate that the driver may perform a more
559                     exhaustive verification operation of the device during
560                     reset, now this par is ignored in this driver
561   @retval  EFI_SUCCESS:      The Floppy Logic Drive is reset
562   @retval  EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly
563                       and can not be reset
564 
565 **/
566 EFI_STATUS
567 EFIAPI
568 FdcReset (
569   IN EFI_BLOCK_IO_PROTOCOL  *This,
570   IN BOOLEAN                ExtendedVerification
571   );
572 
573 /**
574   Flush block via fdd controller.
575 
576   @param  This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface
577   @return EFI_SUCCESS
578 
579 **/
580 EFI_STATUS
581 EFIAPI
582 FddFlushBlocks (
583   IN EFI_BLOCK_IO_PROTOCOL  *This
584   );
585 
586 /**
587   Read the requested number of blocks from the device.
588 
589   @param This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface
590   @param MediaId UINT32:    The media id that the read request is for
591   @param  Lba EFI_LBA:     The starting logic block address to read from on the device
592   @param  BufferSize UINTN:  The size of the Buffer in bytes
593   @param  Buffer VOID *:     A pointer to the destination buffer for the data
594 
595   @retval  EFI_SUCCESS:     The data was read correctly from the device
596   @retval  EFI_DEVICE_ERROR:The device reported an error while attempting to perform
597                      the read operation
598   @retval  EFI_NO_MEDIA:    There is no media in the device
599   @retval  EFI_MEDIA_CHANGED:   The MediaId is not for the current media
600   @retval  EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple of the
601                          intrinsic block size of the device
602   @retval  EFI_INVALID_PARAMETER:The read request contains LBAs that are not valid,
603                           or the buffer is not on proper alignment
604 
605 **/
606 EFI_STATUS
607 EFIAPI
608 FddReadBlocks (
609   IN  EFI_BLOCK_IO_PROTOCOL  *This,
610   IN  UINT32                 MediaId,
611   IN  EFI_LBA                Lba,
612   IN  UINTN                  BufferSize,
613   OUT VOID                   *Buffer
614   );
615 
616 /**
617   Write a specified number of blocks to the device.
618 
619   @param  This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface
620   @param  MediaId UINT32:    The media id that the write request is for
621   @param  Lba EFI_LBA:     The starting logic block address to be written
622   @param  BufferSize UINTN:  The size in bytes in Buffer
623   @param  Buffer VOID *:     A pointer to the source buffer for the data
624 
625   @retval  EFI_SUCCESS:     The data were written correctly to the device
626   @retval  EFI_WRITE_PROTECTED: The device can not be written to
627   @retval  EFI_NO_MEDIA:    There is no media in the device
628   @retval  EFI_MEDIA_CHANGED:   The MediaId is not for the current media
629   @retval  EFI_DEVICE_ERROR:  The device reported an error while attempting to perform
630                        the write operation
631   @retval  EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple of the
632                          intrinsic block size of the device
633   @retval  EFI_INVALID_PARAMETER:The write request contains LBAs that are not valid,
634                           or the buffer is not on proper alignment
635 **/
636 EFI_STATUS
637 EFIAPI
638 FddWriteBlocks (
639   IN EFI_BLOCK_IO_PROTOCOL  *This,
640   IN UINT32                 MediaId,
641   IN EFI_LBA                Lba,
642   IN UINTN                  BufferSize,
643   IN VOID                   *Buffer
644   );
645 
646 //
647 // Prototypes of internal functions
648 //
649 /**
650 
651   Detect the floppy drive is presented or not.
652 
653   @param  FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV
654   @retval EFI_SUCCESS    Drive is presented
655   @retval EFI_NOT_FOUND  Drive is not presented
656 
657 **/
658 EFI_STATUS
659 DiscoverFddDevice (
660   IN FDC_BLK_IO_DEV  *FdcDev
661   );
662 
663 /**
664 
665   Do recalibrate  and see the drive is presented or not.
666   Set the media parameters.
667 
668   @param FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV
669   @return the drive is presented or not
670 
671 **/
672 EFI_STATUS
673 FddIdentify (
674   IN FDC_BLK_IO_DEV  *FdcDev
675   );
676 
677 /**
678 
679   Reset the Floppy Logic Drive.
680 
681   @param  FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV
682 
683   @retval EFI_SUCCESS:    The Floppy Logic Drive is reset
684   @retval EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly and
685                       can not be reset
686 
687 **/
688 EFI_STATUS
689 FddReset (
690   IN FDC_BLK_IO_DEV  *FdcDev
691   );
692 
693 /**
694 
695   Turn the drive's motor on.
696   The drive's motor must be on before any command can be executed.
697 
698   @param  FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV
699 
700   @retval  EFI_SUCCESS:       Turn the drive's motor on successfully
701   @retval  EFI_DEVICE_ERROR:    The drive is busy, so can not turn motor on
702   @retval  EFI_INVALID_PARAMETER: Fail to Set timer(Cancel timer)
703 
704 **/
705 EFI_STATUS
706 MotorOn (
707   IN FDC_BLK_IO_DEV  *FdcDev
708   );
709 
710 /**
711 
712   Set a Timer and when Timer goes off, turn the motor off.
713 
714 
715   @param  FdcDev FDC_BLK_IO_DEV * : A pointer to the Data Structure FDC_BLK_IO_DEV
716 
717   @retval  EFI_SUCCESS:       Set the Timer successfully
718   @retval  EFI_INVALID_PARAMETER: Fail to Set the timer
719 
720 **/
721 EFI_STATUS
722 MotorOff (
723   IN FDC_BLK_IO_DEV  *FdcDev
724   );
725 
726 /**
727   Detect the disk in the drive is changed or not.
728 
729 
730   @param  FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
731 
732   @retval  EFI_SUCCESS:    No disk media change
733   @retval  EFI_DEVICE_ERROR: Fail to do the recalibrate or seek operation
734   @retval  EFI_NO_MEDIA:   No disk in the drive
735   @retval  EFI_MEDIA_CHANGED:  There is a new disk in the drive
736 **/
737 EFI_STATUS
738 DisketChanged (
739   IN FDC_BLK_IO_DEV  *FdcDev
740   );
741 
742 /**
743   Do the Specify command, this command sets DMA operation
744   and the initial values for each of the three internal
745   times: HUT, SRT and HLT.
746 
747   @param FdcDev    Pointer to instance of FDC_BLK_IO_DEV
748 
749   @retval  EFI_SUCCESS:    Execute the Specify command successfully
750   @retval  EFI_DEVICE_ERROR: Fail to execute the command
751 
752 **/
753 EFI_STATUS
754 Specify (
755   IN FDC_BLK_IO_DEV  *FdcDev
756   );
757 
758 /**
759   Set the head of floppy drive to track 0.
760 
761   @param  FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
762   @retval EFI_SUCCESS:    Execute the Recalibrate operation successfully
763   @retval EFI_DEVICE_ERROR: Fail to execute the Recalibrate operation
764 
765 **/
766 EFI_STATUS
767 Recalibrate (
768   IN FDC_BLK_IO_DEV  *FdcDev
769   );
770 
771 /**
772   Set the head of floppy drive to the new cylinder.
773 
774   @param  FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
775   @param  Lba EFI_LBA     : The logic block address want to seek
776 
777   @retval  EFI_SUCCESS:    Execute the Seek operation successfully
778   @retval  EFI_DEVICE_ERROR: Fail to execute the Seek operation
779 
780 **/
781 EFI_STATUS
782 Seek (
783   IN FDC_BLK_IO_DEV  *FdcDev,
784   IN EFI_LBA         Lba
785   );
786 
787 /**
788   Do the Sense Interrupt Status command, this command resets the interrupt signal.
789 
790   @param  FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
791   @param  StatusRegister0 UINT8 *: Be used to save Status Register 0 read from FDC
792   @param  PresentCylinderNumber  UINT8 *: Be used to save present cylinder number
793                                     read from FDC
794 
795   @retval  EFI_SUCCESS:    Execute the Sense Interrupt Status command successfully
796   @retval  EFI_DEVICE_ERROR: Fail to execute the command
797 
798 **/
799 EFI_STATUS
800 SenseIntStatus (
801   IN     FDC_BLK_IO_DEV  *FdcDev,
802   IN OUT UINT8           *StatusRegister0,
803   IN OUT UINT8           *PresentCylinderNumber
804   );
805 
806 /**
807   Do the Sense Drive Status command.
808 
809   @param  FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
810   @param  Lba EFI_LBA     : Logic block address
811 
812   @retval  EFI_SUCCESS:    Execute the Sense Drive Status command successfully
813   @retval  EFI_DEVICE_ERROR: Fail to execute the command
814   @retval  EFI_WRITE_PROTECTED:The disk is write protected
815 
816 **/
817 EFI_STATUS
818 SenseDrvStatus (
819   IN FDC_BLK_IO_DEV  *FdcDev,
820   IN EFI_LBA         Lba
821   );
822 
823 /**
824   Update the disk media properties and if necessary reinstall Block I/O interface.
825 
826   @param  FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
827 
828   @retval  EFI_SUCCESS:    Do the operation successfully
829   @retval  EFI_DEVICE_ERROR: Fail to the operation
830 
831 **/
832 EFI_STATUS
833 DetectMedia (
834   IN FDC_BLK_IO_DEV  *FdcDev
835   );
836 
837 /**
838   Set the data rate and so on.
839 
840   @param  FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
841 
842   @retval EFI_SUCCESS success to set the data rate
843 **/
844 EFI_STATUS
845 Setup (
846   IN FDC_BLK_IO_DEV  *FdcDev
847   );
848 
849 /**
850   Read or Write a number of blocks in the same cylinder.
851 
852   @param  FdcDev      A pointer to Data Structure FDC_BLK_IO_DEV
853   @param  HostAddress device address
854   @param  Lba         The starting logic block address to read from on the device
855   @param  NumberOfBlocks The number of block wanted to be read or write
856   @param  Read        Operation type: read or write
857 
858   @retval EFI_SUCCESS Success operate
859 
860 **/
861 EFI_STATUS
862 ReadWriteDataSector (
863   IN FDC_BLK_IO_DEV  *FdcDev,
864   IN VOID            *HostAddress,
865   IN EFI_LBA         Lba,
866   IN UINTN           NumberOfBlocks,
867   IN BOOLEAN         Read
868   );
869 
870 /**
871   Fill in FDD command's parameter.
872 
873   @param FdcDev   Pointer to instance of FDC_BLK_IO_DEV
874   @param Lba      The starting logic block address to read from on the device
875   @param Command  FDD command
876 
877 **/
878 VOID
879 FillPara (
880   IN FDC_BLK_IO_DEV       *FdcDev,
881   IN EFI_LBA              Lba,
882   IN FDD_COMMAND_PACKET1  *Command
883   );
884 
885 /**
886   Read result byte from Data Register of FDC.
887 
888   @param FdcDev   Pointer to instance of FDC_BLK_IO_DEV
889   @param Pointer  Buffer to store the byte read from FDC
890 
891   @retval EFI_SUCCESS       Read result byte from FDC successfully
892   @retval EFI_DEVICE_ERROR  The FDC is not ready to be read
893 
894 **/
895 EFI_STATUS
896 DataInByte (
897   IN  FDC_BLK_IO_DEV  *FdcDev,
898   OUT UINT8           *Pointer
899   );
900 
901 /**
902   Write command byte to Data Register of FDC.
903 
904   @param FdcDev  Pointer to instance of FDC_BLK_IO_DEV
905   @param Pointer Be used to save command byte written to FDC
906 
907   @retval  EFI_SUCCESS:    Write command byte to FDC successfully
908   @retval  EFI_DEVICE_ERROR: The FDC is not ready to be written
909 
910 **/
911 EFI_STATUS
912 DataOutByte (
913   IN FDC_BLK_IO_DEV  *FdcDev,
914   IN UINT8           *Pointer
915   );
916 
917 /**
918   Detect the specified floppy logic drive is busy or not within a period of time.
919 
920   @param FdcDev           Indicate it is drive A or drive B
921   @param Timeout          The time period for waiting
922 
923   @retval EFI_SUCCESS:  The drive and command are not busy
924   @retval EFI_TIMEOUT:  The drive or command is still busy after a period time that
925                         set by Timeout
926 
927 **/
928 EFI_STATUS
929 FddWaitForBSYClear (
930   IN FDC_BLK_IO_DEV  *FdcDev,
931   IN UINTN           Timeout
932   );
933 
934 /**
935   Determine whether FDC is ready to write or read.
936 
937   @param  FdcDev Pointer to instance of FDC_BLK_IO_DEV
938   @param  Dio BOOLEAN:      Indicate the FDC is waiting to write or read
939   @param  Timeout           The time period for waiting
940 
941   @retval EFI_SUCCESS:  FDC is ready to write or read
942   @retval EFI_NOT_READY:  FDC is not ready within the specified time period
943 
944 **/
945 EFI_STATUS
946 FddDRQReady (
947   IN FDC_BLK_IO_DEV  *FdcDev,
948   IN BOOLEAN         Dio,
949   IN UINTN           Timeout
950   );
951 
952 /**
953   Set FDC control structure's attribute according to result.
954 
955   @param Result  Point to result structure
956   @param FdcDev  FDC control structure
957 
958   @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value
959   @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value
960   @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value
961   @retval EFI_SUCCESS - GC_TODO: Add description for return value
962 
963 **/
964 EFI_STATUS
965 CheckResult (
966   IN     FDD_RESULT_PACKET  *Result,
967   IN OUT FDC_BLK_IO_DEV     *FdcDev
968   );
969 
970 /**
971   Check the drive status information.
972 
973   @param StatusRegister3  the value of Status Register 3
974 
975   @retval EFI_SUCCESS           The disk is not write protected
976   @retval EFI_WRITE_PROTECTED:  The disk is write protected
977 
978 **/
979 EFI_STATUS
980 CheckStatus3 (
981   IN UINT8 StatusRegister3
982   );
983 
984 /**
985   Calculate the number of block in the same cylinder according to Lba.
986 
987   @param FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
988   @param Lba EFI_LBA:      The starting logic block address
989   @param NumberOfBlocks UINTN: The number of blocks
990 
991   @return The number of blocks in the same cylinder which the starting
992         logic block address is Lba
993 
994 **/
995 UINTN
996 GetTransferBlockCount (
997   IN FDC_BLK_IO_DEV  *FdcDev,
998   IN EFI_LBA         Lba,
999   IN UINTN           NumberOfBlocks
1000   );
1001 
1002 /**
1003   When the Timer(2s) off, turn the drive's motor off.
1004 
1005   @param Event EFI_EVENT: Event(the timer) whose notification function is being
1006                      invoked
1007   @param Context VOID *:  Pointer to the notification function's context
1008 
1009 **/
1010 VOID
1011 EFIAPI
1012 FddTimerProc (
1013   IN EFI_EVENT  Event,
1014   IN VOID       *Context
1015   );
1016 
1017 /**
1018   Read I/O port for FDC.
1019 
1020   @param FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
1021   @param Offset The offset address of port
1022 
1023 **/
1024 UINT8
1025 FdcReadPort (
1026   IN FDC_BLK_IO_DEV  *FdcDev,
1027   IN UINT32          Offset
1028   );
1029 
1030 /**
1031   Write I/O port for FDC.
1032 
1033   @param FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
1034   @param Offset The offset address of port
1035   @param Data   Value written to port
1036 
1037 **/
1038 VOID
1039 FdcWritePort (
1040   IN FDC_BLK_IO_DEV  *FdcDev,
1041   IN UINT32          Offset,
1042   IN UINT8           Data
1043   );
1044 
1045 /**
1046   Read or Write a number of blocks to floppy device.
1047 
1048   @param This     Pointer to instance of EFI_BLOCK_IO_PROTOCOL
1049   @param MediaId  The media id of read/write request
1050   @param Lba      The starting logic block address to read from on the device
1051   @param BufferSize The size of the Buffer in bytes
1052   @param Operation   - GC_TODO: add argument description
1053   @param Buffer      - GC_TODO: add argument description
1054 
1055   @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
1056   @retval EFI_SUCCESS - GC_TODO: Add description for return value
1057   @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value
1058   @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value
1059   @retval EFI_NO_MEDIA - GC_TODO: Add description for return value
1060   @retval EFI_MEDIA_CHANGED - GC_TODO: Add description for return value
1061   @retval EFI_WRITE_PROTECTED - GC_TODO: Add description for return value
1062   @retval EFI_BAD_BUFFER_SIZE - GC_TODO: Add description for return value
1063   @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
1064   @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
1065   @retval EFI_SUCCESS - GC_TODO: Add description for return value
1066   @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value
1067   @retval EFI_DEVICE_ERROR - GC_TODO: Add description for return value
1068   @retval EFI_SUCCESS - GC_TODO: Add description for return value
1069 
1070 **/
1071 EFI_STATUS
1072 FddReadWriteBlocks (
1073   IN  EFI_BLOCK_IO_PROTOCOL  *This,
1074   IN  UINT32                 MediaId,
1075   IN  EFI_LBA                Lba,
1076   IN  UINTN                  BufferSize,
1077   IN  BOOLEAN                Operation,
1078   OUT VOID                   *Buffer
1079   );
1080 
1081 /**
1082   Common interface for free cache.
1083 
1084   @param FdcDev  Pointer of FDC_BLK_IO_DEV instance
1085 
1086 **/
1087 VOID
1088 FdcFreeCache (
1089   IN    FDC_BLK_IO_DEV  *FdcDev
1090   );
1091 
1092 #endif
1093 
1094