aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivek Gautam <gautam.vivek@samsung.com>2013-03-21 02:36:48 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2013-03-25 13:39:18 -0400
commit1c11a172cb30492f5f6a82c6e118fdcd9946c34f (patch)
tree65c567f41d7e67a63a15c0114478a39cb3785b4b
parentbafcaf6d84b5d1bf92dabd1ffe7753ed36b7552e (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.c24
-rw-r--r--drivers/usb/host/xhci.h4
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