Revision 9bc3a3a2

b/hw/usb/hcd-ehci.c
365 365
    uint32_t seen;
366 366
    uint64_t ts;
367 367
    int async;
368
    int revalidate;
368 369

  
369 370
    /* cached data from guest - needs to be flushed
370 371
     * when guest removes an entry (doorbell, handshake sequence)
......
775 776
    return NULL;
776 777
}
777 778

  
778
static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush)
779
static void ehci_queues_tag_unused_async(EHCIState *ehci)
780
{
781
    EHCIQueue *q;
782

  
783
    QTAILQ_FOREACH(q, &ehci->aqueues, next) {
784
        if (!q->seen) {
785
            q->revalidate = 1;
786
        }
787
    }
788
}
789

  
790
static void ehci_queues_rip_unused(EHCIState *ehci, int async)
779 791
{
780 792
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
781 793
    uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4;
......
787 799
            q->ts = ehci->last_run_ns;
788 800
            continue;
789 801
        }
790
        if (!flush && ehci->last_run_ns < q->ts + maxage) {
802
        if (ehci->last_run_ns < q->ts + maxage) {
791 803
            continue;
792 804
        }
793 805
        ehci_free_queue(q);
......
1631 1643
        ehci_set_usbsts(ehci, USBSTS_REC);
1632 1644
    }
1633 1645

  
1634
    ehci_queues_rip_unused(ehci, async, 0);
1646
    ehci_queues_rip_unused(ehci, async);
1635 1647

  
1636 1648
    /*  Find the head of the list (4.9.1.1) */
1637 1649
    for(i = 0; i < MAX_QH; i++) {
......
1716 1728
    EHCIPacket *p;
1717 1729
    uint32_t entry, devaddr;
1718 1730
    EHCIQueue *q;
1731
    EHCIqh qh;
1719 1732

  
1720 1733
    entry = ehci_get_fetch_addr(ehci, async);
1721 1734
    q = ehci_find_queue_by_qh(ehci, entry, async);
......
1733 1746
    }
1734 1747

  
1735 1748
    get_dwords(ehci, NLPTR_GET(q->qhaddr),
1736
               (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2);
1749
               (uint32_t *) &qh, sizeof(EHCIqh) >> 2);
1750
    if (q->revalidate && (q->qh.epchar      != qh.epchar ||
1751
                          q->qh.epcap       != qh.epcap  ||
1752
                          q->qh.current_qtd != qh.current_qtd)) {
1753
        ehci_free_queue(q);
1754
        q = ehci_alloc_queue(ehci, entry, async);
1755
        q->seen++;
1756
        p = NULL;
1757
    }
1758
    q->qh = qh;
1759
    q->revalidate = 0;
1737 1760
    ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh);
1738 1761

  
1739 1762
    devaddr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR);
......
2228 2251
         */
2229 2252
        if (ehci->usbcmd & USBCMD_IAAD) {
2230 2253
            /* Remove all unseen qhs from the async qhs queue */
2231
            ehci_queues_rip_unused(ehci, async, 1);
2254
            ehci_queues_tag_unused_async(ehci);
2232 2255
            DPRINTF("ASYNC: doorbell request acknowledged\n");
2233 2256
            ehci->usbcmd &= ~USBCMD_IAAD;
2234 2257
            ehci_set_interrupt(ehci, USBSTS_IAA);
......
2281 2304
        ehci_set_fetch_addr(ehci, async,entry);
2282 2305
        ehci_set_state(ehci, async, EST_FETCHENTRY);
2283 2306
        ehci_advance_state(ehci, async);
2284
        ehci_queues_rip_unused(ehci, async, 0);
2307
        ehci_queues_rip_unused(ehci, async);
2285 2308
        break;
2286 2309

  
2287 2310
    default:

Also available in: Unified diff