// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#if WITH_KERNEL_PCIE

#include "object/pci_interrupt_dispatcher.h"

#include <lib/counters.h>
#include <platform.h>
#include <zircon/rights.h>

#include <fbl/alloc_checker.h>
#include <kernel/auto_lock.h>
#include <object/pci_device_dispatcher.h>

KCOUNTER(dispatcher_pci_interrupt_create_count, "dispatcher.pci_interrupt.create")
KCOUNTER(dispatcher_pci_interrupt_destroy_count, "dispatcher.pci_interrupt.destroy")

PciInterruptDispatcher::~PciInterruptDispatcher() {
  kcounter_add(dispatcher_pci_interrupt_destroy_count, 1);

  // Release our reference to our device.
  device_ = nullptr;
}

pcie_irq_handler_retval_t PciInterruptDispatcher::IrqThunk(const PcieDevice& dev, uint irq_id,
                                                           void* ctx) {
  DEBUG_ASSERT(ctx);
  auto thiz = reinterpret_cast<PciInterruptDispatcher*>(ctx);
  thiz->InterruptHandler();
  return PCIE_IRQRET_MASK;
}

zx_status_t PciInterruptDispatcher::Create(const fbl::RefPtr<PcieDevice>& device, uint32_t irq_id,
                                           bool maskable, zx_rights_t* out_rights,
                                           KernelHandle<InterruptDispatcher>* out_interrupt) {
  // Sanity check our args
  if (!device || !out_rights || !out_interrupt) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (!is_valid_interrupt(irq_id, 0)) {
    return ZX_ERR_INTERNAL;
  }

  // Attempt to allocate a new dispatcher wrapper.
  // Do not create a KernelHandle until all initialization has succeeded;
  // if an interrupt already exists on |vector| our on_zero_handles() would
  // tear down the existing interrupt when creation fails.
  fbl::AllocChecker ac;
  auto interrupt_dispatcher =
      fbl::AdoptRef(new (&ac) PciInterruptDispatcher(device, irq_id, maskable));
  if (!ac.check())
    return ZX_ERR_NO_MEMORY;

  Guard<fbl::Mutex> guard{interrupt_dispatcher->get_lock()};

  interrupt_dispatcher->set_flags(INTERRUPT_UNMASK_PREWAIT);

  // Register the interrupt
  zx_status_t status = interrupt_dispatcher->RegisterInterruptHandler();
  if (status != ZX_OK)
    return status;

  // Everything seems to have gone well.  Make sure the interrupt is unmasked
  // (if it is maskable) then transfer our dispatcher reference to the
  // caller.
  if (maskable) {
    device->UnmaskIrq(irq_id);
  }
  out_interrupt->reset(ktl::move(interrupt_dispatcher));
  *out_rights = ZX_DEFAULT_PCI_INTERRUPT_RIGHTS;
  return ZX_OK;
}

void PciInterruptDispatcher::MaskInterrupt() {
  if (maskable_)
    device_->MaskIrq(vector_);
}

void PciInterruptDispatcher::UnmaskInterrupt() {
  if (maskable_)
    device_->UnmaskIrq(vector_);
}

PciInterruptDispatcher::PciInterruptDispatcher(const fbl::RefPtr<PcieDevice>& device,
                                               uint32_t vector, bool maskable)
    : device_(device), vector_(vector), maskable_(maskable) {
  kcounter_add(dispatcher_pci_interrupt_create_count, 1);
}

zx_status_t PciInterruptDispatcher::RegisterInterruptHandler() {
  return device_->RegisterIrqHandler(vector_, IrqThunk, this);
}

void PciInterruptDispatcher::UnregisterInterruptHandler() {
  device_->RegisterIrqHandler(vector_, nullptr, nullptr);
}

#endif  // if WITH_KERNEL_PCIE
