Commit 10b080a3 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Have the CAPI application alloc struct capi_appl

Inside the kernel, we rather go the standard way than converting
to/from indices to the actual data structs all the time.
parent b77e092a
......@@ -121,7 +121,7 @@ struct capincci {
struct capidev {
struct list_head list;
u16 applid;
struct capi20_appl ap;
u16 errcode;
unsigned userflags;
......@@ -309,7 +309,7 @@ static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
mp = 0;
if (cdev->userflags & CAPIFLAG_HIGHJACKING)
mp = np->minorp = capiminor_alloc(cdev->applid, ncci);
mp = np->minorp = capiminor_alloc(cdev->ap.applid, ncci);
if (mp) {
mp->nccip = np;
#ifdef _DEBUG_REFCOUNT
......@@ -399,10 +399,10 @@ static void capidev_free(struct capidev *cdev)
{
unsigned long flags;
if (cdev->applid)
capi20_release(cdev->applid); // XXX
cdev->applid = 0;
if (cdev->ap.applid) {
capi20_release(&cdev->ap);
cdev->ap.applid = 0;
}
skb_queue_purge(&cdev->recvqueue);
write_lock_irqsave(&capidev_list_lock, flags);
......@@ -583,7 +583,7 @@ static void capi_signal(u16 applid, void *param)
return;
}
BUG_ON(cdev->applid != applid);
BUG_ON(cdev->ap.applid != applid);
if (CAPIMSG_COMMAND(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
......@@ -666,7 +666,7 @@ capi_read(struct file *file, char *buf, size_t count, loff_t *ppos)
if (ppos != &file->f_pos)
return -ESPIPE;
if (!cdev->applid)
if (!cdev->ap.applid)
return -ENODEV;
if ((skb = skb_dequeue(&cdev->recvqueue)) == 0) {
......@@ -717,7 +717,7 @@ capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
if (ppos != &file->f_pos)
return -ESPIPE;
if (!cdev->applid)
if (!cdev->ap.applid)
return -ENODEV;
skb = alloc_skb(count, GFP_USER);
......@@ -740,14 +740,14 @@ capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
return -EINVAL;
}
}
CAPIMSG_SETAPPID(skb->data, cdev->applid);
CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
if (CAPIMSG_COMMAND(skb->data) == CAPI_DISCONNECT_B3_RESP) {
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
}
cdev->errcode = capi20_put_message(cdev->applid, skb);
cdev->errcode = capi20_put_message(cdev->ap.applid, skb);
if (cdev->errcode) {
kfree_skb(skb);
......@@ -767,7 +767,7 @@ capi_poll(struct file *file, poll_table * wait)
struct capidev *cdev = (struct capidev *)file->private_data;
unsigned int mask = 0;
if (!cdev->applid)
if (!cdev->ap.applid)
return POLLERR;
poll_wait(file, &(cdev->recvwait), wait);
......@@ -779,7 +779,7 @@ capi_poll(struct file *file, poll_table * wait)
static int
capi_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long arg)
{
struct capidev *cdev = (struct capidev *)file->private_data;
capi_ioctl_struct data;
......@@ -788,21 +788,21 @@ capi_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case CAPI_REGISTER:
{
retval = copy_from_user((void *) &data.rparams,
(void *) arg, sizeof(struct capi_register_params));
if (retval)
return -EFAULT;
if (cdev->applid)
if (cdev->ap.applid)
return -EEXIST;
cdev->errcode = capi20_register(&data.rparams,
&cdev->applid);
if (copy_from_user(&cdev->ap.rparam, (void *) arg,
sizeof(struct capi_register_params)))
return -EFAULT;
cdev->errcode = capi20_register(&cdev->ap);
if (cdev->errcode) {
cdev->applid = 0;
cdev->ap.applid = 0;
return -EIO;
}
capi20_set_signal(cdev->applid, capi_signal, cdev);
capi20_set_signal(cdev->ap.applid, capi_signal, cdev);
}
return (int)cdev->applid;
return (int)cdev->ap.applid;
case CAPI_GET_VERSION:
{
......@@ -1426,7 +1426,7 @@ static int proc_capidev_read_proc(char *page, char **start, off_t off,
list_for_each(l, &capidev_list) {
cdev = list_entry(l, struct capidev, list);
len += sprintf(page+len, "0 %d %lu %lu %lu %lu\n",
cdev->applid,
cdev->ap.applid,
cdev->nrecvctlpkt,
cdev->nrecvdatapkt,
cdev->nsentctlpkt,
......@@ -1466,7 +1466,7 @@ static int proc_capincci_read_proc(char *page, char **start, off_t off,
cdev = list_entry(l, struct capidev, list);
for (np=cdev->nccis; np; np = np->next) {
len += sprintf(page+len, "%d 0x%x\n",
cdev->applid,
cdev->ap.applid,
np->ncci);
if (len <= off) {
off -= len;
......
......@@ -125,10 +125,10 @@ struct capidrv_contr {
struct capidrv_data {
u16 appid;
struct capi20_appl ap;
int ncontr;
struct capidrv_contr *contr_list;
/* statistic */
unsigned long nrecvctlpkt;
unsigned long nrecvdatapkt;
......@@ -518,7 +518,7 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg)
len = CAPIMSG_LEN(cmsg->buf);
skb = alloc_skb(len, GFP_ATOMIC);
memcpy(skb_put(skb, len), cmsg->buf, len);
capi20_put_message(global.appid, skb);
capi20_put_message(global.ap.applid, skb);
global.nsentctlpkt++;
}
......@@ -666,7 +666,7 @@ static void n0(capidrv_contr * card, capidrv_ncci * ncci)
isdn_ctrl cmd;
capi_fill_DISCONNECT_REQ(&cmsg,
global.appid,
global.ap.applid,
card->msgid++,
ncci->plcip->plci,
0, /* BChannelinformation */
......@@ -954,7 +954,7 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
cmd.parm.setup.si2,
cmd.parm.setup.eazmsn);
capi_fill_ALERT_REQ(cmsg,
global.appid,
global.ap.applid,
card->msgid++,
plcip->plci, /* adr */
0, /* BChannelinformation */
......@@ -1094,7 +1094,7 @@ static void handle_plci(_cmsg * cmsg)
break; /* $$$$ */
}
capi_fill_CONNECT_B3_REQ(cmsg,
global.appid,
global.ap.applid,
card->msgid++,
plcip->plci, /* adr */
0 /* NCPI */
......@@ -1211,7 +1211,7 @@ static void handle_ncci(_cmsg * cmsg)
if (nccip) {
ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_IND);
capi_fill_CONNECT_B3_RESP(cmsg,
global.appid,
global.ap.applid,
card->msgid++,
nccip->ncci, /* adr */
0, /* Reject */
......@@ -1229,7 +1229,7 @@ static void handle_ncci(_cmsg * cmsg)
cmsg->adr.adrNCCI);
}
capi_fill_CONNECT_B3_RESP(cmsg,
global.appid,
global.ap.applid,
card->msgid++,
cmsg->adr.adrNCCI,
2, /* Reject */
......@@ -1376,7 +1376,7 @@ static void capidrv_signal(u16 applid, void *dummy)
{
struct sk_buff *skb = 0;
while (capi20_get_message(global.appid, &skb) == CAPI_NOERROR) {
while (capi20_get_message(global.ap.applid, &skb) == CAPI_NOERROR) {
capi_message2cmsg(&s_cmsg, skb->data);
if (debugmode > 2)
printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",
......@@ -1627,7 +1627,7 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
}
capi_fill_CONNECT_REQ(&cmdcmsg,
global.appid,
global.ap.applid,
card->msgid++,
card->contrnr, /* adr */
si2cip(bchan->si1, bchan->si2), /* cipvalue */
......@@ -1673,7 +1673,7 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
c->arg, bchan->l2, bchan->l3);
capi_fill_CONNECT_RESP(&cmdcmsg,
global.appid,
global.ap.applid,
card->msgid++,
bchan->plcip->plci, /* adr */
0, /* Reject */
......@@ -1720,7 +1720,7 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
if (bchan->nccip) {
bchan->disconnecting = 1;
capi_fill_DISCONNECT_B3_REQ(&cmdcmsg,
global.appid,
global.ap.applid,
card->msgid++,
bchan->nccip->ncci,
0 /* NCPI */
......@@ -1741,7 +1741,7 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
} else if (bchan->plcip->plci) {
bchan->disconnecting = 1;
capi_fill_DISCONNECT_REQ(&cmdcmsg,
global.appid,
global.ap.applid,
card->msgid++,
bchan->plcip->plci,
0, /* BChannelinformation */
......@@ -1888,7 +1888,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
return 0;
}
datahandle = nccip->datahandle;
capi_fill_DATA_B3_REQ(&sendcmsg, global.appid, card->msgid++,
capi_fill_DATA_B3_REQ(&sendcmsg, global.ap.applid, card->msgid++,
nccip->ncci, /* adr */
(u32) skb->data, /* Data */
skb->len, /* DataLength */
......@@ -1912,7 +1912,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
printk(KERN_DEBUG "capidrv-%d: only %d bytes headroom, need %d\n",
card->contrnr, skb_headroom(skb), msglen);
memcpy(skb_push(nskb, msglen), sendcmsg.buf, msglen);
errcode = capi20_put_message(global.appid, nskb);
errcode = capi20_put_message(global.ap.applid, nskb);
if (errcode == CAPI_NOERROR) {
dev_kfree_skb(skb);
nccip->datahandle++;
......@@ -1924,7 +1924,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
return errcode == CAPI_SENDQUEUEFULL ? 0 : -1;
} else {
memcpy(skb_push(skb, msglen), sendcmsg.buf, msglen);
errcode = capi20_put_message(global.appid, skb);
errcode = capi20_put_message(global.ap.applid, skb);
if (errcode == CAPI_NOERROR) {
nccip->datahandle++;
global.nsentdatapkt++;
......@@ -1992,7 +1992,7 @@ static void enable_dchannel_trace(capidrv_contr *card)
if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) {
printk(KERN_INFO "%s: D2 trace enabled\n", card->name);
capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.appid,
capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.ap.applid,
card->msgid++,
contr,
0x214D5641, /* ManuID */
......@@ -2001,7 +2001,7 @@ static void enable_dchannel_trace(capidrv_contr *card)
(_cstruct)"\004\200\014\000\000");
} else {
printk(KERN_INFO "%s: D3 trace enabled\n", card->name);
capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.appid,
capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.ap.applid,
card->msgid++,
contr,
0x214D5641, /* ManuID */
......@@ -2015,7 +2015,7 @@ static void enable_dchannel_trace(capidrv_contr *card)
static void send_listen(capidrv_contr *card)
{
capi_fill_LISTEN_REQ(&cmdcmsg, global.appid,
capi_fill_LISTEN_REQ(&cmdcmsg, global.ap.applid,
card->msgid++,
card->contrnr, /* controller */
1 << 6, /* Infomask */
......@@ -2293,7 +2293,6 @@ static void __exit proc_exit(void)
static int __init capidrv_init(void)
{
struct capi_register_params rparam;
capi_profile profile;
char rev[32];
char *p;
......@@ -2310,25 +2309,26 @@ static int __init capidrv_init(void)
} else
strcpy(rev, "1.0");
rparam.level3cnt = -2; /* number of bchannels twice */
rparam.datablkcnt = 16;
rparam.datablklen = 2048;
errcode = capi20_register(&rparam, &global.appid);
global.ap.rparam.level3cnt = -2; /* number of bchannels twice */
global.ap.rparam.datablkcnt = 16;
global.ap.rparam.datablklen = 2048;
errcode = capi20_register(&global.ap);
if (errcode) {
MOD_DEC_USE_COUNT;
return -EIO;
}
capi20_set_callback(global.appid, lower_callback);
capi20_set_callback(global.ap.applid, lower_callback);
errcode = capi20_get_profile(0, &profile);
if (errcode != CAPI_NOERROR) {
capi20_release(global.appid);
capi20_release(&global.ap);
MOD_DEC_USE_COUNT;
return -EIO;
}
capi20_set_signal(global.appid, capidrv_signal, 0);
capi20_set_signal(global.ap.applid, capidrv_signal, 0);
ncontr = profile.ncontroller;
for (contr = 1; contr <= ncontr; contr++) {
......@@ -2358,7 +2358,7 @@ static void __exit capidrv_exit(void)
strcpy(rev, " ??? ");
}
capi20_release(global.appid);
capi20_release(&global.ap);
proc_exit();
......
......@@ -55,26 +55,6 @@ MODULE_PARM(showcapimsgs, "i");
/* ------------------------------------------------------------- */
struct capi_appl {
u16 applid;
capi_register_params rparam;
void *param;
void (*signal) (u16 applid, void *param);
struct sk_buff_head recv_queue;
int nncci;
struct capi_ncci *nccilist;
unsigned long nrecvctlpkt;
unsigned long nrecvdatapkt;
unsigned long nsentctlpkt;
unsigned long nsentdatapkt;
/* ugly hack to allow for notification of added/removed
* controllers. The Right Way (tm) is known. XXX
*/
void (*callback) (unsigned int cmd, __u32 contr, void *data);
};
struct capi_notifier {
struct capi_notifier *next;
unsigned int cmd;
......@@ -91,7 +71,7 @@ static char capi_manufakturer[64] = "AVM Berlin";
#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
static struct capi_appl *applications[CAPI_MAXAPPL];
static struct capi20_appl *applications[CAPI_MAXAPPL];
static struct capi_ctr *cards[CAPI_MAXCONTR];
static int ncards;
static struct sk_buff_head recv_queue;
......@@ -136,7 +116,7 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
return cards[contr - 1];
}
static inline struct capi_appl *get_capi_appl_by_nr(u16 applid)
static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
{
if (applid - 1 >= CAPI_MAXAPPL)
return NULL;
......@@ -199,7 +179,7 @@ static inline int capi_subcmd_valid(u8 subcmd)
static int proc_applications_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct capi_appl *ap;
struct capi20_appl *ap;
int i;
int len = 0;
......@@ -313,7 +293,7 @@ static int proc_controller_read_proc(char *page, char **start, off_t off,
static int proc_applstats_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct capi_appl *ap;
struct capi20_appl *ap;
int i;
int len = 0;
......@@ -517,7 +497,7 @@ static int notify_push(unsigned int cmd, u32 controller,
static void notify_up(u32 contr)
{
struct capi_ctr *card = get_capi_ctr_by_nr(contr);
struct capi_appl *ap;
struct capi20_appl *ap;
u16 applid;
printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
......@@ -533,7 +513,7 @@ static void notify_up(u32 contr)
static void notify_down(u32 contr)
{
struct capi_appl *ap;
struct capi20_appl *ap;
u16 applid;
printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
......@@ -576,7 +556,7 @@ static void notify_handler(void *dummy)
static void recv_handler(void *dummy)
{
struct sk_buff *skb;
struct capi_appl *ap;
struct capi20_appl *ap;
while ((skb = skb_dequeue(&recv_queue)) != 0) {
ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
......@@ -650,7 +630,7 @@ static void controllercb_handle_capimsg(struct capi_ctr * card,
static void controllercb_ready(struct capi_ctr * card)
{
u16 appl;
struct capi_appl *ap;
struct capi20_appl *ap;
card->cardstate = CARD_RUNNING;
......@@ -683,7 +663,7 @@ static void controllercb_reseted(struct capi_ctr * card)
memset(card->serial, 0, sizeof(card->serial));
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
struct capi_appl *ap = get_capi_appl_by_nr(appl);
struct capi20_appl *ap = get_capi_appl_by_nr(appl);
if (!ap)
continue;
......@@ -870,69 +850,62 @@ u16 capi20_isinstalled(void)
EXPORT_SYMBOL(capi20_isinstalled);
u16 capi20_register(capi_register_params * rparam, u16 * applidp)
u16 capi20_register(struct capi20_appl *ap)
{
struct capi_appl *ap;
int appl;
int i;
u16 applid;
DBG("");
if (rparam->datablklen < 128)
if (ap->rparam.datablklen < 128)
return CAPI_LOGBLKSIZETOSMALL;
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
if (applications[appl - 1] == NULL)
for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
if (applications[applid - 1] == NULL)
break;
}
if (appl > CAPI_MAXAPPL)
if (applid > CAPI_MAXAPPL)
return CAPI_TOOMANYAPPLS;
ap = kmalloc(sizeof(*ap), GFP_KERNEL);
if (!ap)
return CAPI_REGOSRESOURCEERR;
ap->applid = applid;
applications[applid - 1] = ap;
memset(ap, 0, sizeof(*ap));
ap->applid = appl;
applications[appl - 1] = ap;
ap->param = NULL;
ap->signal = NULL;
skb_queue_head_init(&ap->recv_queue);
ap->nncci = 0;
memcpy(&ap->rparam, rparam, sizeof(capi_register_params));
ap->nrecvctlpkt = 0;
ap->nrecvdatapkt = 0;
ap->nsentctlpkt = 0;
ap->nsentdatapkt = 0;
ap->callback = 0;
for (i = 0; i < CAPI_MAXCONTR; i++) {
if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue;
register_appl(cards[i], appl, &ap->rparam);
register_appl(cards[i], applid, &ap->rparam);
}
*applidp = appl;
printk(KERN_INFO "kcapi: appl %d up\n", appl);
printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
return CAPI_NOERROR;
}
EXPORT_SYMBOL(capi20_register);
u16 capi20_release(u16 applid)
u16 capi20_release(struct capi20_appl *ap)
{
struct capi_appl *ap = get_capi_appl_by_nr(applid);
int i;
DBG("applid %#x", applid);
if (!ap)
return CAPI_ILLAPPNR;
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;
release_appl(cards[i], applid);
release_appl(cards[i], ap->applid);
}
applications[applid - 1] = NULL;
kfree(ap);
printk(KERN_INFO "kcapi: appl %d down\n", applid);
applications[ap->applid - 1] = NULL;
printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid);
return CAPI_NOERROR;
}
......@@ -942,7 +915,7 @@ EXPORT_SYMBOL(capi20_release);
u16 capi20_put_message(u16 applid, struct sk_buff *skb)
{
struct capi_ctr *card;
struct capi_appl *ap;
struct capi20_appl *ap;
int showctl = 0;
u8 cmd, subcmd;
......@@ -1000,7 +973,7 @@ EXPORT_SYMBOL(capi20_put_message);
u16 capi20_get_message(u16 applid, struct sk_buff **msgp)
{
struct capi_appl *ap = get_capi_appl_by_nr(applid);
struct capi20_appl *ap = get_capi_appl_by_nr(applid);
struct sk_buff *skb;
if (!ap)
......@@ -1017,7 +990,7 @@ u16 capi20_set_signal(u16 applid,
void (*signal) (u16 applid, void *param),
void *param)
{
struct capi_appl *ap = get_capi_appl_by_nr(applid);
struct capi20_appl *ap = get_capi_appl_by_nr(applid);
if (!ap)
return CAPI_ILLAPPNR;
......@@ -1287,7 +1260,7 @@ EXPORT_SYMBOL(capi20_manufacturer);
/* temporary hack */
void capi20_set_callback(u16 applid, void (*callback) (unsigned int cmd, __u32 contr, void *data))
{
struct capi_appl *ap = get_capi_appl_by_nr(applid);
struct capi20_appl *ap = get_capi_appl_by_nr(applid);
ap->callback = callback;
}
......
......@@ -52,9 +52,31 @@ typedef struct kcapi_carddef {
#define KCI_CONTRUP 0 /* struct capi_profile */
#define KCI_CONTRDOWN 1 /* NULL */
struct capi20_appl {
u16 applid;
capi_register_params rparam;
/* internal to kernelcapi.o */
void *param;
void (*signal) (u16 applid, void *param);
struct sk_buff_head recv_queue;
int nncci;
struct capi_ncci *nccilist;
unsigned long nrecvctlpkt;
unsigned long nrecvdatapkt;
unsigned long nsentctlpkt;
unsigned long nsentdatapkt;
/* ugly hack to allow for notification of added/removed
* controllers. The Right Way (tm) is known. XXX
*/
void (*callback) (unsigned int cmd, __u32 contr, void *data);
};
u16 capi20_isinstalled(void);
u16 capi20_register(capi_register_params * rparam, u16 * applidp);
u16 capi20_release(u16 applid);
u16 capi20_register(struct capi20_appl *ap);
u16 capi20_release(struct capi20_appl *ap);
u16 capi20_put_message(u16 applid, struct sk_buff *skb);
u16 capi20_get_message(u16 applid, struct sk_buff **msgp);
u16 capi20_set_signal(u16 applid,
......
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