| From 23ad0a96cdb2c388f5fcd1f1e0290ed0a5965d7f Mon Sep 17 00:00:00 2001 |
| From: Paul Zimmerman <Paul.Zimmerman@synopsys.com> |
| Date: Sat, 12 Feb 2011 14:07:20 -0800 |
| Subject: [PATCH] xhci: Fix errors in the running total calculations in the |
| TRB math |
| |
| commit 5807795bd4dececdf553719cc02869e633395787 upstream. |
| |
| Calculations like |
| |
| running_total = TRB_MAX_BUFF_SIZE - |
| (sg_dma_address(sg) & (TRB_MAX_BUFF_SIZE - 1)); |
| if (running_total != 0) |
| num_trbs++; |
| |
| are incorrect, because running_total can never be zero, so the if() |
| expression will never be true. I think the intention was that |
| running_total be in the range of 0 to TRB_MAX_BUFF_SIZE-1, not 1 |
| to TRB_MAX_BUFF_SIZE. So adding a |
| |
| running_total &= TRB_MAX_BUFF_SIZE - 1; |
| |
| fixes the problem. |
| |
| This patch should be queued for stable kernels back to 2.6.31. |
| |
| [PG: 34 doesn't have count_isoc_trbs_needed() hence this has |
| only two of the three upstream running_total changes.] |
| |
| Signed-off-by: Paul Zimmerman <paulz@synopsys.com> |
| Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c |
| index 8bf5563..e4afa99 100644 |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -1711,6 +1711,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) |
| /* Scatter gather list entries may cross 64KB boundaries */ |
| running_total = TRB_MAX_BUFF_SIZE - |
| (sg_dma_address(sg) & (TRB_MAX_BUFF_SIZE - 1)); |
| + running_total &= TRB_MAX_BUFF_SIZE - 1; |
| if (running_total != 0) |
| num_trbs++; |
| |
| @@ -1978,6 +1979,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, |
| /* How much data is (potentially) left before the 64KB boundary? */ |
| running_total = TRB_MAX_BUFF_SIZE - |
| (urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1)); |
| + running_total &= TRB_MAX_BUFF_SIZE - 1; |
| |
| /* If there's some data on this 64KB chunk, or we have to send a |
| * zero-length transfer, we need at least one TRB |
| -- |
| 1.7.4.4 |
| |