Skip to content

Commit

Permalink
[PATCH] USB: EHCI: fix conflation of buf == 0 with len == 0
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jan 4, 2006
1 parent 959eea2 commit 6912354
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions drivers/usb/host/ehci-q.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) */

Expand Down Expand Up @@ -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)) {
Expand Down

0 comments on commit 6912354

Please sign in to comment.