[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH for-1.2 09/11] ehci: handle TD deactivation of infli
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH for-1.2 09/11] ehci: handle TD deactivation of inflight packets |
Date: |
Fri, 31 Aug 2012 16:19:20 +0200 |
Check the TDs of inflight packets, cancel
packets in case the guest clears the active bit.
Signed-off-by: Gerd Hoffmann <address@hidden>
---
hw/usb/hcd-ehci.c | 38 +++++++++++++++++++++++---------------
1 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 30e5e8f..eca1431 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1816,11 +1816,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci,
int async)
q->dev = ehci_find_device(q->ehci, devaddr);
}
- if (p && p->async == EHCI_ASYNC_INFLIGHT) {
- /* I/O still in progress -- skip queue */
- ehci_set_state(ehci, async, EST_HORIZONTALQH);
- goto out;
- }
if (p && p->async == EHCI_ASYNC_FINISHED) {
/* I/O finished -- continue processing queue */
trace_usb_ehci_packet_action(p->queue, p, "complete");
@@ -1969,28 +1964,41 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd);
p = QTAILQ_FIRST(&q->packets);
- if (p != NULL && p->qtdaddr != q->qtdaddr) {
- /* should not happen (guest bug) */
- ehci_cancel_queue(q);
- p = NULL;
- }
if (p != NULL) {
- ehci_qh_do_overlay(q);
+ if (p->qtdaddr != q->qtdaddr ||
+ (!NLPTR_TBIT(p->qtd.next) && (p->qtd.next != qtd.next)) ||
+ (!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd.altnext)) ||
+ p->qtd.bufptr[0] != qtd.bufptr[0]) {
+ /* guest bug: guest updated active QH or qTD underneath us */
+ ehci_cancel_queue(q);
+ p = NULL;
+ } else {
+ p->qtd = qtd;
+ ehci_qh_do_overlay(q);
+ }
+ }
+
+ if (!(qtd.token & QTD_TOKEN_ACTIVE)) {
+ if (p != NULL) {
+ /* transfer canceled by guest (clear active) */
+ ehci_cancel_queue(q);
+ p = NULL;
+ }
+ ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
+ again = 1;
+ } else if (p != NULL) {
if (p->async == EHCI_ASYNC_INFLIGHT) {
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
} else {
ehci_set_state(q->ehci, q->async, EST_EXECUTING);
}
again = 1;
- } else if (qtd.token & QTD_TOKEN_ACTIVE) {
+ } else {
p = ehci_alloc_packet(q);
p->qtdaddr = q->qtdaddr;
p->qtd = qtd;
ehci_set_state(q->ehci, q->async, EST_EXECUTE);
again = 1;
- } else {
- ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
- again = 1;
}
return again;
--
1.7.1
- [Qemu-devel] [PULL for-1.2 00/11] usb patch queue, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 10/11] ehci: Fix interrupt endpoints no longer working, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 03/11] usb: unique packet ids, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 07/11] ehci: simplify ehci_state_executing, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 04/11] ehci: Fix NULL ptr deref when unplugging an USB dev with an iso stream active, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 05/11] ehci: Schedule async-bh when IAAD bit gets set, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 09/11] ehci: handle TD deactivation of inflight packets,
Gerd Hoffmann <=
- [Qemu-devel] [PATCH for-1.2 11/11] uas: move transfer kickoff, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 06/11] ehci: Remove unnecessary ehci_flush_qh call, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 08/11] ehci: add ehci_cancel_queue(), Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 02/11] usb: Halt ep queue en cancel pending packets on a packet error, Gerd Hoffmann, 2012/08/31
- [Qemu-devel] [PATCH for-1.2 01/11] fix info qtree indention, Gerd Hoffmann, 2012/08/31