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

#include "xhci-util.h"

static void xhci_sync_command_callback(void* data, uint32_t cc, xhci_trb_t* command_trb,
                                         xhci_trb_t* event_trb) {
    xhci_sync_command_t* command = (xhci_sync_command_t*)data;
    command->status = XHCI_READ32(&event_trb->status);
    command->control = XHCI_READ32(&event_trb->control);
    completion_signal(&command->completion);
}

void xhci_sync_command_init(xhci_sync_command_t* command) {
    completion_reset(&command->completion);
    command->context.callback = xhci_sync_command_callback;
    command->context.data = command;
}

// returns condition code
int xhci_sync_command_wait(xhci_sync_command_t* command) {
    completion_wait(&command->completion, ZX_TIME_INFINITE);

    return (command->status & XHCI_MASK(EVT_TRB_CC_START, EVT_TRB_CC_BITS)) >> EVT_TRB_CC_START;
}

zx_status_t xhci_send_command(xhci_t* xhci, uint32_t cmd, uint64_t ptr, uint32_t control_bits) {
    xhci_sync_command_t command;
    int cc;

    xhci_sync_command_init(&command);
    xhci_post_command(xhci, cmd, ptr, control_bits, &command.context);

    // Wait for one second (arbitrarily chosen timeout)
    // TODO(voydanoff) consider making the timeout a parameter to this function
    zx_status_t status = completion_wait(&command.completion, ZX_SEC(1));
    if (status == ZX_OK) {
        cc = (command.status & XHCI_MASK(EVT_TRB_CC_START, EVT_TRB_CC_BITS)) >> EVT_TRB_CC_START;
         if (cc == TRB_CC_SUCCESS) {
            return ZX_OK;
        }
        dprintf(ERROR, "xhci_send_command %u failed, cc: %d\n", cmd, cc);
        return ZX_ERR_INTERNAL;
    } else if (status == ZX_ERR_TIMED_OUT) {
        completion_reset(&command.completion);

        // abort the command
        volatile uint64_t* crcr_ptr = &xhci->op_regs->crcr;
        XHCI_WRITE64(crcr_ptr, CRCR_CA);

        // wait for TRB_CC_COMMAND_ABORTED
        completion_wait(&command.completion, ZX_TIME_INFINITE);
        cc = (command.status & XHCI_MASK(EVT_TRB_CC_START, EVT_TRB_CC_BITS)) >> EVT_TRB_CC_START;
        if (cc == TRB_CC_SUCCESS) {
            // command must have completed while we were trying to abort it
            status = ZX_OK;
        }

        // ring doorbell to restart command ring
        XHCI_WRITE32(&xhci->doorbells[0], 0);
        xhci_wait_bits64(crcr_ptr, CRCR_CRR, CRCR_CRR);
    }

    return status;
}
