--- zzzz-none-000/linux-2.4.17/drivers/isdn/avmb1/kcapi.c 2001-12-21 17:41:54.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/drivers/isdn/avmb1/kcapi.c 2004-11-24 13:23:00.000000000 +0000 @@ -64,6 +64,7 @@ __u32 ncci; __u32 winsize; int nmsg; + spinlock_t lock; struct msgidqueue *msgidqueue; struct msgidqueue *msgidlast; struct msgidqueue *msgidfree; @@ -103,14 +104,14 @@ #define APPL(a) (&applications[(a)-1]) #define VALID_APPLID(a) ((a) && (a) <= CAPI_MAXAPPL && APPL(a)->applid == a) #define APPL_IS_FREE(a) (APPL(a)->applid == 0) -#define APPL_MARK_FREE(a) do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0); -#define APPL_MARK_USED(a) do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0); +#define APPL_MARK_FREE(a) do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0) +#define APPL_MARK_USED(a) do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0) #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) #define VALID_CARD(c) ((c) > 0 && (c) <= CAPI_MAXCONTR) #define CARD(c) (&cards[(c)-1]) -#define CARDNR(cp) (((cp)-cards)+1) +#define CARDNR(cp) ((((cp)-cards)+1) & 0xff) static struct capi_appl applications[CAPI_MAXAPPL]; static struct capi_ctr cards[CAPI_MAXCONTR]; @@ -535,8 +536,13 @@ * user process, not in bh. */ MOD_INC_USE_COUNT; +#if 0 if (schedule_task(&tq_state_notify) == 0) MOD_DEC_USE_COUNT; +#else /* #if 0 */ + queue_task(&tq_state_notify, &tq_immediate); + mark_bh(IMMEDIATE_BH); +#endif /* #if 0 */ return 0; } @@ -545,7 +551,13 @@ static void notify_up(__u32 contr) { struct capi_interface_user *p; + __u16 appl; + for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { + if (!VALID_APPLID(appl)) continue; + if (APPL(appl)->releasing) continue; + CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam); + } printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr); spin_lock(&capi_users_lock); for (p = capi_users; p; p = p->next) { @@ -640,6 +652,7 @@ static inline void mq_init(struct capi_ncci * np) { int i; + np->lock = SPIN_LOCK_UNLOCKED; np->msgidqueue = 0; np->msgidlast = 0; np->nmsg = 0; @@ -654,8 +667,11 @@ static inline int mq_enqueue(struct capi_ncci * np, __u16 msgid) { struct msgidqueue *mq; - if ((mq = np->msgidfree) == 0) + spin_lock_bh(&np->lock); + if ((mq = np->msgidfree) == 0) { + spin_unlock_bh(&np->lock); return 0; + } np->msgidfree = mq->next; mq->msgid = msgid; mq->next = 0; @@ -665,12 +681,14 @@ if (!np->msgidqueue) np->msgidqueue = mq; np->nmsg++; + spin_unlock_bh(&np->lock); return 1; } static inline int mq_dequeue(struct capi_ncci * np, __u16 msgid) { struct msgidqueue **pp; + spin_lock_bh(&np->lock); for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) { if ((*pp)->msgid == msgid) { struct msgidqueue *mq = *pp; @@ -680,9 +698,11 @@ mq->next = np->msgidfree; np->msgidfree = mq; np->nmsg--; + spin_unlock_bh(&np->lock); return 1; } } + spin_unlock_bh(&np->lock); return 0; } @@ -705,12 +725,16 @@ nextpp = &(*pp)->next; } } - APPL(appl)->releasing--; - if (APPL(appl)->releasing <= 0) { - APPL(appl)->signal = 0; - APPL_MARK_FREE(appl); - printk(KERN_INFO "kcapi: appl %d down\n", appl); - } + if (APPL(appl)->releasing) { /* only release if the application was marked for release */ + printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing); + APPL(appl)->releasing--; + if (APPL(appl)->releasing <= 0) { + APPL(appl)->signal = 0; + APPL_MARK_FREE(appl); + printk(KERN_INFO "kcapi: appl %d down\n", appl); + } + } else + printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr); } /* * ncci management @@ -863,16 +887,7 @@ static void controllercb_ready(struct capi_ctr * card) { - __u16 appl; - card->cardstate = CARD_RUNNING; - - for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { - if (!VALID_APPLID(appl)) continue; - if (APPL(appl)->releasing) continue; - card->driver->register_appl(card, appl, &APPL(appl)->rparam); - } - printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", CARDNR(card), card->name); @@ -1104,7 +1119,7 @@ int appl; int i; - if (rparam->datablklen < 128) + if (rparam->datablklen < 64) return CAPI_LOGBLKSIZETOSMALL; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {