aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2011-12-22 11:34:30 +0200
committerJustin M. Forbes <jforbes@redhat.com>2012-01-10 09:45:48 -0600
commit23201c64a789cf948fedcea221a4b6e197fcd628 (patch)
tree238ed4fe2d550406dd999ff22d879500ce0537e3
parentc936f649d4a6b87cabe809170874f6b560cc0524 (diff)
usb-ohci: td.cbp incorrectly updated near page end
The current code that updates the cbp value after a transfer looks like this: td.cbp += ret; if ((td.cbp & 0xfff) + ret > 0xfff) { <handle page overflow> because the 'ret' value is effectively added twice the check may fire too early when the overflow hasn't happened yet. Below is one of the possible changes that correct the behavior: Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--hw/usb-ohci.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index c2981c59a..c27014a88 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1025,10 +1025,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
if (ret == len) {
td.cbp = 0;
} else {
- td.cbp += ret;
if ((td.cbp & 0xfff) + ret > 0xfff) {
- td.cbp &= 0xfff;
- td.cbp |= td.be & ~0xfff;
+ td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
+ } else {
+ td.cbp += ret;
}
}
td.flags |= OHCI_TD_T1;