[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 01/28] usb-uhci: implement bandwidth management
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 01/28] usb-uhci: implement bandwidth management |
Date: |
Fri, 10 Feb 2012 12:42:57 +0100 |
The OS is allowed to make the UHCI Controller run in circles. That is
usually done to serve multiple connected USB devices in a robin-round
fashion, so the available USB bandwidth is evenly distributed between
devices.
The uhci emulation handles this in a very poor way though. When it
figures it runs in circles it stops processing unconditionally, so
it usually processes at most a single transfer desriptor per queue,
even if there are multiple transfer descriptors are queued up.
This patch makes uhci act in a more sophisticated way. It keeps track
of successful processed transfer descriptors and transfered bytes. Then
it will stop processing when there is nothing to do (no transfer
descriptor was completed the last round) or when the transfered data
reaches the usb bandwidth limit.
Result is that the usb-storage devices connected to uhci are ten times
faster, mkfs.vfat time for a 64M stick goes down from five seconds to
a half second. Reason for this is that we are now processing up to 20
transfer descriptors (with 64 bytes each) per frame instead of a single
one.
Signed-off-by: Gerd Hoffmann <address@hidden>
---
hw/usb-uhci.c | 29 ++++++++++++++++++++++-------
1 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index cddcc89..e0c7dbb 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -73,7 +73,7 @@
#define FRAME_TIMER_FREQ 1000
-#define FRAME_MAX_LOOPS 100
+#define FRAME_MAX_LOOPS 256
#define NB_PORTS 2
@@ -942,7 +942,7 @@ static int qhdb_insert(QhDb *db, uint32_t addr)
static void uhci_process_frame(UHCIState *s)
{
uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
- uint32_t curr_qh;
+ uint32_t curr_qh, td_count = 0, bytes_count = 0;
int cnt, ret;
UHCI_TD td;
UHCI_QH qh;
@@ -967,13 +967,26 @@ static void uhci_process_frame(UHCIState *s)
if (qhdb_insert(&qhdb, link)) {
/*
* We're going in circles. Which is not a bug because
- * HCD is allowed to do that as part of the BW management.
- * In our case though it makes no sense to spin here. Sync
transations
- * are already done, and async completion handler will
re-process
- * the frame when something is ready.
+ * HCD is allowed to do that as part of the BW management.
+ *
+ * Stop processing here if
+ * (a) no transaction has been done since we've been
+ * here last time, or
+ * (b) we've reached the usb 1.1 bandwidth, which is
+ * 1280 bytes/frame.
*/
DPRINTF("uhci: detected loop. qh 0x%x\n", link);
- break;
+ if (td_count == 0) {
+ DPRINTF("uhci: no transaction last round, stop\n");
+ break;
+ } else if (bytes_count >= 1280) {
+ DPRINTF("uhci: bandwidth limit reached, stop\n");
+ break;
+ } else {
+ td_count = 0;
+ qhdb_reset(&qhdb);
+ qhdb_insert(&qhdb, link);
+ }
}
pci_dma_read(&s->dev, link & ~0xf, &qh, sizeof(qh));
@@ -1033,6 +1046,8 @@ static void uhci_process_frame(UHCIState *s)
link, td.link, td.ctrl, td.token, curr_qh);
link = td.link;
+ td_count++;
+ bytes_count += (td.ctrl & 0x7ff) + 1;
if (curr_qh) {
/* update QH element link */
--
1.7.1
- [Qemu-devel] [PULL 00/28] usb patch queue, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 02/28] usb-ehci: Clear the portstatus powner bit on device disconnect, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 04/28] usb: kill USB_MSG_{ATTACH,DETACH}, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 08/28] usb-hub: implement find_device, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 01/28] usb-uhci: implement bandwidth management,
Gerd Hoffmann <=
- [Qemu-devel] [PATCH 07/28] usb: add usb_find_device(), Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 22/28] usb: add USBBusOps->wakeup_endpoint, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 10/28] usb-uhci: switch to usb_find_device(), Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 03/28] usb-redir: Add the posibility to filter out certain devices from redirecion, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 18/28] usb: add USBEndpoint->{nr,pid}, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 06/28] usb: kill usb_send_msg, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 14/28] usb-xhci: switch to usb_find_device(), Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 23/28] xhci: signal low- and fullspeed support, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 15/28] usb: kill handle_packet callback, Gerd Hoffmann, 2012/02/10
- [Qemu-devel] [PATCH 12/28] usb-ohci: switch to usb_find_device(), Gerd Hoffmann, 2012/02/10