41 lines
1.3 KiB
Diff
41 lines
1.3 KiB
Diff
|
From 23201c64a789cf948fedcea221a4b6e197fcd628 Mon Sep 17 00:00:00 2001
|
||
|
From: Andriy Gapon <avg@FreeBSD.org>
|
||
|
Date: Thu, 22 Dec 2011 11:34:30 +0200
|
||
|
Subject: [PATCH 18/25] 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>
|
||
|
---
|
||
|
hw/usb-ohci.c | 6 +++---
|
||
|
1 files changed, 3 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
|
||
|
index c2981c5..c27014a 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;
|
||
|
--
|
||
|
1.7.7.5
|
||
|
|