• [PATCH v3 16/19] thunderbolt: Allocate ring HopID automatically if requ

    From Mika Westerberg@21:1/5 to All on Mon Oct 2 12:50:02 2017
    Thunderbolt services should not care which HopID (ring) they use for
    sending and receiving packets over the high-speed DMA path, so make tb_ring_alloc_rx() and tb_ring_alloc_tx() accept negative HopID. This
    means that the NHI will allocate next available HopID for the caller automatically.

    These HopIDs will be allocated from the range which is not reserved for
    the Thunderbolt protocol (8 .. hop_count - 1).

    The allocated HopID can be retrieved from ring->hop field after the ring
    has been allocated successfully if needed.

    Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
    Reviewed-by: Michael Jamet <michael.jamet@intel.com>
    Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
    Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
    ---
    drivers/thunderbolt/nhi.c | 78 ++++++++++++++++++++++++++++++++++++-----------
    1 file changed, 60 insertions(+), 18 deletions(-)

    diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
    index af0a80ddf594..0e79eebfcbb7 100644
    --- a/drivers/thunderbolt/nhi.c
    +++ b/drivers/thunderbolt/nhi.c
    @@ -26,6 +26,8 @@
    * use this ring for anything else.
    */
    #define RING_E2E_UNUSED_HOPID 2
    +/* HopIDs 0-7 are reserved by the Thunderbolt protocol */
    +#define RING_FIRST_USABLE_HOPID 8

    /*
    * Minimal number of vectors when we use MSI-X. Two for control channel
    @@ -411,6 +413,62 @@ static void ring_release_msix(struct tb_ring *ring)
    ring->irq = 0;
    }

    +static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
    +{
    + int ret = 0;
    +
    + spin_lock_irq(&nhi->lock);
    +
    + if (ring->hop < 0) {
    + unsigned int i;
    +
    + /*
    + * Automatically allocate HopID from the non-reserved
    + * range 8 .. hop_count - 1.
    + */
    + for (i = RING_FIRST_USABLE_HOPID; i < nhi->hop_count; i+