[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [qemu-upstream-unstable] uhci: Add a completions_only flag for async completions



commit 887938160e5d631c56ee115b1817613a60184138
Author: Hans de Goede <hdegoede@xxxxxxxxxx>
Date:   Sat Nov 17 12:11:49 2012 +0100

    uhci: Add a completions_only flag for async completions
    
    Add a completions_only flag, and set this when running process_frame for 
async
    completion handling, this fixes 2 issues in a single patch:
    
    1) It makes sure async completed packets get written to guest mem 
immediately,
    even if all the bandwidth for the frame was consumed from the timer run
    process_frame. This is necessary as delaying their writeback to the next 
frame
    can cause the completion to get lost on migration.
    
    2) The calling of process_frame from a bh on async completion causes iso
    tds to get server more often they should, messing up usb sound class device
    timing. By only processing completed packets, the iso tds get skipped fixing
    this.
    
    Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
    Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxxxxx>
---
 hw/usb/hcd-uhci.c |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 2838d21..ef32633 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -152,6 +152,7 @@ struct UHCIState {
     QEMUBH *bh;
     uint32_t frame_bytes;
     uint32_t frame_bandwidth;
+    bool completions_only;
     UHCIPort ports[NB_PORTS];
 
     /* Interrupts that should be raised at the end of the current frame.  */
@@ -891,6 +892,10 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, 
uint32_t qh_addr,
         goto done;
     }
 
+    if (s->completions_only) {
+        return TD_RESULT_ASYNC_CONT;
+    }
+
     /* Allocate new packet */
     if (q == NULL) {
         USBDevice *dev = uhci_find_device(s, (td->token >> 8) & 0x7f);
@@ -960,9 +965,9 @@ static void uhci_async_complete(USBPort *port, USBPacket 
*packet)
     }
 
     async->done = 1;
-    if (s->frame_bytes < s->frame_bandwidth) {
-        qemu_bh_schedule(s->bh);
-    }
+    /* Force processing of this packet *now*, needed for migration */
+    s->completions_only = true;
+    qemu_bh_schedule(s->bh);
 }
 
 static int is_valid(uint32_t link)
@@ -1054,7 +1059,7 @@ static void uhci_process_frame(UHCIState *s)
     qhdb_reset(&qhdb);
 
     for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
-        if (s->frame_bytes >= s->frame_bandwidth) {
+        if (!s->completions_only && s->frame_bytes >= s->frame_bandwidth) {
             /* We've reached the usb 1.1 bandwidth, which is
                1280 bytes/frame, stop processing */
             trace_usb_uhci_frame_stop_bandwidth();
@@ -1170,6 +1175,7 @@ static void uhci_frame_timer(void *opaque)
     /* prepare the timer for the next frame */
     s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ);
     s->frame_bytes = 0;
+    s->completions_only = false;
     qemu_bh_cancel(s->bh);
 
     if (!(s->cmd & UHCI_CMD_RS)) {
--
generated by git-patchbot for /home/xen/git/qemu-upstream-unstable.git

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.