On Thursday 03 November 2005 8:44 am, Alan Stern wrote:
> Dave:
>
> When the ehci-hcd driver prepares a control URB, it tests for a
> zero-length data stage by looking at the transfer_dma value instead of the
> transfer_buffer_length. (In fact it does this even for non-control URBs,
> which is an additional aspect of the same bug.)
>
> However, under certain circumstances it's possible for transfer_dma to be
> 0 while transfer_buffer_length is non-zero. This can happen when a
> freshly allocated page (mapped to address 0 and marked Copy-On-Write, but
> never written to) is used as the source buffer for an OUT transfer. This
> patch (as598) fixes the problem.
>
> Alan Stern
>
>
>
> Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: David Brownell <[EMAIL PROTECTED]>
... yeah that code was probably some of the first ehci code that got
written after making the root hub behave, and it never quite seemed
to really need the (minor) cleanup it was owed. This fix looks
pretty clean; if devices can enumerate with it, any breakage will
be in rare configs.
>
> ---
>
> This was originally posted back when email to you was bouncing, so you
> may not have seen it. Hence I'm sending it again.
>
> I've given this only light testing, but it seems to work okay. You should
> go over it to be sure.
>
> Index: usb-2.6/drivers/usb/host/ehci-q.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/host/ehci-q.c
> +++ usb-2.6/drivers/usb/host/ehci-q.c
> @@ -514,18 +514,18 @@ qh_urb_transaction (
> qtd->urb = urb;
> qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
> list_add_tail (&qtd->qtd_list, head);
> +
> + /* for zero length DATA stages, STATUS is always IN */
> + if (len == 0)
> + token |= (1 /* "in" */ << 8);
> }
>
> /*
> * data transfer stage: buffer setup
> */
> - if (likely (len > 0))
> - buf = urb->transfer_dma;
> - else
> - buf = 0;
> + buf = urb->transfer_dma;
>
> - /* for zero length DATA stages, STATUS is always IN */
> - if (!buf || is_input)
> + if (is_input)
> token |= (1 /* "in" */ << 8);
> /* else it's already initted to "out" pid (0 << 8) */
>
> @@ -572,7 +572,7 @@ qh_urb_transaction (
> * control requests may need a terminating data "status" ack;
> * bulk ones may need a terminating short packet (zero length).
> */
> - if (likely (buf != 0)) {
> + if (likely (urb->transfer_buffer_length != 0)) {
> int one_more = 0;
>
> if (usb_pipecontrol (urb->pipe)) {
>
-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel