diff options
| author | Vivek Gautam <gautam.vivek@samsung.com> | 2013-03-21 02:36:48 -0400 |
|---|---|---|
| committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2013-03-25 13:39:18 -0400 |
| commit | 1c11a172cb30492f5f6a82c6e118fdcd9946c34f (patch) | |
| tree | 65c567f41d7e67a63a15c0114478a39cb3785b4b | |
| parent | bafcaf6d84b5d1bf92dabd1ffe7753ed36b7552e (diff) | |
usb: xhci: Fix TRB transfer length macro used for Event TRB.
Use proper macro while extracting TRB transfer length from
Transfer event TRBs. Adding a macro EVENT_TRB_LEN (bits 0:23)
for the same, and use it instead of TRB_LEN (bits 0:16) in
case of event TRBs.
This patch should be backported to kernels as old as 2.6.31, that
contain the commit b10de142119a676552df3f0d2e3a9d647036c26a "USB: xhci:
Bulk transfer support". This patch will have issues applying to older
kernels.
Signed-off-by: Vivek gautam <gautam.vivek@samsung.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@vger.kernel.org
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 24 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.h | 4 |
2 files changed, 16 insertions, 12 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index ec2681918682..9652dae95942 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -2029,8 +2029,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
| 2029 | if (event_trb != ep_ring->dequeue && | 2029 | if (event_trb != ep_ring->dequeue && |
| 2030 | event_trb != td->last_trb) | 2030 | event_trb != td->last_trb) |
| 2031 | td->urb->actual_length = | 2031 | td->urb->actual_length = |
| 2032 | td->urb->transfer_buffer_length | 2032 | td->urb->transfer_buffer_length - |
| 2033 | - TRB_LEN(le32_to_cpu(event->transfer_len)); | 2033 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
| 2034 | else | 2034 | else |
| 2035 | td->urb->actual_length = 0; | 2035 | td->urb->actual_length = 0; |
| 2036 | 2036 | ||
| @@ -2062,7 +2062,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
| 2062 | /* Maybe the event was for the data stage? */ | 2062 | /* Maybe the event was for the data stage? */ |
| 2063 | td->urb->actual_length = | 2063 | td->urb->actual_length = |
| 2064 | td->urb->transfer_buffer_length - | 2064 | td->urb->transfer_buffer_length - |
| 2065 | TRB_LEN(le32_to_cpu(event->transfer_len)); | 2065 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
| 2066 | xhci_dbg(xhci, "Waiting for status " | 2066 | xhci_dbg(xhci, "Waiting for status " |
| 2067 | "stage event\n"); | 2067 | "stage event\n"); |
| 2068 | return 0; | 2068 | return 0; |
| @@ -2098,7 +2098,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
| 2098 | /* handle completion code */ | 2098 | /* handle completion code */ |
| 2099 | switch (trb_comp_code) { | 2099 | switch (trb_comp_code) { |
| 2100 | case COMP_SUCCESS: | 2100 | case COMP_SUCCESS: |
| 2101 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { | 2101 | if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { |
| 2102 | frame->status = 0; | 2102 | frame->status = 0; |
| 2103 | break; | 2103 | break; |
| 2104 | } | 2104 | } |
| @@ -2143,7 +2143,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
| 2143 | len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])); | 2143 | len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])); |
| 2144 | } | 2144 | } |
| 2145 | len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - | 2145 | len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - |
| 2146 | TRB_LEN(le32_to_cpu(event->transfer_len)); | 2146 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
| 2147 | 2147 | ||
| 2148 | if (trb_comp_code != COMP_STOP_INVAL) { | 2148 | if (trb_comp_code != COMP_STOP_INVAL) { |
| 2149 | frame->actual_length = len; | 2149 | frame->actual_length = len; |
| @@ -2201,7 +2201,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
| 2201 | case COMP_SUCCESS: | 2201 | case COMP_SUCCESS: |
| 2202 | /* Double check that the HW transferred everything. */ | 2202 | /* Double check that the HW transferred everything. */ |
| 2203 | if (event_trb != td->last_trb || | 2203 | if (event_trb != td->last_trb || |
| 2204 | TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { | 2204 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
| 2205 | xhci_warn(xhci, "WARN Successful completion " | 2205 | xhci_warn(xhci, "WARN Successful completion " |
| 2206 | "on short TX\n"); | 2206 | "on short TX\n"); |
| 2207 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) | 2207 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
| @@ -2229,18 +2229,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
| 2229 | "%d bytes untransferred\n", | 2229 | "%d bytes untransferred\n", |
| 2230 | td->urb->ep->desc.bEndpointAddress, | 2230 | td->urb->ep->desc.bEndpointAddress, |
| 2231 | td->urb->transfer_buffer_length, | 2231 | td->urb->transfer_buffer_length, |
| 2232 | TRB_LEN(le32_to_cpu(event->transfer_len))); | 2232 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); |
| 2233 | /* Fast path - was this the last TRB in the TD for this URB? */ | 2233 | /* Fast path - was this the last TRB in the TD for this URB? */ |
| 2234 | if (event_trb == td->last_trb) { | 2234 | if (event_trb == td->last_trb) { |
| 2235 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { | 2235 | if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
| 2236 | td->urb->actual_length = | 2236 | td->urb->actual_length = |
| 2237 | td->urb->transfer_buffer_length - | 2237 | td->urb->transfer_buffer_length - |
| 2238 | TRB_LEN(le32_to_cpu(event->transfer_len)); | 2238 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
| 2239 | if (td->urb->transfer_buffer_length < | 2239 | if (td->urb->transfer_buffer_length < |
| 2240 | td->urb->actual_length) { | 2240 | td->urb->actual_length) { |
| 2241 | xhci_warn(xhci, "HC gave bad length " | 2241 | xhci_warn(xhci, "HC gave bad length " |
| 2242 | "of %d bytes left\n", | 2242 | "of %d bytes left\n", |
| 2243 | TRB_LEN(le32_to_cpu(event->transfer_len))); | 2243 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); |
| 2244 | td->urb->actual_length = 0; | 2244 | td->urb->actual_length = 0; |
| 2245 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) | 2245 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
| 2246 | *status = -EREMOTEIO; | 2246 | *status = -EREMOTEIO; |
| @@ -2282,7 +2282,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
| 2282 | if (trb_comp_code != COMP_STOP_INVAL) | 2282 | if (trb_comp_code != COMP_STOP_INVAL) |
| 2283 | td->urb->actual_length += | 2283 | td->urb->actual_length += |
| 2284 | TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - | 2284 | TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - |
| 2285 | TRB_LEN(le32_to_cpu(event->transfer_len)); | 2285 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
| 2286 | } | 2286 | } |
| 2287 | 2287 | ||
| 2288 | return finish_td(xhci, td, event_trb, event, ep, status, false); | 2288 | return finish_td(xhci, td, event_trb, event, ep, status, false); |
| @@ -2370,7 +2370,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
| 2370 | * transfer type | 2370 | * transfer type |
| 2371 | */ | 2371 | */ |
| 2372 | case COMP_SUCCESS: | 2372 | case COMP_SUCCESS: |
| 2373 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) | 2373 | if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) |
| 2374 | break; | 2374 | break; |
| 2375 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) | 2375 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) |
| 2376 | trb_comp_code = COMP_SHORT_TX; | 2376 | trb_comp_code = COMP_SHORT_TX; |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d798b6931914..63582719e0fb 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
| @@ -972,6 +972,10 @@ struct xhci_transfer_event { | |||
| 972 | __le32 flags; | 972 | __le32 flags; |
| 973 | }; | 973 | }; |
| 974 | 974 | ||
| 975 | /* Transfer event TRB length bit mask */ | ||
| 976 | /* bits 0:23 */ | ||
| 977 | #define EVENT_TRB_LEN(p) ((p) & 0xffffff) | ||
| 978 | |||
| 975 | /** Transfer Event bit fields **/ | 979 | /** Transfer Event bit fields **/ |
| 976 | #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f) | 980 | #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f) |
| 977 | 981 | ||
