Revision df5d5c5c

b/hw/usb-ehci.c
347 347
struct EHCIQueue {
348 348
    EHCIState *ehci;
349 349
    QTAILQ_ENTRY(EHCIQueue) next;
350
    bool async_schedule;
351 350
    uint32_t seen;
352 351
    uint64_t ts;
353 352

  
......
367 366
    int usb_status;
368 367
};
369 368

  
369
typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead;
370

  
370 371
struct EHCIState {
371 372
    PCIDevice dev;
372 373
    USBBus bus;
......
410 411
    USBPort ports[NB_PORTS];
411 412
    USBPort *companion_ports[NB_PORTS];
412 413
    uint32_t usbsts_pending;
413
    QTAILQ_HEAD(, EHCIQueue) queues;
414
    EHCIQueueHead aqueues;
415
    EHCIQueueHead pqueues;
414 416

  
415 417
    uint32_t a_fetch_addr;   // which address to look at next
416 418
    uint32_t p_fetch_addr;   // which address to look at next
......
660 662

  
661 663
static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, int async)
662 664
{
665
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
663 666
    EHCIQueue *q;
664 667

  
665 668
    q = g_malloc0(sizeof(*q));
666 669
    q->ehci = ehci;
667
    q->async_schedule = async;
668
    QTAILQ_INSERT_HEAD(&ehci->queues, q, next);
670
    QTAILQ_INSERT_HEAD(head, q, next);
669 671
    trace_usb_ehci_queue_action(q, "alloc");
670 672
    return q;
671 673
}
672 674

  
673
static void ehci_free_queue(EHCIQueue *q)
675
static void ehci_free_queue(EHCIQueue *q, int async)
674 676
{
677
    EHCIQueueHead *head = async ? &q->ehci->aqueues : &q->ehci->pqueues;
675 678
    trace_usb_ehci_queue_action(q, "free");
676 679
    if (q->async == EHCI_ASYNC_INFLIGHT) {
677 680
        usb_cancel_packet(&q->packet);
678 681
    }
679
    QTAILQ_REMOVE(&q->ehci->queues, q, next);
682
    QTAILQ_REMOVE(head, q, next);
680 683
    g_free(q);
681 684
}
682 685

  
683
static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr)
686
static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr,
687
                                        int async)
684 688
{
689
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
685 690
    EHCIQueue *q;
686 691

  
687
    QTAILQ_FOREACH(q, &ehci->queues, next) {
692
    QTAILQ_FOREACH(q, head, next) {
688 693
        if (addr == q->qhaddr) {
689 694
            return q;
690 695
        }
......
692 697
    return NULL;
693 698
}
694 699

  
695
static void ehci_queues_rip_unused(EHCIState *ehci)
700
static void ehci_queues_rip_unused(EHCIState *ehci, int async)
696 701
{
702
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
697 703
    EHCIQueue *q, *tmp;
698 704

  
699
    QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
705
    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
700 706
        if (q->seen) {
701 707
            q->seen = 0;
702 708
            q->ts = ehci->last_run_ns;
......
706 712
            /* allow 0.25 sec idle */
707 713
            continue;
708 714
        }
709
        ehci_free_queue(q);
715
        ehci_free_queue(q, async);
710 716
    }
711 717
}
712 718

  
713
static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev)
719
static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async)
714 720
{
721
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
715 722
    EHCIQueue *q, *tmp;
716 723

  
717
    QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
724
    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
718 725
        if (!usb_packet_is_inflight(&q->packet) ||
719 726
            q->packet.ep->dev != dev) {
720 727
            continue;
721 728
        }
722
        ehci_free_queue(q);
729
        ehci_free_queue(q, async);
723 730
    }
724 731
}
725 732

  
726
static void ehci_queues_rip_all(EHCIState *ehci)
733
static void ehci_queues_rip_all(EHCIState *ehci, int async)
727 734
{
735
    EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
728 736
    EHCIQueue *q, *tmp;
729 737

  
730
    QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
731
        ehci_free_queue(q);
738
    QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
739
        ehci_free_queue(q, async);
732 740
    }
733 741
}
734 742

  
......
773 781
        return;
774 782
    }
775 783

  
776
    ehci_queues_rip_device(s, port->dev);
784
    ehci_queues_rip_device(s, port->dev, 0);
785
    ehci_queues_rip_device(s, port->dev, 1);
777 786

  
778 787
    *portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
779 788
    *portsc |= PORTSC_CSC;
......
793 802
        return;
794 803
    }
795 804

  
796
    ehci_queues_rip_device(s, child);
805
    ehci_queues_rip_device(s, child, 0);
806
    ehci_queues_rip_device(s, child, 1);
797 807
}
798 808

  
799 809
static void ehci_wakeup(USBPort *port)
......
911 921
            usb_device_reset(devs[i]);
912 922
        }
913 923
    }
914
    ehci_queues_rip_all(s);
924
    ehci_queues_rip_all(s, 0);
925
    ehci_queues_rip_all(s, 1);
915 926
    qemu_del_timer(s->frame_timer);
916 927
}
917 928

  
......
1526 1537
        ehci_set_usbsts(ehci, USBSTS_REC);
1527 1538
    }
1528 1539

  
1529
    ehci_queues_rip_unused(ehci);
1540
    ehci_queues_rip_unused(ehci, async);
1530 1541

  
1531 1542
    /*  Find the head of the list (4.9.1.1) */
1532 1543
    for(i = 0; i < MAX_QH; i++) {
......
1613 1624
    int reload;
1614 1625

  
1615 1626
    entry = ehci_get_fetch_addr(ehci, async);
1616
    q = ehci_find_queue_by_qh(ehci, entry);
1627
    q = ehci_find_queue_by_qh(ehci, entry, async);
1617 1628
    if (NULL == q) {
1618 1629
        q = ehci_alloc_queue(ehci, async);
1619 1630
    }
......
2064 2075

  
2065 2076
static void ehci_advance_async_state(EHCIState *ehci)
2066 2077
{
2067
    int async = 1;
2078
    const int async = 1;
2068 2079

  
2069 2080
    switch(ehci_get_state(ehci, async)) {
2070 2081
    case EST_INACTIVE:
......
2121 2132
{
2122 2133
    uint32_t entry;
2123 2134
    uint32_t list;
2124
    int async = 0;
2135
    const int async = 0;
2125 2136

  
2126 2137
    // 4.6
2127 2138

  
......
2354 2365
    }
2355 2366

  
2356 2367
    s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);
2357
    QTAILQ_INIT(&s->queues);
2368
    QTAILQ_INIT(&s->aqueues);
2369
    QTAILQ_INIT(&s->pqueues);
2358 2370

  
2359 2371
    qemu_register_reset(ehci_reset, s);
2360 2372

  

Also available in: Unified diff