Skip to content

Commit f2d9b99

Browse files
author
Sarah Sharp
committed
xhci: Set scatter-gather limit to avoid failed block writes.
Commit 35773da "usb: xhci: Link TRB must not occur within a USB payload burst" attempted to fix an issue found with USB ethernet adapters, and inadvertently broke USB storage devices. The patch attempts to ensure that transfers never span a segment, and rejects transfers that have more than 63 entries (or possibly less, if some entries cross 64KB boundaries). usb-storage limits the maximum transfer size to 120K, and we had assumed the block layer would pass a scatter-gather list of 4K entries, resulting in no more than 31 sglist entries: http://marc.info/?l=linux-usb&m=138498190419312&w=2 That assumption was wrong, since we've seen the driver reject a write that was 218 sectors long (of probably 512 bytes each): Jan 1 07:04:49 jidanni5 kernel: [ 559.624704] xhci_hcd 0000:00:14.0: Too many fragments 79, max 63 ... Jan 1 07:04:58 jidanni5 kernel: [ 568.622583] Write(10): 2a 00 00 06 85 0e 00 00 da 00 Limit the number of scatter-gather entries to half a ring segment. That should be margin enough in case some entries cross 64KB boundaries. Increase the number of TRBs per segment from 64 to 256, which should result in ring segments fitting on a 4K page. Signed-off-by: Sarah Sharp <[email protected]> Reported-by: [email protected] References: http://bugs.debian.org/733907 Fixes: 35773da ('usb: xhci: Link TRB must not occur within a USB payload burst') Cc: stable <[email protected]> # 3.12
1 parent d6c9ea9 commit f2d9b99

File tree

2 files changed

+3
-3
lines changed

2 files changed

+3
-3
lines changed

drivers/usb/host/xhci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4730,8 +4730,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
47304730
struct device *dev = hcd->self.controller;
47314731
int retval;
47324732

4733-
/* Accept arbitrarily long scatter-gather lists */
4734-
hcd->self.sg_tablesize = ~0;
4733+
/* Limit the block layer scatter-gather lists to half a segment. */
4734+
hcd->self.sg_tablesize = TRBS_PER_SEGMENT / 2;
47354735

47364736
/* support to build packet from discontinuous buffers */
47374737
hcd->self.no_sg_constraint = 1;

drivers/usb/host/xhci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,7 @@ union xhci_trb {
12791279
* since the command ring is 64-byte aligned.
12801280
* It must also be greater than 16.
12811281
*/
1282-
#define TRBS_PER_SEGMENT 64
1282+
#define TRBS_PER_SEGMENT 256
12831283
/* Allow two commands + a link TRB, along with any reserved command TRBs */
12841284
#define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3)
12851285
#define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16)

0 commit comments

Comments
 (0)