Home | History | Annotate | Download | only in IsaFloppyDxe
      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