On Thu, Apr 26, 2018 at 05:44:18PM +0200, Martin Pieuchot wrote:
> In xhci_xfer_tdsize() makes sure we do not forget to count packets with
> a size inferior as UE_GET_SIZE(mps).  This is only really used by the
> isoc code, so the remaining calculation can now be corrected.
> 
> While here use UE_GET_SIZE() coherently and howmany() where it applies.
> 
> Finally remove a KASSERT() that can be triggered by a driver trusting
> a badly crafter device descriptor.

OK

> Index: xhci.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/xhci.c,v
> retrieving revision 1.79
> diff -u -p -r1.79 xhci.c
> --- xhci.c    26 Apr 2018 10:19:31 -0000      1.79
> +++ xhci.c    26 Apr 2018 15:38:42 -0000
> @@ -2488,7 +2488,7 @@ xhci_xfer_tdsize(struct usbd_xfer *xfer,
>       if (len == 0)
>               return XHCI_TRB_TDREM(0);
>  
> -     npkt = (remain - len) / mps;
> +     npkt = howmany(remain - len, UE_GET_SIZE(mps));
>       if (npkt > 31)
>               npkt = 31;
>  
> @@ -2630,7 +2630,7 @@ xhci_device_generic_start(struct usbd_xf
>               return (USBD_IOERROR);
>  
>       /* How many TRBs do we need for this transfer? */
> -     ntrb = (xfer->length + XHCI_TRB_MAXSIZE - 1) / XHCI_TRB_MAXSIZE;
> +     ntrb = howmany(xfer->length, XHCI_TRB_MAXSIZE);
>  
>       /* If the buffer crosses a 64k boundary, we need one more. */
>       len0 = XHCI_TRB_MAXSIZE - (paddr & (XHCI_TRB_MAXSIZE - 1));
> @@ -2641,7 +2641,7 @@ xhci_device_generic_start(struct usbd_xf
>  
>       /* If we need to append a zero length packet, we need one more. */
>       if ((xfer->flags & USBD_FORCE_SHORT_XFER || xfer->length == 0) &&
> -         (xfer->length % mps == 0))
> +         (xfer->length % UE_GET_SIZE(mps) == 0))
>               ntrb++;
>  
>       if (xp->free_trbs < ntrb)
> @@ -2781,14 +2781,12 @@ xhci_device_isoc_start(struct usbd_xfer 
>       /* We'll do the first TRB once we're finished with the chain. */
>       trb0 = xhci_xfer_get_trb(sc, xfer, &toggle0, (ntrb == 1));
>  
> -     remain = xfer->length;
> +     remain = xfer->length - len0;
>       paddr += len0;
>  
>       /* Chain more TRBs if needed. */
>       for (i = ntrb - 1; i > 0; i--) {
>               len = xfer->frlengths[ntrb - i];
> -
> -             KASSERT(len <= UGETW(ed->wMaxPacketSize));
>  
>               /* Next (or Last) TRB. */
>               trb = xhci_xfer_get_trb(sc, xfer, &toggle, (i == 1));

Reply via email to