// Copyright 2018 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 "xdc.h"

#include <assert.h>
#include <fuchsia/usb/debug/c/fidl.h>
#include <stdio.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/hw/usb.h>

#include <ddk/debug.h>
#include <fbl/alloc_checker.h>
#include <xdc-server-utils/msg.h>
#include <xdc-server-utils/stream.h>

#include "trb-sizes.h"
#include "xdc-transfer.h"
#include "xhci-hw.h"
#include "xhci-util.h"

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

namespace usb_xhci {

// String descriptors use UNICODE UTF-16LE encodings.
#define XDC_MANUFACTURER u"Google Inc."
#define XDC_PRODUCT u"Fuchsia XDC Target"
#define XDC_SERIAL_NUMBER u""
#define XDC_VENDOR_ID 0x18D1
#define XDC_PRODUCT_ID 0xA0DC
#define XDC_REVISION 0x1000

// Multi-segment event rings are not currently supported.

// The maximum duration to transition from connected to configured state.
#define TRANSITION_CONFIGURED_THRESHOLD ZX_SEC(5)

#define OUT_EP_ADDR 0x01
#define IN_EP_ADDR 0x81

#define MAX_REQS 30
#define MAX_REQ_SIZE (16 * 1024)

typedef struct xdc_instance {
  zx_device_t* zxdev;
  xdc_t* parent;

  // Whether the instance has registered a stream ID.
  bool has_stream_id;
  // ID of stream that this instance is reading and writing from.
  // Only valid if has_stream_id is true.
  uint32_t stream_id;
  // Whether the host has registered a stream of the same id.
  bool connected;
  bool dead;
  xdc_packet_state_t cur_read_packet;
  // Where we've read up to, in the first request of the completed reads list.
  size_t cur_req_read_offset;
  list_node_t completed_reads;
  // Needs to be acquired before accessing the stream_id, dead or read members.
  mtx_t lock;

  // For storing this instance in the parent's instance_list.
  list_node_t node;
} xdc_instance_t;

// For tracking streams registered on the host side.
typedef struct {
  uint32_t stream_id;
  // For storing this in xdc's host_streams list.
  list_node_t node;
} xdc_host_stream_t;

zx_status_t xdc_req_list_add_head(list_node_t* list, usb_request_t* req, size_t parent_req_size) {
  if (req->alloc_size < parent_req_size + sizeof(list_node_t)) {
    return ZX_ERR_INVALID_ARGS;
  }
  xdc_req_internal_t* req_int = USB_REQ_TO_XDC_INTERNAL(req, parent_req_size);
  list_add_head(list, &req_int->node);
  return ZX_OK;
}

zx_status_t xdc_req_list_add_tail(list_node_t* list, usb_request_t* req, size_t parent_req_size) {
  if (req->alloc_size < parent_req_size + sizeof(list_node_t)) {
    return ZX_ERR_INVALID_ARGS;
  }
  xdc_req_internal_t* req_int = USB_REQ_TO_XDC_INTERNAL(req, parent_req_size);
  list_add_tail(list, &req_int->node);
  return ZX_OK;
}

usb_request_t* xdc_req_list_remove_head(list_node_t* list, size_t parent_req_size) {
  xdc_req_internal_t* req_int = list_remove_head_type(list, xdc_req_internal_t, node);
  if (req_int) {
    return XDC_INTERNAL_TO_USB_REQ(req_int, parent_req_size);
  }
  return NULL;
}

usb_request_t* xdc_req_list_remove_tail(list_node_t* list, size_t parent_req_size) {
  xdc_req_internal_t* req_int = list_remove_tail_type(list, xdc_req_internal_t, node);
  if (req_int) {
    return XDC_INTERNAL_TO_USB_REQ(req_int, parent_req_size);
  }
  return NULL;
}

static zx_status_t xdc_write(xdc_t* xdc, uint32_t stream_id, const void* buf, size_t count,
                             size_t* actual, bool is_ctrl_msg);

static void xdc_wait_bits(volatile uint32_t* ptr, uint32_t bits, uint32_t expected) {
  uint32_t value = XHCI_READ32(ptr);
  while ((value & bits) != expected) {
    usleep(1000);
    value = XHCI_READ32(ptr);
  }
}

// Populates the pointer to the debug capability in the xdc struct.
static zx_status_t xdc_get_debug_cap(xdc_t* xdc) {
  uint32_t cap_id = EXT_CAP_USB_DEBUG_CAPABILITY;
  xdc->debug_cap_regs = (xdc_debug_cap_regs_t*)xhci_get_next_ext_cap(xdc->mmio, nullptr, &cap_id);
  return xdc->debug_cap_regs ? ZX_OK : ZX_ERR_NOT_FOUND;
}

// Populates the string descriptors and info context (DbCIC) string descriptor metadata.
static void xdc_str_descs_init(xdc_t* xdc, zx_paddr_t strs_base) {
  xdc_str_descs_t* strs = xdc->str_descs;

  // String Descriptor 0 contains the supported languages as a list of numbers (LANGIDs).
  // 0x0409: English (United States)
  strs->str_0_desc.string[0] = 0x09;
  strs->str_0_desc.string[1] = 0x04;
  strs->str_0_desc.len = STR_DESC_METADATA_LEN + 2;
  strs->str_0_desc.type = USB_DT_STRING;

  memcpy(&strs->manufacturer_desc.string, XDC_MANUFACTURER, sizeof(XDC_MANUFACTURER));
  strs->manufacturer_desc.len = STR_DESC_METADATA_LEN + sizeof(XDC_MANUFACTURER);
  strs->manufacturer_desc.type = USB_DT_STRING;

  memcpy(&strs->product_desc.string, XDC_PRODUCT, sizeof(XDC_PRODUCT));
  strs->product_desc.len = STR_DESC_METADATA_LEN + sizeof(XDC_PRODUCT);
  strs->product_desc.type = USB_DT_STRING;

  memcpy(&strs->serial_num_desc.string, XDC_SERIAL_NUMBER, sizeof(XDC_SERIAL_NUMBER));
  strs->serial_num_desc.len = STR_DESC_METADATA_LEN + sizeof(XDC_SERIAL_NUMBER);
  strs->serial_num_desc.type = USB_DT_STRING;

  // Populate the addresses and lengths of the string descriptors in the info context (DbCIC).
  xdc_dbcic_t* dbcic = &xdc->context_data->dbcic;

  dbcic->str_0_desc_addr = strs_base + offsetof(xdc_str_descs_t, str_0_desc);
  dbcic->manufacturer_desc_addr = strs_base + offsetof(xdc_str_descs_t, manufacturer_desc);
  dbcic->product_desc_addr = strs_base + offsetof(xdc_str_descs_t, product_desc);
  dbcic->serial_num_desc_addr = strs_base + offsetof(xdc_str_descs_t, serial_num_desc);

  dbcic->str_0_desc_len = strs->str_0_desc.len;
  dbcic->manufacturer_desc_len = strs->manufacturer_desc.len;
  dbcic->product_desc_len = strs->product_desc.len;
  dbcic->serial_num_desc_len = strs->serial_num_desc.len;
}

static zx_status_t xdc_endpoint_ctx_init(xdc_t* xdc, uint32_t ep_idx) {
  if (ep_idx >= NUM_EPS) {
    return ZX_ERR_INVALID_ARGS;
  }
  // Initialize the endpoint.
  xdc_endpoint_t* ep = &xdc->eps[ep_idx];
  list_initialize(&ep->queued_reqs);
  list_initialize(&ep->pending_reqs);
  ep->direction = ep_idx == IN_EP_IDX ? USB_DIR_IN : USB_DIR_OUT;
  snprintf(ep->name, MAX_EP_DEBUG_NAME_LEN, ep_idx == IN_EP_IDX ? "IN" : "OUT");
  ep->state = XDC_EP_STATE_RUNNING;

  zx_status_t status =
      xhci_transfer_ring_init(&ep->transfer_ring, xdc->bti_handle, TRANSFER_RING_SIZE);
  if (status != ZX_OK) {
    return status;
  }
  zx_paddr_t tr_dequeue = ep->transfer_ring.buffers.front()->phys_list()[0];

  uint32_t max_burst =
      XHCI_GET_BITS32(&xdc->debug_cap_regs->dcctrl, DCCTRL_MAX_BURST_START, DCCTRL_MAX_BURST_BITS);
  int avg_trb_length = EP_CTX_MAX_PACKET_SIZE * (max_burst + 1);

  xhci_endpoint_context_t* epc =
      ep_idx == IN_EP_IDX ? &xdc->context_data->in_epc : &xdc->context_data->out_epc;

  XHCI_WRITE32(&epc->epc0, 0);

  XHCI_SET_BITS32(&epc->epc1, EP_CTX_EP_TYPE_START, EP_CTX_EP_TYPE_BITS,
                  ep_idx == IN_EP_IDX ? EP_CTX_EP_TYPE_BULK_IN : EP_CTX_EP_TYPE_BULK_OUT);
  XHCI_SET_BITS32(&epc->epc1, EP_CTX_MAX_BURST_SIZE_START, EP_CTX_MAX_BURST_SIZE_BITS, max_burst);
  XHCI_SET_BITS32(&epc->epc1, EP_CTX_MAX_PACKET_SIZE_START, EP_CTX_MAX_PACKET_SIZE_BITS,
                  EP_CTX_MAX_PACKET_SIZE);

  XHCI_WRITE32(&epc->epc2, ((uint32_t)tr_dequeue & EP_CTX_TR_DEQUEUE_LO_MASK) | EP_CTX_DCS);
  XHCI_WRITE32(&epc->tr_dequeue_hi, (uint32_t)(tr_dequeue >> 32));

  XHCI_SET_BITS32(&epc->epc4, EP_CTX_AVG_TRB_LENGTH_START, EP_CTX_AVG_TRB_LENGTH_BITS,
                  avg_trb_length);
  // The Endpoint Context Interval, LSA, MaxPStreams, Mult, HID, Cerr, FE and
  // Max Esit Payload fields do not apply to the DbC. See section 7.6.3.2 of XHCI Spec.
  return ZX_OK;
}

static zx_status_t xdc_context_data_init(xdc_t* xdc) {
  // Allocate a buffer to store the context data and string descriptors.
  zx_status_t status = io_buffer_init(&xdc->context_str_descs_buffer, xdc->bti_handle, PAGE_SIZE,
                                      IO_BUFFER_RW | IO_BUFFER_CONTIG | IO_BUFFER_UNCACHED);
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to alloc xdc context and strings buffer, err: %d", status);
    return status;
  }
  xdc->context_data =
      static_cast<xdc_context_data_t*>(io_buffer_virt(&xdc->context_str_descs_buffer));
  zx_paddr_t context_data_phys = io_buffer_phys(&xdc->context_str_descs_buffer);

  // The context data only takes 192 bytes, so we can store the string descriptors after it.
  xdc->str_descs = reinterpret_cast<xdc_str_descs_t*>(
      reinterpret_cast<uintptr_t>(xdc->context_data) + sizeof(xdc_context_data_t));
  zx_paddr_t str_descs_phys = context_data_phys + sizeof(xdc_context_data_t);

  // Populate the string descriptors, and string descriptor metadata in the context data.
  xdc_str_descs_init(xdc, str_descs_phys);

  // Initialize the endpoint contexts in the context data.
  for (uint32_t i = 0; i < NUM_EPS; i++) {
    status = xdc_endpoint_ctx_init(xdc, i);
    if (status != ZX_OK) {
      return status;
    }
  }
  XHCI_WRITE64(&xdc->debug_cap_regs->dccp, context_data_phys);
  return ZX_OK;
}

// Updates the event ring dequeue pointer register to the current event ring position.
static void xdc_update_erdp(xdc_t* xdc) {
  uint64_t erdp = xhci_event_ring_current_phys(&xdc->event_ring);
  XHCI_WRITE64(&xdc->debug_cap_regs->dcerdp, erdp);
}

// Sets up the event ring segment table and buffers.
static zx_status_t xdc_event_ring_init(xdc_t* xdc) {
  // Event Ring Segment Table and Event Ring Segments
  zx_status_t status = io_buffer_init(&xdc->erst_buffer, xdc->bti_handle, PAGE_SIZE,
                                      IO_BUFFER_RW | IO_BUFFER_CONTIG | IO_BUFFER_UNCACHED);
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to alloc xdc erst_buffer, err: %d", status);
    return status;
  }

  xdc->erst_array = (erst_entry_t*)io_buffer_virt(&xdc->erst_buffer);
  zx_paddr_t erst_array_phys = io_buffer_phys(&xdc->erst_buffer);

  status =
      xhci_event_ring_init(&xdc->event_ring, xdc->bti_handle, xdc->erst_array, EVENT_RING_SIZE);
  if (status != ZX_OK) {
    zxlogf(ERROR, "xhci_event_ring_init failed, err: %d", status);
    return status;
  }

  // Update the event ring dequeue pointer.
  xdc_update_erdp(xdc);

  XHCI_SET32(&xdc->debug_cap_regs->dcerstsz, ERSTSZ_MASK, ERST_ARRAY_SIZE);
  XHCI_WRITE64(&xdc->debug_cap_regs->dcerstba, erst_array_phys);

  return ZX_OK;
}

// Initializes the debug capability registers and required data structures.
// This needs to be called everytime the host controller is reset.
static zx_status_t xdc_init_debug_cap(xdc_t* xdc) {
  // Initialize the Device Descriptor Info Registers.
  XHCI_WRITE32(&xdc->debug_cap_regs->dcddi1, XDC_VENDOR_ID << DCDDI1_VENDOR_ID_START);
  XHCI_WRITE32(&xdc->debug_cap_regs->dcddi2,
               (XDC_REVISION << DCDDI2_DEVICE_REVISION_START) | XDC_PRODUCT_ID);

  zx_status_t status = xdc_event_ring_init(xdc);
  if (status != ZX_OK) {
    return status;
  }
  status = xdc_context_data_init(xdc);
  if (status != ZX_OK) {
    return status;
  }
  return ZX_OK;
}

static zx_status_t xdc_write_instance(void* ctx, const void* buf, size_t count, zx_off_t off,
                                      size_t* actual) {
  auto* inst = static_cast<xdc_instance_t*>(ctx);

  mtx_lock(&inst->lock);

  if (inst->dead) {
    mtx_unlock(&inst->lock);
    return ZX_ERR_PEER_CLOSED;
  }
  if (!inst->has_stream_id) {
    zxlogf(ERROR, "write failed, instance %p did not register for a stream id", inst);
    mtx_unlock(&inst->lock);
    return ZX_ERR_BAD_STATE;
  }
  if (!inst->connected) {
    mtx_unlock(&inst->lock);
    return ZX_ERR_SHOULD_WAIT;
  }
  uint32_t stream_id = inst->stream_id;

  mtx_unlock(&inst->lock);

  return xdc_write(inst->parent, stream_id, buf, count, actual, false /* is_ctrl_msg */);
}

static void xdc_update_instance_write_signal(xdc_instance_t* inst, bool writable) {
  mtx_lock(&inst->lock);

  if (inst->dead || !inst->has_stream_id) {
    mtx_unlock(&inst->lock);
    return;
  }

  // For an instance to be writable, we need the xdc device to be ready for writing,
  // and the corresponding stream to be registered on the host.
  if (writable && inst->connected) {
    device_state_set(inst->zxdev, DEV_STATE_WRITABLE);
  } else {
    device_state_clr(inst->zxdev, DEV_STATE_WRITABLE);
  }

  mtx_unlock(&inst->lock);
}

static xdc_host_stream_t* xdc_get_host_stream(xdc_t* xdc, uint32_t stream_id)
    __TA_REQUIRES(xdc->instance_list_lock) {
  xdc_host_stream_t* host_stream;
  list_for_every_entry (&xdc->host_streams, host_stream, xdc_host_stream_t, node) {
    if (host_stream->stream_id == stream_id) {
      return host_stream;
    }
  }
  return nullptr;
}

// Sends a message to the host to notify when a xdc device stream becomes online or offline.
// If the message cannot be currently sent, it will be queued for later.
static void xdc_notify_stream_state(xdc_t* xdc, uint32_t stream_id, bool online) {
  xdc_msg_t msg = {.opcode = XDC_NOTIFY_STREAM_STATE,
                   .notify_stream_state = {.stream_id = stream_id, .online = online}};

  size_t actual;
  zx_status_t status =
      xdc_write(xdc, XDC_MSG_STREAM, &msg, sizeof(msg), &actual, true /* is_ctrl_msg */);
  if (status == ZX_OK) {
    // The write size is much less than the max packet size, so it should complete entirely.
    ZX_DEBUG_ASSERT(actual == sizeof(xdc_msg_t));
  } else {
    // xdc_write should always queue ctrl msgs, unless some fatal error occurs e.g. OOM.
    zxlogf(ERROR, "xdc_write_internal returned err: %d, dropping ctrl msg for stream id %u", status,
           stream_id);
  }
}

// Sets the stream id for the device instance.
// Returns ZX_OK if successful, or ZX_ERR_INVALID_ARGS if the stream id is unavailable.
static zx_status_t xdc_register_stream(xdc_instance_t* inst, uint32_t stream_id) {
  xdc_t* xdc = inst->parent;

  if (stream_id == DEBUG_STREAM_ID_RESERVED) {
    return ZX_ERR_INVALID_ARGS;
  }

  mtx_lock(&xdc->instance_list_lock);

  xdc_instance_t* test_inst;
  list_for_every_entry (&xdc->instance_list, test_inst, xdc_instance_t, node) {
    mtx_lock(&test_inst->lock);
    // We can only register the stream id if no one else already has.
    if (test_inst->stream_id == stream_id) {
      zxlogf(ERROR, "stream id %u was already registered", stream_id);
      mtx_unlock(&test_inst->lock);
      mtx_unlock(&xdc->instance_list_lock);
      return ZX_ERR_INVALID_ARGS;
    }
    mtx_unlock(&test_inst->lock);
  }

  mtx_lock(&inst->lock);
  inst->stream_id = stream_id;
  inst->has_stream_id = true;
  inst->connected = xdc_get_host_stream(xdc, stream_id) != nullptr;
  mtx_unlock(&inst->lock);

  mtx_unlock(&xdc->instance_list_lock);

  // Notify the host that this stream id is available on the debug device.
  xdc_notify_stream_state(xdc, stream_id, true /* online */);

  mtx_lock(&xdc->write_lock);
  xdc_update_instance_write_signal(inst, xdc->writable);
  mtx_unlock(&xdc->write_lock);

  zxlogf(DEBUG, "registered stream id %u", stream_id);
  return ZX_OK;
}

// Attempts to requeue the request on the IN endpoint.
// If not successful, the request is returned to the free_read_reqs list.
static void xdc_queue_read_locked(xdc_t* xdc, usb_request_t* req) __TA_REQUIRES(xdc->read_lock) {
  zx_status_t status = xdc_queue_transfer(xdc, req, true /** in **/, false /* is_ctrl_msg */);
  if (status != ZX_OK) {
    zxlogf(ERROR, "xdc_read failed to re-queue request %d", status);
    status = xdc_req_list_add_tail(&xdc->free_read_reqs, req, sizeof(usb_request_t));
    ZX_DEBUG_ASSERT(status == ZX_OK);
  }
}

static void xdc_update_instance_read_signal_locked(xdc_instance_t* inst) __TA_REQUIRES(inst->lock) {
  if (list_length(&inst->completed_reads) > 0) {
    device_state_set(inst->zxdev, DEV_STATE_READABLE);
  } else {
    device_state_clr(inst->zxdev, DEV_STATE_READABLE);
  }
}

static zx_status_t xdc_read_instance(void* ctx, void* buf, size_t count, zx_off_t off,
                                     size_t* actual) {
  auto* inst = static_cast<xdc_instance_t*>(ctx);
  uint64_t usb_req_size = sizeof(usb_request_t);

  mtx_lock(&inst->lock);

  if (inst->dead) {
    mtx_unlock(&inst->lock);
    return ZX_ERR_PEER_CLOSED;
  }

  if (!inst->has_stream_id) {
    zxlogf(ERROR, "read failed, instance %p did not have a valid stream id", inst);
    mtx_unlock(&inst->lock);
    return ZX_ERR_BAD_STATE;
  }

  if (list_is_empty(&inst->completed_reads)) {
    mtx_unlock(&inst->lock);
    return ZX_ERR_SHOULD_WAIT;
  }

  list_node_t done_reqs = LIST_INITIAL_VALUE(done_reqs);

  size_t copied = 0;
  usb_request_t* req;
  // Copy up to the requested amount, or until we have no completed read buffers left.
  while (copied < count) {
    xdc_req_internal_t* req_int =
        list_peek_head_type(&inst->completed_reads, xdc_req_internal_t, node);
    if (req_int == nullptr) {
      continue;
    }
    req = XDC_INTERNAL_TO_USB_REQ(req_int, sizeof(usb_request_t));
    if (inst->cur_req_read_offset == 0) {
      bool is_new_packet;
      void* data;
      zx_status_t status = usb_request_mmap(req, &data);
      if (status != ZX_OK) {
        zxlogf(ERROR, "usb_request_mmap failed, err: %d", status);
        mtx_unlock(&inst->lock);
        return ZX_ERR_BAD_STATE;
      }

      status = xdc_update_packet_state(&inst->cur_read_packet, data, req->response.actual,
                                       &is_new_packet);
      if (status != ZX_OK) {
        mtx_unlock(&inst->lock);
        return ZX_ERR_BAD_STATE;
      }
      if (is_new_packet) {
        // Skip over the header, which contains internal metadata like stream id.
        inst->cur_req_read_offset += sizeof(xdc_packet_header_t);
      }
    }
    size_t req_bytes_left = req->response.actual - inst->cur_req_read_offset;
    size_t to_copy = MIN(count - copied, req_bytes_left);
    size_t bytes_copied = usb_request_copy_from(req, static_cast<uint8_t*>(buf) + copied, to_copy,
                                                inst->cur_req_read_offset);

    copied += bytes_copied;
    inst->cur_req_read_offset += bytes_copied;

    // Finished copying all the available bytes from this usb request buffer.
    if (inst->cur_req_read_offset >= req->response.actual) {
      list_remove_head(&inst->completed_reads);
      zx_status_t status = xdc_req_list_add_tail(&done_reqs, req, usb_req_size);
      ZX_DEBUG_ASSERT(status == ZX_OK);
      inst->cur_req_read_offset = 0;
    }
  }

  xdc_update_instance_read_signal_locked(inst);
  mtx_unlock(&inst->lock);

  xdc_t* xdc = inst->parent;
  mtx_lock(&xdc->read_lock);
  while ((req = xdc_req_list_remove_tail(&done_reqs, usb_req_size)) != nullptr) {
    xdc_queue_read_locked(xdc, req);
  }
  mtx_unlock(&xdc->read_lock);

  *actual = copied;
  return ZX_OK;
}

static zx_status_t fidl_SetStream(void* ctx, uint32_t stream_id, fidl_txn_t* txn) {
  auto* inst = static_cast<xdc_instance_t*>(ctx);
  return fuchsia_usb_debug_DeviceSetStream_reply(txn, xdc_register_stream(inst, stream_id));
}

static fuchsia_usb_debug_Device_ops_t fidl_ops = {
    .SetStream = fidl_SetStream,
};

static zx_status_t xdc_message(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn) {
  return fuchsia_usb_debug_Device_dispatch(ctx, txn, msg, &fidl_ops);
}

static zx_status_t xdc_close_instance(void* ctx, uint32_t flags) {
  auto* inst = static_cast<xdc_instance_t*>(ctx);

  list_node_t free_reqs = LIST_INITIAL_VALUE(free_reqs);

  mtx_lock(&inst->lock);
  inst->dead = true;
  list_move(&inst->completed_reads, &free_reqs);
  mtx_unlock(&inst->lock);

  mtx_lock(&inst->parent->instance_list_lock);
  list_delete(&inst->node);
  mtx_unlock(&inst->parent->instance_list_lock);

  xdc_t* xdc = inst->parent;
  // Return any unprocessed requests back to the read queue to be reused.
  mtx_lock(&xdc->read_lock);
  usb_request_t* req;
  uint64_t usb_req_size = sizeof(usb_request_t);
  while ((req = xdc_req_list_remove_tail(&free_reqs, usb_req_size)) != nullptr) {
    xdc_queue_read_locked(xdc, req);
  }
  mtx_unlock(&xdc->read_lock);

  if (inst->has_stream_id) {
    // Notify the host that this stream id is now unavailable on the debug device.
    xdc_notify_stream_state(xdc, inst->stream_id, false /* online */);
  }

  xdc->num_instances.fetch_add(-1);

  return ZX_OK;
}

static void xdc_release_instance(void* ctx) {
  auto* inst = static_cast<xdc_instance_t*>(ctx);
  free(inst);
}

static zx_protocol_device_t xdc_instance_ops = []() {
  zx_protocol_device_t device = {};
  device.version = DEVICE_OPS_VERSION;
  device.write = xdc_write_instance;
  device.read = xdc_read_instance;
  device.message = xdc_message;
  device.close = xdc_close_instance;
  device.release = xdc_release_instance;
  return device;
}();

static zx_status_t xdc_open(void* ctx, zx_device_t** dev_out, uint32_t flags) {
  auto* xdc = static_cast<xdc_t*>(ctx);

  auto* inst = static_cast<xdc_instance_t*>(calloc(1, sizeof(xdc_instance_t)));
  if (inst == nullptr) {
    return ZX_ERR_NO_MEMORY;
  }

  device_add_args_t args = {};
  args.version = DEVICE_ADD_ARGS_VERSION;
  args.name = "xdc";
  args.ctx = inst;
  args.ops = &xdc_instance_ops;
  args.proto_id = ZX_PROTOCOL_USB_DBC;
  args.flags = DEVICE_ADD_INSTANCE;

  zx_status_t status;
  status = device_add(xdc->zxdev, &args, &inst->zxdev);
  if (status != ZX_OK) {
    zxlogf(ERROR, "xdc: error creating instance %d", status);
    free(inst);
    return status;
  }

  inst->parent = xdc;
  list_initialize(&inst->completed_reads);

  mtx_lock(&xdc->instance_list_lock);
  list_add_tail(&xdc->instance_list, &inst->node);
  mtx_unlock(&xdc->instance_list_lock);

  *dev_out = inst->zxdev;

  xdc->num_instances.fetch_add(1);
  sync_completion_signal(&xdc->has_instance_completion);
  return ZX_OK;
}

static void xdc_shutdown(xdc_t* xdc) {
  zxlogf(DEBUG, "xdc_shutdown");
  uint64_t usb_req_size = sizeof(usb_request_t);

  xdc->suspended.store(true);
  // The poll thread will be waiting on this completion if no instances are open.
  sync_completion_signal(&xdc->has_instance_completion);

  int res;
  thrd_join(xdc->start_thread, &res);
  if (res != 0) {
    zxlogf(ERROR, "failed to join with xdc start_thread");
  }

  XHCI_WRITE32(&xdc->debug_cap_regs->dcctrl, 0);
  xdc_wait_bits(&xdc->debug_cap_regs->dcctrl, DCCTRL_DCR, 0);

  mtx_lock(&xdc->lock);
  xdc->configured = false;

  for (uint32_t i = 0; i < NUM_EPS; ++i) {
    xdc_endpoint_t* ep = &xdc->eps[i];
    ep->state = XDC_EP_STATE_DEAD;

    usb_request_t* req;
    xdc_req_internal_t* req_int;
    while ((req_int = list_remove_tail_type(&ep->pending_reqs, xdc_req_internal_t, node)) !=
           nullptr) {
      req = XDC_INTERNAL_TO_USB_REQ(req_int, usb_req_size);
      usb_request_complete(req, ZX_ERR_IO_NOT_PRESENT, 0, &req_int->complete_cb);
    }
    while ((req_int = list_remove_tail_type(&ep->queued_reqs, xdc_req_internal_t, node)) !=
           nullptr) {
      req = XDC_INTERNAL_TO_USB_REQ(req_int, usb_req_size);
      usb_request_complete(req, ZX_ERR_IO_NOT_PRESENT, 0, &req_int->complete_cb);
    }
  }

  mtx_unlock(&xdc->lock);

  zxlogf(DEBUG, "xdc_shutdown succeeded");
}

static void xdc_free(xdc_t* xdc) {
  zxlogf(INFO, "xdc_free");
  uint64_t usb_req_size = sizeof(usb_request_t);

  io_buffer_release(&xdc->erst_buffer);
  io_buffer_release(&xdc->context_str_descs_buffer);

  xhci_event_ring_free(&xdc->event_ring);

  for (uint32_t i = 0; i < NUM_EPS; ++i) {
    xdc_endpoint_t* ep = &xdc->eps[i];
    xhci_transfer_ring_free(&ep->transfer_ring);
  }

  usb_request_pool_release(&xdc->free_write_reqs);

  usb_request_t* req;
  while ((req = xdc_req_list_remove_tail(&xdc->free_read_reqs, usb_req_size)) != nullptr) {
    usb_request_release(req);
  }
  delete xdc;
}

static void xdc_suspend(void* ctx, uint8_t requested_state, bool enable_wake,
                        uint8_t suspend_reason) {
  zxlogf(DEBUG, "xdc_suspend %u", suspend_reason);
  auto* xdc = static_cast<xdc_t*>(ctx);

  // TODO(jocelyndang) do different things based on the flags.
  // For now we shutdown the driver in preparation for mexec.
  xdc_shutdown(xdc);

  device_suspend_reply(xdc->zxdev, ZX_OK, requested_state);
}

static void xdc_unbind(void* ctx) {
  zxlogf(INFO, "xdc_unbind");
  auto* xdc = static_cast<xdc_t*>(ctx);
  xdc_shutdown(xdc);

  mtx_lock(&xdc->instance_list_lock);
  xdc_instance_t* inst;
  list_for_every_entry (&xdc->instance_list, inst, xdc_instance_t, node) {
    mtx_lock(&inst->lock);

    inst->dead = true;
    // Signal any waiting instances to wake up, so they will close the instance.
    device_state_set(inst->zxdev, DEV_STATE_WRITABLE | DEV_STATE_READABLE);

    mtx_unlock(&inst->lock);
  }
  mtx_unlock(&xdc->instance_list_lock);

  device_unbind_reply(xdc->zxdev);
}

static void xdc_release(void* ctx) {
  zxlogf(INFO, "xdc_release");
  auto* xdc = static_cast<xdc_t*>(ctx);
  xdc_free(xdc);
}

static void xdc_update_write_signal_locked(xdc_t* xdc, bool online) __TA_REQUIRES(xdc->write_lock) {
  bool was_writable = xdc->writable;
  xdc->writable = online && xdc_has_free_trbs(xdc, false /* in */);
  if (was_writable == xdc->writable) {
    return;
  }

  mtx_lock(&xdc->instance_list_lock);
  xdc_instance_t* inst;
  list_for_every_entry (&xdc->instance_list, inst, xdc_instance_t, node) {
    xdc_update_instance_write_signal(inst, xdc->writable);
  }
  mtx_unlock(&xdc->instance_list_lock);
}

void xdc_write_complete(void* ctx, usb_request_t* req) {
  auto* xdc = static_cast<xdc_t*>(ctx);

  zx_status_t status = req->response.status;
  if (status != ZX_OK) {
    zxlogf(ERROR, "xdc_write_complete got unexpected error: %d", req->response.status);
  }

  mtx_lock(&xdc->write_lock);
  ZX_DEBUG_ASSERT(usb_request_pool_add(&xdc->free_write_reqs, req) == ZX_OK);
  xdc_update_write_signal_locked(xdc, status != ZX_ERR_IO_NOT_PRESENT /* online */);
  mtx_unlock(&xdc->write_lock);
}

static zx_status_t xdc_write(xdc_t* xdc, uint32_t stream_id, const void* buf, size_t count,
                             size_t* actual, bool is_ctrl_msg) {
  // TODO(jocelyndang): we should check for requests that are too big to fit on the transfer ring.

  zx_status_t status = ZX_OK;

  mtx_lock(&xdc->write_lock);

  // We should always queue control messages unless there is an unrecoverable error.
  if (!is_ctrl_msg && !xdc->writable) {
    // Need to wait for some requests to complete.
    mtx_unlock(&xdc->write_lock);
    return ZX_ERR_SHOULD_WAIT;
  }

  size_t header_len = sizeof(xdc_packet_header_t);
  xdc_packet_header_t header = {.stream_id = stream_id, .total_length = header_len + count};
  usb_request_t* req = usb_request_pool_get(&xdc->free_write_reqs, header.total_length);
  if (!req) {
    zx_status_t status = usb_request_alloc(&req, header.total_length, OUT_EP_ADDR,
                                           sizeof(usb_request_t) + sizeof(xdc_req_internal_t));
    if (status != ZX_OK) {
      goto out;
    }
  }

  usb_request_copy_to(req, &header, header_len, 0);
  usb_request_copy_to(req, buf, count, header_len /* offset */);
  req->header.length = header.total_length;

  status = xdc_queue_transfer(xdc, req, false /* in */, is_ctrl_msg);
  if (status != ZX_OK) {
    zxlogf(ERROR, "xdc_write failed %d", status);
    ZX_DEBUG_ASSERT(usb_request_pool_add(&xdc->free_write_reqs, req) == ZX_OK);
    goto out;
  }

  *actual = count;

out:
  xdc_update_write_signal_locked(xdc, status != ZX_ERR_IO_NOT_PRESENT /* online */);
  mtx_unlock(&xdc->write_lock);
  return status;
}

static void xdc_handle_msg(xdc_t* xdc, xdc_msg_t* msg) {
  switch (msg->opcode) {
    case XDC_NOTIFY_STREAM_STATE: {
      xdc_notify_stream_state_t* state = &msg->notify_stream_state;

      mtx_lock(&xdc->instance_list_lock);

      // Find the saved host stream if it exists.
      xdc_host_stream_t* host_stream = xdc_get_host_stream(xdc, state->stream_id);
      if (state->online == (host_stream != nullptr)) {
        zxlogf(ERROR, "cannot set host stream state for id %u as it was already %s",
               state->stream_id, state->online ? "online" : "offline");
        mtx_unlock(&xdc->instance_list_lock);
        return;
      }
      if (state->online) {
        auto* host_stream = static_cast<xdc_host_stream_t*>(malloc(sizeof(xdc_host_stream_t)));
        if (!host_stream) {
          zxlogf(ERROR, "can't create host stream, out of memory!");
          mtx_unlock(&xdc->instance_list_lock);
          return;
        }
        zxlogf(DEBUG, "setting host stream id %u as online", state->stream_id);
        host_stream->stream_id = state->stream_id;
        list_add_tail(&xdc->host_streams, &host_stream->node);
      } else {
        zxlogf(DEBUG, "setting host stream id %u as offline", state->stream_id);
        list_delete(&host_stream->node);
      }

      // Check if any instance is registered to this stream id and update its connected status.
      xdc_instance_t* test;
      xdc_instance_t* match = nullptr;
      list_for_every_entry (&xdc->instance_list, test, xdc_instance_t, node) {
        mtx_lock(&test->lock);
        if (test->has_stream_id && test->stream_id == state->stream_id) {
          zxlogf(DEBUG, "stream id %u is now %s to the host", state->stream_id,
                 state->online ? "connected" : "disconnected");
          test->connected = state->online;
          match = test;
          mtx_unlock(&test->lock);
          break;
        }
        mtx_unlock(&test->lock);
      }
      mtx_unlock(&xdc->instance_list_lock);

      if (match) {
        // Notify the instance whether they can now write.
        mtx_lock(&xdc->write_lock);
        xdc_update_instance_write_signal(match, xdc->writable);
        mtx_unlock(&xdc->write_lock);
      }
      return;
    }
    default:
      zxlogf(ERROR, "unrecognized command: %d", msg->opcode);
  }
}

void xdc_read_complete(void* ctx, usb_request_t* req) {
  auto* xdc = static_cast<xdc_t*>(ctx);

  mtx_lock(&xdc->read_lock);

  if (req->response.status == ZX_ERR_IO_NOT_PRESENT) {
    zx_status_t status = xdc_req_list_add_tail(&xdc->free_read_reqs, req, sizeof(usb_request_t));
    ZX_DEBUG_ASSERT(status == ZX_OK);
    goto out;
  }

  if (req->response.status != ZX_OK) {
    zxlogf(ERROR, "xdc_read_complete: req completion status = %d", req->response.status);
    xdc_queue_read_locked(xdc, req);
    goto out;
  }

  void* data;
  zx_status_t status;
  status = usb_request_mmap(req, &data);
  if (status != ZX_OK) {
    zxlogf(ERROR, "usb_request_mmap failed, err: %d", status);
    xdc_queue_read_locked(xdc, req);
    goto out;
  }
  bool new_header;
  status = xdc_update_packet_state(&xdc->cur_read_packet, data, req->response.actual, &new_header);
  if (status != ZX_OK) {
    xdc_queue_read_locked(xdc, req);
    goto out;
  }

  if (new_header && xdc->cur_read_packet.header.stream_id == XDC_MSG_STREAM) {
    size_t offset = sizeof(xdc_packet_header_t);
    if (req->response.actual - offset < sizeof(xdc_msg_t)) {
      zxlogf(ERROR, "malformed xdc ctrl msg, len was %lu want %lu", req->response.actual - offset,
             sizeof(xdc_msg_t));
      xdc_queue_read_locked(xdc, req);
      goto out;
    }
    xdc_msg_t msg;
    usb_request_copy_from(req, &msg, sizeof(xdc_msg_t), offset);

    // We should process the control message outside of the lock, so requeue the request now.
    xdc_queue_read_locked(xdc, req);
    mtx_unlock(&xdc->read_lock);

    xdc_handle_msg(xdc, &msg);
    return;
  }

  // Find the instance that is registered for the stream id of the message.
  mtx_lock(&xdc->instance_list_lock);

  bool found;
  found = false;
  xdc_instance_t* inst;
  list_for_every_entry (&xdc->instance_list, inst, xdc_instance_t, node) {
    mtx_lock(&inst->lock);
    if (inst->has_stream_id && !inst->dead &&
        (inst->stream_id == xdc->cur_read_packet.header.stream_id)) {
      status = xdc_req_list_add_tail(&inst->completed_reads, req, sizeof(usb_request_t));
      ZX_DEBUG_ASSERT(status == ZX_OK);
      xdc_update_instance_read_signal_locked(inst);
      found = true;
      mtx_unlock(&inst->lock);
      break;
    }
    mtx_unlock(&inst->lock);
  }

  mtx_unlock(&xdc->instance_list_lock);

  if (!found) {
    zxlogf(ERROR, "read packet for stream id %u, but it is not currently registered",
           xdc->cur_read_packet.header.stream_id);
    xdc_queue_read_locked(xdc, req);
  }

out:
  mtx_unlock(&xdc->read_lock);
}

static zx_protocol_device_t xdc_device_ops = []() {
  zx_protocol_device_t device = {};
  device.version = DEVICE_OPS_VERSION;
  device.open = xdc_open, device.suspend = xdc_suspend, device.unbind = xdc_unbind,
  device.release = xdc_release;
  return device;
}();

static void xdc_handle_port_status_change(xdc_t* xdc, xdc_poll_state_t* poll_state) {
  uint32_t dcportsc = XHCI_READ32(&xdc->debug_cap_regs->dcportsc);

  if (dcportsc & DCPORTSC_CSC) {
    poll_state->connected = dcportsc & DCPORTSC_CCS;
    if (poll_state->connected) {
      poll_state->last_conn = zx_clock_get_monotonic();
    }
    zxlogf(DEBUG, "Port: Connect Status Change, connected: %d", poll_state->connected != 0);
  }
  if (dcportsc & DCPORTSC_PRC) {
    zxlogf(DEBUG, "Port: Port Reset complete");
  }
  if (dcportsc & DCPORTSC_PLC) {
    zxlogf(DEBUG, "Port: Port Link Status Change");
  }
  if (dcportsc & DCPORTSC_CEC) {
    zxlogf(DEBUG, "Port: Port Config Error detected");
  }

  // Ack change events.
  XHCI_WRITE32(&xdc->debug_cap_regs->dcportsc, dcportsc);
}

static void xdc_handle_events(xdc_t* xdc, xdc_poll_state_t* poll_state) {
  xhci_event_ring_t* er = &xdc->event_ring;

  // process all TRBs with cycle bit matching our CCS
  while ((XHCI_READ32(&er->current->control) & TRB_C) == er->ccs) {
    uint32_t type = trb_get_type(er->current);
    switch (type) {
      case TRB_EVENT_PORT_STATUS_CHANGE:
        xdc_handle_port_status_change(xdc, poll_state);
        break;
      case TRB_EVENT_TRANSFER:
        mtx_lock(&xdc->lock);
        xdc_handle_transfer_event_locked(xdc, poll_state, er->current);
        mtx_unlock(&xdc->lock);
        break;
      default:
        zxlogf(ERROR, "xdc_handle_events: unhandled event type %d", type);
        break;
    }

    er->current++;
    if (er->current == er->end) {
      er->current = er->start;
      er->ccs ^= TRB_C;
    }
  }
  xdc_update_erdp(xdc);
}

// Returns whether we just entered the Configured state.
bool xdc_update_state(xdc_t* xdc, xdc_poll_state_t* poll_state) {
  uint32_t dcst =
      XHCI_GET_BITS32(&xdc->debug_cap_regs->dcst, DCST_ER_NOT_EMPTY_START, DCST_ER_NOT_EMPTY_BITS);
  if (dcst) {
    xdc_handle_events(xdc, poll_state);
  }

  uint32_t dcctrl = XHCI_READ32(&xdc->debug_cap_regs->dcctrl);

  if (dcctrl & DCCTRL_DRC) {
    zxlogf(DEBUG, "xdc configured exit");
    // Need to clear the bit to re-enable the DCDB.
    // TODO(jocelyndang): check if we need to update the transfer ring as per 7.6.4.4.
    XHCI_WRITE32(&xdc->debug_cap_regs->dcctrl, dcctrl);
    poll_state->configured = false;

    mtx_lock(&xdc->lock);
    xdc->configured = false;
    mtx_unlock(&xdc->lock);
  }

  bool entered_configured = false;
  // Just entered the Configured state.
  if (!poll_state->configured && (dcctrl & DCCTRL_DCR)) {
    uint32_t port =
        XHCI_GET_BITS32(&xdc->debug_cap_regs->dcst, DCST_PORT_NUM_START, DCST_PORT_NUM_BITS);
    if (port == 0) {
      zxlogf(ERROR, "xdc could not get port number");
    } else {
      entered_configured = true;
      poll_state->configured = true;

      mtx_lock(&xdc->lock);

      xdc->configured = true;
      zxlogf(INFO, "xdc configured on port: %u", port);

      // We just entered configured mode, so endpoints are ready. Queue any waiting messages.
      for (int i = 0; i < NUM_EPS; i++) {
        xdc_process_transactions_locked(xdc, &xdc->eps[i]);
      }

      mtx_unlock(&xdc->lock);
    }
  }

  // If it takes too long to enter the configured state, we should toggle the
  // DCE bit to retry the Debug Device enumeration process. See last paragraph of
  // 7.6.4.1 of XHCI spec.
  if (poll_state->connected && !poll_state->configured) {
    zx_duration_t waited_ns = zx_clock_get_monotonic() - poll_state->last_conn;

    if (waited_ns > TRANSITION_CONFIGURED_THRESHOLD) {
      zxlogf(ERROR, "xdc failed to enter configured state, toggling DCE");
      XHCI_WRITE32(&xdc->debug_cap_regs->dcctrl, 0);
      XHCI_WRITE32(&xdc->debug_cap_regs->dcctrl, DCCTRL_LSE | DCCTRL_DCE);

      // We won't get the disconnect event from disabling DCE, so update it now.
      poll_state->connected = false;
    }
  }
  return entered_configured;
}

void xdc_endpoint_set_halt_locked(xdc_t* xdc, xdc_poll_state_t* poll_state, xdc_endpoint_t* ep)
    __TA_REQUIRES(xdc->lock) {
  bool* halt_state = ep->direction == USB_DIR_OUT ? &poll_state->halt_out : &poll_state->halt_in;
  *halt_state = true;

  switch (ep->state) {
    case XDC_EP_STATE_DEAD:
      return;
    case XDC_EP_STATE_RUNNING:
      zxlogf(DEBUG, "%s ep transitioned from running to halted", ep->name);
      ep->state = XDC_EP_STATE_HALTED;
      return;
    case XDC_EP_STATE_STOPPED:
      // This shouldn't happen as we don't schedule new TRBs when stopped.
      zxlogf(ERROR, "%s ep transitioned from stopped to halted", ep->name);
      ep->state = XDC_EP_STATE_HALTED;
      return;
    case XDC_EP_STATE_HALTED:
      return;  // No change in state.
    default:
      zxlogf(ERROR, "unknown ep state: %d", ep->state);
      return;
  }
}

static void xdc_endpoint_clear_halt_locked(xdc_t* xdc, xdc_poll_state_t* poll_state,
                                           xdc_endpoint_t* ep) __TA_REQUIRES(xdc->lock) {
  bool* halt_state = ep->direction == USB_DIR_OUT ? &poll_state->halt_out : &poll_state->halt_in;
  *halt_state = false;

  switch (ep->state) {
    case XDC_EP_STATE_DEAD:
    case XDC_EP_STATE_RUNNING:
      return;  // No change in state.
    case XDC_EP_STATE_STOPPED:
      break;  // Already cleared the halt.
    case XDC_EP_STATE_HALTED:
      // The DbC has received the ClearFeature(ENDPOINT_HALT) request from the host.
      zxlogf(DEBUG, "%s ep transitioned from halted to stopped", ep->name);
      ep->state = XDC_EP_STATE_STOPPED;
      break;
    default:
      zxlogf(ERROR, "unknown ep state: %d", ep->state);
      return;
  }

  // If we get here, we are now in the STOPPED state and the halt has been cleared.
  // We should have processed the error events on the event ring once the halt flag was set,
  // but double-check this is the case.
  if (ep->got_err_event) {
    zx_status_t status = xdc_restart_transfer_ring_locked(xdc, ep);
    if (status != ZX_OK) {
      // This should never fail. If it does, disable the debug capability.
      // TODO(jocelyndang): the polling thread should re-initialize everything
      // if DCE is cleared.
      zxlogf(ERROR, "xdc_restart_transfer_ring got err %d, clearing DCE", status);
      XHCI_WRITE32(&xdc->debug_cap_regs->dcctrl, 0);
    }
    ep->got_err_event = false;
  }
}

void xdc_update_endpoint_state(xdc_t* xdc, xdc_poll_state_t* poll_state, xdc_endpoint_t* ep) {
  uint32_t dcctrl = XHCI_READ32(&xdc->debug_cap_regs->dcctrl);
  if (!(dcctrl & DCCTRL_DCR)) {
    // Halt bits are irrelevant when the debug capability isn't in Run Mode.
    return;
  }
  bool halt_state = ep->direction == USB_DIR_OUT ? poll_state->halt_out : poll_state->halt_in;

  uint32_t bit = ep->direction == USB_DIR_OUT ? DCCTRL_HOT : DCCTRL_HIT;
  if (halt_state == !!(dcctrl & bit)) {
    // Nothing has changed.
    return;
  }

  mtx_lock(&xdc->lock);
  if (dcctrl & bit) {
    xdc_endpoint_set_halt_locked(xdc, poll_state, ep);
  } else {
    xdc_endpoint_clear_halt_locked(xdc, poll_state, ep);
  }
  mtx_unlock(&xdc->lock);
}

zx_status_t xdc_poll(xdc_t* xdc) {
  xdc_poll_state_t poll_state;
  list_initialize(&poll_state.completed_reqs);
  uint64_t usb_req_size = sizeof(usb_request_t);

  for (;;) {
    zxlogf(DEBUG, "xdc_poll: waiting for a new instance");
    // Wait for at least one active instance before polling.
    sync_completion_wait(&xdc->has_instance_completion, ZX_TIME_INFINITE);
    zxlogf(DEBUG, "xdc_poll: instance completion signaled, about to enter poll loop");
    sync_completion_reset(&xdc->has_instance_completion);

    for (;;) {
      if (xdc->suspended.load()) {
        zxlogf(INFO, "xdc_poll: suspending xdc, shutting down poll thread");
        return ZX_OK;
      }
      if (xdc->num_instances.load() == 0) {
        // If all pending writes have completed, exit the poll loop.
        mtx_lock(&xdc->lock);
        if (list_is_empty(&xdc->eps[OUT_EP_IDX].pending_reqs)) {
          zxlogf(DEBUG, "xdc_poll: no active instances, exiting inner poll loop");
          mtx_unlock(&xdc->lock);
          // Wait for a new instance to be active.
          break;
        }
        mtx_unlock(&xdc->lock);
      }
      bool entered_configured = xdc_update_state(xdc, &poll_state);

      // Check if any EP has halted or recovered.
      for (int i = 0; i < NUM_EPS; i++) {
        xdc_endpoint_t* ep = &xdc->eps[i];
        xdc_update_endpoint_state(xdc, &poll_state, ep);
      }

      // If we just entered the configured state, we should schedule the read requests.
      if (entered_configured) {
        mtx_lock(&xdc->read_lock);
        usb_request_t* req;
        while ((req = xdc_req_list_remove_tail(&xdc->free_read_reqs, usb_req_size)) != nullptr) {
          xdc_queue_read_locked(xdc, req);
        }
        mtx_unlock(&xdc->read_lock);

        mtx_lock(&xdc->write_lock);
        xdc_update_write_signal_locked(xdc, true /* online */);
        mtx_unlock(&xdc->write_lock);
      }

      // Call complete callbacks out of the lock.
      // TODO(jocelyndang): might want a separate thread for this.
      xdc_req_internal_t* req_int;
      usb_request_t* req;
      while ((req_int = list_remove_head_type(&poll_state.completed_reqs, xdc_req_internal_t,
                                              node)) != nullptr) {
        req = XDC_INTERNAL_TO_USB_REQ(req_int, usb_req_size);
        usb_request_complete(req, req->response.status, req->response.actual,
                             &req_int->complete_cb);
      }
    }
  }
  return ZX_OK;
}

static int xdc_start_thread(void* arg) {
  auto* xdc = static_cast<xdc_t*>(arg);

  zxlogf(DEBUG, "about to enable XHCI DBC");
  XHCI_WRITE32(&xdc->debug_cap_regs->dcctrl, DCCTRL_LSE | DCCTRL_DCE);

  return xdc_poll(xdc);
}

// This should only be called once in xdc_bind.
static zx_status_t xdc_init_internal(xdc_t* xdc) {
  mtx_init(&xdc->lock, mtx_plain);

  list_initialize(&xdc->instance_list);
  mtx_init(&xdc->instance_list_lock, mtx_plain);

  list_initialize(&xdc->host_streams);

  sync_completion_reset(&xdc->has_instance_completion);

  uint64_t usb_req_size = sizeof(usb_request_t);
  uint64_t total_req_size = usb_req_size + sizeof(xdc_req_internal_t);
  usb_request_pool_init(&xdc->free_write_reqs, usb_req_size + offsetof(xdc_req_internal_t, node));
  mtx_init(&xdc->write_lock, mtx_plain);

  list_initialize(&xdc->free_read_reqs);
  mtx_init(&xdc->read_lock, mtx_plain);

  // Allocate the usb requests for write / read.
  for (int i = 0; i < MAX_REQS; i++) {
    usb_request_t* req;
    zx_status_t status = usb_request_alloc(&req, MAX_REQ_SIZE, OUT_EP_ADDR, total_req_size);
    if (status != ZX_OK) {
      zxlogf(ERROR, "xdc failed to alloc write usb requests, err: %d", status);
      return status;
    }
    ZX_DEBUG_ASSERT(usb_request_pool_add(&xdc->free_write_reqs, req) == ZX_OK);
  }
  for (int i = 0; i < MAX_REQS; i++) {
    usb_request_t* req;
    zx_status_t status = usb_request_alloc(&req, MAX_REQ_SIZE, IN_EP_ADDR, total_req_size);
    if (status != ZX_OK) {
      zxlogf(ERROR, "xdc failed to alloc read usb requests, err: %d", status);
      return status;
    }
    status = xdc_req_list_add_head(&xdc->free_read_reqs, req, usb_req_size);
    ZX_DEBUG_ASSERT(status == ZX_OK);
  }
  return ZX_OK;
}

zx_status_t xdc_bind(zx_device_t* parent, zx_handle_t bti_handle, void* mmio) {
  fbl::AllocChecker ac;
  auto* xdc = new (&ac) xdc_t();
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }
  xdc->bti_handle = bti_handle;
  xdc->mmio = mmio;

  zx_status_t status = xdc_init_internal(xdc);
  if (status != ZX_OK) {
    goto error_return;
  }
  status = xdc_get_debug_cap(xdc);
  if (status != ZX_OK) {
    zxlogf(ERROR, "xdc_get_debug_cap, err: %d", status);
    goto error_return;
  }
  status = xdc_init_debug_cap(xdc);
  if (status != ZX_OK) {
    zxlogf(ERROR, "xdc_init failed, err: %d", status);
    goto error_return;
  }

  device_add_args_t args;
  args = {};
  args.version = DEVICE_ADD_ARGS_VERSION;
  args.name = "xdc";
  args.ctx = xdc;
  args.ops = &xdc_device_ops;
  args.proto_id = ZX_PROTOCOL_USB_DBC;
  args.flags = DEVICE_ADD_NON_BINDABLE;

  status = device_add(parent, &args, &xdc->zxdev);
  if (status != ZX_OK) {
    goto error_return;
  }

  int ret;
  ret = thrd_create_with_name(&xdc->start_thread, xdc_start_thread, xdc, "xdc_start_thread");
  if (ret != thrd_success) {
    device_remove_deprecated(xdc->zxdev);
    return ZX_ERR_BAD_STATE;
  }
  return ZX_OK;

error_return:
  zxlogf(ERROR, "xdc_bind failed: %d", status);
  delete xdc;
  return status;
}

}  // namespace usb_xhci
