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 | ||