// 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 <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/bt/hci.h>
#include <ddk/protocol/usb.h>
#include <usb/usb.h>
#include <usb/usb-request.h>
#include <zircon/device/bt-hci.h>
#include <zircon/listnode.h>
#include <zircon/status.h>
#include <zircon/syscalls/port.h>

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>

#define EVENT_REQ_COUNT 8

// TODO(armansito): Consider increasing these.
#define ACL_READ_REQ_COUNT 8
#define ACL_WRITE_REQ_COUNT 8

// The maximum HCI ACL frame size used for data transactions
#define ACL_MAX_FRAME_SIZE 1028 // (1024 + 4 bytes for the ACL header)

#define CMD_BUF_SIZE 255 + 3   // 3 byte header + payload
#define EVENT_BUF_SIZE 255 + 2 // 2 byte header + payload

// The number of currently supported HCI channel endpoints. We currently have
// one channel for command/event flow and one for ACL data flow. The sniff channel is managed
// separately.
#define NUM_CHANNELS 2

#define NUM_WAIT_ITEMS NUM_CHANNELS + 1 // add one item for the changed event

// TODO(jamuraa): move these to hw/usb.h (or hw/bluetooth.h if that exists)
#define USB_SUBCLASS_BLUETOOTH 1
#define USB_PROTOCOL_BLUETOOTH 1

typedef struct {
    zx_device_t* zxdev;
    zx_device_t* usb_zxdev;
    usb_protocol_t usb;

    zx_handle_t cmd_channel;
    zx_handle_t acl_channel;
    zx_handle_t snoop_channel;

    // Port to queue PEER_CLOSED signals on
    zx_handle_t snoop_watch;

    // Signaled when a channel opens or closes
    zx_handle_t channels_changed_evt;

    zx_wait_item_t read_wait_items[NUM_WAIT_ITEMS];
    uint32_t read_wait_item_count;

    bool read_thread_running;

    void* intr_queue;

    // for accumulating HCI events
    uint8_t event_buffer[EVENT_BUF_SIZE];
    size_t event_buffer_offset;
    size_t event_buffer_packet_length;

    // pool of free USB requests
    list_node_t free_event_reqs;
    list_node_t free_acl_read_reqs;
    list_node_t free_acl_write_reqs;

    mtx_t mutex;
    size_t parent_req_size;
} hci_t;

static void hci_event_complete(void* ctx, usb_request_t* req);
static void hci_acl_read_complete(void* ctx, usb_request_t* req);

static void queue_acl_read_requests_locked(hci_t* hci) {
    usb_request_t* req = NULL;
    usb_request_complete_t complete = {
        .callback = hci_acl_read_complete,
        .ctx = hci,
    };
    while ((req = usb_req_list_remove_head(&hci->free_acl_read_reqs, hci->parent_req_size)) != NULL) {
        usb_request_queue(&hci->usb, req, &complete);
    }
}

static void queue_interrupt_requests_locked(hci_t* hci) {
    usb_request_t* req = NULL;
    usb_request_complete_t complete = {
        .callback = hci_event_complete,
        .ctx = hci,
    };
    while ((req = usb_req_list_remove_head(&hci->free_event_reqs, hci->parent_req_size)) != NULL) {
        usb_request_queue(&hci->usb, req, &complete);
    }
}

static void channel_cleanup_locked(hci_t* hci, zx_handle_t* channel) {
    if (*channel == ZX_HANDLE_INVALID)
        return;

    zx_handle_close(*channel);
    *channel = ZX_HANDLE_INVALID;
    zx_object_signal(hci->channels_changed_evt, 0, ZX_EVENT_SIGNALED);
}

static void snoop_channel_write_locked(hci_t* hci, uint8_t flags, uint8_t* bytes, size_t length) {
    if (hci->snoop_channel == ZX_HANDLE_INVALID)
        return;

    // We tack on a flags byte to the beginning of the payload.
    uint8_t snoop_buffer[length + 1];
    snoop_buffer[0] = flags;
    memcpy(snoop_buffer + 1, bytes, length);
    zx_status_t status = zx_channel_write(hci->snoop_channel, 0, snoop_buffer, length + 1, NULL, 0);
    if (status < 0) {
        zxlogf(ERROR, "bt-transport-usb: failed to write to snoop channel: %s\n", zx_status_get_string(status));
        channel_cleanup_locked(hci, &hci->snoop_channel);
    }
}

static void hci_event_complete(void* ctx, usb_request_t* req) {
    hci_t* hci = (hci_t*)ctx;
    zxlogf(SPEW, "bt-transport-usb: Event received\n");
    mtx_lock(&hci->mutex);
    zx_status_t status;

    // Handle the interrupt as long as either the command channel or the snoop
    // channel is open.
    if (hci->cmd_channel == ZX_HANDLE_INVALID && hci->snoop_channel == ZX_HANDLE_INVALID)
        goto out2;

    if (req->response.status == ZX_OK) {
        uint8_t* buffer;
        zx_status_t status = usb_request_mmap(req, (void*)&buffer);
        if (status != ZX_OK) {
            zxlogf(ERROR, "bt-transport-usb: usb_req_mmap failed: %s\n", zx_status_get_string(status));
            goto out2;
        }
        size_t length = req->response.actual;
        size_t packet_size = buffer[1] + 2;

        // simple case - packet fits in received data
        if (hci->event_buffer_offset == 0 && length >= 2) {
            if (packet_size == length) {
                if (hci->cmd_channel != ZX_HANDLE_INVALID) {
                    zx_status_t status = zx_channel_write(hci->cmd_channel, 0, buffer, length, NULL, 0);
                    if (status < 0) {
                        zxlogf(ERROR, "bt-transport-usb: hci_event_complete failed to write: %s\n", zx_status_get_string(status));
                    }
                }
                snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_EVT, true), buffer, length);
                goto out;
            }
        }

        // complicated case - need to accumulate into hci->event_buffer

        if (hci->event_buffer_offset + length > sizeof(hci->event_buffer)) {
            zxlogf(ERROR, "bt-transport-usb: event_buffer would overflow!\n");
            goto out2;
        }

        memcpy(&hci->event_buffer[hci->event_buffer_offset], buffer, length);
        if (hci->event_buffer_offset == 0) {
            hci->event_buffer_packet_length = packet_size;
        } else {
            packet_size = hci->event_buffer_packet_length;
        }
        hci->event_buffer_offset += length;

        // check to see if we have a full packet
        if (packet_size <= hci->event_buffer_offset) {
            zx_status_t status = zx_channel_write(hci->cmd_channel, 0, hci->event_buffer,
                                                  packet_size, NULL, 0);
            if (status < 0) {
                zxlogf(ERROR, "bt-transport-usb: failed to write: %s\n", zx_status_get_string(status));
            }

            snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_EVT, true), hci->event_buffer, packet_size);

            uint32_t remaining = hci->event_buffer_offset - packet_size;
            memmove(hci->event_buffer, hci->event_buffer + packet_size, remaining);
            hci->event_buffer_offset = 0;
            hci->event_buffer_packet_length = 0;
        }
    }

out:
    status = usb_req_list_add_head(&hci->free_event_reqs, req, hci->parent_req_size);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    queue_interrupt_requests_locked(hci);
out2:
    mtx_unlock(&hci->mutex);
}

static void hci_acl_read_complete(void* ctx, usb_request_t* req) {
    hci_t* hci = (hci_t*)ctx;
    zxlogf(SPEW, "bt-transport-usb: ACL frame received\n");
    mtx_lock(&hci->mutex);

    if (req->response.status == ZX_OK) {
        void* buffer;
        zx_status_t status = usb_request_mmap(req, &buffer);
        if (status != ZX_OK) {
            zxlogf(ERROR, "bt-transport-usb: usb_req_mmap failed: %s\n", zx_status_get_string(status));
            mtx_unlock(&hci->mutex);
            return;
        }

        if (hci->acl_channel == ZX_HANDLE_INVALID) {
            zxlogf(ERROR, "bt-transport-usb: ACL data received while channel is closed");
        } else {
            status = zx_channel_write(hci->acl_channel, 0, buffer, req->response.actual, NULL, 0);
            if (status < 0) {
                zxlogf(ERROR, "bt-transport-usb: hci_acl_read_complete failed to write: %s\n", zx_status_get_string(status));
            }
        }

        // If the snoop channel is open then try to write the packet even if acl_channel was closed.
        snoop_channel_write_locked(
            hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_ACL, true), buffer, req->response.actual);
    }

    zx_status_t status = usb_req_list_add_head(&hci->free_acl_read_reqs, req, hci->parent_req_size);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    queue_acl_read_requests_locked(hci);

    mtx_unlock(&hci->mutex);
}

static void hci_acl_write_complete(void* ctx, usb_request_t* req) {
    hci_t* hci = (hci_t*)ctx;

    // FIXME what to do with error here?
    mtx_lock(&hci->mutex);
    zx_status_t status = usb_req_list_add_tail(&hci->free_acl_write_reqs, req,
                                                hci->parent_req_size);
    ZX_DEBUG_ASSERT(status == ZX_OK);

    if (hci->snoop_channel) {
        void* buffer;
        zx_status_t status = usb_request_mmap(req, &buffer);
        if (status != ZX_OK) {
            zxlogf(ERROR, "bt-transport-usb: usb_req_mmap failed: %s\n", zx_status_get_string(status));
            mtx_unlock(&hci->mutex);
            return;
        }

        snoop_channel_write_locked(
            hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_ACL, false), buffer, req->response.actual);
    }

    mtx_unlock(&hci->mutex);
}

static void hci_build_read_wait_items_locked(hci_t* hci) {
    zx_wait_item_t* items = hci->read_wait_items;
    memset(items, 0, sizeof(hci->read_wait_items));
    uint32_t count = 0;

    if (hci->cmd_channel != ZX_HANDLE_INVALID) {
        items[count].handle = hci->cmd_channel;
        items[count].waitfor = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
        count++;
    }

    if (hci->acl_channel != ZX_HANDLE_INVALID) {
        items[count].handle = hci->acl_channel;
        items[count].waitfor = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
        count++;
    }

    items[count].handle = hci->channels_changed_evt;
    items[count].waitfor = ZX_EVENT_SIGNALED;
    count++;

    hci->read_wait_item_count = count;

    zx_object_signal(hci->channels_changed_evt, ZX_EVENT_SIGNALED, 0);
}

static void hci_build_read_wait_items(hci_t* hci) {
    mtx_lock(&hci->mutex);
    hci_build_read_wait_items_locked(hci);
    mtx_unlock(&hci->mutex);
}

// Returns false if there's an error while sending the packet to the hardware or
// if the channel peer closed its endpoint.
static void hci_handle_cmd_read_events(hci_t* hci, zx_wait_item_t* cmd_item) {
    if (cmd_item->pending & (ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED)) {
        uint8_t buf[CMD_BUF_SIZE];
        uint32_t length = sizeof(buf);
        zx_status_t status =
            zx_channel_read(cmd_item->handle, 0, buf, NULL, length, 0, &length, NULL);
        if (status < 0) {
            zxlogf(ERROR, "hci_read_thread: failed to read from command channel %s\n",
                   zx_status_get_string(status));
            goto fail;
        }

        status = usb_control_out(&hci->usb, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE,
                             0, 0, 0, ZX_TIME_INFINITE, buf, length);
        if (status < 0) {
            zxlogf(ERROR, "hci_read_thread: usb_control_out failed: %s\n",
                   zx_status_get_string(status));
            goto fail;
        }

        mtx_lock(&hci->mutex);
        snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_CMD, false), buf,
                                   length);
        mtx_unlock(&hci->mutex);
    }

    return;

fail:
    mtx_lock(&hci->mutex);
    channel_cleanup_locked(hci, &hci->cmd_channel);
    mtx_unlock(&hci->mutex);
}

static void hci_handle_acl_read_events(hci_t* hci, zx_wait_item_t* acl_item) {
    if (acl_item->pending & (ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED)) {
        mtx_lock(&hci->mutex);
        list_node_t* node = list_peek_head(&hci->free_acl_write_reqs);
        mtx_unlock(&hci->mutex);

        // We don't have enough reqs. Simply punt the channel read until later.
        if (!node)
            return;

        uint8_t buf[ACL_MAX_FRAME_SIZE];
        uint32_t length = sizeof(buf);
        zx_status_t status =
            zx_channel_read(acl_item->handle, 0, buf, NULL, length, 0, &length, NULL);
        if (status < 0) {
            zxlogf(ERROR, "hci_read_thread: failed to read from ACL channel %s\n",
                   zx_status_get_string(status));
            goto fail;
        }

        mtx_lock(&hci->mutex);
        node = list_remove_head(&hci->free_acl_write_reqs);
        mtx_unlock(&hci->mutex);

        // At this point if we don't get a free node from |free_acl_write_reqs| that means that
        // they were cleaned up in hci_release(). Just drop the packet.
        if (!node)
            return;

        usb_req_internal_t* req_int = containerof(node, usb_req_internal_t, node);
        usb_request_t* req = REQ_INTERNAL_TO_USB_REQ(req_int, hci->parent_req_size);
        usb_request_copy_to(req, buf, length, 0);
        req->header.length = length;
        usb_request_complete_t complete = {
            .callback = hci_acl_write_complete,
            .ctx = hci,
        };
        usb_request_queue(&hci->usb, req, &complete);
    }

    return;

fail:
    mtx_lock(&hci->mutex);
    channel_cleanup_locked(hci, &hci->acl_channel);
    mtx_unlock(&hci->mutex);
}

static bool hci_has_read_channels_locked(hci_t* hci) {
    // One for the signal event, any additional are read channels.
    return hci->read_wait_item_count > 1;
}

static int hci_read_thread(void* arg) {
    hci_t* hci = (hci_t*)arg;

    mtx_lock(&hci->mutex);

    if (!hci_has_read_channels_locked(hci)) {
        zxlogf(ERROR, "bt-transport-usb: no channels are open - exiting\n");
        hci->read_thread_running = false;
        mtx_unlock(&hci->mutex);
        return 0;
    }

    mtx_unlock(&hci->mutex);

    while (1) {
        zx_status_t status = zx_object_wait_many(
            hci->read_wait_items, hci->read_wait_item_count, ZX_TIME_INFINITE);
        if (status < 0) {
            zxlogf(ERROR, "bt-transport-usb: zx_object_wait_many failed (%s) - exiting\n",
                   zx_status_get_string(status));
            mtx_lock(&hci->mutex);
            channel_cleanup_locked(hci, &hci->cmd_channel);
            channel_cleanup_locked(hci, &hci->acl_channel);
            mtx_unlock(&hci->mutex);
            break;
        }

        for (unsigned i = 0; i < hci->read_wait_item_count; ++i) {
            mtx_lock(&hci->mutex);
            zx_wait_item_t item = hci->read_wait_items[i];
            mtx_unlock(&hci->mutex);

            if (item.handle == hci->cmd_channel) {
                hci_handle_cmd_read_events(hci, &item);
            } else if (item.handle == hci->acl_channel) {
                hci_handle_acl_read_events(hci, &item);
            }
        }

        // The channels might have been changed by the *_read_events, recheck the event.
        status = zx_object_wait_one(hci->channels_changed_evt, ZX_EVENT_SIGNALED, 0u, NULL);
        if (status == ZX_OK) {
            hci_build_read_wait_items(hci);
            if (!hci_has_read_channels_locked(hci)) {
                zxlogf(ERROR, "bt-transport-usb: all channels closed - exiting\n");
                break;
            }
        }
    }

    mtx_lock(&hci->mutex);
    hci->read_thread_running = false;
    mtx_unlock(&hci->mutex);
    return 0;
}

static zx_status_t hci_open_channel(hci_t* hci, zx_handle_t* in_channel, zx_handle_t in) {
    zx_status_t result = ZX_OK;
    mtx_lock(&hci->mutex);

    if (*in_channel != ZX_HANDLE_INVALID) {
        zxlogf(ERROR, "bt-transport-usb: already bound, failing\n");
        result = ZX_ERR_ALREADY_BOUND;
        goto done;
    }

    *in_channel = in;

    // Kick off the hci_read_thread if it's not already running.
    if (!hci->read_thread_running) {
        hci_build_read_wait_items_locked(hci);
        thrd_t read_thread;
        thrd_create_with_name(&read_thread, hci_read_thread, hci, "bt_usb_read_thread");
        hci->read_thread_running = true;
        thrd_detach(read_thread);
    } else {
        // Poke the changed event to get the new channel.
        zx_object_signal(hci->channels_changed_evt, 0, ZX_EVENT_SIGNALED);
    }

done:
    mtx_unlock(&hci->mutex);
    return result;
}

static void hci_unbind(void* ctx) {
    hci_t* hci = ctx;

    // Close the transport channels so that the host stack is notified of device removal.
    mtx_lock(&hci->mutex);

    channel_cleanup_locked(hci, &hci->cmd_channel);
    channel_cleanup_locked(hci, &hci->acl_channel);
    channel_cleanup_locked(hci, &hci->snoop_channel);

    mtx_unlock(&hci->mutex);

    device_remove(hci->zxdev);
}

static void hci_release(void* ctx) {
    hci_t* hci = ctx;

    mtx_lock(&hci->mutex);

    usb_request_t* req;
    while ((req = usb_req_list_remove_head(&hci->free_event_reqs, hci->parent_req_size)) != NULL) {
        usb_request_release(req);
    }
    while ((req = usb_req_list_remove_head(&hci->free_acl_read_reqs,
                                           hci->parent_req_size)) != NULL) {
        usb_request_release(req);
    }
    while ((req = usb_req_list_remove_head(&hci->free_acl_write_reqs,
                                           hci->parent_req_size)) != NULL) {
        usb_request_release(req);
    }

    mtx_unlock(&hci->mutex);

    free(hci);
}

static zx_status_t hci_open_command_channel(void* ctx, zx_handle_t in) {
    hci_t* hci = ctx;
    return hci_open_channel(hci, &hci->cmd_channel, in);
}

static zx_status_t hci_open_acl_data_channel(void* ctx, zx_handle_t in) {
    hci_t* hci = ctx;
    return hci_open_channel(hci, &hci->acl_channel, in);
}

static zx_status_t hci_open_snoop_channel(void* ctx, zx_handle_t in) {
    hci_t* hci = ctx;

    if (hci->snoop_watch == ZX_HANDLE_INVALID) {
        zx_status_t status = zx_port_create(0, &hci->snoop_watch);
        if (status != ZX_OK) {
            zxlogf(ERROR,
                   "bt-transport-usb: failed to create a port to watch snoop channel: "
                   "%s\n",
                   zx_status_get_string(status));
            return status;
        }
    }

    zx_port_packet_t packet;
    zx_status_t status = zx_port_wait(hci->snoop_watch, 0, &packet);
    if (status == ZX_ERR_TIMED_OUT) {
        zxlogf(ERROR, "bt-transport-usb: timed out: %s\n",
               zx_status_get_string(status));
    } else if (packet.signal.observed & ZX_CHANNEL_PEER_CLOSED) {
        hci->snoop_channel = ZX_HANDLE_INVALID;
    }

    zx_status_t ret = hci_open_channel(hci, &hci->snoop_channel, in);
    if (ret == ZX_OK) {
        zx_signals_t sigs = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
        zx_object_wait_async(hci->snoop_channel, hci->snoop_watch, 0, sigs,
                             ZX_WAIT_ASYNC_ONCE);
    }
    return ret;
}

static bt_hci_protocol_ops_t hci_protocol_ops = {
    .open_command_channel = hci_open_command_channel,
    .open_acl_data_channel = hci_open_acl_data_channel,
    .open_snoop_channel = hci_open_snoop_channel,
};

static zx_status_t hci_get_protocol(void* ctx, uint32_t proto_id, void* protocol) {
    hci_t* hci = ctx;
    if (proto_id != ZX_PROTOCOL_BT_HCI) {
        // Pass this on for drivers to load firmware / initialize
        return device_get_protocol(hci->usb_zxdev, proto_id, protocol);
    }

    bt_hci_protocol_t* hci_proto = protocol;

    hci_proto->ops = &hci_protocol_ops;
    hci_proto->ctx = ctx;
    return ZX_OK;
};

static zx_protocol_device_t hci_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .get_protocol = hci_get_protocol,
    .unbind = hci_unbind,
    .release = hci_release,
};

static zx_status_t hci_bind(void* ctx, zx_device_t* device) {
    zxlogf(TRACE, "hci_bind\n");
    usb_protocol_t usb;

    zx_status_t status = device_get_protocol(device, ZX_PROTOCOL_USB, &usb);
    if (status != ZX_OK) {
        zxlogf(ERROR, "bt-transport-usb: get protocol failed: %s\n", zx_status_get_string(status));
        return status;
    }

    // find our endpoints
    usb_desc_iter_t iter;
    zx_status_t result = usb_desc_iter_init(&usb, &iter);
    if (result < 0) {
        zxlogf(ERROR, "bt-transport-usb: usb iterator failed: %s\n", zx_status_get_string(status));
        return result;
    }

    usb_interface_descriptor_t* intf = usb_desc_iter_next_interface(&iter, true);
    if (!intf || intf->bNumEndpoints != 3) {
        usb_desc_iter_release(&iter);
        return ZX_ERR_NOT_SUPPORTED;
    }

    uint8_t bulk_in_addr = 0;
    uint8_t bulk_out_addr = 0;
    uint8_t intr_addr = 0;
    uint16_t intr_max_packet = 0;

    usb_endpoint_descriptor_t* endp = usb_desc_iter_next_endpoint(&iter);
    while (endp) {
        if (usb_ep_direction(endp) == USB_ENDPOINT_OUT) {
            if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
                bulk_out_addr = endp->bEndpointAddress;
            }
        } else {
            if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
                bulk_in_addr = endp->bEndpointAddress;
            } else if (usb_ep_type(endp) == USB_ENDPOINT_INTERRUPT) {
                intr_addr = endp->bEndpointAddress;
                intr_max_packet = usb_ep_max_packet(endp);
            }
        }
        endp = usb_desc_iter_next_endpoint(&iter);
    }
    usb_desc_iter_release(&iter);

    if (!bulk_in_addr || !bulk_out_addr || !intr_addr) {
        zxlogf(ERROR, "bt-transport-usb: bind could not find endpoints\n");
        return ZX_ERR_NOT_SUPPORTED;
    }

    hci_t* hci = calloc(1, sizeof(hci_t));
    if (!hci) {
        zxlogf(ERROR, "bt-transport-usb: Not enough memory for hci_t\n");
        return ZX_ERR_NO_MEMORY;
    }

    list_initialize(&hci->free_event_reqs);
    list_initialize(&hci->free_acl_read_reqs);
    list_initialize(&hci->free_acl_write_reqs);

    zx_event_create(0, &hci->channels_changed_evt);

    mtx_init(&hci->mutex, mtx_plain);

    hci->usb_zxdev = device;
    memcpy(&hci->usb, &usb, sizeof(hci->usb));

    hci->parent_req_size = usb_get_request_size(&hci->usb);
    size_t req_size = hci->parent_req_size + sizeof(usb_req_internal_t);
    for (int i = 0; i < EVENT_REQ_COUNT; i++) {
        usb_request_t* req;
        status = usb_request_alloc(&req, intr_max_packet, intr_addr, req_size);
        if (status != ZX_OK) {
            goto fail;
        }
        status = usb_req_list_add_head(&hci->free_event_reqs, req, hci->parent_req_size);
        ZX_DEBUG_ASSERT(status == ZX_OK);
    }
    for (int i = 0; i < ACL_READ_REQ_COUNT; i++) {
        usb_request_t* req;
        status = usb_request_alloc(&req, ACL_MAX_FRAME_SIZE, bulk_in_addr, req_size);
        if (status != ZX_OK) {
            goto fail;
        }
        status = usb_req_list_add_head(&hci->free_acl_read_reqs, req, hci->parent_req_size);
        ZX_DEBUG_ASSERT(status == ZX_OK);
    }
    for (int i = 0; i < ACL_WRITE_REQ_COUNT; i++) {
        usb_request_t* req;
        status = usb_request_alloc(&req, ACL_MAX_FRAME_SIZE, bulk_out_addr, req_size);
        if (status != ZX_OK) {
            goto fail;
        }
        status = usb_req_list_add_head(&hci->free_acl_write_reqs, req, hci->parent_req_size);
        ZX_DEBUG_ASSERT(status == ZX_OK);
    }

    mtx_lock(&hci->mutex);
    queue_interrupt_requests_locked(hci);
    queue_acl_read_requests_locked(hci);
    mtx_unlock(&hci->mutex);

    // Copy the PID and VID from the underlying BT so that it can be filtered on
    // for HCI drivers
    usb_device_descriptor_t dev_desc;
    usb_get_device_descriptor(&usb, &dev_desc);
    zx_device_prop_t props[] = {
      { BIND_PROTOCOL, 0, ZX_PROTOCOL_BT_TRANSPORT },
      { BIND_USB_VID, 0, dev_desc.idVendor },
      { BIND_USB_PID, 0, dev_desc.idProduct },
    };

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "bt_transport_usb",
        .ctx = hci,
        .ops = &hci_device_proto,
        .proto_id = ZX_PROTOCOL_BT_TRANSPORT,
        .props = props,
        .prop_count = countof(props),
    };

    status = device_add(device, &args, &hci->zxdev);
    if (status == ZX_OK) {
        return ZX_OK;
    }

fail:
    zxlogf(ERROR, "bt-transport-usb: bind failed: %s\n", zx_status_get_string(status));
    hci_release(hci);
    return status;
}

static zx_driver_ops_t usb_bt_hci_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = hci_bind,
};

// clang-format off
ZIRCON_DRIVER_BEGIN(bt_transport_usb, usb_bt_hci_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_USB),
    BI_ABORT_IF(NE, BIND_USB_CLASS, USB_CLASS_WIRELESS),
    BI_ABORT_IF(NE, BIND_USB_SUBCLASS, USB_SUBCLASS_BLUETOOTH),
    BI_MATCH_IF(EQ, BIND_USB_PROTOCOL, USB_PROTOCOL_BLUETOOTH),
ZIRCON_DRIVER_END(bt_transport_usb)
