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: --- hw/usb-ohci.c.orig 2011-12-22 02:44:49.650537164 +0200 +++ hw/usb-ohci.c 2011-12-22 03:50:37.545642734 +0200 @@ -1025,10 +1031,10 @@ static int ohci_service_td(OHCIState *oh 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; -- Andriy Gapon