Home | History | Annotate | Download | only in IdeBusDxe
      1 /** @file
      2    This file contains all helper functions on the ATAPI command
      3 
      4   Copyright (c) 2006 - 2010, 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 "IdeBus.h"
     16 
     17 /**
     18   This function is used to get the current status of the media residing
     19   in the LS-120 drive or ZIP drive. The media status is returned in the
     20   Error Status.
     21 
     22   @param IdeDev   pointer pointing to IDE_BLK_IO_DEV data structure, used
     23                   to record all the information of the IDE device.
     24 
     25   @retval EFI_SUCCESS         The media status is achieved successfully and the media
     26                               can be read/written.
     27   @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.
     28   @retval EFI_NO_MEDIA        There is no media in the drive.
     29   @retval EFI_WRITE_PROTECTED The media is writing protected.
     30 
     31   @note  This function must be called after the LS120EnableMediaStatus()
     32          with second parameter set to TRUE
     33          (means enable media status notification) is called.
     34 **/
     35 EFI_STATUS
     36 LS120GetMediaStatus (
     37   IN  IDE_BLK_IO_DEV  *IdeDev
     38   )
     39 {
     40   UINT8       DeviceSelect;
     41   UINT8       StatusValue;
     42   EFI_STATUS  EfiStatus;
     43   //
     44   // Poll Alternate Register for BSY clear within timeout.
     45   //
     46   EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
     47   if (EFI_ERROR (EfiStatus)) {
     48     return EFI_DEVICE_ERROR;
     49   }
     50 
     51   //
     52   // Select device via Device/Head Register.
     53   //
     54   DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);
     55   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);
     56 
     57   //
     58   // Poll Alternate Register for DRDY set within timeout.
     59   // After device is selected, DRDY set indicates the device is ready to
     60   // accept command.
     61   //
     62   EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT);
     63   if (EFI_ERROR (EfiStatus)) {
     64     return EFI_DEVICE_ERROR;
     65   }
     66 
     67   //
     68   // Get Media Status Command is sent
     69   //
     70   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA);
     71 
     72   //
     73   // BSY bit will clear after command is complete.
     74   //
     75   EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
     76   if (EFI_ERROR (EfiStatus)) {
     77     return EFI_DEVICE_ERROR;
     78   }
     79 
     80   //
     81   // the media status is returned by the command in the ERROR register
     82   //
     83   StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);
     84 
     85   if ((StatusValue & BIT1) != 0) {
     86     return EFI_NO_MEDIA;
     87   }
     88 
     89   if ((StatusValue & BIT6) != 0) {
     90     return EFI_WRITE_PROTECTED;
     91   } else {
     92     return EFI_SUCCESS;
     93   }
     94 }
     95 /**
     96   This function is used to send Enable Media Status Notification Command
     97   or Disable Media Status Notification Command.
     98 
     99   @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
    100                 to record all the information of the IDE device.
    101 
    102   @param Enable a flag that indicates whether enable or disable media
    103                 status notification.
    104   @retval EFI_SUCCESS      If command completes successfully.
    105   @retval EFI_DEVICE_ERROR If command failed.
    106 **/
    107 EFI_STATUS
    108 LS120EnableMediaStatus (
    109   IN  IDE_BLK_IO_DEV  *IdeDev,
    110   IN  BOOLEAN         Enable
    111   )
    112 {
    113   UINT8       DeviceSelect;
    114   EFI_STATUS  Status;
    115 
    116   //
    117   // Poll Alternate Register for BSY clear within timeout.
    118   //
    119   Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
    120   if (EFI_ERROR (Status)) {
    121     return EFI_DEVICE_ERROR;
    122   }
    123 
    124   //
    125   // Select device via Device/Head Register.
    126   //
    127   DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);
    128   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);
    129 
    130   //
    131   // Poll Alternate Register for DRDY set within timeout.
    132   // After device is selected, DRDY set indicates the device is ready to
    133   // accept command.
    134   //
    135   Status = DRDYReady2 (IdeDev, ATATIMEOUT);
    136   if (EFI_ERROR (Status)) {
    137     return EFI_DEVICE_ERROR;
    138   }
    139 
    140   if (Enable) {
    141     //
    142     // 0x95: Enable media status notification
    143     //
    144     IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95);
    145   } else {
    146     //
    147     // 0x31: Disable media status notification
    148     //
    149     IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31);
    150   }
    151   //
    152   // Set Feature Command is sent
    153   //
    154   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF);
    155 
    156   //
    157   // BSY bit will clear after command is complete.
    158   //
    159   Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
    160   if (EFI_ERROR (Status)) {
    161     return EFI_DEVICE_ERROR;
    162   }
    163 
    164   return EFI_SUCCESS;
    165 }
    166 /**
    167   This function reads the pending data in the device.
    168 
    169   @param IdeDev   Indicates the calling context.
    170 
    171   @retval EFI_SUCCESS   Successfully read.
    172   @retval EFI_NOT_READY The BSY is set avoiding reading.
    173 
    174 **/
    175 EFI_STATUS
    176 AtapiReadPendingData (
    177   IN IDE_BLK_IO_DEV     *IdeDev
    178   )
    179 {
    180   UINT8     AltRegister;
    181   UINT16    TempWordBuffer;
    182 
    183   AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);
    184   if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {
    185     return EFI_NOT_READY;
    186   }
    187   if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
    188     TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);
    189     while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
    190       IDEReadPortWMultiple (
    191         IdeDev->PciIo,
    192         IdeDev->IoPort->Data,
    193         1,
    194         &TempWordBuffer
    195         );
    196       TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);
    197     }
    198   }
    199   return EFI_SUCCESS;
    200 }
    201 
    202 /**
    203   This function is called by either AtapiPacketCommandIn() or AtapiPacketCommandOut().
    204   It is used to transfer data between host and device. The data direction is specified
    205   by the fourth parameter.
    206 
    207   @param IdeDev     pointer pointing to IDE_BLK_IO_DEV data structure, used to record
    208                     all the information of the IDE device.
    209   @param Buffer     buffer contained data transferred between host and device.
    210   @param ByteCount  data size in byte unit of the buffer.
    211   @param Read       flag used to determine the data transfer direction.
    212                     Read equals 1, means data transferred from device to host;
    213                     Read equals 0, means data transferred from host to device.
    214   @param TimeOut    timeout value for wait DRQ ready before each data stream's transfer.
    215 
    216   @retval EFI_SUCCESS      data is transferred successfully.
    217   @retval EFI_DEVICE_ERROR the device failed to transfer data.
    218 **/
    219 EFI_STATUS
    220 PioReadWriteData (
    221   IN  IDE_BLK_IO_DEV  *IdeDev,
    222   IN  UINT16          *Buffer,
    223   IN  UINT32          ByteCount,
    224   IN  BOOLEAN         Read,
    225   IN  UINTN           TimeOut
    226   )
    227 {
    228   //
    229   // required transfer data in word unit.
    230   //
    231   UINT32      RequiredWordCount;
    232 
    233   //
    234   // actual transfer data in word unit.
    235   //
    236   UINT32      ActualWordCount;
    237   UINT32      WordCount;
    238   EFI_STATUS  Status;
    239   UINT16      *PtrBuffer;
    240 
    241   //
    242   // No data transfer is premitted.
    243   //
    244   if (ByteCount == 0) {
    245     return EFI_SUCCESS;
    246   }
    247   //
    248   // for performance, we assert the ByteCount is an even number
    249   // which is actually a resonable assumption
    250   ASSERT((ByteCount%2) == 0);
    251 
    252   PtrBuffer         = Buffer;
    253   RequiredWordCount = ByteCount / 2;
    254   //
    255   // ActuralWordCount means the word count of data really transferred.
    256   //
    257   ActualWordCount = 0;
    258 
    259   while (ActualWordCount < RequiredWordCount) {
    260 
    261     //
    262     // before each data transfer stream, the host should poll DRQ bit ready,
    263     // to see whether indicates device is ready to transfer data.
    264     //
    265     Status = DRQReady2 (IdeDev, TimeOut);
    266     if (EFI_ERROR (Status)) {
    267       return CheckErrorStatus (IdeDev);
    268     }
    269 
    270     //
    271     // read Status Register will clear interrupt
    272     //
    273     IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);
    274 
    275     //
    276     // get current data transfer size from Cylinder Registers.
    277     //
    278     WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8;
    279     WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);
    280     WordCount = WordCount & 0xffff;
    281     WordCount /= 2;
    282 
    283     WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));
    284 
    285     if (Read) {
    286       IDEReadPortWMultiple (
    287         IdeDev->PciIo,
    288         IdeDev->IoPort->Data,
    289         WordCount,
    290         PtrBuffer
    291         );
    292     } else {
    293       IDEWritePortWMultiple (
    294         IdeDev->PciIo,
    295         IdeDev->IoPort->Data,
    296         WordCount,
    297         PtrBuffer
    298         );
    299     }
    300 
    301     PtrBuffer += WordCount;
    302     ActualWordCount += WordCount;
    303   }
    304 
    305   if (Read) {
    306     //
    307     // In the case where the drive wants to send more data than we need to read,
    308     // the DRQ bit will be set and cause delays from DRQClear2().
    309     // We need to read data from the drive until it clears DRQ so we can move on.
    310     //
    311     AtapiReadPendingData (IdeDev);
    312   }
    313 
    314   //
    315   // After data transfer is completed, normally, DRQ bit should clear.
    316   //
    317   Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
    318   if (EFI_ERROR (Status)) {
    319     return EFI_DEVICE_ERROR;
    320   }
    321 
    322   //
    323   // read status register to check whether error happens.
    324   //
    325   return CheckErrorStatus (IdeDev);
    326 }
    327 
    328 /**
    329   This function is used to send out ATAPI commands conforms to the Packet Command
    330   with PIO Data In Protocol.
    331 
    332   @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used
    333                    to record all the information of the IDE device.
    334   @param Packet    pointer pointing to ATAPI_PACKET_COMMAND data structure
    335                    which contains the contents of the command.
    336   @param Buffer    buffer contained data transferred from device to host.
    337   @param ByteCount data size in byte unit of the buffer.
    338   @param TimeOut   this parameter is used to specify the timeout value for the
    339                    PioReadWriteData() function.
    340 
    341   @retval EFI_SUCCESS       send out the ATAPI packet command successfully
    342                             and device sends data successfully.
    343   @retval EFI_DEVICE_ERROR  the device failed to send data.
    344 
    345 **/
    346 EFI_STATUS
    347 AtapiPacketCommandIn (
    348   IN  IDE_BLK_IO_DEV        *IdeDev,
    349   IN  ATAPI_PACKET_COMMAND  *Packet,
    350   IN  UINT16                *Buffer,
    351   IN  UINT32                ByteCount,
    352   IN  UINTN                 TimeOut
    353   )
    354 {
    355   UINT16      *CommandIndex;
    356   EFI_STATUS  Status;
    357   UINT32      Count;
    358 
    359   //
    360   // Set all the command parameters by fill related registers.
    361   // Before write to all the following registers, BSY and DRQ must be 0.
    362   //
    363   Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
    364   if (EFI_ERROR (Status)) {
    365     return Status;
    366   }
    367 
    368   //
    369   // Select device via Device/Head Register.
    370   //
    371   IDEWritePortB (
    372     IdeDev->PciIo,
    373     IdeDev->IoPort->Head,
    374     (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD)  // DEFAULT_CMD: 0xa0 (1010,0000)
    375     );
    376 
    377   //
    378   // No OVL; No DMA
    379   //
    380   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);
    381 
    382   //
    383   // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
    384   // determine how many data should be transferred.
    385   //
    386   IDEWritePortB (
    387     IdeDev->PciIo,
    388     IdeDev->IoPort->CylinderLsb,
    389     (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)
    390     );
    391   IDEWritePortB (
    392     IdeDev->PciIo,
    393     IdeDev->IoPort->CylinderMsb,
    394     (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)
    395     );
    396 
    397   //
    398   //  ATA_DEFAULT_CTL:0x0a (0000,1010)
    399   //  Disable interrupt
    400   //
    401   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);
    402 
    403   //
    404   // Send Packet command to inform device
    405   // that the following data bytes are command packet.
    406   //
    407   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);
    408 
    409   Status = DRQReady (IdeDev, ATAPITIMEOUT);
    410   if (EFI_ERROR (Status)) {
    411     return Status;
    412   }
    413 
    414   //
    415   // Send out command packet
    416   //
    417   CommandIndex = Packet->Data16;
    418   for (Count = 0; Count < 6; Count++, CommandIndex++) {
    419 
    420     IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);
    421     gBS->Stall (10);
    422   }
    423 
    424   //
    425   // call PioReadWriteData() function to get
    426   // requested transfer data form device.
    427   //
    428   return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut);
    429 }
    430 /**
    431   This function is used to send out ATAPI commands conforms to the Packet Command
    432   with PIO Data Out Protocol.
    433 
    434   @param IdeDev      pointer pointing to IDE_BLK_IO_DEV data structure, used
    435                      to record all the information of the IDE device.
    436   @param Packet      pointer pointing to ATAPI_PACKET_COMMAND data structure
    437                      which contains the contents of the command.
    438   @param Buffer      buffer contained data transferred from host to device.
    439   @param ByteCount   data size in byte unit of the buffer.
    440   @param TimeOut     this parameter is used to specify the timeout value
    441                      for the PioReadWriteData() function.
    442   @retval EFI_SUCCESS      send out the ATAPI packet command successfully
    443                            and device received data successfully.
    444   @retval EFI_DEVICE_ERROR the device failed to send data.
    445 
    446 **/
    447 EFI_STATUS
    448 AtapiPacketCommandOut (
    449   IN  IDE_BLK_IO_DEV        *IdeDev,
    450   IN  ATAPI_PACKET_COMMAND  *Packet,
    451   IN  UINT16                *Buffer,
    452   IN  UINT32                ByteCount,
    453   IN  UINTN                 TimeOut
    454   )
    455 {
    456   UINT16      *CommandIndex;
    457   EFI_STATUS  Status;
    458   UINT32      Count;
    459 
    460   //
    461   // set all the command parameters
    462   // Before write to all the following registers, BSY and DRQ must be 0.
    463   //
    464   Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
    465   if (EFI_ERROR (Status)) {
    466     return Status;
    467   }
    468 
    469   //
    470   // Select device via Device/Head Register.
    471   //
    472   IDEWritePortB (
    473     IdeDev->PciIo,
    474     IdeDev->IoPort->Head,
    475     (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD)   // ATA_DEFAULT_CMD: 0xa0 (1010,0000)
    476     );
    477 
    478   //
    479   // No OVL; No DMA
    480   //
    481   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);
    482 
    483   //
    484   // set the transfersize to ATAPI_MAX_BYTE_COUNT to
    485   // let the device determine how many data should be transferred.
    486   //
    487   IDEWritePortB (
    488     IdeDev->PciIo,
    489     IdeDev->IoPort->CylinderLsb,
    490     (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)
    491     );
    492   IDEWritePortB (
    493     IdeDev->PciIo,
    494     IdeDev->IoPort->CylinderMsb,
    495     (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)
    496     );
    497 
    498   //
    499   //  DEFAULT_CTL:0x0a (0000,1010)
    500   //  Disable interrupt
    501   //
    502   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);
    503 
    504   //
    505   // Send Packet command to inform device
    506   // that the following data bytes are command packet.
    507   //
    508   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);
    509 
    510   Status = DRQReady2 (IdeDev, ATAPITIMEOUT);
    511   if (EFI_ERROR (Status)) {
    512     return Status;
    513   }
    514 
    515   //
    516   // Send out command packet
    517   //
    518   CommandIndex = Packet->Data16;
    519   for (Count = 0; Count < 6; Count++, CommandIndex++) {
    520     IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);
    521     gBS->Stall (10);
    522   }
    523 
    524   //
    525   // call PioReadWriteData() function to send requested transfer data to device.
    526   //
    527   return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut);
    528 }
    529 /**
    530   Sends out ATAPI Inquiry Packet Command to the specified device. This command will
    531   return INQUIRY data of the device.
    532 
    533   @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
    534                 to record all the information of the IDE device.
    535 
    536   @retval EFI_SUCCESS       Inquiry command completes successfully.
    537   @retval EFI_DEVICE_ERROR  Inquiry command failed.
    538 
    539   @note  Parameter "IdeDev" will be updated in this function.
    540 
    541 **/
    542 EFI_STATUS
    543 AtapiInquiry (
    544   IN  IDE_BLK_IO_DEV  *IdeDev
    545   )
    546 {
    547   ATAPI_PACKET_COMMAND  Packet;
    548   EFI_STATUS            Status;
    549   ATAPI_INQUIRY_DATA          *InquiryData;
    550 
    551   //
    552   // prepare command packet for the ATAPI Inquiry Packet Command.
    553   //
    554   ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
    555   Packet.Inquiry.opcode             = ATA_CMD_INQUIRY;
    556   Packet.Inquiry.page_code          = 0;
    557   Packet.Inquiry.allocation_length  = (UINT8) sizeof (ATAPI_INQUIRY_DATA);
    558 
    559   InquiryData                       = AllocatePool (sizeof (ATAPI_INQUIRY_DATA));
    560   if (InquiryData == NULL) {
    561     return EFI_DEVICE_ERROR;
    562   }
    563 
    564   //
    565   // Send command packet and get requested Inquiry data.
    566   //
    567   Status = AtapiPacketCommandIn (
    568             IdeDev,
    569             &Packet,
    570             (UINT16 *) InquiryData,
    571             sizeof (ATAPI_INQUIRY_DATA),
    572             ATAPITIMEOUT
    573             );
    574   if (EFI_ERROR (Status)) {
    575     gBS->FreePool (InquiryData);
    576     return EFI_DEVICE_ERROR;
    577   }
    578 
    579   IdeDev->InquiryData = InquiryData;
    580 
    581   return EFI_SUCCESS;
    582 }
    583 /**
    584   This function is called by DiscoverIdeDevice() during its device
    585   identification.
    586   Its main purpose is to get enough information for the device media
    587   to fill in the Media data structure of the Block I/O Protocol interface.
    588 
    589   There are 5 steps to reach such objective:
    590   1. Sends out the ATAPI Identify Command to the specified device.
    591   Only ATAPI device responses to this command. If the command succeeds,
    592   it returns the Identify data structure which filled with information
    593   about the device. Since the ATAPI device contains removable media,
    594   the only meaningful information is the device module name.
    595   2. Sends out ATAPI Inquiry Packet Command to the specified device.
    596   This command will return inquiry data of the device, which contains
    597   the device type information.
    598   3. Allocate sense data space for future use. We don't detect the media
    599   presence here to improvement boot performance, especially when CD
    600   media is present. The media detection will be performed just before
    601   each BLK_IO read/write
    602 
    603   @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
    604                  to record all the information of the IDE device.
    605 
    606   @retval EFI_SUCCESS       Identify ATAPI device successfully.
    607   @retval EFI_DEVICE_ERROR  ATAPI Identify Device Command failed or device type
    608                             is not supported by this IDE driver.
    609   @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed
    610 
    611   @note   Parameter "IdeDev" will be updated in this function.
    612 **/
    613 EFI_STATUS
    614 ATAPIIdentify (
    615   IN  IDE_BLK_IO_DEV  *IdeDev
    616   )
    617 {
    618   EFI_IDENTIFY_DATA *AtapiIdentifyPointer;
    619   UINT8             DeviceSelect;
    620   EFI_STATUS        Status;
    621 
    622   //
    623   // device select bit
    624   //
    625   DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);
    626 
    627   AtapiIdentifyPointer  = AllocatePool (sizeof (EFI_IDENTIFY_DATA));
    628   if (AtapiIdentifyPointer == NULL) {
    629     return EFI_OUT_OF_RESOURCES;
    630   }
    631   //
    632   // Send ATAPI Identify Command to get IDENTIFY data.
    633   //
    634   Status = AtaPioDataIn (
    635             IdeDev,
    636             (VOID *) AtapiIdentifyPointer,
    637             sizeof (EFI_IDENTIFY_DATA),
    638             ATA_CMD_IDENTIFY_DEVICE,
    639             DeviceSelect,
    640             0,
    641             0,
    642             0,
    643             0
    644             );
    645 
    646   if (EFI_ERROR (Status)) {
    647     gBS->FreePool (AtapiIdentifyPointer);
    648     return EFI_DEVICE_ERROR;
    649   }
    650 
    651   IdeDev->IdData = AtapiIdentifyPointer;
    652   PrintAtaModuleName (IdeDev);
    653 
    654   //
    655   // Send ATAPI Inquiry Packet Command to get INQUIRY data.
    656   //
    657   Status = AtapiInquiry (IdeDev);
    658   if (EFI_ERROR (Status)) {
    659     gBS->FreePool (IdeDev->IdData);
    660     //
    661     // Make sure the pIdData will not be freed again.
    662     //
    663     IdeDev->IdData = NULL;
    664     return EFI_DEVICE_ERROR;
    665   }
    666   //
    667   // Get media removable info from INQUIRY data.
    668   //
    669   IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->InquiryData->RMB & 0x80) == 0x80);
    670 
    671   //
    672   // Identify device type via INQUIRY data.
    673   //
    674   switch (IdeDev->InquiryData->peripheral_type & 0x1f) {
    675 
    676   //
    677   // Magnetic Disk
    678   //
    679   case 0x00:
    680 
    681     //
    682     // device is LS120 or ZIP drive.
    683     //
    684     IdeDev->Type = IdeMagnetic;
    685 
    686     IdeDev->BlkIo.Media->MediaId      = 0;
    687     //
    688     // Give initial value
    689     //
    690     IdeDev->BlkIo.Media->MediaPresent = FALSE;
    691 
    692     IdeDev->BlkIo.Media->LastBlock  = 0;
    693     IdeDev->BlkIo.Media->BlockSize  = 0x200;
    694     break;
    695 
    696   //
    697   // CD-ROM
    698   //
    699   case 0x05:
    700 
    701     IdeDev->Type                      = IdeCdRom;
    702     IdeDev->BlkIo.Media->MediaId      = 0;
    703     //
    704     // Give initial value
    705     //
    706     IdeDev->BlkIo.Media->MediaPresent = FALSE;
    707 
    708     IdeDev->BlkIo.Media->LastBlock  = 0;
    709     IdeDev->BlkIo.Media->BlockSize  = 0x800;
    710     IdeDev->BlkIo.Media->ReadOnly   = TRUE;
    711     break;
    712 
    713   //
    714   // Tape
    715   //
    716   case 0x01:
    717 
    718   //
    719   // WORM
    720   //
    721   case 0x04:
    722 
    723   //
    724   // Optical
    725   //
    726   case 0x07:
    727 
    728   default:
    729     IdeDev->Type = IdeUnknown;
    730     gBS->FreePool (IdeDev->IdData);
    731     gBS->FreePool (IdeDev->InquiryData);
    732     //
    733     // Make sure the pIdData and pInquiryData will not be freed again.
    734     //
    735     IdeDev->IdData       = NULL;
    736     IdeDev->InquiryData  = NULL;
    737     return EFI_DEVICE_ERROR;
    738   }
    739 
    740   //
    741   // original sense data numbers
    742   //
    743   IdeDev->SenseDataNumber = 20;
    744 
    745   IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA));
    746   if (IdeDev->SenseData == NULL) {
    747     gBS->FreePool (IdeDev->IdData);
    748     gBS->FreePool (IdeDev->InquiryData);
    749     //
    750     // Make sure the pIdData and pInquiryData will not be freed again.
    751     //
    752     IdeDev->IdData       = NULL;
    753     IdeDev->InquiryData  = NULL;
    754     return EFI_OUT_OF_RESOURCES;
    755   }
    756 
    757   return EFI_SUCCESS;
    758 }
    759 /**
    760   Sends out ATAPI Request Sense Packet Command to the specified device. This command
    761   will return all the current Sense data in the device.  This function will pack
    762   all the Sense data in one single buffer.
    763 
    764   @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used
    765                       to record all the information of the IDE device.
    766   @param SenseCounts  allocated in this function, and freed by the calling function.
    767                       This buffer is used to accommodate all the sense data returned
    768                       by the device.
    769 
    770   @retval EFI_SUCCESS      Request Sense command completes successfully.
    771   @retval EFI_DEVICE_ERROR Request Sense command failed.
    772 **/
    773 EFI_STATUS
    774 AtapiRequestSense (
    775   IN  IDE_BLK_IO_DEV  *IdeDev,
    776   OUT UINTN           *SenseCounts
    777   )
    778 {
    779   EFI_STATUS            Status;
    780   ATAPI_REQUEST_SENSE_DATA    *Sense;
    781   UINT16                *Ptr;
    782   BOOLEAN               FetchSenseData;
    783   ATAPI_PACKET_COMMAND  Packet;
    784 
    785   *SenseCounts = 0;
    786 
    787   ZeroMem (IdeDev->SenseData, sizeof (ATAPI_REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber));
    788   //
    789   // fill command packet for Request Sense Packet Command
    790   //
    791   ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
    792   Packet.RequestSence.opcode            = ATA_CMD_REQUEST_SENSE;
    793   Packet.RequestSence.allocation_length = (UINT8) sizeof (ATAPI_REQUEST_SENSE_DATA);
    794 
    795   //
    796   // initialize pointer
    797   //
    798   Ptr = (UINT16 *) IdeDev->SenseData;
    799   //
    800   //  request sense data from device continuously until no sense data
    801   //  exists in the device.
    802   //
    803   for (FetchSenseData = TRUE; FetchSenseData;) {
    804 
    805     Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr;
    806 
    807     //
    808     // send out Request Sense Packet Command and get one Sense data form device
    809     //
    810     Status = AtapiPacketCommandIn (
    811               IdeDev,
    812               &Packet,
    813               Ptr,
    814               sizeof (ATAPI_REQUEST_SENSE_DATA),
    815               ATAPITIMEOUT
    816               );
    817     //
    818     // failed to get Sense data
    819     //
    820     if (EFI_ERROR (Status)) {
    821       if (*SenseCounts == 0) {
    822         return EFI_DEVICE_ERROR;
    823       } else {
    824         return EFI_SUCCESS;
    825       }
    826     }
    827 
    828     (*SenseCounts)++;
    829     //
    830     // We limit MAX sense data count to 20 in order to avoid dead loop. Some
    831     // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
    832     // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
    833     // supposed to be large enough for any ATAPI device.
    834     //
    835     if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {
    836       //
    837       // Ptr is word-based pointer
    838       //
    839       Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1;
    840 
    841     } else {
    842       //
    843       // when no sense key, skip out the loop
    844       //
    845       FetchSenseData = FALSE;
    846     }
    847   }
    848 
    849   return EFI_SUCCESS;
    850 }
    851 /**
    852   This function is used to parse sense data. Only the first sense data is honoured
    853 
    854   @param IdeDev     Indicates the calling context.
    855   @param SenseCount Count of sense data.
    856   @param Result    The parsed result.
    857 
    858   @retval EFI_SUCCESS           Successfully parsed.
    859   @retval EFI_INVALID_PARAMETER Count of sense data is zero.
    860 
    861 **/
    862 EFI_STATUS
    863 ParseSenseData (
    864   IN IDE_BLK_IO_DEV     *IdeDev,
    865   IN UINTN              SenseCount,
    866   OUT SENSE_RESULT      *Result
    867   )
    868 {
    869   ATAPI_REQUEST_SENSE_DATA      *SenseData;
    870 
    871   if (SenseCount == 0) {
    872     return EFI_INVALID_PARAMETER;
    873   }
    874 
    875   //
    876   // Only use the first sense data
    877   //
    878   SenseData = IdeDev->SenseData;
    879   *Result   = SenseOtherSense;
    880 
    881   switch (SenseData->sense_key) {
    882   case ATA_SK_NO_SENSE:
    883     *Result = SenseNoSenseKey;
    884     break;
    885   case ATA_SK_NOT_READY:
    886     switch (SenseData->addnl_sense_code) {
    887     case ATA_ASC_NO_MEDIA:
    888       *Result = SenseNoMedia;
    889       break;
    890     case ATA_ASC_MEDIA_UPSIDE_DOWN:
    891       *Result = SenseMediaError;
    892       break;
    893     case ATA_ASC_NOT_READY:
    894       if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) {
    895         *Result = SenseDeviceNotReadyNeedRetry;
    896       } else {
    897         *Result = SenseDeviceNotReadyNoRetry;
    898       }
    899       break;
    900     }
    901     break;
    902   case ATA_SK_UNIT_ATTENTION:
    903     if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) {
    904       *Result = SenseMediaChange;
    905     }
    906     break;
    907   case ATA_SK_MEDIUM_ERROR:
    908     switch (SenseData->addnl_sense_code) {
    909     case ATA_ASC_MEDIA_ERR1:
    910     case ATA_ASC_MEDIA_ERR2:
    911     case ATA_ASC_MEDIA_ERR3:
    912     case ATA_ASC_MEDIA_ERR4:
    913       *Result = SenseMediaError;
    914       break;
    915     }
    916     break;
    917   default:
    918     break;
    919   }
    920 
    921   return EFI_SUCCESS;
    922 }
    923 
    924 /**
    925   Sends out ATAPI Test Unit Ready Packet Command to the specified device
    926   to find out whether device is accessible.
    927 
    928   @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used
    929                    to record all the information of the IDE device.
    930   @param SResult   Sense result for this packet command.
    931 
    932   @retval EFI_SUCCESS      Device is accessible.
    933   @retval EFI_DEVICE_ERROR Device is not accessible.
    934 
    935 **/
    936 EFI_STATUS
    937 AtapiTestUnitReady (
    938   IN  IDE_BLK_IO_DEV  *IdeDev,
    939   OUT SENSE_RESULT    *SResult
    940   )
    941 {
    942   ATAPI_PACKET_COMMAND  Packet;
    943   EFI_STATUS            Status;
    944   UINTN 				SenseCount;
    945 
    946   //
    947   // fill command packet
    948   //
    949   ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
    950   Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;
    951 
    952   //
    953   // send command packet
    954   //
    955   Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);
    956   if (EFI_ERROR (Status)) {
    957     return Status;
    958   }
    959 
    960   Status = AtapiRequestSense (IdeDev, &SenseCount);
    961   if (EFI_ERROR (Status)) {
    962     return Status;
    963   }
    964 
    965   ParseSenseData (IdeDev, SenseCount, SResult);
    966   return EFI_SUCCESS;
    967 }
    968 
    969 
    970 /**
    971   Sends out ATAPI Read Capacity Packet Command to the specified device.
    972   This command will return the information regarding the capacity of the
    973   media in the device.
    974 
    975   Current device status will impact device's response to the Read Capacity
    976   Command. For example, if the device once reset, the Read Capacity
    977   Command will fail. The Sense data record the current device status, so
    978   if the Read Capacity Command failed, the Sense data must be requested
    979   and be analyzed to determine if the Read Capacity Command should retry.
    980 
    981   @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used
    982                    to record all the information of the IDE device.
    983   @param SResult   Sense result for this packet command
    984 
    985   @retval EFI_SUCCESS      Read Capacity Command finally completes successfully.
    986   @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.
    987   @retval EFI_NOT_READY    Operation succeeds but returned capacity is 0
    988 
    989   @note Parameter "IdeDev" will be updated in this function.
    990 
    991 
    992 **/
    993 EFI_STATUS
    994 AtapiReadCapacity (
    995   IN  IDE_BLK_IO_DEV  *IdeDev,
    996   OUT SENSE_RESULT	  *SResult
    997   )
    998 {
    999   //
   1000   // status returned by Read Capacity Packet Command
   1001   //
   1002   EFI_STATUS                Status;
   1003   EFI_STATUS                SenseStatus;
   1004   ATAPI_PACKET_COMMAND      Packet;
   1005   UINTN 					SenseCount;
   1006 
   1007   //
   1008   // used for capacity data returned from ATAPI device
   1009   //
   1010   ATAPI_READ_CAPACITY_DATA        Data;
   1011   ATAPI_READ_FORMAT_CAPACITY_DATA FormatData;
   1012 
   1013   ZeroMem (&Data, sizeof (Data));
   1014   ZeroMem (&FormatData, sizeof (FormatData));
   1015 
   1016   if (IdeDev->Type == IdeCdRom) {
   1017 
   1018     ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
   1019     Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;
   1020     Status = AtapiPacketCommandIn (
   1021                IdeDev,
   1022                &Packet,
   1023                (UINT16 *) &Data,
   1024                sizeof (ATAPI_READ_CAPACITY_DATA),
   1025                ATAPITIMEOUT
   1026                );
   1027 
   1028   } else {
   1029     //
   1030     // Type == IdeMagnetic
   1031     //
   1032     ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
   1033     Packet.ReadFormatCapacity.opcode                = ATA_CMD_READ_FORMAT_CAPACITY;
   1034     Packet.ReadFormatCapacity.allocation_length_lo  = 12;
   1035     Status = AtapiPacketCommandIn (
   1036                IdeDev,
   1037                &Packet,
   1038                (UINT16 *) &FormatData,
   1039                sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA),
   1040                ATAPITIMEOUT
   1041                );
   1042   }
   1043 
   1044   if (Status == EFI_TIMEOUT) {
   1045     return Status;
   1046   }
   1047 
   1048   SenseStatus = AtapiRequestSense (IdeDev, &SenseCount);
   1049 
   1050   if (!EFI_ERROR (SenseStatus)) {
   1051 	ParseSenseData (IdeDev, SenseCount, SResult);
   1052 
   1053 	if (!EFI_ERROR (Status) && *SResult == SenseNoSenseKey) {
   1054       if (IdeDev->Type == IdeCdRom) {
   1055 
   1056         IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |
   1057           (Data.LastLba2 << 16) |
   1058           (Data.LastLba1 << 8) |
   1059           Data.LastLba0;
   1060 
   1061 	      IdeDev->BlkIo.Media->MediaPresent = TRUE;
   1062 
   1063         IdeDev->BlkIo.Media->ReadOnly = TRUE;
   1064 
   1065         //
   1066         // Because the user data portion in the sector of the Data CD supported
   1067         // is always 0x800
   1068         //
   1069         IdeDev->BlkIo.Media->BlockSize = 0x800;
   1070       }
   1071 
   1072       if (IdeDev->Type == IdeMagnetic) {
   1073 
   1074         if (FormatData.DesCode == 3) {
   1075           IdeDev->BlkIo.Media->MediaPresent = FALSE;
   1076           IdeDev->BlkIo.Media->LastBlock    = 0;
   1077         } else {
   1078 
   1079           IdeDev->BlkIo.Media->LastBlock =  (FormatData.LastLba3 << 24) |
   1080             (FormatData.LastLba2 << 16) |
   1081             (FormatData.LastLba1 << 8)  |
   1082             FormatData.LastLba0;
   1083           if (IdeDev->BlkIo.Media->LastBlock != 0) {
   1084             IdeDev->BlkIo.Media->LastBlock--;
   1085 
   1086             IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |
   1087               (FormatData.BlockSize1 << 8) |
   1088               FormatData.BlockSize0;
   1089 
   1090             IdeDev->BlkIo.Media->MediaPresent = TRUE;
   1091           } else {
   1092             IdeDev->BlkIo.Media->MediaPresent = FALSE;
   1093             //
   1094             // Return EFI_NOT_READY operation succeeds but returned capacity is 0
   1095             //
   1096             return EFI_NOT_READY;
   1097           }
   1098 
   1099           IdeDev->BlkIo.Media->BlockSize = 0x200;
   1100 
   1101         }
   1102       }
   1103     }
   1104 
   1105     return EFI_SUCCESS;
   1106 
   1107   } else {
   1108     return EFI_DEVICE_ERROR;
   1109   }
   1110 }
   1111 /**
   1112   This function is used to test the current media write-protected or not residing
   1113   in the LS-120 drive or ZIP drive.
   1114   @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used
   1115                          to record all the information of the IDE device.
   1116   @param WriteProtected  if True, current media is write protected.
   1117                          if FALSE, current media is writable
   1118 
   1119   @retval EFI_SUCCESS         The media write-protected status is achieved successfully
   1120   @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.
   1121 **/
   1122 EFI_STATUS
   1123 IsLS120orZipWriteProtected (
   1124   IN  IDE_BLK_IO_DEV    *IdeDev,
   1125   OUT BOOLEAN           *WriteProtected
   1126   )
   1127 {
   1128   EFI_STATUS  Status;
   1129 
   1130   *WriteProtected = FALSE;
   1131 
   1132   Status          = LS120EnableMediaStatus (IdeDev, TRUE);
   1133   if (EFI_ERROR (Status)) {
   1134     return EFI_DEVICE_ERROR;
   1135   }
   1136 
   1137   //
   1138   // the Get Media Status Command is only valid
   1139   // if a Set Features/Enable Media Status Command has been priviously issued.
   1140   //
   1141   if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {
   1142 
   1143     *WriteProtected = TRUE;
   1144   } else {
   1145 
   1146     *WriteProtected = FALSE;
   1147   }
   1148 
   1149   //
   1150   // After Get Media Status Command completes,
   1151   // Set Features/Disable Media Command should be sent.
   1152   //
   1153   Status = LS120EnableMediaStatus (IdeDev, FALSE);
   1154   if (EFI_ERROR (Status)) {
   1155     return EFI_DEVICE_ERROR;
   1156   }
   1157 
   1158   return EFI_SUCCESS;
   1159 }
   1160 
   1161 /**
   1162   Used before read/write blocks from/to ATAPI device media. Since ATAPI device
   1163   media is removable, it is necessary to detect whether media is present and
   1164   get current present media's information, and if media has been changed, Block
   1165   I/O Protocol need to be reinstalled.
   1166 
   1167   @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used
   1168                       to record all the information of the IDE device.
   1169   @param MediaChange  return value that indicates if the media of the device has been
   1170                       changed.
   1171 
   1172   @retval EFI_SUCCESS       media found successfully.
   1173   @retval EFI_DEVICE_ERROR  any error encounters during media detection.
   1174   @retval EFI_NO_MEDIA      media not found.
   1175 
   1176   @note
   1177   parameter IdeDev may be updated in this function.
   1178 
   1179 **/
   1180 EFI_STATUS
   1181 AtapiDetectMedia (
   1182   IN  IDE_BLK_IO_DEV  *IdeDev,
   1183   OUT BOOLEAN         *MediaChange
   1184   )
   1185 {
   1186   EFI_STATUS                    Status;
   1187   EFI_STATUS                    CleanStateStatus;
   1188   EFI_BLOCK_IO_MEDIA            OldMediaInfo;
   1189   UINTN                         RetryTimes;
   1190   UINTN                         RetryNotReady;
   1191   SENSE_RESULT                  SResult;
   1192   BOOLEAN                       WriteProtected;
   1193 
   1194   CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (EFI_BLOCK_IO_MEDIA));
   1195   *MediaChange  = FALSE;
   1196   //
   1197   // Retry for SenseDeviceNotReadyNeedRetry.
   1198   // Each retry takes 1s and we limit the upper boundary to
   1199   // 120 times about 2 min.
   1200   //
   1201   RetryNotReady = 120;
   1202 
   1203   //
   1204   // Do Test Unit Ready
   1205   //
   1206  DoTUR:
   1207   //
   1208   // Retry 5 times
   1209   //
   1210   RetryTimes = 5;
   1211   while (RetryTimes != 0) {
   1212 
   1213     Status = AtapiTestUnitReady (IdeDev, &SResult);
   1214 
   1215     if (EFI_ERROR (Status)) {
   1216       //
   1217       // Test Unit Ready error without sense data.
   1218       // For some devices, this means there's extra data
   1219       // that has not been read, so we read these extra
   1220       // data out before going on.
   1221       //
   1222       CleanStateStatus = AtapiReadPendingData (IdeDev);
   1223       if (EFI_ERROR (CleanStateStatus)) {
   1224         //
   1225         // Busy wait failed, try again
   1226         //
   1227         RetryTimes--;
   1228       }
   1229       //
   1230       // Try again without counting down RetryTimes
   1231       //
   1232       continue;
   1233     } else {
   1234       switch (SResult) {
   1235       case SenseNoSenseKey:
   1236         if (IdeDev->BlkIo.Media->MediaPresent) {
   1237           goto Done;
   1238         } else {
   1239           //
   1240           // Media present but the internal structure need refreshed.
   1241           // Try Read Capacity
   1242           //
   1243           goto DoRC;
   1244         }
   1245         break;
   1246 
   1247       case SenseDeviceNotReadyNeedRetry:
   1248         if (--RetryNotReady == 0) {
   1249           return EFI_DEVICE_ERROR;
   1250         }
   1251         gBS->Stall (1000 * STALL_1_MILLI_SECOND);
   1252         continue;
   1253         break;
   1254 
   1255       case SenseNoMedia:
   1256         IdeDev->BlkIo.Media->MediaPresent = FALSE;
   1257         IdeDev->BlkIo.Media->LastBlock    = 0;
   1258         goto Done;
   1259         break;
   1260 
   1261       case SenseDeviceNotReadyNoRetry:
   1262       case SenseMediaError:
   1263         return EFI_DEVICE_ERROR;
   1264 
   1265       case SenseMediaChange:
   1266         IdeDev->BlkIo.Media->MediaId++;
   1267         goto DoRC;
   1268         break;
   1269 
   1270       default:
   1271         RetryTimes--;
   1272         break;
   1273       }
   1274     }
   1275   }
   1276 
   1277   return EFI_DEVICE_ERROR;
   1278 
   1279   //
   1280   // Do Read Capacity
   1281   //
   1282  DoRC:
   1283     RetryTimes = 5;
   1284 
   1285     while (RetryTimes != 0) {
   1286 
   1287       Status = AtapiReadCapacity (IdeDev, &SResult);
   1288 
   1289       if (EFI_ERROR (Status)) {
   1290         RetryTimes--;
   1291         continue;
   1292       } else {
   1293         switch (SResult) {
   1294         case SenseNoSenseKey:
   1295           goto Done;
   1296           break;
   1297 
   1298         case SenseDeviceNotReadyNeedRetry:
   1299           //
   1300           // We use Test Unit Ready to retry which
   1301           // is faster.
   1302           //
   1303           goto DoTUR;
   1304           break;
   1305 
   1306         case SenseNoMedia:
   1307           IdeDev->BlkIo.Media->MediaPresent = FALSE;
   1308           IdeDev->BlkIo.Media->LastBlock    = 0;
   1309           goto Done;
   1310           break;
   1311 
   1312         case SenseDeviceNotReadyNoRetry:
   1313         case SenseMediaError:
   1314           return EFI_DEVICE_ERROR;
   1315 
   1316         case SenseMediaChange:
   1317           IdeDev->BlkIo.Media->MediaId++;
   1318           continue;
   1319           break;
   1320 
   1321         default:
   1322           RetryTimes--;
   1323           break;
   1324         }
   1325       }
   1326     }
   1327 
   1328   return EFI_DEVICE_ERROR;
   1329 
   1330  Done:
   1331   //
   1332   // the following code is to check the write-protected for LS120 media
   1333   //
   1334   if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) {
   1335 
   1336     Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected);
   1337     if (!EFI_ERROR (Status)) {
   1338 
   1339       if (WriteProtected) {
   1340 
   1341         IdeDev->BlkIo.Media->ReadOnly = TRUE;
   1342       } else {
   1343 
   1344         IdeDev->BlkIo.Media->ReadOnly = FALSE;
   1345       }
   1346 
   1347     }
   1348   }
   1349 
   1350   if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {
   1351     //
   1352     // Media change information got from the device
   1353     //
   1354     *MediaChange = TRUE;
   1355   }
   1356 
   1357   if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {
   1358     *MediaChange = TRUE;
   1359     IdeDev->BlkIo.Media->MediaId += 1;
   1360   }
   1361 
   1362   if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {
   1363     *MediaChange = TRUE;
   1364     IdeDev->BlkIo.Media->MediaId += 1;
   1365   }
   1366 
   1367   if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {
   1368     *MediaChange = TRUE;
   1369     IdeDev->BlkIo.Media->MediaId += 1;
   1370   }
   1371 
   1372   if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {
   1373     if (IdeDev->BlkIo.Media->MediaPresent) {
   1374       //
   1375       // when change from no media to media present, reset the MediaId to 1.
   1376       //
   1377       IdeDev->BlkIo.Media->MediaId = 1;
   1378     } else {
   1379       //
   1380       // when no media, reset the MediaId to zero.
   1381       //
   1382       IdeDev->BlkIo.Media->MediaId = 0;
   1383     }
   1384 
   1385     *MediaChange = TRUE;
   1386   }
   1387 
   1388   //
   1389   // if any change on current existing media,
   1390   // the Block I/O protocol need to be reinstalled.
   1391   //
   1392   if (*MediaChange) {
   1393     gBS->ReinstallProtocolInterface (
   1394           IdeDev->Handle,
   1395           &gEfiBlockIoProtocolGuid,
   1396           &IdeDev->BlkIo,
   1397           &IdeDev->BlkIo
   1398           );
   1399   }
   1400 
   1401   if (IdeDev->BlkIo.Media->MediaPresent) {
   1402     return EFI_SUCCESS;
   1403   } else {
   1404     return EFI_NO_MEDIA;
   1405   }
   1406 }
   1407 
   1408 /**
   1409   This function is called by the AtapiBlkIoReadBlocks() to perform
   1410   read from media in block unit.
   1411 
   1412   The main command used to access media here is READ(10) Command.
   1413   READ(10) Command requests that the ATAPI device media transfer
   1414   specified data to the host. Data is transferred in block(sector)
   1415   unit. The maximum number of blocks that can be transferred once is
   1416   65536. This is the main difference between READ(10) and READ(12)
   1417   Command. The maximum number of blocks in READ(12) is 2 power 32.
   1418 
   1419   @param IdeDev           pointer pointing to IDE_BLK_IO_DEV data structure, used
   1420                           to record all the information of the IDE device.
   1421   @param Buffer           A pointer to the destination buffer for the data.
   1422   @param Lba              The starting logical block address to read from on the
   1423                           device media.
   1424   @param NumberOfBlocks   The number of transfer data blocks.
   1425 
   1426   @return status is fully dependent on the return status of AtapiPacketCommandIn() function.
   1427 
   1428 **/
   1429 EFI_STATUS
   1430 AtapiReadSectors (
   1431   IN  IDE_BLK_IO_DEV  *IdeDev,
   1432   IN  VOID            *Buffer,
   1433   IN  EFI_LBA         Lba,
   1434   IN  UINTN           NumberOfBlocks
   1435   )
   1436 {
   1437 
   1438   ATAPI_PACKET_COMMAND  Packet;
   1439   ATAPI_READ10_CMD            *Read10Packet;
   1440   EFI_STATUS            Status;
   1441   UINTN                 BlocksRemaining;
   1442   UINT32                Lba32;
   1443   UINT32                BlockSize;
   1444   UINT32                ByteCount;
   1445   UINT16                SectorCount;
   1446   VOID                  *PtrBuffer;
   1447   UINT16                MaxBlock;
   1448   UINTN                 TimeOut;
   1449 
   1450   //
   1451   // fill command packet for Read(10) command
   1452   //
   1453   ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
   1454   Read10Packet  = &Packet.Read10;
   1455   Lba32         = (UINT32) Lba;
   1456   PtrBuffer     = Buffer;
   1457 
   1458   BlockSize     = IdeDev->BlkIo.Media->BlockSize;
   1459 
   1460   //
   1461   // limit the data bytes that can be transferred by one Read(10) Command
   1462   //
   1463   MaxBlock        = 65535;
   1464 
   1465   BlocksRemaining = NumberOfBlocks;
   1466 
   1467   Status          = EFI_SUCCESS;
   1468   while (BlocksRemaining > 0) {
   1469 
   1470     if (BlocksRemaining <= MaxBlock) {
   1471 
   1472       SectorCount = (UINT16) BlocksRemaining;
   1473     } else {
   1474 
   1475       SectorCount = MaxBlock;
   1476     }
   1477 
   1478     //
   1479     // fill the Packet data structure
   1480     //
   1481 
   1482     Read10Packet->opcode = ATA_CMD_READ_10;
   1483 
   1484     //
   1485     // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
   1486     // Lba0 is MSB, Lba3 is LSB
   1487     //
   1488     Read10Packet->Lba3  = (UINT8) (Lba32 & 0xff);
   1489     Read10Packet->Lba2  = (UINT8) (Lba32 >> 8);
   1490     Read10Packet->Lba1  = (UINT8) (Lba32 >> 16);
   1491     Read10Packet->Lba0  = (UINT8) (Lba32 >> 24);
   1492 
   1493     //
   1494     // TranLen0 ~ TranLen1 specify the transfer length in block unit.
   1495     // TranLen0 is MSB, TranLen is LSB
   1496     //
   1497     Read10Packet->TranLen1  = (UINT8) (SectorCount & 0xff);
   1498     Read10Packet->TranLen0  = (UINT8) (SectorCount >> 8);
   1499 
   1500     ByteCount               = SectorCount * BlockSize;
   1501 
   1502     if (IdeDev->Type == IdeCdRom) {
   1503       TimeOut = CDROMLONGTIMEOUT;
   1504     } else {
   1505       TimeOut = ATAPILONGTIMEOUT;
   1506     }
   1507 
   1508     Status = AtapiPacketCommandIn (
   1509               IdeDev,
   1510               &Packet,
   1511               (UINT16 *) PtrBuffer,
   1512               ByteCount,
   1513               TimeOut
   1514               );
   1515     if (EFI_ERROR (Status)) {
   1516       return Status;
   1517     }
   1518 
   1519     Lba32 += SectorCount;
   1520     PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;
   1521     BlocksRemaining -= SectorCount;
   1522   }
   1523 
   1524   return Status;
   1525 }
   1526 
   1527 /**
   1528   This function is called by the AtapiBlkIoWriteBlocks() to perform
   1529   write onto media in block unit.
   1530   The main command used to access media here is Write(10) Command.
   1531   Write(10) Command requests that the ATAPI device media transfer
   1532   specified data to the host. Data is transferred in block (sector)
   1533   unit. The maximum number of blocks that can be transferred once is
   1534   65536.
   1535 
   1536   @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used
   1537                          to record all the information of the IDE device.
   1538   @param Buffer          A pointer to the source buffer for the data.
   1539   @param Lba             The starting logical block address to write onto
   1540                          the device media.
   1541   @param NumberOfBlocks  The number of transfer data blocks.
   1542 
   1543   @return status is fully dependent on the return status of AtapiPacketCommandOut() function.
   1544 
   1545 **/
   1546 EFI_STATUS
   1547 AtapiWriteSectors (
   1548   IN  IDE_BLK_IO_DEV  *IdeDev,
   1549   IN  VOID            *Buffer,
   1550   IN  EFI_LBA         Lba,
   1551   IN  UINTN           NumberOfBlocks
   1552   )
   1553 {
   1554 
   1555   ATAPI_PACKET_COMMAND  Packet;
   1556   ATAPI_READ10_CMD            *Read10Packet;
   1557 
   1558   EFI_STATUS            Status;
   1559   UINTN                 BlocksRemaining;
   1560   UINT32                Lba32;
   1561   UINT32                BlockSize;
   1562   UINT32                ByteCount;
   1563   UINT16                SectorCount;
   1564   VOID                  *PtrBuffer;
   1565   UINT16                MaxBlock;
   1566 
   1567   //
   1568   // fill command packet for Write(10) command
   1569   // Write(10) command packet has the same data structure as
   1570   // Read(10) command packet,
   1571   // so here use the Read10Packet data structure
   1572   // for the Write(10) command packet.
   1573   //
   1574   ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
   1575   Read10Packet  = &Packet.Read10;
   1576 
   1577   Lba32         = (UINT32) Lba;
   1578   PtrBuffer     = Buffer;
   1579 
   1580   BlockSize     = IdeDev->BlkIo.Media->BlockSize;
   1581 
   1582   //
   1583   // limit the data bytes that can be transferred by one Read(10) Command
   1584   //
   1585   MaxBlock        = (UINT16) (65536 / BlockSize);
   1586 
   1587   BlocksRemaining = NumberOfBlocks;
   1588 
   1589   Status          = EFI_SUCCESS;
   1590   while (BlocksRemaining > 0) {
   1591 
   1592     if (BlocksRemaining >= MaxBlock) {
   1593       SectorCount = MaxBlock;
   1594     } else {
   1595       SectorCount = (UINT16) BlocksRemaining;
   1596     }
   1597 
   1598     //
   1599     // Command code is WRITE_10.
   1600     //
   1601     Read10Packet->opcode = ATA_CMD_WRITE_10;
   1602 
   1603     //
   1604     // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
   1605     // Lba0 is MSB, Lba3 is LSB
   1606     //
   1607     Read10Packet->Lba3  = (UINT8) (Lba32 & 0xff);
   1608     Read10Packet->Lba2  = (UINT8) (Lba32 >> 8);
   1609     Read10Packet->Lba1  = (UINT8) (Lba32 >> 16);
   1610     Read10Packet->Lba0  = (UINT8) (Lba32 >> 24);
   1611 
   1612     //
   1613     // TranLen0 ~ TranLen1 specify the transfer length in block unit.
   1614     // TranLen0 is MSB, TranLen is LSB
   1615     //
   1616     Read10Packet->TranLen1  = (UINT8) (SectorCount & 0xff);
   1617     Read10Packet->TranLen0  = (UINT8) (SectorCount >> 8);
   1618 
   1619     ByteCount               = SectorCount * BlockSize;
   1620 
   1621     Status = AtapiPacketCommandOut (
   1622               IdeDev,
   1623               &Packet,
   1624               (UINT16 *) PtrBuffer,
   1625               ByteCount,
   1626               ATAPILONGTIMEOUT
   1627               );
   1628     if (EFI_ERROR (Status)) {
   1629       return Status;
   1630     }
   1631 
   1632     Lba32 += SectorCount;
   1633     PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize);
   1634     BlocksRemaining -= SectorCount;
   1635   }
   1636 
   1637   return Status;
   1638 }
   1639 /**
   1640   This function is used to implement the Soft Reset on the specified
   1641   ATAPI device. Different from the AtaSoftReset(), here reset is a ATA
   1642   Soft Reset Command special for ATAPI device, and it only take effects
   1643   on the specified ATAPI device, not on the whole IDE bus.
   1644   Since the ATAPI soft reset is needed when device is in exceptional
   1645   condition (such as BSY bit is always set ), I think the Soft Reset
   1646   command should be sent without waiting for the BSY clear and DRDY
   1647   set.
   1648   This function is called by IdeBlkIoReset(),
   1649   a interface function of Block I/O protocol.
   1650 
   1651   @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used
   1652                    to record all the information of the IDE device.
   1653 
   1654   @retval EFI_SUCCESS      Soft reset completes successfully.
   1655   @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
   1656 
   1657 **/
   1658 EFI_STATUS
   1659 AtapiSoftReset (
   1660   IN  IDE_BLK_IO_DEV  *IdeDev
   1661   )
   1662 {
   1663   UINT8       Command;
   1664   UINT8       DeviceSelect;
   1665   EFI_STATUS  Status;
   1666 
   1667   //
   1668   // for ATAPI device, no need to wait DRDY ready after device selecting.
   1669   // (bit7 and bit5 are both set to 1 for backward compatibility)
   1670   //
   1671   DeviceSelect = (UINT8) (((BIT7 | BIT5) | (IdeDev->Device << 4)));
   1672   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);
   1673 
   1674   Command = ATA_CMD_SOFT_RESET;
   1675   IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command);
   1676 
   1677   //
   1678   // BSY cleared is the only status return to the host by the device
   1679   // when reset is completed.
   1680   // slave device needs at most 31s to clear BSY
   1681   //
   1682   Status = WaitForBSYClear (IdeDev, 31000);
   1683   if (EFI_ERROR (Status)) {
   1684     return EFI_DEVICE_ERROR;
   1685   }
   1686 
   1687   //
   1688   // stall 5 seconds to make the device status stable
   1689   //
   1690   gBS->Stall (5000000);
   1691 
   1692   return EFI_SUCCESS;
   1693 }
   1694 
   1695 /**
   1696   This function is the ATAPI implementation for ReadBlocks in the
   1697   Block I/O Protocol interface.
   1698 
   1699   @param IdeBlkIoDevice Indicates the calling context.
   1700   @param MediaId        The media id that the read request is for.
   1701   @param Lba            The starting logical block address to read from on the device.
   1702   @param BufferSize     The size of the Buffer in bytes. This must be a multiple
   1703                         of the intrinsic block size of the device.
   1704   @param Buffer         A pointer to the destination buffer for the data. The caller
   1705                         is responsible for either having implicit or explicit
   1706                         ownership of the memory that data is read into.
   1707 
   1708   @retval EFI_SUCCESS           Read Blocks successfully.
   1709   @retval EFI_DEVICE_ERROR      Read Blocks failed.
   1710   @retval EFI_NO_MEDIA          There is no media in the device.
   1711   @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.
   1712   @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the
   1713                                 intrinsic block size of the device.
   1714   @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
   1715                                 or the data buffer is not valid.
   1716 **/
   1717 EFI_STATUS
   1718 AtapiBlkIoReadBlocks (
   1719   IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,
   1720   IN UINT32           MediaId,
   1721   IN EFI_LBA          Lba,
   1722   IN UINTN            BufferSize,
   1723   OUT VOID            *Buffer
   1724   )
   1725 {
   1726   EFI_BLOCK_IO_MEDIA  *Media;
   1727   UINTN               BlockSize;
   1728   UINTN               NumberOfBlocks;
   1729   EFI_STATUS          Status;
   1730 
   1731   BOOLEAN             MediaChange;
   1732 
   1733   if (Buffer == NULL) {
   1734     return EFI_INVALID_PARAMETER;
   1735   }
   1736 
   1737   if (BufferSize == 0) {
   1738     return EFI_SUCCESS;
   1739   }
   1740 
   1741   //
   1742   // ATAPI device media is removable, so it is a must
   1743   // to detect media first before read operation
   1744   //
   1745   MediaChange = FALSE;
   1746   Status      = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);
   1747   if (EFI_ERROR (Status)) {
   1748 
   1749     if (IdeBlkIoDevice->Cache != NULL) {
   1750       gBS->FreePool (IdeBlkIoDevice->Cache);
   1751       IdeBlkIoDevice->Cache = NULL;
   1752     }
   1753 
   1754     return Status;
   1755   }
   1756   //
   1757   // Get the intrinsic block size
   1758   //
   1759   Media           = IdeBlkIoDevice->BlkIo.Media;
   1760   BlockSize       = Media->BlockSize;
   1761 
   1762   NumberOfBlocks  = BufferSize / BlockSize;
   1763 
   1764   if (!(Media->MediaPresent)) {
   1765 
   1766     if (IdeBlkIoDevice->Cache != NULL) {
   1767       gBS->FreePool (IdeBlkIoDevice->Cache);
   1768       IdeBlkIoDevice->Cache = NULL;
   1769     }
   1770     return EFI_NO_MEDIA;
   1771 
   1772   }
   1773 
   1774   if ((MediaId != Media->MediaId) || MediaChange) {
   1775 
   1776     if (IdeBlkIoDevice->Cache != NULL) {
   1777       gBS->FreePool (IdeBlkIoDevice->Cache);
   1778       IdeBlkIoDevice->Cache = NULL;
   1779     }
   1780     return EFI_MEDIA_CHANGED;
   1781   }
   1782 
   1783   if (BufferSize % BlockSize != 0) {
   1784     return EFI_BAD_BUFFER_SIZE;
   1785   }
   1786 
   1787   if (Lba > Media->LastBlock) {
   1788     return EFI_INVALID_PARAMETER;
   1789   }
   1790 
   1791   if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
   1792     return EFI_INVALID_PARAMETER;
   1793   }
   1794 
   1795   if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
   1796     return EFI_INVALID_PARAMETER;
   1797   }
   1798 
   1799   //
   1800   // if all the parameters are valid, then perform read sectors command
   1801   // to transfer data from device to host.
   1802   //
   1803   Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
   1804   if (EFI_ERROR (Status)) {
   1805     return EFI_DEVICE_ERROR;
   1806   }
   1807 
   1808   //
   1809   // Read blocks succeeded
   1810   //
   1811 
   1812   //
   1813   // save the first block to the cache for performance
   1814   //
   1815   if (Lba == 0 && (IdeBlkIoDevice->Cache == NULL)) {
   1816     IdeBlkIoDevice->Cache = AllocatePool (BlockSize);
   1817     if (IdeBlkIoDevice->Cache!= NULL) {
   1818       CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize);
   1819     }
   1820   }
   1821 
   1822   return EFI_SUCCESS;
   1823 
   1824 }
   1825 /**
   1826   This function is the ATAPI implementation for WriteBlocks in the
   1827   Block I/O Protocol interface.
   1828 
   1829   @param IdeBlkIoDevice  Indicates the calling context.
   1830   @param MediaId         The media id that the write request is for.
   1831   @param Lba             The starting logical block address to write onto the device.
   1832   @param BufferSize      The size of the Buffer in bytes. This must be a multiple
   1833                          of the intrinsic block size of the device.
   1834   @param Buffer          A pointer to the source buffer for the data. The caller
   1835                          is responsible for either having implicit or explicit ownership
   1836                          of the memory that data is written from.
   1837 
   1838   @retval EFI_SUCCESS            Write Blocks successfully.
   1839   @retval EFI_DEVICE_ERROR       Write Blocks failed.
   1840   @retval EFI_NO_MEDIA           There is no media in the device.
   1841   @retval EFI_MEDIA_CHANGE       The MediaId is not for the current media.
   1842   @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the
   1843                                  intrinsic block size of the device.
   1844   @retval EFI_INVALID_PARAMETER  The write request contains LBAs that are not valid,
   1845                                  or the data buffer is not valid.
   1846 
   1847   @retval EFI_WRITE_PROTECTED    The write protected is enabled or the media does not support write
   1848 **/
   1849 EFI_STATUS
   1850 AtapiBlkIoWriteBlocks (
   1851   IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,
   1852   IN UINT32           MediaId,
   1853   IN EFI_LBA          Lba,
   1854   IN UINTN            BufferSize,
   1855   OUT VOID            *Buffer
   1856   )
   1857 {
   1858 
   1859   EFI_BLOCK_IO_MEDIA  *Media;
   1860   UINTN               BlockSize;
   1861   UINTN               NumberOfBlocks;
   1862   EFI_STATUS          Status;
   1863   BOOLEAN             MediaChange;
   1864 
   1865   if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
   1866     gBS->FreePool (IdeBlkIoDevice->Cache);
   1867     IdeBlkIoDevice->Cache = NULL;
   1868   }
   1869 
   1870   if (Buffer == NULL) {
   1871     return EFI_INVALID_PARAMETER;
   1872   }
   1873 
   1874   if (BufferSize == 0) {
   1875     return EFI_SUCCESS;
   1876   }
   1877 
   1878   //
   1879   // ATAPI device media is removable,
   1880   // so it is a must to detect media first before write operation
   1881   //
   1882   MediaChange = FALSE;
   1883   Status      = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);
   1884   if (EFI_ERROR (Status)) {
   1885 
   1886     if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
   1887       gBS->FreePool (IdeBlkIoDevice->Cache);
   1888       IdeBlkIoDevice->Cache = NULL;
   1889     }
   1890     return Status;
   1891   }
   1892 
   1893   //
   1894   // Get the intrinsic block size
   1895   //
   1896   Media           = IdeBlkIoDevice->BlkIo.Media;
   1897   BlockSize       = Media->BlockSize;
   1898   NumberOfBlocks  = BufferSize / BlockSize;
   1899 
   1900   if (!(Media->MediaPresent)) {
   1901 
   1902     if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
   1903       gBS->FreePool (IdeBlkIoDevice->Cache);
   1904       IdeBlkIoDevice->Cache = NULL;
   1905     }
   1906     return EFI_NO_MEDIA;
   1907   }
   1908 
   1909   if ((MediaId != Media->MediaId) || MediaChange) {
   1910 
   1911     if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
   1912       gBS->FreePool (IdeBlkIoDevice->Cache);
   1913       IdeBlkIoDevice->Cache = NULL;
   1914     }
   1915     return EFI_MEDIA_CHANGED;
   1916   }
   1917 
   1918   if (Media->ReadOnly) {
   1919     return EFI_WRITE_PROTECTED;
   1920   }
   1921 
   1922   if (BufferSize % BlockSize != 0) {
   1923     return EFI_BAD_BUFFER_SIZE;
   1924   }
   1925 
   1926   if (Lba > Media->LastBlock) {
   1927     return EFI_INVALID_PARAMETER;
   1928   }
   1929 
   1930   if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
   1931     return EFI_INVALID_PARAMETER;
   1932   }
   1933 
   1934   if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
   1935     return EFI_INVALID_PARAMETER;
   1936   }
   1937 
   1938   //
   1939   // if all the parameters are valid,
   1940   // then perform write sectors command to transfer data from host to device.
   1941   //
   1942   Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
   1943   if (EFI_ERROR (Status)) {
   1944     return EFI_DEVICE_ERROR;
   1945   }
   1946 
   1947   return EFI_SUCCESS;
   1948 
   1949 }
   1950 
   1951 
   1952 
   1953