Re: [RFC PATCH 19/20] xhci: v1.0 scatterlist enqueue support (td-fragment rework)

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

 



On 08/22/2014 08:16 PM, Dan Williams wrote:
> v1.0 hosts require that TD-fragments (portions of a TD that do not end
> on a MPB boundary) not cross a TRB segment boundary.  This constraint is
> in addition to the constraint that a TRB may not specify a transfer that
> crosses a 64K boundary. This enabling permits the driver to accept
> scatterlists of nearly any geometry.  "Nearly" because there is one
> unlikely remaining degenerate case of a driver submitting a transfer
> that consumes all the TRBs in a segment before hitting an MBP boundary.
> That case is trapped and the transfer is rejected.
> 
> Given the multi-dimensional constraints of queuing TRBs from a
> scattelist, this implementation does not attempt to pre-calculate the
> number TRBs in a TD.  Instead it attempts a dry-run of enqueuing the
> TRBs to the ring.  If it discovers a TD-fragment straddling a segment
> boundary it backs up to the last MBP boundary, inserts a link-trb at
> that boundary, and restarts enqueuing in the next segment.  A side
> effect of not pre-calculating the number of required TRBs is that the
> ring is now expanded as the scatterlist is walked, rather than in
> prepare_ring().
> 
> To simplify the math and forgo the need to track (union xhci_trb *) and
> (struct xhci_segment *) pointers, modulo-power-of-2 ring indexes are
> used.  A small portion of the patch is adding infrastructure to convert
> from a (struct xhci_ring_pointer *) to an integer index.
> 
> Glossary of acronyms:
> TRB: Transfer Request Buffer, 16-byte xhci-hardware scatterlist entry
> 
> TD: Transfer Descriptor, the set of trbs that comprise a transfer
> 
> TRB segment: A contiguous allocation of TRBs.  They are of size
>   PAGE_SIZE in the xhci driver.  Each segment ends with a link TRB
>   pointing to the next segment, but the link trb may appear at any TRB
>   boundary in the segment.
> 
> Ring: A linked list of segments.
> 
> MBP: Max Burst Packet, is the minimum amount of data hardware expects to
>   transfer before the end of a segment (assuming the TD spans a segment
>   boundary).
> 
...

>  }
>  
> +static unsigned int xhci_ring_num_trbs_free(struct xhci_ring *ring)
> +{
> +	unsigned int enq_idx, deq_idx, num_trbs, num_segs;
> +
> +	enq_idx = xhci_ring_pointer_to_index(&ring->enq);
> +	deq_idx = xhci_ring_pointer_to_index(&ring->deq);
> +
> +	num_trbs = to_xhci_ring_index(ring, deq_idx - (enq_idx + 1));
> +	num_segs = (enq_idx % TRBS_PER_SEGMENT + num_trbs) / TRBS_PER_SEGMENT;
> +

I'm don't really understand whats going on here. If we for example have a ring with 3 segments, 256 trbs per segment.
enqueue is the first trb in seg3 and dequeue first trb in seg2. 

enq_idx = 512
deq_idx = 256
deq_idq - (enq_idx + 1) = 256 - 513 = -xxx
Looks to me like to_xhci_ring_index() doesn't really like negative values

I feel that there's something clever going on here that I just can't figure out

-Mathias




--
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