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)
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
/* -------- 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;
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
......@@ -574,15 +574,8 @@ static void capi_signal(struct capi20_appl *ap)
u16 datahandle;
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
struct capincci *np;
struct sk_buff *skb = 0;
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) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
if (info == 0)
......@@ -795,12 +788,12 @@ capi_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
cdev->ap.private = cdev;
cdev->ap.recv_message = capi_recv_message;
cdev->errcode = capi20_register(ap);
if (cdev->errcode) {
ap->applid = 0;
return -EIO;
}
capi20_set_signal(ap, capi_signal);
}
return (int)ap->applid;
......
......@@ -1372,36 +1372,32 @@ static void handle_data(_cmsg * cmsg, struct sk_buff *skb)
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;
while (capi20_get_message(ap, &skb) == CAPI_NOERROR) {
capi_message2cmsg(&s_cmsg, skb->data);
if (debugmode > 2)
printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",
ap->applid, capi_cmsg2str(&s_cmsg));
if (s_cmsg.Command == CAPI_DATA_B3
&& s_cmsg.Subcommand == CAPI_IND) {
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++;
capi_message2cmsg(&s_cmsg, skb->data);
if (debugmode > 2)
printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",
ap->applid, capi_cmsg2str(&s_cmsg));
if (s_cmsg.Command == CAPI_DATA_B3
&& s_cmsg.Subcommand == CAPI_IND) {
handle_data(&s_cmsg, skb);
global.nrecvdatapkt++;
return;
}
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)
global.ap.rparam.datablkcnt = 16;
global.ap.rparam.datablklen = 2048;
global.ap.recv_message = capidrv_recv_message;
errcode = capi20_register(&global.ap);
if (errcode) {
MOD_DEC_USE_COUNT;
......@@ -2328,8 +2325,6 @@ static int __init capidrv_init(void)
return -EIO;
}
capi20_set_signal(&global.ap, capidrv_signal);
ncontr = profile.ncontroller;
for (contr = 1; contr <= ncontr; contr++) {
errcode = capi20_get_profile(contr, &profile);
......
......@@ -186,13 +186,11 @@ static int proc_applications_read_proc(char *page, char **start, off_t off,
for (i=1; i <= CAPI_MAXAPPL; i++) {
ap = get_capi_appl_by_nr(i);
if (!ap) continue;
len += sprintf(page+len, "%u %d %d %d %d %d\n",
ap->applid,
ap->rparam.level3cnt,
ap->rparam.datablkcnt,
ap->rparam.datablklen,
ap->nncci,
skb_queue_len(&ap->recv_queue));
len += sprintf(page+len, "%u %d %d %d\n",
ap->applid,
ap->rparam.level3cnt,
ap->rparam.datablkcnt,
ap->rparam.datablklen);
if (len <= off) {
off -= len;
len = 0;
......@@ -566,20 +564,14 @@ static void recv_handler(void *dummy)
kfree_skb(skb);
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
&& CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
ap->nrecvdatapkt++;
} else {
ap->nrecvctlpkt++;
}
skb_queue_tail(&ap->recv_queue, skb);
(ap->signal) (ap);
ap->recv_message(ap, skb);
}
}
......@@ -870,9 +862,6 @@ u16 capi20_register(struct capi20_appl *ap)
ap->applid = applid;
applications[applid - 1] = ap;
ap->signal = NULL;
skb_queue_head_init(&ap->recv_queue);
ap->nncci = 0;
ap->nrecvctlpkt = 0;
ap->nrecvdatapkt = 0;
ap->nsentctlpkt = 0;
......@@ -897,7 +886,6 @@ u16 capi20_release(struct capi20_appl *ap)
DBG("applid %#x", ap->applid);
skb_queue_purge(&ap->recv_queue);
for (i = 0; i < CAPI_MAXCONTR; i++) {
if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue;
......@@ -968,31 +956,6 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
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])
{
struct capi_ctr *card;
......
......@@ -49,20 +49,16 @@ typedef struct kcapi_carddef {
#include <linux/skbuff.h>
#define KCI_CONTRUP 0 /* struct capi_profile */
#define KCI_CONTRDOWN 1 /* NULL */
#define KCI_CONTRUP 0 /* arg: struct capi_profile */
#define KCI_CONTRDOWN 1 /* arg: NULL */
struct capi20_appl {
u16 applid;
capi_register_params rparam;
void (*recv_message)(struct capi20_appl *ap, struct sk_buff *skb);
void *private;
/* 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 nrecvdatapkt;
unsigned long nsentctlpkt;
......@@ -78,9 +74,6 @@ u16 capi20_isinstalled(void);
u16 capi20_register(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_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_version(u32 contr, struct capi_version *verp);
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