// 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/debug.h>
#include <ddk/phys-iter.h>
#include <ddk/protocol/usb/hci.h>
#include <fbl/auto_lock.h>
#include <zircon/assert.h>
#include <zircon/hw/usb.h>
#include <stdio.h>
#include <string.h>
#include <threads.h>

#include "xhci-transfer.h"
#include "xhci-trb.h"
#include "xhci-util.h"

namespace usb_xhci {

// reads a range of bits from an integer
#define READ_FIELD(i, start, bits) (((i) >> (start)) & ((1 << (bits)) - 1))

// This resets the transfer ring's dequeue pointer just past the last completed transfer.
// This can only be called when the endpoint is stopped and we are locked on ep->lock.
static zx_status_t xhci_reset_dequeue_ptr_locked(xhci_t* xhci, uint32_t slot_id,
                                                 uint32_t ep_index) {
    xhci_slot_t* slot = &xhci->slots[slot_id];
    xhci_endpoint_t* ep = &slot->eps[ep_index];
    xhci_transfer_ring_t* transfer_ring = &ep->transfer_ring;

    xhci_sync_command_t command;
    xhci_sync_command_init(&command);
    uint64_t ptr = xhci_transfer_ring_current_phys(transfer_ring);
    ptr |= transfer_ring->pcs;
    // command expects device context index, so increment ep_index by 1
    uint32_t control = (slot_id << TRB_SLOT_ID_START) |
                        ((ep_index + 1) << TRB_ENDPOINT_ID_START);
    zx_status_t status = xhci_post_command(xhci, TRB_CMD_SET_TR_DEQUEUE, ptr, control,
                                           &command.context);
    if (status != ZX_OK) {
        return status;
    }
    int cc = xhci_sync_command_wait(&command);
    if (cc != TRB_CC_SUCCESS) {
        zxlogf(ERROR, "TRB_CMD_SET_TR_DEQUEUE failed cc: %d\n", cc);
        return ZX_ERR_INTERNAL;
    }
    xhci_set_dequeue_ptr(transfer_ring, transfer_ring->current_trb);

    return ZX_OK;
}

static void xhci_process_transactions_locked(xhci_t* xhci, xhci_slot_t* slot, uint8_t ep_index,
                                             list_node_t* completed_reqs);

zx_status_t xhci_reset_endpoint(xhci_t* xhci, uint32_t slot_id, uint8_t ep_address) {
    xhci_slot_t* slot = &xhci->slots[slot_id];
    uint8_t ep_index = xhci_endpoint_index(ep_address);
    xhci_endpoint_t* ep = &slot->eps[ep_index];
    usb_request_t* req;

    // Recover from Halted and Error conditions. See section 4.8.3 of the XHCI spec.

    ep->lock.Acquire();

    if (ep->state != EP_STATE_HALTED && ep->state != EP_STATE_ERROR) {
        ep->lock.Release();
        return ZX_OK;
    }

    int ep_ctx_state = xhci_get_ep_ctx_state(slot, ep);
    zxlogf(TRACE, "xhci_reset_endpoint %d %d ep_ctx_state %d\n", slot_id, ep_index, ep_ctx_state);

    if (ep_ctx_state == EP_CTX_STATE_STOPPED || ep_ctx_state == EP_CTX_STATE_RUNNING) {
        ep->state = EP_STATE_RUNNING;
        ep->lock.Release();
        return ZX_OK;
    }
    if (ep_ctx_state == EP_CTX_STATE_HALTED) {
        // reset the endpoint to move from Halted to Stopped state
        xhci_sync_command_t command;
        xhci_sync_command_init(&command);
        // command expects device context index, so increment ep_index by 1
        uint32_t control = (slot_id << TRB_SLOT_ID_START) |
                            ((ep_index + 1) << TRB_ENDPOINT_ID_START);
        zx_status_t status = xhci_post_command(xhci, TRB_CMD_RESET_ENDPOINT, 0, control,
                                               &command.context);
        if (status != ZX_OK) {
            ep->lock.Release();
            return status;
        }

        // Release the lock before waiting for the command. The command may not complete,
        // if there is another transfer event on the completer thread waiting for the lock
        // on the same endpoint.
        ep->lock.Release();
        int cc = xhci_sync_command_wait(&command);
        if (cc != TRB_CC_SUCCESS) {
            zxlogf(ERROR, "xhci_reset_endpoint: TRB_CMD_RESET_ENDPOINT failed cc: %d\n", cc);
            return ZX_ERR_INTERNAL;
        }
        ep->lock.Acquire();

        // calling USB_REQ_CLEAR_FEATURE on a stalled control endpoint will not work,
        // so we only do this for the other endpoints
        if (ep_address != 0) {
            // This should come after the successful completion of a Reset Endpoint Command.
            // See XHCI spec, section 4.6.8
            xhci_control_request(xhci, slot_id, USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT,
                                 USB_REQ_CLEAR_FEATURE, USB_ENDPOINT_HALT, ep_address, nullptr, 0,
                                 nullptr);
        }
    }

    // resetting the dequeue pointer gets us out of ERROR state, and is also necessary
    // after TRB_CMD_RESET_ENDPOINT.
    if (ep_ctx_state == EP_CTX_STATE_ERROR || ep_ctx_state == EP_CTX_STATE_HALTED) {
        // move transfer ring's dequeue pointer passed the failed transaction
        zx_status_t status = xhci_reset_dequeue_ptr_locked(xhci, slot_id, ep_index);
        if (status != ZX_OK) {
            ep->lock.Release();
            return status;
        }
    }

    // xhci_reset_dequeue_ptr_locked will skip past all pending transactions,
    // so move them all to the queued list so they will be requeued
    // Completed these with ZX_ERR_CANCELED out of the lock.
    // Remove from tail and add to head to preserve the ordering
    while (xhci_remove_from_list_tail(xhci, &ep->pending_reqs, &req)) {
        xhci_add_to_list_head(xhci, &ep->queued_reqs, req);
    }

    ep_ctx_state = xhci_get_ep_ctx_state(slot, ep);
    zx_status_t status;
    switch (ep_ctx_state) {
    case EP_CTX_STATE_DISABLED:
        ep->state = EP_STATE_DEAD;
        status = ZX_ERR_IO_NOT_PRESENT;
        break;
    case EP_CTX_STATE_RUNNING:
    case EP_CTX_STATE_STOPPED:
        ep->state = EP_STATE_RUNNING;
        status = ZX_OK;
        break;
    case EP_CTX_STATE_ERROR:
        ep->state = EP_STATE_ERROR;
        status = ZX_ERR_IO_INVALID;
        break;
    case EP_CTX_STATE_HALTED:
        ep->state = EP_STATE_HALTED;
        status = ZX_ERR_IO_REFUSED;
        break;
    default:
        ep->state = EP_STATE_HALTED;
        status = ZX_ERR_INTERNAL;
        break;
    }

    list_node_t completed_reqs = LIST_INITIAL_VALUE(completed_reqs);
    if (ep->state == EP_STATE_RUNNING) {
        // start processing transactions again
        xhci_process_transactions_locked(xhci, slot, ep_index, &completed_reqs);
    }

    ep->lock.Release();

    xhci_usb_request_internal_t* req_int = nullptr;
    // call complete callbacks out of the lock
    while ((req_int = list_remove_head_type(&completed_reqs,
                                            xhci_usb_request_internal_t, node)) != nullptr) {
        req = XHCI_INTERNAL_TO_USB_REQ(req_int);
        usb_request_complete(req, req->response.status, req->response.actual,
                             &req_int->complete_cb);
    }

    return status;
}

// locked on ep->lock
static zx_status_t xhci_start_transfer_locked(xhci_t* xhci, xhci_slot_t* slot, uint32_t ep_index,
                                              usb_request_t* req) {
    xhci_endpoint_t* ep = &slot->eps[ep_index];
    xhci_transfer_ring_t* ring = &ep->transfer_ring;
    if (ep->state != EP_STATE_RUNNING) {
        zxlogf(ERROR, "xhci_start_transfer_locked bad ep->state %d\n", ep->state);
        return ZX_ERR_BAD_STATE;
    }

    if (req->header.length > 0) {
        zx_status_t status = usb_request_physmap(req, xhci->bti_handle.get());
        if (status != ZX_OK) {
            zxlogf(ERROR, "%s: usb_request_physmap failed: %d\n", __FUNCTION__, status);
            return status;
        }
    }

    xhci_transfer_state_t* state = ep->transfer_state;
    xhci_transfer_state_init(state, req, ep->ep_type, ep->max_packet_size);

    if (req->header.length > UINT32_MAX) {
        return ZX_ERR_BUFFER_TOO_SMALL;
    }
    auto length = static_cast<uint32_t>(req->header.length);
    uint32_t interrupter_target = 0;

    usb_setup_t* setup = (req->header.ep_address == 0 ? &req->setup : nullptr);
    if (setup) {
        // Setup Stage
        xhci_trb_t* trb = ring->current_trb;
        xhci_clear_trb(trb);

        XHCI_SET_BITS32(&trb->ptr_low, SETUP_TRB_REQ_TYPE_START, SETUP_TRB_REQ_TYPE_BITS,
                        setup->bmRequestType);
        XHCI_SET_BITS32(&trb->ptr_low, SETUP_TRB_REQUEST_START, SETUP_TRB_REQUEST_BITS,
                        setup->bRequest);
        XHCI_SET_BITS32(&trb->ptr_low, SETUP_TRB_VALUE_START, SETUP_TRB_VALUE_BITS, setup->wValue);
        XHCI_SET_BITS32(&trb->ptr_high, SETUP_TRB_INDEX_START, SETUP_TRB_INDEX_BITS, setup->wIndex);
        XHCI_SET_BITS32(&trb->ptr_high, SETUP_TRB_LENGTH_START, SETUP_TRB_LENGTH_BITS, length);
        XHCI_SET_BITS32(&trb->status, XFER_TRB_XFER_LENGTH_START, XFER_TRB_XFER_LENGTH_BITS, 8);
        XHCI_SET_BITS32(&trb->status, XFER_TRB_INTR_TARGET_START, XFER_TRB_INTR_TARGET_BITS,
                        interrupter_target);

        uint32_t control_bits = (length == 0 ? XFER_TRB_TRT_NONE :
                            (state->direction == USB_DIR_IN ? XFER_TRB_TRT_IN : XFER_TRB_TRT_OUT));
        control_bits |= XFER_TRB_IDT; // immediate data flag
        trb_set_control(trb, TRB_TRANSFER_SETUP, control_bits);
        if (driver_get_log_flags() & DDK_LOG_SPEW) xhci_print_trb(ring, trb);
        xhci_increment_ring(ring);
    }

    return ZX_OK;
}

// returns ZX_OK if req has been successfully queued,
// ZX_ERR_SHOULD_WAIT if we ran out of TRBs and need to try again later,
// or other error for a hard failure.
static zx_status_t xhci_continue_transfer_locked(xhci_t* xhci, xhci_slot_t* slot,
                                                 uint32_t ep_index, usb_request_t* req) {
    xhci_endpoint_t* ep = &slot->eps[ep_index];
    xhci_transfer_ring_t* ring = &ep->transfer_ring;

    usb_header_t* header = &req->header;
    xhci_transfer_state_t* state = ep->transfer_state;
    size_t length = header->length;
    size_t free_trbs = xhci_transfer_ring_free_trbs(&ep->transfer_ring);
    uint8_t direction = state->direction;
    bool isochronous = (ep->ep_type == USB_ENDPOINT_ISOCHRONOUS);
    uint64_t frame = header->frame;

    uint32_t interrupter_target = 0;

    if (isochronous) {
        if (length == 0) return ZX_ERR_INVALID_ARGS;
        if (xhci->num_interrupts > 1) {
            interrupter_target = ISOCH_INTERRUPTER;
        }
    }

    if (frame != 0) {
        if (!isochronous) {
            zxlogf(ERROR, "frame scheduling only supported for isochronous transfers\n");
            return ZX_ERR_INVALID_ARGS;
        }
        uint64_t current_frame = xhci_get_current_frame(xhci);
        if (frame < current_frame) {
            zxlogf(ERROR, "can't schedule transfer into the past\n");
            return ZX_ERR_INVALID_ARGS;
        }
        if (frame - current_frame >= 895) {
            // See XHCI spec, section 4.11.2.5
            zxlogf(ERROR, "can't schedule transfer more than 895ms into the future\n");
            return ZX_ERR_INVALID_ARGS;
        }
    }

    // need to clean the cache for both IN and OUT transfers, invalidate only for IN
    if (direction == USB_DIR_IN) {
        usb_request_cache_flush_invalidate(req, 0, header->length);
    } else {
        usb_request_cache_flush(req, 0, header->length);
    }

    zx_status_t status = xhci_queue_data_trbs(ring, state, req, interrupter_target, isochronous);
    if (status != ZX_OK) {
        return status;
    }

    if (state->needs_status) {
        if (free_trbs == 0) {
            // will need to do this later
            return ZX_ERR_SHOULD_WAIT;
        }

        // Status Stage
        xhci_trb_t* trb = ring->current_trb;
        xhci_clear_trb(trb);
        XHCI_SET_BITS32(&trb->status, XFER_TRB_INTR_TARGET_START, XFER_TRB_INTR_TARGET_BITS,
                        interrupter_target);
        uint32_t control_bits = (direction == USB_DIR_IN && length > 0 ? XFER_TRB_DIR_OUT
                                                                       : XFER_TRB_DIR_IN);
        // generate an event for the status phase so we can catch stalls or other errors
        // before completing control transfer requests
        control_bits |= XFER_TRB_IOC;
        trb_set_control(trb, TRB_TRANSFER_STATUS, control_bits);
        if (driver_get_log_flags() & DDK_LOG_SPEW) xhci_print_trb(ring, trb);
        xhci_increment_ring(ring);
        free_trbs--;
        state->needs_status = false;
    }

    xhci_usb_request_internal_t* req_int = USB_REQ_TO_XHCI_INTERNAL(req);
    // if we get here, then we are ready to ring the doorbell
    // update dequeue_ptr to TRB following this transaction
    req_int->context = ring->current_trb;

    XHCI_WRITE32(&xhci->doorbells[header->device_id], ep_index + 1);
    // it seems we need to ring the doorbell a second time when transitioning from STOPPED
    while (xhci_get_ep_ctx_state(slot, ep) == EP_CTX_STATE_STOPPED) {
        zx_nanosleep(zx_deadline_after(ZX_MSEC(1)));
        XHCI_WRITE32(&xhci->doorbells[header->device_id], ep_index + 1);
    }

    return ZX_OK;
}

static void xhci_process_transactions_locked(xhci_t* xhci, xhci_slot_t* slot, uint8_t ep_index,
                                             list_node_t* completed_reqs) {
    xhci_endpoint_t* ep = &slot->eps[ep_index];

    // loop until we fill our transfer ring or run out of requests to process
    while (1) {
        if (xhci_transfer_ring_free_trbs(&ep->transfer_ring) == 0) {
            // no available TRBs - need to wait for some complete
            return;
        }

        while (!ep->current_req) {
            // start the next transaction in the queue
            usb_request_t* req;
            xhci_remove_from_list_head(xhci, &ep->queued_reqs, &req);
            if (!req) {
                // nothing to do
                return;
            }

            zx_status_t status = xhci_start_transfer_locked(xhci, slot, ep_index, req);
            if (status == ZX_OK) {
                xhci_add_to_list_tail(xhci, &ep->pending_reqs, req);
                ep->current_req = req;
            } else {
                req->response.status = status;
                req->response.actual = 0;
                xhci_add_to_list_tail(xhci, completed_reqs, req);
            }
        }

        if (ep->current_req) {
            usb_request_t* req = ep->current_req;
            zx_status_t status = xhci_continue_transfer_locked(xhci, slot, ep_index, req);
            if (status == ZX_ERR_SHOULD_WAIT) {
                // no available TRBs - need to wait for some complete
                return;
            } else {
                if (status != ZX_OK) {
                    req->response.status = status;
                    req->response.actual = 0;
                    xhci_delete_req_node(xhci, req);
                    xhci_add_to_list_tail(xhci, completed_reqs, req);
                }
                ep->current_req = nullptr;
            }
        }
    }
}

zx_status_t xhci_queue_transfer(xhci_t* xhci, usb_request_t* req) {
    uint32_t slot_id = req->header.device_id;
    uint8_t ep_index = xhci_endpoint_index(req->header.ep_address);
    __UNUSED usb_setup_t* setup = (ep_index == 0 ? &req->setup : nullptr);

    zxlogf(LSPEW, "xhci_queue_transfer slot_id: %d setup: %p ep_index: %d length: %lu\n",
            slot_id, setup, ep_index, req->header.length);

    int rh_index = xhci_get_root_hub_index(xhci, slot_id);
    if (rh_index >= 0) {
        return xhci_rh_usb_request_queue(xhci, req, rh_index);
    }

    if (slot_id < 1 || slot_id > xhci->max_slots) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (ep_index >= XHCI_NUM_EPS) {
        return ZX_ERR_INVALID_ARGS;
    }

    xhci_slot_t* slot = &xhci->slots[slot_id];
    xhci_endpoint_t* ep = &slot->eps[ep_index];
    if (!slot->sc) {
        // slot no longer enabled
        return ZX_ERR_IO_NOT_PRESENT;
    }

    list_node_t completed_reqs = LIST_INITIAL_VALUE(completed_reqs);

    {
        fbl::AutoLock al(&ep->lock);

        zx_status_t status;
        switch (ep->state) {
        case EP_STATE_DEAD:
            status = ZX_ERR_IO_NOT_PRESENT;
            break;
        case EP_STATE_RUNNING:
            status = ZX_OK;
            break;
        case EP_STATE_PAUSED:
            status = ZX_ERR_BAD_STATE;
            break;
        case EP_STATE_ERROR:
            status = ZX_ERR_IO_INVALID;
            break;
        case EP_STATE_HALTED:
            status = ZX_ERR_IO_REFUSED;
            break;
        case EP_STATE_DISABLED:
            status = ZX_ERR_BAD_STATE;
            break;
        default:
            status = ZX_ERR_INTERNAL;
            break;
        }

        if (status != ZX_OK) {
            return status;
        }

        xhci_add_to_list_tail(xhci, &ep->queued_reqs, req);

        xhci_process_transactions_locked(xhci, slot, ep_index, &completed_reqs);
    }

    xhci_usb_request_internal_t* req_int = nullptr;
    // call complete callbacks out of the lock
    while ((req_int = list_remove_head_type(&completed_reqs,
                                            xhci_usb_request_internal_t, node)) != nullptr) {
        req = XHCI_INTERNAL_TO_USB_REQ(req_int);
        usb_request_complete(req, req->response.status, req->response.actual,
                             &req_int->complete_cb);
    }

    return ZX_OK;
}

zx_status_t xhci_cancel_transfers(xhci_t* xhci, uint32_t slot_id, uint32_t ep_index) {
    zxlogf(TRACE, "xhci_cancel_transfers slot_id: %d ep_index: %d\n", slot_id, ep_index);

    if (slot_id < 1 || slot_id > xhci->max_slots) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (ep_index >= XHCI_NUM_EPS) {
        return ZX_ERR_INVALID_ARGS;
    }

    xhci_slot_t* slot = &xhci->slots[slot_id];
    xhci_endpoint_t* ep = &slot->eps[ep_index];
    list_node_t completed_reqs = LIST_INITIAL_VALUE(completed_reqs);
    usb_request_t* req;
    zx_status_t status = ZX_OK;

    ep->lock.Acquire();

    if (ep->state == EP_STATE_HALTED) {
      // xhci_reset_endpoint will be issued, when the transaction
      // that caused the STALL is completed. Let xhci_reset_endpoint
      // take care of resetting the endpoint to a running state.
      ep->lock.Release();
      return status;
    }
    if (!list_is_empty(&ep->pending_reqs)) {
        // stop the endpoint and remove transactions that have already been queued
        // in the transfer ring
        ep->state = EP_STATE_PAUSED;

        xhci_sync_command_t command;
        xhci_sync_command_init(&command);
        // command expects device context index, so increment ep_index by 1
        uint32_t control = (slot_id << TRB_SLOT_ID_START) |
                           ((ep_index + 1) << TRB_ENDPOINT_ID_START);
        zx_status_t status = xhci_post_command(xhci, TRB_CMD_STOP_ENDPOINT, 0, control,
                                               &command.context);
        if (status != ZX_OK) {
            ep->lock.Release();
            return status;
        }

        // We can't block on command completion while holding the lock.
        // It is safe to unlock here because no additional transactions will be
        // queued on the endpoint when ep->state is EP_STATE_PAUSED.
        ep->lock.Release();
        int cc = xhci_sync_command_wait(&command);
        if (cc != TRB_CC_SUCCESS) {
            // TRB_CC_CONTEXT_STATE_ERROR is normal here in the case of a disconnected device,
            // since by then the endpoint would already be in error state.
            zxlogf(ERROR, "xhci_cancel_transfers: TRB_CMD_STOP_ENDPOINT failed cc: %d\n", cc);
            return ZX_ERR_INTERNAL;
        }
        ep->lock.Acquire();

        // TRB_CMD_STOP_ENDPOINT may have have completed a currently executing request
        // but we may still have other pending requests. xhci_reset_dequeue_ptr_locked()
        // will set the dequeue pointer after the last completed request.
        while (xhci_remove_from_list_head(xhci, &ep->queued_reqs, &req)) {
            req->response.status = ZX_ERR_CANCELED;
            req->response.actual = 0;
            xhci_add_to_list_head(xhci, &completed_reqs, req);
        }

        status = xhci_reset_dequeue_ptr_locked(xhci, slot_id, ep_index);
        if (status == ZX_OK) {
            ep->state = EP_STATE_RUNNING;
        }
    }

    // elements of the queued_reqs list can simply be removed and completed.
    while (xhci_remove_from_list_head(xhci, &ep->queued_reqs, &req)) {
        req->response.status = ZX_ERR_CANCELED;
        req->response.actual = 0;
        xhci_add_to_list_head(xhci, &completed_reqs, req);
    }

    ep->lock.Release();

    xhci_usb_request_internal_t* req_int;
    // call complete callbacks out of the lock
    while ((req_int = list_remove_head_type(&completed_reqs,
                                            xhci_usb_request_internal_t, node)) != NULL) {
        req = XHCI_INTERNAL_TO_USB_REQ(req_int);
        usb_request_complete(req, req->response.status, req->response.actual,
                             &req_int->complete_cb);
    }

    return status;
}

static void xhci_control_complete(void* ctx, usb_request_t* req) {
    sync_completion_signal((sync_completion_t*)ctx);
}

zx_status_t xhci_control_request(xhci_t* xhci, uint32_t slot_id, uint8_t request_type,
                                 uint8_t request, uint16_t value, uint16_t index, void* data,
                                 uint16_t length, size_t* out_actual) {
    zxlogf(LTRACE, "xhci_control_request slot_id: %d type: 0x%02X req: %d value: %d index: %d "
            "length: %d\n", slot_id, request_type, request, value, index, length);

    // xhci_control_request is only used for reading first 8 bytes of the device descriptor,
    // so it makes sense to pool them.
    usb_request_t* req = usb_request_pool_get(&xhci->free_reqs, length);

    if (req == nullptr) {
        uint64_t total_req_size = sizeof(usb_request_t) + sizeof(xhci_usb_request_internal_t);
        auto status = usb_request_alloc(&req, length, 0, total_req_size);
        if (status != ZX_OK) {
            return status;
        }
    }

    usb_setup_t* setup = &req->setup;
    setup->bmRequestType = request_type;
    setup->bRequest = request;
    setup->wValue = value;
    setup->wIndex = index;
    setup->wLength = length;
    req->header.device_id = slot_id;

    bool out = !!((request_type & USB_DIR_MASK) == USB_DIR_OUT);
    if (length > 0 && out) {
        usb_request_copy_to(req, data, length, 0);
    }

    sync_completion_t completion;

    req->header.length = length;
    usb_request_complete_t complete = {
        .callback = xhci_control_complete,
        .ctx = &completion,
    };
    xhci_request_queue(xhci, req, &complete);
    auto status = sync_completion_wait(&completion, ZX_SEC(1));
    if (status == ZX_OK) {
        status = req->response.status;
    } else if (status == ZX_ERR_TIMED_OUT) {
        zxlogf(ERROR, "xhci_control_request ZX_ERR_TIMED_OUT\n");
        sync_completion_reset(&completion);
        status = xhci_cancel_transfers(xhci, slot_id, 0);
        if (status == ZX_OK) {
            sync_completion_wait(&completion, ZX_TIME_INFINITE);
            status = ZX_ERR_TIMED_OUT;
        }
    }
    zxlogf(TRACE, "xhci_control_transfer got %d\n", status);
    if (status == ZX_OK && out_actual != nullptr) {
        *out_actual = req->response.actual;

        if (length > 0 && !out) {
            usb_request_copy_from(req, data, req->response.actual, 0);
        }
    }

    if (usb_request_pool_add(&xhci->free_reqs, req) != ZX_OK) {
        zxlogf(TRACE, "xhci_control_transfer: Unable to add back request to the free pool\n");
        usb_request_release(req);
    }

    zxlogf(TRACE, "xhci_control_request returning %d\n", status);
    return status;
}

zx_status_t xhci_get_descriptor(xhci_t* xhci, uint32_t slot_id, uint8_t type, uint16_t value,
                                uint16_t index, void* data, uint16_t length, size_t* out_actual) {
    return xhci_control_request(xhci, slot_id, USB_DIR_IN | type | USB_RECIP_DEVICE,
                                USB_REQ_GET_DESCRIPTOR, value, index, data, length, out_actual);
}

void xhci_handle_transfer_event(xhci_t* xhci, xhci_trb_t* trb) {
    zxlogf(LTRACE, "xhci_handle_transfer_event: %08X %08X %08X %08X\n",
            ((uint32_t*)trb)[0], ((uint32_t*)trb)[1], ((uint32_t*)trb)[2], ((uint32_t*)trb)[3]);

    uint32_t control = XHCI_READ32(&trb->control);
    uint32_t status = XHCI_READ32(&trb->status);
    uint32_t slot_id = READ_FIELD(control, TRB_SLOT_ID_START, TRB_SLOT_ID_BITS);
    // ep_index is device context index, so decrement by 1 to get zero based index
    auto ep_index = static_cast<uint8_t>(
                            READ_FIELD(control, TRB_ENDPOINT_ID_START, TRB_ENDPOINT_ID_BITS) - 1);
    xhci_slot_t* slot = &xhci->slots[slot_id];
    xhci_endpoint_t* ep = &slot->eps[ep_index];
    xhci_transfer_ring_t* ring = &ep->transfer_ring;

    uint32_t cc = READ_FIELD(status, EVT_TRB_CC_START, EVT_TRB_CC_BITS);
    uint32_t length = READ_FIELD(status, EVT_TRB_XFER_LENGTH_START, EVT_TRB_XFER_LENGTH_BITS);
    usb_request_t* req = nullptr;

    list_node_t completed_reqs = LIST_INITIAL_VALUE(completed_reqs);
    {
        fbl::AutoLock al(&ep->lock);
        zx_status_t result;
        switch (cc) {
        case TRB_CC_SUCCESS:
        case TRB_CC_SHORT_PACKET:
            result = length;
            break;
        case TRB_CC_BABBLE_DETECTED_ERROR:
            zxlogf(TRACE, "xhci_handle_transfer_event: TRB_CC_BABBLE_DETECTED_ERROR\n");
            result = ZX_ERR_IO_OVERRUN;
            break;
        case TRB_CC_TRB_ERROR:
            zxlogf(TRACE, "xhci_handle_transfer_event: TRB_CC_TRB_ERROR\n");
            int ep_ctx_state;
            ep_ctx_state = xhci_get_ep_ctx_state(slot, ep);
            /*
             * For usb-c ethernet adapters on Intel xhci controller, we receive this error
             * when a packet fails with NRDY token on the bus.see NET:97 for more details.
             * Slow down the requests in the client when this error is received.
             */
            if (ep_ctx_state == EP_CTX_STATE_ERROR) {
                result = ZX_ERR_IO_INVALID;
            } else {
                result = ZX_ERR_IO;
            }
            break;
        case TRB_CC_USB_TRANSACTION_ERROR:
        case TRB_CC_STALL_ERROR: {
            int ep_ctx_state = xhci_get_ep_ctx_state(slot, ep);
            zxlogf(TRACE, "xhci_handle_transfer_event: cc %d ep_ctx_state %d\n", cc, ep_ctx_state);
            if (ep_ctx_state == EP_CTX_STATE_HALTED) {
                result = ZX_ERR_IO_REFUSED;
            } else {
                result = ZX_ERR_IO;
            }
            break;
        }
        case TRB_CC_RING_UNDERRUN:
            // non-fatal error that happens when no transfers are available for isochronous
            // endpoint
            zxlogf(TRACE, "xhci_handle_transfer_event: TRB_CC_RING_UNDERRUN\n");
            return;
        case TRB_CC_RING_OVERRUN:
            // non-fatal error that happens when no transfers are available for isochronous
            // endpoint
            zxlogf(TRACE, "xhci_handle_transfer_event: TRB_CC_RING_OVERRUN\n");
            return;
        case TRB_CC_MISSED_SERVICE_ERROR:
            zxlogf(TRACE, "xhci_handle_transfer_event: TRB_CC_MISSED_SERVICE_ERROR\n");
            result = ZX_ERR_IO_MISSED_DEADLINE;
            break;
        case TRB_CC_STOPPED:
        case TRB_CC_STOPPED_LENGTH_INVALID:
        case TRB_CC_STOPPED_SHORT_PACKET:
        case TRB_CC_ENDPOINT_NOT_ENABLED_ERROR:
            switch (ep->state) {
            case EP_STATE_PAUSED:
                result = ZX_ERR_CANCELED;
                break;
            case EP_STATE_DISABLED:
                result = ZX_ERR_BAD_STATE;
                break;
            case EP_STATE_DEAD:
                result = ZX_ERR_IO_NOT_PRESENT;
                break;
            default:
                zxlogf(ERROR, "xhci_handle_transfer_event: bad state for stopped req: %d\n",
                       ep->state);
                result = ZX_ERR_INTERNAL;
            }
            break;
        default: {
            int ep_ctx_state = xhci_get_ep_ctx_state(slot, ep);
            zxlogf(ERROR,
                   "xhci_handle_transfer_event: unhandled transfer event condition"
                   " code %d  ep_ctx_state %d:  %08X %08X %08X %08X\n",
                   cc, ep_ctx_state, ((uint32_t*)trb)[0], ((uint32_t*)trb)[1], ((uint32_t*)trb)[2],
                   ((uint32_t*)trb)[3]);
            if (ep_ctx_state == EP_CTX_STATE_HALTED) {
                result = ZX_ERR_IO_REFUSED;
            } else if (ep_ctx_state == EP_CTX_STATE_ERROR) {
                result = ZX_ERR_IO_INVALID;
            } else {
                result = ZX_ERR_IO;
            }
            break;
        }
        }

        bool req_status_set = false;

        if (trb->ptr && !list_is_empty(&ep->pending_reqs) && ep->state != EP_STATE_DISABLED &&
            ep->state != EP_STATE_DEAD) {
            if (control & EVT_TRB_ED) {
                req = reinterpret_cast<usb_request_t*>(trb->ptr);
                if (ep_index == 0) {
                    // For control requests we are expecting a second transfer event to signal the
                    // end of the status phase. So here we record the status and actual for the
                    // data phase but wait for the status phase to complete before completing the
                    // request.
                    slot->current_ctrl_req = req;
                    if (result < 0) {
                        req->response.status = result;
                        req->response.actual = 0;
                    } else {
                        req->response.status = 0;
                        req->response.actual = result;
                    }
                    return;
                }
            } else {
                trb = xhci_read_trb_ptr(ring, trb);
                if (trb_get_type(trb) == TRB_TRANSFER_STATUS && slot->current_ctrl_req) {
                    // complete current control request
                    req = slot->current_ctrl_req;
                    slot->current_ctrl_req = nullptr;
                    if (result < 0) {
                        // sometimes we receive stall errors in the status phase so update
                        // request status if necessary
                        req->response.status = result;
                        req->response.actual = 0;
                    }
                    req_status_set = true;
                } else {
                    for (uint i = 0; i < TRANSFER_RING_SIZE && trb; i++) {
                        if (trb_get_type(trb) == TRB_TRANSFER_EVENT_DATA) {
                            req = reinterpret_cast<usb_request_t*>(trb->ptr);
                            break;
                        }
                        trb = xhci_get_next_trb(ring, trb);
                    }
                }
            }
        }

        int ep_ctx_state = xhci_get_ep_ctx_state(slot, ep);
        if (ep_ctx_state != EP_CTX_STATE_RUNNING) {
            zxlogf(TRACE, "xhci_handle_transfer_event: ep ep_ctx_state %d cc %d\n", ep_ctx_state,
                   cc);
        }

        if (!req) {
            // no req expected for this condition code
            if (cc != TRB_CC_STOPPED_LENGTH_INVALID) {
                zxlogf(TRACE, "xhci_handle_transfer_event: unable to find request to complete!\n");
            }
            return;
        }

        // When transaction errors occur, we sometimes receive multiple events for the same
        // transfer. Here we check to make sure that this event doesn't correspond to a transfer
        // that has already been completed. In the typical case, the context will be found at the
        // head of pending_reqs.
        bool found_req = false;
        usb_request_t* test;
        xhci_usb_request_internal_t* req_int = nullptr;
        list_for_every_entry(&ep->pending_reqs, req_int, xhci_usb_request_internal_t, node) {
            test = XHCI_INTERNAL_TO_USB_REQ(req_int);
            if (test == req) {
                found_req = true;
                break;
            }
        }
        if (!found_req) {
            zxlogf(TRACE, "xhci_handle_transfer_event: ignoring transfer event for completed "
                          "transfer\n");
            return;
        }

        // update dequeue_ptr to TRB following this transaction
        xhci_set_dequeue_ptr(ring, req_int->context);

        // remove request from pending_reqs
        xhci_delete_req_node(xhci, req);

        if (!req_status_set) {
            if (result < 0) {
                req->response.status = result;
                req->response.actual = 0;
            } else {
                req->response.status = 0;
                req->response.actual = result;
            }
        }

        xhci_add_to_list_head(xhci, &completed_reqs, req);

        if (result == ZX_ERR_IO_REFUSED && ep->state != EP_STATE_DEAD) {
            ep->state = EP_STATE_HALTED;
        } else if (result == ZX_ERR_IO_INVALID && ep->state != EP_STATE_DEAD) {
            ep->state = EP_STATE_ERROR;
        } else if (ep->state == EP_STATE_RUNNING) {
            xhci_process_transactions_locked(xhci, slot, ep_index, &completed_reqs);
        }
    }

    // call complete callbacks out of the lock
    xhci_usb_request_internal_t* req_int;
    while ((req_int = list_remove_head_type(&completed_reqs,
                                             xhci_usb_request_internal_t, node)) != NULL) {
        req = XHCI_INTERNAL_TO_USB_REQ(req_int);
        usb_request_complete(req, req->response.status, req->response.actual,
                             &req_int->complete_cb);
    }
}

} // namespace usb_xhci
