// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device.h"

#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>

#include <ddk/debug.h>
#include <hw/inout.h>
#include <pretty/hexdump.h>
#include <zircon/status.h>

#include <utility>

#include "trace.h"

#define LOCAL_TRACE 0

namespace virtio {

Device::Device(zx_device_t* bus_device, zx::bti bti, fbl::unique_ptr<Backend> backend)
    : bti_(std::move(bti)), backend_(std::move(backend)), bus_device_(bus_device) {
    LTRACE_ENTRY;
    device_ops_.version = DEVICE_OPS_VERSION;
}

Device::~Device() {
    LTRACE_ENTRY;
}

void Device::Unbind() {
    device_remove(device_);
}

void Device::Release() {
    backend_.reset();
}

void Device::IrqWorker() {
    zx_status_t rc;
    zxlogf(TRACE, "%s: starting irq worker\n", tag());

    while (backend_->InterruptValid() == ZX_OK) {
        if ((rc = backend_->WaitForInterrupt()) != ZX_OK) {
            zxlogf(SPEW, "%s: error while waiting for interrupt: %s\n",
                   tag(), zx_status_get_string(rc));
            continue;
        }

        // Read the status before completing the interrupt in case
        // another interrupt fires and changes the status.
        uint32_t irq_status = IsrStatus();

        LTRACEF_LEVEL(2, "irq_status %#x\n", irq_status);

        // Since we handle both interrupt types here it's possible for a
        // spurious interrupt if they come in sequence and we check IsrStatus
        // after both have been triggered.
        if (irq_status == 0)
            continue;

        if (irq_status & VIRTIO_ISR_QUEUE_INT) { /* used ring update */
            IrqRingUpdate();
        }
        if (irq_status & VIRTIO_ISR_DEV_CFG_INT) { /* config change */
            IrqConfigChange();
        }
    }
}

int Device::IrqThreadEntry(void* arg) {
    Device* d = static_cast<Device*>(arg);

    d->IrqWorker();

    return 0;
}

void Device::StartIrqThread() {
    thrd_create_with_name(&irq_thread_, IrqThreadEntry, this, "virtio-irq-thread");
    thrd_detach(irq_thread_);
}

zx_status_t Device::CopyDeviceConfig(void* _buf, size_t len) const {
    assert(_buf);

    for (uint16_t i = 0; i < len; i++) {
        backend_->ReadDeviceConfig(i, static_cast<uint8_t*>(_buf) + i);
    }

    return ZX_OK;
}

} // namespace virtio
