unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
struct xhci_ring *ep_ring;
+ struct usb_interface_cache *intfc;
unsigned int max_packet;
enum xhci_ring_type ring_type;
u32 max_esit_payload;
unsigned int mult;
unsigned int avg_trb_len;
unsigned int err_count = 0;
+ unsigned int is_ums_dev = 0;
+ unsigned int i;
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
mult = xhci_get_endpoint_mult(udev, ep);
max_packet = usb_endpoint_maxp(&ep->desc);
- max_burst = xhci_get_endpoint_max_burst(udev, ep);
avg_trb_len = max_esit_payload;
+ /*
+ * VL805 errata - Bulk OUT bursts to superspeed mass-storage
+ * devices behind hub ports can cause data corruption with
+ * non-wMaxPacket-multiple transfers.
+ */
+ for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
+ intfc = udev->config->intf_cache[i];
+ /*
+ * Slight hack - look at interface altsetting 0, which
+ * should be the UMS bulk-only interface. If the class
+ * matches, then we disable out bursts for all OUT
+ * endpoints because endpoint assignments may change
+ * between alternate settings.
+ */
+ if (intfc->altsetting[0].desc.bInterfaceClass ==
+ USB_CLASS_MASS_STORAGE) {
+ is_ums_dev = 1;
+ break;
+ }
+ }
+ if (xhci->quirks & XHCI_VLI_SS_BULK_OUT_BUG &&
+ usb_endpoint_is_bulk_out(&ep->desc) && is_ums_dev &&
+ udev->route)
+ max_burst = 0;
+ else
+ max_burst = xhci_get_endpoint_max_burst(udev, ep);
+
/* FIXME dig Mult and streams info out of ep companion desc */
/* Allow 3 retries for everything but isoc, set CErr = 3 */