dect
/
libdect
Archived
13
0
Fork 0

lce: order MM transactions properly

Order MM transactions such that the last one opened is shut down first.

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2010-09-02 18:49:18 +02:00
parent 661b96d618
commit 1038f1b083
3 changed files with 28 additions and 6 deletions

View File

@ -337,6 +337,17 @@ static inline void list_splice_tail_init(struct list_head *list,
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_last_entry - get the last element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_last_entry(ptr, type, member) \
list_entry((ptr)->prev, type, member)
/**
* list_for_each_entry - iterate over list of given type

View File

@ -1274,15 +1274,25 @@ static int dect_transaction_alloc_tv(const struct dect_data_link *ddl,
static void dect_transaction_link(struct dect_data_link *ddl,
struct dect_transaction *ta)
{
struct dect_transaction *last;
/* Insert MM transactions at the end of the list to make sure they get
* destroyed last on shutdown. This makes sure that other protocols
* which might invoke and wait for the completion of MM transactions
* have their transactions terminated first and don't mistake a link
* shutdown or a protocol specific error for a MM error.
*
* Ordering among MM transactions is such that the transaction opened
* last is shut down first.
*/
if (ta->pd == DECT_PD_MM)
list_add_tail(&ta->list, &ddl->transactions);
else
if (ta->pd == DECT_PD_MM) {
last = list_last_entry(&ddl->transactions, struct dect_transaction, list);
if (!list_empty(&ddl->transactions) && last->pd == DECT_PD_MM)
list_add_tail(&ta->list, &last->list);
else
list_add_tail(&ta->list, &ddl->transactions);
} else
list_add(&ta->list, &ddl->transactions);
}

View File

@ -440,7 +440,8 @@ static void dect_mm_procedure_complete(struct dect_handle *dh,
struct dect_mm_endpoint *mme,
struct dect_mm_procedure *mp)
{
mm_debug(mme, "complete procedure");
mm_debug(mme, "complete %s procedure", dect_mm_proc[mp->type].name);
assert(mme->current == mp);
if (dect_timer_running(mp->timer))
dect_timer_stop(dh, mp->timer);
@ -451,8 +452,8 @@ static void dect_mm_procedure_complete(struct dect_handle *dh,
dect_transaction_close(dh, &mp->transaction, DECT_DDL_RELEASE_PARTIAL);
mp->type = DECT_MMP_NONE;
if (mme->procedure[!mme->current->role].type != DECT_MMP_NONE)
mme->current = &mme->procedure[!mme->current->role];
if (mme->procedure[!mp->role].type != DECT_MMP_NONE)
mme->current = &mme->procedure[!mp->role];
else
mme->current = NULL;
}