Commit 7914ddde authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: CAPI: Get rid of capi_signal mechanism

On arrival of a new message, kernelcapi used to call
capi20_appl::signal(), which, from the application, would call back
to capi20_get_message(). So we rather just push the message down
directly, saving this detour.
parent c0734386
...@@ -566,7 +566,7 @@ static int handle_minor_send(struct capiminor *mp) ...@@ -566,7 +566,7 @@ static int handle_minor_send(struct capiminor *mp)
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
/* -------- function called by lower level -------------------------- */ /* -------- function called by lower level -------------------------- */
static void capi_signal(struct capi20_appl *ap) static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
{ {
struct capidev *cdev = ap->private; struct capidev *cdev = ap->private;
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
...@@ -574,15 +574,8 @@ static void capi_signal(struct capi20_appl *ap) ...@@ -574,15 +574,8 @@ static void capi_signal(struct capi20_appl *ap)
u16 datahandle; u16 datahandle;
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
struct capincci *np; struct capincci *np;
struct sk_buff *skb = 0;
u32 ncci; u32 ncci;
capi20_get_message(&cdev->ap, &skb);
if (!skb) {
printk(KERN_ERR "BUG: capi_signal: no skb\n");
return;
}
if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_CONF) { if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field u16 info = CAPIMSG_U16(skb->data, 12); // Info field
if (info == 0) if (info == 0)
...@@ -795,12 +788,12 @@ capi_ioctl(struct inode *inode, struct file *file, ...@@ -795,12 +788,12 @@ capi_ioctl(struct inode *inode, struct file *file,
return -EFAULT; return -EFAULT;
cdev->ap.private = cdev; cdev->ap.private = cdev;
cdev->ap.recv_message = capi_recv_message;
cdev->errcode = capi20_register(ap); cdev->errcode = capi20_register(ap);
if (cdev->errcode) { if (cdev->errcode) {
ap->applid = 0; ap->applid = 0;
return -EIO; return -EIO;
} }
capi20_set_signal(ap, capi_signal);
} }
return (int)ap->applid; return (int)ap->applid;
......
...@@ -1372,36 +1372,32 @@ static void handle_data(_cmsg * cmsg, struct sk_buff *skb) ...@@ -1372,36 +1372,32 @@ static void handle_data(_cmsg * cmsg, struct sk_buff *skb)
static _cmsg s_cmsg; static _cmsg s_cmsg;
static void capidrv_signal(struct capi20_appl *ap) static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
{ {
struct sk_buff *skb = 0; capi_message2cmsg(&s_cmsg, skb->data);
if (debugmode > 2)
while (capi20_get_message(ap, &skb) == CAPI_NOERROR) { printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",
capi_message2cmsg(&s_cmsg, skb->data); ap->applid, capi_cmsg2str(&s_cmsg));
if (debugmode > 2)
printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n", if (s_cmsg.Command == CAPI_DATA_B3
ap->applid, capi_cmsg2str(&s_cmsg)); && s_cmsg.Subcommand == CAPI_IND) {
handle_data(&s_cmsg, skb);
if (s_cmsg.Command == CAPI_DATA_B3 global.nrecvdatapkt++;
&& s_cmsg.Subcommand == CAPI_IND) { return;
handle_data(&s_cmsg, skb);
global.nrecvdatapkt++;
continue;
}
if ((s_cmsg.adr.adrController & 0xffffff00) == 0)
handle_controller(&s_cmsg);
else if ((s_cmsg.adr.adrPLCI & 0xffff0000) == 0)
handle_plci(&s_cmsg);
else
handle_ncci(&s_cmsg);
/*
* data of skb used in s_cmsg,
* free data when s_cmsg is not used again
* thanks to Lars Heete <hel@admin.de>
*/
kfree_skb(skb);
global.nrecvctlpkt++;
} }
if ((s_cmsg.adr.adrController & 0xffffff00) == 0)
handle_controller(&s_cmsg);
else if ((s_cmsg.adr.adrPLCI & 0xffff0000) == 0)
handle_plci(&s_cmsg);
else
handle_ncci(&s_cmsg);
/*
* data of skb used in s_cmsg,
* free data when s_cmsg is not used again
* thanks to Lars Heete <hel@admin.de>
*/
kfree_skb(skb);
global.nrecvctlpkt++;
} }
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
...@@ -2313,6 +2309,7 @@ static int __init capidrv_init(void) ...@@ -2313,6 +2309,7 @@ static int __init capidrv_init(void)
global.ap.rparam.datablkcnt = 16; global.ap.rparam.datablkcnt = 16;
global.ap.rparam.datablklen = 2048; global.ap.rparam.datablklen = 2048;
global.ap.recv_message = capidrv_recv_message;
errcode = capi20_register(&global.ap); errcode = capi20_register(&global.ap);
if (errcode) { if (errcode) {
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
...@@ -2328,8 +2325,6 @@ static int __init capidrv_init(void) ...@@ -2328,8 +2325,6 @@ static int __init capidrv_init(void)
return -EIO; return -EIO;
} }
capi20_set_signal(&global.ap, capidrv_signal);
ncontr = profile.ncontroller; ncontr = profile.ncontroller;
for (contr = 1; contr <= ncontr; contr++) { for (contr = 1; contr <= ncontr; contr++) {
errcode = capi20_get_profile(contr, &profile); errcode = capi20_get_profile(contr, &profile);
......
...@@ -186,13 +186,11 @@ static int proc_applications_read_proc(char *page, char **start, off_t off, ...@@ -186,13 +186,11 @@ static int proc_applications_read_proc(char *page, char **start, off_t off,
for (i=1; i <= CAPI_MAXAPPL; i++) { for (i=1; i <= CAPI_MAXAPPL; i++) {
ap = get_capi_appl_by_nr(i); ap = get_capi_appl_by_nr(i);
if (!ap) continue; if (!ap) continue;
len += sprintf(page+len, "%u %d %d %d %d %d\n", len += sprintf(page+len, "%u %d %d %d\n",
ap->applid, ap->applid,
ap->rparam.level3cnt, ap->rparam.level3cnt,
ap->rparam.datablkcnt, ap->rparam.datablkcnt,
ap->rparam.datablklen, ap->rparam.datablklen);
ap->nncci,
skb_queue_len(&ap->recv_queue));
if (len <= off) { if (len <= off) {
off -= len; off -= len;
len = 0; len = 0;
...@@ -566,20 +564,14 @@ static void recv_handler(void *dummy) ...@@ -566,20 +564,14 @@ static void recv_handler(void *dummy)
kfree_skb(skb); kfree_skb(skb);
continue; continue;
} }
if (ap->signal == 0) {
printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n",
ap->applid);
kfree_skb(skb);
continue;
}
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) {
ap->nrecvdatapkt++; ap->nrecvdatapkt++;
} else { } else {
ap->nrecvctlpkt++; ap->nrecvctlpkt++;
} }
skb_queue_tail(&ap->recv_queue, skb); ap->recv_message(ap, skb);
(ap->signal) (ap);
} }
} }
...@@ -870,9 +862,6 @@ u16 capi20_register(struct capi20_appl *ap) ...@@ -870,9 +862,6 @@ u16 capi20_register(struct capi20_appl *ap)
ap->applid = applid; ap->applid = applid;
applications[applid - 1] = ap; applications[applid - 1] = ap;
ap->signal = NULL;
skb_queue_head_init(&ap->recv_queue);
ap->nncci = 0;
ap->nrecvctlpkt = 0; ap->nrecvctlpkt = 0;
ap->nrecvdatapkt = 0; ap->nrecvdatapkt = 0;
ap->nsentctlpkt = 0; ap->nsentctlpkt = 0;
...@@ -897,7 +886,6 @@ u16 capi20_release(struct capi20_appl *ap) ...@@ -897,7 +886,6 @@ u16 capi20_release(struct capi20_appl *ap)
DBG("applid %#x", ap->applid); DBG("applid %#x", ap->applid);
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;
...@@ -968,31 +956,6 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) ...@@ -968,31 +956,6 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
EXPORT_SYMBOL(capi20_put_message); EXPORT_SYMBOL(capi20_put_message);
u16 capi20_get_message(struct capi20_appl *ap, struct sk_buff **msgp)
{
struct sk_buff *skb;
if (ap->applid == 0)
return CAPI_ILLAPPNR;
if ((skb = skb_dequeue(&ap->recv_queue)) == 0)
return CAPI_RECEIVEQUEUEEMPTY;
*msgp = skb;
return CAPI_NOERROR;
}
EXPORT_SYMBOL(capi20_get_message);
u16 capi20_set_signal(struct capi20_appl *ap,
void (*signal) (struct capi20_appl *appl))
{
if (ap->applid == 0)
return CAPI_ILLAPPNR;
ap->signal = signal;
return CAPI_NOERROR;
}
EXPORT_SYMBOL(capi20_set_signal);
u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]) u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
{ {
struct capi_ctr *card; struct capi_ctr *card;
......
...@@ -49,20 +49,16 @@ typedef struct kcapi_carddef { ...@@ -49,20 +49,16 @@ typedef struct kcapi_carddef {
#include <linux/skbuff.h> #include <linux/skbuff.h>
#define KCI_CONTRUP 0 /* struct capi_profile */ #define KCI_CONTRUP 0 /* arg: struct capi_profile */
#define KCI_CONTRDOWN 1 /* NULL */ #define KCI_CONTRDOWN 1 /* arg: NULL */
struct capi20_appl { struct capi20_appl {
u16 applid; u16 applid;
capi_register_params rparam; capi_register_params rparam;
void (*recv_message)(struct capi20_appl *ap, struct sk_buff *skb);
void *private; void *private;
/* internal to kernelcapi.o */ /* internal to kernelcapi.o */
void (*signal) (struct capi20_appl *ap);
struct sk_buff_head recv_queue;
int nncci;
struct capi_ncci *nccilist;
unsigned long nrecvctlpkt; unsigned long nrecvctlpkt;
unsigned long nrecvdatapkt; unsigned long nrecvdatapkt;
unsigned long nsentctlpkt; unsigned long nsentctlpkt;
...@@ -78,9 +74,6 @@ u16 capi20_isinstalled(void); ...@@ -78,9 +74,6 @@ u16 capi20_isinstalled(void);
u16 capi20_register(struct capi20_appl *ap); u16 capi20_register(struct capi20_appl *ap);
u16 capi20_release(struct capi20_appl *ap); u16 capi20_release(struct capi20_appl *ap);
u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb); u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb);
u16 capi20_get_message(struct capi20_appl *ap, struct sk_buff **msgp);
u16 capi20_set_signal(struct capi20_appl *ap,
void (*signal) (struct capi20_appl *ap));
u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]); u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]);
u16 capi20_get_version(u32 contr, struct capi_version *verp); u16 capi20_get_version(u32 contr, struct capi_version *verp);
u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]); u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]);
......
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