/** @file
 Emu Bus driver

Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2011, Apple Inc. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.


**/

#include "EmuBusDriverDxe.h"



//
// DriverBinding protocol global
//
EFI_DRIVER_BINDING_PROTOCOL           gEmuBusDriverBinding = {
  EmuBusDriverBindingSupported,
  EmuBusDriverBindingStart,
  EmuBusDriverBindingStop,
  0xa,
  NULL,
  NULL
};



EFI_STATUS
EFIAPI
EmuBusDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
  EMU_THUNK_PROTOCOL        *EmuThunk;

  //
  // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
  // it is a legal Device Path Node for this bus driver's children.
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node,
    // if yes, go on checking other conditions
    //
    if (!IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath isn't the End of Device Path Node,
      // check its validation
      //
      if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
          RemainingDevicePath->SubType != HW_VENDOR_DP ||
          DevicePathNodeLength(RemainingDevicePath) != sizeof(EMU_VENDOR_DEVICE_PATH_NODE)) {
        return EFI_UNSUPPORTED;
      }
    }
  }

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEmuThunkProtocolGuid,
                  (VOID **)&EmuThunk   ,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEmuThunkProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  //
  // Open the EFI Device Path protocol needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }


  //
  // Close protocol, don't use device path protocol in the Support() function
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEfiDevicePathProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  return Status;
}


EFI_STATUS
EFIAPI
EmuBusDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                      Status;
  EFI_STATUS                      InstallStatus;
  EMU_THUNK_PROTOCOL              *EmuThunk;
  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
  EMU_IO_DEVICE                   *EmuDevice;
  EMU_BUS_DEVICE                  *EmuBusDevice;
  EMU_IO_THUNK_PROTOCOL           *EmuIoThunk;
  UINT16                          ComponentName[512];
  EMU_VENDOR_DEVICE_PATH_NODE     *Node;
  BOOLEAN                         CreateDevice;

  InstallStatus = EFI_UNSUPPORTED;
  Status = EFI_UNSUPPORTED;

  //
  // Grab the protocols we need
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEmuThunkProtocolGuid,
                  (VOID **)&EmuThunk,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  if (Status != EFI_ALREADY_STARTED) {
    EmuBusDevice = AllocatePool (sizeof (EMU_BUS_DEVICE));
    if (EmuBusDevice == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    EmuBusDevice->Signature           = EMU_BUS_DEVICE_SIGNATURE;
    EmuBusDevice->ControllerNameTable = NULL;

    AddUnicodeString2 (
      "eng",
      gEmuBusDriverComponentName.SupportedLanguages,
      &EmuBusDevice->ControllerNameTable,
      L"Emulator Bus Controller",
      TRUE
      );
    AddUnicodeString2 (
      "en",
      gEmuBusDriverComponentName2.SupportedLanguages,
      &EmuBusDevice->ControllerNameTable,
      L"Emulator Bus Controller",
      FALSE
      );


    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ControllerHandle,
                    &gEfiCallerIdGuid, EmuBusDevice,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
      gBS->FreePool (EmuBusDevice);
      return Status;
    }
  }


  for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) {
    Status = EmuThunk->GetNextProtocol (TRUE, &EmuIoThunk);
    if (EFI_ERROR (Status)) {
      break;
    }

    CreateDevice = TRUE;
    if (RemainingDevicePath != NULL) {
      CreateDevice  = FALSE;
      //
      // Check if RemainingDevicePath is the End of Device Path Node,
      // if yes, don't create any child device
      //
      if (!IsDevicePathEnd (RemainingDevicePath)) {
        //
        // If RemainingDevicePath isn't the End of Device Path Node,
        // check its validation
        //
        Node          = (EMU_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
        if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
            Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
            DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (EMU_VENDOR_DEVICE_PATH_NODE)
            ) {
          if (CompareGuid (&Node->VendorDevicePath.Guid, EmuIoThunk->Protocol) && Node->Instance == EmuIoThunk->Instance) {
            CreateDevice = TRUE;
          }
        }
      }
    }

    if (CreateDevice) {
      //
      // Allocate instance structure, and fill in parent information.
      //
      EmuDevice = AllocatePool (sizeof (EMU_IO_DEVICE));
      if (EmuDevice == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      EmuDevice->Handle             = NULL;
      EmuDevice->ControllerHandle   = ControllerHandle;
      EmuDevice->ParentDevicePath   = ParentDevicePath;
      CopyMem (&EmuDevice->EmuIoThunk, EmuIoThunk, sizeof (EMU_IO_THUNK_PROTOCOL));

      EmuDevice->ControllerNameTable = NULL;

      StrnCpy (ComponentName, EmuIoThunk->ConfigString, sizeof (ComponentName)/sizeof (CHAR16));

      EmuDevice->DevicePath = EmuBusCreateDevicePath (
                                  ParentDevicePath,
                                  EmuIoThunk->Protocol,
                                  EmuIoThunk->Instance
                                  );
      if (EmuDevice->DevicePath == NULL) {
        gBS->FreePool (EmuDevice);
        return EFI_OUT_OF_RESOURCES;
      }

      AddUnicodeString (
        "eng",
        gEmuBusDriverComponentName.SupportedLanguages,
        &EmuDevice->ControllerNameTable,
        ComponentName
        );

      EmuDevice->Signature = EMU_IO_DEVICE_SIGNATURE;

      InstallStatus = gBS->InstallMultipleProtocolInterfaces (
                            &EmuDevice->Handle,
                            &gEfiDevicePathProtocolGuid,  EmuDevice->DevicePath,
                            &gEmuIoThunkProtocolGuid,     &EmuDevice->EmuIoThunk,
                            NULL
                            );
      if (EFI_ERROR (InstallStatus)) {
        FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
        gBS->FreePool (EmuDevice);
      } else {
        //
        // Open For Child Device
        //
        Status = gBS->OpenProtocol (
                        ControllerHandle,
                        &gEmuThunkProtocolGuid,
                        (VOID **)&EmuThunk   ,
                        This->DriverBindingHandle,
                        EmuDevice->Handle,
                        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                        );
        if (!EFI_ERROR (Status)) {
          InstallStatus = EFI_SUCCESS;
        }
      }
    }
  }

  return InstallStatus;
}


EFI_STATUS
EFIAPI
EmuBusDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS                Status;
  UINTN                     Index;
  BOOLEAN                   AllChildrenStopped;
  EMU_IO_THUNK_PROTOCOL     *EmuIoThunk;
  EMU_BUS_DEVICE            *EmuBusDevice;
  EMU_IO_DEVICE             *EmuDevice;
  EMU_THUNK_PROTOCOL        *EmuThunk;

  //
  // Complete all outstanding transactions to Controller.
  // Don't allow any new transaction to Controller to be started.
  //

  if (NumberOfChildren == 0) {
    //
    // Close the bus driver
    //
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    &gEfiCallerIdGuid,
                    (VOID **)&EmuBusDevice,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    gBS->UninstallMultipleProtocolInterfaces (
          ControllerHandle,
          &gEfiCallerIdGuid,  EmuBusDevice,
          NULL
          );

    FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);

    gBS->FreePool (EmuBusDevice);

    gBS->CloseProtocol (
          ControllerHandle,
          &gEmuThunkProtocolGuid,
          This->DriverBindingHandle,
          ControllerHandle
          );

    gBS->CloseProtocol (
          ControllerHandle,
          &gEfiDevicePathProtocolGuid,
          This->DriverBindingHandle,
          ControllerHandle
          );
    return EFI_SUCCESS;
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {

    Status = gBS->OpenProtocol (
                    ChildHandleBuffer[Index],
                    &gEmuIoThunkProtocolGuid,
                    (VOID **)&EmuIoThunk,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      EmuDevice = EMU_IO_DEVICE_FROM_THIS (EmuIoThunk);

      Status = gBS->CloseProtocol (
                      ControllerHandle,
                      &gEmuThunkProtocolGuid,
                      This->DriverBindingHandle,
                      EmuDevice->Handle
                      );

      Status = gBS->UninstallMultipleProtocolInterfaces (
                      EmuDevice->Handle,
                      &gEfiDevicePathProtocolGuid,  EmuDevice->DevicePath,
                      &gEmuIoThunkProtocolGuid,     &EmuDevice->EmuIoThunk,
                      NULL
                      );

      if (EFI_ERROR (Status)) {
        gBS->OpenProtocol (
              ControllerHandle,
              &gEmuThunkProtocolGuid,
              (VOID **) &EmuThunk   ,
              This->DriverBindingHandle,
              EmuDevice->Handle,
              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
              );
      } else {
        //
        // Close the child handle
        //
        FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
        FreePool (EmuDevice);
      }
    }

    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}


/*++

Routine Description:
  Create a device path node using Guid and InstanceNumber and append it to
  the passed in RootDevicePath

Arguments:
  RootDevicePath - Root of the device path to return.

  Guid           - GUID to use in vendor device path node.

  InstanceNumber - Instance number to use in the vendor device path. This
                    argument is needed to make sure each device path is unique.

Returns:

  EFI_DEVICE_PATH_PROTOCOL

**/
EFI_DEVICE_PATH_PROTOCOL *
EmuBusCreateDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDevicePath,
  IN  EFI_GUID                  *Guid,
  IN  UINT16                    InstanceNumber
  )
{
  EMU_VENDOR_DEVICE_PATH_NODE  DevicePath;

  DevicePath.VendorDevicePath.Header.Type     = HARDWARE_DEVICE_PATH;
  DevicePath.VendorDevicePath.Header.SubType  = HW_VENDOR_DP;
  SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (EMU_VENDOR_DEVICE_PATH_NODE));

  //
  // The GUID defines the Class
  //
  CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));

  //
  // Add an instance number so we can make sure there are no Device Path
  // duplication.
  //
  DevicePath.Instance = InstanceNumber;

  return AppendDevicePathNode (
          RootDevicePath,
          (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
          );
}



/**
  The user Entry Point for module EmuBusDriver. The user code starts with this function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializeEmuBusDriver (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  Status = EfiLibInstallAllDriverProtocols (
             ImageHandle,
             SystemTable,
             &gEmuBusDriverBinding,
             ImageHandle,
             &gEmuBusDriverComponentName,
             NULL,
             NULL
             );
  ASSERT_EFI_ERROR (Status);


  return Status;
}




