/*
 * USB xHCI controller emulation
 *
 * Copyright (c) 2011 Securiforest
 * Date: 2011-05-11 ;  Author: Hector Martin <hector@marcansoft.com>
 * Based on usb-ohci.c, emulates Renesas NEC USB 3.0
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
#include "hw.h"
#include "qemu-timer.h"
#include "usb.h"
#include "pci.h"
#include "qdev-addr.h"
#include "msi.h"

//#define DEBUG_XHCI
//#define DEBUG_DATA

#ifdef DEBUG_XHCI
#define DPRINTF(...) fprintf(stderr, __VA_ARGS__)
#else
#define DPRINTF(...) do {} while (0)
#endif
#define FIXME() do { fprintf(stderr, "FIXME %s:%d\n", \
                             __func__, __LINE__); abort(); } while (0)

#define MAXSLOTS 8
#define MAXINTRS 1

#define USB2_PORTS 4
#define USB3_PORTS 4

#define MAXPORTS (USB2_PORTS+USB3_PORTS)

#define TD_QUEUE 24
#define BG_XFERS 8
#define BG_PKTS 8

/* Very pessimistic, let's hope it's enough for all cases */
#define EV_QUEUE (((3*TD_QUEUE)+16)*MAXSLOTS)
/* Do not deliver ER Full events. NEC's driver does some things not bound
 * to the specs when it gets them */
#define ER_FULL_HACK

#define LEN_CAP         0x40
#define OFF_OPER        LEN_CAP
#define LEN_OPER        (0x400 + 0x10 * MAXPORTS)
#define OFF_RUNTIME     ((OFF_OPER + LEN_OPER + 0x20) & ~0x1f)
#define LEN_RUNTIME     (0x20 + MAXINTRS * 0x20)
#define OFF_DOORBELL    (OFF_RUNTIME + LEN_RUNTIME)
#define LEN_DOORBELL    ((MAXSLOTS + 1) * 0x20)

/* must be power of 2 */
#define LEN_REGS        0x2000

#if (OFF_DOORBELL + LEN_DOORBELL) > LEN_REGS
# error Increase LEN_REGS
#endif

#if MAXINTRS > 1
# error TODO: only one interrupter supported
#endif

/* bit definitions */
#define USBCMD_RS       (1<<0)
#define USBCMD_HCRST    (1<<1)
#define USBCMD_INTE     (1<<2)
#define USBCMD_HSEE     (1<<3)
#define USBCMD_LHCRST   (1<<7)
#define USBCMD_CSS      (1<<8)
#define USBCMD_CRS      (1<<9)
#define USBCMD_EWE      (1<<10)
#define USBCMD_EU3S     (1<<11)

#define USBSTS_HCH      (1<<0)
#define USBSTS_HSE      (1<<2)
#define USBSTS_EINT     (1<<3)
#define USBSTS_PCD      (1<<4)
#define USBSTS_SSS      (1<<8)
#define USBSTS_RSS      (1<<9)
#define USBSTS_SRE      (1<<10)
#define USBSTS_CNR      (1<<11)
#define USBSTS_HCE      (1<<12)


#define PORTSC_CCS          (1<<0)
#define PORTSC_PED          (1<<1)
#define PORTSC_OCA          (1<<3)
#define PORTSC_PR           (1<<4)
#define PORTSC_PLS_SHIFT        5
#define PORTSC_PLS_MASK     0xf
#define PORTSC_PP           (1<<9)
#define PORTSC_SPEED_SHIFT      10
#define PORTSC_SPEED_MASK   0xf
#define PORTSC_SPEED_FULL   (1<<10)
#define PORTSC_SPEED_LOW    (2<<10)
#define PORTSC_SPEED_HIGH   (3<<10)
#define PORTSC_SPEED_SUPER  (4<<10)
#define PORTSC_PIC_SHIFT        14
#define PORTSC_PIC_MASK     0x3
#define PORTSC_LWS          (1<<16)
#define PORTSC_CSC          (1<<17)
#define PORTSC_PEC          (1<<18)
#define PORTSC_WRC          (1<<19)
#define PORTSC_OCC          (1<<20)
#define PORTSC_PRC          (1<<21)
#define PORTSC_PLC          (1<<22)
#define PORTSC_CEC          (1<<23)
#define PORTSC_CAS          (1<<24)
#define PORTSC_WCE          (1<<25)
#define PORTSC_WDE          (1<<26)
#define PORTSC_WOE          (1<<27)
#define PORTSC_DR           (1<<30)
#define PORTSC_WPR          (1<<31)

#define CRCR_RCS        (1<<0)
#define CRCR_CS         (1<<1)
#define CRCR_CA         (1<<2)
#define CRCR_CRR        (1<<3)

#define IMAN_IP         (1<<0)
#define IMAN_IE         (1<<1)

#define ERDP_EHB        (1<<3)

#define TRB_SIZE 16
typedef struct XHCITRB {
    uint64_t parameter;
    uint32_t status;
    uint32_t control;
    target_phys_addr_t addr;
    bool ccs;
} XHCITRB;


typedef enum TRBType {
    TRB_RESERVED = 0,
    TR_NORMAL,
    TR_SETUP,
    TR_DATA,
    TR_STATUS,
    TR_ISOCH,
    TR_LINK,
    TR_EVDATA,
    TR_NOOP,
    CR_ENABLE_SLOT,
    CR_DISABLE_SLOT,
    CR_ADDRESS_DEVICE,
    CR_CONFIGURE_ENDPOINT,
    CR_EVALUATE_CONTEXT,
    CR_RESET_ENDPOINT,
    CR_STOP_ENDPOINT,
    CR_SET_TR_DEQUEUE,
    CR_RESET_DEVICE,
    CR_FORCE_EVENT,
    CR_NEGOTIATE_BW,
    CR_SET_LATENCY_TOLERANCE,
    CR_GET_PORT_BANDWIDTH,
    CR_FORCE_HEADER,
    CR_NOOP,
    ER_TRANSFER = 32,
    ER_COMMAND_COMPLETE,
    ER_PORT_STATUS_CHANGE,
    ER_BANDWIDTH_REQUEST,
    ER_DOORBELL,
    ER_HOST_CONTROLLER,
    ER_DEVICE_NOTIFICATION,
    ER_MFINDEX_WRAP,
    /* vendor specific bits */
    CR_VENDOR_VIA_CHALLENGE_RESPONSE = 48,
    CR_VENDOR_NEC_FIRMWARE_REVISION  = 49,
    CR_VENDOR_NEC_CHALLENGE_RESPONSE = 50,
} TRBType;

#define CR_LINK TR_LINK

typedef enum TRBCCode {
    CC_INVALID = 0,
    CC_SUCCESS,
    CC_DATA_BUFFER_ERROR,
    CC_BABBLE_DETECTED,
    CC_USB_TRANSACTION_ERROR,
    CC_TRB_ERROR,
    CC_STALL_ERROR,
    CC_RESOURCE_ERROR,
    CC_BANDWIDTH_ERROR,
    CC_NO_SLOTS_ERROR,
    CC_INVALID_STREAM_TYPE_ERROR,
    CC_SLOT_NOT_ENABLED_ERROR,
    CC_EP_NOT_ENABLED_ERROR,
    CC_SHORT_PACKET,
    CC_RING_UNDERRUN,
    CC_RING_OVERRUN,
    CC_VF_ER_FULL,
    CC_PARAMETER_ERROR,
    CC_BANDWIDTH_OVERRUN,
    CC_CONTEXT_STATE_ERROR,
    CC_NO_PING_RESPONSE_ERROR,
    CC_EVENT_RING_FULL_ERROR,
    CC_INCOMPATIBLE_DEVICE_ERROR,
    CC_MISSED_SERVICE_ERROR,
    CC_COMMAND_RING_STOPPED,
    CC_COMMAND_ABORTED,
    CC_STOPPED,
    CC_STOPPED_LENGTH_INVALID,
    CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29,
    CC_ISOCH_BUFFER_OVERRUN = 31,
    CC_EVENT_LOST_ERROR,
    CC_UNDEFINED_ERROR,
    CC_INVALID_STREAM_ID_ERROR,
    CC_SECONDARY_BANDWIDTH_ERROR,
    CC_SPLIT_TRANSACTION_ERROR
} TRBCCode;

#define TRB_C               (1<<0)
#define TRB_TYPE_SHIFT          10
#define TRB_TYPE_MASK       0x3f
#define TRB_TYPE(t)         (((t).control >> TRB_TYPE_SHIFT) & TRB_TYPE_MASK)

#define TRB_EV_ED           (1<<2)

#define TRB_TR_ENT          (1<<1)
#define TRB_TR_ISP          (1<<2)
#define TRB_TR_NS           (1<<3)
#define TRB_TR_CH           (1<<4)
#define TRB_TR_IOC          (1<<5)
#define TRB_TR_IDT          (1<<6)
#define TRB_TR_TBC_SHIFT        7
#define TRB_TR_TBC_MASK     0x3
#define TRB_TR_BEI          (1<<9)
#define TRB_TR_TLBPC_SHIFT      16
#define TRB_TR_TLBPC_MASK   0xf
#define TRB_TR_FRAMEID_SHIFT    20
#define TRB_TR_FRAMEID_MASK 0x7ff
#define TRB_TR_SIA          (1<<31)

#define TRB_TR_DIR          (1<<16)

#define TRB_CR_SLOTID_SHIFT     24
#define TRB_CR_SLOTID_MASK  0xff
#define TRB_CR_EPID_SHIFT       16
#define TRB_CR_EPID_MASK    0x1f

#define TRB_CR_BSR          (1<<9)
#define TRB_CR_DC           (1<<9)

#define TRB_LK_TC           (1<<1)

#define EP_TYPE_MASK        0x7
#define EP_TYPE_SHIFT           3

#define EP_STATE_MASK       0x7
#define EP_DISABLED         (0<<0)
#define EP_RUNNING          (1<<0)
#define EP_HALTED           (2<<0)
#define EP_STOPPED          (3<<0)
#define EP_ERROR            (4<<0)

#define SLOT_STATE_MASK     0x1f
#define SLOT_STATE_SHIFT        27
#define SLOT_STATE(s)       (((s)>>SLOT_STATE_SHIFT)&SLOT_STATE_MASK)
#define SLOT_ENABLED        0
#define SLOT_DEFAULT        1
#define SLOT_ADDRESSED      2
#define SLOT_CONFIGURED     3

#define SLOT_CONTEXT_ENTRIES_MASK 0x1f
#define SLOT_CONTEXT_ENTRIES_SHIFT 27

typedef enum EPType {
    ET_INVALID = 0,
    ET_ISO_OUT,
    ET_BULK_OUT,
    ET_INTR_OUT,
    ET_CONTROL,
    ET_ISO_IN,
    ET_BULK_IN,
    ET_INTR_IN,
} EPType;

typedef struct XHCIRing {
    target_phys_addr_t base;
    target_phys_addr_t dequeue;
    bool ccs;
} XHCIRing;

typedef struct XHCIPort {
    USBPort port;
    uint32_t portsc;
} XHCIPort;

struct XHCIState;
typedef struct XHCIState XHCIState;

typedef struct XHCITransfer {
    XHCIState *xhci;
    USBPacket packet;
    bool running_async;
    bool running_retry;
    bool cancelled;
    bool complete;
    bool backgrounded;
    unsigned int iso_pkts;
    unsigned int slotid;
    unsigned int epid;
    bool in_xfer;
    bool iso_xfer;
    bool bg_xfer;

    unsigned int trb_count;
    unsigned int trb_alloced;
    XHCITRB *trbs;

    unsigned int data_length;
    unsigned int data_alloced;
    uint8_t *data;

    TRBCCode status;

    unsigned int pkts;
    unsigned int pktsize;
    unsigned int cur_pkt;
} XHCITransfer;

typedef struct XHCIEPContext {
    XHCIRing ring;
    unsigned int next_xfer;
    unsigned int comp_xfer;
    XHCITransfer transfers[TD_QUEUE];
    XHCITransfer *retry;
    bool bg_running;
    bool bg_updating;
    unsigned int next_bg;
    XHCITransfer bg_transfers[BG_XFERS];
    EPType type;
    target_phys_addr_t pctx;
    unsigned int max_psize;
    bool has_bg;
    uint32_t state;
} XHCIEPContext;

typedef struct XHCISlot {
    bool enabled;
    target_phys_addr_t ctx;
    unsigned int port;
    unsigned int devaddr;
    XHCIEPContext * eps[31];
} XHCISlot;

typedef struct XHCIEvent {
    TRBType type;
    TRBCCode ccode;
    uint64_t ptr;
    uint32_t length;
    uint32_t flags;
    uint8_t slotid;
    uint8_t epid;
} XHCIEvent;

struct XHCIState {
    PCIDevice pci_dev;
    USBBus bus;
    qemu_irq irq;
    MemoryRegion mem;
    const char *name;
    uint32_t msi;
    unsigned int devaddr;

    /* Operational Registers */
    uint32_t usbcmd;
    uint32_t usbsts;
    uint32_t dnctrl;
    uint32_t crcr_low;
    uint32_t crcr_high;
    uint32_t dcbaap_low;
    uint32_t dcbaap_high;
    uint32_t config;

    XHCIPort ports[MAXPORTS];
    XHCISlot slots[MAXSLOTS];

    /* Runtime Registers */
    uint32_t mfindex;
    /* note: we only support one interrupter */
    uint32_t iman;
    uint32_t imod;
    uint32_t erstsz;
    uint32_t erstba_low;
    uint32_t erstba_high;
    uint32_t erdp_low;
    uint32_t erdp_high;

    target_phys_addr_t er_start;
    uint32_t er_size;
    bool er_pcs;
    unsigned int er_ep_idx;
    bool er_full;

    XHCIEvent ev_buffer[EV_QUEUE];
    unsigned int ev_buffer_put;
    unsigned int ev_buffer_get;

    XHCIRing cmd_ring;
};

typedef struct XHCIEvRingSeg {
    uint32_t addr_low;
    uint32_t addr_high;
    uint32_t size;
    uint32_t rsvd;
} XHCIEvRingSeg;

#ifdef DEBUG_XHCI
static const char *TRBType_names[] = {
    [TRB_RESERVED]                     = "TRB_RESERVED",
    [TR_NORMAL]                        = "TR_NORMAL",
    [TR_SETUP]                         = "TR_SETUP",
    [TR_DATA]                          = "TR_DATA",
    [TR_STATUS]                        = "TR_STATUS",
    [TR_ISOCH]                         = "TR_ISOCH",
    [TR_LINK]                          = "TR_LINK",
    [TR_EVDATA]                        = "TR_EVDATA",
    [TR_NOOP]                          = "TR_NOOP",
    [CR_ENABLE_SLOT]                   = "CR_ENABLE_SLOT",
    [CR_DISABLE_SLOT]                  = "CR_DISABLE_SLOT",
    [CR_ADDRESS_DEVICE]                = "CR_ADDRESS_DEVICE",
    [CR_CONFIGURE_ENDPOINT]            = "CR_CONFIGURE_ENDPOINT",
    [CR_EVALUATE_CONTEXT]              = "CR_EVALUATE_CONTEXT",
    [CR_RESET_ENDPOINT]                = "CR_RESET_ENDPOINT",
    [CR_STOP_ENDPOINT]                 = "CR_STOP_ENDPOINT",
    [CR_SET_TR_DEQUEUE]                = "CR_SET_TR_DEQUEUE",
    [CR_RESET_DEVICE]                  = "CR_RESET_DEVICE",
    [CR_FORCE_EVENT]                   = "CR_FORCE_EVENT",
    [CR_NEGOTIATE_BW]                  = "CR_NEGOTIATE_BW",
    [CR_SET_LATENCY_TOLERANCE]         = "CR_SET_LATENCY_TOLERANCE",
    [CR_GET_PORT_BANDWIDTH]            = "CR_GET_PORT_BANDWIDTH",
    [CR_FORCE_HEADER]                  = "CR_FORCE_HEADER",
    [CR_NOOP]                          = "CR_NOOP",
    [ER_TRANSFER]                      = "ER_TRANSFER",
    [ER_COMMAND_COMPLETE]              = "ER_COMMAND_COMPLETE",
    [ER_PORT_STATUS_CHANGE]            = "ER_PORT_STATUS_CHANGE",
    [ER_BANDWIDTH_REQUEST]             = "ER_BANDWIDTH_REQUEST",
    [ER_DOORBELL]                      = "ER_DOORBELL",
    [ER_HOST_CONTROLLER]               = "ER_HOST_CONTROLLER",
    [ER_DEVICE_NOTIFICATION]           = "ER_DEVICE_NOTIFICATION",
    [ER_MFINDEX_WRAP]                  = "ER_MFINDEX_WRAP",
    [CR_VENDOR_VIA_CHALLENGE_RESPONSE] = "CR_VENDOR_VIA_CHALLENGE_RESPONSE",
    [CR_VENDOR_NEC_FIRMWARE_REVISION]  = "CR_VENDOR_NEC_FIRMWARE_REVISION",
    [CR_VENDOR_NEC_CHALLENGE_RESPONSE] = "CR_VENDOR_NEC_CHALLENGE_RESPONSE",
};

static const char *lookup_name(uint32_t index, const char **list, uint32_t llen)
{
    if (index >= llen || list[index] == NULL) {
        return "???";
    }
    return list[index];
}

static const char *trb_name(XHCITRB *trb)
{
    return lookup_name(TRB_TYPE(*trb), TRBType_names,
                       ARRAY_SIZE(TRBType_names));
}
#endif

static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
                         unsigned int epid);

static inline target_phys_addr_t xhci_addr64(uint32_t low, uint32_t high)
{
#if TARGET_PHYS_ADDR_BITS > 32
    return low | ((target_phys_addr_t)high << 32);
#else
    return low;
#endif
}

static inline target_phys_addr_t xhci_mask64(uint64_t addr)
{
#if TARGET_PHYS_ADDR_BITS > 32
    return addr;
#else
    return addr & 0xffffffff;
#endif
}

static void xhci_irq_update(XHCIState *xhci)
{
    int level = 0;

    if (xhci->iman & IMAN_IP && xhci->iman & IMAN_IE &&
        xhci->usbcmd && USBCMD_INTE) {
        level = 1;
    }

    DPRINTF("xhci_irq_update(): %d\n", level);

    if (xhci->msi && msi_enabled(&xhci->pci_dev)) {
        if (level) {
            DPRINTF("xhci_irq_update(): MSI signal\n");
            msi_notify(&xhci->pci_dev, 0);
        }
    } else {
        qemu_set_irq(xhci->irq, level);
    }
}

static inline int xhci_running(XHCIState *xhci)
{
    return !(xhci->usbsts & USBSTS_HCH) && !xhci->er_full;
}

static void xhci_die(XHCIState *xhci)
{
    xhci->usbsts |= USBSTS_HCE;
    fprintf(stderr, "xhci: asserted controller error\n");
}

static void xhci_write_event(XHCIState *xhci, XHCIEvent *event)
{
    XHCITRB ev_trb;
    target_phys_addr_t addr;

    ev_trb.parameter = cpu_to_le64(event->ptr);
    ev_trb.status = cpu_to_le32(event->length | (event->ccode << 24));
    ev_trb.control = (event->slotid << 24) | (event->epid << 16) |
                     event->flags | (event->type << TRB_TYPE_SHIFT);
    if (xhci->er_pcs) {
        ev_trb.control |= TRB_C;
    }
    ev_trb.control = cpu_to_le32(ev_trb.control);

    DPRINTF("xhci_write_event(): [%d] %016"PRIx64" %08x %08x %s\n",
            xhci->er_ep_idx, ev_trb.parameter, ev_trb.status, ev_trb.control,
            trb_name(&ev_trb));

    addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx;
    cpu_physical_memory_write(addr, (uint8_t *) &ev_trb, TRB_SIZE);

    xhci->er_ep_idx++;
    if (xhci->er_ep_idx >= xhci->er_size) {
        xhci->er_ep_idx = 0;
        xhci->er_pcs = !xhci->er_pcs;
    }
}

static void xhci_events_update(XHCIState *xhci)
{
    target_phys_addr_t erdp;
    unsigned int dp_idx;
    bool do_irq = 0;

    if (xhci->usbsts & USBSTS_HCH) {
        return;
    }

    erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high);
    if (erdp < xhci->er_start ||
        erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) {
        fprintf(stderr, "xhci: ERDP out of bounds: "TARGET_FMT_plx"\n", erdp);
        fprintf(stderr, "xhci: ER at "TARGET_FMT_plx" len %d\n",
                xhci->er_start, xhci->er_size);
        xhci_die(xhci);
        return;
    }
    dp_idx = (erdp - xhci->er_start) / TRB_SIZE;
    assert(dp_idx < xhci->er_size);

    /* NEC didn't read section 4.9.4 of the spec (v1.0 p139 top Note) and thus
     * deadlocks when the ER is full. Hack it by holding off events until
     * the driver decides to free at least half of the ring */
    if (xhci->er_full) {
        int er_free = dp_idx - xhci->er_ep_idx;
        if (er_free <= 0) {
            er_free += xhci->er_size;
        }
        if (er_free < (xhci->er_size/2)) {
            DPRINTF("xhci_events_update(): event ring still "
                    "more than half full (hack)\n");
            return;
        }
    }

    while (xhci->ev_buffer_put != xhci->ev_buffer_get) {
        assert(xhci->er_full);
        if (((xhci->er_ep_idx+1) % xhci->er_size) == dp_idx) {
            DPRINTF("xhci_events_update(): event ring full again\n");
#ifndef ER_FULL_HACK
            XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR};
            xhci_write_event(xhci, &full);
#endif
            do_irq = 1;
            break;
        }
        XHCIEvent *event = &xhci->ev_buffer[xhci->ev_buffer_get];
        xhci_write_event(xhci, event);
        xhci->ev_buffer_get++;
        do_irq = 1;
        if (xhci->ev_buffer_get == EV_QUEUE) {
            xhci->ev_buffer_get = 0;
        }
    }

    if (do_irq) {
        xhci->erdp_low |= ERDP_EHB;
        xhci->iman |= IMAN_IP;
        xhci->usbsts |= USBSTS_EINT;
        xhci_irq_update(xhci);
    }

    if (xhci->er_full && xhci->ev_buffer_put == xhci->ev_buffer_get) {
        DPRINTF("xhci_events_update(): event ring no longer full\n");
        xhci->er_full = 0;
    }
    return;
}

static void xhci_event(XHCIState *xhci, XHCIEvent *event)
{
    target_phys_addr_t erdp;
    unsigned int dp_idx;

    if (xhci->er_full) {
        DPRINTF("xhci_event(): ER full, queueing\n");
        if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) {
            fprintf(stderr, "xhci: event queue full, dropping event!\n");
            return;
        }
        xhci->ev_buffer[xhci->ev_buffer_put++] = *event;
        if (xhci->ev_buffer_put == EV_QUEUE) {
            xhci->ev_buffer_put = 0;
        }
        return;
    }

    erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high);
    if (erdp < xhci->er_start ||
        erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) {
        fprintf(stderr, "xhci: ERDP out of bounds: "TARGET_FMT_plx"\n", erdp);
        fprintf(stderr, "xhci: ER at "TARGET_FMT_plx" len %d\n",
                xhci->er_start, xhci->er_size);
        xhci_die(xhci);
        return;
    }

    dp_idx = (erdp - xhci->er_start) / TRB_SIZE;
    assert(dp_idx < xhci->er_size);

    if ((xhci->er_ep_idx+1) % xhci->er_size == dp_idx) {
        DPRINTF("xhci_event(): ER full, queueing\n");
#ifndef ER_FULL_HACK
        XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR};
        xhci_write_event(xhci, &full);
#endif
        xhci->er_full = 1;
        if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) {
            fprintf(stderr, "xhci: event queue full, dropping event!\n");
            return;
        }
        xhci->ev_buffer[xhci->ev_buffer_put++] = *event;
        if (xhci->ev_buffer_put == EV_QUEUE) {
            xhci->ev_buffer_put = 0;
        }
    } else {
        xhci_write_event(xhci, event);
    }

    xhci->erdp_low |= ERDP_EHB;
    xhci->iman |= IMAN_IP;
    xhci->usbsts |= USBSTS_EINT;

    xhci_irq_update(xhci);
}

static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
                           target_phys_addr_t base)
{
    ring->base = base;
    ring->dequeue = base;
    ring->ccs = 1;
}

static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
                               target_phys_addr_t *addr)
{
    while (1) {
        TRBType type;
        cpu_physical_memory_read(ring->dequeue, (uint8_t *) trb, TRB_SIZE);
        trb->addr = ring->dequeue;
        trb->ccs = ring->ccs;
        le64_to_cpus(&trb->parameter);
        le32_to_cpus(&trb->status);
        le32_to_cpus(&trb->control);

        DPRINTF("xhci: TRB fetched [" TARGET_FMT_plx "]: "
                "%016" PRIx64 " %08x %08x %s\n",
                ring->dequeue, trb->parameter, trb->status, trb->control,
                trb_name(trb));

        if ((trb->control & TRB_C) != ring->ccs) {
            return 0;
        }

        type = TRB_TYPE(*trb);

        if (type != TR_LINK) {
            if (addr) {
                *addr = ring->dequeue;
            }
            ring->dequeue += TRB_SIZE;
            return type;
        } else {
            ring->dequeue = xhci_mask64(trb->parameter);
            if (trb->control & TRB_LK_TC) {
                ring->ccs = !ring->ccs;
            }
        }
    }
}

static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring)
{
    XHCITRB trb;
    int length = 0;
    target_phys_addr_t dequeue = ring->dequeue;
    bool ccs = ring->ccs;
    /* hack to bundle together the two/three TDs that make a setup transfer */
    bool control_td_set = 0;

    while (1) {
        TRBType type;
        cpu_physical_memory_read(dequeue, (uint8_t *) &trb, TRB_SIZE);
        le64_to_cpus(&trb.parameter);
        le32_to_cpus(&trb.status);
        le32_to_cpus(&trb.control);

        DPRINTF("xhci: TRB peeked [" TARGET_FMT_plx "]: "
                "%016" PRIx64 " %08x %08x\n",
                dequeue, trb.parameter, trb.status, trb.control);

        if ((trb.control & TRB_C) != ccs) {
            return -length;
        }

        type = TRB_TYPE(trb);

        if (type == TR_LINK) {
            dequeue = xhci_mask64(trb.parameter);
            if (trb.control & TRB_LK_TC) {
                ccs = !ccs;
            }
            continue;
        }

        length += 1;
        dequeue += TRB_SIZE;

        if (type == TR_SETUP) {
            control_td_set = 1;
        } else if (type == TR_STATUS) {
            control_td_set = 0;
        }

        if (!control_td_set && !(trb.control & TRB_TR_CH)) {
            return length;
        }
    }
}

static void xhci_er_reset(XHCIState *xhci)
{
    XHCIEvRingSeg seg;

    /* cache the (sole) event ring segment location */
    if (xhci->erstsz != 1) {
        fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", xhci->erstsz);
        xhci_die(xhci);
        return;
    }
    target_phys_addr_t erstba = xhci_addr64(xhci->erstba_low, xhci->erstba_high);
    cpu_physical_memory_read(erstba, (uint8_t *) &seg, sizeof(seg));
    le32_to_cpus(&seg.addr_low);
    le32_to_cpus(&seg.addr_high);
    le32_to_cpus(&seg.size);
    if (seg.size < 16 || seg.size > 4096) {
        fprintf(stderr, "xhci: invalid value for segment size: %d\n", seg.size);
        xhci_die(xhci);
        return;
    }
    xhci->er_start = xhci_addr64(seg.addr_low, seg.addr_high);
    xhci->er_size = seg.size;

    xhci->er_ep_idx = 0;
    xhci->er_pcs = 1;
    xhci->er_full = 0;

    DPRINTF("xhci: event ring:" TARGET_FMT_plx " [%d]\n",
            xhci->er_start, xhci->er_size);
}

static void xhci_run(XHCIState *xhci)
{
    DPRINTF("xhci_run()\n");

    xhci->usbsts &= ~USBSTS_HCH;
}

static void xhci_stop(XHCIState *xhci)
{
    DPRINTF("xhci_stop()\n");
    xhci->usbsts |= USBSTS_HCH;
    xhci->crcr_low &= ~CRCR_CRR;
}

static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
                              uint32_t state)
{
    uint32_t ctx[5];
    if (epctx->state == state) {
        return;
    }

    cpu_physical_memory_read(epctx->pctx, (uint8_t *) ctx, sizeof(ctx));
    ctx[0] &= ~EP_STATE_MASK;
    ctx[0] |= state;
    ctx[2] = epctx->ring.dequeue | epctx->ring.ccs;
    ctx[3] = (epctx->ring.dequeue >> 16) >> 16;
    DPRINTF("xhci: set epctx: " TARGET_FMT_plx " state=%d dequeue=%08x%08x\n",
            epctx->pctx, state, ctx[3], ctx[2]);
    cpu_physical_memory_write(epctx->pctx, (uint8_t *) ctx, sizeof(ctx));
    epctx->state = state;
}

static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
                               unsigned int epid, target_phys_addr_t pctx,
                               uint32_t *ctx)
{
    XHCISlot *slot;
    XHCIEPContext *epctx;
    target_phys_addr_t dequeue;
    int i;

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    assert(epid >= 1 && epid <= 31);

    DPRINTF("xhci_enable_ep(%d, %d)\n", slotid, epid);

    slot = &xhci->slots[slotid-1];
    if (slot->eps[epid-1]) {
        fprintf(stderr, "xhci: slot %d ep %d already enabled!\n", slotid, epid);
        return CC_TRB_ERROR;
    }

    epctx = g_malloc(sizeof(XHCIEPContext));
    memset(epctx, 0, sizeof(XHCIEPContext));

    slot->eps[epid-1] = epctx;

    dequeue = xhci_addr64(ctx[2] & ~0xf, ctx[3]);
    xhci_ring_init(xhci, &epctx->ring, dequeue);
    epctx->ring.ccs = ctx[2] & 1;

    epctx->type = (ctx[1] >> EP_TYPE_SHIFT) & EP_TYPE_MASK;
    DPRINTF("xhci: endpoint %d.%d type is %d\n", epid/2, epid%2, epctx->type);
    epctx->pctx = pctx;
    epctx->max_psize = ctx[1]>>16;
    epctx->max_psize *= 1+((ctx[1]>>8)&0xff);
    epctx->has_bg = false;
    if (epctx->type == ET_ISO_IN) {
        epctx->has_bg = true;
    }
    DPRINTF("xhci: endpoint %d.%d max transaction (burst) size is %d\n",
            epid/2, epid%2, epctx->max_psize);
    for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) {
        usb_packet_init(&epctx->transfers[i].packet);
    }

    epctx->state = EP_RUNNING;
    ctx[0] &= ~EP_STATE_MASK;
    ctx[0] |= EP_RUNNING;

    return CC_SUCCESS;
}

static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
                               unsigned int epid)
{
    XHCISlot *slot;
    XHCIEPContext *epctx;
    int i, xferi, killed = 0;
    assert(slotid >= 1 && slotid <= MAXSLOTS);
    assert(epid >= 1 && epid <= 31);

    DPRINTF("xhci_ep_nuke_xfers(%d, %d)\n", slotid, epid);

    slot = &xhci->slots[slotid-1];

    if (!slot->eps[epid-1]) {
        return 0;
    }

    epctx = slot->eps[epid-1];

    xferi = epctx->next_xfer;
    for (i = 0; i < TD_QUEUE; i++) {
        XHCITransfer *t = &epctx->transfers[xferi];
        if (t->running_async) {
            usb_cancel_packet(&t->packet);
            t->running_async = 0;
            t->cancelled = 1;
            DPRINTF("xhci: cancelling transfer %d, waiting for it to complete...\n", i);
            killed++;
        }
        if (t->running_retry) {
            t->running_retry = 0;
            epctx->retry = NULL;
        }
        if (t->backgrounded) {
            t->backgrounded = 0;
        }
        if (t->trbs) {
            g_free(t->trbs);
        }
        if (t->data) {
            g_free(t->data);
        }

        t->trbs = NULL;
        t->data = NULL;
        t->trb_count = t->trb_alloced = 0;
        t->data_length = t->data_alloced = 0;
        xferi = (xferi + 1) % TD_QUEUE;
    }
    if (epctx->has_bg) {
        xferi = epctx->next_bg;
        for (i = 0; i < BG_XFERS; i++) {
            XHCITransfer *t = &epctx->bg_transfers[xferi];
            if (t->running_async) {
                usb_cancel_packet(&t->packet);
                t->running_async = 0;
                t->cancelled = 1;
                DPRINTF("xhci: cancelling bg transfer %d, waiting for it to complete...\n", i);
                killed++;
            }
            if (t->data) {
                g_free(t->data);
            }

            t->data = NULL;
            xferi = (xferi + 1) % BG_XFERS;
        }
    }
    return killed;
}

static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid,
                               unsigned int epid)
{
    XHCISlot *slot;
    XHCIEPContext *epctx;

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    assert(epid >= 1 && epid <= 31);

    DPRINTF("xhci_disable_ep(%d, %d)\n", slotid, epid);

    slot = &xhci->slots[slotid-1];

    if (!slot->eps[epid-1]) {
        DPRINTF("xhci: slot %d ep %d already disabled\n", slotid, epid);
        return CC_SUCCESS;
    }

    xhci_ep_nuke_xfers(xhci, slotid, epid);

    epctx = slot->eps[epid-1];

    xhci_set_ep_state(xhci, epctx, EP_DISABLED);

    g_free(epctx);
    slot->eps[epid-1] = NULL;

    return CC_SUCCESS;
}

static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned int slotid,
                             unsigned int epid)
{
    XHCISlot *slot;
    XHCIEPContext *epctx;

    DPRINTF("xhci_stop_ep(%d, %d)\n", slotid, epid);

    assert(slotid >= 1 && slotid <= MAXSLOTS);

    if (epid < 1 || epid > 31) {
        fprintf(stderr, "xhci: bad ep %d\n", epid);
        return CC_TRB_ERROR;
    }

    slot = &xhci->slots[slotid-1];

    if (!slot->eps[epid-1]) {
        DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid);
        return CC_EP_NOT_ENABLED_ERROR;
    }

    if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) {
        fprintf(stderr, "xhci: FIXME: endpoint stopped w/ xfers running, "
                "data might be lost\n");
    }

    epctx = slot->eps[epid-1];

    xhci_set_ep_state(xhci, epctx, EP_STOPPED);

    return CC_SUCCESS;
}

static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
                              unsigned int epid)
{
    XHCISlot *slot;
    XHCIEPContext *epctx;
    USBDevice *dev;

    assert(slotid >= 1 && slotid <= MAXSLOTS);

    DPRINTF("xhci_reset_ep(%d, %d)\n", slotid, epid);

    if (epid < 1 || epid > 31) {
        fprintf(stderr, "xhci: bad ep %d\n", epid);
        return CC_TRB_ERROR;
    }

    slot = &xhci->slots[slotid-1];

    if (!slot->eps[epid-1]) {
        DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid);
        return CC_EP_NOT_ENABLED_ERROR;
    }

    epctx = slot->eps[epid-1];

    if (epctx->state != EP_HALTED) {
        fprintf(stderr, "xhci: reset EP while EP %d not halted (%d)\n",
                epid, epctx->state);
        return CC_CONTEXT_STATE_ERROR;
    }

    if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) {
        fprintf(stderr, "xhci: FIXME: endpoint reset w/ xfers running, "
                "data might be lost\n");
    }

    uint8_t ep = epid>>1;

    if (epid & 1) {
        ep |= 0x80;
    }

    dev = xhci->ports[xhci->slots[slotid-1].port-1].port.dev;
    if (!dev) {
        return CC_USB_TRANSACTION_ERROR;
    }

    xhci_set_ep_state(xhci, epctx, EP_STOPPED);

    return CC_SUCCESS;
}

static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid,
                                    unsigned int epid, uint64_t pdequeue)
{
    XHCISlot *slot;
    XHCIEPContext *epctx;
    target_phys_addr_t dequeue;

    assert(slotid >= 1 && slotid <= MAXSLOTS);

    if (epid < 1 || epid > 31) {
        fprintf(stderr, "xhci: bad ep %d\n", epid);
        return CC_TRB_ERROR;
    }

    DPRINTF("xhci_set_ep_dequeue(%d, %d, %016"PRIx64")\n", slotid, epid, pdequeue);
    dequeue = xhci_mask64(pdequeue);

    slot = &xhci->slots[slotid-1];

    if (!slot->eps[epid-1]) {
        DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid);
        return CC_EP_NOT_ENABLED_ERROR;
    }

    epctx = slot->eps[epid-1];


    if (epctx->state != EP_STOPPED) {
        fprintf(stderr, "xhci: set EP dequeue pointer while EP %d not stopped\n", epid);
        return CC_CONTEXT_STATE_ERROR;
    }

    xhci_ring_init(xhci, &epctx->ring, dequeue & ~0xF);
    epctx->ring.ccs = dequeue & 1;

    xhci_set_ep_state(xhci, epctx, EP_STOPPED);

    return CC_SUCCESS;
}

static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
                          unsigned int length, bool in_xfer, bool out_xfer,
                          bool report)
{
    int i;
    uint32_t edtla = 0;
    unsigned int transferred = 0;
    unsigned int left = length;
    bool reported = 0;
    bool shortpkt = 0;
    XHCIEvent event = {ER_TRANSFER, CC_SUCCESS};
    XHCIState *xhci = xfer->xhci;

    DPRINTF("xhci_xfer_data(len=%d, in_xfer=%d, out_xfer=%d, report=%d)\n",
            length, in_xfer, out_xfer, report);

    assert(!(in_xfer && out_xfer));

    for (i = 0; i < xfer->trb_count; i++) {
        XHCITRB *trb = &xfer->trbs[i];
        target_phys_addr_t addr;
        unsigned int chunk = 0;

        switch (TRB_TYPE(*trb)) {
        case TR_DATA:
            if ((!(trb->control & TRB_TR_DIR)) != (!in_xfer)) {
                fprintf(stderr, "xhci: data direction mismatch for TR_DATA\n");
                xhci_die(xhci);
                return transferred;
            }
            /* fallthrough */
        case TR_NORMAL:
        case TR_ISOCH:
            addr = xhci_mask64(trb->parameter);
            chunk = trb->status & 0x1ffff;
            if (chunk > left) {
                chunk = left;
                shortpkt = 1;
            }
            if (in_xfer || out_xfer) {
                if (trb->control & TRB_TR_IDT) {
                    uint64_t idata;
                    if (chunk > 8 || in_xfer) {
                        fprintf(stderr, "xhci: invalid immediate data TRB\n");
                        xhci_die(xhci);
                        return transferred;
                    }
                    idata = le64_to_cpu(trb->parameter);
                    memcpy(data, &idata, chunk);
                } else {
                    DPRINTF("xhci_xfer_data: r/w(%d) %d bytes at "
                            TARGET_FMT_plx "\n", in_xfer, chunk, addr);
                    if (in_xfer) {
                        cpu_physical_memory_write(addr, data, chunk);
                    } else {
                        cpu_physical_memory_read(addr, data, chunk);
                    }
#ifdef DEBUG_DATA
                    unsigned int count = chunk;
                    int i;
                    if (count > 16) {
                        count = 16;
                    }
                    DPRINTF(" ::");
                    for (i = 0; i < count; i++) {
                        DPRINTF(" %02x", data[i]);
                    }
                    DPRINTF("\n");
#endif
                }
            }
            left -= chunk;
            data += chunk;
            edtla += chunk;
            transferred += chunk;
            break;
        case TR_STATUS:
            reported = 0;
            shortpkt = 0;
            break;
        }

        if (report && !reported && (trb->control & TRB_TR_IOC ||
            (shortpkt && (trb->control & TRB_TR_ISP)))) {
            event.slotid = xfer->slotid;
            event.epid = xfer->epid;
            event.length = (trb->status & 0x1ffff) - chunk;
            event.flags = 0;
            event.ptr = trb->addr;
            if (xfer->status == CC_SUCCESS) {
                event.ccode = shortpkt ? CC_SHORT_PACKET : CC_SUCCESS;
            } else {
                event.ccode = xfer->status;
            }
            if (TRB_TYPE(*trb) == TR_EVDATA) {
                event.ptr = trb->parameter;
                event.flags |= TRB_EV_ED;
                event.length = edtla & 0xffffff;
                DPRINTF("xhci_xfer_data: EDTLA=%d\n", event.length);
                edtla = 0;
            }
            xhci_event(xhci, &event);
            reported = 1;
        }
    }
    return transferred;
}

static void xhci_stall_ep(XHCITransfer *xfer)
{
    XHCIState *xhci = xfer->xhci;
    XHCISlot *slot = &xhci->slots[xfer->slotid-1];
    XHCIEPContext *epctx = slot->eps[xfer->epid-1];

    epctx->ring.dequeue = xfer->trbs[0].addr;
    epctx->ring.ccs = xfer->trbs[0].ccs;
    xhci_set_ep_state(xhci, epctx, EP_HALTED);
    DPRINTF("xhci: stalled slot %d ep %d\n", xfer->slotid, xfer->epid);
    DPRINTF("xhci: will continue at "TARGET_FMT_plx"\n", epctx->ring.dequeue);
}

static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer,
                       XHCIEPContext *epctx);

static void xhci_bg_update(XHCIState *xhci, XHCIEPContext *epctx)
{
    if (epctx->bg_updating) {
        return;
    }
    DPRINTF("xhci_bg_update(%p, %p)\n", xhci, epctx);
    assert(epctx->has_bg);
    DPRINTF("xhci: fg=%d bg=%d\n", epctx->comp_xfer, epctx->next_bg);
    epctx->bg_updating = 1;
    while (epctx->transfers[epctx->comp_xfer].backgrounded &&
           epctx->bg_transfers[epctx->next_bg].complete) {
        XHCITransfer *fg = &epctx->transfers[epctx->comp_xfer];
        XHCITransfer *bg = &epctx->bg_transfers[epctx->next_bg];
#if 0
        DPRINTF("xhci: completing fg %d from bg %d.%d (stat: %d)\n",
                epctx->comp_xfer, epctx->next_bg, bg->cur_pkt,
                bg->usbxfer->iso_packet_desc[bg->cur_pkt].status
               );
#endif
        assert(epctx->type == ET_ISO_IN);
        assert(bg->iso_xfer);
        assert(bg->in_xfer);
        uint8_t *p = bg->data + bg->cur_pkt * bg->pktsize;
#if 0
        int len = bg->usbxfer->iso_packet_desc[bg->cur_pkt].actual_length;
        fg->status = libusb_to_ccode(bg->usbxfer->iso_packet_desc[bg->cur_pkt].status);
#else
        int len = 0;
        FIXME();
#endif
        fg->complete = 1;
        fg->backgrounded = 0;

        if (fg->status == CC_STALL_ERROR) {
            xhci_stall_ep(fg);
        }

        xhci_xfer_data(fg, p, len, 1, 0, 1);

        epctx->comp_xfer++;
        if (epctx->comp_xfer == TD_QUEUE) {
            epctx->comp_xfer = 0;
        }
        DPRINTF("next fg xfer: %d\n", epctx->comp_xfer);
        bg->cur_pkt++;
        if (bg->cur_pkt == bg->pkts) {
            bg->complete = 0;
            if (xhci_submit(xhci, bg, epctx) < 0) {
                fprintf(stderr, "xhci: bg resubmit failed\n");
            }
            epctx->next_bg++;
            if (epctx->next_bg == BG_XFERS) {
                epctx->next_bg = 0;
            }
            DPRINTF("next bg xfer: %d\n", epctx->next_bg);

        xhci_kick_ep(xhci, fg->slotid, fg->epid);
        }
    }
    epctx->bg_updating = 0;
}

#if 0
static void xhci_xfer_cb(struct libusb_transfer *transfer)
{
    XHCIState *xhci;
    XHCITransfer *xfer;

    xfer = (XHCITransfer *)transfer->user_data;
    xhci = xfer->xhci;

    DPRINTF("xhci_xfer_cb(slot=%d, ep=%d, status=%d)\n", xfer->slotid,
            xfer->epid, transfer->status);

    assert(xfer->slotid >= 1 && xfer->slotid <= MAXSLOTS);
    assert(xfer->epid >= 1 && xfer->epid <= 31);

    if (xfer->cancelled) {
        DPRINTF("xhci: transfer cancelled, not reporting anything\n");
        xfer->running = 0;
        return;
    }

    XHCIEPContext *epctx;
    XHCISlot *slot;
    slot = &xhci->slots[xfer->slotid-1];
    assert(slot->eps[xfer->epid-1]);
    epctx = slot->eps[xfer->epid-1];

    if (xfer->bg_xfer) {
        DPRINTF("xhci: background transfer, updating\n");
        xfer->complete = 1;
        xfer->running = 0;
        xhci_bg_update(xhci, epctx);
        return;
    }

    if (xfer->iso_xfer) {
        transfer->status = transfer->iso_packet_desc[0].status;
        transfer->actual_length = transfer->iso_packet_desc[0].actual_length;
    }

    xfer->status = libusb_to_ccode(transfer->status);

    xfer->complete = 1;
    xfer->running = 0;

    if (transfer->status == LIBUSB_TRANSFER_STALL)
        xhci_stall_ep(xhci, epctx, xfer);

    DPRINTF("xhci: transfer actual length = %d\n", transfer->actual_length);

    if (xfer->in_xfer) {
        if (xfer->epid == 1) {
            xhci_xfer_data(xhci, xfer, xfer->data + 8,
                           transfer->actual_length, 1, 0, 1);
        } else {
            xhci_xfer_data(xhci, xfer, xfer->data,
                           transfer->actual_length, 1, 0, 1);
        }
    } else {
        xhci_xfer_data(xhci, xfer, NULL, transfer->actual_length, 0, 0, 1);
    }

    xhci_kick_ep(xhci, xfer->slotid, xfer->epid);
}

static int xhci_hle_control(XHCIState *xhci, XHCITransfer *xfer,
                            uint8_t bmRequestType, uint8_t bRequest,
                            uint16_t wValue, uint16_t wIndex, uint16_t wLength)
{
    uint16_t type_req = (bmRequestType << 8) | bRequest;

    switch (type_req) {
        case 0x0000 | USB_REQ_SET_CONFIGURATION:
            DPRINTF("xhci: HLE switch configuration\n");
            return xhci_switch_config(xhci, xfer->slotid, wValue) == 0;
        case 0x0100 | USB_REQ_SET_INTERFACE:
            DPRINTF("xhci: HLE set interface altsetting\n");
            return xhci_set_iface_alt(xhci, xfer->slotid, wIndex, wValue) == 0;
        case 0x0200 | USB_REQ_CLEAR_FEATURE:
            if (wValue == 0) { // endpoint halt
                DPRINTF("xhci: HLE clear halt\n");
                return xhci_clear_halt(xhci, xfer->slotid, wIndex);
            }
        case 0x0000 | USB_REQ_SET_ADDRESS:
            fprintf(stderr, "xhci: warn: illegal SET_ADDRESS request\n");
            return 0;
        default:
            return 0;
    }
}
#endif

static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev)
{
    USBEndpoint *ep;
    int dir;

    dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT;
    ep = usb_ep_get(dev, dir, xfer->epid >> 1);
    usb_packet_setup(&xfer->packet, dir, ep);
    usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length);
    DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n",
            xfer->packet.pid, dev->addr, ep->nr);
    return 0;
}

static int xhci_complete_packet(XHCITransfer *xfer, int ret)
{
    if (ret == USB_RET_ASYNC) {
        xfer->running_async = 1;
        xfer->running_retry = 0;
        xfer->complete = 0;
        xfer->cancelled = 0;
        return 0;
    } else if (ret == USB_RET_NAK) {
        xfer->running_async = 0;
        xfer->running_retry = 1;
        xfer->complete = 0;
        xfer->cancelled = 0;
        return 0;
    } else {
        xfer->running_async = 0;
        xfer->running_retry = 0;
        xfer->complete = 1;
    }

    if (ret >= 0) {
        xfer->status = CC_SUCCESS;
        xhci_xfer_data(xfer, xfer->data, ret, xfer->in_xfer, 0, 1);
        return 0;
    }

    /* error */
    switch (ret) {
    case USB_RET_NODEV:
        xfer->status = CC_USB_TRANSACTION_ERROR;
        xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1);
        xhci_stall_ep(xfer);
        break;
    case USB_RET_STALL:
        xfer->status = CC_STALL_ERROR;
        xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1);
        xhci_stall_ep(xfer);
        break;
    default:
        fprintf(stderr, "%s: FIXME: ret = %d\n", __FUNCTION__, ret);
        FIXME();
    }
    return 0;
}

static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr)
{
    if (!(port->portsc & PORTSC_PED)) {
        return NULL;
    }
    return usb_find_device(&port->port, addr);
}

static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
{
    XHCITRB *trb_setup, *trb_status;
    uint8_t bmRequestType, bRequest;
    uint16_t wValue, wLength, wIndex;
    XHCIPort *port;
    USBDevice *dev;
    int ret;

    DPRINTF("xhci_fire_ctl_transfer(slot=%d)\n", xfer->slotid);

    trb_setup = &xfer->trbs[0];
    trb_status = &xfer->trbs[xfer->trb_count-1];

    /* at most one Event Data TRB allowed after STATUS */
    if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) {
        trb_status--;
    }

    /* do some sanity checks */
    if (TRB_TYPE(*trb_setup) != TR_SETUP) {
        fprintf(stderr, "xhci: ep0 first TD not SETUP: %d\n",
                TRB_TYPE(*trb_setup));
        return -1;
    }
    if (TRB_TYPE(*trb_status) != TR_STATUS) {
        fprintf(stderr, "xhci: ep0 last TD not STATUS: %d\n",
                TRB_TYPE(*trb_status));
        return -1;
    }
    if (!(trb_setup->control & TRB_TR_IDT)) {
        fprintf(stderr, "xhci: Setup TRB doesn't have IDT set\n");
        return -1;
    }
    if ((trb_setup->status & 0x1ffff) != 8) {
        fprintf(stderr, "xhci: Setup TRB has bad length (%d)\n",
                (trb_setup->status & 0x1ffff));
        return -1;
    }

    bmRequestType = trb_setup->parameter;
    bRequest = trb_setup->parameter >> 8;
    wValue = trb_setup->parameter >> 16;
    wIndex = trb_setup->parameter >> 32;
    wLength = trb_setup->parameter >> 48;

    if (xfer->data && xfer->data_alloced < wLength) {
        xfer->data_alloced = 0;
        g_free(xfer->data);
        xfer->data = NULL;
    }
    if (!xfer->data) {
        DPRINTF("xhci: alloc %d bytes data\n", wLength);
        xfer->data = g_malloc(wLength+1);
        xfer->data_alloced = wLength;
    }
    xfer->data_length = wLength;

    port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1];
    dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr);
    if (!dev) {
        fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid,
                xhci->slots[xfer->slotid-1].port);
        return -1;
    }

    xfer->in_xfer = bmRequestType & USB_DIR_IN;
    xfer->iso_xfer = false;

    xhci_setup_packet(xfer, dev);
    if (!xfer->in_xfer) {
        xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0);
    }
    ret = usb_device_handle_control(dev, &xfer->packet,
                                    (bmRequestType << 8) | bRequest,
                                    wValue, wIndex, wLength, xfer->data);

    xhci_complete_packet(xfer, ret);
    if (!xfer->running_async && !xfer->running_retry) {
        xhci_kick_ep(xhci, xfer->slotid, xfer->epid);
    }
    return 0;
}

static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx)
{
    XHCIPort *port;
    USBDevice *dev;
    int ret;

    DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid);

    xfer->in_xfer = epctx->type>>2;

    if (xfer->data && xfer->data_alloced < xfer->data_length) {
        xfer->data_alloced = 0;
        g_free(xfer->data);
        xfer->data = NULL;
    }
    if (!xfer->data && xfer->data_length) {
        DPRINTF("xhci: alloc %d bytes data\n", xfer->data_length);
        xfer->data = g_malloc(xfer->data_length);
        xfer->data_alloced = xfer->data_length;
    }
    if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) {
        if (!xfer->bg_xfer) {
            xfer->pkts = 1;
        }
    } else {
        xfer->pkts = 0;
    }

    port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1];
    dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr);
    if (!dev) {
        fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid,
                xhci->slots[xfer->slotid-1].port);
        return -1;
    }

    xhci_setup_packet(xfer, dev);

    switch(epctx->type) {
    case ET_INTR_OUT:
    case ET_INTR_IN:
    case ET_BULK_OUT:
    case ET_BULK_IN:
        break;
    case ET_ISO_OUT:
    case ET_ISO_IN:
        FIXME();
        break;
    default:
        fprintf(stderr, "xhci: unknown or unhandled EP "
                "(type %d, in %d, ep %02x)\n",
                epctx->type, xfer->in_xfer, xfer->epid);
        return -1;
    }

    if (!xfer->in_xfer) {
        xhci_xfer_data(xfer, xfer->data, xfer->data_length, 0, 1, 0);
    }
    ret = usb_handle_packet(dev, &xfer->packet);

    xhci_complete_packet(xfer, ret);
    if (!xfer->running_async && !xfer->running_retry) {
        xhci_kick_ep(xhci, xfer->slotid, xfer->epid);
    }
    return 0;
}

static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx)
{
    int i;
    unsigned int length = 0;
    XHCITRB *trb;

    DPRINTF("xhci_fire_transfer(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid);

    for (i = 0; i < xfer->trb_count; i++) {
        trb = &xfer->trbs[i];
        if (TRB_TYPE(*trb) == TR_NORMAL || TRB_TYPE(*trb) == TR_ISOCH) {
            length += trb->status & 0x1ffff;
        }
    }
    DPRINTF("xhci: total TD length=%d\n", length);

    if (!epctx->has_bg) {
        xfer->data_length = length;
        xfer->backgrounded = 0;
        return xhci_submit(xhci, xfer, epctx);
    } else {
        if (!epctx->bg_running) {
            for (i = 0; i < BG_XFERS; i++) {
                XHCITransfer *t = &epctx->bg_transfers[i];
                t->xhci = xhci;
                t->epid = xfer->epid;
                t->slotid = xfer->slotid;
                t->pkts = BG_PKTS;
                t->pktsize = epctx->max_psize;
                t->data_length = t->pkts * t->pktsize;
                t->bg_xfer = 1;
                if (xhci_submit(xhci, t, epctx) < 0) {
                    fprintf(stderr, "xhci: bg submit failed\n");
                    return -1;
                }
            }
            epctx->bg_running = 1;
        }
        xfer->backgrounded = 1;
        xhci_bg_update(xhci, epctx);
        return 0;
    }
}

static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid)
{
    XHCIEPContext *epctx;
    int length;
    int i;

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    assert(epid >= 1 && epid <= 31);
    DPRINTF("xhci_kick_ep(%d, %d)\n", slotid, epid);

    if (!xhci->slots[slotid-1].enabled) {
        fprintf(stderr, "xhci: xhci_kick_ep for disabled slot %d\n", slotid);
        return;
    }
    epctx = xhci->slots[slotid-1].eps[epid-1];
    if (!epctx) {
        fprintf(stderr, "xhci: xhci_kick_ep for disabled endpoint %d,%d\n",
                epid, slotid);
        return;
    }

    if (epctx->retry) {
        /* retry nak'ed transfer */
        XHCITransfer *xfer = epctx->retry;
        int result;

        DPRINTF("xhci: retry nack'ed transfer ...\n");
        assert(xfer->running_retry);
        xhci_setup_packet(xfer, xfer->packet.ep->dev);
        result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
        if (result == USB_RET_NAK) {
            DPRINTF("xhci: ... xfer still nacked\n");
            return;
        }
        DPRINTF("xhci: ... result %d\n", result);
        xhci_complete_packet(xfer, result);
        assert(!xfer->running_retry);
        epctx->retry = NULL;
    }

    if (epctx->state == EP_HALTED) {
        DPRINTF("xhci: ep halted, not running schedule\n");
        return;
    }

    xhci_set_ep_state(xhci, epctx, EP_RUNNING);

    while (1) {
        XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer];
        if (xfer->running_async || xfer->running_retry || xfer->backgrounded) {
            DPRINTF("xhci: ep is busy (#%d,%d,%d,%d)\n",
                    epctx->next_xfer, xfer->running_async,
                    xfer->running_retry, xfer->backgrounded);
            break;
        } else {
            DPRINTF("xhci: ep: using #%d\n", epctx->next_xfer);
        }
        length = xhci_ring_chain_length(xhci, &epctx->ring);
        if (length < 0) {
            DPRINTF("xhci: incomplete TD (%d TRBs)\n", -length);
            break;
        } else if (length == 0) {
            break;
        }
        DPRINTF("xhci: fetching %d-TRB TD\n", length);
        if (xfer->trbs && xfer->trb_alloced < length) {
            xfer->trb_count = 0;
            xfer->trb_alloced = 0;
            g_free(xfer->trbs);
            xfer->trbs = NULL;
        }
        if (!xfer->trbs) {
            xfer->trbs = g_malloc(sizeof(XHCITRB) * length);
            xfer->trb_alloced = length;
        }
        xfer->trb_count = length;

        for (i = 0; i < length; i++) {
            assert(xhci_ring_fetch(xhci, &epctx->ring, &xfer->trbs[i], NULL));
        }
        xfer->xhci = xhci;
        xfer->epid = epid;
        xfer->slotid = slotid;

        if (epid == 1) {
            if (xhci_fire_ctl_transfer(xhci, xfer) >= 0) {
                epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
            } else {
                fprintf(stderr, "xhci: error firing CTL transfer\n");
            }
        } else {
            if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) {
                epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
            } else {
                fprintf(stderr, "xhci: error firing data transfer\n");
            }
        }

        if (epctx->state == EP_HALTED) {
            DPRINTF("xhci: ep halted, stopping schedule\n");
            break;
        }
        if (xfer->running_retry) {
            DPRINTF("xhci: xfer nacked, stopping schedule\n");
            epctx->retry = xfer;
            break;
        }
    }
}

static TRBCCode xhci_enable_slot(XHCIState *xhci, unsigned int slotid)
{
    assert(slotid >= 1 && slotid <= MAXSLOTS);
    DPRINTF("xhci_enable_slot(%d)\n", slotid);
    xhci->slots[slotid-1].enabled = 1;
    xhci->slots[slotid-1].port = 0;
    memset(xhci->slots[slotid-1].eps, 0, sizeof(XHCIEPContext*)*31);

    return CC_SUCCESS;
}

static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid)
{
    int i;

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    DPRINTF("xhci_disable_slot(%d)\n", slotid);

    for (i = 1; i <= 31; i++) {
        if (xhci->slots[slotid-1].eps[i-1]) {
            xhci_disable_ep(xhci, slotid, i);
        }
    }

    xhci->slots[slotid-1].enabled = 0;
    return CC_SUCCESS;
}

static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
                                  uint64_t pictx, bool bsr)
{
    XHCISlot *slot;
    USBDevice *dev;
    target_phys_addr_t ictx, octx, dcbaap;
    uint64_t poctx;
    uint32_t ictl_ctx[2];
    uint32_t slot_ctx[4];
    uint32_t ep0_ctx[5];
    unsigned int port;
    int i;
    TRBCCode res;

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    DPRINTF("xhci_address_slot(%d)\n", slotid);

    dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
    cpu_physical_memory_read(dcbaap + 8*slotid,
                             (uint8_t *) &poctx, sizeof(poctx));
    ictx = xhci_mask64(pictx);
    octx = xhci_mask64(le64_to_cpu(poctx));

    DPRINTF("xhci: input context at "TARGET_FMT_plx"\n", ictx);
    DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx);

    cpu_physical_memory_read(ictx, (uint8_t *) ictl_ctx, sizeof(ictl_ctx));

    if (ictl_ctx[0] != 0x0 || ictl_ctx[1] != 0x3) {
        fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
                ictl_ctx[0], ictl_ctx[1]);
        return CC_TRB_ERROR;
    }

    cpu_physical_memory_read(ictx+32, (uint8_t *) slot_ctx, sizeof(slot_ctx));
    cpu_physical_memory_read(ictx+64, (uint8_t *) ep0_ctx, sizeof(ep0_ctx));

    DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n",
            slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);

    DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n",
            ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);

    port = (slot_ctx[1]>>16) & 0xFF;
    dev = xhci->ports[port-1].port.dev;

    if (port < 1 || port > MAXPORTS) {
        fprintf(stderr, "xhci: bad port %d\n", port);
        return CC_TRB_ERROR;
    } else if (!dev) {
        fprintf(stderr, "xhci: port %d not connected\n", port);
        return CC_USB_TRANSACTION_ERROR;
    }

    for (i = 0; i < MAXSLOTS; i++) {
        if (xhci->slots[i].port == port) {
            fprintf(stderr, "xhci: port %d already assigned to slot %d\n",
                    port, i+1);
            return CC_TRB_ERROR;
        }
    }

    slot = &xhci->slots[slotid-1];
    slot->port = port;
    slot->ctx = octx;

    if (bsr) {
        slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;
    } else {
        slot->devaddr = xhci->devaddr++;
        slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr;
        DPRINTF("xhci: device address is %d\n", slot->devaddr);
        usb_device_handle_control(dev, NULL,
                                  DeviceOutRequest | USB_REQ_SET_ADDRESS,
                                  slot->devaddr, 0, 0, NULL);
    }

    res = xhci_enable_ep(xhci, slotid, 1, octx+32, ep0_ctx);

    DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
            slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
    DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n",
            ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);

    cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));
    cpu_physical_memory_write(octx+32, (uint8_t *) ep0_ctx, sizeof(ep0_ctx));

    return res;
}


static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
                                  uint64_t pictx, bool dc)
{
    target_phys_addr_t ictx, octx;
    uint32_t ictl_ctx[2];
    uint32_t slot_ctx[4];
    uint32_t islot_ctx[4];
    uint32_t ep_ctx[5];
    int i;
    TRBCCode res;

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    DPRINTF("xhci_configure_slot(%d)\n", slotid);

    ictx = xhci_mask64(pictx);
    octx = xhci->slots[slotid-1].ctx;

    DPRINTF("xhci: input context at "TARGET_FMT_plx"\n", ictx);
    DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx);

    if (dc) {
        for (i = 2; i <= 31; i++) {
            if (xhci->slots[slotid-1].eps[i-1]) {
                xhci_disable_ep(xhci, slotid, i);
            }
        }

        cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));
        slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT);
        slot_ctx[3] |= SLOT_ADDRESSED << SLOT_STATE_SHIFT;
        DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
                slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
        cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));

        return CC_SUCCESS;
    }

    cpu_physical_memory_read(ictx, (uint8_t *) ictl_ctx, sizeof(ictl_ctx));

    if ((ictl_ctx[0] & 0x3) != 0x0 || (ictl_ctx[1] & 0x3) != 0x1) {
        fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
                ictl_ctx[0], ictl_ctx[1]);
        return CC_TRB_ERROR;
    }

    cpu_physical_memory_read(ictx+32, (uint8_t *) islot_ctx, sizeof(islot_ctx));
    cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));

    if (SLOT_STATE(slot_ctx[3]) < SLOT_ADDRESSED) {
        fprintf(stderr, "xhci: invalid slot state %08x\n", slot_ctx[3]);
        return CC_CONTEXT_STATE_ERROR;
    }

    for (i = 2; i <= 31; i++) {
        if (ictl_ctx[0] & (1<<i)) {
            xhci_disable_ep(xhci, slotid, i);
        }
        if (ictl_ctx[1] & (1<<i)) {
            cpu_physical_memory_read(ictx+32+(32*i),
                                     (uint8_t *) ep_ctx, sizeof(ep_ctx));
            DPRINTF("xhci: input ep%d.%d context: %08x %08x %08x %08x %08x\n",
                    i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2],
                    ep_ctx[3], ep_ctx[4]);
            xhci_disable_ep(xhci, slotid, i);
            res = xhci_enable_ep(xhci, slotid, i, octx+(32*i), ep_ctx);
            if (res != CC_SUCCESS) {
                return res;
            }
            DPRINTF("xhci: output ep%d.%d context: %08x %08x %08x %08x %08x\n",
                    i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2],
                    ep_ctx[3], ep_ctx[4]);
            cpu_physical_memory_write(octx+(32*i),
                                      (uint8_t *) ep_ctx, sizeof(ep_ctx));
        }
    }

    slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT);
    slot_ctx[3] |= SLOT_CONFIGURED << SLOT_STATE_SHIFT;
    slot_ctx[0] &= ~(SLOT_CONTEXT_ENTRIES_MASK << SLOT_CONTEXT_ENTRIES_SHIFT);
    slot_ctx[0] |= islot_ctx[0] & (SLOT_CONTEXT_ENTRIES_MASK <<
                                   SLOT_CONTEXT_ENTRIES_SHIFT);
    DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
            slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);

    cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));

    return CC_SUCCESS;
}


static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid,
                                   uint64_t pictx)
{
    target_phys_addr_t ictx, octx;
    uint32_t ictl_ctx[2];
    uint32_t iep0_ctx[5];
    uint32_t ep0_ctx[5];
    uint32_t islot_ctx[4];
    uint32_t slot_ctx[4];

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    DPRINTF("xhci_evaluate_slot(%d)\n", slotid);

    ictx = xhci_mask64(pictx);
    octx = xhci->slots[slotid-1].ctx;

    DPRINTF("xhci: input context at "TARGET_FMT_plx"\n", ictx);
    DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx);

    cpu_physical_memory_read(ictx, (uint8_t *) ictl_ctx, sizeof(ictl_ctx));

    if (ictl_ctx[0] != 0x0 || ictl_ctx[1] & ~0x3) {
        fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
                ictl_ctx[0], ictl_ctx[1]);
        return CC_TRB_ERROR;
    }

    if (ictl_ctx[1] & 0x1) {
        cpu_physical_memory_read(ictx+32,
                                 (uint8_t *) islot_ctx, sizeof(islot_ctx));

        DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n",
                islot_ctx[0], islot_ctx[1], islot_ctx[2], islot_ctx[3]);

        cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));

        slot_ctx[1] &= ~0xFFFF; /* max exit latency */
        slot_ctx[1] |= islot_ctx[1] & 0xFFFF;
        slot_ctx[2] &= ~0xFF00000; /* interrupter target */
        slot_ctx[2] |= islot_ctx[2] & 0xFF000000;

        DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
                slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);

        cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));
    }

    if (ictl_ctx[1] & 0x2) {
        cpu_physical_memory_read(ictx+64,
                                 (uint8_t *) iep0_ctx, sizeof(iep0_ctx));

        DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n",
                iep0_ctx[0], iep0_ctx[1], iep0_ctx[2],
                iep0_ctx[3], iep0_ctx[4]);

        cpu_physical_memory_read(octx+32, (uint8_t *) ep0_ctx, sizeof(ep0_ctx));

        ep0_ctx[1] &= ~0xFFFF0000; /* max packet size*/
        ep0_ctx[1] |= iep0_ctx[1] & 0xFFFF0000;

        DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n",
                ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);

        cpu_physical_memory_write(octx+32,
                                  (uint8_t *) ep0_ctx, sizeof(ep0_ctx));
    }

    return CC_SUCCESS;
}

static TRBCCode xhci_reset_slot(XHCIState *xhci, unsigned int slotid)
{
    uint32_t slot_ctx[4];
    target_phys_addr_t octx;
    int i;

    assert(slotid >= 1 && slotid <= MAXSLOTS);
    DPRINTF("xhci_reset_slot(%d)\n", slotid);

    octx = xhci->slots[slotid-1].ctx;

    DPRINTF("xhci: output context at "TARGET_FMT_plx"\n", octx);

    for (i = 2; i <= 31; i++) {
        if (xhci->slots[slotid-1].eps[i-1]) {
            xhci_disable_ep(xhci, slotid, i);
        }
    }

    cpu_physical_memory_read(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));
    slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT);
    slot_ctx[3] |= SLOT_DEFAULT << SLOT_STATE_SHIFT;
    DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n",
            slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]);
    cpu_physical_memory_write(octx, (uint8_t *) slot_ctx, sizeof(slot_ctx));

    return CC_SUCCESS;
}

static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *trb)
{
    unsigned int slotid;
    slotid = (trb->control >> TRB_CR_SLOTID_SHIFT) & TRB_CR_SLOTID_MASK;
    if (slotid < 1 || slotid > MAXSLOTS) {
        fprintf(stderr, "xhci: bad slot id %d\n", slotid);
        event->ccode = CC_TRB_ERROR;
        return 0;
    } else if (!xhci->slots[slotid-1].enabled) {
        fprintf(stderr, "xhci: slot id %d not enabled\n", slotid);
        event->ccode = CC_SLOT_NOT_ENABLED_ERROR;
        return 0;
    }
    return slotid;
}

static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
{
    target_phys_addr_t ctx;
    uint8_t bw_ctx[MAXPORTS+1];

    DPRINTF("xhci_get_port_bandwidth()\n");

    ctx = xhci_mask64(pctx);

    DPRINTF("xhci: bandwidth context at "TARGET_FMT_plx"\n", ctx);

    /* TODO: actually implement real values here */
    bw_ctx[0] = 0;
    memset(&bw_ctx[1], 80, MAXPORTS); /* 80% */
    cpu_physical_memory_write(ctx, bw_ctx, sizeof(bw_ctx));

    return CC_SUCCESS;
}

static uint32_t rotl(uint32_t v, unsigned count)
{
    count &= 31;
    return (v << count) | (v >> (32 - count));
}


static uint32_t xhci_nec_challenge(uint32_t hi, uint32_t lo)
{
    uint32_t val;
    val = rotl(lo - 0x49434878, 32 - ((hi>>8) & 0x1F));
    val += rotl(lo + 0x49434878, hi & 0x1F);
    val -= rotl(hi ^ 0x49434878, (lo >> 16) & 0x1F);
    return ~val;
}

static void xhci_via_challenge(uint64_t addr)
{
    uint32_t buf[8];
    uint32_t obuf[8];
    target_phys_addr_t paddr = xhci_mask64(addr);

    cpu_physical_memory_read(paddr, (uint8_t *) &buf, 32);

    memcpy(obuf, buf, sizeof(obuf));

    if ((buf[0] & 0xff) == 2) {
        obuf[0] = 0x49932000 + 0x54dc200 * buf[2] + 0x7429b578 * buf[3];
        obuf[0] |=  (buf[2] * buf[3]) & 0xff;
        obuf[1] = 0x0132bb37 + 0xe89 * buf[2] + 0xf09 * buf[3];
        obuf[2] = 0x0066c2e9 + 0x2091 * buf[2] + 0x19bd * buf[3];
        obuf[3] = 0xd5281342 + 0x2cc9691 * buf[2] + 0x2367662 * buf[3];
        obuf[4] = 0x0123c75c + 0x1595 * buf[2] + 0x19ec * buf[3];
        obuf[5] = 0x00f695de + 0x26fd * buf[2] + 0x3e9 * buf[3];
        obuf[6] = obuf[2] ^ obuf[3] ^ 0x29472956;
        obuf[7] = obuf[2] ^ obuf[3] ^ 0x65866593;
    }

    cpu_physical_memory_write(paddr, (uint8_t *) &obuf, 32);
}

static void xhci_process_commands(XHCIState *xhci)
{
    XHCITRB trb;
    TRBType type;
    XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
    target_phys_addr_t addr;
    unsigned int i, slotid = 0;

    DPRINTF("xhci_process_commands()\n");
    if (!xhci_running(xhci)) {
        DPRINTF("xhci_process_commands() called while xHC stopped or paused\n");
        return;
    }

    xhci->crcr_low |= CRCR_CRR;

    while ((type = xhci_ring_fetch(xhci, &xhci->cmd_ring, &trb, &addr))) {
        event.ptr = addr;
        switch (type) {
        case CR_ENABLE_SLOT:
            for (i = 0; i < MAXSLOTS; i++) {
                if (!xhci->slots[i].enabled) {
                    break;
                }
            }
            if (i >= MAXSLOTS) {
                fprintf(stderr, "xhci: no device slots available\n");
                event.ccode = CC_NO_SLOTS_ERROR;
            } else {
                slotid = i+1;
                event.ccode = xhci_enable_slot(xhci, slotid);
            }
            break;
        case CR_DISABLE_SLOT:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                event.ccode = xhci_disable_slot(xhci, slotid);
            }
            break;
        case CR_ADDRESS_DEVICE:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                event.ccode = xhci_address_slot(xhci, slotid, trb.parameter,
                                                trb.control & TRB_CR_BSR);
            }
            break;
        case CR_CONFIGURE_ENDPOINT:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                event.ccode = xhci_configure_slot(xhci, slotid, trb.parameter,
                                                  trb.control & TRB_CR_DC);
            }
            break;
        case CR_EVALUATE_CONTEXT:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                event.ccode = xhci_evaluate_slot(xhci, slotid, trb.parameter);
            }
            break;
        case CR_STOP_ENDPOINT:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT)
                    & TRB_CR_EPID_MASK;
                event.ccode = xhci_stop_ep(xhci, slotid, epid);
            }
            break;
        case CR_RESET_ENDPOINT:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT)
                    & TRB_CR_EPID_MASK;
                event.ccode = xhci_reset_ep(xhci, slotid, epid);
            }
            break;
        case CR_SET_TR_DEQUEUE:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT)
                    & TRB_CR_EPID_MASK;
                event.ccode = xhci_set_ep_dequeue(xhci, slotid, epid,
                                                  trb.parameter);
            }
            break;
        case CR_RESET_DEVICE:
            slotid = xhci_get_slot(xhci, &event, &trb);
            if (slotid) {
                event.ccode = xhci_reset_slot(xhci, slotid);
            }
            break;
        case CR_GET_PORT_BANDWIDTH:
            event.ccode = xhci_get_port_bandwidth(xhci, trb.parameter);
            break;
        case CR_VENDOR_VIA_CHALLENGE_RESPONSE:
            xhci_via_challenge(trb.parameter);
            break;
        case CR_VENDOR_NEC_FIRMWARE_REVISION:
            event.type = 48; /* NEC reply */
            event.length = 0x3025;
            break;
        case CR_VENDOR_NEC_CHALLENGE_RESPONSE:
        {
            uint32_t chi = trb.parameter >> 32;
            uint32_t clo = trb.parameter;
            uint32_t val = xhci_nec_challenge(chi, clo);
            event.length = val & 0xFFFF;
            event.epid = val >> 16;
            slotid = val >> 24;
            event.type = 48; /* NEC reply */
        }
        break;
        default:
            fprintf(stderr, "xhci: unimplemented command %d\n", type);
            event.ccode = CC_TRB_ERROR;
            break;
        }
        event.slotid = slotid;
        xhci_event(xhci, &event);
    }
}

static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
{
    int nr = port->port.index + 1;

    port->portsc = PORTSC_PP;
    if (port->port.dev && !is_detach) {
        port->portsc |= PORTSC_CCS;
        switch (port->port.dev->speed) {
        case USB_SPEED_LOW:
            port->portsc |= PORTSC_SPEED_LOW;
            break;
        case USB_SPEED_FULL:
            port->portsc |= PORTSC_SPEED_FULL;
            break;
        case USB_SPEED_HIGH:
            port->portsc |= PORTSC_SPEED_HIGH;
            break;
        }
    }

    if (xhci_running(xhci)) {
        port->portsc |= PORTSC_CSC;
        XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24};
        xhci_event(xhci, &ev);
        DPRINTF("xhci: port change event for port %d\n", nr);
    }
}

static void xhci_reset(void *opaque)
{
    XHCIState *xhci = opaque;
    int i;

    DPRINTF("xhci: full reset\n");
    if (!(xhci->usbsts & USBSTS_HCH)) {
        fprintf(stderr, "xhci: reset while running!\n");
    }

    xhci->usbcmd = 0;
    xhci->usbsts = USBSTS_HCH;
    xhci->dnctrl = 0;
    xhci->crcr_low = 0;
    xhci->crcr_high = 0;
    xhci->dcbaap_low = 0;
    xhci->dcbaap_high = 0;
    xhci->config = 0;
    xhci->devaddr = 2;

    for (i = 0; i < MAXSLOTS; i++) {
        xhci_disable_slot(xhci, i+1);
    }

    for (i = 0; i < MAXPORTS; i++) {
        xhci_update_port(xhci, xhci->ports + i, 0);
    }

    xhci->mfindex = 0;
    xhci->iman = 0;
    xhci->imod = 0;
    xhci->erstsz = 0;
    xhci->erstba_low = 0;
    xhci->erstba_high = 0;
    xhci->erdp_low = 0;
    xhci->erdp_high = 0;

    xhci->er_ep_idx = 0;
    xhci->er_pcs = 1;
    xhci->er_full = 0;
    xhci->ev_buffer_put = 0;
    xhci->ev_buffer_get = 0;
}

static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
{
    DPRINTF("xhci_cap_read(0x%x)\n", reg);

    switch (reg) {
    case 0x00: /* HCIVERSION, CAPLENGTH */
        return 0x01000000 | LEN_CAP;
    case 0x04: /* HCSPARAMS 1 */
        return (MAXPORTS<<24) | (MAXINTRS<<8) | MAXSLOTS;
    case 0x08: /* HCSPARAMS 2 */
        return 0x0000000f;
    case 0x0c: /* HCSPARAMS 3 */
        return 0x00000000;
    case 0x10: /* HCCPARAMS */
#if TARGET_PHYS_ADDR_BITS > 32
        return 0x00081001;
#else
        return 0x00081000;
#endif
    case 0x14: /* DBOFF */
        return OFF_DOORBELL;
    case 0x18: /* RTSOFF */
        return OFF_RUNTIME;

    /* extended capabilities */
    case 0x20: /* Supported Protocol:00 */
#if USB3_PORTS > 0
        return 0x02000402; /* USB 2.0 */
#else
        return 0x02000002; /* USB 2.0 */
#endif
    case 0x24: /* Supported Protocol:04 */
        return 0x20425455; /* "USB " */
    case 0x28: /* Supported Protocol:08 */
        return 0x00000001 | (USB2_PORTS<<8);
    case 0x2c: /* Supported Protocol:0c */
        return 0x00000000; /* reserved */
#if USB3_PORTS > 0
    case 0x30: /* Supported Protocol:00 */
        return 0x03000002; /* USB 3.0 */
    case 0x34: /* Supported Protocol:04 */
        return 0x20425455; /* "USB " */
    case 0x38: /* Supported Protocol:08 */
        return 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8);
    case 0x3c: /* Supported Protocol:0c */
        return 0x00000000; /* reserved */
#endif
    default:
        fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", reg);
    }
    return 0;
}

static uint32_t xhci_port_read(XHCIState *xhci, uint32_t reg)
{
    uint32_t port = reg >> 4;
    if (port >= MAXPORTS) {
        fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port);
        return 0;
    }

    switch (reg & 0xf) {
    case 0x00: /* PORTSC */
        return xhci->ports[port].portsc;
    case 0x04: /* PORTPMSC */
    case 0x08: /* PORTLI */
        return 0;
    case 0x0c: /* reserved */
    default:
        fprintf(stderr, "xhci_port_read (port %d): reg 0x%x unimplemented\n",
                port, reg);
        return 0;
    }
}

static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
{
    uint32_t port = reg >> 4;
    uint32_t portsc;

    if (port >= MAXPORTS) {
        fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port);
        return;
    }

    switch (reg & 0xf) {
    case 0x00: /* PORTSC */
        portsc = xhci->ports[port].portsc;
        /* write-1-to-clear bits*/
        portsc &= ~(val & (PORTSC_CSC|PORTSC_PEC|PORTSC_WRC|PORTSC_OCC|
                           PORTSC_PRC|PORTSC_PLC|PORTSC_CEC));
        if (val & PORTSC_LWS) {
            /* overwrite PLS only when LWS=1 */
            portsc &= ~(PORTSC_PLS_MASK << PORTSC_PLS_SHIFT);
            portsc |= val & (PORTSC_PLS_MASK << PORTSC_PLS_SHIFT);
        }
        /* read/write bits */
        portsc &= ~(PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE);
        portsc |= (val & (PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE));
        /* write-1-to-start bits */
        if (val & PORTSC_PR) {
            DPRINTF("xhci: port %d reset\n", port);
            usb_device_reset(xhci->ports[port].port.dev);
            portsc |= PORTSC_PRC | PORTSC_PED;
        }
        xhci->ports[port].portsc = portsc;
        break;
    case 0x04: /* PORTPMSC */
    case 0x08: /* PORTLI */
    default:
        fprintf(stderr, "xhci_port_write (port %d): reg 0x%x unimplemented\n",
                port, reg);
    }
}

static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
{
    DPRINTF("xhci_oper_read(0x%x)\n", reg);

    if (reg >= 0x400) {
        return xhci_port_read(xhci, reg - 0x400);
    }

    switch (reg) {
    case 0x00: /* USBCMD */
        return xhci->usbcmd;
    case 0x04: /* USBSTS */
        return xhci->usbsts;
    case 0x08: /* PAGESIZE */
        return 1; /* 4KiB */
    case 0x14: /* DNCTRL */
        return xhci->dnctrl;
    case 0x18: /* CRCR low */
        return xhci->crcr_low & ~0xe;
    case 0x1c: /* CRCR high */
        return xhci->crcr_high;
    case 0x30: /* DCBAAP low */
        return xhci->dcbaap_low;
    case 0x34: /* DCBAAP high */
        return xhci->dcbaap_high;
    case 0x38: /* CONFIG */
        return xhci->config;
    default:
        fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", reg);
    }
    return 0;
}

static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
{
    DPRINTF("xhci_oper_write(0x%x, 0x%08x)\n", reg, val);

    if (reg >= 0x400) {
        xhci_port_write(xhci, reg - 0x400, val);
        return;
    }

    switch (reg) {
    case 0x00: /* USBCMD */
        if ((val & USBCMD_RS) && !(xhci->usbcmd & USBCMD_RS)) {
            xhci_run(xhci);
        } else if (!(val & USBCMD_RS) && (xhci->usbcmd & USBCMD_RS)) {
            xhci_stop(xhci);
        }
        xhci->usbcmd = val & 0xc0f;
        if (val & USBCMD_HCRST) {
            xhci_reset(xhci);
        }
        xhci_irq_update(xhci);
        break;

    case 0x04: /* USBSTS */
        /* these bits are write-1-to-clear */
        xhci->usbsts &= ~(val & (USBSTS_HSE|USBSTS_EINT|USBSTS_PCD|USBSTS_SRE));
        xhci_irq_update(xhci);
        break;

    case 0x14: /* DNCTRL */
        xhci->dnctrl = val & 0xffff;
        break;
    case 0x18: /* CRCR low */
        xhci->crcr_low = (val & 0xffffffcf) | (xhci->crcr_low & CRCR_CRR);
        break;
    case 0x1c: /* CRCR high */
        xhci->crcr_high = val;
        if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) {
            XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED};
            xhci->crcr_low &= ~CRCR_CRR;
            xhci_event(xhci, &event);
            DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low);
        } else {
            target_phys_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val);
            xhci_ring_init(xhci, &xhci->cmd_ring, base);
        }
        xhci->crcr_low &= ~(CRCR_CA | CRCR_CS);
        break;
    case 0x30: /* DCBAAP low */
        xhci->dcbaap_low = val & 0xffffffc0;
        break;
    case 0x34: /* DCBAAP high */
        xhci->dcbaap_high = val;
        break;
    case 0x38: /* CONFIG */
        xhci->config = val & 0xff;
        break;
    default:
        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
    }
}

static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
{
    DPRINTF("xhci_runtime_read(0x%x)\n", reg);

    switch (reg) {
    case 0x00: /* MFINDEX */
        fprintf(stderr, "xhci_runtime_read: MFINDEX not yet implemented\n");
        return xhci->mfindex;
    case 0x20: /* IMAN */
        return xhci->iman;
    case 0x24: /* IMOD */
        return xhci->imod;
    case 0x28: /* ERSTSZ */
        return xhci->erstsz;
    case 0x30: /* ERSTBA low */
        return xhci->erstba_low;
    case 0x34: /* ERSTBA high */
        return xhci->erstba_high;
    case 0x38: /* ERDP low */
        return xhci->erdp_low;
    case 0x3c: /* ERDP high */
        return xhci->erdp_high;
    default:
        fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg);
    }
    return 0;
}

static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
{
    DPRINTF("xhci_runtime_write(0x%x, 0x%08x)\n", reg, val);

    switch (reg) {
    case 0x20: /* IMAN */
        if (val & IMAN_IP) {
            xhci->iman &= ~IMAN_IP;
        }
        xhci->iman &= ~IMAN_IE;
        xhci->iman |= val & IMAN_IE;
        xhci_irq_update(xhci);
        break;
    case 0x24: /* IMOD */
        xhci->imod = val;
        break;
    case 0x28: /* ERSTSZ */
        xhci->erstsz = val & 0xffff;
        break;
    case 0x30: /* ERSTBA low */
        /* XXX NEC driver bug: it doesn't align this to 64 bytes
        xhci->erstba_low = val & 0xffffffc0; */
        xhci->erstba_low = val & 0xfffffff0;
        break;
    case 0x34: /* ERSTBA high */
        xhci->erstba_high = val;
        xhci_er_reset(xhci);
        break;
    case 0x38: /* ERDP low */
        if (val & ERDP_EHB) {
            xhci->erdp_low &= ~ERDP_EHB;
        }
        xhci->erdp_low = (val & ~ERDP_EHB) | (xhci->erdp_low & ERDP_EHB);
        break;
    case 0x3c: /* ERDP high */
        xhci->erdp_high = val;
        xhci_events_update(xhci);
        break;
    default:
        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
    }
}

static uint32_t xhci_doorbell_read(XHCIState *xhci, uint32_t reg)
{
    DPRINTF("xhci_doorbell_read(0x%x)\n", reg);
    /* doorbells always read as 0 */
    return 0;
}

static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val)
{
    DPRINTF("xhci_doorbell_write(0x%x, 0x%08x)\n", reg, val);

    if (!xhci_running(xhci)) {
        fprintf(stderr, "xhci: wrote doorbell while xHC stopped or paused\n");
        return;
    }

    reg >>= 2;

    if (reg == 0) {
        if (val == 0) {
            xhci_process_commands(xhci);
        } else {
            fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", val);
        }
    } else {
        if (reg > MAXSLOTS) {
            fprintf(stderr, "xhci: bad doorbell %d\n", reg);
        } else if (val > 31) {
            fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", reg, val);
        } else {
            xhci_kick_ep(xhci, reg, val);
        }
    }
}

static uint64_t xhci_mem_read(void *ptr, target_phys_addr_t addr,
                              unsigned size)
{
    XHCIState *xhci = ptr;

    /* Only aligned reads are allowed on xHCI */
    if (addr & 3) {
        fprintf(stderr, "xhci_mem_read: Mis-aligned read\n");
        return 0;
    }

    if (addr < LEN_CAP) {
        return xhci_cap_read(xhci, addr);
    } else if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) {
        return xhci_oper_read(xhci, addr - OFF_OPER);
    } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) {
        return xhci_runtime_read(xhci, addr - OFF_RUNTIME);
    } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) {
        return xhci_doorbell_read(xhci, addr - OFF_DOORBELL);
    } else {
        fprintf(stderr, "xhci_mem_read: Bad offset %x\n", (int)addr);
        return 0;
    }
}

static void xhci_mem_write(void *ptr, target_phys_addr_t addr,
                           uint64_t val, unsigned size)
{
    XHCIState *xhci = ptr;

    /* Only aligned writes are allowed on xHCI */
    if (addr & 3) {
        fprintf(stderr, "xhci_mem_write: Mis-aligned write\n");
        return;
    }

    if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) {
        xhci_oper_write(xhci, addr - OFF_OPER, val);
    } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) {
        xhci_runtime_write(xhci, addr - OFF_RUNTIME, val);
    } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) {
        xhci_doorbell_write(xhci, addr - OFF_DOORBELL, val);
    } else {
        fprintf(stderr, "xhci_mem_write: Bad offset %x\n", (int)addr);
    }
}

static const MemoryRegionOps xhci_mem_ops = {
    .read = xhci_mem_read,
    .write = xhci_mem_write,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void xhci_attach(USBPort *usbport)
{
    XHCIState *xhci = usbport->opaque;
    XHCIPort *port = &xhci->ports[usbport->index];

    xhci_update_port(xhci, port, 0);
}

static void xhci_detach(USBPort *usbport)
{
    XHCIState *xhci = usbport->opaque;
    XHCIPort *port = &xhci->ports[usbport->index];

    xhci_update_port(xhci, port, 1);
}

static void xhci_wakeup(USBPort *usbport)
{
    XHCIState *xhci = usbport->opaque;
    XHCIPort *port = &xhci->ports[usbport->index];
    int nr = port->port.index + 1;
    XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24};
    uint32_t pls;

    pls = (port->portsc >> PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK;
    if (pls != 3) {
        return;
    }
    port->portsc |= 0xf << PORTSC_PLS_SHIFT;
    if (port->portsc & PORTSC_PLC) {
        return;
    }
    port->portsc |= PORTSC_PLC;
    xhci_event(xhci, &ev);
}

static void xhci_complete(USBPort *port, USBPacket *packet)
{
    XHCITransfer *xfer = container_of(packet, XHCITransfer, packet);

    xhci_complete_packet(xfer, packet->result);
    xhci_kick_ep(xfer->xhci, xfer->slotid, xfer->epid);
}

static void xhci_child_detach(USBPort *port, USBDevice *child)
{
    FIXME();
}

static USBPortOps xhci_port_ops = {
    .attach   = xhci_attach,
    .detach   = xhci_detach,
    .wakeup   = xhci_wakeup,
    .complete = xhci_complete,
    .child_detach = xhci_child_detach,
};

static int xhci_find_slotid(XHCIState *xhci, USBDevice *dev)
{
    XHCISlot *slot;
    int slotid;

    for (slotid = 1; slotid <= MAXSLOTS; slotid++) {
        slot = &xhci->slots[slotid-1];
        if (slot->devaddr == dev->addr) {
            return slotid;
        }
    }
    return 0;
}

static int xhci_find_epid(USBEndpoint *ep)
{
    if (ep->nr == 0) {
        return 1;
    }
    if (ep->pid == USB_TOKEN_IN) {
        return ep->nr * 2 + 1;
    } else {
        return ep->nr * 2;
    }
}

static void xhci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep)
{
    XHCIState *xhci = container_of(bus, XHCIState, bus);
    int slotid;

    DPRINTF("%s\n", __func__);
    slotid = xhci_find_slotid(xhci, ep->dev);
    if (slotid == 0 || !xhci->slots[slotid-1].enabled) {
        DPRINTF("%s: oops, no slot for dev %d\n", __func__, ep->dev->addr);
        return;
    }
    xhci_kick_ep(xhci, slotid, xhci_find_epid(ep));
}

static USBBusOps xhci_bus_ops = {
    .wakeup_endpoint = xhci_wakeup_endpoint,
};

static void usb_xhci_init(XHCIState *xhci, DeviceState *dev)
{
    int i;

    xhci->usbsts = USBSTS_HCH;

    usb_bus_new(&xhci->bus, &xhci_bus_ops, &xhci->pci_dev.qdev);

    for (i = 0; i < MAXPORTS; i++) {
        memset(&xhci->ports[i], 0, sizeof(xhci->ports[i]));
        usb_register_port(&xhci->bus, &xhci->ports[i].port, xhci, i,
                          &xhci_port_ops,
                          USB_SPEED_MASK_LOW  |
                          USB_SPEED_MASK_FULL |
                          USB_SPEED_MASK_HIGH);
    }
    for (i = 0; i < MAXSLOTS; i++) {
        xhci->slots[i].enabled = 0;
    }

    qemu_register_reset(xhci_reset, xhci);
}

static int usb_xhci_initfn(struct PCIDevice *dev)
{
    int ret;

    XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev, dev);

    xhci->pci_dev.config[PCI_CLASS_PROG] = 0x30;    /* xHCI */
    xhci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
    xhci->pci_dev.config[PCI_CACHE_LINE_SIZE] = 0x10;
    xhci->pci_dev.config[0x60] = 0x30; /* release number */

    usb_xhci_init(xhci, &dev->qdev);

    xhci->irq = xhci->pci_dev.irq[0];

    memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci,
                          "xhci", LEN_REGS);
    pci_register_bar(&xhci->pci_dev, 0,
                     PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
                     &xhci->mem);

    ret = pcie_cap_init(&xhci->pci_dev, 0xa0, PCI_EXP_TYPE_ENDPOINT, 0);
    assert(ret >= 0);

    if (xhci->msi) {
        ret = msi_init(&xhci->pci_dev, 0x70, 1, true, false);
        assert(ret >= 0);
    }

    return 0;
}

static void xhci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val,
                              int len)
{
    XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev, dev);

    pci_default_write_config(dev, addr, val, len);
    if (xhci->msi) {
        msi_write_config(dev, addr, val, len);
    }
}

static const VMStateDescription vmstate_xhci = {
    .name = "xhci",
    .unmigratable = 1,
};

static Property xhci_properties[] = {
    DEFINE_PROP_UINT32("msi", XHCIState, msi, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void xhci_class_init(ObjectClass *klass, void *data)
{
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->vmsd    = &vmstate_xhci;
    dc->props   = xhci_properties;
    k->init         = usb_xhci_initfn;
    k->vendor_id    = PCI_VENDOR_ID_NEC;
    k->device_id    = PCI_DEVICE_ID_NEC_UPD720200;
    k->class_id     = PCI_CLASS_SERIAL_USB;
    k->revision     = 0x03;
    k->is_express   = 1;
    k->config_write = xhci_write_config;
}

static TypeInfo xhci_info = {
    .name          = "nec-usb-xhci",
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(XHCIState),
    .class_init    = xhci_class_init,
};

static void xhci_register_types(void)
{
    type_register_static(&xhci_info);
}

type_init(xhci_register_types)
