Commit f8f0a287 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-isdn.bkbits.net/linux-2.5.isdn

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 6d22ea1b 86315789
...@@ -413,26 +413,6 @@ static void capidev_free(struct capidev *cdev) ...@@ -413,26 +413,6 @@ static void capidev_free(struct capidev *cdev)
kmem_cache_free(capidev_cachep, cdev); kmem_cache_free(capidev_cachep, cdev);
} }
static struct capidev *capidev_find(u16 applid)
{
// FIXME this doesn't guarantee that the device won't go away shortly
struct list_head *l;
struct capidev *p = NULL;
read_lock(&capidev_list_lock);
list_for_each(l, &capidev_list) {
p = list_entry(l, struct capidev, list);
if (p->applid == applid)
break;
}
read_unlock(&capidev_list_lock);
if (l == &capidev_list)
return NULL;
return p;
}
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
/* -------- handle data queue --------------------------------------- */ /* -------- handle data queue --------------------------------------- */
...@@ -605,6 +585,16 @@ static void capi_signal(u16 applid, void *param) ...@@ -605,6 +585,16 @@ static void capi_signal(u16 applid, void *param)
return; return;
} }
BUG_ON(cdev->applid != applid);
if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
if (info == 0)
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
}
if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_IND) {
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
}
if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
skb_queue_tail(&cdev->recvqueue, skb); skb_queue_tail(&cdev->recvqueue, skb);
wake_up_interruptible(&cdev->recvwait); wake_up_interruptible(&cdev->recvwait);
...@@ -754,6 +744,11 @@ capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ...@@ -754,6 +744,11 @@ capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
} }
CAPIMSG_SETAPPID(skb->data, cdev->applid); CAPIMSG_SETAPPID(skb->data, cdev->applid);
if (CAPIMSG_COMMAND(skb->data) == CAPI_DISCONNECT_B3_RESP) {
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
}
cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb); cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb);
if (cdev->errcode) { if (cdev->errcode) {
...@@ -1601,36 +1596,8 @@ static int __init alloc_init(void) ...@@ -1601,36 +1596,8 @@ static int __init alloc_init(void)
return 0; return 0;
} }
static void lower_callback(unsigned int cmd, u32 contr, void *data)
{
struct capi_ncciinfo *np;
struct capidev *cdev;
switch (cmd) {
case KCI_CONTRUP:
printk(KERN_INFO "capi: controller %hu up\n", contr);
break;
case KCI_CONTRDOWN:
printk(KERN_INFO "capi: controller %hu down\n", contr);
break;
case KCI_NCCIUP:
np = (struct capi_ncciinfo *)data;
if ((cdev = capidev_find(np->applid)) == 0)
return;
(void)capincci_alloc(cdev, np->ncci);
break;
case KCI_NCCIDOWN:
np = (struct capi_ncciinfo *)data;
if ((cdev = capidev_find(np->applid)) == 0)
return;
(void)capincci_free(cdev, np->ncci);
break;
}
}
static struct capi_interface_user cuser = { static struct capi_interface_user cuser = {
name: "capi20", name: "capi20",
callback: lower_callback,
}; };
static char rev[32]; static char rev[32];
......
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
* *
*/ */
#define DBG(format, arg...) do { \
printk(KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg); \
} while (0)
#define CONFIG_AVMB1_COMPAT #define CONFIG_AVMB1_COMPAT
#include <linux/config.h> #include <linux/config.h>
...@@ -97,15 +101,9 @@ static struct capi_version driver_version = {2, 0, 1, 1<<4}; ...@@ -97,15 +101,9 @@ static struct capi_version driver_version = {2, 0, 1, 1<<4};
static char driver_serial[CAPI_SERIAL_LEN] = "0004711"; static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
static char capi_manufakturer[64] = "AVM Berlin"; static char capi_manufakturer[64] = "AVM Berlin";
#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 NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
static struct capi_appl applications[CAPI_MAXAPPL]; static struct capi_appl *applications[CAPI_MAXAPPL];
static struct capi_ctr *cards[CAPI_MAXCONTR]; static struct capi_ctr *cards[CAPI_MAXCONTR];
static int ncards; static int ncards;
static struct sk_buff_head recv_queue; static struct sk_buff_head recv_queue;
...@@ -125,11 +123,13 @@ static inline struct capi_ctr * ...@@ -125,11 +123,13 @@ static inline struct capi_ctr *
capi_ctr_get(struct capi_ctr *card) capi_ctr_get(struct capi_ctr *card)
{ {
if (card->driver->owner) { if (card->driver->owner) {
if (try_inc_mod_count(card->driver->owner)) if (try_inc_mod_count(card->driver->owner)) {
DBG("MOD_COUNT INC");
return card; return card;
else } else
return NULL; return NULL;
} }
DBG("MOD_COUNT INC");
return card; return card;
} }
...@@ -138,8 +138,11 @@ capi_ctr_put(struct capi_ctr *card) ...@@ -138,8 +138,11 @@ capi_ctr_put(struct capi_ctr *card)
{ {
if (card->driver->owner) if (card->driver->owner)
__MOD_DEC_USE_COUNT(card->driver->owner); __MOD_DEC_USE_COUNT(card->driver->owner);
DBG("MOD_COUNT DEC");
} }
/* ------------------------------------------------------------- */
static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
{ {
if (contr - 1 >= CAPI_MAXCONTR) if (contr - 1 >= CAPI_MAXCONTR)
...@@ -148,6 +151,14 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) ...@@ -148,6 +151,14 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
return cards[contr - 1]; return cards[contr - 1];
} }
static inline struct capi_appl *get_capi_appl_by_nr(u16 applid)
{
if (applid - 1 >= CAPI_MAXAPPL)
return NULL;
return applications[applid - 1];
}
/* -------- util functions ------------------------------------ */ /* -------- util functions ------------------------------------ */
static char *cardstate2str(unsigned short cardstate) static char *cardstate2str(unsigned short cardstate)
...@@ -207,9 +218,9 @@ static int proc_applications_read_proc(char *page, char **start, off_t off, ...@@ -207,9 +218,9 @@ static int proc_applications_read_proc(char *page, char **start, off_t off,
int i; int i;
int len = 0; int len = 0;
for (i=0; i < CAPI_MAXAPPL; i++) { for (i=1; i <= CAPI_MAXAPPL; i++) {
ap = &applications[i]; ap = get_capi_appl_by_nr(i);
if (ap->applid == 0) continue; if (!ap) continue;
len += sprintf(page+len, "%u %d %d %d %d %d\n", len += sprintf(page+len, "%u %d %d %d %d %d\n",
ap->applid, ap->applid,
ap->rparam.level3cnt, ap->rparam.level3cnt,
...@@ -246,9 +257,9 @@ static int proc_ncci_read_proc(char *page, char **start, off_t off, ...@@ -246,9 +257,9 @@ static int proc_ncci_read_proc(char *page, char **start, off_t off,
int i; int i;
int len = 0; int len = 0;
for (i=0; i < CAPI_MAXAPPL; i++) { for (i=1; i <= CAPI_MAXAPPL; i++) {
ap = &applications[i]; ap = get_capi_appl_by_nr(i);
if (ap->applid == 0) continue; if (!ap) continue;
for (np = ap->nccilist; np; np = np->next) { for (np = ap->nccilist; np; np = np->next) {
len += sprintf(page+len, "%d 0x%x %d %d\n", len += sprintf(page+len, "%d 0x%x %d %d\n",
np->applid, np->applid,
...@@ -393,9 +404,9 @@ static int proc_applstats_read_proc(char *page, char **start, off_t off, ...@@ -393,9 +404,9 @@ static int proc_applstats_read_proc(char *page, char **start, off_t off,
int i; int i;
int len = 0; int len = 0;
for (i=0; i < CAPI_MAXAPPL; i++) { for (i=1; i <= CAPI_MAXAPPL; i++) {
ap = &applications[i]; ap = get_capi_appl_by_nr(i);
if (ap->applid == 0) continue; if (!ap) continue;
len += sprintf(page+len, "%u %lu %lu %lu %lu\n", len += sprintf(page+len, "%u %lu %lu %lu %lu\n",
ap->applid, ap->applid,
ap->nrecvctlpkt, ap->nrecvctlpkt,
...@@ -514,15 +525,18 @@ static void register_appl(struct capi_ctr *card, u16 applid, capi_register_param ...@@ -514,15 +525,18 @@ static void register_appl(struct capi_ctr *card, u16 applid, capi_register_param
static void release_appl(struct capi_ctr *card, u16 applid) static void release_appl(struct capi_ctr *card, u16 applid)
{ {
struct capi_appl *ap = get_capi_appl_by_nr(applid);
struct capi_ncci **pp, **nextpp; struct capi_ncci **pp, **nextpp;
for (pp = &APPL(applid)->nccilist; *pp; pp = nextpp) { DBG("");
for (pp = &ap->nccilist; *pp; pp = nextpp) {
if (NCCI2CTRL((*pp)->ncci) == card->cnr) { if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
struct capi_ncci *np = *pp; struct capi_ncci *np = *pp;
*pp = np->next; *pp = np->next;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", applid, np->ncci); printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", applid, np->ncci);
kfree(np); kfree(np);
APPL(applid)->nncci--; ap->nncci--;
nextpp = pp; nextpp = pp;
} else { } else {
nextpp = &(*pp)->next; nextpp = &(*pp)->next;
...@@ -639,46 +653,6 @@ static void notify_down(u32 contr) ...@@ -639,46 +653,6 @@ static void notify_down(u32 contr)
spin_unlock(&users_lock); spin_unlock(&users_lock);
} }
/* -------- KCI_NCCIUP ---------------------------------------- */
static void notify_ncciup(u32 contr, u16 applid, u32 ncci)
{
struct list_head *l;
struct capi_interface_user *p;
struct capi_ncciinfo n;
n.applid = applid;
n.ncci = ncci;
/*printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);*/
spin_lock(&users_lock);
list_for_each(l, &users) {
p = list_entry(l, struct capi_interface_user, user_list);
if (!p->callback) continue;
(*p->callback) (KCI_NCCIUP, contr, &n);
}
spin_unlock(&users_lock);
};
/* -------- KCI_NCCIDOWN -------------------------------------- */
static void notify_nccidown(u32 contr, u16 applid, u32 ncci)
{
struct list_head *l;
struct capi_interface_user *p;
struct capi_ncciinfo n;
n.applid = applid;
n.ncci = ncci;
/*printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);*/
spin_lock(&users_lock);
list_for_each(l, &users) {
p = list_entry(l, struct capi_interface_user, user_list);
if (!p->callback) continue;
(*p->callback) (KCI_NCCIDOWN, contr, &n);
}
spin_unlock(&users_lock);
};
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
static void inline notify_doit(struct capi_notifier *np) static void inline notify_doit(struct capi_notifier *np)
...@@ -690,12 +664,6 @@ static void inline notify_doit(struct capi_notifier *np) ...@@ -690,12 +664,6 @@ static void inline notify_doit(struct capi_notifier *np)
case KCI_CONTRDOWN: case KCI_CONTRDOWN:
notify_down(np->controller); notify_down(np->controller);
break; break;
case KCI_NCCIUP:
notify_ncciup(np->controller, np->applid, np->ncci);
break;
case KCI_NCCIDOWN:
notify_nccidown(np->controller, np->applid, np->ncci);
break;
} }
} }
...@@ -770,7 +738,9 @@ static void controllercb_new_ncci(struct capi_ctr * card, ...@@ -770,7 +738,9 @@ static void controllercb_new_ncci(struct capi_ctr * card,
u16 appl, u32 ncci, u32 winsize) u16 appl, u32 ncci, u32 winsize)
{ {
struct capi_ncci *np; struct capi_ncci *np;
if (!VALID_APPLID(appl)) { struct capi_appl *ap = get_capi_appl_by_nr(appl);
if (!ap) {
printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl); printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl);
return; return;
} }
...@@ -787,30 +757,28 @@ static void controllercb_new_ncci(struct capi_ctr * card, ...@@ -787,30 +757,28 @@ static void controllercb_new_ncci(struct capi_ctr * card,
np->ncci = ncci; np->ncci = ncci;
np->winsize = winsize; np->winsize = winsize;
mq_init(np); mq_init(np);
np->next = APPL(appl)->nccilist; np->next = ap->nccilist;
APPL(appl)->nccilist = np; ap->nccilist = np;
APPL(appl)->nncci++; ap->nncci++;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci); printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci);
notify_push(KCI_NCCIUP, card->cnr, appl, ncci);
} }
static void controllercb_free_ncci(struct capi_ctr * card, static void controllercb_free_ncci(struct capi_ctr * card,
u16 appl, u32 ncci) u16 appl, u32 ncci)
{ {
struct capi_ncci **pp; struct capi_ncci **pp;
if (!VALID_APPLID(appl)) { struct capi_appl *ap = get_capi_appl_by_nr(appl);
if (!ap) {
printk(KERN_ERR "free_ncci: illegal appl %d\n", appl); printk(KERN_ERR "free_ncci: illegal appl %d\n", appl);
return; return;
} }
for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) { for (pp = &ap->nccilist; *pp; pp = &(*pp)->next) {
if ((*pp)->ncci == ncci) { if ((*pp)->ncci == ncci) {
struct capi_ncci *np = *pp; struct capi_ncci *np = *pp;
*pp = np->next; *pp = np->next;
kfree(np); kfree(np);
APPL(appl)->nncci--; ap->nncci--;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci); printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci);
notify_push(KCI_NCCIDOWN, card->cnr, appl, ncci);
return; return;
} }
} }
...@@ -833,37 +801,38 @@ static struct capi_ncci *find_ncci(struct capi_appl * app, u32 ncci) ...@@ -833,37 +801,38 @@ static struct capi_ncci *find_ncci(struct capi_appl * app, u32 ncci)
static void recv_handler(void *dummy) static void recv_handler(void *dummy)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct capi_appl *ap;
struct capi_ncci *np;
while ((skb = skb_dequeue(&recv_queue)) != 0) { while ((skb = skb_dequeue(&recv_queue)) != 0) {
u16 appl = CAPIMSG_APPID(skb->data); ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
struct capi_ncci *np; if (!ap) {
if (!VALID_APPLID(appl)) {
printk(KERN_ERR "kcapi: recv_handler: applid %d ? (%s)\n", printk(KERN_ERR "kcapi: recv_handler: applid %d ? (%s)\n",
appl, capi_message2str(skb->data)); ap->applid, capi_message2str(skb->data));
kfree_skb(skb); kfree_skb(skb);
continue; continue;
} }
if (APPL(appl)->signal == 0) { if (ap->signal == 0) {
printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n", printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n",
appl); ap->applid);
kfree_skb(skb); kfree_skb(skb);
continue; continue;
} }
if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
&& CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF
&& (np = find_ncci(APPL(appl), CAPIMSG_NCCI(skb->data))) != 0 && (np = find_ncci(ap, CAPIMSG_NCCI(skb->data))) != 0
&& mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) { && mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) {
printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n", printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
CAPIMSG_MSGID(skb->data), np->ncci); CAPIMSG_MSGID(skb->data), np->ncci);
} }
if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
&& CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) { && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
APPL(appl)->nrecvdatapkt++; ap->nrecvdatapkt++;
} else { } else {
APPL(appl)->nrecvctlpkt++; ap->nrecvctlpkt++;
} }
skb_queue_tail(&APPL(appl)->recv_queue, skb); skb_queue_tail(&ap->recv_queue, skb);
(APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param); (ap->signal) (ap->applid, ap->param);
} }
} }
...@@ -914,12 +883,14 @@ static void controllercb_handle_capimsg(struct capi_ctr * card, ...@@ -914,12 +883,14 @@ static void controllercb_handle_capimsg(struct capi_ctr * card,
static void controllercb_ready(struct capi_ctr * card) static void controllercb_ready(struct capi_ctr * card)
{ {
u16 appl; u16 appl;
struct capi_appl *ap;
card->cardstate = CARD_RUNNING; card->cardstate = CARD_RUNNING;
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
if (!VALID_APPLID(appl)) continue; ap = get_capi_appl_by_nr(appl);
register_appl(card, appl, &APPL(appl)->rparam); if (!ap) continue;
register_appl(card, appl, &ap->rparam);
} }
printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
...@@ -932,6 +903,8 @@ static void controllercb_reseted(struct capi_ctr * card) ...@@ -932,6 +903,8 @@ static void controllercb_reseted(struct capi_ctr * card)
{ {
u16 appl; u16 appl;
DBG("");
if (card->cardstate == CARD_DETECTED) if (card->cardstate == CARD_DETECTED)
return; return;
...@@ -943,13 +916,17 @@ static void controllercb_reseted(struct capi_ctr * card) ...@@ -943,13 +916,17 @@ static void controllercb_reseted(struct capi_ctr * card)
memset(card->serial, 0, sizeof(card->serial)); memset(card->serial, 0, sizeof(card->serial));
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
struct capi_appl *ap = get_capi_appl_by_nr(appl);
struct capi_ncci **pp, **nextpp; struct capi_ncci **pp, **nextpp;
for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) {
if (!ap)
continue;
for (pp = &ap->nccilist; *pp; pp = nextpp) {
if (NCCI2CTRL((*pp)->ncci) == card->cnr) { if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
struct capi_ncci *np = *pp; struct capi_ncci *np = *pp;
*pp = np->next; *pp = np->next;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci); printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci);
notify_push(KCI_NCCIDOWN, card->cnr, appl, np->ncci);
kfree(np); kfree(np);
nextpp = pp; nextpp = pp;
} else { } else {
...@@ -1141,29 +1118,39 @@ static u16 capi_isinstalled(void) ...@@ -1141,29 +1118,39 @@ static u16 capi_isinstalled(void)
static u16 capi_register(capi_register_params * rparam, u16 * applidp) static u16 capi_register(capi_register_params * rparam, u16 * applidp)
{ {
struct capi_appl *ap;
int appl; int appl;
int i; int i;
DBG("");
if (rparam->datablklen < 128) if (rparam->datablklen < 128)
return CAPI_LOGBLKSIZETOSMALL; return CAPI_LOGBLKSIZETOSMALL;
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
if (APPL_IS_FREE(appl)) if (applications[appl - 1] == NULL)
break; break;
} }
if (appl > CAPI_MAXAPPL) if (appl > CAPI_MAXAPPL)
return CAPI_TOOMANYAPPLS; return CAPI_TOOMANYAPPLS;
APPL_MARK_USED(appl); ap = kmalloc(sizeof(*ap), GFP_KERNEL);
skb_queue_head_init(&APPL(appl)->recv_queue); if (!ap)
APPL(appl)->nncci = 0; return CAPI_REGOSRESOURCEERR;
memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params)); memset(ap, 0, sizeof(*ap));
ap->applid = appl;
applications[appl - 1] = ap;
skb_queue_head_init(&ap->recv_queue);
ap->nncci = 0;
memcpy(&ap->rparam, rparam, sizeof(capi_register_params));
for (i = 0; i < CAPI_MAXCONTR; i++) { for (i = 0; i < CAPI_MAXCONTR; i++) {
if (!cards[i] || cards[i]->cardstate != CARD_RUNNING) if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue; continue;
register_appl(cards[i], appl, &APPL(appl)->rparam); register_appl(cards[i], appl, &ap->rparam);
} }
*applidp = appl; *applidp = appl;
printk(KERN_INFO "kcapi: appl %d up\n", appl); printk(KERN_INFO "kcapi: appl %d up\n", appl);
...@@ -1173,18 +1160,22 @@ static u16 capi_register(capi_register_params * rparam, u16 * applidp) ...@@ -1173,18 +1160,22 @@ static u16 capi_register(capi_register_params * rparam, u16 * applidp)
static u16 capi_release(u16 applid) static u16 capi_release(u16 applid)
{ {
struct capi_appl *ap = get_capi_appl_by_nr(applid);
int i; int i;
if (!VALID_APPLID(applid)) DBG("applid %#x", applid);
if (!ap)
return CAPI_ILLAPPNR; return CAPI_ILLAPPNR;
skb_queue_purge(&APPL(applid)->recv_queue);
skb_queue_purge(&ap->recv_queue);
for (i = 0; i < CAPI_MAXCONTR; i++) { for (i = 0; i < CAPI_MAXCONTR; i++) {
if (!cards[i] || cards[i]->cardstate != CARD_RUNNING) if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue; continue;
release_appl(cards[i], applid); release_appl(cards[i], applid);
} }
APPL(applid)->signal = 0; applications[applid - 1] = NULL;
APPL_MARK_FREE(applid); kfree(ap);
printk(KERN_INFO "kcapi: appl %d down\n", applid); printk(KERN_INFO "kcapi: appl %d down\n", applid);
return CAPI_NOERROR; return CAPI_NOERROR;
...@@ -1193,13 +1184,17 @@ static u16 capi_release(u16 applid) ...@@ -1193,13 +1184,17 @@ static u16 capi_release(u16 applid)
static u16 capi_put_message(u16 applid, struct sk_buff *skb) static u16 capi_put_message(u16 applid, struct sk_buff *skb)
{ {
struct capi_ctr *card; struct capi_ctr *card;
struct capi_appl *ap;
struct capi_ncci *np; struct capi_ncci *np;
int showctl = 0; int showctl = 0;
u8 cmd, subcmd; u8 cmd, subcmd;
DBG("applid %#x", applid);
if (ncards == 0) if (ncards == 0)
return CAPI_REGNOTINSTALLED; return CAPI_REGNOTINSTALLED;
if (!VALID_APPLID(applid)) ap = get_capi_appl_by_nr(applid);
if (!ap)
return CAPI_ILLAPPNR; return CAPI_ILLAPPNR;
if (skb->len < 12 if (skb->len < 12
|| !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
...@@ -1218,15 +1213,15 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb) ...@@ -1218,15 +1213,15 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb)
subcmd = CAPIMSG_SUBCOMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data);
if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0 if ((np = find_ncci(ap, CAPIMSG_NCCI(skb->data))) != 0
&& mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0) && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0)
return CAPI_SENDQUEUEFULL; return CAPI_SENDQUEUEFULL;
card->nsentdatapkt++; card->nsentdatapkt++;
APPL(applid)->nsentdatapkt++; ap->nsentdatapkt++;
if (card->traceflag > 2) showctl |= 2; if (card->traceflag > 2) showctl |= 2;
} else { } else {
card->nsentctlpkt++; card->nsentctlpkt++;
APPL(applid)->nsentctlpkt++; ap->nsentctlpkt++;
if (card->traceflag) showctl |= 2; if (card->traceflag) showctl |= 2;
} }
showctl |= (card->traceflag & 1); showctl |= (card->traceflag & 1);
...@@ -1250,11 +1245,12 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb) ...@@ -1250,11 +1245,12 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb)
static u16 capi_get_message(u16 applid, struct sk_buff **msgp) static u16 capi_get_message(u16 applid, struct sk_buff **msgp)
{ {
struct capi_appl *ap = get_capi_appl_by_nr(applid);
struct sk_buff *skb; struct sk_buff *skb;
if (!VALID_APPLID(applid)) if (!ap)
return CAPI_ILLAPPNR; return CAPI_ILLAPPNR;
if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0) if ((skb = skb_dequeue(&ap->recv_queue)) == 0)
return CAPI_RECEIVEQUEUEEMPTY; return CAPI_RECEIVEQUEUEEMPTY;
*msgp = skb; *msgp = skb;
return CAPI_NOERROR; return CAPI_NOERROR;
...@@ -1264,10 +1260,12 @@ static u16 capi_set_signal(u16 applid, ...@@ -1264,10 +1260,12 @@ static u16 capi_set_signal(u16 applid,
void (*signal) (u16 applid, void *param), void (*signal) (u16 applid, void *param),
void *param) void *param)
{ {
if (!VALID_APPLID(applid)) struct capi_appl *ap = get_capi_appl_by_nr(applid);
if (!ap)
return CAPI_ILLAPPNR; return CAPI_ILLAPPNR;
APPL(applid)->signal = signal; ap->signal = signal;
APPL(applid)->param = param; ap->param = param;
return CAPI_NOERROR; return CAPI_NOERROR;
} }
......
...@@ -69,15 +69,8 @@ struct capi_interface { ...@@ -69,15 +69,8 @@ struct capi_interface {
}; };
struct capi_ncciinfo {
__u16 applid;
__u32 ncci;
};
#define KCI_CONTRUP 0 /* struct capi_profile */ #define KCI_CONTRUP 0 /* struct capi_profile */
#define KCI_CONTRDOWN 1 /* NULL */ #define KCI_CONTRDOWN 1 /* NULL */
#define KCI_NCCIUP 2 /* struct capi_ncciinfo */
#define KCI_NCCIDOWN 3 /* struct capi_ncciinfo */
struct capi_interface_user { struct capi_interface_user {
char name[20]; char name[20];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment