* [Qemu-devel] [PATCH 1/4] usb: Enforce iso endpoints never returing USB_RET_ASYNC
2012-10-18 14:08 [Qemu-devel] [PATCH 0/4] RFC: uhci: various cleanups Hans de Goede
@ 2012-10-18 14:08 ` Hans de Goede
2012-10-18 14:08 ` [Qemu-devel] [PATCH 2/4] uhci: No need to handle async completion of isoc packets Hans de Goede
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2012-10-18 14:08 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
ehci was already testing for this, and we depend in various places
on no devices doing this, so lets move the check for this to the
usb core.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/core.c | 1 +
hw/usb/hcd-ehci.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 34a65af..4f4adaa 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -394,6 +394,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
ret = usb_process_one(p);
if (ret == USB_RET_ASYNC) {
+ assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
usb_packet_set_state(p, USB_PACKET_ASYNC);
QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
} else if (ret == USB_RET_ADD_TO_QUEUE) {
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 70b6363..534e1ed 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1667,7 +1667,6 @@ static int ehci_process_itd(EHCIState *ehci,
(itd->transact[i] & ITD_XACT_IOC) != 0);
usb_packet_map(&ehci->ipacket, &ehci->isgl);
ret = usb_handle_packet(dev, &ehci->ipacket);
- assert(ret != USB_RET_ASYNC);
usb_packet_unmap(&ehci->ipacket, &ehci->isgl);
} else {
DPRINTF("ISOCH: attempt to addess non-iso endpoint\n");
--
1.7.12.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 2/4] uhci: No need to handle async completion of isoc packets
2012-10-18 14:08 [Qemu-devel] [PATCH 0/4] RFC: uhci: various cleanups Hans de Goede
2012-10-18 14:08 ` [Qemu-devel] [PATCH 1/4] usb: Enforce iso endpoints never returing USB_RET_ASYNC Hans de Goede
@ 2012-10-18 14:08 ` Hans de Goede
2012-10-18 14:08 ` [Qemu-devel] [PATCH 3/4] uhci: cleanup: Add an unlink call to uhci_async_cancel() Hans de Goede
2012-10-18 14:08 ` [Qemu-devel] [PATCH 4/4] uhci: Don't retry on error Hans de Goede
3 siblings, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2012-10-18 14:08 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
No devices ever return async for isoc endpoints and the core
already enforces this.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/hcd-uhci.c | 29 +++--------------------------
1 file changed, 3 insertions(+), 26 deletions(-)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 65b63d3..a1d9c1f 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -101,7 +101,6 @@ struct UHCIAsync {
UHCIQueue *queue;
QTAILQ_ENTRY(UHCIAsync) next;
uint32_t td;
- uint8_t isoc;
uint8_t done;
};
@@ -848,7 +847,6 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
* for initial isochronous requests
*/
async->queue->valid = 32;
- async->isoc = td->ctrl & TD_CTRL_IOS;
max_len = ((td->token >> 21) + 1) & 0x7ff;
pid = td->token & 0xff;
@@ -911,30 +909,9 @@ static void uhci_async_complete(USBPort *port, USBPacket *packet)
return;
}
- if (async->isoc) {
- UHCI_TD td;
- uint32_t link = async->td;
- uint32_t int_mask = 0, val;
-
- pci_dma_read(&s->dev, link & ~0xf, &td, sizeof(td));
- le32_to_cpus(&td.link);
- le32_to_cpus(&td.ctrl);
- le32_to_cpus(&td.token);
- le32_to_cpus(&td.buffer);
-
- uhci_async_unlink(async);
- uhci_complete_td(s, &td, async, &int_mask);
- s->pending_int_mask |= int_mask;
-
- /* update the status bits of the TD */
- val = cpu_to_le32(td.ctrl);
- pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val));
- uhci_async_free(async);
- } else {
- async->done = 1;
- if (s->frame_bytes < s->frame_bandwidth) {
- qemu_bh_schedule(s->bh);
- }
+ async->done = 1;
+ if (s->frame_bytes < s->frame_bandwidth) {
+ qemu_bh_schedule(s->bh);
}
}
--
1.7.12.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 3/4] uhci: cleanup: Add an unlink call to uhci_async_cancel()
2012-10-18 14:08 [Qemu-devel] [PATCH 0/4] RFC: uhci: various cleanups Hans de Goede
2012-10-18 14:08 ` [Qemu-devel] [PATCH 1/4] usb: Enforce iso endpoints never returing USB_RET_ASYNC Hans de Goede
2012-10-18 14:08 ` [Qemu-devel] [PATCH 2/4] uhci: No need to handle async completion of isoc packets Hans de Goede
@ 2012-10-18 14:08 ` Hans de Goede
2012-10-18 14:08 ` [Qemu-devel] [PATCH 4/4] uhci: Don't retry on error Hans de Goede
3 siblings, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2012-10-18 14:08 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
All callers of uhci_async_cancel() call uhci_async_unlink() first, so
lets move the unlink call to uhci_async_cancel()
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/hcd-uhci.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index a1d9c1f..1e0920e 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -232,6 +232,7 @@ static void uhci_async_unlink(UHCIAsync *async)
static void uhci_async_cancel(UHCIAsync *async)
{
+ uhci_async_unlink(async);
trace_usb_uhci_packet_cancel(async->queue->token, async->td, async->done);
if (!async->done)
usb_cancel_packet(&async->packet);
@@ -266,7 +267,6 @@ static void uhci_async_validate_end(UHCIState *s)
}
while (!QTAILQ_EMPTY(&queue->asyncs)) {
async = QTAILQ_FIRST(&queue->asyncs);
- uhci_async_unlink(async);
uhci_async_cancel(async);
}
uhci_queue_free(queue);
@@ -284,7 +284,6 @@ static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev)
curr->packet.ep->dev != dev) {
continue;
}
- uhci_async_unlink(curr);
uhci_async_cancel(curr);
}
}
@@ -297,7 +296,6 @@ static void uhci_async_cancel_all(UHCIState *s)
QTAILQ_FOREACH_SAFE(queue, &s->queues, next, nq) {
QTAILQ_FOREACH_SAFE(curr, &queue->asyncs, next, n) {
- uhci_async_unlink(curr);
uhci_async_cancel(curr);
}
uhci_queue_free(queue);
@@ -904,7 +902,6 @@ static void uhci_async_complete(USBPort *port, USBPacket *packet)
UHCIState *s = async->queue->uhci;
if (packet->status == USB_RET_REMOVE_FROM_QUEUE) {
- uhci_async_unlink(async);
uhci_async_cancel(async);
return;
}
--
1.7.12.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 4/4] uhci: Don't retry on error
2012-10-18 14:08 [Qemu-devel] [PATCH 0/4] RFC: uhci: various cleanups Hans de Goede
` (2 preceding siblings ...)
2012-10-18 14:08 ` [Qemu-devel] [PATCH 3/4] uhci: cleanup: Add an unlink call to uhci_async_cancel() Hans de Goede
@ 2012-10-18 14:08 ` Hans de Goede
3 siblings, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2012-10-18 14:08 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Hans de Goede, qemu-devel
Since we are either dealing with emulated devices, where retrying is
not going to help, or with redirected devices where the host OS will
have already retried, don't bother retrying on failed transfers.
Also move some common/indentical code out of all the error cases
into the generic error path.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/hcd-uhci.c | 62 +++++++++++++++++--------------------------------------
1 file changed, 19 insertions(+), 43 deletions(-)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 1e0920e..400a337 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -696,10 +696,6 @@ static USBDevice *uhci_find_device(UHCIState *s, uint8_t addr)
static void uhci_async_complete(USBPort *port, USBPacket *packet);
static void uhci_process_frame(UHCIState *s);
-/* return -1 if fatal error (frame must be stopped)
- 0 if TD successful
- 1 if TD unsuccessful or inactive
-*/
static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_t *int_mask)
{
int len = 0, max_len, err;
@@ -741,60 +737,40 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
out:
switch (async->packet.status) {
+ case USB_RET_NAK:
+ td->ctrl |= TD_CTRL_NAK;
+ return TD_RESULT_NEXT_QH;
+
case USB_RET_STALL:
td->ctrl |= TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
- s->status |= UHCI_STS_USBERR;
- if (td->ctrl & TD_CTRL_IOC) {
- *int_mask |= 0x01;
- }
- uhci_update_irq(s);
trace_usb_uhci_packet_complete_stall(async->queue->token, async->td);
- return TD_RESULT_NEXT_QH;
+ err = TD_RESULT_NEXT_QH;
+ break;
case USB_RET_BABBLE:
td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
- s->status |= UHCI_STS_USBERR;
- if (td->ctrl & TD_CTRL_IOC) {
- *int_mask |= 0x01;
- }
- uhci_update_irq(s);
/* frame interrupted */
trace_usb_uhci_packet_complete_babble(async->queue->token, async->td);
- return TD_RESULT_STOP_FRAME;
-
- case USB_RET_NAK:
- td->ctrl |= TD_CTRL_NAK;
- if (pid == USB_TOKEN_SETUP)
- break;
- return TD_RESULT_NEXT_QH;
+ err = TD_RESULT_STOP_FRAME;
+ break;
case USB_RET_IOERROR:
case USB_RET_NODEV:
default:
- break;
+ td->ctrl |= TD_CTRL_TIMEOUT;
+ td->ctrl &= ~(3 << TD_CTRL_ERROR_SHIFT);
+ trace_usb_uhci_packet_complete_error(async->queue->token, async->td);
+ err = TD_RESULT_NEXT_QH;
+ break;
}
- /* Retry the TD if error count is not zero */
-
- td->ctrl |= TD_CTRL_TIMEOUT;
- err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
- if (err != 0) {
- err--;
- if (err == 0) {
- td->ctrl &= ~TD_CTRL_ACTIVE;
- s->status |= UHCI_STS_USBERR;
- if (td->ctrl & TD_CTRL_IOC)
- *int_mask |= 0x01;
- uhci_update_irq(s);
- trace_usb_uhci_packet_complete_error(async->queue->token,
- async->td);
- }
+ td->ctrl &= ~TD_CTRL_ACTIVE;
+ s->status |= UHCI_STS_USBERR;
+ if (td->ctrl & TD_CTRL_IOC) {
+ *int_mask |= 0x01;
}
- td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
- (err << TD_CTRL_ERROR_SHIFT);
- return TD_RESULT_NEXT_QH;
+ uhci_update_irq(s);
+ return err;
}
static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
--
1.7.12.1
^ permalink raw reply related [flat|nested] 5+ messages in thread