aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2011-12-22 11:34:30 +0200
committerGerd Hoffmann <kraxel@redhat.com>2012-01-06 12:36:14 +0100
commitfd891c9318b112462e54ee1b3b16b074b8bec5b1 (patch)
treea2c97b4385d2b67d012c2cad9e023f79352fefcd
parentc75fead66e25b35b867b661ee92087dc245a48c9 (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 e68be70b1..81488c48e 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;