/* ------------------------------------------------------------- */
-#define CARD_FREE 0
#define CARD_DETECTED 1
#define CARD_LOADING 2
#define CARD_RUNNING 3
#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
-#define VALID_CARD(c) ((c) > 0 && (c) <= CAPI_MAXCONTR)
-#define CARD(c) (&cards[(c)-1])
-#define CARDNR(cp) (((cp)-cards)+1)
-
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 struct sk_buff_head recv_queue;
__MOD_DEC_USE_COUNT(card->driver->owner);
}
+static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
+{
+ if (contr - 1 >= CAPI_MAXCONTR)
+ return NULL;
+
+ return cards[contr - 1];
+}
+
/* -------- util functions ------------------------------------ */
static char *cardstate2str(unsigned short cardstate)
{
switch (cardstate) {
- default:
- case CARD_FREE: return "free";
- case CARD_DETECTED: return "detected";
- case CARD_LOADING: return "loading";
- case CARD_RUNNING: return "running";
+ case CARD_DETECTED: return "detected";
+ case CARD_LOADING: return "loading";
+ case CARD_RUNNING: return "running";
+ default: return "???";
}
}
int len = 0;
for (i=0; i < CAPI_MAXCONTR; i++) {
- cp = &cards[i];
- if (cp->cardstate == CARD_FREE) continue;
+ cp = cards[i];
+ if (!cp)
+ continue;
+
len += sprintf(page+len, "%d %-10s %-8s %-16s %s\n",
cp->cnr, cp->driver->name,
cardstate2str(cp->cardstate),
int len = 0;
for (i=0; i < CAPI_MAXCONTR; i++) {
- cp = &cards[i];
- if (cp->cardstate == CARD_FREE) continue;
+ cp = cards[i];
+ if (!cp)
+ continue;
len += sprintf(page+len, "%d %lu %lu %lu %lu\n",
cp->cnr,
cp->nrecvctlpkt,
{
struct list_head *l;
struct capi_interface_user *p;
+ struct capi_ctr *card = get_capi_ctr_by_nr(contr);
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_CONTRUP, contr, &CARD(contr)->profile);
+ (*p->callback) (KCI_CONTRUP, contr, &card->profile);
}
spin_unlock(&users_lock);
}
APPL(appl)->nncci++;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci);
- notify_push(KCI_NCCIUP, CARDNR(card), appl, ncci);
+ notify_push(KCI_NCCIUP, card->cnr, appl, ncci);
}
static void controllercb_free_ncci(struct capi_ctr * card,
kfree(np);
APPL(appl)->nncci--;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci);
- notify_push(KCI_NCCIDOWN, CARDNR(card), appl, ncci);
+ notify_push(KCI_NCCIDOWN, card->cnr, appl, ncci);
return;
}
}
}
printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
- CARDNR(card), card->name);
+ card->cnr, card->name);
- notify_push(KCI_CONTRUP, CARDNR(card), 0, 0);
+ notify_push(KCI_CONTRUP, card->cnr, 0, 0);
}
static void controllercb_reseted(struct capi_ctr * card)
{
u16 appl;
- if (card->cardstate == CARD_FREE)
- return;
if (card->cardstate == CARD_DETECTED)
return;
struct capi_ncci *np = *pp;
*pp = np->next;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci);
- notify_push(KCI_NCCIDOWN, CARDNR(card), appl, np->ncci);
+ notify_push(KCI_NCCIDOWN, card->cnr, appl, np->ncci);
kfree(np);
nextpp = pp;
} else {
capi_ctr_put(card);
}
- printk(KERN_NOTICE "kcapi: card %d down.\n", CARDNR(card));
+ printk(KERN_NOTICE "kcapi: card %d down.\n", card->cnr);
- notify_push(KCI_CONTRDOWN, CARDNR(card), 0, 0);
+ notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
}
static void controllercb_suspend_output(struct capi_ctr *card)
{
if (!card->blocked) {
- printk(KERN_DEBUG "kcapi: card %d suspend\n", CARDNR(card));
+ printk(KERN_DEBUG "kcapi: card %d suspend\n", card->cnr);
card->blocked = 1;
}
}
static void controllercb_resume_output(struct capi_ctr *card)
{
if (card->blocked) {
- printk(KERN_DEBUG "kcapi: card %d resume\n", CARDNR(card));
+ printk(KERN_DEBUG "kcapi: card %d resume\n", card->cnr);
card->blocked = 0;
}
}
struct capi_ctr *card;
int i;
- for (i=0; i < CAPI_MAXCONTR && cards[i].cardstate != CARD_FREE; i++) ;
-
+ for (i=0; i < CAPI_MAXCONTR; i++) {
+ if (cards[i] == NULL)
+ break;
+ }
if (i == CAPI_MAXCONTR) {
printk(KERN_ERR "kcapi: out of controller slots\n");
- return 0;
+ return NULL;
}
- card = &cards[i];
+ card = kmalloc(sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return NULL;
+
+ cards[i] = card;
memset(card, 0, sizeof(struct capi_ctr));
card->driver = driver;
- card->cnr = CARDNR(card);
+ card->cnr = i + 1;
strncpy(card->name, name, sizeof(card->name));
card->cardstate = CARD_DETECTED;
card->blocked = 0;
{
struct capi_driver *driver = card->driver;
- if (card->cardstate == CARD_FREE)
- return 0;
if (card->cardstate != CARD_DETECTED)
controllercb_reseted(card);
remove_proc_entry(card->procfn, 0);
card->procent = 0;
}
- card->cardstate = CARD_FREE;
+ cards[card->cnr - 1] = NULL;
printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n",
card->cnr, card->name);
+ kfree(card);
+
return 0;
}
{
int i;
for (i = 0; i < CAPI_MAXCONTR; i++) {
- if (cards[i].cardstate == CARD_RUNNING)
+ if (cards[i] && cards[i]->cardstate == CARD_RUNNING)
return CAPI_NOERROR;
}
return CAPI_REGNOTINSTALLED;
memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params));
for (i = 0; i < CAPI_MAXCONTR; i++) {
- if (cards[i].cardstate != CARD_RUNNING)
+ if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue;
- register_appl(&cards[i], appl, &APPL(appl)->rparam);
+ register_appl(cards[i], appl, &APPL(appl)->rparam);
}
*applidp = appl;
printk(KERN_INFO "kcapi: appl %d up\n", appl);
return CAPI_ILLAPPNR;
skb_queue_purge(&APPL(applid)->recv_queue);
for (i = 0; i < CAPI_MAXCONTR; i++) {
- if (cards[i].cardstate != CARD_RUNNING)
+ if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue;
- release_appl(&cards[i], applid);
+ release_appl(cards[i], applid);
}
APPL(applid)->signal = 0;
APPL_MARK_FREE(applid);
static u16 capi_put_message(u16 applid, struct sk_buff *skb)
{
+ struct capi_ctr *card;
struct capi_ncci *np;
- u32 contr;
int showctl = 0;
u8 cmd, subcmd;
|| !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
|| !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
- contr = CAPIMSG_CONTROLLER(skb->data);
- if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) {
- contr = 1;
- if (CARD(contr)->cardstate != CARD_RUNNING)
+ card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
+ if (!card || card->cardstate != CARD_RUNNING) {
+ card = get_capi_ctr_by_nr(1); // XXX why?
+ if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED;
}
- if (CARD(contr)->blocked)
+ if (card->blocked)
return CAPI_SENDQUEUEFULL;
cmd = CAPIMSG_COMMAND(skb->data);
if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0
&& mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0)
return CAPI_SENDQUEUEFULL;
- CARD(contr)->nsentdatapkt++;
+ card->nsentdatapkt++;
APPL(applid)->nsentdatapkt++;
- if (CARD(contr)->traceflag > 2) showctl |= 2;
+ if (card->traceflag > 2) showctl |= 2;
} else {
- CARD(contr)->nsentctlpkt++;
+ card->nsentctlpkt++;
APPL(applid)->nsentctlpkt++;
- if (CARD(contr)->traceflag) showctl |= 2;
+ if (card->traceflag) showctl |= 2;
}
- showctl |= (CARD(contr)->traceflag & 1);
+ showctl |= (card->traceflag & 1);
if (showctl & 2) {
if (showctl & 1) {
- printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n",
- (unsigned long) contr,
+ printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n",
+ CAPIMSG_CONTROLLER(skb->data),
CAPIMSG_APPID(skb->data),
capi_cmd2str(cmd, subcmd),
CAPIMSG_LEN(skb->data));
} else {
- printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n",
- (unsigned long) contr,
- capi_message2str(skb->data));
+ printk(KERN_DEBUG "kcapi: put [%#x] %s\n",
+ CAPIMSG_CONTROLLER(skb->data),
+ capi_message2str(skb->data));
}
}
- CARD(contr)->driver->send_message(CARD(contr), skb);
+ card->driver->send_message(card, skb);
return CAPI_NOERROR;
}
static u16 capi_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
{
+ struct capi_ctr *card;
+
if (contr == 0) {
strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
return CAPI_NOERROR;
}
- if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
+ card = get_capi_ctr_by_nr(contr);
+ if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED;
- strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN);
+ strncpy(buf, card->manu, CAPI_MANUFACTURER_LEN);
return CAPI_NOERROR;
}
static u16 capi_get_version(u32 contr, struct capi_version *verp)
{
+ struct capi_ctr *card;
+
if (contr == 0) {
*verp = driver_version;
return CAPI_NOERROR;
}
- if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
+ card = get_capi_ctr_by_nr(contr);
+ if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED;
- memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version));
+ memcpy((void *) verp, &card->version, sizeof(capi_version));
return CAPI_NOERROR;
}
static u16 capi_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN])
{
+ struct capi_ctr *card;
+
if (contr == 0) {
strncpy(serial, driver_serial, CAPI_SERIAL_LEN);
return CAPI_NOERROR;
}
- if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
+ card = get_capi_ctr_by_nr(contr);
+ if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED;
- strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN);
+ strncpy((void *) serial, card->serial, CAPI_SERIAL_LEN);
return CAPI_NOERROR;
}
static u16 capi_get_profile(u32 contr, struct capi_profile *profp)
{
+ struct capi_ctr *card;
+
if (contr == 0) {
profp->ncontroller = ncards;
return CAPI_NOERROR;
}
- if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
+ card = get_capi_ctr_by_nr(contr);
+ if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED;
- memcpy((void *) profp, &CARD(contr)->profile,
+ memcpy((void *) profp, &card->profile,
sizeof(struct capi_profile));
return CAPI_NOERROR;
}
sizeof(avmb1_loadandconfigdef))))
return retval;
}
- if (!VALID_CARD(ldef.contr))
- return -ESRCH;
-
- card = CARD(ldef.contr);
- if (card->cardstate == CARD_FREE)
+ card = get_capi_ctr_by_nr(ldef.contr);
+ if (!card)
return -ESRCH;
if (card->driver->load_firmware == 0) {
printk(KERN_DEBUG "kcapi: load: driver \%s\" has no load function\n", card->driver->name);
if ((retval = copy_from_user((void *) &rdef, data,
sizeof(avmb1_resetdef))))
return retval;
- if (!VALID_CARD(rdef.contr))
+ card = get_capi_ctr_by_nr(rdef.contr);
+ if (!card)
return -ESRCH;
- card = CARD(rdef.contr);
- if (card->cardstate == CARD_FREE)
- return -ESRCH;
if (card->cardstate == CARD_DETECTED)
return 0;
sizeof(avmb1_getdef))))
return retval;
- if (!VALID_CARD(gdef.contr))
- return -ESRCH;
-
- card = CARD(gdef.contr);
-
- if (card->cardstate == CARD_FREE)
+ card = get_capi_ctr_by_nr(gdef.contr);
+ if (!card)
return -ESRCH;
gdef.cardstate = card->cardstate;
sizeof(avmb1_resetdef))))
return retval;
- if (!VALID_CARD(rdef.contr))
- return -ESRCH;
- card = CARD(rdef.contr);
-
- if (card->cardstate == CARD_FREE)
+ card = get_capi_ctr_by_nr(rdef.contr);
+ if (!card)
return -ESRCH;
if (card->cardstate != CARD_DETECTED)
card->driver->remove_ctr(card);
- while (card->cardstate != CARD_FREE) {
+ while (cards[rdef.contr]) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/10); /* 0.1 sec */
sizeof(kcapi_flagdef))))
return retval;
- if (!VALID_CARD(fdef.contr))
- return -ESRCH;
- card = CARD(fdef.contr);
- if (card->cardstate == CARD_FREE)
+ card = get_capi_ctr_by_nr(fdef.contr);
+ if (!card)
return -ESRCH;
+
card->traceflag = fdef.flag;
printk(KERN_INFO "kcapi: contr %d set trace=%d\n",
card->cnr, card->traceflag);