// 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 <usb/usb-request.h>
#include <ddk/debug.h>

#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

static inline size_t req_buffer_size(usb_request_t* req, size_t offset) {
    size_t remaining = req->size - req->offset - offset;
    // May overflow.
    if (remaining > req->size) {
        remaining = 0;
    }
    return remaining;
}

static inline void* req_buffer_virt(usb_request_t* req) {
    return (void*)(((uintptr_t)req->virt) + req->offset);
}

// Frees any resources allocated by the usb request, but not the usb request itself.
static void usb_request_release_static(usb_request_t* req) {
    if (req->vmo_handle != ZX_HANDLE_INVALID) {
        if (req->pmt != ZX_HANDLE_INVALID) {
            zx_status_t status = zx_pmt_unpin(req->pmt);
            ZX_DEBUG_ASSERT(status == ZX_OK);
            req->pmt = ZX_HANDLE_INVALID;
        }

        zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)req->virt, req->size);
        zx_handle_close(req->vmo_handle);
        req->vmo_handle = ZX_HANDLE_INVALID;
    }
    if (req->phys_list && req->pmt != ZX_HANDLE_INVALID) {
        zx_status_t status = zx_pmt_unpin(req->pmt);
        ZX_DEBUG_ASSERT(status == ZX_OK);
        req->pmt = ZX_HANDLE_INVALID;
    }
    free(req->phys_list);
    req->phys_list = NULL;
    req->phys_count = 0;
}

// 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);
}

__EXPORT 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;
    }
    zx_status_t status = ZX_OK;
    if (data_size > 0) {
        status = zx_vmo_create(data_size, 0, &req->vmo_handle);
        if (status != ZX_OK) {
            zxlogf(ERROR, "usb_request_alloc: Failed to create vmo: %d\n", status);
            free(req);
            return status;
        }

        zx_vaddr_t mapped_addr;
        status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                             0, req->vmo_handle, 0, data_size, &mapped_addr);

        if (status != ZX_OK) {
            zxlogf(ERROR, "usb_request_alloc: Failed to map the vmo: %d\n", status);
            free(req);
            return status;
        }

        req->virt = (void *)mapped_addr;
        req->offset = 0;
        req->size = data_size;
    }
    req->header.ep_address = ep_address;
    req->header.length = data_size;
    req->release_cb = usb_request_release_free;
    *out = req;
    return ZX_OK;
}

// usb_request_alloc_vmo() creates a new usb request with the given VMO.
__EXPORT 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_handle_t dup_handle;
    zx_status_t status = zx_handle_duplicate(vmo_handle, ZX_RIGHT_SAME_RIGHTS, &dup_handle);
    if (status != ZX_OK) {
        zxlogf(ERROR, "usb_request_alloc_vmo: Failed to duplicate handle: %d\n", status);
        free(req);
        return status;
    }

    uint64_t size;
    status = zx_vmo_get_size(dup_handle, &size);
    if (status != ZX_OK) {
        zx_handle_close(dup_handle);
        free(req);
        return status;
    }

    zx_vaddr_t mapped_addr;
    status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                         0, dup_handle, 0, size, &mapped_addr);
    if (status != ZX_OK) {
        zxlogf(ERROR, "usb_request_alloc_vmo: zx_vmar_map failed %d size: %zu\n", status, size);
        zx_handle_close(dup_handle);
        free(req);
        return status;
    }

    req->vmo_handle = dup_handle;
    req->virt = (void *)mapped_addr;
    req->offset = vmo_offset;
    req->size = size;

    req->pmt = ZX_HANDLE_INVALID;

    req->header.ep_address = ep_address;
    req->header.length = length;
    req->release_cb = usb_request_release_free;
    *out = req;
    return ZX_OK;
}

// usb_request_init() initializes the statically allocated usb request with the given VMO.
// This will free any resources allocated by the usb request but not the usb request itself.
__EXPORT 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_handle_t dup_handle;
    zx_status_t status = zx_handle_duplicate(vmo_handle, ZX_RIGHT_SAME_RIGHTS, &dup_handle);
    if (status != ZX_OK) {
        zxlogf(ERROR, "usb_request_init: Failed to duplicate handle: %d\n", status);
        return status;
    }

    uint64_t size;
    status = zx_vmo_get_size(dup_handle, &size);
    if (status != ZX_OK) {
        zx_handle_close(dup_handle);
        return status;
    }

    //TODO(ravoorir): Do not map the entire vmo. Map only what is needed.
    zx_vaddr_t mapped_addr;
    status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                         0, dup_handle, 0, size, &mapped_addr);
    if (status != ZX_OK) {
        zxlogf(ERROR, "usb_request_init: zx_vmar_map failed %d size: %zu\n", status, size);
        zx_handle_close(dup_handle);
        return status;
    }

    req->vmo_handle = dup_handle;
    req->virt = (void *)mapped_addr;
    req->offset = vmo_offset;
    req->size = size;

    req->pmt = ZX_HANDLE_INVALID;

    req->header.ep_address = ep_address;
    req->header.length = length;
    req->release_cb = usb_request_release_static;
    return ZX_OK;
}

__EXPORT ssize_t usb_request_copy_from(usb_request_t* req, void* data, size_t length, size_t offset) {
    length = MIN(req_buffer_size(req, offset), length);
    memcpy(data, req_buffer_virt(req) + offset, length);
    return length;
}

__EXPORT ssize_t usb_request_copy_to(usb_request_t* req, const void* data, size_t length, size_t offset) {
    length = MIN(req_buffer_size(req, offset), length);
    memcpy(req_buffer_virt(req) + offset, data, length);
    return length;
}

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

__EXPORT zx_status_t usb_request_cacheop(usb_request_t* req, uint32_t op, size_t offset, size_t length) {
    if (length > 0) {
        return zx_vmo_op_range(req->vmo_handle, op, req->offset + offset, length, NULL, 0);
    } else {
        return ZX_OK;
    }
}

__EXPORT zx_status_t usb_request_cache_flush(usb_request_t* req, zx_off_t offset, size_t length) {
    if (offset + length < offset || offset + length > req->size) {
        return ZX_ERR_OUT_OF_RANGE;
    }
    return zx_cache_flush(req_buffer_virt(req) + offset, length, ZX_CACHE_FLUSH_DATA);
}

__EXPORT zx_status_t usb_request_cache_flush_invalidate(usb_request_t* req, zx_off_t offset, size_t length) {
    if (offset + length < offset || offset + length > req->size) {
        return ZX_ERR_OUT_OF_RANGE;
    }
    return zx_cache_flush(req_buffer_virt(req) + offset, length,
                          ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);
}

zx_status_t usb_request_physmap(usb_request_t* req, zx_handle_t bti_handle) {
    if (req->phys_count > 0) {
        return ZX_OK;
    }
    // zx_bti_pin returns whole pages, so take into account unaligned vmo
    // offset and length when calculating the amount of pages returned
    uint64_t page_offset = ROUNDDOWN(req->offset, PAGE_SIZE);
    // The buffer size is the vmo size from offset 0.
    uint64_t page_length = req->size - page_offset;
    uint64_t pages = ROUNDUP(page_length, PAGE_SIZE) / PAGE_SIZE;

    zx_paddr_t* paddrs = malloc(pages * sizeof(zx_paddr_t));
    if (paddrs == NULL) {
        zxlogf(ERROR, "usb_request_physmap: out of memory\n");
        return ZX_ERR_NO_MEMORY;
    }
    const size_t sub_offset = page_offset & (PAGE_SIZE - 1);
    const size_t pin_offset = page_offset - sub_offset;
    const size_t pin_length = ROUNDUP(page_length + sub_offset, PAGE_SIZE);

    if (pin_length / PAGE_SIZE != pages) {
        return ZX_ERR_INVALID_ARGS;
    }
    zx_handle_t pmt;
    uint32_t options = ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE;
    zx_status_t status = zx_bti_pin(bti_handle, options, req->vmo_handle,
                                    pin_offset, pin_length, paddrs, pages, &pmt);
    if (status != ZX_OK) {
        zxlogf(ERROR, "usb_request_physmap: zx_bti_pin failed:%d\n", status);
        free(paddrs);
        return status;
    }
    // Account for the initial misalignment if any
    paddrs[0] += sub_offset;
    req->phys_list = paddrs;
    req->phys_count = pages;
    req->pmt = pmt;

    return ZX_OK;
}

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

__EXPORT 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->cb_on_error_only && req->response.status == ZX_OK) {
        return;
    }
    if (req->complete_cb) {
        req->complete_cb(req, req->cookie);
    }
}

__EXPORT 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->offset,
        .phys = req->phys_list,
        .phys_count = req->phys_count,
    };
    phys_iter_init(iter, &buf, max_length);
}

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

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

__EXPORT 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);
}

__EXPORT 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->size == length) {
            found = true;
            break;
        }
    }
    if (found) {
        list_delete(&req->node);
    }
    mtx_unlock(&pool->lock);

    return found ? req : NULL;
}

__EXPORT void usb_request_pool_release(usb_request_pool_t* pool) {
    mtx_lock(&pool->lock);

    usb_request_t* req;
    while ((req = list_remove_tail_type(&pool->free_reqs, usb_request_t, node)) != NULL) {
        usb_request_release(req);
    }

    mtx_unlock(&pool->lock);
}
