// Copyright 2017 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 <ddk/protocol/usb.h>
#include <ddk/usb-request.h>
#include <zircon/syscalls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MIN(a, b) ((a) < (b) ? (a) : (b))

// Frees any resources allocated by the usb request, but not the usb request itself.
static void usb_request_release_static(usb_request_t* req) {
    io_buffer_release(&req->buffer);
}

// Frees any resources allocated by the usb request, as well as the usb request itself.
static void usb_request_release_free(usb_request_t* req) {
    usb_request_release_static(req);
    free(req);
}

zx_status_t usb_request_alloc(usb_request_t** out, uint64_t data_size, uint8_t ep_address) {
    usb_request_t* req = calloc(1, sizeof(usb_request_t));
    if (!req) {
        return ZX_ERR_NO_MEMORY;
    }
    if (data_size > 0) {
        zx_status_t status = io_buffer_init(&req->buffer, data_size, IO_BUFFER_RW);
        if (status != ZX_OK) {
            free(req);
            return status;
        }
    }
    req->header.ep_address = ep_address;
    req->header.length = data_size;
    req->release_cb = usb_request_release_free;
    *out = req;
    return ZX_OK;
}

zx_status_t usb_request_alloc_vmo(usb_request_t** out, zx_handle_t vmo_handle,
                                  uint64_t vmo_offset, uint64_t length, uint8_t ep_address) {
    usb_request_t* req = calloc(1, sizeof(usb_request_t));
    if (!req) {
        return ZX_ERR_NO_MEMORY;
    }
    zx_status_t status = io_buffer_init_vmo(&req->buffer, vmo_handle, vmo_offset, IO_BUFFER_RW);
    if (status != ZX_OK) {
        free(req);
        return status;
    }
    req->header.ep_address = ep_address;
    req->header.length = length;
    req->release_cb = usb_request_release_free;
    *out = req;
    return ZX_OK;
}

zx_status_t usb_request_init(usb_request_t* req, zx_handle_t vmo_handle, uint64_t vmo_offset,
                             uint64_t length, uint8_t ep_address) {
    memset(req, 0, sizeof(*req));

    zx_status_t status = io_buffer_init_vmo(&req->buffer, vmo_handle, vmo_offset, IO_BUFFER_RW);
    if (status != ZX_OK) {
        return status;
    }
    req->header.ep_address = ep_address;
    req->header.length = length;
    req->release_cb = usb_request_release_static;
    return ZX_OK;
}

ssize_t usb_request_copyfrom(usb_request_t* req, void* data, size_t length, size_t offset) {
    length = MIN(io_buffer_size(&req->buffer, offset), length);
    memcpy(data, io_buffer_virt(&req->buffer) + offset, length);
    return length;
}

ssize_t usb_request_copyto(usb_request_t* req, const void* data, size_t length, size_t offset) {
    length = MIN(io_buffer_size(&req->buffer, offset), length);
    memcpy(io_buffer_virt(&req->buffer) + offset, data, length);
    return length;
}

zx_status_t usb_request_mmap(usb_request_t* req, void** data) {
    *data = io_buffer_virt(&req->buffer);
    // TODO(jocelyndang): modify this once we start passing usb requests across process boundaries.
    return ZX_OK;
}

zx_status_t usb_request_cacheop(usb_request_t* req, uint32_t op, size_t offset, size_t length) {
    return io_buffer_cache_op(&req->buffer, op, offset, length);
}

zx_status_t usb_request_physmap(usb_request_t* req) {
    return io_buffer_physmap(&req->buffer);
}

void usb_request_release(usb_request_t* req) {
    if (req->release_cb) {
        req->release_cb(req);
    }
}

void usb_request_complete(usb_request_t* req, zx_status_t status, zx_off_t actual) {
    req->response.status = status;
    req->response.actual = actual;

    if (req->complete_cb) {
        req->complete_cb(req, req->cookie);
    }
}

void usb_request_phys_iter_init(phys_iter_t* iter, usb_request_t* req, size_t max_length) {
    phys_iter_buffer_t buf = {
        .length = req->header.length,
        .vmo_offset = req->buffer.offset,
        .phys = req->buffer.phys_list,
        .phys_count = req->buffer.phys_count
    };
    phys_iter_init(iter, &buf, max_length);
}

size_t usb_request_phys_iter_next(phys_iter_t* iter, zx_paddr_t* out_paddr) {
    return phys_iter_next(iter, out_paddr);
}

void usb_request_pool_init(usb_request_pool_t* pool) {
    mtx_init(&pool->lock, mtx_plain);
    list_initialize(&pool->free_reqs);
}

void usb_request_pool_add(usb_request_pool_t* pool, usb_request_t* req) {
    mtx_lock(&pool->lock);

    list_add_tail(&pool->free_reqs, &req->node);

    mtx_unlock(&pool->lock);
}

usb_request_t* usb_request_pool_get(usb_request_pool_t* pool, size_t length) {
    usb_request_t* req = NULL;
    bool found = false;

    mtx_lock(&pool->lock);
    list_for_every_entry (&pool->free_reqs, req, usb_request_t, node) {
        if (req->buffer.size == length) {
            found = true;
            break;
        }
    }
    if (found) {
        list_delete(&req->node);
    }
    mtx_unlock(&pool->lock);

    return found ? req : NULL;
}
