Home | History | Annotate | Download | only in SataControllerDxe
      1 /** @file
      2   This driver module produces IDE_CONTROLLER_INIT protocol for Sata Controllers.
      3 
      4   Copyright (c) 2011, 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 "SataController.h"
     16 
     17 ///
     18 /// EFI_DRIVER_BINDING_PROTOCOL instance
     19 ///
     20 EFI_DRIVER_BINDING_PROTOCOL gSataControllerDriverBinding = {
     21   SataControllerSupported,
     22   SataControllerStart,
     23   SataControllerStop,
     24   0xa,
     25   NULL,
     26   NULL
     27 };
     28 
     29 /**
     30   Read AHCI Operation register.
     31 
     32   @param PciIo      The PCI IO protocol instance.
     33   @param Offset     The operation register offset.
     34 
     35   @return The register content read.
     36 
     37 **/
     38 UINT32
     39 EFIAPI
     40 AhciReadReg (
     41   IN EFI_PCI_IO_PROTOCOL    *PciIo,
     42   IN UINT32                 Offset
     43   )
     44 {
     45   UINT32    Data;
     46 
     47   ASSERT (PciIo != NULL);
     48 
     49   Data = 0;
     50 
     51   PciIo->Mem.Read (
     52                PciIo,
     53                EfiPciIoWidthUint32,
     54                AHCI_BAR_INDEX,
     55                (UINT64) Offset,
     56                1,
     57                &Data
     58                );
     59 
     60   return Data;
     61 }
     62 
     63 /**
     64   Write AHCI Operation register.
     65 
     66   @param PciIo      The PCI IO protocol instance.
     67   @param Offset     The operation register offset.
     68   @param Data       The data used to write down.
     69 
     70 **/
     71 VOID
     72 EFIAPI
     73 AhciWriteReg (
     74   IN EFI_PCI_IO_PROTOCOL    *PciIo,
     75   IN UINT32                 Offset,
     76   IN UINT32                 Data
     77   )
     78 {
     79   ASSERT (PciIo != NULL);
     80 
     81   PciIo->Mem.Write (
     82                PciIo,
     83                EfiPciIoWidthUint32,
     84                AHCI_BAR_INDEX,
     85                (UINT64) Offset,
     86                1,
     87                &Data
     88                );
     89 
     90   return;
     91 }
     92 
     93 /**
     94   This function is used to calculate the best PIO mode supported by specific IDE device
     95 
     96   @param IdentifyData   The identify data of specific IDE device.
     97   @param DisPioMode     Disqualified PIO modes collection.
     98   @param SelectedMode   Available PIO modes collection.
     99 
    100   @retval EFI_SUCCESS       Best PIO modes are returned.
    101   @retval EFI_UNSUPPORTED   The device doesn't support PIO mode,
    102                             or all supported modes have been disqualified.
    103 **/
    104 EFI_STATUS
    105 CalculateBestPioMode (
    106   IN EFI_IDENTIFY_DATA  *IdentifyData,
    107   IN UINT16             *DisPioMode OPTIONAL,
    108   OUT UINT16            *SelectedMode
    109   )
    110 {
    111   UINT16    PioMode;
    112   UINT16    AdvancedPioMode;
    113   UINT16    Temp;
    114   UINT16    Index;
    115   UINT16    MinimumPioCycleTime;
    116 
    117   Temp = 0xff;
    118 
    119   PioMode = (UINT8) (((ATA5_IDENTIFY_DATA *) (&(IdentifyData->AtaData)))->pio_cycle_timing >> 8);
    120 
    121   //
    122   // See whether Identify Data word 64 - 70 are valid
    123   //
    124   if ((IdentifyData->AtaData.field_validity & 0x02) == 0x02) {
    125 
    126     AdvancedPioMode = IdentifyData->AtaData.advanced_pio_modes;
    127     DEBUG ((EFI_D_INFO, "CalculateBestPioMode: AdvancedPioMode = %x\n", AdvancedPioMode));
    128 
    129     for (Index = 0; Index < 8; Index++) {
    130       if ((AdvancedPioMode & 0x01) != 0) {
    131         Temp = Index;
    132       }
    133 
    134       AdvancedPioMode >>= 1;
    135     }
    136 
    137     //
    138     // If Temp is modified, mean the advanced_pio_modes is not zero;
    139     // if Temp is not modified, mean there is no advanced PIO mode supported,
    140     // the best PIO Mode is the value in pio_cycle_timing.
    141     //
    142     if (Temp != 0xff) {
    143       AdvancedPioMode = (UINT16) (Temp + 3);
    144     } else {
    145       AdvancedPioMode = PioMode;
    146     }
    147 
    148     //
    149     // Limit the PIO mode to at most PIO4.
    150     //
    151     PioMode = (UINT16) MIN (AdvancedPioMode, 4);
    152 
    153     MinimumPioCycleTime = IdentifyData->AtaData.min_pio_cycle_time_with_flow_control;
    154 
    155     if (MinimumPioCycleTime <= 120) {
    156       PioMode = (UINT16) MIN (4, PioMode);
    157     } else if (MinimumPioCycleTime <= 180) {
    158       PioMode = (UINT16) MIN (3, PioMode);
    159     } else if (MinimumPioCycleTime <= 240) {
    160       PioMode = (UINT16) MIN (2, PioMode);
    161     } else {
    162       PioMode = 0;
    163     }
    164 
    165     //
    166     // Degrade the PIO mode if the mode has been disqualified
    167     //
    168     if (DisPioMode != NULL) {
    169       if (*DisPioMode < 2) {
    170         return EFI_UNSUPPORTED; // no mode below ATA_PIO_MODE_BELOW_2
    171       }
    172 
    173       if (PioMode >= *DisPioMode) {
    174         PioMode = (UINT16) (*DisPioMode - 1);
    175       }
    176     }
    177 
    178     if (PioMode < 2) {
    179       *SelectedMode = 1;        // ATA_PIO_MODE_BELOW_2;
    180     } else {
    181       *SelectedMode = PioMode;  // ATA_PIO_MODE_2 to ATA_PIO_MODE_4;
    182     }
    183 
    184   } else {
    185     //
    186     // Identify Data word 64 - 70 are not valid
    187     // Degrade the PIO mode if the mode has been disqualified
    188     //
    189     if (DisPioMode != NULL) {
    190       if (*DisPioMode < 2) {
    191         return EFI_UNSUPPORTED; // no mode below ATA_PIO_MODE_BELOW_2
    192       }
    193 
    194       if (PioMode == *DisPioMode) {
    195         PioMode--;
    196       }
    197     }
    198 
    199     if (PioMode < 2) {
    200       *SelectedMode = 1;        // ATA_PIO_MODE_BELOW_2;
    201     } else {
    202       *SelectedMode = 2;        // ATA_PIO_MODE_2;
    203     }
    204 
    205   }
    206 
    207   return EFI_SUCCESS;
    208 }
    209 
    210 /**
    211   This function is used to calculate the best UDMA mode supported by specific IDE device
    212 
    213   @param IdentifyData   The identify data of specific IDE device.
    214   @param DisUDmaMode     Disqualified UDMA modes collection.
    215   @param SelectedMode   Available UDMA modes collection.
    216 
    217   @retval EFI_SUCCESS       Best UDMA modes are returned.
    218   @retval EFI_UNSUPPORTED   The device doesn't support UDMA mode,
    219                             or all supported modes have been disqualified.
    220 **/
    221 EFI_STATUS
    222 CalculateBestUdmaMode (
    223   IN EFI_IDENTIFY_DATA  *IdentifyData,
    224   IN UINT16             *DisUDmaMode OPTIONAL,
    225   OUT UINT16            *SelectedMode
    226   )
    227 {
    228   UINT16    TempMode;
    229   UINT16    DeviceUDmaMode;
    230 
    231   DeviceUDmaMode = 0;
    232 
    233   //
    234   // Check whether the WORD 88 (supported UltraDMA by drive) is valid
    235   //
    236   if ((IdentifyData->AtaData.field_validity & 0x04) == 0x00) {
    237     return EFI_UNSUPPORTED;
    238   }
    239 
    240   DeviceUDmaMode = IdentifyData->AtaData.ultra_dma_mode;
    241   DEBUG ((EFI_D_INFO, "CalculateBestUdmaMode: DeviceUDmaMode = %x\n", DeviceUDmaMode));
    242   DeviceUDmaMode &= 0x3f;
    243   TempMode = 0;                 // initialize it to UDMA-0
    244 
    245   while ((DeviceUDmaMode >>= 1) != 0) {
    246     TempMode++;
    247   }
    248 
    249   //
    250   // Degrade the UDMA mode if the mode has been disqualified
    251   //
    252   if (DisUDmaMode != NULL) {
    253     if (*DisUDmaMode == 0) {
    254       *SelectedMode = 0;
    255       return EFI_UNSUPPORTED;   // no mode below ATA_UDMA_MODE_0
    256     }
    257 
    258     if (TempMode >= *DisUDmaMode) {
    259       TempMode = (UINT16) (*DisUDmaMode - 1);
    260     }
    261   }
    262 
    263   //
    264   // Possible returned mode is between ATA_UDMA_MODE_0 and ATA_UDMA_MODE_5
    265   //
    266   *SelectedMode = TempMode;
    267 
    268   return EFI_SUCCESS;
    269 }
    270 
    271 /**
    272   The Entry Point of module. It follows the standard UEFI driver model.
    273 
    274   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
    275   @param[in] SystemTable    A pointer to the EFI System Table.
    276 
    277   @retval EFI_SUCCESS   The entry point is executed successfully.
    278   @retval other         Some error occurs when executing this entry point.
    279 
    280 **/
    281 EFI_STATUS
    282 EFIAPI
    283 InitializeSataControllerDriver (
    284   IN EFI_HANDLE         ImageHandle,
    285   IN EFI_SYSTEM_TABLE   *SystemTable
    286   )
    287 {
    288   EFI_STATUS    Status;
    289 
    290   //
    291   // Install driver model protocol(s).
    292   //
    293   Status = EfiLibInstallDriverBindingComponentName2 (
    294              ImageHandle,
    295              SystemTable,
    296              &gSataControllerDriverBinding,
    297              ImageHandle,
    298              &gSataControllerComponentName,
    299              &gSataControllerComponentName2
    300              );
    301   ASSERT_EFI_ERROR (Status);
    302 
    303   return Status;
    304 }
    305 
    306 /**
    307   Supported function of Driver Binding protocol for this driver.
    308   Test to see if this driver supports ControllerHandle.
    309 
    310   @param This                   Protocol instance pointer.
    311   @param Controller             Handle of device to test.
    312   @param RemainingDevicePath    A pointer to the device path.
    313                                 it should be ignored by device driver.
    314 
    315   @retval EFI_SUCCESS           This driver supports this device.
    316   @retval EFI_ALREADY_STARTED   This driver is already running on this device.
    317   @retval other                 This driver does not support this device.
    318 
    319 **/
    320 EFI_STATUS
    321 EFIAPI
    322 SataControllerSupported (
    323   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
    324   IN EFI_HANDLE                     Controller,
    325   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
    326   )
    327 {
    328   EFI_STATUS            Status;
    329   EFI_PCI_IO_PROTOCOL   *PciIo;
    330   PCI_TYPE00            PciData;
    331 
    332   //
    333   // Attempt to open PCI I/O Protocol
    334   //
    335   Status = gBS->OpenProtocol (
    336                   Controller,
    337                   &gEfiPciIoProtocolGuid,
    338                   (VOID **) &PciIo,
    339                   This->DriverBindingHandle,
    340                   Controller,
    341                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    342                   );
    343   if (EFI_ERROR (Status)) {
    344     return Status;
    345   }
    346 
    347   //
    348   // Now further check the PCI header: Base Class (offset 0x0B) and
    349   // Sub Class (offset 0x0A). This controller should be an SATA controller
    350   //
    351   Status = PciIo->Pci.Read (
    352                         PciIo,
    353                         EfiPciIoWidthUint8,
    354                         PCI_CLASSCODE_OFFSET,
    355                         sizeof (PciData.Hdr.ClassCode),
    356                         PciData.Hdr.ClassCode
    357                         );
    358   if (EFI_ERROR (Status)) {
    359     return EFI_UNSUPPORTED;
    360   }
    361 
    362   if (IS_PCI_IDE (&PciData) || IS_PCI_SATADPA (&PciData)) {
    363     return EFI_SUCCESS;
    364   }
    365 
    366   return EFI_UNSUPPORTED;
    367 }
    368 
    369 /**
    370   This routine is called right after the .Supported() called and
    371   Start this driver on ControllerHandle.
    372 
    373   @param This                   Protocol instance pointer.
    374   @param Controller             Handle of device to bind driver to.
    375   @param RemainingDevicePath    A pointer to the device path.
    376                                 it should be ignored by device driver.
    377 
    378   @retval EFI_SUCCESS           This driver is added to this device.
    379   @retval EFI_ALREADY_STARTED   This driver is already running on this device.
    380   @retval other                 Some error occurs when binding this driver to this device.
    381 
    382 **/
    383 EFI_STATUS
    384 EFIAPI
    385 SataControllerStart (
    386   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
    387   IN EFI_HANDLE                     Controller,
    388   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
    389   )
    390 {
    391   EFI_STATUS                        Status;
    392   EFI_PCI_IO_PROTOCOL               *PciIo;
    393   UINT64                            OriginalPciAttributes;
    394   PCI_TYPE00                        PciData;
    395   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
    396   UINT32                            Data32;
    397   UINTN                             ChannelDeviceCount;
    398 
    399   DEBUG ((EFI_D_INFO, "SataControllerStart START\n"));
    400 
    401   SataPrivateData = NULL;
    402 
    403   //
    404   // Now test and open PCI I/O Protocol
    405   //
    406   Status = gBS->OpenProtocol (
    407                   Controller,
    408                   &gEfiPciIoProtocolGuid,
    409                   (VOID **) &PciIo,
    410                   This->DriverBindingHandle,
    411                   Controller,
    412                   EFI_OPEN_PROTOCOL_BY_DRIVER
    413                   );
    414   if (EFI_ERROR (Status)) {
    415     goto Bail;
    416   }
    417 
    418   //
    419   // Save original PCI attributes, and enable IO space access, memory space
    420   // access, and Bus Master (DMA).
    421   //
    422   Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationGet, 0,
    423                     &OriginalPciAttributes);
    424   if (EFI_ERROR (Status)) {
    425     goto ClosePciIo;
    426   }
    427   Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationEnable,
    428                     EFI_PCI_DEVICE_ENABLE, NULL);
    429   if (EFI_ERROR (Status)) {
    430     goto ClosePciIo;
    431   }
    432 
    433   //
    434   // Allocate Sata Private Data structure
    435   //
    436   SataPrivateData = AllocateZeroPool (sizeof (EFI_SATA_CONTROLLER_PRIVATE_DATA));
    437   if (SataPrivateData == NULL) {
    438     Status = EFI_OUT_OF_RESOURCES;
    439     goto RestorePciAttributes;
    440   }
    441 
    442   //
    443   // Initialize Sata Private Data
    444   //
    445   SataPrivateData->Signature = SATA_CONTROLLER_SIGNATURE;
    446   SataPrivateData->PciIo = PciIo;
    447   SataPrivateData->OriginalPciAttributes = OriginalPciAttributes;
    448   SataPrivateData->IdeInit.GetChannelInfo = IdeInitGetChannelInfo;
    449   SataPrivateData->IdeInit.NotifyPhase = IdeInitNotifyPhase;
    450   SataPrivateData->IdeInit.SubmitData = IdeInitSubmitData;
    451   SataPrivateData->IdeInit.DisqualifyMode = IdeInitDisqualifyMode;
    452   SataPrivateData->IdeInit.CalculateMode = IdeInitCalculateMode;
    453   SataPrivateData->IdeInit.SetTiming = IdeInitSetTiming;
    454   SataPrivateData->IdeInit.EnumAll = SATA_ENUMER_ALL;
    455 
    456   Status = PciIo->Pci.Read (
    457                         PciIo,
    458                         EfiPciIoWidthUint8,
    459                         PCI_CLASSCODE_OFFSET,
    460                         sizeof (PciData.Hdr.ClassCode),
    461                         PciData.Hdr.ClassCode
    462                         );
    463   if (EFI_ERROR (Status)) {
    464     goto FreeSataPrivateData;
    465   }
    466 
    467   if (IS_PCI_IDE (&PciData)) {
    468     SataPrivateData->IdeInit.ChannelCount = IDE_MAX_CHANNEL;
    469     SataPrivateData->DeviceCount = IDE_MAX_DEVICES;
    470   } else if (IS_PCI_SATADPA (&PciData)) {
    471     //
    472     // Read Host Capability Register(CAP) to get Number of Ports(NPS) and Supports Port Multiplier(SPM)
    473     //   NPS is 0's based value indicating the maximum number of ports supported by the HBA silicon.
    474     //   A maximum of 32 ports can be supported. A value of '0h', indicating one port, is the minimum requirement.
    475     //
    476     Data32 = AhciReadReg (PciIo, R_AHCI_CAP);
    477     SataPrivateData->IdeInit.ChannelCount = (UINT8) ((Data32 & B_AHCI_CAP_NPS) + 1);
    478     SataPrivateData->DeviceCount = AHCI_MAX_DEVICES;
    479     if ((Data32 & B_AHCI_CAP_SPM) == B_AHCI_CAP_SPM) {
    480       SataPrivateData->DeviceCount = AHCI_MULTI_MAX_DEVICES;
    481     }
    482   }
    483 
    484   ChannelDeviceCount = (UINTN) (SataPrivateData->IdeInit.ChannelCount) * (UINTN) (SataPrivateData->DeviceCount);
    485   SataPrivateData->DisqualifiedModes = AllocateZeroPool ((sizeof (EFI_ATA_COLLECTIVE_MODE)) * ChannelDeviceCount);
    486   if (SataPrivateData->DisqualifiedModes == NULL) {
    487     Status = EFI_OUT_OF_RESOURCES;
    488     goto FreeSataPrivateData;
    489   }
    490 
    491   SataPrivateData->IdentifyData = AllocateZeroPool ((sizeof (EFI_IDENTIFY_DATA)) * ChannelDeviceCount);
    492   if (SataPrivateData->IdentifyData == NULL) {
    493     Status = EFI_OUT_OF_RESOURCES;
    494     goto FreeDisqualifiedModes;
    495   }
    496 
    497   SataPrivateData->IdentifyValid = AllocateZeroPool ((sizeof (BOOLEAN)) * ChannelDeviceCount);
    498   if (SataPrivateData->IdentifyValid == NULL) {
    499     Status = EFI_OUT_OF_RESOURCES;
    500     goto FreeIdentifyData;
    501   }
    502 
    503   //
    504   // Install IDE Controller Init Protocol to this instance
    505   //
    506   Status = gBS->InstallMultipleProtocolInterfaces (
    507                   &Controller,
    508                   &gEfiIdeControllerInitProtocolGuid,
    509                   &(SataPrivateData->IdeInit),
    510                   NULL
    511                   );
    512 
    513   if (EFI_ERROR (Status)) {
    514     goto FreeIdentifyValid;
    515   }
    516 
    517   DEBUG ((EFI_D_INFO, "SataControllerStart END status = %r\n", Status));
    518   return Status;
    519 
    520 FreeIdentifyValid:
    521   FreePool (SataPrivateData->IdentifyValid);
    522 
    523 FreeIdentifyData:
    524   FreePool (SataPrivateData->IdentifyData);
    525 
    526 FreeDisqualifiedModes:
    527   FreePool (SataPrivateData->DisqualifiedModes);
    528 
    529 FreeSataPrivateData:
    530   FreePool (SataPrivateData);
    531 
    532 RestorePciAttributes:
    533   PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSet,
    534            OriginalPciAttributes, NULL);
    535 
    536 ClosePciIo:
    537   gBS->CloseProtocol (
    538          Controller,
    539          &gEfiPciIoProtocolGuid,
    540          This->DriverBindingHandle,
    541          Controller
    542          );
    543 
    544 Bail:
    545   DEBUG ((EFI_D_ERROR, "SataControllerStart error return status = %r\n", Status));
    546   return Status;
    547 }
    548 
    549 /**
    550   Stop this driver on ControllerHandle.
    551 
    552   @param This               Protocol instance pointer.
    553   @param Controller         Handle of device to stop driver on.
    554   @param NumberOfChildren   Not used.
    555   @param ChildHandleBuffer  Not used.
    556 
    557   @retval EFI_SUCCESS   This driver is removed from this device.
    558   @retval other         Some error occurs when removing this driver from this device.
    559 
    560 **/
    561 EFI_STATUS
    562 EFIAPI
    563 SataControllerStop (
    564   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
    565   IN EFI_HANDLE                     Controller,
    566   IN UINTN                          NumberOfChildren,
    567   IN EFI_HANDLE                     *ChildHandleBuffer
    568   )
    569 {
    570   EFI_STATUS                        Status;
    571   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
    572   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
    573   EFI_PCI_IO_PROTOCOL               *PciIo;
    574   UINT64                            OriginalPciAttributes;
    575 
    576   //
    577   // Open the produced protocol
    578   //
    579   Status = gBS->OpenProtocol (
    580                   Controller,
    581                   &gEfiIdeControllerInitProtocolGuid,
    582                   (VOID **) &IdeInit,
    583                   This->DriverBindingHandle,
    584                   Controller,
    585                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    586                   );
    587   if (EFI_ERROR (Status)) {
    588     return EFI_UNSUPPORTED;
    589   }
    590 
    591   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (IdeInit);
    592   ASSERT (SataPrivateData != NULL);
    593 
    594   PciIo                 = SataPrivateData->PciIo;
    595   OriginalPciAttributes = SataPrivateData->OriginalPciAttributes;
    596 
    597   //
    598   // Uninstall the IDE Controller Init Protocol from this instance
    599   //
    600   Status = gBS->UninstallMultipleProtocolInterfaces (
    601                   Controller,
    602                   &gEfiIdeControllerInitProtocolGuid,
    603                   &(SataPrivateData->IdeInit),
    604                   NULL
    605                   );
    606   if (EFI_ERROR (Status)) {
    607     return Status;
    608   }
    609 
    610   if (SataPrivateData->DisqualifiedModes != NULL) {
    611     FreePool (SataPrivateData->DisqualifiedModes);
    612   }
    613   if (SataPrivateData->IdentifyData != NULL) {
    614     FreePool (SataPrivateData->IdentifyData);
    615   }
    616   if (SataPrivateData->IdentifyValid != NULL) {
    617     FreePool (SataPrivateData->IdentifyValid);
    618   }
    619   FreePool (SataPrivateData);
    620 
    621   //
    622   // Restore original PCI attributes
    623   //
    624   PciIo->Attributes (
    625            PciIo,
    626            EfiPciIoAttributeOperationSet,
    627            OriginalPciAttributes,
    628            NULL
    629            );
    630 
    631   //
    632   // Close protocols opened by Sata Controller driver
    633   //
    634   return gBS->CloseProtocol (
    635                 Controller,
    636                 &gEfiPciIoProtocolGuid,
    637                 This->DriverBindingHandle,
    638                 Controller
    639                 );
    640 }
    641 
    642 /**
    643   Calculate the flat array subscript of a (Channel, Device) pair.
    644 
    645   @param[in] SataPrivateData  The private data structure corresponding to the
    646                               SATA controller that attaches the device for
    647                               which the flat array subscript is being
    648                               calculated.
    649 
    650   @param[in] Channel          The channel (ie. port) number on the SATA
    651                               controller that the device is attached to.
    652 
    653   @param[in] Device           The device number on the channel.
    654 
    655   @return  The flat array subscript suitable for indexing DisqualifiedModes,
    656            IdentifyData, and IdentifyValid.
    657 **/
    658 STATIC
    659 UINTN
    660 FlatDeviceIndex (
    661   IN CONST EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData,
    662   IN UINTN                                   Channel,
    663   IN UINTN                                   Device
    664   )
    665 {
    666   ASSERT (SataPrivateData != NULL);
    667   ASSERT (Channel < SataPrivateData->IdeInit.ChannelCount);
    668   ASSERT (Device < SataPrivateData->DeviceCount);
    669 
    670   return Channel * SataPrivateData->DeviceCount + Device;
    671 }
    672 
    673 //
    674 // Interface functions of IDE_CONTROLLER_INIT protocol
    675 //
    676 /**
    677   Returns the information about the specified IDE channel.
    678 
    679   This function can be used to obtain information about a particular IDE channel.
    680   The driver entity uses this information during the enumeration process.
    681 
    682   If Enabled is set to FALSE, the driver entity will not scan the channel. Note
    683   that it will not prevent an operating system driver from scanning the channel.
    684 
    685   For most of today's controllers, MaxDevices will either be 1 or 2. For SATA
    686   controllers, this value will always be 1. SATA configurations can contain SATA
    687   port multipliers. SATA port multipliers behave like SATA bridges and can support
    688   up to 16 devices on the other side. If a SATA port out of the IDE controller
    689   is connected to a port multiplier, MaxDevices will be set to the number of SATA
    690   devices that the port multiplier supports. Because today's port multipliers
    691   support up to fifteen SATA devices, this number can be as large as fifteen. The IDE
    692   bus driver is required to scan for the presence of port multipliers behind an SATA
    693   controller and enumerate up to MaxDevices number of devices behind the port
    694   multiplier.
    695 
    696   In this context, the devices behind a port multiplier constitute a channel.
    697 
    698   @param[in]  This         The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
    699   @param[in]  Channel      Zero-based channel number.
    700   @param[out] Enabled      TRUE if this channel is enabled.  Disabled channels
    701                            are not scanned to see if any devices are present.
    702   @param[out] MaxDevices   The maximum number of IDE devices that the bus driver
    703                            can expect on this channel.  For the ATA/ATAPI
    704                            specification, version 6, this number will either be
    705                            one or two. For Serial ATA (SATA) configurations with a
    706                            port multiplier, this number can be as large as fifteen.
    707 
    708   @retval EFI_SUCCESS             Information was returned without any errors.
    709   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
    710 
    711 **/
    712 EFI_STATUS
    713 EFIAPI
    714 IdeInitGetChannelInfo (
    715   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
    716   IN UINT8                              Channel,
    717   OUT BOOLEAN                           *Enabled,
    718   OUT UINT8                             *MaxDevices
    719   )
    720 {
    721   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
    722   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
    723   ASSERT (SataPrivateData != NULL);
    724 
    725   if (Channel < This->ChannelCount) {
    726     *Enabled = TRUE;
    727     *MaxDevices = SataPrivateData->DeviceCount;
    728     return EFI_SUCCESS;
    729   }
    730 
    731   *Enabled = FALSE;
    732   return EFI_INVALID_PARAMETER;
    733 }
    734 
    735 /**
    736   The notifications from the driver entity that it is about to enter a certain
    737   phase of the IDE channel enumeration process.
    738 
    739   This function can be used to notify the IDE controller driver to perform
    740   specific actions, including any chipset-specific initialization, so that the
    741   chipset is ready to enter the next phase. Seven notification points are defined
    742   at this time.
    743 
    744   More synchronization points may be added as required in the future.
    745 
    746   @param[in] This      The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
    747   @param[in] Phase     The phase during enumeration.
    748   @param[in] Channel   Zero-based channel number.
    749 
    750   @retval EFI_SUCCESS             The notification was accepted without any errors.
    751   @retval EFI_UNSUPPORTED         Phase is not supported.
    752   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
    753   @retval EFI_NOT_READY           This phase cannot be entered at this time; for
    754                                   example, an attempt was made to enter a Phase
    755                                   without having entered one or more previous
    756                                   Phase.
    757 
    758 **/
    759 EFI_STATUS
    760 EFIAPI
    761 IdeInitNotifyPhase (
    762   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
    763   IN EFI_IDE_CONTROLLER_ENUM_PHASE      Phase,
    764   IN UINT8                              Channel
    765   )
    766 {
    767   return EFI_SUCCESS;
    768 }
    769 
    770 /**
    771   Submits the device information to the IDE controller driver.
    772 
    773   This function is used by the driver entity to pass detailed information about
    774   a particular device to the IDE controller driver. The driver entity obtains
    775   this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData
    776   is the pointer to the response data buffer. The IdentifyData buffer is owned
    777   by the driver entity, and the IDE controller driver must make a local copy
    778   of the entire buffer or parts of the buffer as needed. The original IdentifyData
    779   buffer pointer may not be valid when
    780 
    781     - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or
    782     - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point.
    783 
    784   The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to
    785   compute the optimum mode for the device. These fields are not limited to the
    786   timing information. For example, an implementation of the IDE controller driver
    787   may examine the vendor and type/mode field to match known bad drives.
    788 
    789   The driver entity may submit drive information in any order, as long as it
    790   submits information for all the devices belonging to the enumeration group
    791   before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device
    792   in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
    793   should be called with IdentifyData set to NULL.  The IDE controller driver may
    794   not have any other mechanism to know whether a device is present or not. Therefore,
    795   setting IdentifyData to NULL does not constitute an error condition.
    796   EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a
    797   given (Channel, Device) pair.
    798 
    799   @param[in] This           A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
    800   @param[in] Channel        Zero-based channel number.
    801   @param[in] Device         Zero-based device number on the Channel.
    802   @param[in] IdentifyData   The device's response to the ATA IDENTIFY_DEVICE command.
    803 
    804   @retval EFI_SUCCESS             The information was accepted without any errors.
    805   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
    806   @retval EFI_INVALID_PARAMETER   Device is invalid.
    807 
    808 **/
    809 EFI_STATUS
    810 EFIAPI
    811 IdeInitSubmitData (
    812   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
    813   IN UINT8                              Channel,
    814   IN UINT8                              Device,
    815   IN EFI_IDENTIFY_DATA                  *IdentifyData
    816   )
    817 {
    818   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
    819   UINTN                             DeviceIndex;
    820 
    821   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
    822   ASSERT (SataPrivateData != NULL);
    823 
    824   if ((Channel >= This->ChannelCount) || (Device >= SataPrivateData->DeviceCount)) {
    825     return EFI_INVALID_PARAMETER;
    826   }
    827 
    828   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
    829 
    830   //
    831   // Make a local copy of device's IdentifyData and mark the valid flag
    832   //
    833   if (IdentifyData != NULL) {
    834     CopyMem (
    835       &(SataPrivateData->IdentifyData[DeviceIndex]),
    836       IdentifyData,
    837       sizeof (EFI_IDENTIFY_DATA)
    838       );
    839 
    840     SataPrivateData->IdentifyValid[DeviceIndex] = TRUE;
    841   } else {
    842     SataPrivateData->IdentifyValid[DeviceIndex] = FALSE;
    843   }
    844 
    845   return EFI_SUCCESS;
    846 }
    847 
    848 /**
    849   Disqualifies specific modes for an IDE device.
    850 
    851   This function allows the driver entity or other drivers (such as platform
    852   drivers) to reject certain timing modes and request the IDE controller driver
    853   to recalculate modes. This function allows the driver entity and the IDE
    854   controller driver to negotiate the timings on a per-device basis. This function
    855   is useful in the case of drives that lie about their capabilities. An example
    856   is when the IDE device fails to accept the timing modes that are calculated
    857   by the IDE controller driver based on the response to the Identify Drive command.
    858 
    859   If the driver entity does not want to limit the ATA timing modes and leave that
    860   decision to the IDE controller driver, it can either not call this function for
    861   the given device or call this function and set the Valid flag to FALSE for all
    862   modes that are listed in EFI_ATA_COLLECTIVE_MODE.
    863 
    864   The driver entity may disqualify modes for a device in any order and any number
    865   of times.
    866 
    867   This function can be called multiple times to invalidate multiple modes of the
    868   same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI
    869   specification for more information on PIO modes.
    870 
    871   For Serial ATA (SATA) controllers, this member function can be used to disqualify
    872   a higher transfer rate mode on a given channel. For example, a platform driver
    873   may inform the IDE controller driver to not use second-generation (Gen2) speeds
    874   for a certain SATA drive.
    875 
    876   @param[in] This       The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
    877   @param[in] Channel    The zero-based channel number.
    878   @param[in] Device     The zero-based device number on the Channel.
    879   @param[in] BadModes   The modes that the device does not support and that
    880                         should be disqualified.
    881 
    882   @retval EFI_SUCCESS             The modes were accepted without any errors.
    883   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
    884   @retval EFI_INVALID_PARAMETER   Device is invalid.
    885   @retval EFI_INVALID_PARAMETER   IdentifyData is NULL.
    886 
    887 **/
    888 EFI_STATUS
    889 EFIAPI
    890 IdeInitDisqualifyMode (
    891   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
    892   IN UINT8                              Channel,
    893   IN UINT8                              Device,
    894   IN EFI_ATA_COLLECTIVE_MODE            *BadModes
    895   )
    896 {
    897   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
    898   UINTN                             DeviceIndex;
    899 
    900   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
    901   ASSERT (SataPrivateData != NULL);
    902 
    903   if ((Channel >= This->ChannelCount) || (BadModes == NULL) || (Device >= SataPrivateData->DeviceCount)) {
    904     return EFI_INVALID_PARAMETER;
    905   }
    906 
    907   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
    908 
    909   //
    910   // Record the disqualified modes per channel per device. From ATA/ATAPI spec,
    911   // if a mode is not supported, the modes higher than it is also not supported.
    912   //
    913   CopyMem (
    914     &(SataPrivateData->DisqualifiedModes[DeviceIndex]),
    915     BadModes,
    916     sizeof (EFI_ATA_COLLECTIVE_MODE)
    917     );
    918 
    919   return EFI_SUCCESS;
    920 }
    921 
    922 /**
    923   Returns the information about the optimum modes for the specified IDE device.
    924 
    925   This function is used by the driver entity to obtain the optimum ATA modes for
    926   a specific device.  The IDE controller driver takes into account the following
    927   while calculating the mode:
    928     - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
    929     - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode()
    930 
    931   The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
    932   for all the devices that belong to an enumeration group before calling
    933   EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group.
    934 
    935   The IDE controller driver will use controller- and possibly platform-specific
    936   algorithms to arrive at SupportedModes.  The IDE controller may base its
    937   decision on user preferences and other considerations as well. This function
    938   may be called multiple times because the driver entity may renegotiate the mode
    939   with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode().
    940 
    941   The driver entity may collect timing information for various devices in any
    942   order. The driver entity is responsible for making sure that all the dependencies
    943   are satisfied. For example, the SupportedModes information for device A that
    944   was previously returned may become stale after a call to
    945   EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B.
    946 
    947   The buffer SupportedModes is allocated by the callee because the caller does
    948   not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE
    949   is defined in a way that allows for future extensibility and can be of variable
    950   length. This memory pool should be deallocated by the caller when it is no
    951   longer necessary.
    952 
    953   The IDE controller driver for a Serial ATA (SATA) controller can use this
    954   member function to force a lower speed (first-generation [Gen1] speeds on a
    955   second-generation [Gen2]-capable hardware).  The IDE controller driver can
    956   also allow the driver entity to stay with the speed that has been negotiated
    957   by the physical layer.
    958 
    959   @param[in]  This             The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
    960   @param[in]  Channel          A zero-based channel number.
    961   @param[in]  Device           A zero-based device number on the Channel.
    962   @param[out] SupportedModes   The optimum modes for the device.
    963 
    964   @retval EFI_SUCCESS             SupportedModes was returned.
    965   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
    966   @retval EFI_INVALID_PARAMETER   Device is invalid.
    967   @retval EFI_INVALID_PARAMETER   SupportedModes is NULL.
    968   @retval EFI_NOT_READY           Modes cannot be calculated due to a lack of
    969                                   data.  This error may happen if
    970                                   EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData()
    971                                   and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData()
    972                                   were not called for at least one drive in the
    973                                   same enumeration group.
    974 
    975 **/
    976 EFI_STATUS
    977 EFIAPI
    978 IdeInitCalculateMode (
    979   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
    980   IN UINT8                              Channel,
    981   IN UINT8                              Device,
    982   OUT EFI_ATA_COLLECTIVE_MODE           **SupportedModes
    983   )
    984 {
    985   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
    986   EFI_IDENTIFY_DATA                 *IdentifyData;
    987   BOOLEAN                           IdentifyValid;
    988   EFI_ATA_COLLECTIVE_MODE           *DisqualifiedModes;
    989   UINT16                            SelectedMode;
    990   EFI_STATUS                        Status;
    991   UINTN                             DeviceIndex;
    992 
    993   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
    994   ASSERT (SataPrivateData != NULL);
    995 
    996   if ((Channel >= This->ChannelCount) || (SupportedModes == NULL) || (Device >= SataPrivateData->DeviceCount)) {
    997     return EFI_INVALID_PARAMETER;
    998   }
    999 
   1000   *SupportedModes = AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE));
   1001   if (*SupportedModes == NULL) {
   1002     ASSERT (*SupportedModes != NULL);
   1003     return EFI_OUT_OF_RESOURCES;
   1004   }
   1005 
   1006   DeviceIndex = FlatDeviceIndex (SataPrivateData, Channel, Device);
   1007 
   1008   IdentifyData = &(SataPrivateData->IdentifyData[DeviceIndex]);
   1009   IdentifyValid = SataPrivateData->IdentifyValid[DeviceIndex];
   1010   DisqualifiedModes = &(SataPrivateData->DisqualifiedModes[DeviceIndex]);
   1011 
   1012   //
   1013   // Make sure we've got the valid identify data of the device from SubmitData()
   1014   //
   1015   if (!IdentifyValid) {
   1016     FreePool (*SupportedModes);
   1017     return EFI_NOT_READY;
   1018   }
   1019 
   1020   Status = CalculateBestPioMode (
   1021             IdentifyData,
   1022             (DisqualifiedModes->PioMode.Valid ? ((UINT16 *) &(DisqualifiedModes->PioMode.Mode)) : NULL),
   1023             &SelectedMode
   1024             );
   1025   if (!EFI_ERROR (Status)) {
   1026     (*SupportedModes)->PioMode.Valid = TRUE;
   1027     (*SupportedModes)->PioMode.Mode = SelectedMode;
   1028 
   1029   } else {
   1030     (*SupportedModes)->PioMode.Valid = FALSE;
   1031   }
   1032   DEBUG ((EFI_D_INFO, "IdeInitCalculateMode: PioMode = %x\n", (*SupportedModes)->PioMode.Mode));
   1033 
   1034   Status = CalculateBestUdmaMode (
   1035             IdentifyData,
   1036             (DisqualifiedModes->UdmaMode.Valid ? ((UINT16 *) &(DisqualifiedModes->UdmaMode.Mode)) : NULL),
   1037             &SelectedMode
   1038             );
   1039 
   1040   if (!EFI_ERROR (Status)) {
   1041     (*SupportedModes)->UdmaMode.Valid = TRUE;
   1042     (*SupportedModes)->UdmaMode.Mode  = SelectedMode;
   1043 
   1044   } else {
   1045     (*SupportedModes)->UdmaMode.Valid = FALSE;
   1046   }
   1047   DEBUG ((EFI_D_INFO, "IdeInitCalculateMode: UdmaMode = %x\n", (*SupportedModes)->UdmaMode.Mode));
   1048 
   1049   //
   1050   // The modes other than PIO and UDMA are not supported
   1051   //
   1052   return EFI_SUCCESS;
   1053 }
   1054 
   1055 /**
   1056   Commands the IDE controller driver to program the IDE controller hardware
   1057   so that the specified device can operate at the specified mode.
   1058 
   1059   This function is used by the driver entity to instruct the IDE controller
   1060   driver to program the IDE controller hardware to the specified modes. This
   1061   function can be called only once for a particular device. For a Serial ATA
   1062   (SATA) Advanced Host Controller Interface (AHCI) controller, no controller-
   1063   specific programming may be required.
   1064 
   1065   @param[in] This      Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
   1066   @param[in] Channel   Zero-based channel number.
   1067   @param[in] Device    Zero-based device number on the Channel.
   1068   @param[in] Modes     The modes to set.
   1069 
   1070   @retval EFI_SUCCESS             The command was accepted without any errors.
   1071   @retval EFI_INVALID_PARAMETER   Channel is invalid (Channel >= ChannelCount).
   1072   @retval EFI_INVALID_PARAMETER   Device is invalid.
   1073   @retval EFI_NOT_READY           Modes cannot be set at this time due to lack of data.
   1074   @retval EFI_DEVICE_ERROR        Modes cannot be set due to hardware failure.
   1075                                   The driver entity should not use this device.
   1076 
   1077 **/
   1078 EFI_STATUS
   1079 EFIAPI
   1080 IdeInitSetTiming (
   1081   IN EFI_IDE_CONTROLLER_INIT_PROTOCOL   *This,
   1082   IN UINT8                              Channel,
   1083   IN UINT8                              Device,
   1084   IN EFI_ATA_COLLECTIVE_MODE            *Modes
   1085   )
   1086 {
   1087   return EFI_SUCCESS;
   1088 }
   1089