*
*/
+#define DBG(format, arg...) do { \
+printk(KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg); \
+} while (0)
+
#define CONFIG_AVMB1_COMPAT
#include <linux/config.h>
static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
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)
-static struct capi_appl applications[CAPI_MAXAPPL];
+static struct capi_appl *applications[CAPI_MAXAPPL];
static struct capi_ctr *cards[CAPI_MAXCONTR];
static int ncards;
static struct sk_buff_head recv_queue;
capi_ctr_get(struct capi_ctr *card)
{
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;
- else
+ } else
return NULL;
}
+ DBG("MOD_COUNT INC");
return card;
}
{
if (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)
{
if (contr - 1 >= CAPI_MAXCONTR)
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 ------------------------------------ */
static char *cardstate2str(unsigned short cardstate)
int i;
int len = 0;
- for (i=0; i < CAPI_MAXAPPL; i++) {
- ap = &applications[i];
- if (ap->applid == 0) continue;
+ 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,
int i;
int len = 0;
- for (i=0; i < CAPI_MAXAPPL; i++) {
- ap = &applications[i];
- if (ap->applid == 0) continue;
+ for (i=1; i <= CAPI_MAXAPPL; i++) {
+ ap = get_capi_appl_by_nr(i);
+ if (!ap) continue;
for (np = ap->nccilist; np; np = np->next) {
len += sprintf(page+len, "%d 0x%x %d %d\n",
np->applid,
int i;
int len = 0;
- for (i=0; i < CAPI_MAXAPPL; i++) {
- ap = &applications[i];
- if (ap->applid == 0) continue;
+ for (i=1; i <= CAPI_MAXAPPL; i++) {
+ ap = get_capi_appl_by_nr(i);
+ if (!ap) continue;
len += sprintf(page+len, "%u %lu %lu %lu %lu\n",
ap->applid,
ap->nrecvctlpkt,
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;
-
- for (pp = &APPL(applid)->nccilist; *pp; pp = nextpp) {
+
+ DBG("");
+
+ for (pp = &ap->nccilist; *pp; pp = nextpp) {
if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
struct capi_ncci *np = *pp;
*pp = np->next;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", applid, np->ncci);
kfree(np);
- APPL(applid)->nncci--;
+ ap->nncci--;
nextpp = pp;
} else {
nextpp = &(*pp)->next;
u16 appl, u32 ncci, u32 winsize)
{
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);
return;
}
np->ncci = ncci;
np->winsize = winsize;
mq_init(np);
- np->next = APPL(appl)->nccilist;
- APPL(appl)->nccilist = np;
- APPL(appl)->nncci++;
+ np->next = ap->nccilist;
+ ap->nccilist = np;
+ ap->nncci++;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci);
notify_push(KCI_NCCIUP, card->cnr, appl, ncci);
u16 appl, u32 ncci)
{
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);
return;
}
- for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) {
+ for (pp = &ap->nccilist; *pp; pp = &(*pp)->next) {
if ((*pp)->ncci == ncci) {
struct capi_ncci *np = *pp;
*pp = np->next;
kfree(np);
- APPL(appl)->nncci--;
+ ap->nncci--;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci);
notify_push(KCI_NCCIDOWN, card->cnr, appl, ncci);
return;
static void recv_handler(void *dummy)
{
struct sk_buff *skb;
+ struct capi_appl *ap;
+ struct capi_ncci *np;
while ((skb = skb_dequeue(&recv_queue)) != 0) {
- u16 appl = CAPIMSG_APPID(skb->data);
- struct capi_ncci *np;
- if (!VALID_APPLID(appl)) {
+ ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
+ if (!ap) {
printk(KERN_ERR "kcapi: recv_handler: applid %d ? (%s)\n",
- appl, capi_message2str(skb->data));
+ ap->applid, capi_message2str(skb->data));
kfree_skb(skb);
continue;
}
- if (APPL(appl)->signal == 0) {
+ if (ap->signal == 0) {
printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n",
- appl);
+ ap->applid);
kfree_skb(skb);
continue;
}
if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
&& 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) {
printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
CAPIMSG_MSGID(skb->data), np->ncci);
}
if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
&& CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
- APPL(appl)->nrecvdatapkt++;
+ ap->nrecvdatapkt++;
} else {
- APPL(appl)->nrecvctlpkt++;
+ ap->nrecvctlpkt++;
}
- skb_queue_tail(&APPL(appl)->recv_queue, skb);
- (APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param);
+ skb_queue_tail(&ap->recv_queue, skb);
+ (ap->signal) (ap->applid, ap->param);
}
}
static void controllercb_ready(struct capi_ctr * card)
{
u16 appl;
+ struct capi_appl *ap;
card->cardstate = CARD_RUNNING;
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
- if (!VALID_APPLID(appl)) continue;
- register_appl(card, appl, &APPL(appl)->rparam);
+ ap = get_capi_appl_by_nr(appl);
+ if (!ap) continue;
+ register_appl(card, appl, &ap->rparam);
}
printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
{
u16 appl;
+ DBG("");
+
if (card->cardstate == CARD_DETECTED)
return;
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 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) {
struct capi_ncci *np = *pp;
*pp = np->next;
static u16 capi_register(capi_register_params * rparam, u16 * applidp)
{
+ struct capi_appl *ap;
int appl;
int i;
+ DBG("");
+
if (rparam->datablklen < 128)
return CAPI_LOGBLKSIZETOSMALL;
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
- if (APPL_IS_FREE(appl))
+ if (applications[appl - 1] == NULL)
break;
}
if (appl > CAPI_MAXAPPL)
return CAPI_TOOMANYAPPLS;
- APPL_MARK_USED(appl);
- skb_queue_head_init(&APPL(appl)->recv_queue);
- APPL(appl)->nncci = 0;
+ ap = kmalloc(sizeof(*ap), GFP_KERNEL);
+ if (!ap)
+ return CAPI_REGOSRESOURCEERR;
+
+ memset(ap, 0, sizeof(*ap));
+ ap->applid = appl;
+ applications[appl - 1] = ap;
+
+ skb_queue_head_init(&ap->recv_queue);
+ ap->nncci = 0;
- memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params));
+ memcpy(&ap->rparam, rparam, sizeof(capi_register_params));
for (i = 0; i < CAPI_MAXCONTR; i++) {
if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue;
- register_appl(cards[i], appl, &APPL(appl)->rparam);
+ register_appl(cards[i], appl, &ap->rparam);
}
*applidp = appl;
printk(KERN_INFO "kcapi: appl %d up\n", appl);
static u16 capi_release(u16 applid)
{
+ struct capi_appl *ap = get_capi_appl_by_nr(applid);
int i;
- if (!VALID_APPLID(applid))
+ DBG("applid %#x", applid);
+
+ if (!ap)
return CAPI_ILLAPPNR;
- skb_queue_purge(&APPL(applid)->recv_queue);
+
+ 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);
}
- APPL(applid)->signal = 0;
- APPL_MARK_FREE(applid);
+ applications[applid - 1] = NULL;
+ kfree(ap);
printk(KERN_INFO "kcapi: appl %d down\n", applid);
return CAPI_NOERROR;
static u16 capi_put_message(u16 applid, struct sk_buff *skb)
{
struct capi_ctr *card;
+ struct capi_appl *ap;
struct capi_ncci *np;
int showctl = 0;
u8 cmd, subcmd;
+ DBG("applid %#x", applid);
+
if (ncards == 0)
return CAPI_REGNOTINSTALLED;
- if (!VALID_APPLID(applid))
+ ap = get_capi_appl_by_nr(applid);
+ if (!ap)
return CAPI_ILLAPPNR;
if (skb->len < 12
|| !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
subcmd = CAPIMSG_SUBCOMMAND(skb->data);
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)
return CAPI_SENDQUEUEFULL;
card->nsentdatapkt++;
- APPL(applid)->nsentdatapkt++;
+ ap->nsentdatapkt++;
if (card->traceflag > 2) showctl |= 2;
} else {
card->nsentctlpkt++;
- APPL(applid)->nsentctlpkt++;
+ ap->nsentctlpkt++;
if (card->traceflag) showctl |= 2;
}
showctl |= (card->traceflag & 1);
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;
- if (!VALID_APPLID(applid))
+ if (!ap)
return CAPI_ILLAPPNR;
- if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0)
+ if ((skb = skb_dequeue(&ap->recv_queue)) == 0)
return CAPI_RECEIVEQUEUEEMPTY;
*msgp = skb;
return CAPI_NOERROR;
void (*signal) (u16 applid, void *param),
void *param)
{
- if (!VALID_APPLID(applid))
+ struct capi_appl *ap = get_capi_appl_by_nr(applid);
+
+ if (!ap)
return CAPI_ILLAPPNR;
- APPL(applid)->signal = signal;
- APPL(applid)->param = param;
+ ap->signal = signal;
+ ap->param = param;
return CAPI_NOERROR;
}