Previously, during the merge, I resolved the changeset
2cfc40201be5562a942615452fc2c4ee45d1165c
usb-uhci: correctly deal with interrupt in asynchronous completion
which came from xen-unstable
changeset: 12775:
60bbcf799384d779c2a561b9d9ba30f28e31d970
date: Thu Dec 07 11:52:26 2006 +0000
files: tools/ioemu/hw/usb-hid.c tools/ioemu/hw/usb-uhci.c
description:
[HVM] qemu mouse: Adds support for USB mouse/tablet status check and
...
And UHC should leave a TD active when receiving NAK and execute this
incompleted TD in a subseqent frame. UHC only generates an interrupt
on complete after the TD with ICO bit is completed.
...
Signed-off-by: Xinmei Huang <xinmei.huang@intel.com>
with the new uhci controller in upstream qemu.
However, in the context of the new uhci controller this is a broken
change; it causes the polling of the usb tablet (for example) to cease
after the first two polls.
So I'm reverting it.
ret = async->packet.len;
+ if (td->ctrl & TD_CTRL_IOC)
+ *int_mask |= 0x01;
+
if (td->ctrl & TD_CTRL_IOS)
td->ctrl &= ~TD_CTRL_ACTIVE;
*int_mask |= 0x02;
/* short packet: do not update QH */
dprintf("uhci: short packet. td 0x%x token 0x%x\n", async->td, async->token);
- ret = 1;
- goto out_update_ioc;
+ return 1;
}
}
/* success */
- ret = 0;
- goto out_update_ioc;
+ return 0;
out:
switch(ret) {
case USB_RET_STALL:
td->ctrl |= TD_CTRL_STALL;
td->ctrl &= ~TD_CTRL_ACTIVE;
- ret = 1;
- goto out_update_ioc;
+ return 1;
case USB_RET_BABBLE:
td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
td->ctrl &= ~TD_CTRL_ACTIVE;
/* frame interrupted */
- ret = -1;
- goto out_update_ioc;
+ return -1;
case USB_RET_NAK:
td->ctrl |= TD_CTRL_NAK;
if (pid == USB_TOKEN_SETUP)
break;
- ret = 1;
- goto out_update_ioc;
+ return 1;
case USB_RET_NODEV:
default:
}
td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
(err << TD_CTRL_ERROR_SHIFT);
- ret = 1;
-
- out_update_ioc:
- if ((td->ctrl & TD_CTRL_IOC) && !(td->ctrl &= ~TD_CTRL_ACTIVE))
- *int_mask |= 0x01;
- return ret;
+ return 1;
}
static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)