On Thu, 11 Aug 2011, Andiry Xu wrote: > > Please don't submit zero-length transfers. The xHCI driver just isn't > > able to handle it. Arguably, it probably should have just rejected your > > URB when it found a zero length buffer, so I'll probably be submitting a > > patch to fix that. > > > > I think queue a zero-length TRB to xhci host is OK. I've not tested it, > but the issue here seems is caused by td->last_trb = NULL. Check > count_isoc_trbs_needed(), num_trbs will be 0 if the packet length is > zero and (addr & (TRB_MAS_BUFF_SIZE - 1)) is zero. We can not return > num_trbs as 0 to xhci_queue_isoc_tx(), which caused a td added to ep's > td list, while it's not actually queued to ep ring and last_trb is not > set. > > In order to avoid this, we just make sure count_isoc_trbs_needed() > always return 1 or larger numbers, instead of reject the urb. Is that > feasible? I just looked for the first time at the code in count_isoc_trbs_needed(). It does seem rather sub-optimal. The basic idea is that you need to know how many TRB buffers can cover the memory area spanned by the packet data, where a TRB buffer's size cannot be larger than TRB_MAX_BUFF_SIZE and all but the first buffer must be aligned on a TRB_MAX_BUFF_SIZE boundary, right? With a slight adjustment in the case of a zero-length packet, since you always need at least one TRB. Given that the packet data starts at addr and has length td_len, the number of TRBs should be calculated as follows: num = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1))), TRB_MAX_BUFF_SIZE); num += (num == 0); No need for a running_total or a loop. Alan Stern -- 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