Home | History | Annotate | Download | only in AtaAtapiPassThru
      1 /** @file
      2   Header file for AHCI mode of ATA host controller.
      3 
      4   Copyright (c) 2010 - 2015, 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 #include "AtaAtapiPassThru.h"
     16 
     17 /**
     18   read a one-byte data from a IDE port.
     19 
     20   @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure
     21   @param  Port   The IDE Port number
     22 
     23   @return  the one-byte data read from IDE port
     24 **/
     25 UINT8
     26 EFIAPI
     27 IdeReadPortB (
     28   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
     29   IN  UINT16                Port
     30   )
     31 {
     32   UINT8 Data;
     33 
     34   ASSERT (PciIo != NULL);
     35 
     36   Data = 0;
     37   //
     38   // perform 1-byte data read from register
     39   //
     40   PciIo->Io.Read (
     41               PciIo,
     42               EfiPciIoWidthUint8,
     43               EFI_PCI_IO_PASS_THROUGH_BAR,
     44               (UINT64) Port,
     45               1,
     46               &Data
     47               );
     48   return Data;
     49 }
     50 
     51 /**
     52   write a 1-byte data to a specific IDE port.
     53 
     54   @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure
     55   @param  Port   The IDE port to be writen
     56   @param  Data   The data to write to the port
     57 **/
     58 VOID
     59 EFIAPI
     60 IdeWritePortB (
     61   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
     62   IN  UINT16                Port,
     63   IN  UINT8                 Data
     64   )
     65 {
     66   ASSERT (PciIo != NULL);
     67 
     68   //
     69   // perform 1-byte data write to register
     70   //
     71   PciIo->Io.Write (
     72               PciIo,
     73               EfiPciIoWidthUint8,
     74               EFI_PCI_IO_PASS_THROUGH_BAR,
     75               (UINT64) Port,
     76               1,
     77               &Data
     78               );
     79 }
     80 
     81 /**
     82   write a 1-word data to a specific IDE port.
     83 
     84   @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure
     85   @param  Port   The IDE port to be writen
     86   @param  Data   The data to write to the port
     87 **/
     88 VOID
     89 EFIAPI
     90 IdeWritePortW (
     91   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
     92   IN  UINT16                Port,
     93   IN  UINT16                Data
     94   )
     95 {
     96   ASSERT (PciIo != NULL);
     97 
     98   //
     99   // perform 1-word data write to register
    100   //
    101   PciIo->Io.Write (
    102               PciIo,
    103               EfiPciIoWidthUint16,
    104               EFI_PCI_IO_PASS_THROUGH_BAR,
    105               (UINT64) Port,
    106               1,
    107               &Data
    108               );
    109 }
    110 
    111 /**
    112   write a 2-word data to a specific IDE port.
    113 
    114   @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure
    115   @param  Port   The IDE port to be writen
    116   @param  Data   The data to write to the port
    117 **/
    118 VOID
    119 EFIAPI
    120 IdeWritePortDW (
    121   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
    122   IN  UINT16                Port,
    123   IN  UINT32                Data
    124   )
    125 {
    126   ASSERT (PciIo != NULL);
    127 
    128   //
    129   // perform 2-word data write to register
    130   //
    131   PciIo->Io.Write (
    132               PciIo,
    133               EfiPciIoWidthUint32,
    134               EFI_PCI_IO_PASS_THROUGH_BAR,
    135               (UINT64) Port,
    136               1,
    137               &Data
    138               );
    139 }
    140 
    141 /**
    142   Write multiple words of data to the IDE data port.
    143   Call the IO abstraction once to do the complete read,
    144   not one word at a time
    145 
    146   @param  PciIo      A pointer to EFI_PCI_IO_PROTOCOL data structure
    147   @param  Port       IO port to read
    148   @param  Count      No. of UINT16's to read
    149   @param  Buffer     Pointer to the data buffer for read
    150 
    151 **/
    152 VOID
    153 EFIAPI
    154 IdeWritePortWMultiple (
    155   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
    156   IN  UINT16                Port,
    157   IN  UINTN                 Count,
    158   IN  VOID                  *Buffer
    159   )
    160 {
    161   ASSERT (PciIo  != NULL);
    162   ASSERT (Buffer != NULL);
    163 
    164   //
    165   // perform UINT16 data write to the FIFO
    166   //
    167   PciIo->Io.Write (
    168               PciIo,
    169               EfiPciIoWidthFifoUint16,
    170               EFI_PCI_IO_PASS_THROUGH_BAR,
    171               (UINT64) Port,
    172               Count,
    173               (UINT16 *) Buffer
    174               );
    175 
    176 }
    177 
    178 /**
    179   Reads multiple words of data from the IDE data port.
    180   Call the IO abstraction once to do the complete read,
    181   not one word at a time
    182 
    183   @param  PciIo    A pointer to EFI_PCI_IO_PROTOCOL data structure
    184   @param  Port     IO port to read
    185   @param  Count    Number of UINT16's to read
    186   @param  Buffer   Pointer to the data buffer for read
    187 
    188 **/
    189 VOID
    190 EFIAPI
    191 IdeReadPortWMultiple (
    192   IN  EFI_PCI_IO_PROTOCOL   *PciIo,
    193   IN  UINT16                Port,
    194   IN  UINTN                 Count,
    195   IN  VOID                  *Buffer
    196   )
    197 {
    198   ASSERT (PciIo  != NULL);
    199   ASSERT (Buffer != NULL);
    200 
    201   //
    202   // Perform UINT16 data read from FIFO
    203   //
    204   PciIo->Io.Read (
    205               PciIo,
    206               EfiPciIoWidthFifoUint16,
    207               EFI_PCI_IO_PASS_THROUGH_BAR,
    208               (UINT64) Port,
    209               Count,
    210               (UINT16 *) Buffer
    211               );
    212 
    213 }
    214 
    215 /**
    216   This function is used to analyze the Status Register and print out
    217   some debug information and if there is ERR bit set in the Status
    218   Register, the Error Register's value is also be parsed and print out.
    219 
    220   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    221   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    222   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
    223 
    224 **/
    225 VOID
    226 EFIAPI
    227 DumpAllIdeRegisters (
    228   IN     EFI_PCI_IO_PROTOCOL      *PciIo,
    229   IN     EFI_IDE_REGISTERS        *IdeRegisters,
    230   IN OUT EFI_ATA_STATUS_BLOCK     *AtaStatusBlock
    231   )
    232 {
    233   EFI_ATA_STATUS_BLOCK StatusBlock;
    234 
    235   ASSERT (PciIo != NULL);
    236   ASSERT (IdeRegisters != NULL);
    237 
    238   ZeroMem (&StatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
    239 
    240   StatusBlock.AtaStatus          = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
    241   StatusBlock.AtaError           = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
    242   StatusBlock.AtaSectorCount     = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
    243   StatusBlock.AtaSectorCountExp  = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
    244   StatusBlock.AtaSectorNumber    = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
    245   StatusBlock.AtaSectorNumberExp = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
    246   StatusBlock.AtaCylinderLow     = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
    247   StatusBlock.AtaCylinderLowExp  = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
    248   StatusBlock.AtaCylinderHigh    = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
    249   StatusBlock.AtaCylinderHighExp = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
    250   StatusBlock.AtaDeviceHead      = IdeReadPortB (PciIo, IdeRegisters->Head);
    251 
    252   if (AtaStatusBlock != NULL) {
    253     //
    254     // Dump the content of all ATA registers.
    255     //
    256     CopyMem (AtaStatusBlock, &StatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
    257   }
    258 
    259   DEBUG_CODE_BEGIN ();
    260   if ((StatusBlock.AtaStatus & ATA_STSREG_DWF) != 0) {
    261     DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock.AtaStatus));
    262   }
    263 
    264   if ((StatusBlock.AtaStatus & ATA_STSREG_CORR) != 0) {
    265     DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock.AtaStatus));
    266   }
    267 
    268   if ((StatusBlock.AtaStatus & ATA_STSREG_ERR) != 0) {
    269     if ((StatusBlock.AtaError & ATA_ERRREG_BBK) != 0) {
    270       DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock.AtaError));
    271     }
    272 
    273     if ((StatusBlock.AtaError & ATA_ERRREG_UNC) != 0) {
    274       DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock.AtaError));
    275     }
    276 
    277     if ((StatusBlock.AtaError & ATA_ERRREG_MC) != 0) {
    278       DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock.AtaError));
    279     }
    280 
    281     if ((StatusBlock.AtaError & ATA_ERRREG_ABRT) != 0) {
    282       DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock.AtaError));
    283     }
    284 
    285     if ((StatusBlock.AtaError & ATA_ERRREG_TK0NF) != 0) {
    286       DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock.AtaError));
    287     }
    288 
    289     if ((StatusBlock.AtaError & ATA_ERRREG_AMNF) != 0) {
    290       DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock.AtaError));
    291     }
    292   }
    293   DEBUG_CODE_END ();
    294 }
    295 
    296 /**
    297   This function is used to analyze the Status Register at the condition that BSY is zero.
    298   if there is ERR bit set in the Status Register, then return error.
    299 
    300   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    301   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    302 
    303   @retval EFI_SUCCESS       No err information in the Status Register.
    304   @retval EFI_DEVICE_ERROR  Any err information in the Status Register.
    305 
    306 **/
    307 EFI_STATUS
    308 EFIAPI
    309 CheckStatusRegister (
    310   IN  EFI_PCI_IO_PROTOCOL      *PciIo,
    311   IN  EFI_IDE_REGISTERS        *IdeRegisters
    312   )
    313 {
    314   UINT8           StatusRegister;
    315 
    316   ASSERT (PciIo != NULL);
    317   ASSERT (IdeRegisters != NULL);
    318 
    319   StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
    320 
    321   if ((StatusRegister & ATA_STSREG_BSY) == 0) {
    322     if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {
    323       return EFI_SUCCESS;
    324     } else {
    325       return EFI_DEVICE_ERROR;
    326     }
    327   }
    328   return EFI_SUCCESS;
    329 }
    330 
    331 /**
    332   This function is used to poll for the DRQ bit clear in the Status
    333   Register. DRQ is cleared when the device is finished transferring data.
    334   So this function is called after data transfer is finished.
    335 
    336   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    337   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    338   @param Timeout          The time to complete the command, uses 100ns as a unit.
    339 
    340   @retval EFI_SUCCESS     DRQ bit clear within the time out.
    341 
    342   @retval EFI_TIMEOUT     DRQ bit not clear within the time out.
    343 
    344   @note
    345   Read Status Register will clear interrupt status.
    346 
    347 **/
    348 EFI_STATUS
    349 EFIAPI
    350 DRQClear (
    351   IN  EFI_PCI_IO_PROTOCOL       *PciIo,
    352   IN  EFI_IDE_REGISTERS         *IdeRegisters,
    353   IN  UINT64                    Timeout
    354   )
    355 {
    356   UINT64  Delay;
    357   UINT8   StatusRegister;
    358   BOOLEAN InfiniteWait;
    359 
    360   ASSERT (PciIo != NULL);
    361   ASSERT (IdeRegisters != NULL);
    362 
    363   if (Timeout == 0) {
    364     InfiniteWait = TRUE;
    365   } else {
    366     InfiniteWait = FALSE;
    367   }
    368 
    369   Delay = DivU64x32(Timeout, 1000) + 1;
    370   do {
    371     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
    372 
    373     //
    374     // Wait for BSY == 0, then judge if DRQ is clear
    375     //
    376     if ((StatusRegister & ATA_STSREG_BSY) == 0) {
    377       if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
    378         return EFI_DEVICE_ERROR;
    379       } else {
    380         return EFI_SUCCESS;
    381       }
    382     }
    383 
    384     //
    385     // Stall for 100 microseconds.
    386     //
    387     MicroSecondDelay (100);
    388 
    389     Delay--;
    390 
    391   } while (InfiniteWait || (Delay > 0));
    392 
    393   return EFI_TIMEOUT;
    394 }
    395 /**
    396   This function is used to poll for the DRQ bit clear in the Alternate
    397   Status Register. DRQ is cleared when the device is finished
    398   transferring data. So this function is called after data transfer
    399   is finished.
    400 
    401   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    402   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    403   @param Timeout          The time to complete the command, uses 100ns as a unit.
    404 
    405   @retval EFI_SUCCESS     DRQ bit clear within the time out.
    406 
    407   @retval EFI_TIMEOUT     DRQ bit not clear within the time out.
    408   @note   Read Alternate Status Register will not clear interrupt status.
    409 
    410 **/
    411 EFI_STATUS
    412 EFIAPI
    413 DRQClear2 (
    414   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
    415   IN  EFI_IDE_REGISTERS    *IdeRegisters,
    416   IN  UINT64               Timeout
    417   )
    418 {
    419   UINT64  Delay;
    420   UINT8   AltRegister;
    421   BOOLEAN InfiniteWait;
    422 
    423   ASSERT (PciIo != NULL);
    424   ASSERT (IdeRegisters != NULL);
    425 
    426   if (Timeout == 0) {
    427     InfiniteWait = TRUE;
    428   } else {
    429     InfiniteWait = FALSE;
    430   }
    431 
    432   Delay = DivU64x32(Timeout, 1000) + 1;
    433   do {
    434     AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
    435 
    436     //
    437     // Wait for BSY == 0, then judge if DRQ is clear
    438     //
    439     if ((AltRegister & ATA_STSREG_BSY) == 0) {
    440       if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
    441         return EFI_DEVICE_ERROR;
    442       } else {
    443         return EFI_SUCCESS;
    444       }
    445     }
    446 
    447     //
    448     // Stall for 100 microseconds.
    449     //
    450     MicroSecondDelay (100);
    451 
    452     Delay--;
    453 
    454   } while (InfiniteWait || (Delay > 0));
    455 
    456   return EFI_TIMEOUT;
    457 }
    458 
    459 /**
    460   This function is used to poll for the DRQ bit set in the
    461   Status Register.
    462   DRQ is set when the device is ready to transfer data. So this function
    463   is called after the command is sent to the device and before required
    464   data is transferred.
    465 
    466   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    467   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    468   @param Timeout          The time to complete the command, uses 100ns as a unit.
    469 
    470   @retval EFI_SUCCESS           BSY bit cleared and DRQ bit set within the
    471                                 timeout.
    472 
    473   @retval EFI_TIMEOUT           BSY bit not cleared within the timeout.
    474 
    475   @retval EFI_ABORTED           Polling abandoned due to command abort.
    476 
    477   @retval EFI_DEVICE_ERROR      Polling abandoned due to a non-abort error.
    478 
    479   @retval EFI_NOT_READY         BSY bit cleared within timeout, and device
    480                                 reported "command complete" by clearing DRQ
    481                                 bit.
    482 
    483   @note  Read Status Register will clear interrupt status.
    484 
    485 **/
    486 EFI_STATUS
    487 EFIAPI
    488 DRQReady (
    489   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
    490   IN  EFI_IDE_REGISTERS    *IdeRegisters,
    491   IN  UINT64               Timeout
    492   )
    493 {
    494   UINT64  Delay;
    495   UINT8   StatusRegister;
    496   UINT8   ErrorRegister;
    497   BOOLEAN InfiniteWait;
    498 
    499   ASSERT (PciIo != NULL);
    500   ASSERT (IdeRegisters != NULL);
    501 
    502   if (Timeout == 0) {
    503     InfiniteWait = TRUE;
    504   } else {
    505     InfiniteWait = FALSE;
    506   }
    507 
    508   Delay = DivU64x32(Timeout, 1000) + 1;
    509   do {
    510     //
    511     // Read Status Register will clear interrupt
    512     //
    513     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
    514 
    515     //
    516     // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
    517     //
    518     if ((StatusRegister & ATA_STSREG_BSY) == 0) {
    519       if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
    520         ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
    521 
    522         if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
    523           return EFI_ABORTED;
    524         }
    525         return EFI_DEVICE_ERROR;
    526       }
    527 
    528       if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
    529         return EFI_SUCCESS;
    530       } else {
    531         return EFI_NOT_READY;
    532       }
    533     }
    534 
    535     //
    536     // Stall for 100 microseconds.
    537     //
    538     MicroSecondDelay (100);
    539 
    540     Delay--;
    541   } while (InfiniteWait || (Delay > 0));
    542 
    543   return EFI_TIMEOUT;
    544 }
    545 /**
    546   This function is used to poll for the DRQ bit set in the Alternate Status Register.
    547   DRQ is set when the device is ready to transfer data. So this function is called after
    548   the command is sent to the device and before required data is transferred.
    549 
    550   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    551   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    552   @param Timeout          The time to complete the command, uses 100ns as a unit.
    553 
    554   @retval EFI_SUCCESS           BSY bit cleared and DRQ bit set within the
    555                                 timeout.
    556 
    557   @retval EFI_TIMEOUT           BSY bit not cleared within the timeout.
    558 
    559   @retval EFI_ABORTED           Polling abandoned due to command abort.
    560 
    561   @retval EFI_DEVICE_ERROR      Polling abandoned due to a non-abort error.
    562 
    563   @retval EFI_NOT_READY         BSY bit cleared within timeout, and device
    564                                 reported "command complete" by clearing DRQ
    565                                 bit.
    566 
    567   @note  Read Alternate Status Register will not clear interrupt status.
    568 
    569 **/
    570 EFI_STATUS
    571 EFIAPI
    572 DRQReady2 (
    573   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
    574   IN  EFI_IDE_REGISTERS    *IdeRegisters,
    575   IN  UINT64               Timeout
    576   )
    577 {
    578   UINT64  Delay;
    579   UINT8   AltRegister;
    580   UINT8   ErrorRegister;
    581   BOOLEAN InfiniteWait;
    582 
    583   ASSERT (PciIo != NULL);
    584   ASSERT (IdeRegisters != NULL);
    585 
    586   if (Timeout == 0) {
    587     InfiniteWait = TRUE;
    588   } else {
    589     InfiniteWait = FALSE;
    590   }
    591 
    592   Delay = DivU64x32(Timeout, 1000) + 1;
    593 
    594   do {
    595     //
    596     // Read Alternate Status Register will not clear interrupt status
    597     //
    598     AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
    599     //
    600     // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
    601     //
    602     if ((AltRegister & ATA_STSREG_BSY) == 0) {
    603       if ((AltRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
    604         ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
    605 
    606         if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
    607           return EFI_ABORTED;
    608         }
    609         return EFI_DEVICE_ERROR;
    610       }
    611 
    612       if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {
    613         return EFI_SUCCESS;
    614       } else {
    615         return EFI_NOT_READY;
    616       }
    617     }
    618 
    619     //
    620     // Stall for 100 microseconds.
    621     //
    622     MicroSecondDelay (100);
    623 
    624     Delay--;
    625   } while (InfiniteWait || (Delay > 0));
    626 
    627   return EFI_TIMEOUT;
    628 }
    629 
    630 /**
    631   This function is used to poll for the DRDY bit set in the Status Register. DRDY
    632   bit is set when the device is ready to accept command. Most ATA commands must be
    633   sent after DRDY set except the ATAPI Packet Command.
    634 
    635   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    636   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    637   @param Timeout          The time to complete the command, uses 100ns as a unit.
    638 
    639   @retval EFI_SUCCESS         DRDY bit set within the time out.
    640   @retval EFI_TIMEOUT         DRDY bit not set within the time out.
    641 
    642   @note  Read Status Register will clear interrupt status.
    643 **/
    644 EFI_STATUS
    645 EFIAPI
    646 DRDYReady (
    647   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
    648   IN  EFI_IDE_REGISTERS    *IdeRegisters,
    649   IN  UINT64               Timeout
    650   )
    651 {
    652   UINT64  Delay;
    653   UINT8   StatusRegister;
    654   UINT8   ErrorRegister;
    655   BOOLEAN InfiniteWait;
    656 
    657   ASSERT (PciIo != NULL);
    658   ASSERT (IdeRegisters != NULL);
    659 
    660   if (Timeout == 0) {
    661     InfiniteWait = TRUE;
    662   } else {
    663     InfiniteWait = FALSE;
    664   }
    665 
    666   Delay = DivU64x32(Timeout, 1000) + 1;
    667   do {
    668     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
    669     //
    670     // Wait for BSY == 0, then judge if DRDY is set or ERR is set
    671     //
    672     if ((StatusRegister & ATA_STSREG_BSY) == 0) {
    673       if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
    674         ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
    675 
    676         if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
    677           return EFI_ABORTED;
    678         }
    679         return EFI_DEVICE_ERROR;
    680       }
    681 
    682       if ((StatusRegister & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) {
    683         return EFI_SUCCESS;
    684       } else {
    685         return EFI_DEVICE_ERROR;
    686       }
    687     }
    688 
    689     //
    690     // Stall for 100 microseconds.
    691     //
    692     MicroSecondDelay (100);
    693 
    694     Delay--;
    695   } while (InfiniteWait || (Delay > 0));
    696 
    697   return EFI_TIMEOUT;
    698 }
    699 
    700 /**
    701   This function is used to poll for the DRDY bit set in the Alternate Status Register.
    702   DRDY bit is set when the device is ready to accept command. Most ATA commands must
    703   be sent after DRDY set except the ATAPI Packet Command.
    704 
    705   @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.
    706   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    707   @param Timeout          The time to complete the command, uses 100ns as a unit.
    708 
    709   @retval EFI_SUCCESS      DRDY bit set within the time out.
    710   @retval EFI_TIMEOUT      DRDY bit not set within the time out.
    711 
    712   @note  Read Alternate Status Register will clear interrupt status.
    713 
    714 **/
    715 EFI_STATUS
    716 EFIAPI
    717 DRDYReady2 (
    718   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
    719   IN  EFI_IDE_REGISTERS    *IdeRegisters,
    720   IN  UINT64               Timeout
    721   )
    722 {
    723   UINT64  Delay;
    724   UINT8   AltRegister;
    725   UINT8   ErrorRegister;
    726   BOOLEAN InfiniteWait;
    727 
    728   ASSERT (PciIo != NULL);
    729   ASSERT (IdeRegisters != NULL);
    730 
    731   if (Timeout == 0) {
    732     InfiniteWait = TRUE;
    733   } else {
    734     InfiniteWait = FALSE;
    735   }
    736 
    737   Delay = DivU64x32(Timeout, 1000) + 1;
    738   do {
    739     AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
    740     //
    741     // Wait for BSY == 0, then judge if DRDY is set or ERR is set
    742     //
    743     if ((AltRegister & ATA_STSREG_BSY) == 0) {
    744       if ((AltRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {
    745         ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
    746 
    747         if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {
    748           return EFI_ABORTED;
    749         }
    750         return EFI_DEVICE_ERROR;
    751       }
    752 
    753       if ((AltRegister & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) {
    754         return EFI_SUCCESS;
    755       } else {
    756         return EFI_DEVICE_ERROR;
    757       }
    758     }
    759 
    760     //
    761     // Stall for 100 microseconds.
    762     //
    763     MicroSecondDelay (100);
    764 
    765     Delay--;
    766   } while (InfiniteWait || (Delay > 0));
    767 
    768   return EFI_TIMEOUT;
    769 }
    770 
    771 /**
    772   This function is used to poll for the BSY bit clear in the Status Register. BSY
    773   is clear when the device is not busy. Every command must be sent after device is not busy.
    774 
    775   @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
    776   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    777   @param Timeout          The time to complete the command, uses 100ns as a unit.
    778 
    779   @retval EFI_SUCCESS          BSY bit clear within the time out.
    780   @retval EFI_TIMEOUT          BSY bit not clear within the time out.
    781 
    782   @note Read Status Register will clear interrupt status.
    783 **/
    784 EFI_STATUS
    785 EFIAPI
    786 WaitForBSYClear (
    787   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
    788   IN  EFI_IDE_REGISTERS    *IdeRegisters,
    789   IN  UINT64               Timeout
    790   )
    791 {
    792   UINT64  Delay;
    793   UINT8   StatusRegister;
    794   BOOLEAN InfiniteWait;
    795 
    796   ASSERT (PciIo != NULL);
    797   ASSERT (IdeRegisters != NULL);
    798 
    799   if (Timeout == 0) {
    800     InfiniteWait = TRUE;
    801   } else {
    802     InfiniteWait = FALSE;
    803   }
    804 
    805   Delay = DivU64x32(Timeout, 1000) + 1;
    806   do {
    807     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
    808 
    809     if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {
    810       return EFI_SUCCESS;
    811     }
    812 
    813     //
    814     // Stall for 100 microseconds.
    815     //
    816     MicroSecondDelay (100);
    817 
    818     Delay--;
    819 
    820   } while (InfiniteWait || (Delay > 0));
    821 
    822   return EFI_TIMEOUT;
    823 }
    824 
    825 /**
    826   This function is used to poll for the BSY bit clear in the Status Register. BSY
    827   is clear when the device is not busy. Every command must be sent after device is not busy.
    828 
    829   @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
    830   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
    831   @param Timeout          The time to complete the command, uses 100ns as a unit.
    832 
    833   @retval EFI_SUCCESS          BSY bit clear within the time out.
    834   @retval EFI_TIMEOUT          BSY bit not clear within the time out.
    835 
    836   @note Read Status Register will clear interrupt status.
    837 **/
    838 EFI_STATUS
    839 EFIAPI
    840 WaitForBSYClear2 (
    841   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
    842   IN  EFI_IDE_REGISTERS    *IdeRegisters,
    843   IN  UINT64               Timeout
    844   )
    845 {
    846   UINT64  Delay;
    847   UINT8   AltStatusRegister;
    848   BOOLEAN InfiniteWait;
    849 
    850   ASSERT (PciIo != NULL);
    851   ASSERT (IdeRegisters != NULL);
    852 
    853   if (Timeout == 0) {
    854     InfiniteWait = TRUE;
    855   } else {
    856     InfiniteWait = FALSE;
    857   }
    858 
    859   Delay = DivU64x32(Timeout, 1000) + 1;
    860   do {
    861     AltStatusRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
    862 
    863     if ((AltStatusRegister & ATA_STSREG_BSY) == 0x00) {
    864       return EFI_SUCCESS;
    865     }
    866 
    867     //
    868     // Stall for 100 microseconds.
    869     //
    870     MicroSecondDelay (100);
    871 
    872     Delay--;
    873 
    874   } while (InfiniteWait || (Delay > 0));
    875 
    876   return EFI_TIMEOUT;
    877 }
    878 
    879 /**
    880   Get IDE i/o port registers' base addresses by mode.
    881 
    882   In 'Compatibility' mode, use fixed addresses.
    883   In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
    884   Configuration Space.
    885 
    886   The steps to get IDE i/o port registers' base addresses for each channel
    887   as follows:
    888 
    889   1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
    890   controller's Configuration Space to determine the operating mode.
    891 
    892   2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
    893    ___________________________________________
    894   |           | Command Block | Control Block |
    895   |  Channel  |   Registers   |   Registers   |
    896   |___________|_______________|_______________|
    897   |  Primary  |  1F0h - 1F7h  |  3F6h - 3F7h  |
    898   |___________|_______________|_______________|
    899   | Secondary |  170h - 177h  |  376h - 377h  |
    900   |___________|_______________|_______________|
    901 
    902   Table 1. Compatibility resource mappings
    903 
    904   b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
    905   in IDE controller's PCI Configuration Space, shown in the Table 2 below.
    906    ___________________________________________________
    907   |           |   Command Block   |   Control Block   |
    908   |  Channel  |     Registers     |     Registers     |
    909   |___________|___________________|___________________|
    910   |  Primary  | BAR at offset 0x10| BAR at offset 0x14|
    911   |___________|___________________|___________________|
    912   | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
    913   |___________|___________________|___________________|
    914 
    915   Table 2. BARs for Register Mapping
    916 
    917   @param[in]      PciIo          Pointer to the EFI_PCI_IO_PROTOCOL instance
    918   @param[in, out] IdeRegisters    Pointer to EFI_IDE_REGISTERS which is used to
    919                                  store the IDE i/o port registers' base addresses
    920 
    921   @retval EFI_UNSUPPORTED        Return this value when the BARs is not IO type
    922   @retval EFI_SUCCESS            Get the Base address successfully
    923   @retval Other                  Read the pci configureation data error
    924 
    925 **/
    926 EFI_STATUS
    927 EFIAPI
    928 GetIdeRegisterIoAddr (
    929   IN     EFI_PCI_IO_PROTOCOL         *PciIo,
    930   IN OUT EFI_IDE_REGISTERS           *IdeRegisters
    931   )
    932 {
    933   EFI_STATUS        Status;
    934   PCI_TYPE00        PciData;
    935   UINT16            CommandBlockBaseAddr;
    936   UINT16            ControlBlockBaseAddr;
    937   UINT16            BusMasterBaseAddr;
    938 
    939   if ((PciIo == NULL) || (IdeRegisters == NULL)) {
    940     return EFI_INVALID_PARAMETER;
    941   }
    942 
    943   Status = PciIo->Pci.Read (
    944                         PciIo,
    945                         EfiPciIoWidthUint8,
    946                         0,
    947                         sizeof (PciData),
    948                         &PciData
    949                         );
    950 
    951   if (EFI_ERROR (Status)) {
    952     return Status;
    953   }
    954 
    955   BusMasterBaseAddr    = (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));
    956 
    957   if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
    958     CommandBlockBaseAddr = 0x1f0;
    959     ControlBlockBaseAddr = 0x3f6;
    960   } else {
    961     //
    962     // The BARs should be of IO type
    963     //
    964     if ((PciData.Device.Bar[0] & BIT0) == 0 ||
    965         (PciData.Device.Bar[1] & BIT0) == 0) {
    966       return EFI_UNSUPPORTED;
    967     }
    968 
    969     CommandBlockBaseAddr = (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);
    970     ControlBlockBaseAddr = (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);
    971   }
    972 
    973   //
    974   // Calculate IDE primary channel I/O register base address.
    975   //
    976   IdeRegisters[EfiIdePrimary].Data              = CommandBlockBaseAddr;
    977   IdeRegisters[EfiIdePrimary].ErrOrFeature      = (UINT16) (CommandBlockBaseAddr + 0x01);
    978   IdeRegisters[EfiIdePrimary].SectorCount       = (UINT16) (CommandBlockBaseAddr + 0x02);
    979   IdeRegisters[EfiIdePrimary].SectorNumber      = (UINT16) (CommandBlockBaseAddr + 0x03);
    980   IdeRegisters[EfiIdePrimary].CylinderLsb       = (UINT16) (CommandBlockBaseAddr + 0x04);
    981   IdeRegisters[EfiIdePrimary].CylinderMsb       = (UINT16) (CommandBlockBaseAddr + 0x05);
    982   IdeRegisters[EfiIdePrimary].Head              = (UINT16) (CommandBlockBaseAddr + 0x06);
    983   IdeRegisters[EfiIdePrimary].CmdOrStatus       = (UINT16) (CommandBlockBaseAddr + 0x07);
    984   IdeRegisters[EfiIdePrimary].AltOrDev          = ControlBlockBaseAddr;
    985   IdeRegisters[EfiIdePrimary].BusMasterBaseAddr = BusMasterBaseAddr;
    986 
    987   if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {
    988     CommandBlockBaseAddr = 0x170;
    989     ControlBlockBaseAddr = 0x376;
    990   } else {
    991     //
    992     // The BARs should be of IO type
    993     //
    994     if ((PciData.Device.Bar[2] & BIT0) == 0 ||
    995         (PciData.Device.Bar[3] & BIT0) == 0) {
    996       return EFI_UNSUPPORTED;
    997     }
    998 
    999     CommandBlockBaseAddr = (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);
   1000     ControlBlockBaseAddr = (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);
   1001   }
   1002 
   1003   //
   1004   // Calculate IDE secondary channel I/O register base address.
   1005   //
   1006   IdeRegisters[EfiIdeSecondary].Data              = CommandBlockBaseAddr;
   1007   IdeRegisters[EfiIdeSecondary].ErrOrFeature      = (UINT16) (CommandBlockBaseAddr + 0x01);
   1008   IdeRegisters[EfiIdeSecondary].SectorCount       = (UINT16) (CommandBlockBaseAddr + 0x02);
   1009   IdeRegisters[EfiIdeSecondary].SectorNumber      = (UINT16) (CommandBlockBaseAddr + 0x03);
   1010   IdeRegisters[EfiIdeSecondary].CylinderLsb       = (UINT16) (CommandBlockBaseAddr + 0x04);
   1011   IdeRegisters[EfiIdeSecondary].CylinderMsb       = (UINT16) (CommandBlockBaseAddr + 0x05);
   1012   IdeRegisters[EfiIdeSecondary].Head              = (UINT16) (CommandBlockBaseAddr + 0x06);
   1013   IdeRegisters[EfiIdeSecondary].CmdOrStatus       = (UINT16) (CommandBlockBaseAddr + 0x07);
   1014   IdeRegisters[EfiIdeSecondary].AltOrDev          = ControlBlockBaseAddr;
   1015   IdeRegisters[EfiIdeSecondary].BusMasterBaseAddr = (UINT16) (BusMasterBaseAddr + 0x8);
   1016 
   1017   return EFI_SUCCESS;
   1018 }
   1019 
   1020 /**
   1021   This function is used to implement the Soft Reset on the specified device. But,
   1022   the ATA Soft Reset mechanism is so strong a reset method that it will force
   1023   resetting on both devices connected to the same cable.
   1024 
   1025   It is called by IdeBlkIoReset(), a interface function of Block
   1026   I/O protocol.
   1027 
   1028   This function can also be used by the ATAPI device to perform reset when
   1029   ATAPI Reset command is failed.
   1030 
   1031   @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   1032   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
   1033   @param Timeout          The time to complete the command, uses 100ns as a unit.
   1034 
   1035   @retval EFI_SUCCESS       Soft reset completes successfully.
   1036   @retval EFI_DEVICE_ERROR  Any step during the reset process is failed.
   1037 
   1038   @note  The registers initial values after ATA soft reset are different
   1039          to the ATA device and ATAPI device.
   1040 **/
   1041 EFI_STATUS
   1042 EFIAPI
   1043 AtaSoftReset (
   1044   IN  EFI_PCI_IO_PROTOCOL  *PciIo,
   1045   IN  EFI_IDE_REGISTERS    *IdeRegisters,
   1046   IN  UINT64               Timeout
   1047   )
   1048 {
   1049   UINT8 DeviceControl;
   1050 
   1051   DeviceControl = 0;
   1052   //
   1053   // disable Interrupt and set SRST bit to initiate soft reset
   1054   //
   1055   DeviceControl = ATA_CTLREG_SRST | ATA_CTLREG_IEN_L;
   1056 
   1057   IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
   1058 
   1059   //
   1060   // SRST should assert for at least 5 us, we use 10 us for
   1061   // better compatibility
   1062   //
   1063   MicroSecondDelay (10);
   1064 
   1065   //
   1066   // Enable interrupt to support UDMA, and clear SRST bit
   1067   //
   1068   DeviceControl = 0;
   1069   IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
   1070 
   1071   //
   1072   // Wait for at least 10 ms to check BSY status, we use 10 ms
   1073   // for better compatibility
   1074   //
   1075   MicroSecondDelay (10000);
   1076 
   1077   //
   1078   // slave device needs at most 31ms to clear BSY
   1079   //
   1080   if (WaitForBSYClear (PciIo, IdeRegisters, Timeout) == EFI_TIMEOUT) {
   1081     return EFI_DEVICE_ERROR;
   1082   }
   1083 
   1084   return EFI_SUCCESS;
   1085 }
   1086 
   1087 /**
   1088   Send ATA Ext command into device with NON_DATA protocol.
   1089 
   1090   @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   1091   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
   1092   @param AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.
   1093   @param Timeout          The time to complete the command, uses 100ns as a unit.
   1094 
   1095   @retval  EFI_SUCCESS Reading succeed
   1096   @retval  EFI_DEVICE_ERROR Error executing commands on this device.
   1097 
   1098 **/
   1099 EFI_STATUS
   1100 EFIAPI
   1101 AtaIssueCommand (
   1102   IN  EFI_PCI_IO_PROTOCOL       *PciIo,
   1103   IN  EFI_IDE_REGISTERS         *IdeRegisters,
   1104   IN  EFI_ATA_COMMAND_BLOCK     *AtaCommandBlock,
   1105   IN  UINT64                    Timeout
   1106   )
   1107 {
   1108   EFI_STATUS  Status;
   1109   UINT8       DeviceHead;
   1110   UINT8       AtaCommand;
   1111 
   1112   ASSERT (PciIo != NULL);
   1113   ASSERT (IdeRegisters != NULL);
   1114   ASSERT (AtaCommandBlock != NULL);
   1115 
   1116   DeviceHead = AtaCommandBlock->AtaDeviceHead;
   1117   AtaCommand = AtaCommandBlock->AtaCommand;
   1118 
   1119   Status = WaitForBSYClear (PciIo, IdeRegisters, Timeout);
   1120   if (EFI_ERROR (Status)) {
   1121     return EFI_DEVICE_ERROR;
   1122   }
   1123 
   1124   //
   1125   // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
   1126   //
   1127   IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8) (0xe0 | DeviceHead));
   1128 
   1129   //
   1130   // set all the command parameters
   1131   // Before write to all the following registers, BSY and DRQ must be 0.
   1132   //
   1133   Status = DRQClear2 (PciIo, IdeRegisters, Timeout);
   1134   if (EFI_ERROR (Status)) {
   1135     return EFI_DEVICE_ERROR;
   1136   }
   1137 
   1138   //
   1139   // Fill the feature register, which is a two-byte FIFO. Need write twice.
   1140   //
   1141   IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeaturesExp);
   1142   IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeatures);
   1143 
   1144   //
   1145   // Fill the sector count register, which is a two-byte FIFO. Need write twice.
   1146   //
   1147   IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCountExp);
   1148   IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCount);
   1149 
   1150   //
   1151   // Fill the start LBA registers, which are also two-byte FIFO
   1152   //
   1153   IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumberExp);
   1154   IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumber);
   1155 
   1156   IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLowExp);
   1157   IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLow);
   1158 
   1159   IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHighExp);
   1160   IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHigh);
   1161 
   1162   //
   1163   // Send command via Command Register
   1164   //
   1165   IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, AtaCommand);
   1166 
   1167   //
   1168   // Stall at least 400 microseconds.
   1169   //
   1170   MicroSecondDelay (400);
   1171 
   1172   return EFI_SUCCESS;
   1173 }
   1174 
   1175 /**
   1176   This function is used to send out ATA commands conforms to the PIO Data In Protocol.
   1177 
   1178   @param[in]      PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
   1179                                    structure.
   1180   @param[in]      IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
   1181   @param[in, out] Buffer           A pointer to the source buffer for the data.
   1182   @param[in]      ByteCount        The length of the data.
   1183   @param[in]      Read             Flag used to determine the data transfer direction.
   1184                                    Read equals 1, means data transferred from device
   1185                                    to host;Read equals 0, means data transferred
   1186                                    from host to device.
   1187   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.
   1188   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   1189   @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.
   1190   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK
   1191                                    used by non-blocking mode.
   1192 
   1193   @retval EFI_SUCCESS      send out the ATA command and device send required data successfully.
   1194   @retval EFI_DEVICE_ERROR command sent failed.
   1195 
   1196 **/
   1197 EFI_STATUS
   1198 EFIAPI
   1199 AtaPioDataInOut (
   1200   IN     EFI_PCI_IO_PROTOCOL       *PciIo,
   1201   IN     EFI_IDE_REGISTERS         *IdeRegisters,
   1202   IN OUT VOID                      *Buffer,
   1203   IN     UINT64                    ByteCount,
   1204   IN     BOOLEAN                   Read,
   1205   IN     EFI_ATA_COMMAND_BLOCK     *AtaCommandBlock,
   1206   IN OUT EFI_ATA_STATUS_BLOCK      *AtaStatusBlock,
   1207   IN     UINT64                    Timeout,
   1208   IN     ATA_NONBLOCK_TASK         *Task
   1209   )
   1210 {
   1211   UINTN       WordCount;
   1212   UINTN       Increment;
   1213   UINT16      *Buffer16;
   1214   EFI_STATUS  Status;
   1215 
   1216   if ((PciIo == NULL) || (IdeRegisters == NULL) || (Buffer == NULL) || (AtaCommandBlock == NULL)) {
   1217     return EFI_INVALID_PARAMETER;
   1218   }
   1219 
   1220   //
   1221   // Issue ATA command
   1222   //
   1223   Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
   1224   if (EFI_ERROR (Status)) {
   1225     Status = EFI_DEVICE_ERROR;
   1226     goto Exit;
   1227   }
   1228 
   1229   Buffer16 = (UINT16 *) Buffer;
   1230 
   1231   //
   1232   // According to PIO data in protocol, host can perform a series of reads to
   1233   // the data register after each time device set DRQ ready;
   1234   // The data size of "a series of read" is command specific.
   1235   // For most ATA command, data size received from device will not exceed
   1236   // 1 sector, hence the data size for "a series of read" can be the whole data
   1237   // size of one command request.
   1238   // For ATA command such as Read Sector command, the data size of one ATA
   1239   // command request is often larger than 1 sector, according to the
   1240   // Read Sector command, the data size of "a series of read" is exactly 1
   1241   // sector.
   1242   // Here for simplification reason, we specify the data size for
   1243   // "a series of read" to 1 sector (256 words) if data size of one ATA command
   1244   // request is larger than 256 words.
   1245   //
   1246   Increment = 256;
   1247 
   1248   //
   1249   // used to record bytes of currently transfered data
   1250   //
   1251   WordCount = 0;
   1252 
   1253   while (WordCount < RShiftU64(ByteCount, 1)) {
   1254     //
   1255     // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
   1256     //
   1257     Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
   1258     if (EFI_ERROR (Status)) {
   1259       Status = EFI_DEVICE_ERROR;
   1260       goto Exit;
   1261     }
   1262 
   1263     //
   1264     // Get the byte count for one series of read
   1265     //
   1266     if ((WordCount + Increment) > RShiftU64(ByteCount, 1)) {
   1267       Increment = (UINTN)(RShiftU64(ByteCount, 1) - WordCount);
   1268     }
   1269 
   1270     if (Read) {
   1271       IdeReadPortWMultiple (
   1272         PciIo,
   1273         IdeRegisters->Data,
   1274         Increment,
   1275         Buffer16
   1276         );
   1277     } else {
   1278       IdeWritePortWMultiple (
   1279         PciIo,
   1280         IdeRegisters->Data,
   1281         Increment,
   1282         Buffer16
   1283         );
   1284     }
   1285 
   1286     Status = CheckStatusRegister (PciIo, IdeRegisters);
   1287     if (EFI_ERROR (Status)) {
   1288       Status = EFI_DEVICE_ERROR;
   1289       goto Exit;
   1290     }
   1291 
   1292     WordCount += Increment;
   1293     Buffer16  += Increment;
   1294   }
   1295 
   1296   Status = DRQClear (PciIo, IdeRegisters, Timeout);
   1297   if (EFI_ERROR (Status)) {
   1298     Status = EFI_DEVICE_ERROR;
   1299     goto Exit;
   1300   }
   1301 
   1302 Exit:
   1303   //
   1304   // Dump All Ide registers to ATA_STATUS_BLOCK
   1305   //
   1306   DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
   1307 
   1308   //
   1309   // Not support the Non-blocking now,just do the blocking process.
   1310   //
   1311   return Status;
   1312 }
   1313 
   1314 /**
   1315   Send ATA command into device with NON_DATA protocol
   1316 
   1317   @param[in]      PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
   1318                                    data structure.
   1319   @param[in]      IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
   1320   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data
   1321                                    structure.
   1322   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   1323   @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.
   1324   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK
   1325                                    used by non-blocking mode.
   1326 
   1327   @retval  EFI_SUCCESS Reading succeed
   1328   @retval  EFI_ABORTED Command failed
   1329   @retval  EFI_DEVICE_ERROR Device status error.
   1330 
   1331 **/
   1332 EFI_STATUS
   1333 EFIAPI
   1334 AtaNonDataCommandIn (
   1335   IN     EFI_PCI_IO_PROTOCOL       *PciIo,
   1336   IN     EFI_IDE_REGISTERS         *IdeRegisters,
   1337   IN     EFI_ATA_COMMAND_BLOCK     *AtaCommandBlock,
   1338   IN OUT EFI_ATA_STATUS_BLOCK      *AtaStatusBlock,
   1339   IN     UINT64                    Timeout,
   1340   IN     ATA_NONBLOCK_TASK         *Task
   1341   )
   1342 {
   1343   EFI_STATUS  Status;
   1344 
   1345   if ((PciIo == NULL) || (IdeRegisters == NULL) || (AtaCommandBlock == NULL)) {
   1346     return EFI_INVALID_PARAMETER;
   1347   }
   1348 
   1349   //
   1350   // Issue ATA command
   1351   //
   1352   Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
   1353   if (EFI_ERROR (Status)) {
   1354     Status = EFI_DEVICE_ERROR;
   1355     goto Exit;
   1356   }
   1357 
   1358   //
   1359   // Wait for command completion
   1360   //
   1361   Status = WaitForBSYClear (PciIo, IdeRegisters, Timeout);
   1362   if (EFI_ERROR (Status)) {
   1363     Status = EFI_DEVICE_ERROR;
   1364     goto Exit;
   1365   }
   1366 
   1367   Status = CheckStatusRegister (PciIo, IdeRegisters);
   1368   if (EFI_ERROR (Status)) {
   1369     Status = EFI_DEVICE_ERROR;
   1370     goto Exit;
   1371   }
   1372 
   1373 Exit:
   1374   //
   1375   // Dump All Ide registers to ATA_STATUS_BLOCK
   1376   //
   1377   DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
   1378 
   1379   //
   1380   // Not support the Non-blocking now,just do the blocking process.
   1381   //
   1382   return Status;
   1383 }
   1384 
   1385 /**
   1386   Wait for memory to be set.
   1387 
   1388   @param[in]  PciIo           The PCI IO protocol instance.
   1389   @param[in]  IdeRegisters    A pointer to EFI_IDE_REGISTERS data structure.
   1390   @param[in]  Timeout         The time to complete the command, uses 100ns as a unit.
   1391 
   1392   @retval EFI_DEVICE_ERROR  The memory is not set.
   1393   @retval EFI_TIMEOUT       The memory setting is time out.
   1394   @retval EFI_SUCCESS       The memory is correct set.
   1395 
   1396 **/
   1397 EFI_STATUS
   1398 AtaUdmStatusWait (
   1399   IN  EFI_PCI_IO_PROTOCOL       *PciIo,
   1400   IN  EFI_IDE_REGISTERS         *IdeRegisters,
   1401   IN  UINT64                    Timeout
   1402  )
   1403 {
   1404   UINT8                         RegisterValue;
   1405   EFI_STATUS                    Status;
   1406   UINT16                        IoPortForBmis;
   1407   UINT64                        Delay;
   1408   BOOLEAN                       InfiniteWait;
   1409 
   1410   if (Timeout == 0) {
   1411     InfiniteWait = TRUE;
   1412   } else {
   1413     InfiniteWait = FALSE;
   1414   }
   1415 
   1416   Delay = DivU64x32 (Timeout, 1000) + 1;
   1417 
   1418   do {
   1419     Status = CheckStatusRegister (PciIo, IdeRegisters);
   1420     if (EFI_ERROR (Status)) {
   1421       Status = EFI_DEVICE_ERROR;
   1422       break;
   1423     }
   1424 
   1425     IoPortForBmis = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
   1426     RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
   1427     if (((RegisterValue & BMIS_ERROR) != 0) || (Timeout == 0)) {
   1428       DEBUG ((EFI_D_ERROR, "ATA UDMA operation fails\n"));
   1429       Status = EFI_DEVICE_ERROR;
   1430       break;
   1431     }
   1432 
   1433     if ((RegisterValue & BMIS_INTERRUPT) != 0) {
   1434       Status = EFI_SUCCESS;
   1435       break;
   1436     }
   1437     //
   1438     // Stall for 100 microseconds.
   1439     //
   1440     MicroSecondDelay (100);
   1441     Delay--;
   1442   } while (InfiniteWait || (Delay > 0));
   1443 
   1444   return Status;
   1445 }
   1446 
   1447 /**
   1448   Check if the memory to be set.
   1449 
   1450   @param[in]  PciIo           The PCI IO protocol instance.
   1451   @param[in]  Task            Optional. Pointer to the ATA_NONBLOCK_TASK
   1452                               used by non-blocking mode.
   1453   @param[in]  IdeRegisters    A pointer to EFI_IDE_REGISTERS data structure.
   1454 
   1455   @retval EFI_DEVICE_ERROR  The memory setting met a issue.
   1456   @retval EFI_NOT_READY     The memory is not set.
   1457   @retval EFI_TIMEOUT       The memory setting is time out.
   1458   @retval EFI_SUCCESS       The memory is correct set.
   1459 
   1460 **/
   1461 EFI_STATUS
   1462 AtaUdmStatusCheck (
   1463   IN     EFI_PCI_IO_PROTOCOL        *PciIo,
   1464   IN     ATA_NONBLOCK_TASK          *Task,
   1465   IN     EFI_IDE_REGISTERS          *IdeRegisters
   1466  )
   1467 {
   1468   UINT8          RegisterValue;
   1469   UINT16         IoPortForBmis;
   1470   EFI_STATUS     Status;
   1471 
   1472   Task->RetryTimes--;
   1473 
   1474   Status = CheckStatusRegister (PciIo, IdeRegisters);
   1475   if (EFI_ERROR (Status)) {
   1476     return EFI_DEVICE_ERROR;
   1477   }
   1478 
   1479   IoPortForBmis = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
   1480   RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);
   1481 
   1482   if ((RegisterValue & BMIS_ERROR) != 0) {
   1483     DEBUG ((EFI_D_ERROR, "ATA UDMA operation fails\n"));
   1484     return EFI_DEVICE_ERROR;
   1485   }
   1486 
   1487   if ((RegisterValue & BMIS_INTERRUPT) != 0) {
   1488     return EFI_SUCCESS;
   1489   }
   1490 
   1491   if (!Task->InfiniteWait && (Task->RetryTimes == 0)) {
   1492     return EFI_TIMEOUT;
   1493   } else {
   1494     //
   1495     // The memory is not set.
   1496     //
   1497     return EFI_NOT_READY;
   1498   }
   1499 }
   1500 
   1501 /**
   1502   Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
   1503 
   1504   @param[in]      Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
   1505                                    structure.
   1506   @param[in]      IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.
   1507   @param[in]      Read             Flag used to determine the data transfer
   1508                                    direction. Read equals 1, means data transferred
   1509                                    from device to host;Read equals 0, means data
   1510                                    transferred from host to device.
   1511   @param[in]      DataBuffer       A pointer to the source buffer for the data.
   1512   @param[in]      DataLength       The length of  the data.
   1513   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.
   1514   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   1515   @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.
   1516   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK
   1517                                    used by non-blocking mode.
   1518 
   1519   @retval EFI_SUCCESS          the operation is successful.
   1520   @retval EFI_OUT_OF_RESOURCES Build PRD table failed
   1521   @retval EFI_UNSUPPORTED      Unknown channel or operations command
   1522   @retval EFI_DEVICE_ERROR     Ata command execute failed
   1523 
   1524 **/
   1525 EFI_STATUS
   1526 EFIAPI
   1527 AtaUdmaInOut (
   1528   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   1529   IN     EFI_IDE_REGISTERS             *IdeRegisters,
   1530   IN     BOOLEAN                       Read,
   1531   IN     VOID                          *DataBuffer,
   1532   IN     UINT64                        DataLength,
   1533   IN     EFI_ATA_COMMAND_BLOCK         *AtaCommandBlock,
   1534   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock,
   1535   IN     UINT64                        Timeout,
   1536   IN     ATA_NONBLOCK_TASK             *Task
   1537   )
   1538 {
   1539   EFI_STATUS                    Status;
   1540   UINT16                        IoPortForBmic;
   1541   UINT16                        IoPortForBmis;
   1542   UINT16                        IoPortForBmid;
   1543 
   1544   UINTN                         PrdTableSize;
   1545   EFI_PHYSICAL_ADDRESS          PrdTableMapAddr;
   1546   VOID                          *PrdTableMap;
   1547   EFI_PHYSICAL_ADDRESS          PrdTableBaseAddr;
   1548   EFI_ATA_DMA_PRD               *TempPrdBaseAddr;
   1549   UINTN                         PrdTableNum;
   1550 
   1551   UINT8                         RegisterValue;
   1552   UINTN                         PageCount;
   1553   UINTN                         ByteCount;
   1554   UINTN                         ByteRemaining;
   1555   UINT8                         DeviceControl;
   1556 
   1557   VOID                          *BufferMap;
   1558   EFI_PHYSICAL_ADDRESS          BufferMapAddress;
   1559   EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation;
   1560 
   1561   UINT8                         DeviceHead;
   1562   EFI_PCI_IO_PROTOCOL           *PciIo;
   1563   EFI_TPL                       OldTpl;
   1564 
   1565   UINTN                         AlignmentMask;
   1566   UINTN                         RealPageCount;
   1567   EFI_PHYSICAL_ADDRESS          BaseAddr;
   1568   EFI_PHYSICAL_ADDRESS          BaseMapAddr;
   1569 
   1570   Status        = EFI_SUCCESS;
   1571   PrdTableMap   = NULL;
   1572   BufferMap     = NULL;
   1573   PageCount     = 0;
   1574   RealPageCount = 0;
   1575   BaseAddr      = 0;
   1576   PciIo         = Instance->PciIo;
   1577 
   1578   if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {
   1579     return EFI_INVALID_PARAMETER;
   1580   }
   1581 
   1582   //
   1583   // Before starting the Blocking BlockIO operation, push to finish all non-blocking
   1584   // BlockIO tasks.
   1585   // Delay 1ms to simulate the blocking time out checking.
   1586   //
   1587   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
   1588   while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
   1589     AsyncNonBlockingTransferRoutine (NULL, Instance);
   1590     //
   1591     // Stall for 1 milliseconds.
   1592     //
   1593     MicroSecondDelay (1000);
   1594   }
   1595   gBS->RestoreTPL (OldTpl);
   1596 
   1597   //
   1598   // The data buffer should be even alignment
   1599   //
   1600   if (((UINTN)DataBuffer & 0x1) != 0) {
   1601     return EFI_INVALID_PARAMETER;
   1602   }
   1603 
   1604   //
   1605   // Set relevant IO Port address.
   1606   //
   1607   IoPortForBmic = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);
   1608   IoPortForBmis = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
   1609   IoPortForBmid = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
   1610 
   1611   //
   1612   // For Blocking mode, start the command.
   1613   // For non-blocking mode, when the command is not started, start it, otherwise
   1614   // go to check the status.
   1615   //
   1616   if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) {
   1617     //
   1618     // Calculate the number of PRD entry.
   1619     // Every entry in PRD table can specify a 64K memory region.
   1620     //
   1621     PrdTableNum   = (UINTN)(RShiftU64(DataLength, 16) + 1);
   1622 
   1623     //
   1624     // Make sure that the memory region of PRD table is not cross 64K boundary
   1625     //
   1626     PrdTableSize = PrdTableNum * sizeof (EFI_ATA_DMA_PRD);
   1627     if (PrdTableSize > 0x10000) {
   1628       return EFI_INVALID_PARAMETER;
   1629     }
   1630 
   1631     //
   1632     // Allocate buffer for PRD table initialization.
   1633     // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte
   1634     // boundary and the table cannot cross a 64K boundary in memory.
   1635     //
   1636     PageCount     = EFI_SIZE_TO_PAGES (PrdTableSize);
   1637     RealPageCount = PageCount + EFI_SIZE_TO_PAGES (SIZE_64KB);
   1638 
   1639     //
   1640     // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.
   1641     //
   1642     ASSERT (RealPageCount > PageCount);
   1643 
   1644     Status    = PciIo->AllocateBuffer (
   1645                          PciIo,
   1646                          AllocateAnyPages,
   1647                          EfiBootServicesData,
   1648                          RealPageCount,
   1649                          (VOID **)&BaseAddr,
   1650                          0
   1651                          );
   1652     if (EFI_ERROR (Status)) {
   1653       return EFI_OUT_OF_RESOURCES;
   1654     }
   1655 
   1656     ByteCount = EFI_PAGES_TO_SIZE (RealPageCount);
   1657     Status    = PciIo->Map (
   1658                          PciIo,
   1659                          EfiPciIoOperationBusMasterCommonBuffer,
   1660                          (VOID*)(UINTN)BaseAddr,
   1661                          &ByteCount,
   1662                          &BaseMapAddr,
   1663                          &PrdTableMap
   1664                          );
   1665     if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (RealPageCount))) {
   1666       //
   1667       // If the data length actually mapped is not equal to the requested amount,
   1668       // it means the DMA operation may be broken into several discontinuous smaller chunks.
   1669       // Can't handle this case.
   1670       //
   1671       PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);
   1672       return EFI_OUT_OF_RESOURCES;
   1673     }
   1674 
   1675     ZeroMem ((VOID *) ((UINTN) BaseAddr), ByteCount);
   1676 
   1677     //
   1678     // Calculate the 64K align address as PRD Table base address.
   1679     //
   1680     AlignmentMask    = SIZE_64KB - 1;
   1681     PrdTableBaseAddr = ((UINTN) BaseAddr + AlignmentMask) & ~AlignmentMask;
   1682     PrdTableMapAddr  = ((UINTN) BaseMapAddr + AlignmentMask) & ~AlignmentMask;
   1683 
   1684     //
   1685     // Map the host address of DataBuffer to DMA master address.
   1686     //
   1687     if (Read) {
   1688       PciIoOperation = EfiPciIoOperationBusMasterWrite;
   1689     } else {
   1690       PciIoOperation = EfiPciIoOperationBusMasterRead;
   1691     }
   1692 
   1693     ByteCount = (UINTN)DataLength;
   1694     Status    = PciIo->Map (
   1695                          PciIo,
   1696                          PciIoOperation,
   1697                          DataBuffer,
   1698                          &ByteCount,
   1699                          &BufferMapAddress,
   1700                          &BufferMap
   1701                          );
   1702     if (EFI_ERROR (Status) || (ByteCount != DataLength)) {
   1703       PciIo->Unmap (PciIo, PrdTableMap);
   1704       PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);
   1705       return EFI_OUT_OF_RESOURCES;
   1706     }
   1707 
   1708     //
   1709     // According to Ata spec, it requires the buffer address and size to be even.
   1710     //
   1711     ASSERT ((BufferMapAddress & 0x1) == 0);
   1712     ASSERT ((ByteCount & 0x1) == 0);
   1713 
   1714     //
   1715     // Fill the PRD table with appropriate bus master address of data buffer and data length.
   1716     //
   1717     ByteRemaining   = ByteCount;
   1718     TempPrdBaseAddr = (EFI_ATA_DMA_PRD*)(UINTN)PrdTableBaseAddr;
   1719     while (ByteRemaining != 0) {
   1720       if (ByteRemaining <= 0x10000) {
   1721         TempPrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
   1722         TempPrdBaseAddr->ByteCount      = (UINT16) ByteRemaining;
   1723         TempPrdBaseAddr->EndOfTable     = 0x8000;
   1724         break;
   1725       }
   1726 
   1727       TempPrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);
   1728       TempPrdBaseAddr->ByteCount      = (UINT16) 0x0;
   1729 
   1730       ByteRemaining    -= 0x10000;
   1731       BufferMapAddress += 0x10000;
   1732       TempPrdBaseAddr++;
   1733     }
   1734 
   1735     //
   1736     // Start to enable the DMA operation
   1737     //
   1738     DeviceHead = AtaCommandBlock->AtaDeviceHead;
   1739 
   1740     IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
   1741 
   1742     //
   1743     // Enable interrupt to support UDMA
   1744     //
   1745     DeviceControl = 0;
   1746     IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
   1747 
   1748     //
   1749     // Read BMIS register and clear ERROR and INTR bit
   1750     //
   1751     RegisterValue  = IdeReadPortB(PciIo, IoPortForBmis);
   1752     RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
   1753     IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
   1754 
   1755     //
   1756     // Set the base address to BMID register
   1757     //
   1758     IdeWritePortDW (PciIo, IoPortForBmid, (UINT32)PrdTableMapAddr);
   1759 
   1760     //
   1761     // Set BMIC register to identify the operation direction
   1762     //
   1763     RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);
   1764     if (Read) {
   1765       RegisterValue |= BMIC_NREAD;
   1766     } else {
   1767       RegisterValue &= ~((UINT8) BMIC_NREAD);
   1768     }
   1769     IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
   1770 
   1771     if (Task != NULL) {
   1772       Task->Map            = BufferMap;
   1773       Task->TableMap       = PrdTableMap;
   1774       Task->MapBaseAddress = (EFI_ATA_DMA_PRD*)(UINTN)BaseAddr;
   1775       Task->PageCount      = RealPageCount;
   1776       Task->IsStart        = TRUE;
   1777     }
   1778 
   1779     //
   1780     // Issue ATA command
   1781     //
   1782     Status = AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
   1783 
   1784     if (EFI_ERROR (Status)) {
   1785       Status = EFI_DEVICE_ERROR;
   1786       goto Exit;
   1787     }
   1788 
   1789     Status = CheckStatusRegister (PciIo, IdeRegisters);
   1790     if (EFI_ERROR (Status)) {
   1791       Status = EFI_DEVICE_ERROR;
   1792       goto Exit;
   1793     }
   1794     //
   1795     // Set START bit of BMIC register
   1796     //
   1797     RegisterValue  = IdeReadPortB(PciIo, IoPortForBmic);
   1798     RegisterValue |= BMIC_START;
   1799     IdeWritePortB(PciIo, IoPortForBmic, RegisterValue);
   1800 
   1801   }
   1802 
   1803   //
   1804   // Check the INTERRUPT and ERROR bit of BMIS
   1805   //
   1806   if (Task != NULL) {
   1807     Status = AtaUdmStatusCheck (PciIo, Task, IdeRegisters);
   1808   } else {
   1809     Status = AtaUdmStatusWait (PciIo, IdeRegisters, Timeout);
   1810   }
   1811 
   1812   //
   1813   // For blocking mode, clear registers and free buffers.
   1814   // For non blocking mode, when the related registers have been set or time
   1815   // out, or a error has been happened, it needs to clear the register and free
   1816   // buffer.
   1817   //
   1818   if ((Task == NULL) || Status != EFI_NOT_READY) {
   1819     //
   1820     // Read BMIS register and clear ERROR and INTR bit
   1821     //
   1822     RegisterValue  = IdeReadPortB (PciIo, IoPortForBmis);
   1823     RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
   1824     IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);
   1825 
   1826     //
   1827     // Read Status Register of IDE device to clear interrupt
   1828     //
   1829     RegisterValue  = IdeReadPortB(PciIo, IdeRegisters->CmdOrStatus);
   1830 
   1831     //
   1832     // Clear START bit of BMIC register
   1833     //
   1834     RegisterValue  = IdeReadPortB(PciIo, IoPortForBmic);
   1835     RegisterValue &= ~((UINT8) BMIC_START);
   1836     IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);
   1837 
   1838     //
   1839     // Disable interrupt of Select device
   1840     //
   1841     DeviceControl  = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
   1842     DeviceControl |= ATA_CTLREG_IEN_L;
   1843     IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
   1844     //
   1845     // Stall for 10 milliseconds.
   1846     //
   1847     MicroSecondDelay (10000);
   1848 
   1849   }
   1850 
   1851 Exit:
   1852   //
   1853   // Free all allocated resource
   1854   //
   1855   if ((Task == NULL) || Status != EFI_NOT_READY) {
   1856     if (Task != NULL) {
   1857       PciIo->Unmap (PciIo, Task->TableMap);
   1858       PciIo->FreeBuffer (PciIo, Task->PageCount, Task->MapBaseAddress);
   1859       PciIo->Unmap (PciIo, Task->Map);
   1860     } else {
   1861       PciIo->Unmap (PciIo, PrdTableMap);
   1862       PciIo->FreeBuffer (PciIo, RealPageCount, (VOID*)(UINTN)BaseAddr);
   1863       PciIo->Unmap (PciIo, BufferMap);
   1864     }
   1865 
   1866     //
   1867     // Dump All Ide registers to ATA_STATUS_BLOCK
   1868     //
   1869     DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);
   1870   }
   1871 
   1872   return Status;
   1873 }
   1874 
   1875 /**
   1876   This function reads the pending data in the device.
   1877 
   1878   @param PciIo         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   1879   @param IdeRegisters  A pointer to EFI_IDE_REGISTERS data structure.
   1880 
   1881   @retval EFI_SUCCESS   Successfully read.
   1882   @retval EFI_NOT_READY The BSY is set avoiding reading.
   1883 
   1884 **/
   1885 EFI_STATUS
   1886 EFIAPI
   1887 AtaPacketReadPendingData (
   1888   IN  EFI_PCI_IO_PROTOCOL       *PciIo,
   1889   IN  EFI_IDE_REGISTERS         *IdeRegisters
   1890   )
   1891 {
   1892   UINT8     AltRegister;
   1893   UINT16    TempWordBuffer;
   1894 
   1895   AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
   1896   if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {
   1897     return EFI_NOT_READY;
   1898   }
   1899 
   1900   if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
   1901     TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
   1902     while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
   1903       IdeReadPortWMultiple (
   1904         PciIo,
   1905         IdeRegisters->Data,
   1906         1,
   1907         &TempWordBuffer
   1908         );
   1909       TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
   1910     }
   1911   }
   1912   return EFI_SUCCESS;
   1913 }
   1914 
   1915 /**
   1916   This function is called by AtaPacketCommandExecute().
   1917   It is used to transfer data between host and device. The data direction is specified
   1918   by the fourth parameter.
   1919 
   1920   @param PciIo         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   1921   @param IdeRegisters  A pointer to EFI_IDE_REGISTERS data structure.
   1922   @param Buffer        Buffer contained data transferred between host and device.
   1923   @param ByteCount     Data size in byte unit of the buffer.
   1924   @param Read          Flag used to determine the data transfer direction.
   1925                        Read equals 1, means data transferred from device to host;
   1926                        Read equals 0, means data transferred from host to device.
   1927   @param Timeout       Timeout value for wait DRQ ready before each data stream's transfer
   1928                        , uses 100ns as a unit.
   1929 
   1930   @retval EFI_SUCCESS      data is transferred successfully.
   1931   @retval EFI_DEVICE_ERROR the device failed to transfer data.
   1932 **/
   1933 EFI_STATUS
   1934 EFIAPI
   1935 AtaPacketReadWrite (
   1936   IN     EFI_PCI_IO_PROTOCOL       *PciIo,
   1937   IN     EFI_IDE_REGISTERS         *IdeRegisters,
   1938   IN OUT VOID                      *Buffer,
   1939   IN OUT UINT32                    *ByteCount,
   1940   IN     BOOLEAN                   Read,
   1941   IN     UINT64                    Timeout
   1942   )
   1943 {
   1944   UINT32      RequiredWordCount;
   1945   UINT32      ActualWordCount;
   1946   UINT32      WordCount;
   1947   EFI_STATUS  Status;
   1948   UINT16      *PtrBuffer;
   1949 
   1950   PtrBuffer         = Buffer;
   1951   RequiredWordCount = *ByteCount >> 1;
   1952 
   1953   //
   1954   // No data transfer is premitted.
   1955   //
   1956   if (RequiredWordCount == 0) {
   1957     return EFI_SUCCESS;
   1958   }
   1959 
   1960   //
   1961   // ActualWordCount means the word count of data really transferred.
   1962   //
   1963   ActualWordCount = 0;
   1964 
   1965   while (ActualWordCount < RequiredWordCount) {
   1966     //
   1967     // before each data transfer stream, the host should poll DRQ bit ready,
   1968     // to see whether indicates device is ready to transfer data.
   1969     //
   1970     Status = DRQReady2 (PciIo, IdeRegisters, Timeout);
   1971     if (EFI_ERROR (Status)) {
   1972       if (Status == EFI_NOT_READY) {
   1973         //
   1974         // Device provided less data than we intended to read, or wanted less
   1975         // data than we intended to write, but it may still be successful.
   1976         //
   1977         break;
   1978       } else {
   1979         return Status;
   1980       }
   1981     }
   1982 
   1983     //
   1984     // get current data transfer size from Cylinder Registers.
   1985     //
   1986     WordCount  = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb) << 8;
   1987     WordCount  = WordCount | IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
   1988     WordCount  = WordCount & 0xffff;
   1989     WordCount /= 2;
   1990 
   1991     WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));
   1992 
   1993     if (Read) {
   1994       IdeReadPortWMultiple (
   1995         PciIo,
   1996         IdeRegisters->Data,
   1997         WordCount,
   1998         PtrBuffer
   1999         );
   2000     } else {
   2001       IdeWritePortWMultiple (
   2002         PciIo,
   2003         IdeRegisters->Data,
   2004         WordCount,
   2005         PtrBuffer
   2006         );
   2007     }
   2008 
   2009     //
   2010     // read status register to check whether error happens.
   2011     //
   2012     Status = CheckStatusRegister (PciIo, IdeRegisters);
   2013     if (EFI_ERROR (Status)) {
   2014       return EFI_DEVICE_ERROR;
   2015     }
   2016 
   2017     PtrBuffer       += WordCount;
   2018     ActualWordCount += WordCount;
   2019   }
   2020 
   2021   if (Read) {
   2022     //
   2023     // In the case where the drive wants to send more data than we need to read,
   2024     // the DRQ bit will be set and cause delays from DRQClear2().
   2025     // We need to read data from the drive until it clears DRQ so we can move on.
   2026     //
   2027     AtaPacketReadPendingData (PciIo, IdeRegisters);
   2028   }
   2029 
   2030   //
   2031   // read status register to check whether error happens.
   2032   //
   2033   Status = CheckStatusRegister (PciIo, IdeRegisters);
   2034   if (EFI_ERROR (Status)) {
   2035     return EFI_DEVICE_ERROR;
   2036   }
   2037 
   2038   //
   2039   // After data transfer is completed, normally, DRQ bit should clear.
   2040   //
   2041   Status = DRQClear (PciIo, IdeRegisters, Timeout);
   2042   if (EFI_ERROR (Status)) {
   2043     return EFI_DEVICE_ERROR;
   2044   }
   2045 
   2046   *ByteCount = ActualWordCount << 1;
   2047   return Status;
   2048 }
   2049 
   2050 /**
   2051   This function is used to send out ATAPI commands conforms to the Packet Command
   2052   with PIO Data In Protocol.
   2053 
   2054   @param[in] PciIo          Pointer to the EFI_PCI_IO_PROTOCOL instance
   2055   @param[in] IdeRegisters   Pointer to EFI_IDE_REGISTERS which is used to
   2056                             store the IDE i/o port registers' base addresses
   2057   @param[in] Channel        The channel number of device.
   2058   @param[in] Device         The device number of device.
   2059   @param[in] Packet         A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
   2060 
   2061   @retval EFI_SUCCESS       send out the ATAPI packet command successfully
   2062                             and device sends data successfully.
   2063   @retval EFI_DEVICE_ERROR  the device failed to send data.
   2064 
   2065 **/
   2066 EFI_STATUS
   2067 EFIAPI
   2068 AtaPacketCommandExecute (
   2069   IN  EFI_PCI_IO_PROTOCOL                           *PciIo,
   2070   IN  EFI_IDE_REGISTERS                             *IdeRegisters,
   2071   IN  UINT8                                         Channel,
   2072   IN  UINT8                                         Device,
   2073   IN  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
   2074   )
   2075 {
   2076   EFI_ATA_COMMAND_BLOCK       AtaCommandBlock;
   2077   EFI_STATUS                  Status;
   2078   UINT8                       Count;
   2079   UINT8                       PacketCommand[12];
   2080 
   2081   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2082 
   2083   //
   2084   // Fill ATAPI Command Packet according to CDB.
   2085   // For Atapi cmd, its length should be less than or equal to 12 bytes.
   2086   //
   2087   if (Packet->CdbLength > 12) {
   2088     return EFI_INVALID_PARAMETER;
   2089   }
   2090 
   2091   ZeroMem (PacketCommand, 12);
   2092   CopyMem (PacketCommand, Packet->Cdb, Packet->CdbLength);
   2093 
   2094   //
   2095   // No OVL; No DMA
   2096   //
   2097   AtaCommandBlock.AtaFeatures = 0x00;
   2098   //
   2099   // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
   2100   // determine how many data should be transferred.
   2101   //
   2102   AtaCommandBlock.AtaCylinderLow  = (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff);
   2103   AtaCommandBlock.AtaCylinderHigh = (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8);
   2104   AtaCommandBlock.AtaDeviceHead   = (UINT8) (Device << 0x4);
   2105   AtaCommandBlock.AtaCommand      = ATA_CMD_PACKET;
   2106 
   2107   IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | (Device << 0x4)));
   2108   //
   2109   //  Disable interrupt
   2110   //
   2111   IdeWritePortB (PciIo, IdeRegisters->AltOrDev, ATA_DEFAULT_CTL);
   2112 
   2113   //
   2114   // Issue ATA PACKET command firstly
   2115   //
   2116   Status = AtaIssueCommand (PciIo, IdeRegisters, &AtaCommandBlock, Packet->Timeout);
   2117   if (EFI_ERROR (Status)) {
   2118     return Status;
   2119   }
   2120 
   2121   Status = DRQReady (PciIo, IdeRegisters, Packet->Timeout);
   2122   if (EFI_ERROR (Status)) {
   2123     return Status;
   2124   }
   2125 
   2126   //
   2127   // Send out ATAPI command packet
   2128   //
   2129   for (Count = 0; Count < 6; Count++) {
   2130     IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16*)PacketCommand + Count));
   2131     //
   2132     // Stall for 10 microseconds.
   2133     //
   2134     MicroSecondDelay (10);
   2135   }
   2136 
   2137   //
   2138   // Read/Write the data of ATAPI Command
   2139   //
   2140   if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
   2141     Status = AtaPacketReadWrite (
   2142                PciIo,
   2143                IdeRegisters,
   2144                Packet->InDataBuffer,
   2145                &Packet->InTransferLength,
   2146                TRUE,
   2147                Packet->Timeout
   2148                );
   2149   } else {
   2150     Status = AtaPacketReadWrite (
   2151                PciIo,
   2152                IdeRegisters,
   2153                Packet->OutDataBuffer,
   2154                &Packet->OutTransferLength,
   2155                FALSE,
   2156                Packet->Timeout
   2157                );
   2158   }
   2159 
   2160   return Status;
   2161 }
   2162 
   2163 
   2164 /**
   2165   Set the calculated Best transfer mode to a detected device.
   2166 
   2167   @param Instance               A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   2168   @param Channel                The channel number of device.
   2169   @param Device                 The device number of device.
   2170   @param TransferMode           A pointer to EFI_ATA_TRANSFER_MODE data structure.
   2171   @param AtaStatusBlock         A pointer to EFI_ATA_STATUS_BLOCK data structure.
   2172 
   2173   @retval EFI_SUCCESS          Set transfer mode successfully.
   2174   @retval EFI_DEVICE_ERROR     Set transfer mode failed.
   2175   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
   2176 
   2177 **/
   2178 EFI_STATUS
   2179 EFIAPI
   2180 SetDeviceTransferMode (
   2181   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   2182   IN     UINT8                         Channel,
   2183   IN     UINT8                         Device,
   2184   IN     EFI_ATA_TRANSFER_MODE         *TransferMode,
   2185   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
   2186   )
   2187 {
   2188   EFI_STATUS              Status;
   2189   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
   2190 
   2191   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2192 
   2193   AtaCommandBlock.AtaCommand     = ATA_CMD_SET_FEATURES;
   2194   AtaCommandBlock.AtaDeviceHead  = (UINT8)(Device << 0x4);
   2195   AtaCommandBlock.AtaFeatures    = 0x03;
   2196   AtaCommandBlock.AtaSectorCount = *((UINT8 *)TransferMode);
   2197 
   2198   //
   2199   // Send SET FEATURE command (sub command 0x03) to set pio mode.
   2200   //
   2201   Status = AtaNonDataCommandIn (
   2202              Instance->PciIo,
   2203              &Instance->IdeRegisters[Channel],
   2204              &AtaCommandBlock,
   2205              AtaStatusBlock,
   2206              ATA_ATAPI_TIMEOUT,
   2207              NULL
   2208              );
   2209 
   2210   return Status;
   2211 }
   2212 
   2213 /**
   2214   Set drive parameters for devices not support PACKETS command.
   2215 
   2216   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   2217   @param Channel          The channel number of device.
   2218   @param Device           The device number of device.
   2219   @param DriveParameters  A pointer to EFI_ATA_DRIVE_PARMS data structure.
   2220   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   2221 
   2222   @retval EFI_SUCCESS          Set drive parameter successfully.
   2223   @retval EFI_DEVICE_ERROR     Set drive parameter failed.
   2224   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
   2225 
   2226 **/
   2227 EFI_STATUS
   2228 EFIAPI
   2229 SetDriveParameters (
   2230   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   2231   IN     UINT8                         Channel,
   2232   IN     UINT8                         Device,
   2233   IN     EFI_ATA_DRIVE_PARMS           *DriveParameters,
   2234   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
   2235   )
   2236 {
   2237   EFI_STATUS              Status;
   2238   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
   2239 
   2240   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2241 
   2242   AtaCommandBlock.AtaCommand     = ATA_CMD_INIT_DRIVE_PARAM;
   2243   AtaCommandBlock.AtaSectorCount = DriveParameters->Sector;
   2244   AtaCommandBlock.AtaDeviceHead  = (UINT8) ((Device << 0x4) + DriveParameters->Heads);
   2245 
   2246   //
   2247   // Send Init drive parameters
   2248   //
   2249   Status = AtaNonDataCommandIn (
   2250              Instance->PciIo,
   2251              &Instance->IdeRegisters[Channel],
   2252              &AtaCommandBlock,
   2253              AtaStatusBlock,
   2254              ATA_ATAPI_TIMEOUT,
   2255              NULL
   2256              );
   2257 
   2258   //
   2259   // Send Set Multiple parameters
   2260   //
   2261   AtaCommandBlock.AtaCommand     = ATA_CMD_SET_MULTIPLE_MODE;
   2262   AtaCommandBlock.AtaSectorCount = DriveParameters->MultipleSector;
   2263   AtaCommandBlock.AtaDeviceHead  = (UINT8)(Device << 0x4);
   2264 
   2265   Status = AtaNonDataCommandIn (
   2266              Instance->PciIo,
   2267              &Instance->IdeRegisters[Channel],
   2268              &AtaCommandBlock,
   2269              AtaStatusBlock,
   2270              ATA_ATAPI_TIMEOUT,
   2271              NULL
   2272              );
   2273 
   2274   return Status;
   2275 }
   2276 
   2277 /**
   2278   Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
   2279 
   2280   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   2281   @param Channel          The channel number of device.
   2282   @param Device           The device number of device.
   2283   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   2284 
   2285   @retval EFI_SUCCESS     Successfully get the return status of S.M.A.R.T command execution.
   2286   @retval Others          Fail to get return status data.
   2287 
   2288 **/
   2289 EFI_STATUS
   2290 EFIAPI
   2291 IdeAtaSmartReturnStatusCheck (
   2292   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   2293   IN     UINT8                         Channel,
   2294   IN     UINT8                         Device,
   2295   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
   2296   )
   2297 {
   2298   EFI_STATUS              Status;
   2299   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
   2300   UINT8                   LBAMid;
   2301   UINT8                   LBAHigh;
   2302 
   2303   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2304 
   2305   AtaCommandBlock.AtaCommand      = ATA_CMD_SMART;
   2306   AtaCommandBlock.AtaFeatures     = ATA_SMART_RETURN_STATUS;
   2307   AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;
   2308   AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
   2309   AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);
   2310 
   2311   //
   2312   // Send S.M.A.R.T Read Return Status command to device
   2313   //
   2314   Status = AtaNonDataCommandIn (
   2315              Instance->PciIo,
   2316              &Instance->IdeRegisters[Channel],
   2317              &AtaCommandBlock,
   2318              AtaStatusBlock,
   2319              ATA_ATAPI_TIMEOUT,
   2320              NULL
   2321              );
   2322 
   2323   if (EFI_ERROR (Status)) {
   2324     REPORT_STATUS_CODE (
   2325       EFI_ERROR_CODE | EFI_ERROR_MINOR,
   2326       (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
   2327       );
   2328     return EFI_DEVICE_ERROR;
   2329   }
   2330 
   2331   REPORT_STATUS_CODE (
   2332     EFI_PROGRESS_CODE,
   2333     (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
   2334     );
   2335 
   2336   LBAMid  = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderLsb);
   2337   LBAHigh = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderMsb);
   2338 
   2339   if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
   2340     //
   2341     // The threshold exceeded condition is not detected by the device
   2342     //
   2343     DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
   2344     REPORT_STATUS_CODE (
   2345           EFI_PROGRESS_CODE,
   2346           (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
   2347           );
   2348   } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
   2349     //
   2350     // The threshold exceeded condition is detected by the device
   2351     //
   2352     DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
   2353     REPORT_STATUS_CODE (
   2354          EFI_PROGRESS_CODE,
   2355          (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
   2356          );
   2357   }
   2358 
   2359   return EFI_SUCCESS;
   2360 }
   2361 
   2362 /**
   2363   Enable SMART command of the disk if supported.
   2364 
   2365   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   2366   @param Channel          The channel number of device.
   2367   @param Device           The device number of device.
   2368   @param IdentifyData     A pointer to data buffer which is used to contain IDENTIFY data.
   2369   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   2370 
   2371 **/
   2372 VOID
   2373 EFIAPI
   2374 IdeAtaSmartSupport (
   2375   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   2376   IN     UINT8                         Channel,
   2377   IN     UINT8                         Device,
   2378   IN     EFI_IDENTIFY_DATA             *IdentifyData,
   2379   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
   2380   )
   2381 {
   2382   EFI_STATUS              Status;
   2383   EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;
   2384 
   2385   //
   2386   // Detect if the device supports S.M.A.R.T.
   2387   //
   2388   if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
   2389     //
   2390     // S.M.A.R.T is not supported by the device
   2391     //
   2392     DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
   2393             (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));
   2394     REPORT_STATUS_CODE (
   2395       EFI_ERROR_CODE | EFI_ERROR_MINOR,
   2396       (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
   2397       );
   2398   } else {
   2399     //
   2400     // Check if the feature is enabled. If not, then enable S.M.A.R.T.
   2401     //
   2402     if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
   2403 
   2404       REPORT_STATUS_CODE (
   2405         EFI_PROGRESS_CODE,
   2406         (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
   2407         );
   2408 
   2409       ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2410 
   2411       AtaCommandBlock.AtaCommand      = ATA_CMD_SMART;
   2412       AtaCommandBlock.AtaFeatures     = ATA_SMART_ENABLE_OPERATION;
   2413       AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;
   2414       AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
   2415       AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);
   2416 
   2417       //
   2418       // Send S.M.A.R.T Enable command to device
   2419       //
   2420       Status = AtaNonDataCommandIn (
   2421                  Instance->PciIo,
   2422                  &Instance->IdeRegisters[Channel],
   2423                  &AtaCommandBlock,
   2424                  AtaStatusBlock,
   2425                  ATA_ATAPI_TIMEOUT,
   2426                  NULL
   2427                  );
   2428 
   2429       if (!EFI_ERROR (Status)) {
   2430         //
   2431         // Send S.M.A.R.T AutoSave command to device
   2432         //
   2433         ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2434 
   2435         AtaCommandBlock.AtaCommand      = ATA_CMD_SMART;
   2436         AtaCommandBlock.AtaFeatures     = 0xD2;
   2437         AtaCommandBlock.AtaSectorCount  = 0xF1;
   2438         AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;
   2439         AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
   2440         AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);
   2441 
   2442         Status = AtaNonDataCommandIn (
   2443                    Instance->PciIo,
   2444                    &Instance->IdeRegisters[Channel],
   2445                    &AtaCommandBlock,
   2446                    AtaStatusBlock,
   2447                    ATA_ATAPI_TIMEOUT,
   2448                    NULL
   2449                    );
   2450         if (!EFI_ERROR (Status)) {
   2451           Status = IdeAtaSmartReturnStatusCheck (
   2452                      Instance,
   2453                      Channel,
   2454                      Device,
   2455                      AtaStatusBlock
   2456                      );
   2457         }
   2458       }
   2459     }
   2460 
   2461     DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
   2462            (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));
   2463 
   2464   }
   2465 
   2466   return ;
   2467 }
   2468 
   2469 
   2470 /**
   2471   Sends out an ATA Identify Command to the specified device.
   2472 
   2473   This function is called by DiscoverIdeDevice() during its device
   2474   identification. It sends out the ATA Identify Command to the
   2475   specified device. Only ATA device responses to this command. If
   2476   the command succeeds, it returns the Identify data structure which
   2477   contains information about the device. This function extracts the
   2478   information it needs to fill the IDE_BLK_IO_DEV data structure,
   2479   including device type, media block size, media capacity, and etc.
   2480 
   2481   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   2482   @param Channel          The channel number of device.
   2483   @param Device           The device number of device.
   2484   @param Buffer           A pointer to data buffer which is used to contain IDENTIFY data.
   2485   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   2486 
   2487   @retval EFI_SUCCESS          Identify ATA device successfully.
   2488   @retval EFI_DEVICE_ERROR     ATA Identify Device Command failed or device is not ATA device.
   2489   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
   2490 
   2491 **/
   2492 EFI_STATUS
   2493 EFIAPI
   2494 AtaIdentify (
   2495   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   2496   IN     UINT8                         Channel,
   2497   IN     UINT8                         Device,
   2498   IN OUT EFI_IDENTIFY_DATA             *Buffer,
   2499   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
   2500   )
   2501 {
   2502   EFI_STATUS             Status;
   2503   EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;
   2504 
   2505   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2506 
   2507   AtaCommandBlock.AtaCommand    = ATA_CMD_IDENTIFY_DRIVE;
   2508   AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
   2509 
   2510   Status = AtaPioDataInOut (
   2511              Instance->PciIo,
   2512              &Instance->IdeRegisters[Channel],
   2513              Buffer,
   2514              sizeof (EFI_IDENTIFY_DATA),
   2515              TRUE,
   2516              &AtaCommandBlock,
   2517              AtaStatusBlock,
   2518              ATA_ATAPI_TIMEOUT,
   2519              NULL
   2520              );
   2521 
   2522   return Status;
   2523 }
   2524 
   2525 /**
   2526   This function is called by DiscoverIdeDevice() during its device
   2527   identification.
   2528   Its main purpose is to get enough information for the device media
   2529   to fill in the Media data structure of the Block I/O Protocol interface.
   2530 
   2531   There are 5 steps to reach such objective:
   2532   1. Sends out the ATAPI Identify Command to the specified device.
   2533   Only ATAPI device responses to this command. If the command succeeds,
   2534   it returns the Identify data structure which filled with information
   2535   about the device. Since the ATAPI device contains removable media,
   2536   the only meaningful information is the device module name.
   2537   2. Sends out ATAPI Inquiry Packet Command to the specified device.
   2538   This command will return inquiry data of the device, which contains
   2539   the device type information.
   2540   3. Allocate sense data space for future use. We don't detect the media
   2541   presence here to improvement boot performance, especially when CD
   2542   media is present. The media detection will be performed just before
   2543   each BLK_IO read/write
   2544 
   2545   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   2546   @param Channel          The channel number of device.
   2547   @param Device           The device number of device.
   2548   @param Buffer           A pointer to data buffer which is used to contain IDENTIFY data.
   2549   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
   2550 
   2551   @retval EFI_SUCCESS          Identify ATAPI device successfully.
   2552   @retval EFI_DEVICE_ERROR     ATA Identify Packet Device Command failed or device type
   2553                                is not supported by this IDE driver.
   2554   @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
   2555 
   2556 **/
   2557 EFI_STATUS
   2558 EFIAPI
   2559 AtaIdentifyPacket (
   2560   IN     ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   2561   IN     UINT8                         Channel,
   2562   IN     UINT8                         Device,
   2563   IN OUT EFI_IDENTIFY_DATA             *Buffer,
   2564   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock
   2565   )
   2566 {
   2567   EFI_STATUS             Status;
   2568   EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;
   2569 
   2570   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
   2571 
   2572   AtaCommandBlock.AtaCommand    = ATA_CMD_IDENTIFY_DEVICE;
   2573   AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
   2574 
   2575   //
   2576   // Send ATAPI Identify Command to get IDENTIFY data.
   2577   //
   2578   Status = AtaPioDataInOut (
   2579              Instance->PciIo,
   2580              &Instance->IdeRegisters[Channel],
   2581              (VOID *) Buffer,
   2582              sizeof (EFI_IDENTIFY_DATA),
   2583              TRUE,
   2584              &AtaCommandBlock,
   2585              AtaStatusBlock,
   2586              ATA_ATAPI_TIMEOUT,
   2587              NULL
   2588              );
   2589 
   2590   return Status;
   2591 }
   2592 
   2593 
   2594 /**
   2595   This function is used for detect whether the IDE device exists in the
   2596   specified Channel as the specified Device Number.
   2597 
   2598   There is two IDE channels: one is Primary Channel, the other is
   2599   Secondary Channel.(Channel is the logical name for the physical "Cable".)
   2600   Different channel has different register group.
   2601 
   2602   On each IDE channel, at most two IDE devices attach,
   2603   one is called Device 0 (Master device), the other is called Device 1
   2604   (Slave device). The devices on the same channel co-use the same register
   2605   group, so before sending out a command for a specified device via command
   2606   register, it is a must to select the current device to accept the command
   2607   by set the device number in the Head/Device Register.
   2608 
   2609   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
   2610   @param IdeChannel       The channel number of device.
   2611 
   2612   @retval EFI_SUCCESS successfully detects device.
   2613   @retval other       any failure during detection process will return this value.
   2614 
   2615 **/
   2616 EFI_STATUS
   2617 EFIAPI
   2618 DetectAndConfigIdeDevice (
   2619   IN  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
   2620   IN  UINT8                         IdeChannel
   2621   )
   2622 {
   2623   EFI_STATUS                        Status;
   2624   UINT8                             SectorCountReg;
   2625   UINT8                             LBALowReg;
   2626   UINT8                             LBAMidReg;
   2627   UINT8                             LBAHighReg;
   2628   EFI_ATA_DEVICE_TYPE               DeviceType;
   2629   UINT8                             IdeDevice;
   2630   EFI_IDE_REGISTERS                 *IdeRegisters;
   2631   EFI_IDENTIFY_DATA                 Buffer;
   2632 
   2633   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
   2634   EFI_PCI_IO_PROTOCOL               *PciIo;
   2635 
   2636   EFI_ATA_COLLECTIVE_MODE           *SupportedModes;
   2637   EFI_ATA_TRANSFER_MODE             TransferMode;
   2638   EFI_ATA_DRIVE_PARMS               DriveParameters;
   2639 
   2640   IdeRegisters = &Instance->IdeRegisters[IdeChannel];
   2641   IdeInit      = Instance->IdeControllerInit;
   2642   PciIo        = Instance->PciIo;
   2643 
   2644   for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {
   2645     //
   2646     // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
   2647     //
   2648     IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
   2649 
   2650     //
   2651     // Send ATA Device Execut Diagnostic command.
   2652     // This command should work no matter DRDY is ready or not
   2653     //
   2654     IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, ATA_CMD_EXEC_DRIVE_DIAG);
   2655 
   2656     Status = WaitForBSYClear (PciIo, IdeRegisters, 350000000);
   2657     if (EFI_ERROR (Status)) {
   2658       DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));
   2659       continue;
   2660     }
   2661 
   2662     //
   2663     // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
   2664     //
   2665     IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
   2666     //
   2667     // Stall for 1 milliseconds.
   2668     //
   2669     MicroSecondDelay (1000);
   2670 
   2671     SectorCountReg = IdeReadPortB (PciIo, IdeRegisters->SectorCount);
   2672     LBALowReg      = IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
   2673     LBAMidReg      = IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
   2674     LBAHighReg     = IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
   2675 
   2676     //
   2677     // Refer to ATA/ATAPI 4 Spec, section 9.1
   2678     //
   2679     if ((SectorCountReg == 0x1) && (LBALowReg == 0x1) && (LBAMidReg == 0x0) && (LBAHighReg == 0x0)) {
   2680       DeviceType = EfiIdeHarddisk;
   2681     } else if ((LBAMidReg == 0x14) && (LBAHighReg == 0xeb)) {
   2682       DeviceType = EfiIdeCdrom;
   2683     } else {
   2684       continue;
   2685     }
   2686 
   2687     //
   2688     // Send IDENTIFY cmd to the device to test if it is really attached.
   2689     //
   2690     if (DeviceType == EfiIdeHarddisk) {
   2691       Status = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
   2692       //
   2693       // if identifying ata device is failure, then try to send identify packet cmd.
   2694       //
   2695       if (EFI_ERROR (Status)) {
   2696         REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));
   2697 
   2698         DeviceType = EfiIdeCdrom;
   2699         Status     = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
   2700       }
   2701     } else {
   2702       Status = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
   2703       //
   2704       // if identifying atapi device is failure, then try to send identify cmd.
   2705       //
   2706       if (EFI_ERROR (Status)) {
   2707         DeviceType = EfiIdeHarddisk;
   2708         Status     = AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer, NULL);
   2709       }
   2710     }
   2711 
   2712     if (EFI_ERROR (Status)) {
   2713       //
   2714       // No device is found at this port
   2715       //
   2716       continue;
   2717     }
   2718 
   2719     DEBUG ((EFI_D_INFO, "[%a] channel [%a] [%a] device\n",
   2720             (IdeChannel == 1) ? "secondary" : "primary  ", (IdeDevice == 1) ? "slave " : "master",
   2721             DeviceType == EfiIdeCdrom ? "cdrom   " : "harddisk"));
   2722     //
   2723     // If the device is a hard disk, then try to enable S.M.A.R.T feature
   2724     //
   2725     if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {
   2726       IdeAtaSmartSupport (
   2727         Instance,
   2728         IdeChannel,
   2729         IdeDevice,
   2730         &Buffer,
   2731         NULL
   2732         );
   2733     }
   2734 
   2735     //
   2736     // Submit identify data to IDE controller init driver
   2737     //
   2738     IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &Buffer);
   2739 
   2740     //
   2741     // Now start to config ide device parameter and transfer mode.
   2742     //
   2743     Status = IdeInit->CalculateMode (
   2744                         IdeInit,
   2745                         IdeChannel,
   2746                         IdeDevice,
   2747                         &SupportedModes
   2748                         );
   2749     if (EFI_ERROR (Status)) {
   2750       DEBUG ((EFI_D_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
   2751       continue;
   2752     }
   2753 
   2754     //
   2755     // Set best supported PIO mode on this IDE device
   2756     //
   2757     if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
   2758       TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
   2759     } else {
   2760       TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
   2761     }
   2762 
   2763     TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
   2764 
   2765     if (SupportedModes->ExtModeCount == 0){
   2766       Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
   2767 
   2768       if (EFI_ERROR (Status)) {
   2769         DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
   2770         continue;
   2771       }
   2772     }
   2773 
   2774     //
   2775     // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
   2776     // be set together. Only one DMA mode can be set to a device. If setting
   2777     // DMA mode operation fails, we can continue moving on because we only use
   2778     // PIO mode at boot time. DMA modes are used by certain kind of OS booting
   2779     //
   2780     if (SupportedModes->UdmaMode.Valid) {
   2781       TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
   2782       TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);
   2783       Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
   2784 
   2785       if (EFI_ERROR (Status)) {
   2786         DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
   2787         continue;
   2788       }
   2789     } else if (SupportedModes->MultiWordDmaMode.Valid) {
   2790       TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
   2791       TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
   2792       Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);
   2793 
   2794       if (EFI_ERROR (Status)) {
   2795         DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
   2796         continue;
   2797       }
   2798     }
   2799 
   2800     //
   2801     // Set Parameters for the device:
   2802     // 1) Init
   2803     // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
   2804     //
   2805     if (DeviceType == EfiIdeHarddisk) {
   2806       //
   2807       // Init driver parameters
   2808       //
   2809       DriveParameters.Sector         = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;
   2810       DriveParameters.Heads          = (UINT8) (((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);
   2811       DriveParameters.MultipleSector = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;
   2812 
   2813       Status = SetDriveParameters (Instance, IdeChannel, IdeDevice, &DriveParameters, NULL);
   2814     }
   2815 
   2816     //
   2817     // Set IDE controller Timing Blocks in the PCI Configuration Space
   2818     //
   2819     IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
   2820 
   2821     //
   2822     // IDE controller and IDE device timing is configured successfully.
   2823     // Now insert the device into device list.
   2824     //
   2825     Status = CreateNewDeviceInfo (Instance, IdeChannel, IdeDevice, DeviceType, &Buffer);
   2826     if (EFI_ERROR (Status)) {
   2827       continue;
   2828     }
   2829 
   2830     if (DeviceType == EfiIdeHarddisk) {
   2831       REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));
   2832     }
   2833   }
   2834   return EFI_SUCCESS;
   2835 }
   2836 
   2837 
   2838 /**
   2839   Initialize ATA host controller at IDE mode.
   2840 
   2841   The function is designed to initialize ATA host controller.
   2842 
   2843   @param[in]  Instance          A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
   2844 
   2845 **/
   2846 EFI_STATUS
   2847 EFIAPI
   2848 IdeModeInitialization (
   2849   IN  ATA_ATAPI_PASS_THRU_INSTANCE    *Instance
   2850   )
   2851 {
   2852   EFI_STATUS                        Status;
   2853   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
   2854   EFI_PCI_IO_PROTOCOL               *PciIo;
   2855   UINT8                             Channel;
   2856   UINT8                             IdeChannel;
   2857   BOOLEAN                           ChannelEnabled;
   2858   UINT8                             MaxDevices;
   2859 
   2860   IdeInit = Instance->IdeControllerInit;
   2861   PciIo   = Instance->PciIo;
   2862   Channel = IdeInit->ChannelCount;
   2863 
   2864   //
   2865   // Obtain IDE IO port registers' base addresses
   2866   //
   2867   Status = GetIdeRegisterIoAddr (PciIo, Instance->IdeRegisters);
   2868   if (EFI_ERROR (Status)) {
   2869     goto ErrorExit;
   2870   }
   2871 
   2872   for (IdeChannel = 0; IdeChannel < Channel; IdeChannel++) {
   2873     IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);
   2874 
   2875     //
   2876     // now obtain channel information fron IdeControllerInit protocol.
   2877     //
   2878     Status = IdeInit->GetChannelInfo (
   2879                         IdeInit,
   2880                         IdeChannel,
   2881                         &ChannelEnabled,
   2882                         &MaxDevices
   2883                         );
   2884     if (EFI_ERROR (Status)) {
   2885       DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));
   2886       continue;
   2887     }
   2888 
   2889     if (!ChannelEnabled) {
   2890       continue;
   2891     }
   2892 
   2893     ASSERT (MaxDevices <= 2);
   2894     //
   2895     // Now inform the IDE Controller Init Module.
   2896     //
   2897     IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);
   2898 
   2899     //
   2900     // No reset channel function implemented.
   2901     //
   2902     IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);
   2903 
   2904     //
   2905     // Now inform the IDE Controller Init Module.
   2906     //
   2907     IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, IdeChannel);
   2908 
   2909     //
   2910     // Detect all attached ATA devices and set the transfer mode for each device.
   2911     //
   2912     DetectAndConfigIdeDevice (Instance, IdeChannel);
   2913   }
   2914 
   2915   //
   2916   // All configurations done! Notify IdeController to do post initialization
   2917   // work such as saving IDE controller PCI settings for S3 resume
   2918   //
   2919   IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
   2920 
   2921 ErrorExit:
   2922   return Status;
   2923 }
   2924 
   2925