qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 26/37] ehci: add async field to EHCIQueue
Date: Thu,  7 Jun 2012 11:31:15 +0200	[thread overview]
Message-ID: <1339061486-28513-27-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1339061486-28513-1-git-send-email-kraxel@redhat.com>

Keep track whenever a EHCIQueue is part of the async or periodic
schedule.  This way we don't have to pass around the async flag
everywhere but can look it up from the EHCIQueue struct when needed.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-ehci.c |   92 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index aa67af6..f363f14 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -364,6 +364,7 @@ struct EHCIQueue {
     QTAILQ_ENTRY(EHCIQueue) next;
     uint32_t seen;
     uint64_t ts;
+    int async;
 
     /* cached data from guest - needs to be flushed
      * when guest removes an entry (doorbell, handshake sequence)
@@ -700,15 +701,16 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async)
     q = g_malloc0(sizeof(*q));
     q->ehci = ehci;
     q->qhaddr = addr;
+    q->async = async;
     QTAILQ_INIT(&q->packets);
     QTAILQ_INSERT_HEAD(head, q, next);
     trace_usb_ehci_queue_action(q, "alloc");
     return q;
 }
 
-static void ehci_free_queue(EHCIQueue *q, int async)
+static void ehci_free_queue(EHCIQueue *q)
 {
-    EHCIQueueHead *head = async ? &q->ehci->aqueues : &q->ehci->pqueues;
+    EHCIQueueHead *head = q->async ? &q->ehci->aqueues : &q->ehci->pqueues;
     EHCIPacket *p;
 
     trace_usb_ehci_queue_action(q, "free");
@@ -748,7 +750,7 @@ static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush)
             /* allow 0.25 sec idle */
             continue;
         }
-        ehci_free_queue(q, async);
+        ehci_free_queue(q);
     }
 }
 
@@ -761,7 +763,7 @@ static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async)
         if (q->dev != dev) {
             continue;
         }
-        ehci_free_queue(q, async);
+        ehci_free_queue(q);
     }
 }
 
@@ -771,7 +773,7 @@ static void ehci_queues_rip_all(EHCIState *ehci, int async)
     EHCIQueue *q, *tmp;
 
     QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
-        ehci_free_queue(q, async);
+        ehci_free_queue(q);
     }
 }
 
@@ -1806,7 +1808,7 @@ static int ehci_state_fetchsitd(EHCIState *ehci, int async)
 }
 
 /* Section 4.10.2 - paragraph 3 */
-static int ehci_state_advqueue(EHCIQueue *q, int async)
+static int ehci_state_advqueue(EHCIQueue *q)
 {
 #if 0
     /* TO-DO: 4.10.2 - paragraph 2
@@ -1825,27 +1827,27 @@ static int ehci_state_advqueue(EHCIQueue *q, int async)
     if (((q->qh.token & QTD_TOKEN_TBYTES_MASK) != 0) &&
         (NLPTR_TBIT(q->qh.altnext_qtd) == 0)) {
         q->qtdaddr = q->qh.altnext_qtd;
-        ehci_set_state(q->ehci, async, EST_FETCHQTD);
+        ehci_set_state(q->ehci, q->async, EST_FETCHQTD);
 
     /*
      *  next qTD is valid
      */
     } else if (NLPTR_TBIT(q->qh.next_qtd) == 0) {
         q->qtdaddr = q->qh.next_qtd;
-        ehci_set_state(q->ehci, async, EST_FETCHQTD);
+        ehci_set_state(q->ehci, q->async, EST_FETCHQTD);
 
     /*
      *  no valid qTD, try next QH
      */
     } else {
-        ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
+        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
     }
 
     return 1;
 }
 
 /* Section 4.10.2 - paragraph 4 */
-static int ehci_state_fetchqtd(EHCIQueue *q, int async)
+static int ehci_state_fetchqtd(EHCIQueue *q)
 {
     EHCIqtd qtd;
     EHCIPacket *p;
@@ -1865,41 +1867,41 @@ static int ehci_state_fetchqtd(EHCIQueue *q, int async)
         ehci_qh_do_overlay(q);
         ehci_flush_qh(q);
         if (p->async == EHCI_ASYNC_INFLIGHT) {
-            ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
+            ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
         } else {
-            ehci_set_state(q->ehci, async, EST_EXECUTING);
+            ehci_set_state(q->ehci, q->async, EST_EXECUTING);
         }
         again = 1;
     } else if (qtd.token & QTD_TOKEN_ACTIVE) {
         p = ehci_alloc_packet(q);
         p->qtdaddr = q->qtdaddr;
         p->qtd = qtd;
-        ehci_set_state(q->ehci, async, EST_EXECUTE);
+        ehci_set_state(q->ehci, q->async, EST_EXECUTE);
         again = 1;
     } else {
-        ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
+        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
         again = 1;
     }
 
     return again;
 }
 
-static int ehci_state_horizqh(EHCIQueue *q, int async)
+static int ehci_state_horizqh(EHCIQueue *q)
 {
     int again = 0;
 
-    if (ehci_get_fetch_addr(q->ehci, async) != q->qh.next) {
-        ehci_set_fetch_addr(q->ehci, async, q->qh.next);
-        ehci_set_state(q->ehci, async, EST_FETCHENTRY);
+    if (ehci_get_fetch_addr(q->ehci, q->async) != q->qh.next) {
+        ehci_set_fetch_addr(q->ehci, q->async, q->qh.next);
+        ehci_set_state(q->ehci, q->async, EST_FETCHENTRY);
         again = 1;
     } else {
-        ehci_set_state(q->ehci, async, EST_ACTIVE);
+        ehci_set_state(q->ehci, q->async, EST_ACTIVE);
     }
 
     return again;
 }
 
-static void ehci_fill_queue(EHCIPacket *p, int async)
+static void ehci_fill_queue(EHCIPacket *p)
 {
     EHCIQueue *q = p->queue;
     EHCIqtd qtd = p->qtd;
@@ -1928,7 +1930,7 @@ static void ehci_fill_queue(EHCIPacket *p, int async)
     }
 }
 
-static int ehci_state_execute(EHCIQueue *q, int async)
+static int ehci_state_execute(EHCIQueue *q)
 {
     EHCIPacket *p = QTAILQ_FIRST(&q->packets);
     int again = 0;
@@ -1944,16 +1946,16 @@ static int ehci_state_execute(EHCIQueue *q, int async)
     // TODO write back ptr to async list when done or out of time
     // TODO Windows does not seem to ever set the MULT field
 
-    if (!async) {
+    if (!q->async) {
         int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT);
         if (!transactCtr) {
-            ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
+            ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
             again = 1;
             goto out;
         }
     }
 
-    if (async) {
+    if (q->async) {
         ehci_set_usbsts(q->ehci, USBSTS_REC);
     }
 
@@ -1966,20 +1968,20 @@ static int ehci_state_execute(EHCIQueue *q, int async)
         ehci_flush_qh(q);
         trace_usb_ehci_packet_action(p->queue, p, "async");
         p->async = EHCI_ASYNC_INFLIGHT;
-        ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
+        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
         again = 1;
-        ehci_fill_queue(p, async);
+        ehci_fill_queue(p);
         goto out;
     }
 
-    ehci_set_state(q->ehci, async, EST_EXECUTING);
+    ehci_set_state(q->ehci, q->async, EST_EXECUTING);
     again = 1;
 
 out:
     return again;
 }
 
-static int ehci_state_executing(EHCIQueue *q, int async)
+static int ehci_state_executing(EHCIQueue *q)
 {
     EHCIPacket *p = QTAILQ_FIRST(&q->packets);
     int again = 0;
@@ -1997,7 +1999,7 @@ static int ehci_state_executing(EHCIQueue *q, int async)
     }
 
     // 4.10.3
-    if (!async) {
+    if (!q->async) {
         int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT);
         transactCtr--;
         set_field(&q->qh.epcap, transactCtr, QH_EPCAP_MULT);
@@ -2007,9 +2009,9 @@ static int ehci_state_executing(EHCIQueue *q, int async)
 
     /* 4.10.5 */
     if (p->usb_status == USB_RET_NAK) {
-        ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
+        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
     } else {
-        ehci_set_state(q->ehci, async, EST_WRITEBACK);
+        ehci_set_state(q->ehci, q->async, EST_WRITEBACK);
     }
 
     again = 1;
@@ -2020,7 +2022,7 @@ out:
 }
 
 
-static int ehci_state_writeback(EHCIQueue *q, int async)
+static int ehci_state_writeback(EHCIQueue *q)
 {
     EHCIPacket *p = QTAILQ_FIRST(&q->packets);
     int again = 0;
@@ -2043,10 +2045,10 @@ static int ehci_state_writeback(EHCIQueue *q, int async)
      * bit is clear.
      */
     if (q->qh.token & QTD_TOKEN_HALT) {
-        ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
+        ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
         again = 1;
     } else {
-        ehci_set_state(q->ehci, async, EST_ADVANCEQUEUE);
+        ehci_set_state(q->ehci, q->async, EST_ADVANCEQUEUE);
         again = 1;
     }
     return again;
@@ -2056,8 +2058,7 @@ static int ehci_state_writeback(EHCIQueue *q, int async)
  * This is the state machine that is common to both async and periodic
  */
 
-static void ehci_advance_state(EHCIState *ehci,
-                               int async)
+static void ehci_advance_state(EHCIState *ehci, int async)
 {
     EHCIQueue *q = NULL;
     int again;
@@ -2074,7 +2075,12 @@ static void ehci_advance_state(EHCIState *ehci,
 
         case EST_FETCHQH:
             q = ehci_state_fetchqh(ehci, async);
-            again = q ? 1 : 0;
+            if (q != NULL) {
+                assert(q->async == async);
+                again = 1;
+            } else {
+                again = 0;
+            }
             break;
 
         case EST_FETCHITD:
@@ -2086,29 +2092,29 @@ static void ehci_advance_state(EHCIState *ehci,
             break;
 
         case EST_ADVANCEQUEUE:
-            again = ehci_state_advqueue(q, async);
+            again = ehci_state_advqueue(q);
             break;
 
         case EST_FETCHQTD:
-            again = ehci_state_fetchqtd(q, async);
+            again = ehci_state_fetchqtd(q);
             break;
 
         case EST_HORIZONTALQH:
-            again = ehci_state_horizqh(q, async);
+            again = ehci_state_horizqh(q);
             break;
 
         case EST_EXECUTE:
-            again = ehci_state_execute(q, async);
+            again = ehci_state_execute(q);
             break;
 
         case EST_EXECUTING:
             assert(q != NULL);
-            again = ehci_state_executing(q, async);
+            again = ehci_state_executing(q);
             break;
 
         case EST_WRITEBACK:
             assert(q != NULL);
-            again = ehci_state_writeback(q, async);
+            again = ehci_state_writeback(q);
             break;
 
         default:
-- 
1.7.1

  parent reply	other threads:[~2012-06-07  9:31 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-07  9:30 [Qemu-devel] [PULL 00/37] usb patch queue Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 01/37] uhci: fix bandwidth management Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 02/37] uhci: use bottom half Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 03/37] uhci: make bandwidth tunable Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 04/37] uhci: fix trace format strings Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 05/37] uhci: zap uhci_pre_save Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 06/37] uhci: fix irq routing Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 07/37] scsi: prepare migration code for usb-storage support Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 08/37] usb-storage: remove MSDState->residue Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 09/37] usb-storage: add usb_msd_packet_complete() Gerd Hoffmann
2012-06-07  9:30 ` [Qemu-devel] [PATCH 10/37] usb-storage: add scsi_off, remove scsi_buf Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 11/37] usb-storage: migration support Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 12/37] xhci: Clean up reset function Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 13/37] xhci: trace: mmio reads+writes Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 14/37] xhci: trace: run+stop Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 15/37] xhci: trace: irq + events Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 16/37] xhci: trace: ring fetch Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 17/37] xhci: trace: endpoints Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 18/37] xhci: trace: transfers Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 19/37] xhci: trace: slots Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 20/37] ehci: add EHCIPacket Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 21/37] ehci: make ehci_execute work on EHCIPacket instead of EHCIQueue Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 22/37] ehci: cache USBDevice in EHCIQueue Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 23/37] ehci: move ehci_flush_qh Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 24/37] ehci: add queuing support Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 25/37] ehci: tweak queue initialization Gerd Hoffmann
2012-06-07  9:31 ` Gerd Hoffmann [this message]
2012-06-07  9:31 ` [Qemu-devel] [PATCH 27/37] ehci: move async schedule to bottom half Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 28/37] ehci: schedule async bh on async packet completion Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 29/37] ehci: kick async schedule on wakeup Gerd Hoffmann
2012-07-06 14:30   ` Hans de Goede
2012-07-06 14:54     ` Hans de Goede
2012-07-09  8:02       ` Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 30/37] ehci: fix reset Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 31/37] ehci: add ehci_*_enabled() helpers Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 32/37] ehci: update status bits in ehci_set_state Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 33/37] ehci: fix halt status handling Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 34/37] ehci: remove unused attach_poll_counter Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 35/37] ehci: create ehci_update_frindex Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 36/37] ehci: adaptive wakeup rate Gerd Hoffmann
2012-06-07  9:31 ` [Qemu-devel] [PATCH 37/37] ehci: rework frame skipping Gerd Hoffmann
2012-06-11 18:27 ` [Qemu-devel] [PULL 00/37] usb patch queue Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1339061486-28513-27-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).