// 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 <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/metadata.h>
#include <ddk/protocol/usb/dci.h>
#include <ddk/protocol/usb/function.h>
#include <ddk/protocol/usb/modeswitch.h>
#include <fuchsia/hardware/usb/peripheral/c/fidl.h>
#include <zircon/device/usb-peripheral.h>
#include <zircon/hw/usb.h>
#include <zircon/hw/usb/cdc.h>
#include <zircon/listnode.h>

/*
    THEORY OF OPERATION

    This driver is responsible for USB in the peripheral role, that is,
    acting as a USB device to a USB host.
    It serves as the central point of coordination for the peripheral role.
    It is configured via ioctls in the ZX_PROTOCOL_USB_DEVICE protocol
    (which is used by the usbctl command line program).
    Based on this configuration, it creates one or more DDK devices with protocol
    ZX_PROTOCOL_USB_FUNCTION. These devices are bind points for USB function drivers,
    which implement USB interfaces for particular functions (like USB ethernet or mass storage).
    This driver also binds to a device with protocol ZX_PROTOCOL_USB_DCI
    (Device Controller Interface) which is implemented by a driver for the actual
    USB controller hardware for the peripheral role.

    There are several steps needed to initialize and start USB in the peripheral role.
    The first step is setting up the USB configuration via ioctls.
    ioctl_usb_peripheral_set_device_desc() sets the USB device descriptor to be presented
    to the host during enumeration.
    Next, ioctl_usb_peripheral_add_function() can be called one or more times to add
    descriptors for the USB functions to be included in the USB configuration.
    Finally after all the functions have been added, ioctl_usb_peripheral_bind_functions()
    tells this driver that configuration is complete and it is now possible to build
    the configuration descriptor. Once we get to this point, usb_device_t.functions_bound
    is set to true.

    Independent of this configuration process, ioctl_usb_peripheral_set_mode() can be used
    to configure the role of the USB controller. If the role is set to USB_MODE_PERIPHERAL
    and "functions_bound" is true, then we are ready to start USB in peripheral role.
    At this point, we create DDK devices for our list of functions.
    When the function drivers bind to these functions, they register an interface of type
    usb_function_interface_t with this driver via the usb_function_register() API.
    Once all of the function drivers have registered themselves this way,
    usb_device_t.functions_registered is set to true.

    if the usb mode is set to USB_MODE_PERIPHERAL and "functions_registered" is true,
    we are now finally ready to operate in the peripheral role.
    At this point we can inform the DCI driver to start running in peripheral role
    by calling usb_mode_switch_set_mode(USB_MODE_PERIPHERAL) on its ZX_PROTOCOL_USB_MODE_SWITCH
    interface. Now the USB controller hardware is up and running as a USB peripheral.

    Teardown of the peripheral role one of two ways:
    First, ioctl_usb_peripheral_clear_functions() will reset this device's list of USB functions.
    Second, the USB mode can be set to something other than USB_MODE_PERIPHERAL.
    In this second case, we will remove the DDK devices for the USB functions
    so the function drivers will unbind, but the USB configuration remains ready to go
    for when the USB mode is switched back to USB_MODE_PERIPHERAL.
*/

#define MAX_INTERFACES 32

typedef fuchsia_hardware_usb_peripheral_FunctionDescriptor usb_function_descriptor_t;

typedef struct {
    zx_device_t* zxdev;
    zx_device_t* dci_dev;
    struct usb_device* dev;
    list_node_t node;
    usb_function_interface_t interface;
    usb_function_descriptor_t desc;
    usb_descriptor_header_t* descriptors;
    size_t descriptors_length;
    unsigned num_interfaces;
} usb_function_t;

typedef struct usb_device {
    // the device we publish
    zx_device_t* zxdev;
    // our parent device
    zx_device_t* dci_dev;
    // our parent's DCI protocol
    usb_dci_protocol_t usb_dci;
    // our parent's USB switch protocol
    usb_mode_switch_protocol_t usb_mode_switch;
    // true if our parent implements usb_mode_switch_protocol_t
    bool has_usb_mode_switch;
    // USB device descriptor set via ioctl_usb_peripheral_set_device_desc()
    usb_device_descriptor_t device_desc;
    // USB configuration descriptor, synthesized from our functions' descriptors
    usb_configuration_descriptor_t* config_desc;
    // map from interface number to function
    usb_function_t* interface_map[MAX_INTERFACES];
    // map from endpoint index to function
    usb_function_t* endpoint_map[USB_MAX_EPS];
    // strings for USB string descriptors
    char* strings[256];
    // list of usb_function_t
    list_node_t functions;
    // mutex for protecting our state
    mtx_t lock;
    // current USB mode set via ioctl_usb_peripheral_set_mode()
    usb_mode_t usb_mode;
    // our parent's USB mode
     usb_mode_t dci_usb_mode;
    // set if ioctl_usb_peripheral_bind_functions() has been called
    // and we have a complete list of our function.
    bool functions_bound;
    // set if all our functions have registered their usb_function_interface_t
    bool functions_registered;
    // true if we have added child devices for our functions
    bool function_devs_added;
    // true if we are connected to a host
    bool connected;
    // current configuration number selected via USB_REQ_SET_CONFIGURATION
    // (will be 0 or 1 since we currently do not support multiple configurations)
    uint8_t configuration;
    // USB connection speed
    usb_speed_t speed;
    size_t parent_request_size;
} usb_device_t;

// for mapping bEndpointAddress value to/from index in range 0 - 31
// OUT endpoints are in range 1 - 15, IN endpoints are in range 17 - 31
#define ep_address_to_index(addr) (((addr) & 0xF) | (((addr) & 0x80) >> 3))
#define ep_index_to_address(index) (((index) & 0xF) | (((index) & 0x10) << 3))
#define OUT_EP_START    1
#define OUT_EP_END      15
#define IN_EP_START     17
#define IN_EP_END       31

static zx_status_t usb_dev_state_changed_locked(usb_device_t* dev);

static zx_status_t usb_device_alloc_string_desc(usb_device_t* dev, const char* string,
                                                uint8_t* out_index) {

    mtx_lock(&dev->lock);

    unsigned i;
    for (i = 1; i < countof(dev->strings); i++) {
        if (!dev->strings[i]) {
            break;
        }
    }
    if (i == countof(dev->strings)) {
        mtx_unlock(&dev->lock);
        return ZX_ERR_NO_RESOURCES;
    }

    dev->strings[i] = strdup(string);
    if (!dev->strings[i]) {
        mtx_unlock(&dev->lock);
        return ZX_ERR_NO_MEMORY;
    }

    mtx_unlock(&dev->lock);

    *out_index = i;
    return ZX_OK;
}

static zx_protocol_device_t function_proto = {
    .version = DEVICE_OPS_VERSION,
    // Note that we purposely do not have a release callback for USB functions.
    // The functions are kept on a list when not active so they can be re-added
    // when reentering device mode.
};

static zx_status_t usb_device_function_registered(usb_device_t* dev) {
    mtx_lock(&dev->lock);

    if (dev->config_desc) {
        zxlogf(ERROR, "usb_device_function_registered: already have configuration descriptor!\n");
        mtx_unlock(&dev->lock);
        return ZX_ERR_BAD_STATE;
    }

    // check to see if we have all our functions registered
    // if so, we can build our configuration descriptor and tell the DCI driver we are ready
    usb_function_t* function;
    size_t length = sizeof(usb_configuration_descriptor_t);
    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
        if (function->descriptors) {
            length += function->descriptors_length;
        } else {
            // need to wait for more functions to register
            mtx_unlock(&dev->lock);
            return ZX_OK;
        }
    }

    // build our configuration descriptor
    usb_configuration_descriptor_t* config_desc = malloc(length);
    if (!config_desc) {
        mtx_unlock(&dev->lock);
        return ZX_ERR_NO_MEMORY;
    }

    config_desc->bLength = sizeof(*config_desc);
    config_desc->bDescriptorType = USB_DT_CONFIG;
    config_desc->wTotalLength = htole16(length);
    config_desc->bNumInterfaces = 0;
    config_desc->bConfigurationValue = 1;
    config_desc->iConfiguration = 0;
    // TODO(voydanoff) add a way to configure bmAttributes and bMaxPower
    config_desc->bmAttributes = USB_CONFIGURATION_SELF_POWERED | USB_CONFIGURATION_RESERVED_7;
    config_desc->bMaxPower = 0;

    void* dest = config_desc + 1;
    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
        memcpy(dest, function->descriptors, function->descriptors_length);
        dest += function->descriptors_length;
        config_desc->bNumInterfaces += function->num_interfaces;
    }
    dev->config_desc = config_desc;

    zxlogf(TRACE, "usb_device_function_registered functions_registered = true\n");
    dev->functions_registered = true;

    zx_status_t status = usb_dev_state_changed_locked(dev);
    mtx_unlock(&dev->lock);
    return status;
}

static zx_status_t usb_func_set_interface(void* ctx, const usb_function_interface_t* interface) {
    usb_function_t* function = ctx;
    usb_device_t* dev = function->dev;
    usb_function_t** endpoint_map = dev->endpoint_map;

    size_t length = usb_function_interface_get_descriptors_size(interface);
    void* descriptors = malloc(length);
    if (!descriptors) {
        return ZX_ERR_NO_MEMORY;
    }
    size_t actual;
    usb_function_interface_get_descriptors(interface, descriptors, length, &actual);
    if (actual != length) {
        zxlogf(ERROR, "usb_function_interface_get_descriptors failed\n");
        return ZX_ERR_INTERNAL;
    }

    usb_interface_descriptor_t* intf_desc = (usb_interface_descriptor_t *)descriptors;
    if (intf_desc->bDescriptorType != USB_DT_INTERFACE ||
            intf_desc->bLength != sizeof(usb_interface_descriptor_t)) {
        zxlogf(ERROR, "usb_func_set_interface: first descriptor not an interface descriptor\n");
        return ZX_ERR_INVALID_ARGS;
    }

    const usb_descriptor_header_t* end = (void *)descriptors + length;
    const usb_descriptor_header_t* header = descriptors;

    while (header < end) {
        if (header->bDescriptorType == USB_DT_INTERFACE) {
            usb_interface_descriptor_t* desc = (usb_interface_descriptor_t *)header;
            if (desc->bInterfaceNumber >= countof(dev->interface_map) ||
                dev->interface_map[desc->bInterfaceNumber] != function) {
                zxlogf(ERROR, "usb_func_set_interface: bInterfaceNumber %u\n",
                       desc->bInterfaceNumber);
                return ZX_ERR_INVALID_ARGS;
            }
            if (desc->bAlternateSetting == 0) {
                function->num_interfaces++;
            }
        } else if (header->bDescriptorType == USB_DT_ENDPOINT) {
            usb_endpoint_descriptor_t* desc = (usb_endpoint_descriptor_t *)header;
            unsigned index = ep_address_to_index(desc->bEndpointAddress);
            if (index == 0 || index >= countof(dev->endpoint_map) ||
                endpoint_map[index] != function) {
                zxlogf(ERROR, "usb_func_set_interface: bad endpoint address 0x%X\n",
                       desc->bEndpointAddress);
                return ZX_ERR_INVALID_ARGS;
            }
        }

        if (header->bLength == 0) {
            zxlogf(ERROR, "usb_func_set_interface: zero length descriptor\n");
            return ZX_ERR_INVALID_ARGS;
        }
        header = (void *)header + header->bLength;
    }

    function->descriptors = malloc(length);
    if (!function->descriptors) {
        return ZX_ERR_NO_MEMORY;
    }
    memcpy(function->descriptors, descriptors, length);
    function->descriptors_length = length;
    memcpy(&function->interface, interface, sizeof(function->interface));

    return usb_device_function_registered(function->dev);
}

static zx_status_t usb_func_alloc_interface(void* ctx, uint8_t* out_intf_num) {
    usb_function_t* function = ctx;
    usb_device_t* dev = function->dev;

    mtx_lock(&dev->lock);

    for (unsigned i = 0; i < countof(dev->interface_map); i++) {
        if (dev->interface_map[i] == NULL) {
            dev->interface_map[i] = function;
            mtx_unlock(&dev->lock);
            *out_intf_num = i;
            return ZX_OK;
        }
    }

    mtx_unlock(&dev->lock);
    return ZX_ERR_NO_RESOURCES;
}

static zx_status_t usb_func_alloc_ep(void* ctx, uint8_t direction, uint8_t* out_address) {
    unsigned start, end;

    if (direction == USB_DIR_OUT) {
        start = OUT_EP_START;
        end = OUT_EP_END;
    } else if (direction == USB_DIR_IN) {
        start = IN_EP_START;
        end = IN_EP_END;
    } else {
        return ZX_ERR_INVALID_ARGS;
    }

    usb_function_t* function = ctx;
    usb_device_t* dev = function->dev;
    usb_function_t** endpoint_map = dev->endpoint_map;

    mtx_lock(&dev->lock);
    for (unsigned index = start; index <= end; index++) {
        if (endpoint_map[index] == NULL) {
            endpoint_map[index] = function;
            mtx_unlock(&dev->lock);
            *out_address = ep_index_to_address(index);
            return ZX_OK;
        }
    }

    mtx_unlock(&dev->lock);
    return ZX_ERR_NO_RESOURCES;
}

static zx_status_t usb_func_config_ep(void* ctx, const usb_endpoint_descriptor_t* ep_desc,
                                      const usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
    usb_function_t* function = ctx;
    return usb_dci_config_ep(&function->dev->usb_dci, ep_desc, ss_comp_desc);
}

static zx_status_t usb_func_disable_ep(void* ctx, uint8_t ep_addr) {
    zxlogf(TRACE, "usb_func_disable_ep\n");
    usb_function_t* function = ctx;
    return usb_dci_disable_ep(&function->dev->usb_dci, ep_addr);
}

static zx_status_t usb_func_alloc_string_desc(void* ctx, const char* string, uint8_t* out_index) {
    usb_function_t* function = ctx;
    return usb_device_alloc_string_desc(function->dev, string, out_index);
}

static void usb_func_request_queue(void* ctx, usb_request_t* req, const usb_request_complete_t* cb) {
    usb_function_t* function = ctx;
    usb_dci_request_queue(&function->dev->usb_dci, req, cb);
}

static zx_status_t usb_func_ep_set_stall(void* ctx, uint8_t ep_address) {
    usb_function_t* function = ctx;
    return usb_dci_ep_set_stall(&function->dev->usb_dci, ep_address);
}

static zx_status_t usb_func_ep_clear_stall(void* ctx, uint8_t ep_address) {
    usb_function_t* function = ctx;
    return usb_dci_ep_clear_stall(&function->dev->usb_dci, ep_address);
}

static size_t usb_func_get_request_size(void* ctx) {
    usb_function_t* function = ctx;
    return function->dev->parent_request_size;
}

usb_function_protocol_ops_t usb_function_proto = {
    .set_interface = usb_func_set_interface,
    .alloc_interface = usb_func_alloc_interface,
    .alloc_ep = usb_func_alloc_ep,
    .config_ep = usb_func_config_ep,
    .disable_ep = usb_func_disable_ep,
    .alloc_string_desc = usb_func_alloc_string_desc,
    .request_queue = usb_func_request_queue,
    .ep_set_stall = usb_func_ep_set_stall,
    .ep_clear_stall = usb_func_ep_clear_stall,
    .get_request_size = usb_func_get_request_size,
};

static zx_status_t usb_dev_get_descriptor(usb_device_t* dev, uint8_t request_type,
                                          uint16_t value, uint16_t index, void* buffer,
                                          size_t length, size_t* out_actual) {
    uint8_t type = request_type & USB_TYPE_MASK;

    if (type == USB_TYPE_STANDARD) {
        uint8_t desc_type = value >> 8;
        if (desc_type == USB_DT_DEVICE && index == 0) {
            const usb_device_descriptor_t* desc = &dev->device_desc;
            if (desc->bLength == 0) {
                zxlogf(ERROR, "usb_dev_get_descriptor: device descriptor not set\n");
                return ZX_ERR_INTERNAL;
            }
            if (length > sizeof(*desc)) length = sizeof(*desc);
            memcpy(buffer, desc, length);
            *out_actual = length;
            return ZX_OK;
        } else if (desc_type == USB_DT_CONFIG && index == 0) {
            const usb_configuration_descriptor_t* desc = dev->config_desc;
            if (!desc) {
                zxlogf(ERROR, "usb_dev_get_descriptor: configuration descriptor not set\n");
                return ZX_ERR_INTERNAL;
            }
            uint16_t desc_length = letoh16(desc->wTotalLength);
            if (length > desc_length) length =desc_length;
            memcpy(buffer, desc, length);
            *out_actual = length;
            return ZX_OK;
        }
        else if (value >> 8 == USB_DT_STRING) {
            uint8_t desc[255];
            usb_descriptor_header_t* header = (usb_descriptor_header_t *)desc;
            header->bDescriptorType = USB_DT_STRING;

            uint8_t string_index = value & 0xFF;
            if (string_index == 0) {
                // special case - return language list
                header->bLength = 4;
                desc[2] = 0x09;     // language ID
                desc[3] = 0x04;
            } else {
                char* string = dev->strings[string_index];
                if (!string) {
                    return ZX_ERR_INVALID_ARGS;
                }
                unsigned index = 2;

                // convert ASCII to Unicode
                if (string) {
                    while (*string && index < sizeof(desc) - 2) {
                        desc[index++] = *string++;
                        desc[index++] = 0;
                    }
                }
                header->bLength = index;
            }

            if (header->bLength < length) length = header->bLength;
            memcpy(buffer, desc, length);
            *out_actual = length;
            return ZX_OK;
        }
    }

    zxlogf(ERROR, "usb_device_get_descriptor unsupported value: %d index: %d\n", value, index);
    return ZX_ERR_NOT_SUPPORTED;
}

static zx_status_t usb_dev_set_configuration(usb_device_t* dev, uint8_t configuration) {
    zx_status_t status = ZX_OK;
    bool configured = configuration > 0;

    mtx_lock(&dev->lock);

    usb_function_t* function;
    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
        if (function->interface.ops) {
            status = usb_function_interface_set_configured(&function->interface, configured,
                                                           dev->speed);
            if (status != ZX_OK && configured) {
                goto fail;
            }
        }
    }

    dev->configuration = configuration;

fail:
    mtx_unlock(&dev->lock);
    return status;
}

static zx_status_t usb_dev_set_interface(usb_device_t* dev, unsigned interface,
                                         unsigned alt_setting) {
    usb_function_t* function = dev->interface_map[interface];
    if (function && function->interface.ops) {
        return usb_function_interface_set_interface(&function->interface, interface, alt_setting);
    }
    return ZX_ERR_NOT_SUPPORTED;
}

static zx_status_t usb_dev_control(void* ctx, const usb_setup_t* setup, const void* write_buffer,
                                   size_t write_size, void* read_buffer, size_t read_size,
                                   size_t* out_read_actual) {
    usb_device_t* dev = ctx;
    uint8_t request_type = setup->bmRequestType;
    uint8_t direction = request_type & USB_DIR_MASK;
    uint8_t request = setup->bRequest;
    uint16_t value = le16toh(setup->wValue);
    uint16_t index = le16toh(setup->wIndex);
    uint16_t length = le16toh(setup->wLength);

    if (direction == USB_DIR_IN && length > read_size) {
        return ZX_ERR_BUFFER_TOO_SMALL;
    } else if (direction == USB_DIR_OUT && length > write_size) {
        return ZX_ERR_BUFFER_TOO_SMALL;
    }
    if ((write_size > 0 && write_buffer == NULL) || (read_size > 0 && read_buffer == NULL)) {
        return ZX_ERR_INVALID_ARGS;
    }

    zxlogf(TRACE, "usb_dev_control type: 0x%02X req: %d value: %d index: %d length: %d\n",
            request_type, request, value, index, length);

    switch (request_type & USB_RECIP_MASK) {
    case USB_RECIP_DEVICE:
        // handle standard device requests
        if ((request_type & (USB_DIR_MASK | USB_TYPE_MASK)) == (USB_DIR_IN | USB_TYPE_STANDARD) &&
            request == USB_REQ_GET_DESCRIPTOR) {
            return usb_dev_get_descriptor(dev, request_type, value, index, read_buffer, length,
                                          out_read_actual);
        } else if (request_type == (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE) &&
                   request == USB_REQ_SET_CONFIGURATION && length == 0) {
            return usb_dev_set_configuration(dev, value);
        } else if (request_type == (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) &&
                   request == USB_REQ_GET_CONFIGURATION && length > 0) {
            *((uint8_t *)read_buffer) = dev->configuration;
            *out_read_actual = sizeof(uint8_t);
            return ZX_OK;
        }
        break;
    case USB_RECIP_INTERFACE: {
        if (request_type == (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) &&
                   request == USB_REQ_SET_INTERFACE && length == 0) {
            return usb_dev_set_interface(dev, index, value);
        } else {
            // delegate to the function driver for the interface
            usb_function_t* function = dev->interface_map[index];
            if (function && function->interface.ops) {
                return usb_function_interface_control(&function->interface, setup, write_buffer,
                                                      write_size, read_buffer, read_size,
                                                      out_read_actual);
            }
        }
        break;
    }
    case USB_RECIP_ENDPOINT: {
        // delegate to the function driver for the endpoint
        index = ep_address_to_index(index);
        if (index == 0 || index >= USB_MAX_EPS) {
            return ZX_ERR_INVALID_ARGS;
        }
        usb_function_t* function = dev->endpoint_map[index];
        if (function && function->interface.ops) {
            return usb_function_interface_control(&function->interface, setup, write_buffer,
                                                   write_size, read_buffer, read_size,
                                                   out_read_actual);
        }
        break;
    }
    case USB_RECIP_OTHER:
        // TODO(voydanoff) - how to handle this?
    default:
        break;
    }

    return ZX_ERR_NOT_SUPPORTED;
}

static void usb_dev_set_connected(void* ctx, bool connected) {
    usb_device_t* dev = ctx;
    if (dev->connected != connected) {
        if (!connected) {
            usb_function_t* function;
            list_for_every_entry(&dev->functions, function, usb_function_t, node) {
                if (function->interface.ops) {
                    usb_function_interface_set_configured(&function->interface, false,
                                                          USB_SPEED_UNDEFINED);
                }
            }
        }

        dev->connected = connected;
    }
}

static void usb_dev_set_speed(void* ctx, usb_speed_t speed) {
    usb_device_t* dev = ctx;
    dev->speed = speed;
}

usb_dci_interface_ops_t dci_ops = {
    .control = usb_dev_control,
    .set_connected = usb_dev_set_connected,
    .set_speed = usb_dev_set_speed,
};

static zx_status_t
usb_dev_set_device_desc(void* ctx, const fuchsia_hardware_usb_peripheral_DeviceDescriptor* desc,
                        fidl_txn_t* txn) {
    usb_device_t* dev = ctx;

    zx_status_t status;
    if (desc->bNumConfigurations != 1) {
        zxlogf(ERROR, "usb_device_ioctl: bNumConfigurations: %u, only 1 supported\n",
                desc->bNumConfigurations);
        status = ZX_ERR_INVALID_ARGS;
    } else {
        dev->device_desc.bLength = sizeof(usb_device_descriptor_t);
        dev->device_desc.bDescriptorType = USB_DT_DEVICE;
        dev->device_desc.bcdUSB = desc->bcdUSB;
        dev->device_desc.bDeviceClass = desc->bDeviceClass;
        dev->device_desc.bDeviceSubClass = desc->bDeviceSubClass;
        dev->device_desc.bDeviceProtocol = desc->bDeviceProtocol;
        dev->device_desc.bMaxPacketSize0 = desc->bMaxPacketSize0;
        dev->device_desc.idVendor = desc->idVendor;
        dev->device_desc.idProduct = desc->idProduct;
        dev->device_desc.bcdDevice = desc->bcdDevice;
        dev->device_desc.iManufacturer = desc->iManufacturer;
        dev->device_desc.iProduct = desc->iProduct;
        dev->device_desc.iSerialNumber = desc->iSerialNumber;
        dev->device_desc.bNumConfigurations = desc->bNumConfigurations;
        status = ZX_OK;
    }

    return fuchsia_hardware_usb_peripheral_DeviceSetDeviceDescriptor_reply(txn, status);
}

static zx_status_t usb_dev_alloc_string_desc(void* ctx, const char* name_data, size_t name_size,
                                             fidl_txn_t* txn) {
    usb_device_t* dev = ctx;

    uint8_t index = 0;
    zx_status_t status = usb_device_alloc_string_desc(dev, name_data, &index);
    return fuchsia_hardware_usb_peripheral_DeviceAllocStringDesc_reply(txn, status, index);
}

static zx_status_t usb_dev_do_add_function(usb_device_t* dev,
                                           const usb_function_descriptor_t* desc) {
    if (dev->functions_bound) {
        return ZX_ERR_BAD_STATE;
    }

    usb_function_t* function = calloc(1, sizeof(usb_function_t));
    if (!function) {
        return ZX_ERR_NO_MEMORY;
    }
    function->dci_dev = dev->dci_dev;
    function->dev = dev;
    memcpy(&function->desc, desc, sizeof(function->desc));
    list_add_tail(&dev->functions, &function->node);

    return ZX_OK;
}

static zx_status_t usb_dev_add_function(void* ctx, const usb_function_descriptor_t* desc,
                                        fidl_txn_t* txn) {
    usb_device_t* dev = ctx;

    zx_status_t status = usb_dev_do_add_function(dev, desc);
    return fuchsia_hardware_usb_peripheral_DeviceAddFunction_reply(txn, status);
}

static void usb_dev_remove_function_devices_locked(usb_device_t* dev) {
    zxlogf(TRACE, "usb_dev_remove_function_devices_locked\n");

    usb_function_t* function;
    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
        if (function->zxdev) {
            // here we remove the function from the DDK device tree,
            // but the storage for the function remains on our function list.
            device_remove(function->zxdev);
            function->zxdev = NULL;
        }
    }

    free(dev->config_desc);
    dev->config_desc = NULL;
    dev->functions_registered = false;
    dev->function_devs_added = false;
}

static zx_status_t usb_dev_add_function_devices_locked(usb_device_t* dev) {
    zxlogf(TRACE, "usb_dev_add_function_devices_locked\n");
    if (dev->function_devs_added) {
        return ZX_OK;
    }

    usb_device_descriptor_t* device_desc = &dev->device_desc;
    int index = 0;
    usb_function_t* function;
    list_for_every_entry(&dev->functions, function, usb_function_t, node) {
        char name[16];
        snprintf(name, sizeof(name), "function-%03d", index);

        usb_function_descriptor_t* desc = &function->desc;

        zx_device_prop_t props[] = {
            { BIND_PROTOCOL, 0, ZX_PROTOCOL_USB_FUNCTION },
            { BIND_USB_CLASS, 0, desc->interface_class },
            { BIND_USB_SUBCLASS, 0, desc->interface_subclass },
            { BIND_USB_PROTOCOL, 0, desc->interface_protocol },
            { BIND_USB_VID, 0, device_desc->idVendor },
            { BIND_USB_PID, 0, device_desc->idProduct },
        };

        device_add_args_t args = {
            .version = DEVICE_ADD_ARGS_VERSION,
            .name = name,
            .ctx = function,
            .ops = &function_proto,
            .proto_id = ZX_PROTOCOL_USB_FUNCTION,
            .proto_ops = &usb_function_proto,
            .props = props,
            .prop_count = countof(props),
        };

        zx_status_t status = device_add(dev->zxdev, &args, &function->zxdev);
        if (status != ZX_OK) {
            zxlogf(ERROR, "usb_dev_bind_functions add_device failed %d\n", status);
            return status;
        }

        index++;
    }

    dev->function_devs_added = true;
    return ZX_OK;
}

static zx_status_t usb_dev_state_changed_locked(usb_device_t* dev) {
    zxlogf(TRACE, "usb_dev_state_changed_locked usb_mode: %d dci_usb_mode: %d\n", dev->usb_mode,
            dev->dci_usb_mode);

    usb_mode_t new_dci_usb_mode = dev->dci_usb_mode;
    bool add_function_devs = (dev->usb_mode == USB_MODE_PERIPHERAL && dev->functions_bound);
    zx_status_t status = ZX_OK;

    if (dev->usb_mode == USB_MODE_PERIPHERAL) {
        if (dev->functions_registered) {
            // switch DCI to device mode
            new_dci_usb_mode = USB_MODE_PERIPHERAL;
        } else {
            new_dci_usb_mode = USB_MODE_NONE;
        }
    } else {
        new_dci_usb_mode = dev->usb_mode;
    }

    if (add_function_devs) {
        // publish child devices if necessary
        if (!dev->function_devs_added) {
            status = usb_dev_add_function_devices_locked(dev);
            if (status != ZX_OK) {
                return status;
            }
        }
    }

    if (dev->dci_usb_mode != new_dci_usb_mode) {
        zxlogf(TRACE, "usb_dev_state_changed_locked set DCI mode %d\n", new_dci_usb_mode);
        if (dev->has_usb_mode_switch) {
            status = usb_mode_switch_set_mode(&dev->usb_mode_switch, new_dci_usb_mode);
            if (status != ZX_OK) {
                usb_mode_switch_set_mode(&dev->usb_mode_switch, USB_MODE_NONE);
                new_dci_usb_mode = USB_MODE_NONE;
            }
        }
        dev->dci_usb_mode = new_dci_usb_mode;
    }

    if (!add_function_devs && dev->function_devs_added) {
        usb_dev_remove_function_devices_locked(dev);
    }

    return status;
}

static zx_status_t usb_dev_do_bind_functions(usb_device_t* dev) {
    mtx_lock(&dev->lock);

    if (dev->functions_bound) {
        zxlogf(ERROR, "usb_dev_bind_functions: already bound!\n");
        mtx_unlock(&dev->lock);
        return ZX_ERR_BAD_STATE;
    }

    usb_device_descriptor_t* device_desc = &dev->device_desc;
    if (device_desc->bLength == 0) {
        zxlogf(ERROR, "usb_dev_bind_functions: device descriptor not set\n");
        mtx_unlock(&dev->lock);
        return ZX_ERR_BAD_STATE;
    }
    if (list_is_empty(&dev->functions)) {
        zxlogf(ERROR, "usb_dev_bind_functions: no functions to bind\n");
        mtx_unlock(&dev->lock);
        return ZX_ERR_BAD_STATE;
    }

    zxlogf(TRACE, "usb_dev_bind_functions functions_bound = true\n");
    dev->functions_bound = true;
    zx_status_t status = usb_dev_state_changed_locked(dev);
    mtx_unlock(&dev->lock);

    return status;
}

static zx_status_t usb_dev_bind_functions(void* ctx, fidl_txn_t* txn) {
    usb_device_t* dev = ctx;

    zx_status_t status = usb_dev_do_bind_functions(dev);
    return fuchsia_hardware_usb_peripheral_DeviceBindFunctions_reply(txn, status);
}


static zx_status_t usb_dev_do_clear_functions(usb_device_t* dev) {
    mtx_lock(&dev->lock);

    usb_function_t* function;
    while ((function = list_remove_head_type(&dev->functions, usb_function_t, node)) != NULL) {
        if (function->zxdev) {
            device_remove(function->zxdev);
            // device_remove will not actually free the function, so we free it here
            free(function->descriptors);
            free(function);
        }
    }
    free(dev->config_desc);
    dev->config_desc = NULL;
    dev->functions_bound = false;
    dev->functions_registered = false;

    memset(dev->interface_map, 0, sizeof(dev->interface_map));
    memset(dev->endpoint_map, 0, sizeof(dev->endpoint_map));
    for (unsigned i = 0; i < countof(dev->strings); i++) {
        free(dev->strings[i]);
        dev->strings[i] = NULL;
    }

    zx_status_t status = usb_dev_state_changed_locked(dev);
    mtx_unlock(&dev->lock);

    return status;
}

static zx_status_t usb_dev_clear_functions(void* ctx, fidl_txn_t* txn) {
    usb_device_t* dev = ctx;

    zxlogf(TRACE, "usb_dev_clear_functions\n");

    zx_status_t status = usb_dev_do_clear_functions(dev);
    return fuchsia_hardware_usb_peripheral_DeviceClearFunctions_reply(txn, status);
}

static zx_status_t usb_dev_get_mode(void* ctx, fidl_txn_t* txn) {
    usb_device_t* dev = ctx;

    mtx_lock(&dev->lock);
    uint32_t mode = dev->usb_mode;
    mtx_unlock(&dev->lock);

    return fuchsia_hardware_usb_peripheral_DeviceGetMode_reply(txn, ZX_OK, mode);
}

static zx_status_t usb_dev_set_mode(void* ctx, uint32_t mode, fidl_txn_t* txn) {
    usb_device_t* dev = ctx;

    mtx_lock(&dev->lock);
    dev->usb_mode = mode;
    zx_status_t status = usb_dev_state_changed_locked(dev);
    mtx_unlock(&dev->lock);

    return fuchsia_hardware_usb_peripheral_DeviceSetMode_reply(txn, status);
}

static fuchsia_hardware_usb_peripheral_Device_ops_t fidl_ops = {
    .SetDeviceDescriptor = usb_dev_set_device_desc,
    .AllocStringDesc = usb_dev_alloc_string_desc,
    .AddFunction = usb_dev_add_function,
    .BindFunctions = usb_dev_bind_functions,
    .ClearFunctions = usb_dev_clear_functions,
    .GetMode = usb_dev_get_mode,
    .SetMode = usb_dev_set_mode,
};

zx_status_t usb_dev_message(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn) {
    return fuchsia_hardware_usb_peripheral_Device_dispatch(ctx, txn, msg, &fidl_ops);
}

static void usb_dev_unbind(void* ctx) {
    zxlogf(TRACE, "usb_dev_unbind\n");
    usb_device_t* dev = ctx;
    usb_dev_do_clear_functions(dev);
    device_remove(dev->zxdev);
}

static void usb_dev_release(void* ctx) {
    zxlogf(TRACE, "usb_dev_release\n");
    usb_device_t* dev = ctx;
    free(dev->config_desc);
    for (unsigned i = 0; i < countof(dev->strings); i++) {
        free(dev->strings[i]);
    }
    free(dev);
}

static zx_protocol_device_t device_proto = {
    .version = DEVICE_OPS_VERSION,
    .message = usb_dev_message,
    .unbind = usb_dev_unbind,
    .release = usb_dev_release,
};

#if defined(USB_DEVICE_VID) && defined(USB_DEVICE_PID) && defined(USB_DEVICE_FUNCTIONS)
static zx_status_t usb_dev_set_default_config(usb_device_t* dev) {
    usb_device_descriptor_t device_desc = {
        .bLength = sizeof(usb_device_descriptor_t),
        .bDescriptorType = USB_DT_DEVICE,
        .bcdUSB = htole16(0x0200),
        .bDeviceClass = 0,
        .bDeviceSubClass = 0,
        .bDeviceProtocol = 0,
        .bMaxPacketSize0 = 64,
        .idVendor = htole16(USB_DEVICE_VID),
        .idProduct = htole16(USB_DEVICE_PID),
        .bcdDevice = htole16(0x0100),
        .bNumConfigurations = 1,
    };

    zx_status_t status = ZX_OK;

#ifdef USB_DEVICE_MANUFACTURER
    status = usb_device_alloc_string_desc(dev, USB_DEVICE_MANUFACTURER, &device_desc.iManufacturer);
    if (status != ZX_OK) return status;
#endif
#ifdef USB_DEVICE_PRODUCT
    usb_device_alloc_string_desc(dev, USB_DEVICE_PRODUCT, &device_desc.iProduct);
    if (status != ZX_OK) return status;
#endif
#ifdef USB_DEVICE_SERIAL
    usb_device_alloc_string_desc(dev, USB_DEVICE_SERIAL, &device_desc.iSerialNumber);
    if (status != ZX_OK) return status;
#endif

    memcpy(&dev->device_desc, &device_desc, sizeof(dev->device_desc));

    usb_function_descriptor_t function_desc;
    if (strcasecmp(USB_DEVICE_FUNCTIONS, "cdc") == 0) {
        function_desc.interface_class = USB_CLASS_COMM;
        function_desc.interface_subclass = USB_CDC_SUBCLASS_ETHERNET;
        function_desc.interface_protocol = 0;
    } else if (strcasecmp(USB_DEVICE_FUNCTIONS, "ums") == 0) {
        function_desc.interface_class = USB_CLASS_MSC;
        function_desc.interface_subclass = USB_SUBCLASS_MSC_SCSI;
        function_desc.interface_protocol = USB_PROTOCOL_MSC_BULK_ONLY;
    } else if (strcasecmp(USB_DEVICE_FUNCTIONS, "test") == 0) {
        function_desc.interface_class = USB_CLASS_VENDOR;
        function_desc.interface_subclass = 0;
        function_desc.interface_protocol = 0;
    } else {
        zxlogf(ERROR, "usb_dev_set_default_config: unknown function %s\n", USB_DEVICE_FUNCTIONS);
        return ZX_ERR_INVALID_ARGS;
    }

    status = usb_dev_do_add_function(dev, &function_desc);
    if (status != ZX_OK) return status;

    return usb_dev_do_bind_functions(dev);
}
#endif // defined(USB_DEVICE_VID) && defined(USB_DEVICE_PID) && defined(USB_DEVICE_FUNCTIONS)

zx_status_t usb_dev_bind(void* ctx, zx_device_t* parent) {
    zxlogf(INFO, "usb_dev_bind\n");

    usb_device_t* dev = calloc(1, sizeof(usb_device_t));
    if (!dev) {
        return ZX_ERR_NO_MEMORY;
    }
    list_initialize(&dev->functions);
    mtx_init(&dev->lock, mtx_plain);
    dev->dci_dev = parent;

    if (device_get_protocol(parent, ZX_PROTOCOL_USB_DCI, &dev->usb_dci)) {
        free(dev);
        return ZX_ERR_NOT_SUPPORTED;
    }

    if (device_get_protocol(parent, ZX_PROTOCOL_USB_MODE_SWITCH, &dev->usb_mode_switch) == ZX_OK) {
        dev->has_usb_mode_switch = true;
    }

    // Starting USB mode is determined from device metadata.
    // We read initial value and store it in dev->usb_mode, but do not actually
    // enable it until after all of our functions have bound.
    size_t actual;
    zx_status_t status = device_get_metadata(parent, DEVICE_METADATA_USB_MODE,
                                             &dev->usb_mode, sizeof(dev->usb_mode), &actual);
    if (status == ZX_ERR_NOT_FOUND) {
        // Assume peripheral mode by default.
        dev->usb_mode = USB_MODE_PERIPHERAL;
    } else if (status != ZX_OK || actual != sizeof(dev->usb_mode)) {
        zxlogf(ERROR, "usb_dev_bind: DEVICE_METADATA_USB_MODE not found\n");
        free(dev);
        return status;
    }
    // Set DCI mode to USB_MODE_NONE until we are ready
    if (dev->has_usb_mode_switch) {
        usb_mode_switch_set_mode(&dev->usb_mode_switch, USB_MODE_NONE);
    }
    dev->dci_usb_mode = USB_MODE_NONE;
    dev->parent_request_size = usb_dci_get_request_size(&dev->usb_dci);

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "usb-peripheral",
        .ctx = dev,
        .ops = &device_proto,
        .proto_id = ZX_PROTOCOL_USB_PERIPHERAL,
        .flags = DEVICE_ADD_NON_BINDABLE,
    };

    status = device_add(parent, &args, &dev->zxdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "usb_device_bind add_device failed %d\n", status);
        free(dev);
        return status;
    }

    usb_dci_interface_t intf = {
        .ops = &dci_ops,
        .ctx = dev,
    };
    usb_dci_set_interface(&dev->usb_dci, &intf);

#if defined(USB_DEVICE_VID) && defined(USB_DEVICE_PID) && defined(USB_DEVICE_FUNCTIONS)
    // set compile time configuration, if we have one
    usb_dev_set_default_config(dev);
#endif

    return ZX_OK;
}

static zx_driver_ops_t usb_device_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = usb_dev_bind,
};

// clang-format off
ZIRCON_DRIVER_BEGIN(usb_device, usb_device_ops, "zircon", "0.1", 1)
    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_USB_DCI),
ZIRCON_DRIVER_END(usb_device)
