xhci: Regression fix for 3.13.
Hi Greg, Here's one bug fix for 3.13. usb-net added support for bulk scatter-gather in 3.12, and it triggered a bug in the xHCI driver. This bug causes xHCI hosts to send an unexpected short transfer, which will cause the USB ethernet device to stop sending packets. The patch is marked for the 3.12 stable kernel. It's a long standing bug, but the usb-net drivers are the first to trigger it. The only other driver that does bulk scatter-gather (usb-storage) will not trigger this bug. I'm not sure what the effect of the no-op TRBs will be on various xHCI host controllers, so I would only like to be conservative and only queue it for 3.13 and 3.12 stable. Please queue this for 3.13. Sarah Sharp -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSnPB6AAoJEBMGWMLi1Gc54rYP/jfd+LC3M/SFxeMGwkU5oCr5 +2xs9mUJso0izC+KFXS39pLvqdFiVQ+Jitl0JtIGj6sbjg02jwrPn+cknqKrg1zm R8gYolnNjEGUBKUk1t7epy/wrR5mtms/XCM6VG+K7Dxd4A0NacncHUjlECBqjm5i P2NhprvdUtJdtr+Hxmy1Z7MH85swKT0YHt4jnUD1QqIKbKiCGmSZ6ZvhMioDs9xL ivGbQLMh44vuZxDLk9OcFUCtIUqjdavAbZcFejeq6z+Zyul7SLioOk9OtKtA240E XvczX13vs73bgKGLuA0lEoi26NhynHkok9sdV317XsgYgiFZL1pd9q5sgmwvjyWO qMOMSgmwpHLV3YDzl9FGpj04h/eHHkYQQ0US08CMRtIadp6sbVOCtrVNdnLLkuAT A+HNMXFZO+8l5UxJFTms2lETdKNaQmG2qH7ur4m+TIiy54wEdwySHrR8XpyBEZZo tmFsD+RFhy5YT2Y+OVsxJDwUsxDcxFF8at2BWOYH6yefguSndebC9ReqPiKwynQn h4cf1308jcQUwU+gwCLxTp6ZTXFiZXPwFfJlk8z5/rXvbI8mNeoUxaPJCTb0cI0Z J10sm7+P5DEP4KveB0ChviHsb4D2auDqs8JedMjzi4soI/UPIaOKdPuDmwAYBnvA FOIoeJgkGoIBgmlIxwHI =kO2u -----END PGP SIGNATURE----- Merge tag 'for-usb-linus-2013-12-02' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus Sarah writes: xhci: Regression fix for 3.13. Hi Greg, Here's one bug fix for 3.13. usb-net added support for bulk scatter-gather in 3.12, and it triggered a bug in the xHCI driver. This bug causes xHCI hosts to send an unexpected short transfer, which will cause the USB ethernet device to stop sending packets. The patch is marked for the 3.12 stable kernel. It's a long standing bug, but the usb-net drivers are the first to trigger it. The only other driver that does bulk scatter-gather (usb-storage) will not trigger this bug. I'm not sure what the effect of the no-op TRBs will be on various xHCI host controllers, so I would only like to be conservative and only queue it for 3.13 and 3.12 stable. Please queue this for 3.13. Sarah Sharp
This commit is contained in:
commit
d63e502dbe
|
@ -2973,8 +2973,58 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
|
|||
}
|
||||
|
||||
while (1) {
|
||||
if (room_on_ring(xhci, ep_ring, num_trbs))
|
||||
break;
|
||||
if (room_on_ring(xhci, ep_ring, num_trbs)) {
|
||||
union xhci_trb *trb = ep_ring->enqueue;
|
||||
unsigned int usable = ep_ring->enq_seg->trbs +
|
||||
TRBS_PER_SEGMENT - 1 - trb;
|
||||
u32 nop_cmd;
|
||||
|
||||
/*
|
||||
* Section 4.11.7.1 TD Fragments states that a link
|
||||
* TRB must only occur at the boundary between
|
||||
* data bursts (eg 512 bytes for 480M).
|
||||
* While it is possible to split a large fragment
|
||||
* we don't know the size yet.
|
||||
* Simplest solution is to fill the trb before the
|
||||
* LINK with nop commands.
|
||||
*/
|
||||
if (num_trbs == 1 || num_trbs <= usable || usable == 0)
|
||||
break;
|
||||
|
||||
if (ep_ring->type != TYPE_BULK)
|
||||
/*
|
||||
* While isoc transfers might have a buffer that
|
||||
* crosses a 64k boundary it is unlikely.
|
||||
* Since we can't add NOPs without generating
|
||||
* gaps in the traffic just hope it never
|
||||
* happens at the end of the ring.
|
||||
* This could be fixed by writing a LINK TRB
|
||||
* instead of the first NOP - however the
|
||||
* TRB_TYPE_LINK_LE32() calls would all need
|
||||
* changing to check the ring length.
|
||||
*/
|
||||
break;
|
||||
|
||||
if (num_trbs >= TRBS_PER_SEGMENT) {
|
||||
xhci_err(xhci, "Too many fragments %d, max %d\n",
|
||||
num_trbs, TRBS_PER_SEGMENT - 1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
nop_cmd = cpu_to_le32(TRB_TYPE(TRB_TR_NOOP) |
|
||||
ep_ring->cycle_state);
|
||||
ep_ring->num_trbs_free -= usable;
|
||||
do {
|
||||
trb->generic.field[0] = 0;
|
||||
trb->generic.field[1] = 0;
|
||||
trb->generic.field[2] = 0;
|
||||
trb->generic.field[3] = nop_cmd;
|
||||
trb++;
|
||||
} while (--usable);
|
||||
ep_ring->enqueue = trb;
|
||||
if (room_on_ring(xhci, ep_ring, num_trbs))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ep_ring == xhci->cmd_ring) {
|
||||
xhci_err(xhci, "Do not support expand command ring\n");
|
||||
|
|
|
@ -1264,6 +1264,8 @@ typedef void (*usb_complete_t)(struct urb *);
|
|||
* @sg: scatter gather buffer list, the buffer size of each element in
|
||||
* the list (except the last) must be divisible by the endpoint's
|
||||
* max packet size if no_sg_constraint isn't set in 'struct usb_bus'
|
||||
* (FIXME: scatter-gather under xHCI is broken for periodic transfers.
|
||||
* Do not use urb->sg for interrupt endpoints for now, only bulk.)
|
||||
* @num_mapped_sgs: (internal) number of mapped sg entries
|
||||
* @num_sgs: number of entries in the sg list
|
||||
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
|
||||
|
|
Loading…
Reference in New Issue