aboutsummaryrefslogtreecommitdiff
path: root/hw/usb/hcd-uhci.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-10-24 18:14:09 +0200
committerGerd Hoffmann <kraxel@redhat.com>2012-10-25 09:08:10 +0200
commit6ba43f1f6b60159e731b1f37ffb53ab9ab59efa9 (patch)
tree50aa334531fbd3b720da7d2dd78eab7453304250 /hw/usb/hcd-uhci.c
parent0cae7b1a004d6857e3bde3d511d7efa39d3cb48a (diff)
downloadqemu-6ba43f1f6b60159e731b1f37ffb53ab9ab59efa9.zip
qemu-6ba43f1f6b60159e731b1f37ffb53ab9ab59efa9.tar.gz
qemu-6ba43f1f6b60159e731b1f37ffb53ab9ab59efa9.tar.bz2
usb: Move short-not-ok handling to the core
After a short-not-ok packet ending short, we should not advance the queue. Move enforcing this to the core, rather then handling it in the hcd code. This may result in the queue now actually containing multiple input packets (which would not happen before), and this requires special handling in combination with pipelining, so disable pipleining for input endpoints (for now). Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb/hcd-uhci.c')
-rw-r--r--hw/usb/hcd-uhci.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 00dc9d5..953897b 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -808,6 +808,7 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
UHCIAsync *async;
int len = 0, max_len;
uint8_t pid;
+ bool spd;
USBDevice *dev;
USBEndpoint *ep;
@@ -852,13 +853,14 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
max_len = ((td->token >> 21) + 1) & 0x7ff;
pid = td->token & 0xff;
+ spd = (pid == USB_TOKEN_IN && (td->ctrl & TD_CTRL_SPD) != 0);
dev = uhci_find_device(s, (td->token >> 8) & 0x7f);
ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);
if (ep_ret) {
*ep_ret = ep;
}
- usb_packet_setup(&async->packet, pid, ep, addr);
+ usb_packet_setup(&async->packet, pid, ep, addr, spd);
qemu_sglist_add(&async->sgl, td->buffer, max_len);
usb_packet_map(&async->packet, &async->sgl);
@@ -985,8 +987,7 @@ static void uhci_fill_queue(UHCIState *s, UHCI_TD *td, struct USBEndpoint *ep)
UHCI_TD ptd;
int ret;
- ptd.ctrl = td->ctrl;
- while (is_valid(plink) && !(ptd.ctrl & TD_CTRL_SPD)) {
+ while (is_valid(plink)) {
pci_dma_read(&s->dev, plink & ~0xf, &ptd, sizeof(ptd));
le32_to_cpus(&ptd.link);
le32_to_cpus(&ptd.ctrl);