/** @file
  Collect IDE information from Native EFI Driver

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "LegacyBiosInterface.h"

BOOLEAN  mIdeDataBuiltFlag = FALSE;

/**
  Collect IDE Inquiry data from the IDE disks

  @param  Private        Legacy BIOS Instance data
  @param  HddInfo        Hdd Information
  @param  Flag           Reconnect IdeController or not

  @retval EFI_SUCCESS    It should always work.

**/
EFI_STATUS
LegacyBiosBuildIdeData (
  IN  LEGACY_BIOS_INSTANCE  *Private,
  IN  HDD_INFO              **HddInfo,
  IN  UINT16                Flag
  )
{
  EFI_STATUS                Status;
  EFI_HANDLE                IdeController;
  UINTN                     HandleCount;
  EFI_HANDLE                *HandleBuffer;
  UINTN                     Index;
  EFI_DISK_INFO_PROTOCOL    *DiskInfo;
  UINT32                    IdeChannel;
  UINT32                    IdeDevice;
  UINT32                    Size;
  UINT8                     *InquiryData;
  UINT32                    InquiryDataSize;
  HDD_INFO                  *LocalHddInfo;
  UINT32                    PciIndex;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePathNode;
  PCI_DEVICE_PATH           *PciDevicePath;

  //
  // Only build data once
  // We have a problem with GetBbsInfo in that it can be invoked two
  // places. Once in BDS, when all EFI drivers are connected and once in
  // LegacyBoot after all EFI drivers are disconnected causing this routine
  // to hang. In LegacyBoot this function is also called before EFI drivers
  // are disconnected.
  // Cases covered
  //    GetBbsInfo invoked in BDS. Both invocations in LegacyBoot ignored.
  //    GetBbsInfo not invoked in BDS. First invocation of this function
  //       proceeds normally and second via GetBbsInfo ignored.
  //
  PciDevicePath = NULL;
  LocalHddInfo  = *HddInfo;
  Status        = Private->LegacyBiosPlatform->GetPlatformHandle (
                                                 Private->LegacyBiosPlatform,
                                                 EfiGetPlatformIdeHandle,
                                                 0,
                                                 &HandleBuffer,
                                                 &HandleCount,
                                                 (VOID *)&LocalHddInfo
                                                 );
  if (!EFI_ERROR (Status)) {
    IdeController = HandleBuffer[0];
    //
    // Force IDE drive spin up!
    //
    if (Flag != 0) {
      gBS->DisconnectController (
             IdeController,
             NULL,
             NULL
             );
    }

    gBS->ConnectController (IdeController, NULL, NULL, FALSE);

    //
    // Do GetIdeHandle twice since disconnect/reconnect will switch to native mode
    // And GetIdeHandle will switch to Legacy mode, if required.
    //
    Private->LegacyBiosPlatform->GetPlatformHandle (
                                   Private->LegacyBiosPlatform,
                                   EfiGetPlatformIdeHandle,
                                   0,
                                   &HandleBuffer,
                                   &HandleCount,
                                   (VOID *)&LocalHddInfo
                                   );
  }

  mIdeDataBuiltFlag = TRUE;

  //
  // Get Identity command from all drives
  //
  gBS->LocateHandleBuffer (
         ByProtocol,
         &gEfiDiskInfoProtocolGuid,
         NULL,
         &HandleCount,
         &HandleBuffer
         );

  Private->IdeDriveCount = (UINT8)HandleCount;
  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiDiskInfoProtocolGuid,
                    (VOID **)&DiskInfo
                    );
    ASSERT_EFI_ERROR (Status);

    if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid)) {
      //
      //  Locate which PCI device
      //
      Status = gBS->HandleProtocol (
                      HandleBuffer[Index],
                      &gEfiDevicePathProtocolGuid,
                      (VOID *)&DevicePath
                      );
      ASSERT_EFI_ERROR (Status);

      DevicePathNode = DevicePath;
      while (!IsDevicePathEnd (DevicePathNode)) {
        TempDevicePathNode = NextDevicePathNode (DevicePathNode);
        if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) &&
            (DevicePathSubType (DevicePathNode) == HW_PCI_DP) &&
            (DevicePathType (TempDevicePathNode) == MESSAGING_DEVICE_PATH) &&
            (DevicePathSubType (TempDevicePathNode) == MSG_ATAPI_DP))
        {
          PciDevicePath = (PCI_DEVICE_PATH *)DevicePathNode;
          break;
        }

        DevicePathNode = NextDevicePathNode (DevicePathNode);
      }

      if (PciDevicePath == NULL) {
        continue;
      }

      //
      // Find start of PCI device in HddInfo. The assumption of the data
      // structure is 2 controllers(channels) per PCI device and each
      // controller can have 2 drives(devices).
      // HddInfo[PciIndex+0].[0] = Channel[0].Device[0] Primary Master
      // HddInfo[PciIndex+0].[1] = Channel[0].Device[1] Primary Slave
      // HddInfo[PciIndex+1].[0] = Channel[1].Device[0] Secondary Master
      // HddInfo[PciIndex+1].[1] = Channel[1].Device[1] Secondary Slave
      // @bug eventually need to pass in max number of entries
      // for end of for loop
      //
      for (PciIndex = 0; PciIndex < 8; PciIndex++) {
        if ((PciDevicePath->Device == LocalHddInfo[PciIndex].Device) &&
            (PciDevicePath->Function == LocalHddInfo[PciIndex].Function)
            )
        {
          break;
        }
      }

      if (PciIndex == 8) {
        continue;
      }

      Status = DiskInfo->WhichIde (DiskInfo, &IdeChannel, &IdeDevice);
      if (!EFI_ERROR (Status)) {
        Size = sizeof (ATAPI_IDENTIFY);
        DiskInfo->Identify (
                    DiskInfo,
                    &LocalHddInfo[PciIndex + IdeChannel].IdentifyDrive[IdeDevice],
                    &Size
                    );
        if (IdeChannel == 0) {
          LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_PRIMARY;
        } else if (IdeChannel == 1) {
          LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SECONDARY;
        }

        InquiryData     = NULL;
        InquiryDataSize = 0;
        Status          = DiskInfo->Inquiry (
                                      DiskInfo,
                                      NULL,
                                      &InquiryDataSize
                                      );
        if (Status == EFI_BUFFER_TOO_SMALL) {
          InquiryData = (UINT8 *)AllocatePool (
                                   InquiryDataSize
                                   );
          if (InquiryData != NULL) {
            Status = DiskInfo->Inquiry (
                                 DiskInfo,
                                 InquiryData,
                                 &InquiryDataSize
                                 );
          }
        } else {
          Status = EFI_DEVICE_ERROR;
        }

        //
        // If ATAPI device then Inquiry will pass and ATA fail.
        //
        if (!EFI_ERROR (Status)) {
          ASSERT (InquiryData != NULL);
          //
          // If IdeDevice = 0 then set master bit, else slave bit
          //
          if (IdeDevice == 0) {
            if ((InquiryData[0] & 0x1f) == 0x05) {
              LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_CDROM;
            } else if ((InquiryData[0] & 0x1f) == 0x00) {
              LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_ZIPDISK;
            }
          } else {
            if ((InquiryData[0] & 0x1f) == 0x05) {
              LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_CDROM;
            } else if ((InquiryData[0] & 0x1f) == 0x00) {
              LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_ZIPDISK;
            }
          }

          FreePool (InquiryData);
        } else {
          if (IdeDevice == 0) {
            LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_IDE;
          } else {
            LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_IDE;
          }
        }
      }
    }
  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }

  return EFI_SUCCESS;
}

/**
  If the IDE channel is in compatibility (legacy) mode, remove all
  PCI I/O BAR addresses from the controller.

  @param  IdeController  The handle of target IDE controller


**/
VOID
InitLegacyIdeController (
  IN EFI_HANDLE  IdeController
  )
{
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINT32               IOBarClear;
  EFI_STATUS           Status;
  PCI_TYPE00           PciData;

  //
  // If the IDE channel is in compatibility (legacy) mode, remove all
  // PCI I/O BAR addresses from the controller.  Some software gets
  // confused if an IDE controller is in compatibility (legacy) mode
  // and has PCI I/O resources allocated
  //
  Status = gBS->HandleProtocol (
                  IdeController,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciData), &PciData);
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Check whether this is IDE
  //
  if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) ||
      (PciData.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE))
  {
    return;
  }

  //
  // Clear bar for legacy IDE
  //
  IOBarClear = 0x00;
  if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_PNE) == 0) {
    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x10, 1, &IOBarClear);
    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x14, 1, &IOBarClear);
  }

  if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_SNE) == 0) {
    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x18, 1, &IOBarClear);
    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1C, 1, &IOBarClear);
  }

  return;
}
