Revision 7c605a23 hw/usb-xhci.c

b/hw/usb-xhci.c
307 307
typedef struct XHCITransfer {
308 308
    XHCIState *xhci;
309 309
    USBPacket packet;
310
    bool running;
310
    bool running_async;
311
    bool running_retry;
311 312
    bool cancelled;
312 313
    bool complete;
313 314
    bool backgrounded;
......
338 339
    unsigned int next_xfer;
339 340
    unsigned int comp_xfer;
340 341
    XHCITransfer transfers[TD_QUEUE];
342
    XHCITransfer *retry;
341 343
    bool bg_running;
342 344
    bool bg_updating;
343 345
    unsigned int next_bg;
......
915 917
    xferi = epctx->next_xfer;
916 918
    for (i = 0; i < TD_QUEUE; i++) {
917 919
        XHCITransfer *t = &epctx->transfers[xferi];
918
        if (t->running) {
920
        if (t->running_async) {
921
            usb_cancel_packet(&t->packet);
922
            t->running_async = 0;
919 923
            t->cancelled = 1;
920
            /* libusb_cancel_transfer(t->usbxfer) */
921 924
            DPRINTF("xhci: cancelling transfer %d, waiting for it to complete...\n", i);
922 925
            killed++;
923 926
        }
927
        if (t->running_retry) {
928
            t->running_retry = 0;
929
            epctx->retry = NULL;
930
        }
924 931
        if (t->backgrounded) {
925 932
            t->backgrounded = 0;
926 933
        }
......
941 948
        xferi = epctx->next_bg;
942 949
        for (i = 0; i < BG_XFERS; i++) {
943 950
            XHCITransfer *t = &epctx->bg_transfers[xferi];
944
            if (t->running) {
951
            if (t->running_async) {
952
                usb_cancel_packet(&t->packet);
953
                t->running_async = 0;
945 954
                t->cancelled = 1;
946
                /* libusb_cancel_transfer(t->usbxfer); */
947 955
                DPRINTF("xhci: cancelling bg transfer %d, waiting for it to complete...\n", i);
948 956
                killed++;
949 957
            }
......
1409 1417
static int xhci_complete_packet(XHCITransfer *xfer, int ret)
1410 1418
{
1411 1419
    if (ret == USB_RET_ASYNC) {
1412
        xfer->running = 1;
1420
        xfer->running_async = 1;
1421
        xfer->running_retry = 0;
1422
        xfer->complete = 0;
1423
        xfer->cancelled = 0;
1424
        return 0;
1425
    } else if (ret == USB_RET_NAK) {
1426
        xfer->running_async = 0;
1427
        xfer->running_retry = 1;
1413 1428
        xfer->complete = 0;
1414 1429
        xfer->cancelled = 0;
1415 1430
        return 0;
1416 1431
    } else {
1417
        xfer->running = 0;
1432
        xfer->running_async = 0;
1433
        xfer->running_retry = 0;
1418 1434
        xfer->complete = 1;
1419 1435
    }
1420 1436

  
......
1529 1545
                                    wValue, wIndex, wLength, xfer->data);
1530 1546

  
1531 1547
    xhci_complete_packet(xfer, ret);
1532
    if (!xfer->running) {
1548
    if (!xfer->running_async && !xfer->running_retry) {
1533 1549
        xhci_kick_ep(xhci, xfer->slotid, xfer->epid);
1534 1550
    }
1535 1551
    return 0;
......
1596 1612
    ret = usb_handle_packet(dev, &xfer->packet);
1597 1613

  
1598 1614
    xhci_complete_packet(xfer, ret);
1599
    if (!xfer->running) {
1615
    if (!xfer->running_async && !xfer->running_retry) {
1600 1616
        xhci_kick_ep(xhci, xfer->slotid, xfer->epid);
1601 1617
    }
1602 1618
    return 0;
......
1667 1683
        return;
1668 1684
    }
1669 1685

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

  
1691
        DPRINTF("xhci: retry nack'ed transfer ...\n");
1692
        assert(xfer->running_retry);
1693
        xhci_setup_packet(xfer, xfer->packet.ep->dev);
1694
        result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
1695
        if (result == USB_RET_NAK) {
1696
            DPRINTF("xhci: ... xfer still nacked\n");
1697
            return;
1698
        }
1699
        DPRINTF("xhci: ... result %d\n", result);
1700
        xhci_complete_packet(xfer, result);
1701
        assert(!xfer->running_retry);
1702
        epctx->retry = NULL;
1703
    }
1704

  
1670 1705
    if (epctx->state == EP_HALTED) {
1671 1706
        DPRINTF("xhci: ep halted, not running schedule\n");
1672 1707
        return;
......
1676 1711

  
1677 1712
    while (1) {
1678 1713
        XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer];
1679
        if (xfer->running || xfer->backgrounded) {
1680
            DPRINTF("xhci: ep is busy\n");
1714
        if (xfer->running_async || xfer->running_retry || xfer->backgrounded) {
1715
            DPRINTF("xhci: ep is busy (#%d,%d,%d,%d)\n",
1716
                    epctx->next_xfer, xfer->running_async,
1717
                    xfer->running_retry, xfer->backgrounded);
1681 1718
            break;
1719
        } else {
1720
            DPRINTF("xhci: ep: using #%d\n", epctx->next_xfer);
1682 1721
        }
1683 1722
        length = xhci_ring_chain_length(xhci, &epctx->ring);
1684 1723
        if (length < 0) {
......
1725 1764
            DPRINTF("xhci: ep halted, stopping schedule\n");
1726 1765
            break;
1727 1766
        }
1767
        if (xfer->running_retry) {
1768
            DPRINTF("xhci: xfer nacked, stopping schedule\n");
1769
            epctx->retry = xfer;
1770
            break;
1771
        }
1728 1772

  
1729 1773
        /*
1730 1774
         * Qemu usb can't handle multiple in-flight xfers.
......
2739 2783
    .child_detach = xhci_child_detach,
2740 2784
};
2741 2785

  
2786
static int xhci_find_slotid(XHCIState *xhci, USBDevice *dev)
2787
{
2788
    XHCISlot *slot;
2789
    int slotid;
2790

  
2791
    for (slotid = 1; slotid <= MAXSLOTS; slotid++) {
2792
        slot = &xhci->slots[slotid-1];
2793
        if (slot->devaddr == dev->addr) {
2794
            return slotid;
2795
        }
2796
    }
2797
    return 0;
2798
}
2799

  
2800
static int xhci_find_epid(USBEndpoint *ep)
2801
{
2802
    if (ep->nr == 0) {
2803
        return 1;
2804
    }
2805
    if (ep->pid == USB_TOKEN_IN) {
2806
        return ep->nr * 2 + 1;
2807
    } else {
2808
        return ep->nr * 2;
2809
    }
2810
}
2811

  
2812
static void xhci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep)
2813
{
2814
    XHCIState *xhci = container_of(bus, XHCIState, bus);
2815
    int slotid;
2816

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

  
2742 2826
static USBBusOps xhci_bus_ops = {
2827
    .wakeup_endpoint = xhci_wakeup_endpoint,
2743 2828
};
2744 2829

  
2745 2830
static void usb_xhci_init(XHCIState *xhci, DeviceState *dev)

Also available in: Unified diff