Two fixes: 1146,1149c1146 < if((td->cbp & ~0xFFF) == (td->cbp0 & ~0xFFF)) < bp->wp = pa2ptr(td->cbp); < else < bp->wp = bp->rp + 0x1000 + (td->cbp&0xFFF); --- > bp->wp = bp->rp + (td->cbp - td->cbp0); td->cbp and td->cbp0 are the real addresses corresponding to virtual addresses bp->wp and bp->rp respectively. The 'else' clause will make BLEN(bp) = (bp->wp - bp->rp) equal to 0x1000 or greater, which can't be right because usb packets are never that big! If td->cbp and td->cbp0 are on different pages, the pages must be adjacent (because no packet is greater than 4k), and the corresponding virtual pages containing bp->wp and bp->rp must also be adjacent (otherwise the mapping would be wrong). So the replacement line works in all cases. I've tested this and confirmed with Nemo that it's sensible. 1370a1368,1369 > if(ed == nil) > return; This "shouldn't happen" code prevents a panic which I've observed but I'm too lazy to investigate. Reference: /n/sources/patch/applied/usbohci-page-boundary Date: Wed Sep 9 17:16:58 CES 2009 Signed-off-by: miller@hamnavoe.com --- /sys/src/9/pc/usbohci.c Wed Sep 9 17:16:15 2009 +++ /sys/src/9/pc/usbohci.c Wed Sep 9 17:16:09 2009 @@ -1143,10 +1143,7 @@ if(mode == OREAD){ if(td->cbp == 0) panic("ohci: short packet but cbp == 0"); - if((td->cbp & ~0xFFF) == (td->cbp0 & ~0xFFF)) - bp->wp = pa2ptr(td->cbp); - else - bp->wp = bp->rp + 0x1000 + (td->cbp&0xFFF); + bp->wp = bp->rp + (td->cbp - td->cbp0); if(bp->wp < bp->rp) panic("ohci: wp < rp"); /* @@ -1368,6 +1365,8 @@ Td *td; ed = io->ed; + if(ed == nil) + return; ed->ctrl |= Edskip; for(td = ed->tds; td != nil; td = td->next) if(td->bp != nil)