diff options
-rw-r--r-- | drivers/net/ipa/gsi.c | 5 | ||||
-rw-r--r-- | drivers/net/ipa/gsi.h | 5 | ||||
-rw-r--r-- | drivers/net/ipa/gsi_trans.c | 26 |
3 files changed, 29 insertions, 7 deletions
diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c index fcd05acf893b..9e307eebd33f 100644 --- a/drivers/net/ipa/gsi.c +++ b/drivers/net/ipa/gsi.c @@ -722,6 +722,9 @@ static struct gsi_trans *gsi_channel_trans_last(struct gsi_channel *channel) list = &trans_info->alloc; if (!list_empty(list)) goto done; + list = &trans_info->committed; + if (!list_empty(list)) + goto done; list = &trans_info->pending; if (!list_empty(list)) goto done; @@ -1364,7 +1367,7 @@ gsi_event_trans(struct gsi *gsi, struct gsi_event *event) * first *unfilled* event in the ring (following the last filled one). * * Events are sequential within the event ring, and transactions are - * sequential within the transaction pool. + * sequential within the transaction array. * * Note that @index always refers to an element *within* the event ring. */ diff --git a/drivers/net/ipa/gsi.h b/drivers/net/ipa/gsi.h index 982c57550ef3..85fb03465713 100644 --- a/drivers/net/ipa/gsi.h +++ b/drivers/net/ipa/gsi.h @@ -89,7 +89,8 @@ struct gsi_trans_info { spinlock_t spinlock; /* protects updates to the lists */ struct list_head alloc; /* allocated, not committed */ - struct list_head pending; /* committed, awaiting completion */ + struct list_head committed; /* committed, awaiting doorbell */ + struct list_head pending; /* pending, awaiting completion */ struct list_head complete; /* completed, awaiting poll */ struct list_head polled; /* returned by gsi_channel_poll_one() */ }; @@ -185,7 +186,7 @@ void gsi_teardown(struct gsi *gsi); * @gsi: GSI pointer * @channel_id: Channel whose limit is to be returned * - * Return: The maximum number of TREs oustanding on the channel + * Return: The maximum number of TREs outstanding on the channel */ u32 gsi_channel_tre_max(struct gsi *gsi, u32 channel_id); diff --git a/drivers/net/ipa/gsi_trans.c b/drivers/net/ipa/gsi_trans.c index 29496ca15825..45572ebb76e9 100644 --- a/drivers/net/ipa/gsi_trans.c +++ b/drivers/net/ipa/gsi_trans.c @@ -241,15 +241,31 @@ struct gsi_trans *gsi_channel_trans_complete(struct gsi_channel *channel) struct gsi_trans, links); } -/* Move a transaction from the allocated list to the pending list */ +/* Move a transaction from the allocated list to the committed list */ +static void gsi_trans_move_committed(struct gsi_trans *trans) +{ + struct gsi_channel *channel = &trans->gsi->channel[trans->channel_id]; + struct gsi_trans_info *trans_info = &channel->trans_info; + + spin_lock_bh(&trans_info->spinlock); + + list_move_tail(&trans->links, &trans_info->committed); + + spin_unlock_bh(&trans_info->spinlock); +} + +/* Move transactions from the committed list to the pending list */ static void gsi_trans_move_pending(struct gsi_trans *trans) { struct gsi_channel *channel = &trans->gsi->channel[trans->channel_id]; struct gsi_trans_info *trans_info = &channel->trans_info; + struct list_head list; spin_lock_bh(&trans_info->spinlock); - list_move_tail(&trans->links, &trans_info->pending); + /* Move this transaction and all predecessors to the pending list */ + list_cut_position(&list, &trans_info->committed, &trans->links); + list_splice_tail(&list, &trans_info->pending); spin_unlock_bh(&trans_info->spinlock); } @@ -581,13 +597,14 @@ static void __gsi_trans_commit(struct gsi_trans *trans, bool ring_db) if (channel->toward_ipa) gsi_trans_tx_committed(trans); - gsi_trans_move_pending(trans); + gsi_trans_move_committed(trans); /* Ring doorbell if requested, or if all TREs are allocated */ if (ring_db || !atomic_read(&channel->trans_info.tre_avail)) { /* Report what we're handing off to hardware for TX channels */ if (channel->toward_ipa) gsi_trans_tx_queued(trans); + gsi_trans_move_pending(trans); gsi_channel_doorbell(channel); } } @@ -710,7 +727,7 @@ int gsi_channel_trans_init(struct gsi *gsi, u32 channel_id) return -ENOMEM; /* We can't use more TREs than there are available in the ring. - * This limits the number of transactions that can be oustanding. + * This limits the number of transactions that can be outstanding. * Worst case is one TRE per transaction (but we actually limit * it to something a little less than that). We allocate resources * for transactions (including transaction structures) based on @@ -747,6 +764,7 @@ int gsi_channel_trans_init(struct gsi *gsi, u32 channel_id) spin_lock_init(&trans_info->spinlock); INIT_LIST_HEAD(&trans_info->alloc); + INIT_LIST_HEAD(&trans_info->committed); INIT_LIST_HEAD(&trans_info->pending); INIT_LIST_HEAD(&trans_info->complete); INIT_LIST_HEAD(&trans_info->polled); |