Home | History | Annotate | Download | only in AtaBusDxe
      1 /** @file
      2   This file implements ATA pass through transaction for ATA bus driver.
      3 
      4   This file implements the low level execution of ATA pass through transaction.
      5   It transforms the high level identity, read/write, reset command to ATA pass
      6   through command and protocol.
      7 
      8   NOTE: This file also implements the StorageSecurityCommandProtocol(SSP). For input
      9   parameter SecurityProtocolSpecificData, ATA spec has no explicitly definition
     10   for Security Protocol Specific layout. This implementation uses big endian for
     11   Cylinder register.
     12 
     13   Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
     14   (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
     15   This program and the accompanying materials
     16   are licensed and made available under the terms and conditions of the BSD License
     17   which accompanies this distribution.  The full text of the license may be found at
     18   http://opensource.org/licenses/bsd-license.php
     19 
     20   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     21   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     22 
     23 
     24 **/
     25 
     26 #include "AtaBus.h"
     27 
     28 #define ATA_CMD_TRUST_NON_DATA    0x5B
     29 #define ATA_CMD_TRUST_RECEIVE     0x5C
     30 #define ATA_CMD_TRUST_RECEIVE_DMA 0x5D
     31 #define ATA_CMD_TRUST_SEND        0x5E
     32 #define ATA_CMD_TRUST_SEND_DMA    0x5F
     33 
     34 //
     35 // Look up table (UdmaValid, IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
     36 //
     37 EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols[][2] = {
     38   {
     39     EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN,
     40     EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
     41   },
     42   {
     43     EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN,
     44     EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT,
     45   }
     46 };
     47 
     48 //
     49 // Look up table (UdmaValid, Lba48Bit, IsIsWrite) for ATA_CMD
     50 //
     51 UINT8 mAtaCommands[][2][2] = {
     52   {
     53     {
     54       ATA_CMD_READ_SECTORS,            // 28-bit LBA; PIO read
     55       ATA_CMD_WRITE_SECTORS            // 28-bit LBA; PIO write
     56     },
     57     {
     58       ATA_CMD_READ_SECTORS_EXT,        // 48-bit LBA; PIO read
     59       ATA_CMD_WRITE_SECTORS_EXT        // 48-bit LBA; PIO write
     60     }
     61   },
     62   {
     63     {
     64       ATA_CMD_READ_DMA,                // 28-bit LBA; DMA read
     65       ATA_CMD_WRITE_DMA                // 28-bit LBA; DMA write
     66     },
     67     {
     68       ATA_CMD_READ_DMA_EXT,            // 48-bit LBA; DMA read
     69       ATA_CMD_WRITE_DMA_EXT            // 48-bit LBA; DMA write
     70     }
     71   }
     72 };
     73 
     74 //
     75 // Look up table (UdmaValid, IsTrustSend) for ATA_CMD
     76 //
     77 UINT8 mAtaTrustCommands[2][2] = {
     78   {
     79     ATA_CMD_TRUST_RECEIVE,            // PIO read
     80     ATA_CMD_TRUST_SEND                // PIO write
     81   },
     82   {
     83     ATA_CMD_TRUST_RECEIVE_DMA,        // DMA read
     84     ATA_CMD_TRUST_SEND_DMA            // DMA write
     85   }
     86 };
     87 
     88 
     89 //
     90 // Look up table (Lba48Bit) for maximum transfer block number
     91 //
     92 UINTN mMaxTransferBlockNumber[] = {
     93   MAX_28BIT_TRANSFER_BLOCK_NUM,
     94   MAX_48BIT_TRANSFER_BLOCK_NUM
     95 };
     96 
     97 
     98 /**
     99   Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
    100 
    101   This function wraps the PassThru() invocation for ATA pass through function
    102   for an ATA device. It assembles the ATA pass through command packet for ATA
    103   transaction.
    104 
    105   @param[in, out]  AtaDevice   The ATA child device involved for the operation.
    106   @param[in, out]  TaskPacket  Pointer to a Pass Thru Command Packet. Optional,
    107                                if it is NULL, blocking mode, and use the packet
    108                                in AtaDevice. If it is not NULL, non blocking mode,
    109                                and pass down this Packet.
    110   @param[in, out]  Event       If Event is NULL, then blocking I/O is performed.
    111                                If Event is not NULL and non-blocking I/O is
    112                                supported,then non-blocking I/O is performed,
    113                                and Event will be signaled when the write
    114                                request is completed.
    115 
    116   @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
    117 
    118 **/
    119 EFI_STATUS
    120 AtaDevicePassThru (
    121   IN OUT ATA_DEVICE                       *AtaDevice,
    122   IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket, OPTIONAL
    123   IN OUT EFI_EVENT                        Event OPTIONAL
    124   )
    125 {
    126   EFI_STATUS                              Status;
    127   EFI_ATA_PASS_THRU_PROTOCOL              *AtaPassThru;
    128   EFI_ATA_PASS_THRU_COMMAND_PACKET        *Packet;
    129 
    130   //
    131   // Assemble packet. If it is non blocking mode, the Ata driver should keep each
    132   // subtask and clean them when the event is signaled.
    133   //
    134   if (TaskPacket != NULL) {
    135     Packet = TaskPacket;
    136     Packet->Asb = AllocateAlignedBuffer (AtaDevice, sizeof (EFI_ATA_STATUS_BLOCK));
    137     if (Packet->Asb == NULL) {
    138       return EFI_OUT_OF_RESOURCES;
    139     }
    140 
    141     CopyMem (Packet->Asb, AtaDevice->Asb, sizeof (EFI_ATA_STATUS_BLOCK));
    142     Packet->Acb = AllocateCopyPool (sizeof (EFI_ATA_COMMAND_BLOCK), &AtaDevice->Acb);
    143   } else {
    144     Packet = &AtaDevice->Packet;
    145     Packet->Asb = AtaDevice->Asb;
    146     Packet->Acb = &AtaDevice->Acb;
    147   }
    148 
    149   AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
    150 
    151   Status = AtaPassThru->PassThru (
    152                           AtaPassThru,
    153                           AtaDevice->Port,
    154                           AtaDevice->PortMultiplierPort,
    155                           Packet,
    156                           Event
    157                           );
    158   //
    159   // Ensure ATA pass through caller and callee have the same
    160   // interpretation of ATA pass through protocol.
    161   //
    162   ASSERT (Status != EFI_INVALID_PARAMETER);
    163   ASSERT (Status != EFI_BAD_BUFFER_SIZE);
    164 
    165   return Status;
    166 }
    167 
    168 
    169 /**
    170   Wrapper for EFI_ATA_PASS_THRU_PROTOCOL.ResetDevice().
    171 
    172   This function wraps the ResetDevice() invocation for ATA pass through function
    173   for an ATA device.
    174 
    175   @param  AtaDevice         The ATA child device involved for the operation.
    176 
    177   @return The return status from EFI_ATA_PASS_THRU_PROTOCOL.PassThru().
    178 
    179 **/
    180 EFI_STATUS
    181 ResetAtaDevice (
    182   IN ATA_DEVICE                           *AtaDevice
    183   )
    184 {
    185   EFI_ATA_PASS_THRU_PROTOCOL              *AtaPassThru;
    186 
    187   AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
    188 
    189   //
    190   // Report Status Code to indicate reset happens
    191   //
    192   REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    193     EFI_PROGRESS_CODE,
    194     (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
    195     AtaDevice->AtaBusDriverData->ParentDevicePath
    196     );
    197 
    198   return AtaPassThru->ResetDevice (
    199                         AtaPassThru,
    200                         AtaDevice->Port,
    201                         AtaDevice->PortMultiplierPort
    202                         );
    203 }
    204 
    205 
    206 /**
    207   Prints ATA model name to ATA device structure.
    208 
    209   This function converts ATA device model name from ATA identify data
    210   to a string in ATA device structure. It needs to change the character
    211   order in the original model name string.
    212 
    213   @param  AtaDevice         The ATA child device involved for the operation.
    214 
    215 **/
    216 VOID
    217 PrintAtaModelName (
    218   IN OUT ATA_DEVICE  *AtaDevice
    219   )
    220 {
    221   UINTN   Index;
    222   CHAR8   *Source;
    223   CHAR16  *Destination;
    224 
    225   Source = AtaDevice->IdentifyData->ModelName;
    226   Destination = AtaDevice->ModelName;
    227 
    228   //
    229   // Swap the byte order in the original module name.
    230   //
    231   for (Index = 0; Index < MAX_MODEL_NAME_LEN; Index += 2) {
    232     Destination[Index]      = Source[Index + 1];
    233     Destination[Index + 1]  = Source[Index];
    234   }
    235   AtaDevice->ModelName[MAX_MODEL_NAME_LEN] = L'\0';
    236 }
    237 
    238 
    239 /**
    240   Gets ATA device Capacity according to ATA 6.
    241 
    242   This function returns the capacity of the ATA device if it follows
    243   ATA 6 to support 48 bit addressing.
    244 
    245   @param  AtaDevice         The ATA child device involved for the operation.
    246 
    247   @return The capacity of the ATA device or 0 if the device does not support
    248           48-bit addressing defined in ATA 6.
    249 
    250 **/
    251 EFI_LBA
    252 GetAtapi6Capacity (
    253   IN ATA_DEVICE                 *AtaDevice
    254   )
    255 {
    256   EFI_LBA                       Capacity;
    257   EFI_LBA                       TmpLba;
    258   UINTN                         Index;
    259   ATA_IDENTIFY_DATA             *IdentifyData;
    260 
    261   IdentifyData = AtaDevice->IdentifyData;
    262   if ((IdentifyData->command_set_supported_83 & BIT10) == 0) {
    263     //
    264     // The device doesn't support 48 bit addressing
    265     //
    266     return 0;
    267   }
    268 
    269   //
    270   // 48 bit address feature set is supported, get maximum capacity
    271   //
    272   Capacity = 0;
    273   for (Index = 0; Index < 4; Index++) {
    274     //
    275     // Lower byte goes first: word[100] is the lowest word, word[103] is highest
    276     //
    277     TmpLba = IdentifyData->maximum_lba_for_48bit_addressing[Index];
    278     Capacity |= LShiftU64 (TmpLba, 16 * Index);
    279   }
    280 
    281   return Capacity;
    282 }
    283 
    284 
    285 /**
    286   Identifies ATA device via the Identify data.
    287 
    288   This function identifies the ATA device and initializes the Media information in
    289   Block IO protocol interface.
    290 
    291   @param  AtaDevice         The ATA child device involved for the operation.
    292 
    293   @retval EFI_UNSUPPORTED   The device is not a valid ATA device (hard disk).
    294   @retval EFI_SUCCESS       The device is successfully identified and Media information
    295                             is correctly initialized.
    296 
    297 **/
    298 EFI_STATUS
    299 IdentifyAtaDevice (
    300   IN OUT ATA_DEVICE                 *AtaDevice
    301   )
    302 {
    303   ATA_IDENTIFY_DATA                 *IdentifyData;
    304   EFI_BLOCK_IO_MEDIA                *BlockMedia;
    305   EFI_LBA                           Capacity;
    306   UINT16                            PhyLogicSectorSupport;
    307   UINT16                            UdmaMode;
    308 
    309   IdentifyData = AtaDevice->IdentifyData;
    310 
    311   if ((IdentifyData->config & BIT15) != 0) {
    312     //
    313     // This is not an hard disk
    314     //
    315     return EFI_UNSUPPORTED;
    316   }
    317 
    318   DEBUG ((EFI_D_INFO, "AtaBus - Identify Device: Port %x PortMultiplierPort %x\n", AtaDevice->Port, AtaDevice->PortMultiplierPort));
    319 
    320   //
    321   // Check whether the WORD 88 (supported UltraDMA by drive) is valid
    322   //
    323   if ((IdentifyData->field_validity & BIT2) != 0) {
    324     UdmaMode = IdentifyData->ultra_dma_mode;
    325     if ((UdmaMode & (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6)) != 0) {
    326       //
    327       // If BIT0~BIT6 is selected, then UDMA is supported
    328       //
    329       AtaDevice->UdmaValid = TRUE;
    330     }
    331   }
    332 
    333   Capacity = GetAtapi6Capacity (AtaDevice);
    334   if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
    335     //
    336     // Capacity exceeds 120GB. 48-bit addressing is really needed
    337     //
    338     AtaDevice->Lba48Bit = TRUE;
    339   } else {
    340     //
    341     // This is a hard disk <= 120GB capacity, treat it as normal hard disk
    342     //
    343     Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) | IdentifyData->user_addressable_sectors_lo;
    344     AtaDevice->Lba48Bit = FALSE;
    345   }
    346 
    347   //
    348   // Block Media Information:
    349   //
    350   BlockMedia = &AtaDevice->BlockMedia;
    351   BlockMedia->LastBlock = Capacity - 1;
    352   BlockMedia->IoAlign = AtaDevice->AtaBusDriverData->AtaPassThru->Mode->IoAlign;
    353   //
    354   // Check whether Long Physical Sector Feature is supported
    355   //
    356   PhyLogicSectorSupport = IdentifyData->phy_logic_sector_support;
    357   if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
    358     //
    359     // Check whether one physical block contains multiple physical blocks
    360     //
    361     if ((PhyLogicSectorSupport & BIT13) != 0) {
    362       BlockMedia->LogicalBlocksPerPhysicalBlock = (UINT32) (1 << (PhyLogicSectorSupport & 0x000f));
    363       //
    364       // Check lowest alignment of logical blocks within physical block
    365       //
    366       if ((IdentifyData->alignment_logic_in_phy_blocks & (BIT14 | BIT15)) == BIT14) {
    367         BlockMedia->LowestAlignedLba = (EFI_LBA) ((BlockMedia->LogicalBlocksPerPhysicalBlock - ((UINT32)IdentifyData->alignment_logic_in_phy_blocks & 0x3fff)) %
    368           BlockMedia->LogicalBlocksPerPhysicalBlock);
    369       }
    370     }
    371     //
    372     // Check logical block size
    373     //
    374     if ((PhyLogicSectorSupport & BIT12) != 0) {
    375       BlockMedia->BlockSize = (UINT32) (((IdentifyData->logic_sector_size_hi << 16) | IdentifyData->logic_sector_size_lo) * sizeof (UINT16));
    376     }
    377     AtaDevice->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
    378   }
    379   //
    380   // Get ATA model name from identify data structure.
    381   //
    382   PrintAtaModelName (AtaDevice);
    383 
    384   return EFI_SUCCESS;
    385 }
    386 
    387 
    388 /**
    389   Discovers whether it is a valid ATA device.
    390 
    391   This function issues ATA_CMD_IDENTIFY_DRIVE command to the ATA device to identify it.
    392   If the command is executed successfully, it then identifies it and initializes
    393   the Media information in Block IO protocol interface.
    394 
    395   @param  AtaDevice         The ATA child device involved for the operation.
    396 
    397   @retval EFI_SUCCESS       The device is successfully identified and Media information
    398                             is correctly initialized.
    399   @return others            Some error occurs when discovering the ATA device.
    400 
    401 **/
    402 EFI_STATUS
    403 DiscoverAtaDevice (
    404   IN OUT ATA_DEVICE                 *AtaDevice
    405   )
    406 {
    407   EFI_STATUS                        Status;
    408   EFI_ATA_COMMAND_BLOCK             *Acb;
    409   EFI_ATA_PASS_THRU_COMMAND_PACKET  *Packet;
    410   UINTN                             Retry;
    411 
    412   //
    413   // Prepare for ATA command block.
    414   //
    415   Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
    416   Acb->AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
    417   Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));
    418 
    419   //
    420   // Prepare for ATA pass through packet.
    421   //
    422   Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
    423   Packet->InDataBuffer = AtaDevice->IdentifyData;
    424   Packet->InTransferLength = sizeof (ATA_IDENTIFY_DATA);
    425   Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
    426   Packet->Length   = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
    427   Packet->Timeout  = ATA_TIMEOUT;
    428 
    429   Retry = MAX_RETRY_TIMES;
    430   do {
    431     Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
    432     if (!EFI_ERROR (Status)) {
    433       //
    434       // The command is issued successfully
    435       //
    436       Status = IdentifyAtaDevice (AtaDevice);
    437       return Status;
    438     }
    439   } while (Retry-- > 0);
    440 
    441   return Status;
    442 }
    443 
    444 /**
    445   Transfer data from ATA device.
    446 
    447   This function performs one ATA pass through transaction to transfer data from/to
    448   ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
    449   interface of ATA pass through.
    450 
    451   @param[in, out]  AtaDevice       The ATA child device involved for the operation.
    452   @param[in, out]  TaskPacket      Pointer to a Pass Thru Command Packet. Optional,
    453                                    if it is NULL, blocking mode, and use the packet
    454                                    in AtaDevice. If it is not NULL, non blocking mode,
    455                                    and pass down this Packet.
    456   @param[in, out]  Buffer          The pointer to the current transaction buffer.
    457   @param[in]       StartLba        The starting logical block address to be accessed.
    458   @param[in]       TransferLength  The block number or sector count of the transfer.
    459   @param[in]       IsWrite         Indicates whether it is a write operation.
    460   @param[in]       Event           If Event is NULL, then blocking I/O is performed.
    461                                    If Event is not NULL and non-blocking I/O is
    462                                    supported,then non-blocking I/O is performed,
    463                                    and Event will be signaled when the write
    464                                    request is completed.
    465 
    466   @retval EFI_SUCCESS       The data transfer is complete successfully.
    467   @return others            Some error occurs when transferring data.
    468 
    469 **/
    470 EFI_STATUS
    471 TransferAtaDevice (
    472   IN OUT ATA_DEVICE                       *AtaDevice,
    473   IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET *TaskPacket, OPTIONAL
    474   IN OUT VOID                             *Buffer,
    475   IN EFI_LBA                              StartLba,
    476   IN UINT32                               TransferLength,
    477   IN BOOLEAN                              IsWrite,
    478   IN EFI_EVENT                            Event OPTIONAL
    479   )
    480 {
    481   EFI_ATA_COMMAND_BLOCK             *Acb;
    482   EFI_ATA_PASS_THRU_COMMAND_PACKET  *Packet;
    483 
    484   //
    485   // Ensure AtaDevice->UdmaValid, AtaDevice->Lba48Bit and IsWrite are valid boolean values
    486   //
    487   ASSERT ((UINTN) AtaDevice->UdmaValid < 2);
    488   ASSERT ((UINTN) AtaDevice->Lba48Bit < 2);
    489   ASSERT ((UINTN) IsWrite < 2);
    490   //
    491   // Prepare for ATA command block.
    492   //
    493   Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
    494   Acb->AtaCommand = mAtaCommands[AtaDevice->UdmaValid][AtaDevice->Lba48Bit][IsWrite];
    495   Acb->AtaSectorNumber = (UINT8) StartLba;
    496   Acb->AtaCylinderLow = (UINT8) RShiftU64 (StartLba, 8);
    497   Acb->AtaCylinderHigh = (UINT8) RShiftU64 (StartLba, 16);
    498   Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));
    499   Acb->AtaSectorCount = (UINT8) TransferLength;
    500   if (AtaDevice->Lba48Bit) {
    501     Acb->AtaSectorNumberExp = (UINT8) RShiftU64 (StartLba, 24);
    502     Acb->AtaCylinderLowExp = (UINT8) RShiftU64 (StartLba, 32);
    503     Acb->AtaCylinderHighExp = (UINT8) RShiftU64 (StartLba, 40);
    504     Acb->AtaSectorCountExp = (UINT8) (TransferLength >> 8);
    505   } else {
    506     Acb->AtaDeviceHead = (UINT8) (Acb->AtaDeviceHead | RShiftU64 (StartLba, 24));
    507   }
    508 
    509   //
    510   // Prepare for ATA pass through packet.
    511   //
    512   if (TaskPacket != NULL) {
    513     Packet = ZeroMem (TaskPacket, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
    514   } else {
    515     Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
    516   }
    517 
    518   if (IsWrite) {
    519     Packet->OutDataBuffer = Buffer;
    520     Packet->OutTransferLength = TransferLength;
    521   } else {
    522     Packet->InDataBuffer = Buffer;
    523     Packet->InTransferLength = TransferLength;
    524   }
    525 
    526   Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite];
    527   Packet->Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
    528   //
    529   // |------------------------|-----------------|------------------------|-----------------|
    530   // | ATA PIO Transfer Mode  |  Transfer Rate  | ATA DMA Transfer Mode  |  Transfer Rate  |
    531   // |------------------------|-----------------|------------------------|-----------------|
    532   // |       PIO Mode 0       |  3.3Mbytes/sec  | Single-word DMA Mode 0 |  2.1Mbytes/sec  |
    533   // |------------------------|-----------------|------------------------|-----------------|
    534   // |       PIO Mode 1       |  5.2Mbytes/sec  | Single-word DMA Mode 1 |  4.2Mbytes/sec  |
    535   // |------------------------|-----------------|------------------------|-----------------|
    536   // |       PIO Mode 2       |  8.3Mbytes/sec  | Single-word DMA Mode 2 |  8.4Mbytes/sec  |
    537   // |------------------------|-----------------|------------------------|-----------------|
    538   // |       PIO Mode 3       | 11.1Mbytes/sec  | Multi-word DMA Mode 0  |  4.2Mbytes/sec  |
    539   // |------------------------|-----------------|------------------------|-----------------|
    540   // |       PIO Mode 4       | 16.6Mbytes/sec  | Multi-word DMA Mode 1  | 13.3Mbytes/sec  |
    541   // |------------------------|-----------------|------------------------|-----------------|
    542   //
    543   // As AtaBus is used to manage ATA devices, we have to use the lowest transfer rate to
    544   // calculate the possible maximum timeout value for each read/write operation.
    545   // The timout value is rounded up to nearest integar and here an additional 30s is added
    546   // to follow ATA spec in which it mentioned that the device may take up to 30s to respond
    547   // commands in the Standby/Idle mode.
    548   //
    549   if (AtaDevice->UdmaValid) {
    550     //
    551     // Calculate the maximum timeout value for DMA read/write operation.
    552     //
    553     Packet->Timeout  = EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength, AtaDevice->BlockMedia.BlockSize), 2100000) + 31);
    554   } else {
    555     //
    556     // Calculate the maximum timeout value for PIO read/write operation
    557     //
    558     Packet->Timeout  = EFI_TIMER_PERIOD_SECONDS (DivU64x32 (MultU64x32 (TransferLength, AtaDevice->BlockMedia.BlockSize), 3300000) + 31);
    559   }
    560 
    561   return AtaDevicePassThru (AtaDevice, TaskPacket, Event);
    562 }
    563 
    564 /**
    565   Free SubTask.
    566 
    567   @param[in, out]  Task      Pointer to task to be freed.
    568 
    569 **/
    570 VOID
    571 EFIAPI
    572 FreeAtaSubTask (
    573   IN OUT ATA_BUS_ASYN_SUB_TASK  *Task
    574   )
    575 {
    576   if (Task->Packet.Asb != NULL) {
    577     FreeAlignedBuffer (Task->Packet.Asb, sizeof (EFI_ATA_STATUS_BLOCK));
    578   }
    579   if (Task->Packet.Acb != NULL) {
    580     FreePool (Task->Packet.Acb);
    581   }
    582 
    583   FreePool (Task);
    584 }
    585 
    586 /**
    587   Terminate any in-flight non-blocking I/O requests by signaling an EFI_ABORTED
    588   in the TransactionStatus member of the EFI_BLOCK_IO2_TOKEN for the non-blocking
    589   I/O. After that it is safe to free any Token or Buffer data structures that
    590   were allocated to initiate the non-blockingI/O requests that were in-flight for
    591   this device.
    592 
    593   @param[in]  AtaDevice     The ATA child device involved for the operation.
    594 
    595 **/
    596 VOID
    597 EFIAPI
    598 AtaTerminateNonBlockingTask (
    599   IN ATA_DEVICE               *AtaDevice
    600   )
    601 {
    602   BOOLEAN               SubTaskEmpty;
    603   EFI_TPL               OldTpl;
    604   ATA_BUS_ASYN_TASK     *AtaTask;
    605   LIST_ENTRY            *Entry;
    606   LIST_ENTRY            *List;
    607 
    608   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    609   //
    610   // Abort all executing tasks from now.
    611   //
    612   AtaDevice->Abort = TRUE;
    613 
    614   List = &AtaDevice->AtaTaskList;
    615   for (Entry = GetFirstNode (List); !IsNull (List, Entry);) {
    616     AtaTask  = ATA_ASYN_TASK_FROM_ENTRY (Entry);
    617     AtaTask->Token->TransactionStatus = EFI_ABORTED;
    618     gBS->SignalEvent (AtaTask->Token->Event);
    619 
    620     Entry = RemoveEntryList (Entry);
    621     FreePool (AtaTask);
    622   }
    623   gBS->RestoreTPL (OldTpl);
    624 
    625   do {
    626     OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    627     //
    628     // Wait for executing subtasks done.
    629     //
    630     SubTaskEmpty = IsListEmpty (&AtaDevice->AtaSubTaskList);
    631     gBS->RestoreTPL (OldTpl);
    632   } while (!SubTaskEmpty);
    633 
    634   //
    635   // Aborting operation has been done. From now on, don't need to abort normal operation.
    636   //
    637   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    638   AtaDevice->Abort = FALSE;
    639   gBS->RestoreTPL (OldTpl);
    640 }
    641 
    642 /**
    643   Call back funtion when the event is signaled.
    644 
    645   @param[in]  Event     The Event this notify function registered to.
    646   @param[in]  Context   Pointer to the context data registered to the
    647                         Event.
    648 
    649 **/
    650 VOID
    651 EFIAPI
    652 AtaNonBlockingCallBack (
    653   IN EFI_EVENT                Event,
    654   IN VOID                     *Context
    655   )
    656 {
    657   ATA_BUS_ASYN_SUB_TASK *Task;
    658   ATA_BUS_ASYN_TASK     *AtaTask;
    659   ATA_DEVICE            *AtaDevice;
    660   LIST_ENTRY            *Entry;
    661   EFI_STATUS            Status;
    662 
    663   Task = (ATA_BUS_ASYN_SUB_TASK *) Context;
    664   gBS->CloseEvent (Event);
    665 
    666   AtaDevice = Task->AtaDevice;
    667 
    668   //
    669   // Check the command status.
    670   // If there is error during the sub task source allocation, the error status
    671   // should be returned to the caller directly, so here the Task->Token may already
    672   // be deleted by the caller and no need to update the status.
    673   //
    674   if ((!(*Task->IsError)) && ((Task->Packet.Asb->AtaStatus & 0x01) == 0x01)) {
    675     Task->Token->TransactionStatus = EFI_DEVICE_ERROR;
    676   }
    677 
    678   if (AtaDevice->Abort) {
    679     Task->Token->TransactionStatus = EFI_ABORTED;
    680   }
    681 
    682   DEBUG ((
    683     EFI_D_BLKIO,
    684     "NON-BLOCKING EVENT FINISHED!- STATUS = %r\n",
    685     Task->Token->TransactionStatus
    686     ));
    687 
    688   //
    689   // Reduce the SubEventCount, till it comes to zero.
    690   //
    691   (*Task->UnsignalledEventCount) --;
    692   DEBUG ((EFI_D_BLKIO, "UnsignalledEventCount = %d\n", *Task->UnsignalledEventCount));
    693 
    694   //
    695   // Remove the SubTask from the Task list.
    696   //
    697   RemoveEntryList (&Task->TaskEntry);
    698   if ((*Task->UnsignalledEventCount) == 0) {
    699     //
    700     // All Sub tasks are done, then signal the upper layer event.
    701     // Except there is error during the sub task source allocation.
    702     //
    703     if (!(*Task->IsError)) {
    704       gBS->SignalEvent (Task->Token->Event);
    705       DEBUG ((EFI_D_BLKIO, "Signal the upper layer event!\n"));
    706     }
    707 
    708     FreePool (Task->UnsignalledEventCount);
    709     FreePool (Task->IsError);
    710 
    711 
    712     //
    713     // Finish all subtasks and move to the next task in AtaTaskList.
    714     //
    715     if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
    716       Entry   = GetFirstNode (&AtaDevice->AtaTaskList);
    717       AtaTask = ATA_ASYN_TASK_FROM_ENTRY (Entry);
    718       DEBUG ((EFI_D_BLKIO, "Start to embark a new Ata Task\n"));
    719       DEBUG ((EFI_D_BLKIO, "AtaTask->NumberOfBlocks = %x; AtaTask->Token=%x\n", AtaTask->NumberOfBlocks, AtaTask->Token));
    720       Status = AccessAtaDevice (
    721                  AtaTask->AtaDevice,
    722                  AtaTask->Buffer,
    723                  AtaTask->StartLba,
    724                  AtaTask->NumberOfBlocks,
    725                  AtaTask->IsWrite,
    726                  AtaTask->Token
    727                  );
    728       if (EFI_ERROR (Status)) {
    729         AtaTask->Token->TransactionStatus = Status;
    730         gBS->SignalEvent (AtaTask->Token->Event);
    731       }
    732       RemoveEntryList (Entry);
    733       FreePool (AtaTask);
    734     }
    735   }
    736 
    737   DEBUG ((
    738     EFI_D_BLKIO,
    739     "PACKET INFO: Write=%s, Length=%x, LowCylinder=%x, HighCylinder=%x, SectionNumber=%x\n",
    740     Task->Packet.OutDataBuffer != NULL ? L"YES" : L"NO",
    741     Task->Packet.OutDataBuffer != NULL ? Task->Packet.OutTransferLength : Task->Packet.InTransferLength,
    742     Task->Packet.Acb->AtaCylinderLow,
    743     Task->Packet.Acb->AtaCylinderHigh,
    744     Task->Packet.Acb->AtaSectorCount
    745     ));
    746 
    747   //
    748   // Free the buffer of SubTask.
    749   //
    750   FreeAtaSubTask (Task);
    751 }
    752 
    753 /**
    754   Read or write a number of blocks from ATA device.
    755 
    756   This function performs ATA pass through transactions to read/write data from/to
    757   ATA device. It may separate the read/write request into several ATA pass through
    758   transactions.
    759 
    760   @param[in, out]  AtaDevice       The ATA child device involved for the operation.
    761   @param[in, out]  Buffer          The pointer to the current transaction buffer.
    762   @param[in]       StartLba        The starting logical block address to be accessed.
    763   @param[in]       NumberOfBlocks  The block number or sector count of the transfer.
    764   @param[in]       IsWrite         Indicates whether it is a write operation.
    765   @param[in, out]  Token           A pointer to the token associated with the transaction.
    766 
    767   @retval EFI_SUCCESS       The data transfer is complete successfully.
    768   @return others            Some error occurs when transferring data.
    769 
    770 **/
    771 EFI_STATUS
    772 AccessAtaDevice(
    773   IN OUT ATA_DEVICE                 *AtaDevice,
    774   IN OUT UINT8                      *Buffer,
    775   IN EFI_LBA                        StartLba,
    776   IN UINTN                          NumberOfBlocks,
    777   IN BOOLEAN                        IsWrite,
    778   IN OUT EFI_BLOCK_IO2_TOKEN        *Token
    779   )
    780 {
    781   EFI_STATUS                        Status;
    782   UINTN                             MaxTransferBlockNumber;
    783   UINTN                             TransferBlockNumber;
    784   UINTN                             BlockSize;
    785   ATA_BUS_ASYN_SUB_TASK             *SubTask;
    786   UINTN                             *EventCount;
    787   UINTN                             TempCount;
    788   ATA_BUS_ASYN_TASK                 *AtaTask;
    789   EFI_EVENT                         SubEvent;
    790   UINTN                             Index;
    791   BOOLEAN                           *IsError;
    792   EFI_TPL                           OldTpl;
    793 
    794   TempCount  = 0;
    795   Status     = EFI_SUCCESS;
    796   EventCount = NULL;
    797   IsError    = NULL;
    798   Index      = 0;
    799   SubTask    = NULL;
    800   SubEvent   = NULL;
    801   AtaTask    = NULL;
    802 
    803   //
    804   // Ensure AtaDevice->Lba48Bit is a valid boolean value
    805   //
    806   ASSERT ((UINTN) AtaDevice->Lba48Bit < 2);
    807   MaxTransferBlockNumber = mMaxTransferBlockNumber[AtaDevice->Lba48Bit];
    808   BlockSize              = AtaDevice->BlockMedia.BlockSize;
    809 
    810   //
    811   // Initial the return status and shared account for Non Blocking.
    812   //
    813   if ((Token != NULL) && (Token->Event != NULL)) {
    814     OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    815 
    816     if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
    817       AtaTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_TASK));
    818       if (AtaTask == NULL) {
    819         gBS->RestoreTPL (OldTpl);
    820         return EFI_OUT_OF_RESOURCES;
    821       }
    822       AtaTask->AtaDevice      = AtaDevice;
    823       AtaTask->Buffer         = Buffer;
    824       AtaTask->IsWrite        = IsWrite;
    825       AtaTask->NumberOfBlocks = NumberOfBlocks;
    826       AtaTask->Signature      = ATA_TASK_SIGNATURE;
    827       AtaTask->StartLba       = StartLba;
    828       AtaTask->Token          = Token;
    829 
    830       InsertTailList (&AtaDevice->AtaTaskList, &AtaTask->TaskEntry);
    831       gBS->RestoreTPL (OldTpl);
    832       return EFI_SUCCESS;
    833     }
    834     gBS->RestoreTPL (OldTpl);
    835 
    836     Token->TransactionStatus = EFI_SUCCESS;
    837     EventCount = AllocateZeroPool (sizeof (UINTN));
    838     if (EventCount == NULL) {
    839       return EFI_OUT_OF_RESOURCES;
    840     }
    841 
    842     IsError = AllocateZeroPool (sizeof (BOOLEAN));
    843     if (IsError == NULL) {
    844       FreePool (EventCount);
    845       return EFI_OUT_OF_RESOURCES;
    846     }
    847     DEBUG ((EFI_D_BLKIO, "Allocation IsError Addr=%x\n", IsError));
    848     *IsError = FALSE;
    849     TempCount   = (NumberOfBlocks + MaxTransferBlockNumber - 1) / MaxTransferBlockNumber;
    850     *EventCount = TempCount;
    851     DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, NumberOfBlocks=%x\n", NumberOfBlocks));
    852     DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, MaxTransferBlockNumber=%x\n", MaxTransferBlockNumber));
    853     DEBUG ((EFI_D_BLKIO, "AccessAtaDevice, EventCount=%x\n", TempCount));
    854   } else {
    855     while (!IsListEmpty (&AtaDevice->AtaTaskList) || !IsListEmpty (&AtaDevice->AtaSubTaskList)) {
    856       //
    857       // Stall for 100us.
    858       //
    859       MicroSecondDelay (100);
    860     }
    861   }
    862 
    863   do {
    864     if (NumberOfBlocks > MaxTransferBlockNumber) {
    865       TransferBlockNumber = MaxTransferBlockNumber;
    866       NumberOfBlocks     -= MaxTransferBlockNumber;
    867     } else  {
    868       TransferBlockNumber = NumberOfBlocks;
    869       NumberOfBlocks      = 0;
    870     }
    871 
    872     //
    873     // Create sub event for the sub ata task. Non-blocking mode.
    874     //
    875     if ((Token != NULL) && (Token->Event != NULL)) {
    876       SubTask  = NULL;
    877       SubEvent = NULL;
    878 
    879       SubTask = AllocateZeroPool (sizeof (ATA_BUS_ASYN_SUB_TASK));
    880       if (SubTask == NULL) {
    881         Status = EFI_OUT_OF_RESOURCES;
    882         goto EXIT;
    883       }
    884 
    885       OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    886       SubTask->UnsignalledEventCount = EventCount;
    887       SubTask->Signature             = ATA_SUB_TASK_SIGNATURE;
    888       SubTask->AtaDevice             = AtaDevice;
    889       SubTask->Token                 = Token;
    890       SubTask->IsError               = IsError;
    891       InsertTailList (&AtaDevice->AtaSubTaskList, &SubTask->TaskEntry);
    892       gBS->RestoreTPL (OldTpl);
    893 
    894       Status = gBS->CreateEvent (
    895                       EVT_NOTIFY_SIGNAL,
    896                       TPL_NOTIFY,
    897                       AtaNonBlockingCallBack,
    898                       SubTask,
    899                       &SubEvent
    900                       );
    901       //
    902       // If resource allocation fail, the un-signalled event count should equal to
    903       // the original one minus the unassigned subtasks number.
    904       //
    905       if (EFI_ERROR (Status)) {
    906         Status = EFI_OUT_OF_RESOURCES;
    907         goto EXIT;
    908       }
    909 
    910       Status = TransferAtaDevice (AtaDevice, &SubTask->Packet, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, SubEvent);
    911     } else {
    912       //
    913       // Blocking Mode.
    914       //
    915       DEBUG ((EFI_D_BLKIO, "Blocking AccessAtaDevice, TransferBlockNumber=%x; StartLba = %x\n", TransferBlockNumber, StartLba));
    916       Status = TransferAtaDevice (AtaDevice, NULL, Buffer, StartLba, (UINT32) TransferBlockNumber, IsWrite, NULL);
    917     }
    918 
    919     if (EFI_ERROR (Status)) {
    920       goto EXIT;
    921     }
    922 
    923     Index++;
    924     StartLba += TransferBlockNumber;
    925     Buffer   += TransferBlockNumber * BlockSize;
    926   } while (NumberOfBlocks > 0);
    927 
    928 EXIT:
    929   if ((Token != NULL) && (Token->Event != NULL)) {
    930     //
    931     // Release resource at non-blocking mode.
    932     //
    933     if (EFI_ERROR (Status)) {
    934       OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    935       Token->TransactionStatus = Status;
    936       *EventCount = (*EventCount) - (TempCount - Index);
    937       *IsError    = TRUE;
    938 
    939       if (*EventCount == 0) {
    940         FreePool (EventCount);
    941         FreePool (IsError);
    942       }
    943 
    944       if (SubTask != NULL) {
    945         RemoveEntryList (&SubTask->TaskEntry);
    946         FreeAtaSubTask (SubTask);
    947       }
    948 
    949       if (SubEvent != NULL) {
    950         gBS->CloseEvent (SubEvent);
    951       }
    952       gBS->RestoreTPL (OldTpl);
    953     }
    954   }
    955 
    956   return Status;
    957 }
    958 
    959 /**
    960   Trust transfer data from/to ATA device.
    961 
    962   This function performs one ATA pass through transaction to do a trust transfer from/to
    963   ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
    964   interface of ATA pass through.
    965 
    966   @param  AtaDevice                    The ATA child device involved for the operation.
    967   @param  Buffer                       The pointer to the current transaction buffer.
    968   @param  SecurityProtocolId           The value of the "Security Protocol" parameter of
    969                                        the security protocol command to be sent.
    970   @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
    971                                        of the security protocol command to be sent.
    972   @param  TransferLength               The block number or sector count of the transfer.
    973   @param  IsTrustSend                  Indicates whether it is a trust send operation or not.
    974   @param  Timeout                      The timeout, in 100ns units, to use for the execution
    975                                        of the security protocol command. A Timeout value of 0
    976                                        means that this function will wait indefinitely for the
    977                                        security protocol command to execute. If Timeout is greater
    978                                        than zero, then this function will return EFI_TIMEOUT
    979                                        if the time required to execute the receive data command
    980                                        is greater than Timeout.
    981   @param  TransferLengthOut            A pointer to a buffer to store the size in bytes of the data
    982                                        written to the buffer. Ignore it when IsTrustSend is TRUE.
    983 
    984   @retval EFI_SUCCESS       The data transfer is complete successfully.
    985   @return others            Some error occurs when transferring data.
    986 
    987 **/
    988 EFI_STATUS
    989 EFIAPI
    990 TrustTransferAtaDevice (
    991   IN OUT ATA_DEVICE                 *AtaDevice,
    992   IN OUT VOID                       *Buffer,
    993   IN UINT8                          SecurityProtocolId,
    994   IN UINT16                         SecurityProtocolSpecificData,
    995   IN UINTN                          TransferLength,
    996   IN BOOLEAN                        IsTrustSend,
    997   IN UINT64                         Timeout,
    998   OUT UINTN                         *TransferLengthOut
    999   )
   1000 {
   1001   EFI_ATA_COMMAND_BLOCK             *Acb;
   1002   EFI_ATA_PASS_THRU_COMMAND_PACKET  *Packet;
   1003   EFI_STATUS                        Status;
   1004   VOID                              *NewBuffer;
   1005   EFI_ATA_PASS_THRU_PROTOCOL        *AtaPassThru;
   1006 
   1007   //
   1008   // Ensure AtaDevice->UdmaValid and IsTrustSend are valid boolean values
   1009   //
   1010   ASSERT ((UINTN) AtaDevice->UdmaValid < 2);
   1011   ASSERT ((UINTN) IsTrustSend < 2);
   1012   //
   1013   // Prepare for ATA command block.
   1014   //
   1015   Acb = ZeroMem (&AtaDevice->Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
   1016   if (TransferLength == 0) {
   1017     Acb->AtaCommand    = ATA_CMD_TRUST_NON_DATA;
   1018   } else {
   1019     Acb->AtaCommand    = mAtaTrustCommands[AtaDevice->UdmaValid][IsTrustSend];
   1020   }
   1021   Acb->AtaFeatures      = SecurityProtocolId;
   1022   Acb->AtaSectorCount   = (UINT8) (TransferLength / 512);
   1023   Acb->AtaSectorNumber  = (UINT8) ((TransferLength / 512) >> 8);
   1024   //
   1025   // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
   1026   // Here use big endian for Cylinder register.
   1027   //
   1028   Acb->AtaCylinderHigh  = (UINT8) SecurityProtocolSpecificData;
   1029   Acb->AtaCylinderLow   = (UINT8) (SecurityProtocolSpecificData >> 8);
   1030   Acb->AtaDeviceHead = (UINT8) (BIT7 | BIT6 | BIT5 | (AtaDevice->PortMultiplierPort == 0xFFFF ? 0 : (AtaDevice->PortMultiplierPort << 4)));
   1031 
   1032   //
   1033   // Prepare for ATA pass through packet.
   1034   //
   1035   Packet = ZeroMem (&AtaDevice->Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
   1036   if (TransferLength == 0) {
   1037     Packet->InTransferLength  = 0;
   1038     Packet->OutTransferLength = 0;
   1039     Packet->Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
   1040   } else if (IsTrustSend) {
   1041     //
   1042     // Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru
   1043     //
   1044     AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
   1045     if ((AtaPassThru->Mode->IoAlign > 1) && !IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) {
   1046       NewBuffer = AllocateAlignedBuffer (AtaDevice, TransferLength);
   1047       if (NewBuffer == NULL) {
   1048         return EFI_OUT_OF_RESOURCES;
   1049       }
   1050 
   1051       CopyMem (NewBuffer, Buffer, TransferLength);
   1052       FreePool (Buffer);
   1053       Buffer = NewBuffer;
   1054     }
   1055     Packet->OutDataBuffer = Buffer;
   1056     Packet->OutTransferLength = (UINT32) TransferLength;
   1057     Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
   1058   } else {
   1059     Packet->InDataBuffer = Buffer;
   1060     Packet->InTransferLength = (UINT32) TransferLength;
   1061     Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsTrustSend];
   1062   }
   1063   Packet->Length   = EFI_ATA_PASS_THRU_LENGTH_BYTES;
   1064   Packet->Timeout  = Timeout;
   1065 
   1066   Status = AtaDevicePassThru (AtaDevice, NULL, NULL);
   1067   if (TransferLengthOut != NULL) {
   1068     if (! IsTrustSend) {
   1069       *TransferLengthOut = Packet->InTransferLength;
   1070     }
   1071   }
   1072   return Status;
   1073 }
   1074