Revision ccaf87a0 hw/usb/hcd-xhci.c

b/hw/usb/hcd-xhci.c
363 363
typedef struct XHCISlot {
364 364
    bool enabled;
365 365
    dma_addr_t ctx;
366
    unsigned int port;
366
    USBPort *uport;
367 367
    unsigned int devaddr;
368 368
    XHCIEPContext * eps[31];
369 369
} XHCISlot;
......
1230 1230
        ep |= 0x80;
1231 1231
    }
1232 1232

  
1233
    dev = xhci->ports[xhci->slots[slotid-1].port-1].uport->dev;
1233
    dev = xhci->slots[slotid-1].uport->dev;
1234 1234
    if (!dev) {
1235 1235
        return CC_USB_TRANSACTION_ERROR;
1236 1236
    }
......
1412 1412
static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer,
1413 1413
                       XHCIEPContext *epctx);
1414 1414

  
1415
static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr)
1416
{
1417
    if (!(port->portsc & PORTSC_PED)) {
1418
        return NULL;
1419
    }
1420
    return usb_find_device(port->uport, addr);
1421
}
1422

  
1423 1415
static int xhci_setup_packet(XHCITransfer *xfer)
1424 1416
{
1425 1417
    XHCIState *xhci = xfer->xhci;
1426
    XHCIPort *port;
1427 1418
    USBDevice *dev;
1428 1419
    USBEndpoint *ep;
1429 1420
    int dir;
......
1434 1425
        ep = xfer->packet.ep;
1435 1426
        dev = ep->dev;
1436 1427
    } else {
1437
        port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1];
1438
        dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr);
1439
        if (!dev) {
1440
            fprintf(stderr, "xhci: slot %d port %d has no device\n",
1441
                    xfer->slotid, xhci->slots[xfer->slotid-1].port);
1428
        if (!xhci->slots[xfer->slotid-1].uport) {
1429
            fprintf(stderr, "xhci: slot %d has no device\n",
1430
                    xfer->slotid);
1442 1431
            return -1;
1443 1432
        }
1433
        dev = xhci->slots[xfer->slotid-1].uport->dev;
1444 1434
        ep = usb_ep_get(dev, dir, xfer->epid >> 1);
1445 1435
    }
1446 1436

  
......
1772 1762
    trace_usb_xhci_slot_enable(slotid);
1773 1763
    assert(slotid >= 1 && slotid <= MAXSLOTS);
1774 1764
    xhci->slots[slotid-1].enabled = 1;
1775
    xhci->slots[slotid-1].port = 0;
1765
    xhci->slots[slotid-1].uport = NULL;
1776 1766
    memset(xhci->slots[slotid-1].eps, 0, sizeof(XHCIEPContext*)*31);
1777 1767

  
1778 1768
    return CC_SUCCESS;
......
1795 1785
    return CC_SUCCESS;
1796 1786
}
1797 1787

  
1788
static USBPort *xhci_lookup_uport(XHCIState *xhci, uint32_t *slot_ctx)
1789
{
1790
    USBPort *uport;
1791
    char path[32];
1792
    int i, pos, port;
1793

  
1794
    port = (slot_ctx[1]>>16) & 0xFF;
1795
    port = xhci->ports[port-1].uport->index+1;
1796
    pos = snprintf(path, sizeof(path), "%d", port);
1797
    for (i = 0; i < 5; i++) {
1798
        port = (slot_ctx[0] >> 4*i) & 0x0f;
1799
        if (!port) {
1800
            break;
1801
        }
1802
        pos += snprintf(path + pos, sizeof(path) - pos, ".%d", port);
1803
    }
1804

  
1805
    QTAILQ_FOREACH(uport, &xhci->bus.used, next) {
1806
        if (strcmp(uport->path, path) == 0) {
1807
            return uport;
1808
        }
1809
    }
1810
    return NULL;
1811
}
1812

  
1798 1813
static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
1799 1814
                                  uint64_t pictx, bool bsr)
1800 1815
{
1801 1816
    XHCISlot *slot;
1817
    USBPort *uport;
1802 1818
    USBDevice *dev;
1803 1819
    dma_addr_t ictx, octx, dcbaap;
1804 1820
    uint64_t poctx;
1805 1821
    uint32_t ictl_ctx[2];
1806 1822
    uint32_t slot_ctx[4];
1807 1823
    uint32_t ep0_ctx[5];
1808
    unsigned int port;
1809 1824
    int i;
1810 1825
    TRBCCode res;
1811 1826

  
......
1837 1852
    DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n",
1838 1853
            ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);
1839 1854

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

  
1843
    if (port < 1 || port > xhci->numports) {
1844
        fprintf(stderr, "xhci: bad port %d\n", port);
1855
    uport = xhci_lookup_uport(xhci, slot_ctx);
1856
    if (uport == NULL) {
1857
        fprintf(stderr, "xhci: port not found\n");
1845 1858
        return CC_TRB_ERROR;
1846
    } else if (!dev) {
1847
        fprintf(stderr, "xhci: port %d not connected\n", port);
1859
    }
1860

  
1861
    dev = uport->dev;
1862
    if (!dev) {
1863
        fprintf(stderr, "xhci: port %s not connected\n", uport->path);
1848 1864
        return CC_USB_TRANSACTION_ERROR;
1849 1865
    }
1850 1866

  
1851 1867
    for (i = 0; i < MAXSLOTS; i++) {
1852
        if (xhci->slots[i].port == port) {
1853
            fprintf(stderr, "xhci: port %d already assigned to slot %d\n",
1854
                    port, i+1);
1868
        if (xhci->slots[i].uport == uport) {
1869
            fprintf(stderr, "xhci: port %s already assigned to slot %d\n",
1870
                    uport->path, i+1);
1855 1871
            return CC_TRB_ERROR;
1856 1872
        }
1857 1873
    }
1858 1874

  
1859 1875
    slot = &xhci->slots[slotid-1];
1860
    slot->port = port;
1876
    slot->uport = uport;
1861 1877
    slot->ctx = octx;
1862 1878

  
1863 1879
    if (bsr) {
......
2821 2837
    xhci_kick_ep(xfer->xhci, xfer->slotid, xfer->epid);
2822 2838
}
2823 2839

  
2824
static void xhci_child_detach(USBPort *port, USBDevice *child)
2840
static void xhci_child_detach(USBPort *uport, USBDevice *child)
2825 2841
{
2826
    FIXME();
2842
    USBBus *bus = usb_bus_from_device(child);
2843
    XHCIState *xhci = container_of(bus, XHCIState, bus);
2844
    int i;
2845

  
2846
    for (i = 0; i < MAXSLOTS; i++) {
2847
        if (xhci->slots[i].uport == uport) {
2848
            xhci->slots[i].uport = NULL;
2849
        }
2850
    }
2827 2851
}
2828 2852

  
2829 2853
static USBPortOps xhci_port_ops = {

Also available in: Unified diff