Hello. On 12/21/2015 03:46 PM, Vikas Bansal wrote:
From: Sumit Batra <sumit.batra@xxxxxxxxxxx> Pre-Condition URB with Scatter Gather list is queued to bulk OUT endpoint. Every buffer in scatter gather list is not a multiple of maximum packet size for that endpoint(short packet). CHAIN bit is set for all TRBs in a TD so that the DMA happens to all of them at once. Issue DMA operation copies all the CHAINED TRBs at contiguous device memory. But since the original packet was a short packet, so the actual data is re-aligned after this DMA operation. At device end this re-aligned data causes data integrity issue with applications like ICMP ping. Solution Don't set the CHAINED bit for these TRBs, if their buffers are not a multiple of maximum packet size. This will reduce the benefit in throughput as required from a scatter gather implementation, but this reduces the CPU utilization. And solves the data integrity issue on Device End Signed-off-by: Sumit Batra <sumit.batra@xxxxxxxxxxx> Signed-off-by: Vikas Bansal <vikas.bansal@xxxxxxxxxxx> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7d34cbf..7363dee 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3110,7 +3110,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, * TRB to indicate it's the last TRB in the chain. */ if (num_trbs > 1) { - field |= TRB_CHAIN; + if (this_sg_len % + usb_endpoint_maxp(&urb->ep->desc) == 0)
Indent with 2 extra tabs ISO 1 please -- it'll be easier on the eyes (blends with the next statement otherwise).
+ field |= TRB_CHAIN; } else { /* FIXME - add check for ZERO_PACKET flag before this */ td->last_trb = ep_ring->enqueue;
MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html