diff options
-rw-r--r-- | sys/dev/usb/ohci.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index a7db2d5..5a5ae49 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -501,9 +501,8 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, len = alen; cur = sp; - dataphys = DMAADDR(dma, 0); - dataphysend = OHCI_PAGE(dataphys + len - 1); + dataphysend = OHCI_PAGE(DMAADDR(dma, len - 1)); tdflags = htole32( (rd ? OHCI_TD_IN : OHCI_TD_OUT) | (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) | @@ -518,8 +517,8 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, /* The OHCI hardware can handle at most one page crossing. */ #if defined(__NetBSD__) || defined(__OpenBSD__) - if (OHCI_PAGE(dataphys) == OHCI_PAGE(dataphysend) || - OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == OHCI_PAGE(dataphysend)) + if (OHCI_PAGE(dataphys) == dataphysend || + OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend) #elif defined(__FreeBSD__) /* XXX This is pretty broken: Because we do not allocate * a contiguous buffer (contiguous in physical pages) we @@ -527,7 +526,7 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, * So check whether the start and end of the buffer are on * the same page. */ - if (OHCI_PAGE(dataphys) == OHCI_PAGE(dataphysend)) + if (OHCI_PAGE(dataphys) == dataphysend) #endif { /* we can handle it in this TD */ @@ -544,6 +543,8 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, /* must use multiple TDs, fill as much as possible. */ curlen = 2 * OHCI_PAGE_SIZE - OHCI_PAGE_MASK(dataphys); + if (curlen > len) /* may have fit in one page */ + curlen = len; #elif defined(__FreeBSD__) /* See comment above (XXX) */ curlen = OHCI_PAGE_SIZE - @@ -568,6 +569,9 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, dataphys, dataphys + curlen - 1)); if (len == 0) break; + if (len < 0) + panic("Length went negative: %d curlen %d dma %p offset %08x", len, curlen, *dma, (int)offset); + DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n")); offset += curlen; cur = next; |