static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,

                                  uint64_t pictx, bool bsr)

{

    XHCISlot *slot;

    USBPort *uport;

    USBDevice *dev;

    dma_addr_t ictx, octx, dcbaap;

    uint64_t poctx;

    uint32_t ictl_ctx[2];

    uint32_t slot_ctx[4];

    uint32_t ep0_ctx[5];

    int i;

    TRBCCode res;



    assert(slotid >= 1 && slotid <= xhci->numslots);



    dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);

    poctx = ldq_le_pci_dma(PCI_DEVICE(xhci), dcbaap + 8 * slotid);

    ictx = xhci_mask64(pictx);

    octx = xhci_mask64(poctx);



    DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx);

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



    xhci_dma_read_u32s(xhci, ictx, 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;

    }



    xhci_dma_read_u32s(xhci, ictx+32, slot_ctx, sizeof(slot_ctx));

    xhci_dma_read_u32s(xhci, ictx+64, 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]);



    uport = xhci_lookup_uport(xhci, slot_ctx);

    if (uport == NULL) {

        fprintf(stderr, "xhci: port not found\n");

        return CC_TRB_ERROR;

    }

    trace_usb_xhci_slot_address(slotid, uport->path);



    dev = uport->dev;

    if (!dev) {

        fprintf(stderr, "xhci: port %s not connected\n", uport->path);

        return CC_USB_TRANSACTION_ERROR;

    }



    for (i = 0; i < xhci->numslots; i++) {

        if (i == slotid-1) {

            continue;

        }

        if (xhci->slots[i].uport == uport) {

            fprintf(stderr, "xhci: port %s already assigned to slot %d\n",

                    uport->path, i+1);

            return CC_TRB_ERROR;

        }

    }



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

    slot->uport = uport;

    slot->ctx = octx;



    if (bsr) {

        slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;

    } else {

        USBPacket p;

        uint8_t buf[1];



        slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid;

        usb_device_reset(dev);

        memset(&p, 0, sizeof(p));

        usb_packet_addbuf(&p, buf, sizeof(buf));

        usb_packet_setup(&p, USB_TOKEN_OUT,

                         usb_ep_get(dev, USB_TOKEN_OUT, 0), 0,

                         0, false, false);

        usb_device_handle_control(dev, &p,

                                  DeviceOutRequest | USB_REQ_SET_ADDRESS,

                                  slotid, 0, 0, NULL);

        assert(p.status != USB_RET_ASYNC);

    }



    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]);



    xhci_dma_write_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx));

    xhci_dma_write_u32s(xhci, octx+32, ep0_ctx, sizeof(ep0_ctx));



    xhci->slots[slotid-1].addressed = 1;

    return res;

}

static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,

                                  uint64_t pictx, bool bsr)

{

    XHCISlot *slot;

    USBPort *uport;

    USBDevice *dev;

    dma_addr_t ictx, octx, dcbaap;

    uint64_t poctx;

    uint32_t ictl_ctx[2];

    uint32_t slot_ctx[4];

    uint32_t ep0_ctx[5];

    int i;

    TRBCCode res;



    assert(slotid >= 1 && slotid <= xhci->numslots);



    dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);

    poctx = ldq_le_pci_dma(PCI_DEVICE(xhci), dcbaap + 8 * slotid);

    ictx = xhci_mask64(pictx);

    octx = xhci_mask64(poctx);



    DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx);

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



    xhci_dma_read_u32s(xhci, ictx, 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;

    }



    xhci_dma_read_u32s(xhci, ictx+32, slot_ctx, sizeof(slot_ctx));

    xhci_dma_read_u32s(xhci, ictx+64, 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]);



    uport = xhci_lookup_uport(xhci, slot_ctx);

    if (uport == NULL) {

        fprintf(stderr, "xhci: port not found\n");

        return CC_TRB_ERROR;

    }

    trace_usb_xhci_slot_address(slotid, uport->path);



    dev = uport->dev;

    if (!dev) {

        fprintf(stderr, "xhci: port %s not connected\n", uport->path);

        return CC_USB_TRANSACTION_ERROR;

    }



    for (i = 0; i < xhci->numslots; i++) {

        if (i == slotid-1) {

            continue;

        }

        if (xhci->slots[i].uport == uport) {

            fprintf(stderr, "xhci: port %s already assigned to slot %d\n",

                    uport->path, i+1);

            return CC_TRB_ERROR;

        }

    }



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

    slot->uport = uport;

    slot->ctx = octx;



    if (bsr) {

        slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;

    } else {

        USBPacket p;

        uint8_t buf[1];



        slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid;

        usb_device_reset(dev);

        memset(&p, 0, sizeof(p));

        usb_packet_addbuf(&p, buf, sizeof(buf));

        usb_packet_setup(&p, USB_TOKEN_OUT,

                         usb_ep_get(dev, USB_TOKEN_OUT, 0), 0,

                         0, false, false);

        usb_device_handle_control(dev, &p,

                                  DeviceOutRequest | USB_REQ_SET_ADDRESS,

                                  slotid, 0, 0, NULL);

        assert(p.status != USB_RET_ASYNC);

    }



    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]);



    xhci_dma_write_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx));

    xhci_dma_write_u32s(xhci, octx+32, ep0_ctx, sizeof(ep0_ctx));



    xhci->slots[slotid-1].addressed = 1;

    return res;

}

    if (!dev) {
static TRBCCode FUNC_0(XHCIState *xhci, unsigned int slotid,

                                  uint64_t pictx, bool bsr)

{

    XHCISlot *slot;

    USBPort *uport;

    USBDevice *dev;

    dma_addr_t ictx, octx, dcbaap;

    uint64_t poctx;

    uint32_t ictl_ctx[2];

    uint32_t slot_ctx[4];

    uint32_t ep0_ctx[5];

    int VAR_0;

    TRBCCode res;



    assert(slotid >= 1 && slotid <= xhci->numslots);



    dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);

    poctx = ldq_le_pci_dma(PCI_DEVICE(xhci), dcbaap + 8 * slotid);

    ictx = xhci_mask64(pictx);

    octx = xhci_mask64(poctx);



    DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx);

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



    xhci_dma_read_u32s(xhci, ictx, 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;

    }



    xhci_dma_read_u32s(xhci, ictx+32, slot_ctx, sizeof(slot_ctx));

    xhci_dma_read_u32s(xhci, ictx+64, 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]);



    uport = xhci_lookup_uport(xhci, slot_ctx);

    if (uport == NULL) {

        fprintf(stderr, "xhci: port not found\n");

        return CC_TRB_ERROR;

    }

    trace_usb_xhci_slot_address(slotid, uport->path);



    dev = uport->dev;

    if (!dev) {

        fprintf(stderr, "xhci: port %s not connected\n", uport->path);

        return CC_USB_TRANSACTION_ERROR;

    }



    for (VAR_0 = 0; VAR_0 < xhci->numslots; VAR_0++) {

        if (VAR_0 == slotid-1) {

            continue;

        }

        if (xhci->slots[VAR_0].uport == uport) {

            fprintf(stderr, "xhci: port %s already assigned to slot %d\n",

                    uport->path, VAR_0+1);

            return CC_TRB_ERROR;

        }

    }



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

    slot->uport = uport;

    slot->ctx = octx;



    if (bsr) {

        slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;

    } else {

        USBPacket p;

        uint8_t buf[1];



        slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid;

        usb_device_reset(dev);

        memset(&p, 0, sizeof(p));

        usb_packet_addbuf(&p, buf, sizeof(buf));

        usb_packet_setup(&p, USB_TOKEN_OUT,

                         usb_ep_get(dev, USB_TOKEN_OUT, 0), 0,

                         0, false, false);

        usb_device_handle_control(dev, &p,

                                  DeviceOutRequest | USB_REQ_SET_ADDRESS,

                                  slotid, 0, 0, NULL);

        assert(p.status != USB_RET_ASYNC);

    }



    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]);



    xhci_dma_write_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx));

    xhci_dma_write_u32s(xhci, octx+32, ep0_ctx, sizeof(ep0_ctx));



    xhci->slots[slotid-1].addressed = 1;

    return res;

}

static TRBCCode FUNC_0(XHCIState *xhci, unsigned int slotid,
uint64_t pictx, bool bsr)
{ XHCISlot *slot; USBPort *uport; USBDevice *dev; dma_addr_t ictx, octx, dcbaap; uint64_t poctx; uint32_t ictl_ctx[2]; uint32_t slot_ctx[4]; uint32_t ep0_ctx[5]; int VAR_0; TRBCCode res; assert(slotid >= 1 && slotid <= xhci->numslots); dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); poctx = ldq_le_pci_dma(PCI_DEVICE(xhci), dcbaap + 8 * slotid); ictx = xhci_mask64(pictx); octx = xhci_mask64(poctx); DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx); DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx); xhci_dma_read_u32s(xhci, ictx, 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; } xhci_dma_read_u32s(xhci, ictx+32, slot_ctx, sizeof(slot_ctx)); xhci_dma_read_u32s(xhci, ictx+64, 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]); uport = xhci_lookup_uport(xhci, slot_ctx); if (uport == NULL) { fprintf(stderr, "xhci: port not found\n"); return CC_TRB_ERROR; } trace_usb_xhci_slot_address(slotid, uport->path); dev = uport->dev; if (!dev) { fprintf(stderr, "xhci: port %s not connected\n", uport->path); return CC_USB_TRANSACTION_ERROR; } for (VAR_0 = 0; VAR_0 < xhci->numslots; VAR_0++) { if (VAR_0 == slotid-1) { continue; } if (xhci->slots[VAR_0].uport == uport) { fprintf(stderr, "xhci: port %s already assigned to slot %d\n",
uport->path, VAR_0+1); return CC_TRB_ERROR; } } slot = &xhci->slots[slotid-1]; slot->uport = uport; slot->ctx = octx; if (bsr) { slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT; } else { USBPacket p; uint8_t buf[1]; slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slotid; usb_device_reset(dev); memset(&p, 0, sizeof(p)); usb_packet_addbuf(&p, buf, sizeof(buf)); usb_packet_setup(&p, USB_TOKEN_OUT,
usb_ep_get(dev, USB_TOKEN_OUT, 0), 0,
0, false, false); usb_device_handle_control(dev, &p,
DeviceOutRequest | USB_REQ_SET_ADDRESS,
slotid, 0, 0, NULL); assert(p.status != USB_RET_ASYNC); } 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]); xhci_dma_write_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx)); xhci_dma_write_u32s(xhci, octx+32, ep0_ctx, sizeof(ep0_ctx)); xhci->slots[slotid-1].addressed = 1; return res; }