RE: [PATCH] usb: xhci: Add support for URB_ZERO_PACKET

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux