On Tue, Feb 04, 2014 at 10:01:32AM +0100, Gerd Hoffmann wrote:
I looked through the QEMU hcd-uhci.c code, and I think QEMU is buggy here. QEMU keeps a mapping of queues that are indexed by the usb device address and endpoint (see uhci_queue_new() ). When the usb device has address 0, it creates an entry in this mapping and the entry remains even after the device is given a new address. Later, when the next device also has address 0, QEMU attempts to use that mapping even though the 0 address now corresponds with a different device.
Nice spotting. Does the attached patch help?
I still get the same behavior (usb keyboard hangs 50% of the time) after applying it...
Thanks, --G
From 42568e8e4812df944abcac27adefdf518ae1361e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann kraxel@redhat.com Date: Tue, 4 Feb 2014 09:57:36 +0100 Subject: [PATCH] uhci: don't cache queues for addr 0 control transfers.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com
hw/usb/hcd-uhci.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 238d1d2..11ebb9f 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -253,6 +253,10 @@ static bool uhci_queue_verify(UHCIQueue *queue, uint32_t qh_addr, UHCI_TD *td, { UHCIAsync *first = QTAILQ_FIRST(&queue->asyncs);
- if (queue->ep->nr == 0 && queue->ep->dev->addr == 0 &&
queue->ep->dev->setup_state == 0 /* SETUP_STATE_IDLE */)
return false;
- return queue->qh_addr == qh_addr && queue->token == uhci_queue_token(td) && (queuing || !(td->ctrl & TD_CTRL_ACTIVE) || first == NULL ||
-- 1.8.3.1