aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-02-02 17:01:56 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-02-02 17:01:56 +0000
commit3bb1e822ca7c8b48ac80cb7bd53af94c91c949e7 (patch)
treec1bce2f8a57206afc2406a7ab9a603f99ff4bade /hw
parentd2ea854c382d4d080de1f149167e60290108f79b (diff)
parent5a8660741a8aa19fbf8a5e8a2b3aac88664f4e66 (diff)
downloadqemu-3bb1e822ca7c8b48ac80cb7bd53af94c91c949e7.zip
qemu-3bb1e822ca7c8b48ac80cb7bd53af94c91c949e7.tar.gz
qemu-3bb1e822ca7c8b48ac80cb7bd53af94c91c949e7.tar.bz2
Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20160202-1' into staging
usb: two ehci fixes. # gpg: Signature made Tue 02 Feb 2016 13:12:00 GMT using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-usb-20160202-1: ehci: update irq on reset usb: check page select value while processing iTD Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/usb/hcd-ehci.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index ab00268..1b50601 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -866,6 +866,7 @@ void ehci_reset(void *opaque)
s->usbsts = USBSTS_HALT;
s->usbsts_pending = 0;
s->usbsts_frindex = 0;
+ ehci_update_irq(s);
s->astate = EST_INACTIVE;
s->pstate = EST_INACTIVE;
@@ -1405,21 +1406,23 @@ static int ehci_process_itd(EHCIState *ehci,
if (itd->transact[i] & ITD_XACT_ACTIVE) {
pg = get_field(itd->transact[i], ITD_XACT_PGSEL);
off = itd->transact[i] & ITD_XACT_OFFSET_MASK;
- ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
- ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
len = get_field(itd->transact[i], ITD_XACT_LENGTH);
if (len > max * mult) {
len = max * mult;
}
-
- if (len > BUFF_SIZE) {
+ if (len > BUFF_SIZE || pg > 6) {
return -1;
}
+ ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
if (off + len > 4096) {
/* transfer crosses page border */
+ if (pg == 6) {
+ return -1; /* avoid page pg + 1 */
+ }
+ ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
uint32_t len2 = off + len - 4096;
uint32_t len1 = len - len2;
qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);