Self nak - I'll send a v2. > If URB_ZERO_PACKET is set on a transfer that is an integral number > of maximum length packets (1k for USB3 bulk) then an additional > zero length fragment must be sent. ... > if (urb->num_sgs == 0) { > sg = NULL; > addr = (u64)urb->transfer_dma; > this_sg_len = urb->transfer_buffer_length; > num_trbs = 0; > } else { > sg = urb->sg; > addr = (u64)sg_dma_address(sg); > this_sg_len = sg_dma_len(sg); > /* > * We only need an upper bound for the number of TRBs. > * Add in two extra TRB for each subsequent segment. > */ > num_trbs = (urb->num_mapped_sgs - 1) * 2; > } > > /* One TRB for each 64k 'page' that contains data */ > num_trbs += DIV_ROUND_UP((addr & (TRB_MAX_BUFF_SIZE - 1)) + > urb->transfer_buffer_length, TRB_MAX_BUFF_SIZE); If a zero length transfer is requested from an aligned address the above sets num_trbs to zero so the ring wrap check will be incorrect. > max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); > > /* > * For v 1.0 we need to calculate the number of TD needed to > * complete the transfer. > * The code here is equivalent to 4.11.2.4. > */ > td_residue = urb->transfer_buffer_length; > if (unlikely(urb->transfer_flags & URB_ZERO_PACKET)) { Adding '|| unlikely(urb->transfer_buffer_length == 0)' here should fix it. The td_residue value is irrelevant in this case. > /* We need an extra zero length TD */ > num_trbs++; > td_residue++; > } David -- 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