On 10/01/2014 11:28 AM, vichy wrote:
> hi all:
> for iso transactions, we use below function to calculate trbs
>        addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset);
>         td_len = urb->iso_frame_desc[i].length;
>         num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)),
>                         TRB_MAX_BUFF_SIZE);
> 
> Could we use below method to calculate it instead?
>        addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset);
>         td_len = urb->iso_frame_desc[i].length;
> -        num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)),
>                         TRB_MAX_BUFF_SIZE);
> +       num_trbs = DIV_ROUND_UP(td_len ,TRB_MAX_BUFF_SIZE);
> 
> Why the trb calculation for iso is related to dma address?
> 
> Appreciate your kind help in advance,
> 

Because the TRB buffers must be aligned at TRB_MAX_BUFF_SIZE boundary, (except 
for the first TRB)
If the starting addr is not aligned at this boundary it may cut the first TRB 
buffer short, and
we need one extra TRB to cover the data 

|-------|-------|-------|-------|,  | = TRB_MAX_BUFF_SIZE boundaries, in this 
example 8 "chars" per trb,  
|-----dddddddddddddddddddd------|,  d = data, 20 chars

Without any alignment restrictions  we would fit 20 data chars to 3 TRBs.
But in this case we need 4 trbs, because the first TRB can only hold two d's 
before it hits a boundary.
The two middle ones are full (8 d's per TRB), and last TRB has remaining 2 d's  
     

Alan's original explanation is here:
http://marc.info/?l=linux-usb&m=131307343023488&w=2

-Mathias
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to