// 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.

#pragma once

#include <ddk/phys-iter.h>
#include <ddk/protocol/usb/request.h>
#include <sys/types.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
#include <zircon/hw/usb.h>
#include <zircon/hw/usb-hub.h>
#include <zircon/listnode.h>

__BEGIN_CDECLS;

typedef struct usb_request usb_request_t;

// cache maintenance ops
#define USB_REQUEST_CACHE_INVALIDATE        ZX_VMO_OP_CACHE_INVALIDATE
#define USB_REQUEST_CACHE_CLEAN             ZX_VMO_OP_CACHE_CLEAN
#define USB_REQUEST_CACHE_CLEAN_INVALIDATE  ZX_VMO_OP_CACHE_CLEAN_INVALIDATE
#define USB_REQUEST_CACHE_SYNC              ZX_VMO_OP_CACHE_SYNC

typedef void (*usb_request_complete_cb)(usb_request_t* req, void* cookie);

// Returns a batch of completed requests for an endpoint.
// The client should free the completed_reqs array once they are finished with it.
typedef void (*usb_batch_complete_cb)(usb_request_t** completed_reqs, size_t num_completed,
                                      void* cookie);

typedef struct {
    zx_status_t (*control)(void* ctx, uint8_t request_type, uint8_t request, uint16_t value,
                           uint16_t index, void* data, size_t length, zx_time_t timeout,
                           size_t* out_length);
    // queues a USB request
    void (*request_queue)(void* ctx, usb_request_t* usb_request, usb_request_complete_cb,
                          void* cookie);

    zx_status_t (*configure_batch_callback)(void* ctx, uint8_t ep_address,
                                            usb_batch_complete_cb cb, void* cookie);

    usb_speed_t (*get_speed)(void* ctx);
    zx_status_t (*set_interface)(void* ctx, uint8_t interface_number, uint8_t alt_setting);
    uint8_t (*get_configuration)(void* ctx);
    zx_status_t (*set_configuration)(void* ctx, uint8_t configuration);
    zx_status_t (*enable_endpoint)(void* ctx, usb_endpoint_descriptor_t* ep_desc,
                                   usb_ss_ep_comp_descriptor_t* ss_comp_desc, bool enable);
    zx_status_t (*reset_endpoint)(void* ctx, uint8_t ep_address);
    size_t (*get_max_transfer_size)(void* ctx, uint8_t ep_address);
    uint32_t (*get_device_id)(void* ctx);
    void (*get_device_descriptor)(void* ctx, usb_device_descriptor_t* out_desc);
    zx_status_t (*get_configuration_descriptor)(void* ctx, uint8_t configuration,
                                                usb_configuration_descriptor_t** out,
                                                size_t* out_length);
    zx_status_t (*get_descriptor_list)(void* ctx, void** out_descriptors, size_t* out_length);
    zx_status_t (*get_string_descriptor)(void* ctx, uint8_t desc_id, uint16_t lang_id,
                                         uint8_t* buf, size_t buflen, size_t* out_actual,
                                         uint16_t* out_actual_lang_id);
    zx_status_t (*cancel_all)(void* ctx, uint8_t ep_address);
    uint64_t (*get_current_frame)(void* ctx);
    size_t (*get_request_size)(void* ctx);
} usb_protocol_ops_t;

typedef struct usb_protocol {
    usb_protocol_ops_t* ops;
    void* ctx;
} usb_protocol_t;

// synchronously executes a control request on endpoint zero
static inline zx_status_t usb_control(const usb_protocol_t* usb, uint8_t request_type,
                                      uint8_t request, uint16_t value, uint16_t index, void* data,
                                      size_t length, zx_time_t timeout, size_t* out_length) {
    return usb->ops->control(usb->ctx, request_type, request, value, index, data, length, timeout,
                             out_length);
}

static inline zx_status_t usb_get_descriptor(const usb_protocol_t* usb, uint8_t request_type,
                                             uint16_t type, uint16_t index, void* data,
                                             size_t length, zx_time_t timeout, size_t* out_length) {
    return usb_control(usb, request_type | USB_DIR_IN, USB_REQ_GET_DESCRIPTOR,
                       (uint16_t)(type << 8 | index), 0, data, length, timeout, out_length);
}

static inline zx_status_t usb_get_status(const usb_protocol_t* usb, uint8_t request_type,
                                         uint16_t index, void* data, size_t length,
                                         zx_time_t timeout, size_t* out_length) {
    return usb_control(usb, request_type | USB_DIR_IN, USB_REQ_GET_STATUS, 0, index, data, length,
                       timeout, out_length);
}

static inline zx_status_t usb_set_feature(const usb_protocol_t* usb, uint8_t request_type,
                                          uint16_t feature, uint16_t index, zx_time_t timeout) {
    return usb_control(usb, request_type, USB_REQ_SET_FEATURE, feature, index, NULL, 0, timeout,
                       NULL);
}

static inline zx_status_t usb_clear_feature(const usb_protocol_t* usb, uint8_t request_type,
                                            uint16_t feature, uint16_t index, zx_time_t timeout) {
    return usb_control(usb, request_type, USB_REQ_CLEAR_FEATURE, feature, index, NULL, 0, timeout,
                       NULL);
}

static inline void usb_request_queue(const usb_protocol_t* usb, usb_request_t* usb_request,
                                     usb_request_complete_cb cb, void* cookie) {
    return usb->ops->request_queue(usb->ctx, usb_request, cb, cookie);
}

// Configures an endpoint to batch multiple requests to a single callback.
// Requests will receive a callback if they have set require_batch_cb to true, or an error occurs.
//   ep_address: the endpoint which requests will be queued on.
//   complete_cb: callback for the batch of completed requests.
//   cookie: user data passed to the |complete_cb|.
static inline zx_status_t usb_configure_batch_callback(const usb_protocol_t* usb,
                                                       uint8_t ep_address,
                                                       usb_batch_complete_cb complete_cb,
                                                       void* cookie) {
    return usb->ops->configure_batch_callback(usb->ctx, ep_address, complete_cb, cookie);
}

static inline usb_speed_t usb_get_speed(const usb_protocol_t* usb) {
    return usb->ops->get_speed(usb->ctx);
}

static inline zx_status_t usb_set_interface(const usb_protocol_t* usb, uint8_t interface_number,
                                            uint8_t alt_setting) {
    return usb->ops->set_interface(usb->ctx, interface_number, alt_setting);
}

static inline uint8_t usb_get_configuration(const usb_protocol_t* usb) {
    return usb->ops->get_configuration(usb->ctx);
}

static inline zx_status_t usb_set_configuration(const usb_protocol_t* usb, uint8_t configuration) {
    return usb->ops->set_configuration(usb->ctx, configuration);
}

static inline zx_status_t usb_enable_endpoint(const usb_protocol_t* usb,
                                              usb_endpoint_descriptor_t* ep_desc,
                                              usb_ss_ep_comp_descriptor_t* ss_comp_desc,
                                              bool enable) {
    return usb->ops->enable_endpoint(usb->ctx, ep_desc, ss_comp_desc, enable);
}

// Resets an endpoint that is in a halted or error state.
// Endpoints will be halted if the device returns a STALL in response to a USB transaction.
// When that occurs, the transaction will fail with ERR_IO_REFUSED.
// usb_reset_endpoint() the endpoint to normal running state.
static inline zx_status_t usb_reset_endpoint(const usb_protocol_t* usb, uint8_t ep_address) {
    return usb->ops->reset_endpoint(usb->ctx, ep_address);
}

// returns the maximum amount of data that can be transferred on an endpoint in a single transaction.
static inline size_t usb_get_max_transfer_size(const usb_protocol_t* usb, uint8_t ep_address) {
    return usb->ops->get_max_transfer_size(usb->ctx, ep_address);
}

// Returns the device ID for the device.
// This ID is generated by and used internally by the USB HCI controller driver.
static inline uint32_t usb_get_device_id(const usb_protocol_t* usb) {
    return usb->ops->get_device_id(usb->ctx);
}

// Returns the device's device descriptor.
static inline void usb_get_device_descriptor(const usb_protocol_t* usb,
                                             usb_device_descriptor_t* out_desc) {
    usb->ops->get_device_descriptor(usb->ctx, out_desc);
}

// Returns the configuration descriptor for the given configuration.
static inline zx_status_t usb_get_configuration_descriptor(const usb_protocol_t* usb,
                                                           uint8_t configuration,
                                                           usb_configuration_descriptor_t** out,
                                                           size_t* out_length) {
    return usb->ops->get_configuration_descriptor(usb->ctx, configuration, out, out_length);
}

// returns the USB descriptors for the USB device or interface
// the returned value is de-allocated with free()
static inline zx_status_t usb_get_descriptor_list(const usb_protocol_t* usb, void** out_descriptors,
                                                  size_t* out_length) {
    return usb->ops->get_descriptor_list(usb->ctx, out_descriptors, out_length);
}

// Fetch the descriptor using the provided descriptor ID and language ID.  If
// the language ID requested is not available, the first entry of the language
// ID table will be used instead and be provided in the updated version of the
// parameter.
//
// The string will be encoded using UTF-8, and will be truncated to fit the
// space provided by the buflen parameter.  Embedded nulls may be present
// in the string, and the result may not be null terminated if the string
// occupies the entire provided buffer.
//
static inline zx_status_t usb_get_string_descriptor(const usb_protocol_t* usb, uint8_t desc_id, 
                                                    uint16_t lang_id, uint8_t* buf, size_t buflen,
                                                    size_t* out_actual,
                                                    uint16_t* out_actual_lang_id) {
    return usb->ops->get_string_descriptor(usb->ctx, desc_id, lang_id, buf, buflen, out_actual,
                                           out_actual_lang_id);
}

static inline zx_status_t usb_cancel_all(const usb_protocol_t* usb, uint8_t ep_address) {
    return usb->ops->cancel_all(usb->ctx, ep_address);
}

// returns the current frame (in milliseconds), used for isochronous transfers
static inline uint64_t usb_get_current_frame(const usb_protocol_t* usb) {
    return usb->ops->get_current_frame(usb->ctx);
}

// return the internal context size plus parents request size
static inline uint64_t usb_get_request_size(const usb_protocol_t* usb) {
    return usb->ops->get_request_size(usb->ctx);
}
__END_CDECLS;
