// 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 <fbl/alloc_checker.h>
#include <kernel/auto_lock.h>
#include <lib/counters.h>
#include <object/pci_device_dispatcher.h>
#include <platform.h>
#include <zircon/rights.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
