Commit 06082418 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-isdn.bkbits.net/linux-2.5.isdn

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 56677816 d095870d
...@@ -36,7 +36,6 @@ static char *revision = "$Revision: 1.21.6.8 $"; ...@@ -36,7 +36,6 @@ static char *revision = "$Revision: 1.21.6.8 $";
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
#define CARD_FREE 0
#define CARD_DETECTED 1 #define CARD_DETECTED 1
#define CARD_LOADING 2 #define CARD_LOADING 2
#define CARD_RUNNING 3 #define CARD_RUNNING 3
...@@ -72,7 +71,6 @@ struct capi_ncci { ...@@ -72,7 +71,6 @@ struct capi_ncci {
struct capi_appl { struct capi_appl {
u16 applid; u16 applid;
capi_register_params rparam; capi_register_params rparam;
int releasing;
void *param; void *param;
void (*signal) (u16 applid, void *param); void (*signal) (u16 applid, void *param);
struct sk_buff_head recv_queue; struct sk_buff_head recv_queue;
...@@ -107,32 +105,58 @@ static char capi_manufakturer[64] = "AVM Berlin"; ...@@ -107,32 +105,58 @@ static char capi_manufakturer[64] = "AVM Berlin";
#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) #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_appl applications[CAPI_MAXAPPL];
static struct capi_ctr cards[CAPI_MAXCONTR]; static struct capi_ctr *cards[CAPI_MAXCONTR];
static int ncards = 0; static int ncards;
static struct sk_buff_head recv_queue; static struct sk_buff_head recv_queue;
static struct capi_interface_user *capi_users = 0;
static spinlock_t capi_users_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(users);
static struct capi_driver *drivers; static spinlock_t users_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(drivers);
static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED; static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
static struct tq_struct tq_state_notify; static struct tq_struct tq_state_notify;
static struct tq_struct tq_recv_notify; static struct tq_struct tq_recv_notify;
/* -------- ref counting -------------------------------------- */
static inline struct capi_ctr *
capi_ctr_get(struct capi_ctr *card)
{
if (card->driver->owner) {
if (try_inc_mod_count(card->driver->owner))
return card;
else
return NULL;
}
return card;
}
static inline void
capi_ctr_put(struct capi_ctr *card)
{
if (card->driver->owner)
__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 ------------------------------------ */ /* -------- util functions ------------------------------------ */
static char *cardstate2str(unsigned short cardstate) static char *cardstate2str(unsigned short cardstate)
{ {
switch (cardstate) { switch (cardstate) {
default: case CARD_DETECTED: return "detected";
case CARD_FREE: return "free"; case CARD_LOADING: return "loading";
case CARD_DETECTED: return "detected"; case CARD_RUNNING: return "running";
case CARD_LOADING: return "loading"; default: return "???";
case CARD_RUNNING: return "running";
} }
} }
...@@ -256,11 +280,14 @@ static int proc_ncci_read_proc(char *page, char **start, off_t off, ...@@ -256,11 +280,14 @@ static int proc_ncci_read_proc(char *page, char **start, off_t off,
static int proc_driver_read_proc(char *page, char **start, off_t off, static int proc_driver_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
struct list_head *l;
struct capi_driver *driver; struct capi_driver *driver;
int len = 0; int len = 0;
spin_lock(&drivers_lock); spin_lock(&drivers_lock);
for (driver = drivers; driver; driver = driver->next) { list_for_each(l, &drivers) {
driver = list_entry(l, struct capi_driver, driver_list);
len += sprintf(page+len, "%-32s %d %s\n", len += sprintf(page+len, "%-32s %d %s\n",
driver->name, driver->name,
driver->ncontroller, driver->ncontroller,
...@@ -290,11 +317,13 @@ static int proc_driver_read_proc(char *page, char **start, off_t off, ...@@ -290,11 +317,13 @@ static int proc_driver_read_proc(char *page, char **start, off_t off,
static int proc_users_read_proc(char *page, char **start, off_t off, static int proc_users_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
struct list_head *l;
struct capi_interface_user *cp; struct capi_interface_user *cp;
int len = 0; int len = 0;
spin_lock(&capi_users_lock); spin_lock(&users_lock);
for (cp = capi_users; cp ; cp = cp->next) { list_for_each(l, &users) {
cp = list_entry(l, struct capi_interface_user, user_list);
len += sprintf(page+len, "%s\n", cp->name); len += sprintf(page+len, "%s\n", cp->name);
if (len <= off) { if (len <= off) {
off -= len; off -= len;
...@@ -305,7 +334,7 @@ static int proc_users_read_proc(char *page, char **start, off_t off, ...@@ -305,7 +334,7 @@ static int proc_users_read_proc(char *page, char **start, off_t off,
} }
} }
endloop: endloop:
spin_unlock(&capi_users_lock); spin_unlock(&users_lock);
*start = page+off; *start = page+off;
if (len < count) if (len < count)
*eof = 1; *eof = 1;
...@@ -326,8 +355,10 @@ static int proc_controller_read_proc(char *page, char **start, off_t off, ...@@ -326,8 +355,10 @@ static int proc_controller_read_proc(char *page, char **start, off_t off,
int len = 0; int len = 0;
for (i=0; i < CAPI_MAXCONTR; i++) { for (i=0; i < CAPI_MAXCONTR; i++) {
cp = &cards[i]; cp = cards[i];
if (cp->cardstate == CARD_FREE) continue; if (!cp)
continue;
len += sprintf(page+len, "%d %-10s %-8s %-16s %s\n", len += sprintf(page+len, "%d %-10s %-8s %-16s %s\n",
cp->cnr, cp->driver->name, cp->cnr, cp->driver->name,
cardstate2str(cp->cardstate), cardstate2str(cp->cardstate),
...@@ -400,8 +431,9 @@ static int proc_contrstats_read_proc(char *page, char **start, off_t off, ...@@ -400,8 +431,9 @@ static int proc_contrstats_read_proc(char *page, char **start, off_t off,
int len = 0; int len = 0;
for (i=0; i < CAPI_MAXCONTR; i++) { for (i=0; i < CAPI_MAXCONTR; i++) {
cp = &cards[i]; cp = cards[i];
if (cp->cardstate == CARD_FREE) continue; if (!cp)
continue;
len += sprintf(page+len, "%d %lu %lu %lu %lu\n", len += sprintf(page+len, "%d %lu %lu %lu %lu\n",
cp->cnr, cp->cnr,
cp->nrecvctlpkt, cp->nrecvctlpkt,
...@@ -470,6 +502,39 @@ static void proc_capi_exit(void) ...@@ -470,6 +502,39 @@ static void proc_capi_exit(void)
} }
} }
/* ------------------------------------------------------------ */
static void register_appl(struct capi_ctr *card, u16 applid, capi_register_params *rparam)
{
card = capi_ctr_get(card);
card->driver->register_appl(card, applid, rparam);
}
static void release_appl(struct capi_ctr *card, u16 applid)
{
struct capi_ncci **pp, **nextpp;
for (pp = &APPL(applid)->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--;
nextpp = pp;
} else {
nextpp = &(*pp)->next;
}
}
card->driver->release_appl(card, applid);
capi_ctr_put(card);
}
/* -------- Notifier handling --------------------------------- */ /* -------- Notifier handling --------------------------------- */
static struct capi_notifier_list{ static struct capi_notifier_list{
...@@ -543,63 +608,75 @@ static int notify_push(unsigned int cmd, u32 controller, ...@@ -543,63 +608,75 @@ static int notify_push(unsigned int cmd, u32 controller,
static void notify_up(u32 contr) static void notify_up(u32 contr)
{ {
struct list_head *l;
struct capi_interface_user *p; 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); printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
spin_lock(&capi_users_lock); spin_lock(&users_lock);
for (p = capi_users; p; p = p->next) { list_for_each(l, &users) {
p = list_entry(l, struct capi_interface_user, user_list);
if (!p->callback) continue; if (!p->callback) continue;
(*p->callback) (KCI_CONTRUP, contr, &CARD(contr)->profile); (*p->callback) (KCI_CONTRUP, contr, &card->profile);
} }
spin_unlock(&capi_users_lock); spin_unlock(&users_lock);
} }
/* -------- KCI_CONTRDOWN ------------------------------------- */ /* -------- KCI_CONTRDOWN ------------------------------------- */
static void notify_down(u32 contr) static void notify_down(u32 contr)
{ {
struct list_head *l;
struct capi_interface_user *p; struct capi_interface_user *p;
printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr); printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);
spin_lock(&capi_users_lock); spin_lock(&users_lock);
for (p = capi_users; p; p = p->next) { list_for_each(l, &users) {
p = list_entry(l, struct capi_interface_user, user_list);
if (!p->callback) continue; if (!p->callback) continue;
(*p->callback) (KCI_CONTRDOWN, contr, 0); (*p->callback) (KCI_CONTRDOWN, contr, 0);
} }
spin_unlock(&capi_users_lock); spin_unlock(&users_lock);
} }
/* -------- KCI_NCCIUP ---------------------------------------- */ /* -------- KCI_NCCIUP ---------------------------------------- */
static void notify_ncciup(u32 contr, u16 applid, u32 ncci) static void notify_ncciup(u32 contr, u16 applid, u32 ncci)
{ {
struct list_head *l;
struct capi_interface_user *p; struct capi_interface_user *p;
struct capi_ncciinfo n; struct capi_ncciinfo n;
n.applid = applid; n.applid = applid;
n.ncci = ncci; n.ncci = ncci;
/*printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);*/ /*printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);*/
spin_lock(&capi_users_lock); spin_lock(&users_lock);
for (p = capi_users; p; p = p->next) { list_for_each(l, &users) {
p = list_entry(l, struct capi_interface_user, user_list);
if (!p->callback) continue; if (!p->callback) continue;
(*p->callback) (KCI_NCCIUP, contr, &n); (*p->callback) (KCI_NCCIUP, contr, &n);
} }
spin_unlock(&capi_users_lock); spin_unlock(&users_lock);
}; };
/* -------- KCI_NCCIDOWN -------------------------------------- */ /* -------- KCI_NCCIDOWN -------------------------------------- */
static void notify_nccidown(u32 contr, u16 applid, u32 ncci) static void notify_nccidown(u32 contr, u16 applid, u32 ncci)
{ {
struct list_head *l;
struct capi_interface_user *p; struct capi_interface_user *p;
struct capi_ncciinfo n; struct capi_ncciinfo n;
n.applid = applid; n.applid = applid;
n.ncci = ncci; n.ncci = ncci;
/*printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);*/ /*printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);*/
spin_lock(&capi_users_lock); spin_lock(&users_lock);
for (p = capi_users; p; p = p->next) { list_for_each(l, &users) {
p = list_entry(l, struct capi_interface_user, user_list);
if (!p->callback) continue; if (!p->callback) continue;
(*p->callback) (KCI_NCCIDOWN, contr, &n); (*p->callback) (KCI_NCCIDOWN, contr, &n);
} }
spin_unlock(&capi_users_lock); spin_unlock(&users_lock);
}; };
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
...@@ -685,32 +762,6 @@ static inline int mq_dequeue(struct capi_ncci * np, u16 msgid) ...@@ -685,32 +762,6 @@ static inline int mq_dequeue(struct capi_ncci * np, u16 msgid)
return 0; return 0;
} }
static void controllercb_appl_registered(struct capi_ctr * card, u16 appl)
{
}
static void controllercb_appl_released(struct capi_ctr * card, u16 appl)
{
struct capi_ncci **pp, **nextpp;
for (pp = &APPL(appl)->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", appl, np->ncci);
kfree(np);
APPL(appl)->nncci--;
nextpp = pp;
} else {
nextpp = &(*pp)->next;
}
}
APPL(appl)->releasing--;
if (APPL(appl)->releasing <= 0) {
APPL(appl)->signal = 0;
APPL_MARK_FREE(appl);
printk(KERN_INFO "kcapi: appl %d down\n", appl);
}
}
/* /*
* ncci management * ncci management
*/ */
...@@ -741,7 +792,7 @@ static void controllercb_new_ncci(struct capi_ctr * card, ...@@ -741,7 +792,7 @@ static void controllercb_new_ncci(struct capi_ctr * card,
APPL(appl)->nncci++; APPL(appl)->nncci++;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci); 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, static void controllercb_free_ncci(struct capi_ctr * card,
...@@ -759,7 +810,7 @@ static void controllercb_free_ncci(struct capi_ctr * card, ...@@ -759,7 +810,7 @@ static void controllercb_free_ncci(struct capi_ctr * card,
kfree(np); kfree(np);
APPL(appl)->nncci--; APPL(appl)->nncci--;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci); 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; return;
} }
} }
...@@ -868,22 +919,19 @@ static void controllercb_ready(struct capi_ctr * card) ...@@ -868,22 +919,19 @@ static void controllercb_ready(struct capi_ctr * card)
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
if (!VALID_APPLID(appl)) continue; if (!VALID_APPLID(appl)) continue;
if (APPL(appl)->releasing) continue; register_appl(card, appl, &APPL(appl)->rparam);
card->driver->register_appl(card, appl, &APPL(appl)->rparam);
} }
printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", 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) static void controllercb_reseted(struct capi_ctr * card)
{ {
u16 appl; u16 appl;
if (card->cardstate == CARD_FREE)
return;
if (card->cardstate == CARD_DETECTED) if (card->cardstate == CARD_DETECTED)
return; return;
...@@ -901,24 +949,25 @@ static void controllercb_reseted(struct capi_ctr * card) ...@@ -901,24 +949,25 @@ static void controllercb_reseted(struct capi_ctr * card)
struct capi_ncci *np = *pp; struct capi_ncci *np = *pp;
*pp = np->next; *pp = np->next;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci); 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); kfree(np);
nextpp = pp; nextpp = pp;
} else { } else {
nextpp = &(*pp)->next; nextpp = &(*pp)->next;
} }
} }
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) static void controllercb_suspend_output(struct capi_ctr *card)
{ {
if (!card->blocked) { 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; card->blocked = 1;
} }
} }
...@@ -926,7 +975,7 @@ static void controllercb_suspend_output(struct capi_ctr *card) ...@@ -926,7 +975,7 @@ static void controllercb_suspend_output(struct capi_ctr *card)
static void controllercb_resume_output(struct capi_ctr *card) static void controllercb_resume_output(struct capi_ctr *card)
{ {
if (card->blocked) { 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; card->blocked = 0;
} }
} }
...@@ -935,21 +984,27 @@ static void controllercb_resume_output(struct capi_ctr *card) ...@@ -935,21 +984,27 @@ static void controllercb_resume_output(struct capi_ctr *card)
struct capi_ctr * struct capi_ctr *
drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata) attach_capi_ctr(struct capi_driver *driver, char *name, void *driverdata)
{ {
struct capi_ctr *card, **pp; struct capi_ctr *card;
int i; 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) { if (i == CAPI_MAXCONTR) {
printk(KERN_ERR "kcapi: out of controller slots\n"); 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)); memset(card, 0, sizeof(struct capi_ctr));
card->driver = driver; card->driver = driver;
card->cnr = CARDNR(card); card->cnr = i + 1;
strncpy(card->name, name, sizeof(card->name)); strncpy(card->name, name, sizeof(card->name));
card->cardstate = CARD_DETECTED; card->cardstate = CARD_DETECTED;
card->blocked = 0; card->blocked = 0;
...@@ -961,14 +1016,10 @@ drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata) ...@@ -961,14 +1016,10 @@ drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata)
card->suspend_output = controllercb_suspend_output; card->suspend_output = controllercb_suspend_output;
card->resume_output = controllercb_resume_output; card->resume_output = controllercb_resume_output;
card->handle_capimsg = controllercb_handle_capimsg; card->handle_capimsg = controllercb_handle_capimsg;
card->appl_registered = controllercb_appl_registered;
card->appl_released = controllercb_appl_released;
card->new_ncci = controllercb_new_ncci; card->new_ncci = controllercb_new_ncci;
card->free_ncci = controllercb_free_ncci; card->free_ncci = controllercb_free_ncci;
for (pp = &driver->controller; *pp; pp = &(*pp)->next) ; list_add_tail(&card->driver_list, &driver->contr_head);
card->next = 0;
*pp = card;
driver->ncontroller++; driver->ncontroller++;
sprintf(card->procfn, "capi/controllers/%d", card->cnr); sprintf(card->procfn, "capi/controllers/%d", card->cnr);
card->procent = create_proc_entry(card->procfn, 0, 0); card->procent = create_proc_entry(card->procfn, 0, 0);
...@@ -985,33 +1036,33 @@ drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata) ...@@ -985,33 +1036,33 @@ drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata)
return card; return card;
} }
static int drivercb_detach_ctr(struct capi_ctr *card) EXPORT_SYMBOL(attach_capi_ctr);
int detach_capi_ctr(struct capi_ctr *card)
{ {
struct capi_driver *driver = card->driver; struct capi_driver *driver = card->driver;
struct capi_ctr **pp;
if (card->cardstate == CARD_FREE)
return 0;
if (card->cardstate != CARD_DETECTED) if (card->cardstate != CARD_DETECTED)
controllercb_reseted(card); controllercb_reseted(card);
for (pp = &driver->controller; *pp ; pp = &(*pp)->next) {
if (*pp == card) { list_del(&card->driver_list);
*pp = card->next; driver->ncontroller--;
driver->ncontroller--; ncards--;
ncards--;
break;
}
}
if (card->procent) { if (card->procent) {
remove_proc_entry(card->procfn, 0); remove_proc_entry(card->procfn, 0);
card->procent = 0; card->procent = 0;
} }
card->cardstate = CARD_FREE; cards[card->cnr - 1] = NULL;
printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n", printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n",
card->cnr, card->name); card->cnr, card->name);
kfree(card);
return 0; return 0;
} }
EXPORT_SYMBOL(detach_capi_ctr);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* fallback if no driver read_proc function defined by driver */ /* fallback if no driver read_proc function defined by driver */
...@@ -1034,21 +1085,14 @@ static int driver_read_proc(char *page, char **start, off_t off, ...@@ -1034,21 +1085,14 @@ static int driver_read_proc(char *page, char **start, off_t off,
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface di = { void attach_capi_driver(struct capi_driver *driver)
drivercb_attach_ctr,
drivercb_detach_ctr,
};
struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
{ {
struct capi_driver **pp; INIT_LIST_HEAD(&driver->contr_head);
MOD_INC_USE_COUNT;
spin_lock(&drivers_lock); spin_lock(&drivers_lock);
for (pp = &drivers; *pp; pp = &(*pp)->next) ; list_add_tail(&driver->driver_list, &drivers);
driver->next = 0;
*pp = driver;
spin_unlock(&drivers_lock); spin_unlock(&drivers_lock);
printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name); printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name);
sprintf(driver->procfn, "capi/drivers/%s", driver->name); sprintf(driver->procfn, "capi/drivers/%s", driver->name);
driver->procent = create_proc_entry(driver->procfn, 0, 0); driver->procent = create_proc_entry(driver->procfn, 0, 0);
...@@ -1062,28 +1106,25 @@ struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver) ...@@ -1062,28 +1106,25 @@ struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
} }
driver->procent->data = driver; driver->procent->data = driver;
} }
return &di;
} }
EXPORT_SYMBOL(attach_capi_driver);
void detach_capi_driver(struct capi_driver *driver) void detach_capi_driver(struct capi_driver *driver)
{ {
struct capi_driver **pp;
spin_lock(&drivers_lock); spin_lock(&drivers_lock);
for (pp = &drivers; *pp && *pp != driver; pp = &(*pp)->next) ; list_del(&driver->driver_list);
if (*pp) {
*pp = (*pp)->next;
printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name);
} else {
printk(KERN_ERR "kcapi: driver %s double detach ?\n", driver->name);
}
spin_unlock(&drivers_lock); spin_unlock(&drivers_lock);
printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name);
if (driver->procent) { if (driver->procent) {
remove_proc_entry(driver->procfn, 0); remove_proc_entry(driver->procfn, 0);
driver->procent = 0; driver->procent = 0;
} }
MOD_DEC_USE_COUNT;
} }
EXPORT_SYMBOL(detach_capi_driver);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* -------- CAPI2.0 Interface ---------------------------------- */ /* -------- CAPI2.0 Interface ---------------------------------- */
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -1092,7 +1133,7 @@ static u16 capi_isinstalled(void) ...@@ -1092,7 +1133,7 @@ static u16 capi_isinstalled(void)
{ {
int i; int i;
for (i = 0; i < CAPI_MAXCONTR; 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_NOERROR;
} }
return CAPI_REGNOTINSTALLED; return CAPI_REGNOTINSTALLED;
...@@ -1120,10 +1161,9 @@ static u16 capi_register(capi_register_params * rparam, u16 * applidp) ...@@ -1120,10 +1161,9 @@ static u16 capi_register(capi_register_params * rparam, u16 * applidp)
memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params)); memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params));
for (i = 0; i < CAPI_MAXCONTR; i++) { for (i = 0; i < CAPI_MAXCONTR; i++) {
if (cards[i].cardstate != CARD_RUNNING) if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue; continue;
cards[i].driver->register_appl(&cards[i], appl, register_appl(cards[i], appl, &APPL(appl)->rparam);
&APPL(appl)->rparam);
} }
*applidp = appl; *applidp = appl;
printk(KERN_INFO "kcapi: appl %d up\n", appl); printk(KERN_INFO "kcapi: appl %d up\n", appl);
...@@ -1135,29 +1175,25 @@ static u16 capi_release(u16 applid) ...@@ -1135,29 +1175,25 @@ static u16 capi_release(u16 applid)
{ {
int i; int i;
if (!VALID_APPLID(applid) || APPL(applid)->releasing) if (!VALID_APPLID(applid))
return CAPI_ILLAPPNR; return CAPI_ILLAPPNR;
APPL(applid)->releasing++;
skb_queue_purge(&APPL(applid)->recv_queue); skb_queue_purge(&APPL(applid)->recv_queue);
for (i = 0; i < CAPI_MAXCONTR; i++) { for (i = 0; i < CAPI_MAXCONTR; i++) {
if (cards[i].cardstate != CARD_RUNNING) if (!cards[i] || cards[i]->cardstate != CARD_RUNNING)
continue; continue;
APPL(applid)->releasing++; release_appl(cards[i], applid);
cards[i].driver->release_appl(&cards[i], applid);
}
APPL(applid)->releasing--;
if (APPL(applid)->releasing <= 0) {
APPL(applid)->signal = 0;
APPL_MARK_FREE(applid);
printk(KERN_INFO "kcapi: appl %d down\n", applid);
} }
APPL(applid)->signal = 0;
APPL_MARK_FREE(applid);
printk(KERN_INFO "kcapi: appl %d down\n", applid);
return CAPI_NOERROR; return CAPI_NOERROR;
} }
static u16 capi_put_message(u16 applid, struct sk_buff *skb) static u16 capi_put_message(u16 applid, struct sk_buff *skb)
{ {
struct capi_ctr *card;
struct capi_ncci *np; struct capi_ncci *np;
u32 contr;
int showctl = 0; int showctl = 0;
u8 cmd, subcmd; u8 cmd, subcmd;
...@@ -1169,13 +1205,13 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb) ...@@ -1169,13 +1205,13 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb)
|| !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
|| !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
contr = CAPIMSG_CONTROLLER(skb->data); card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) { if (!card || card->cardstate != CARD_RUNNING) {
contr = 1; card = get_capi_ctr_by_nr(1); // XXX why?
if (CARD(contr)->cardstate != CARD_RUNNING) if (!card || card->cardstate != CARD_RUNNING)
return CAPI_REGNOTINSTALLED; return CAPI_REGNOTINSTALLED;
} }
if (CARD(contr)->blocked) if (card->blocked)
return CAPI_SENDQUEUEFULL; return CAPI_SENDQUEUEFULL;
cmd = CAPIMSG_COMMAND(skb->data); cmd = CAPIMSG_COMMAND(skb->data);
...@@ -1185,30 +1221,30 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb) ...@@ -1185,30 +1221,30 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb)
if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0 if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0
&& mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0) && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0)
return CAPI_SENDQUEUEFULL; return CAPI_SENDQUEUEFULL;
CARD(contr)->nsentdatapkt++; card->nsentdatapkt++;
APPL(applid)->nsentdatapkt++; APPL(applid)->nsentdatapkt++;
if (CARD(contr)->traceflag > 2) showctl |= 2; if (card->traceflag > 2) showctl |= 2;
} else { } else {
CARD(contr)->nsentctlpkt++; card->nsentctlpkt++;
APPL(applid)->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 & 2) {
if (showctl & 1) { if (showctl & 1) {
printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n", printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n",
(unsigned long) contr, CAPIMSG_CONTROLLER(skb->data),
CAPIMSG_APPID(skb->data), CAPIMSG_APPID(skb->data),
capi_cmd2str(cmd, subcmd), capi_cmd2str(cmd, subcmd),
CAPIMSG_LEN(skb->data)); CAPIMSG_LEN(skb->data));
} else { } else {
printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n", printk(KERN_DEBUG "kcapi: put [%#x] %s\n",
(unsigned long) contr, CAPIMSG_CONTROLLER(skb->data),
capi_message2str(skb->data)); capi_message2str(skb->data));
} }
} }
CARD(contr)->driver->send_message(CARD(contr), skb); card->driver->send_message(card, skb);
return CAPI_NOERROR; return CAPI_NOERROR;
} }
...@@ -1237,64 +1273,81 @@ static u16 capi_set_signal(u16 applid, ...@@ -1237,64 +1273,81 @@ static u16 capi_set_signal(u16 applid,
static u16 capi_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]) static u16 capi_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
{ {
struct capi_ctr *card;
if (contr == 0) { if (contr == 0) {
strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
return CAPI_NOERROR; 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; return CAPI_REGNOTINSTALLED;
strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN); strncpy(buf, card->manu, CAPI_MANUFACTURER_LEN);
return CAPI_NOERROR; return CAPI_NOERROR;
} }
static u16 capi_get_version(u32 contr, struct capi_version *verp) static u16 capi_get_version(u32 contr, struct capi_version *verp)
{ {
struct capi_ctr *card;
if (contr == 0) { if (contr == 0) {
*verp = driver_version; *verp = driver_version;
return CAPI_NOERROR; 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; return CAPI_REGNOTINSTALLED;
memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version)); memcpy((void *) verp, &card->version, sizeof(capi_version));
return CAPI_NOERROR; return CAPI_NOERROR;
} }
static u16 capi_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]) static u16 capi_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN])
{ {
struct capi_ctr *card;
if (contr == 0) { if (contr == 0) {
strncpy(serial, driver_serial, CAPI_SERIAL_LEN); strncpy(serial, driver_serial, CAPI_SERIAL_LEN);
return CAPI_NOERROR; 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; return CAPI_REGNOTINSTALLED;
strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN); strncpy((void *) serial, card->serial, CAPI_SERIAL_LEN);
return CAPI_NOERROR; return CAPI_NOERROR;
} }
static u16 capi_get_profile(u32 contr, struct capi_profile *profp) static u16 capi_get_profile(u32 contr, struct capi_profile *profp)
{ {
struct capi_ctr *card;
if (contr == 0) { if (contr == 0) {
profp->ncontroller = ncards; profp->ncontroller = ncards;
return CAPI_NOERROR; 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; return CAPI_REGNOTINSTALLED;
memcpy((void *) profp, &CARD(contr)->profile, memcpy((void *) profp, &card->profile,
sizeof(struct capi_profile)); sizeof(struct capi_profile));
return CAPI_NOERROR; return CAPI_NOERROR;
} }
static struct capi_driver *find_driver(char *name) static struct capi_driver *find_driver(char *name)
{ {
struct list_head *l;
struct capi_driver *dp; struct capi_driver *dp;
spin_lock(&drivers_lock); spin_lock(&drivers_lock);
for (dp = drivers; dp; dp = dp->next) list_for_each(l, &drivers) {
dp = list_entry(l, struct capi_driver, driver_list);
if (strcmp(dp->name, name) == 0) if (strcmp(dp->name, name) == 0)
break; goto found;
}
dp = NULL;
found:
spin_unlock(&drivers_lock); spin_unlock(&drivers_lock);
return dp; return dp;
} }
...@@ -1365,11 +1418,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data) ...@@ -1365,11 +1418,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
sizeof(avmb1_loadandconfigdef)))) sizeof(avmb1_loadandconfigdef))))
return retval; return retval;
} }
if (!VALID_CARD(ldef.contr)) card = get_capi_ctr_by_nr(ldef.contr);
return -ESRCH; if (!card)
card = CARD(ldef.contr);
if (card->cardstate == CARD_FREE)
return -ESRCH; return -ESRCH;
if (card->driver->load_firmware == 0) { if (card->driver->load_firmware == 0) {
printk(KERN_DEBUG "kcapi: load: driver \%s\" has no load function\n", card->driver->name); printk(KERN_DEBUG "kcapi: load: driver \%s\" has no load function\n", card->driver->name);
...@@ -1419,12 +1469,10 @@ static int old_capi_manufacturer(unsigned int cmd, void *data) ...@@ -1419,12 +1469,10 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
if ((retval = copy_from_user((void *) &rdef, data, if ((retval = copy_from_user((void *) &rdef, data,
sizeof(avmb1_resetdef)))) sizeof(avmb1_resetdef))))
return retval; return retval;
if (!VALID_CARD(rdef.contr)) card = get_capi_ctr_by_nr(rdef.contr);
if (!card)
return -ESRCH; return -ESRCH;
card = CARD(rdef.contr);
if (card->cardstate == CARD_FREE)
return -ESRCH;
if (card->cardstate == CARD_DETECTED) if (card->cardstate == CARD_DETECTED)
return 0; return 0;
...@@ -1445,12 +1493,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data) ...@@ -1445,12 +1493,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
sizeof(avmb1_getdef)))) sizeof(avmb1_getdef))))
return retval; return retval;
if (!VALID_CARD(gdef.contr)) card = get_capi_ctr_by_nr(gdef.contr);
return -ESRCH; if (!card)
card = CARD(gdef.contr);
if (card->cardstate == CARD_FREE)
return -ESRCH; return -ESRCH;
gdef.cardstate = card->cardstate; gdef.cardstate = card->cardstate;
...@@ -1469,11 +1513,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data) ...@@ -1469,11 +1513,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
sizeof(avmb1_resetdef)))) sizeof(avmb1_resetdef))))
return retval; return retval;
if (!VALID_CARD(rdef.contr)) card = get_capi_ctr_by_nr(rdef.contr);
return -ESRCH; if (!card)
card = CARD(rdef.contr);
if (card->cardstate == CARD_FREE)
return -ESRCH; return -ESRCH;
if (card->cardstate != CARD_DETECTED) if (card->cardstate != CARD_DETECTED)
...@@ -1481,7 +1522,7 @@ static int old_capi_manufacturer(unsigned int cmd, void *data) ...@@ -1481,7 +1522,7 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
card->driver->remove_ctr(card); card->driver->remove_ctr(card);
while (card->cardstate != CARD_FREE) { while (cards[rdef.contr]) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/10); /* 0.1 sec */ schedule_timeout(HZ/10); /* 0.1 sec */
...@@ -1519,11 +1560,10 @@ static int capi_manufacturer(unsigned int cmd, void *data) ...@@ -1519,11 +1560,10 @@ static int capi_manufacturer(unsigned int cmd, void *data)
sizeof(kcapi_flagdef)))) sizeof(kcapi_flagdef))))
return retval; return retval;
if (!VALID_CARD(fdef.contr)) card = get_capi_ctr_by_nr(fdef.contr);
return -ESRCH; if (!card)
card = CARD(fdef.contr);
if (card->cardstate == CARD_FREE)
return -ESRCH; return -ESRCH;
card->traceflag = fdef.flag; card->traceflag = fdef.flag;
printk(KERN_INFO "kcapi: contr %d set trace=%d\n", printk(KERN_INFO "kcapi: contr %d set trace=%d\n",
card->cnr, card->traceflag); card->cnr, card->traceflag);
...@@ -1591,56 +1631,31 @@ struct capi_interface avmb1_interface = ...@@ -1591,56 +1631,31 @@ struct capi_interface avmb1_interface =
struct capi_interface *attach_capi_interface(struct capi_interface_user *userp) struct capi_interface *attach_capi_interface(struct capi_interface_user *userp)
{ {
struct capi_interface_user *p;
MOD_INC_USE_COUNT; spin_lock(&users_lock);
spin_lock(&capi_users_lock); list_add_tail(&userp->user_list, &users);
for (p = capi_users; p; p = p->next) { spin_unlock(&users_lock);
if (p == userp) {
spin_unlock(&capi_users_lock);
printk(KERN_ERR "kcapi: double attach from %s\n",
userp->name);
MOD_DEC_USE_COUNT;
return 0;
}
}
userp->next = capi_users;
capi_users = userp;
spin_unlock(&capi_users_lock);
printk(KERN_NOTICE "kcapi: %s attached\n", userp->name); printk(KERN_NOTICE "kcapi: %s attached\n", userp->name);
return &avmb1_interface; return &avmb1_interface;
} }
EXPORT_SYMBOL(attach_capi_interface);
int detach_capi_interface(struct capi_interface_user *userp) int detach_capi_interface(struct capi_interface_user *userp)
{ {
struct capi_interface_user **pp; spin_lock(&users_lock);
list_del(&userp->user_list);
spin_lock(&capi_users_lock); printk(KERN_NOTICE "kcapi: %s detached\n", userp->name);
for (pp = &capi_users; *pp; pp = &(*pp)->next) { return 0;
if (*pp == userp) {
*pp = userp->next;
spin_unlock(&capi_users_lock);
userp->next = 0;
printk(KERN_NOTICE "kcapi: %s detached\n", userp->name);
MOD_DEC_USE_COUNT;
return 0;
}
}
spin_unlock(&capi_users_lock);
printk(KERN_ERR "kcapi: double detach from %s\n", userp->name);
return -1;
} }
EXPORT_SYMBOL(detach_capi_interface);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* -------- Init & Cleanup ------------------------------------- */ /* -------- Init & Cleanup ------------------------------------- */
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
EXPORT_SYMBOL(attach_capi_interface);
EXPORT_SYMBOL(detach_capi_interface);
EXPORT_SYMBOL(attach_capi_driver);
EXPORT_SYMBOL(detach_capi_driver);
/* /*
* init / exit functions * init / exit functions
*/ */
......
...@@ -357,8 +357,6 @@ void b1_register_appl(struct capi_ctr *ctrl, ...@@ -357,8 +357,6 @@ void b1_register_appl(struct capi_ctr *ctrl,
b1_put_word(port, rp->datablkcnt); b1_put_word(port, rp->datablkcnt);
b1_put_word(port, rp->datablklen); b1_put_word(port, rp->datablklen);
restore_flags(flags); restore_flags(flags);
ctrl->appl_registered(ctrl, appl);
} }
void b1_release_appl(struct capi_ctr *ctrl, u16 appl) void b1_release_appl(struct capi_ctr *ctrl, u16 appl)
...@@ -548,7 +546,7 @@ void b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) ...@@ -548,7 +546,7 @@ void b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
if (NCCI != 0xffffffff) if (NCCI != 0xffffffff)
ctrl->free_ncci(ctrl, ApplId, NCCI); ctrl->free_ncci(ctrl, ApplId, NCCI);
else ctrl->appl_released(ctrl, ApplId);
break; break;
case RECEIVE_START: case RECEIVE_START:
......
...@@ -509,7 +509,7 @@ static void b1dma_handle_rx(avmcard *card) ...@@ -509,7 +509,7 @@ static void b1dma_handle_rx(avmcard *card)
if (NCCI != 0xffffffff) if (NCCI != 0xffffffff)
ctrl->free_ncci(ctrl, ApplId, NCCI); ctrl->free_ncci(ctrl, ApplId, NCCI);
else ctrl->appl_released(ctrl, ApplId);
break; break;
case RECEIVE_START: case RECEIVE_START:
...@@ -774,8 +774,6 @@ void b1dma_register_appl(struct capi_ctr *ctrl, ...@@ -774,8 +774,6 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_put(skb, (u8 *)p - (u8 *)skb->data);
b1dma_queue_tx(card, skb); b1dma_queue_tx(card, skb);
ctrl->appl_registered(ctrl, appl);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
......
...@@ -34,10 +34,6 @@ MODULE_LICENSE("GPL"); ...@@ -34,10 +34,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static void b1isa_remove_ctr(struct capi_ctr *ctrl) static void b1isa_remove_ctr(struct capi_ctr *ctrl)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
...@@ -47,7 +43,7 @@ static void b1isa_remove_ctr(struct capi_ctr *ctrl) ...@@ -47,7 +43,7 @@ static void b1isa_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port); b1_reset(port);
b1_reset(port); b1_reset(port);
di->detach_ctr(ctrl); detach_capi_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card); b1_free_card(card);
...@@ -111,7 +107,7 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -111,7 +107,7 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
b1_reset(card->port); b1_reset(card->port);
b1_getrevision(card); b1_getrevision(card);
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "b1isa: attach controller failed.\n"); printk(KERN_ERR "b1isa: attach controller failed.\n");
retval = -EBUSY; retval = -EBUSY;
...@@ -154,27 +150,27 @@ static char *b1isa_procinfo(struct capi_ctr *ctrl) ...@@ -154,27 +150,27 @@ static char *b1isa_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver b1isa_driver = { static struct capi_driver b1isa_driver = {
name: "b1isa", owner: THIS_MODULE,
revision: "0.0", name: "b1isa",
load_firmware: b1_load_firmware, revision: "0.0",
reset_ctr: b1_reset_ctr, load_firmware: b1_load_firmware,
remove_ctr: b1isa_remove_ctr, reset_ctr: b1_reset_ctr,
register_appl: b1_register_appl, remove_ctr: b1isa_remove_ctr,
release_appl: b1_release_appl, register_appl: b1_register_appl,
send_message: b1_send_message, release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1isa_procinfo,
ctr_read_proc: b1ctl_read_proc, procinfo: b1isa_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: b1isa_add_card,
add_card: b1isa_add_card,
}; };
static int __init b1isa_init(void) static int __init b1isa_init(void)
{ {
struct capi_driver *driver = &b1isa_driver; struct capi_driver *driver = &b1isa_driver;
char *p; char *p;
int retval = 0;
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
...@@ -187,15 +183,9 @@ static int __init b1isa_init(void) ...@@ -187,15 +183,9 @@ static int __init b1isa_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(driver); attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
retval = -EIO;
}
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return 0;
} }
static void __exit b1isa_exit(void) static void __exit b1isa_exit(void)
......
...@@ -42,10 +42,6 @@ MODULE_LICENSE("GPL"); ...@@ -42,10 +42,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static char *b1pci_procinfo(struct capi_ctr *ctrl) static char *b1pci_procinfo(struct capi_ctr *ctrl)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
...@@ -113,7 +109,7 @@ static int b1pci_add_card(struct capi_driver *driver, ...@@ -113,7 +109,7 @@ static int b1pci_add_card(struct capi_driver *driver,
goto err_release_region; goto err_release_region;
} }
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", printk(KERN_ERR "%s: attach controller failed.\n",
driver->name); driver->name);
...@@ -153,7 +149,7 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl) ...@@ -153,7 +149,7 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port); b1_reset(port);
b1_reset(port); b1_reset(port);
di->detach_ctr(ctrl); detach_capi_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
ctrl->driverdata = 0; ctrl->driverdata = 0;
...@@ -165,29 +161,26 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl) ...@@ -165,29 +161,26 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver b1pci_driver = { static struct capi_driver b1pci_driver = {
name: "b1pci", owner: THIS_MODULE,
revision: "0.0", name: "b1pci",
load_firmware: b1_load_firmware, revision: "0.0",
reset_ctr: b1_reset_ctr, load_firmware: b1_load_firmware,
remove_ctr: b1pci_remove_ctr, reset_ctr: b1_reset_ctr,
register_appl: b1_register_appl, remove_ctr: b1pci_remove_ctr,
release_appl: b1_release_appl, register_appl: b1_register_appl,
send_message: b1_send_message, release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1pci_procinfo,
ctr_read_proc: b1ctl_read_proc, procinfo: b1pci_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
add_card: 0, /* no add_card function */
}; };
#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface *div4;
/* ------------------------------------------------------------- */
static char *b1pciv4_procinfo(struct capi_ctr *ctrl) static char *b1pciv4_procinfo(struct capi_ctr *ctrl)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
...@@ -274,7 +267,7 @@ static int b1pciv4_add_card(struct capi_driver *driver, ...@@ -274,7 +267,7 @@ static int b1pciv4_add_card(struct capi_driver *driver,
goto err_unmap; goto err_unmap;
} }
cinfo->capi_ctrl = div4->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", driver->name); printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
retval = -EBUSY; retval = -EBUSY;
...@@ -312,7 +305,7 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl) ...@@ -312,7 +305,7 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl)
b1dma_reset(card); b1dma_reset(card);
div4->detach_ctr(ctrl); detach_capi_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
iounmap(card->mbase); iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
...@@ -327,20 +320,21 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl) ...@@ -327,20 +320,21 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl)
static struct capi_driver b1pciv4_driver = { static struct capi_driver b1pciv4_driver = {
name: "b1pciv4", owner: THIS_MODULE,
revision: "0.0", name: "b1pciv4",
load_firmware: b1dma_load_firmware, revision: "0.0",
reset_ctr: b1dma_reset_ctr, load_firmware: b1dma_load_firmware,
remove_ctr: b1pciv4_remove_ctr, reset_ctr: b1dma_reset_ctr,
register_appl: b1dma_register_appl, remove_ctr: b1pciv4_remove_ctr,
release_appl: b1dma_release_appl, register_appl: b1dma_register_appl,
send_message: b1dma_send_message, release_appl: b1dma_release_appl,
send_message: b1dma_send_message,
procinfo: b1pciv4_procinfo,
ctr_read_proc: b1dmactl_read_proc, procinfo: b1pciv4_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: b1dmactl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
add_card: 0, /* no add_card function */
}; };
#endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */ #endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
...@@ -432,25 +426,12 @@ static int __init b1pci_init(void) ...@@ -432,25 +426,12 @@ static int __init b1pci_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(driver); attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
MOD_DEC_USE_COUNT;
return -ENODEV;
}
#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
printk(KERN_INFO "%s: revision %s\n", driverv4->name, driverv4->revision); printk(KERN_INFO "%s: revision %s\n", driverv4->name, driverv4->revision);
div4 = attach_capi_driver(driverv4); attach_capi_driver(driverv4);
if (!div4) {
detach_capi_driver(driver);
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driverv4->name);
MOD_DEC_USE_COUNT;
return -ENODEV;
}
#endif #endif
ncards = pci_register_driver(&b1pci_pci_driver); ncards = pci_register_driver(&b1pci_pci_driver);
......
...@@ -35,10 +35,6 @@ MODULE_LICENSE("GPL"); ...@@ -35,10 +35,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl) static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
...@@ -48,7 +44,7 @@ static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl) ...@@ -48,7 +44,7 @@ static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port); b1_reset(port);
b1_reset(port); b1_reset(port);
di->detach_ctr(ctrl); detach_capi_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
b1_free_card(card); b1_free_card(card);
...@@ -103,7 +99,7 @@ static int b1pcmcia_add_card(struct capi_driver *driver, ...@@ -103,7 +99,7 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
b1_reset(card->port); b1_reset(card->port);
b1_getrevision(card); b1_getrevision(card);
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", printk(KERN_ERR "%s: attach controller failed.\n",
driver->name); driver->name);
...@@ -152,20 +148,21 @@ static char *b1pcmcia_procinfo(struct capi_ctr *ctrl) ...@@ -152,20 +148,21 @@ static char *b1pcmcia_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver b1pcmcia_driver = { static struct capi_driver b1pcmcia_driver = {
name: "b1pcmcia", owner: THIS_MODULE,
revision: "0.0", name: "b1pcmcia",
load_firmware: b1_load_firmware, revision: "0.0",
reset_ctr: b1_reset_ctr, load_firmware: b1_load_firmware,
remove_ctr: b1pcmcia_remove_ctr, reset_ctr: b1_reset_ctr,
register_appl: b1_register_appl, remove_ctr: b1pcmcia_remove_ctr,
release_appl: b1_release_appl, register_appl: b1_register_appl,
send_message: b1_send_message, release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1pcmcia_procinfo,
ctr_read_proc: b1ctl_read_proc, procinfo: b1pcmcia_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0,
add_card: 0,
}; };
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -187,10 +184,12 @@ int b1pcmcia_addcard_m2(unsigned int port, unsigned irq) ...@@ -187,10 +184,12 @@ int b1pcmcia_addcard_m2(unsigned int port, unsigned irq)
int b1pcmcia_delcard(unsigned int port, unsigned irq) int b1pcmcia_delcard(unsigned int port, unsigned irq)
{ {
struct list_head *l;
struct capi_ctr *ctrl; struct capi_ctr *ctrl;
avmcard *card; avmcard *card;
for (ctrl = b1pcmcia_driver.controller; ctrl; ctrl = ctrl->next) { list_for_each(l, &b1pcmcia_driver.contr_head) {
ctrl = list_entry(l, struct capi_ctr, driver_list);
card = ((avmctrl_info *)(ctrl->driverdata))->card; card = ((avmctrl_info *)(ctrl->driverdata))->card;
if (card->port == port && card->irq == irq) { if (card->port == port && card->irq == irq) {
b1pcmcia_remove_ctr(ctrl); b1pcmcia_remove_ctr(ctrl);
...@@ -224,13 +223,8 @@ static int __init b1pcmcia_init(void) ...@@ -224,13 +223,8 @@ static int __init b1pcmcia_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(driver); attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
retval = -EIO;
}
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return retval;
} }
......
...@@ -52,10 +52,6 @@ MODULE_PARM(suppress_pollack, "0-1i"); ...@@ -52,10 +52,6 @@ MODULE_PARM(suppress_pollack, "0-1i");
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static void c4_dispatch_tx(avmcard *card); static void c4_dispatch_tx(avmcard *card);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -587,12 +583,6 @@ static void c4_handle_rx(avmcard *card) ...@@ -587,12 +583,6 @@ static void c4_handle_rx(avmcard *card)
ctrl = card->ctrlinfo[cidx].capi_ctrl; ctrl = card->ctrlinfo[cidx].capi_ctrl;
if (ctrl) if (ctrl)
ctrl->free_ncci(ctrl, ApplId, NCCI); ctrl->free_ncci(ctrl, ApplId, NCCI);
} else {
for (cidx=0; cidx < 4; cidx++) {
ctrl = card->ctrlinfo[cidx].capi_ctrl;
if (ctrl)
ctrl->appl_released(ctrl, ApplId);
}
} }
break; break;
...@@ -918,7 +908,7 @@ static void c4_remove_ctr(struct capi_ctr *ctrl) ...@@ -918,7 +908,7 @@ static void c4_remove_ctr(struct capi_ctr *ctrl)
for (i=0; i < 4; i++) { for (i=0; i < 4; i++) {
cinfo = &card->ctrlinfo[i]; cinfo = &card->ctrlinfo[i];
if (cinfo->capi_ctrl) { if (cinfo->capi_ctrl) {
di->detach_ctr(cinfo->capi_ctrl); detach_capi_ctr(cinfo->capi_ctrl);
cinfo->capi_ctrl = NULL; cinfo->capi_ctrl = NULL;
} }
} }
...@@ -973,8 +963,6 @@ void c4_register_appl(struct capi_ctr *ctrl, ...@@ -973,8 +963,6 @@ void c4_register_appl(struct capi_ctr *ctrl,
skb_queue_tail(&card->dma->send_queue, skb); skb_queue_tail(&card->dma->send_queue, skb);
c4_dispatch_tx(card); c4_dispatch_tx(card);
} }
ctrl->appl_registered(ctrl, appl);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -1170,13 +1158,13 @@ static int c4_add_card(struct capi_driver *driver, ...@@ -1170,13 +1158,13 @@ static int c4_add_card(struct capi_driver *driver,
for (i=0; i < nr_controllers ; i++) { for (i=0; i < nr_controllers ; i++) {
cinfo = &card->ctrlinfo[i]; cinfo = &card->ctrlinfo[i];
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed (%d).\n", printk(KERN_ERR "%s: attach controller failed (%d).\n",
driver->name, i); driver->name, i);
for (i--; i >= 0; i--) { for (i--; i >= 0; i--) {
cinfo = &card->ctrlinfo[i]; cinfo = &card->ctrlinfo[i];
di->detach_ctr(cinfo->capi_ctrl); detach_capi_ctr(cinfo->capi_ctrl);
} }
goto err_free_irq; goto err_free_irq;
} }
...@@ -1208,37 +1196,39 @@ static int c4_add_card(struct capi_driver *driver, ...@@ -1208,37 +1196,39 @@ static int c4_add_card(struct capi_driver *driver,
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver c2_driver = { static struct capi_driver c2_driver = {
name: "c2", owner: THIS_MODULE,
revision: "0.0", name: "c2",
load_firmware: c4_load_firmware, revision: "0.0",
reset_ctr: c4_reset_ctr, load_firmware: c4_load_firmware,
remove_ctr: c4_remove_ctr, reset_ctr: c4_reset_ctr,
register_appl: c4_register_appl, remove_ctr: c4_remove_ctr,
release_appl: c4_release_appl, register_appl: c4_register_appl,
send_message: c4_send_message, release_appl: c4_release_appl,
send_message: c4_send_message,
procinfo: c4_procinfo,
ctr_read_proc: c4_read_proc, procinfo: c4_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: c4_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
add_card: 0, /* no add_card function */
}; };
static struct capi_driver c4_driver = { static struct capi_driver c4_driver = {
name: "c4", owner: THIS_MODULE,
revision: "0.0", name: "c4",
load_firmware: c4_load_firmware, revision: "0.0",
reset_ctr: c4_reset_ctr, load_firmware: c4_load_firmware,
remove_ctr: c4_remove_ctr, reset_ctr: c4_reset_ctr,
register_appl: c4_register_appl, remove_ctr: c4_remove_ctr,
release_appl: c4_release_appl, register_appl: c4_register_appl,
send_message: c4_send_message, release_appl: c4_release_appl,
send_message: c4_send_message,
procinfo: c4_procinfo,
ctr_read_proc: c4_read_proc, procinfo: c4_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: c4_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
add_card: 0, /* no add_card function */
}; };
static int c4_attach_driver (struct capi_driver * driver) static int c4_attach_driver (struct capi_driver * driver)
...@@ -1253,13 +1243,7 @@ static int c4_attach_driver (struct capi_driver * driver) ...@@ -1253,13 +1243,7 @@ static int c4_attach_driver (struct capi_driver * driver)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(driver); attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
MOD_DEC_USE_COUNT;
return -ENODEV;
}
return 0; return 0;
} }
......
...@@ -35,10 +35,6 @@ MODULE_LICENSE("GPL"); ...@@ -35,10 +35,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static int hema_irq_table[16] = static int hema_irq_table[16] =
{0, {0,
0, 0,
...@@ -199,7 +195,7 @@ static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs) ...@@ -199,7 +195,7 @@ static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
if (NCCI != 0xffffffff) if (NCCI != 0xffffffff)
ctrl->free_ncci(ctrl, ApplId, NCCI); ctrl->free_ncci(ctrl, ApplId, NCCI);
else ctrl->appl_released(ctrl, ApplId);
break; break;
case RECEIVE_START: case RECEIVE_START:
...@@ -331,7 +327,7 @@ static void t1isa_remove_ctr(struct capi_ctr *ctrl) ...@@ -331,7 +327,7 @@ static void t1isa_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port); b1_reset(port);
t1_reset(port); t1_reset(port);
di->detach_ctr(ctrl); detach_capi_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card); b1_free_card(card);
...@@ -344,6 +340,7 @@ static void t1isa_remove_ctr(struct capi_ctr *ctrl) ...@@ -344,6 +340,7 @@ static void t1isa_remove_ctr(struct capi_ctr *ctrl)
static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
{ {
struct capi_ctr *ctrl; struct capi_ctr *ctrl;
struct list_head *l;
avmctrl_info *cinfo; avmctrl_info *cinfo;
avmcard *card; avmcard *card;
int retval; int retval;
...@@ -376,8 +373,11 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -376,8 +373,11 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
retval = -EINVAL; retval = -EINVAL;
goto err_free; goto err_free;
} }
for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) { list_for_each(l, &driver->contr_head) {
avmcard *cardp = ((avmctrl_info *)(ctrl->driverdata))->card; avmcard *cardp;
ctrl = list_entry(l, struct capi_ctr, driver_list);
cardp = ((avmctrl_info *)(ctrl->driverdata))->card;
if (cardp->cardnr == card->cardnr) { if (cardp->cardnr == card->cardnr) {
printk(KERN_WARNING "%s: card with number %d already installed at 0x%x.\n", printk(KERN_WARNING "%s: card with number %d already installed at 0x%x.\n",
driver->name, card->cardnr, cardp->port); driver->name, card->cardnr, cardp->port);
...@@ -408,7 +408,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -408,7 +408,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
t1_disable_irq(card->port); t1_disable_irq(card->port);
b1_reset(card->port); b1_reset(card->port);
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", printk(KERN_ERR "%s: attach controller failed.\n",
driver->name); driver->name);
...@@ -479,20 +479,21 @@ static char *t1isa_procinfo(struct capi_ctr *ctrl) ...@@ -479,20 +479,21 @@ static char *t1isa_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver t1isa_driver = { static struct capi_driver t1isa_driver = {
name: "t1isa", owner: THIS_MODULE,
revision: "0.0", name: "t1isa",
load_firmware: t1isa_load_firmware, revision: "0.0",
reset_ctr: t1isa_reset_ctr, load_firmware: t1isa_load_firmware,
remove_ctr: t1isa_remove_ctr, reset_ctr: t1isa_reset_ctr,
register_appl: b1_register_appl, remove_ctr: t1isa_remove_ctr,
release_appl: b1_release_appl, register_appl: b1_register_appl,
send_message: t1isa_send_message, release_appl: b1_release_appl,
send_message: t1isa_send_message,
procinfo: t1isa_procinfo,
ctr_read_proc: b1ctl_read_proc, procinfo: t1isa_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: t1isa_add_card,
add_card: t1isa_add_card,
}; };
static int __init t1isa_init(void) static int __init t1isa_init(void)
...@@ -512,13 +513,7 @@ static int __init t1isa_init(void) ...@@ -512,13 +513,7 @@ static int __init t1isa_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(driver); attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
retval = -EIO;
}
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return retval;
......
...@@ -45,10 +45,6 @@ MODULE_LICENSE("GPL"); ...@@ -45,10 +45,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static int t1pci_add_card(struct capi_driver *driver, static int t1pci_add_card(struct capi_driver *driver,
struct capicardparams *p, struct capicardparams *p,
struct pci_dev *dev) struct pci_dev *dev)
...@@ -119,7 +115,7 @@ static int t1pci_add_card(struct capi_driver *driver, ...@@ -119,7 +115,7 @@ static int t1pci_add_card(struct capi_driver *driver,
goto err_unmap; goto err_unmap;
} }
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", driver->name); printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
retval = -EBUSY; retval = -EBUSY;
...@@ -157,7 +153,7 @@ static void t1pci_remove_ctr(struct capi_ctr *ctrl) ...@@ -157,7 +153,7 @@ static void t1pci_remove_ctr(struct capi_ctr *ctrl)
b1dma_reset(card); b1dma_reset(card);
di->detach_ctr(ctrl); detach_capi_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
iounmap(card->mbase); iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
...@@ -189,20 +185,21 @@ static char *t1pci_procinfo(struct capi_ctr *ctrl) ...@@ -189,20 +185,21 @@ static char *t1pci_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static struct capi_driver t1pci_driver = { static struct capi_driver t1pci_driver = {
name: "t1pci", owner: THIS_MODULE,
revision: "0.0", name: "t1pci",
load_firmware: b1dma_load_firmware, revision: "0.0",
reset_ctr: b1dma_reset_ctr, load_firmware: b1dma_load_firmware,
remove_ctr: t1pci_remove_ctr, reset_ctr: b1dma_reset_ctr,
register_appl: b1dma_register_appl, remove_ctr: t1pci_remove_ctr,
release_appl: b1dma_release_appl, register_appl: b1dma_register_appl,
send_message: b1dma_send_message, release_appl: b1dma_release_appl,
send_message: b1dma_send_message,
procinfo: t1pci_procinfo,
ctr_read_proc: b1dmactl_read_proc, procinfo: t1pci_procinfo,
driver_read_proc: 0, /* use standard driver_read_proc */ ctr_read_proc: b1dmactl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
add_card: 0, /* no add_card function */
}; };
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -261,13 +258,7 @@ static int __init t1pci_init(void) ...@@ -261,13 +258,7 @@ static int __init t1pci_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(&t1pci_driver); attach_capi_driver(&t1pci_driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
MOD_DEC_USE_COUNT;
return -EIO;
}
ncards = pci_register_driver(&t1pci_pci_driver); ncards = pci_register_driver(&t1pci_pci_driver);
if (ncards) { if (ncards) {
......
...@@ -98,7 +98,7 @@ hycapi_remove_ctr(struct capi_ctr *ctrl) ...@@ -98,7 +98,7 @@ hycapi_remove_ctr(struct capi_ctr *ctrl)
hycapi_applications[i].listen_req[ctrl->cnr-1] = NULL; hycapi_applications[i].listen_req[ctrl->cnr-1] = NULL;
} }
} }
hy_di->detach_ctr(ctrl); detach_capi_ctr(ctrl);
ctrl->driverdata = 0; ctrl->driverdata = 0;
kfree(card->hyctrlinfo); kfree(card->hyctrlinfo);
...@@ -252,7 +252,6 @@ hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, ...@@ -252,7 +252,6 @@ hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
rp, sizeof(capi_register_params)); rp, sizeof(capi_register_params));
/* MOD_INC_USE_COUNT; */ /* MOD_INC_USE_COUNT; */
ctrl->appl_registered(ctrl, appl);
} }
/********************************************************************* /*********************************************************************
...@@ -313,7 +312,6 @@ hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl) ...@@ -313,7 +312,6 @@ hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
{ {
hycapi_release_internal(ctrl, appl); hycapi_release_internal(ctrl, appl);
} }
ctrl->appl_released(ctrl, appl);
/* MOD_DEC_USE_COUNT; */ /* MOD_DEC_USE_COUNT; */
} }
...@@ -666,18 +664,21 @@ hycapi_tx_capiget(hysdn_card *card) ...@@ -666,18 +664,21 @@ hycapi_tx_capiget(hysdn_card *card)
static struct capi_driver hycapi_driver = { static struct capi_driver hycapi_driver = {
"hysdn", owner: THIS_MODULE,
"0.0", name: "hysdn",
hycapi_load_firmware, revision: "0.0",
hycapi_reset_ctr, load_firmware: hycapi_load_firmware,
hycapi_remove_ctr, reset_ctr: hycapi_reset_ctr,
hycapi_register_appl, remove_ctr: hycapi_remove_ctr,
hycapi_release_appl, register_appl: hycapi_register_appl,
hycapi_send_message, release_appl: hycapi_release_appl,
hycapi_procinfo, send_message: hycapi_send_message,
hycapi_read_proc,
0, /* use standard driver_read_proc */ procinfo: hycapi_procinfo,
0, /* no add_card function */ ctr_read_proc: hycapi_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
}; };
...@@ -698,11 +699,8 @@ int hycapi_init() ...@@ -698,11 +699,8 @@ int hycapi_init()
} }
driver = &hycapi_driver; driver = &hycapi_driver;
printk(KERN_NOTICE "HYSDN: Attaching capi-driver\n"); printk(KERN_NOTICE "HYSDN: Attaching capi-driver\n");
hy_di = attach_capi_driver(driver); attach_capi_driver(driver);
if (!hy_di) {
printk(KERN_ERR "HYCAPI: failed to attach capi_driver\n");
return(-1);
}
for(i=0;i<CAPI_MAXAPPL;i++) { for(i=0;i<CAPI_MAXAPPL;i++) {
memset(&(hycapi_applications[i]), 0, sizeof(hycapi_appl)); memset(&(hycapi_applications[i]), 0, sizeof(hycapi_appl));
} }
...@@ -798,8 +796,8 @@ hycapi_capi_create(hysdn_card *card) ...@@ -798,8 +796,8 @@ hycapi_capi_create(hysdn_card *card)
default: strcpy(cinfo->cardname,"HYSDN ???"); break; default: strcpy(cinfo->cardname,"HYSDN ???"); break;
} }
cinfo->capi_ctrl = hy_di->attach_ctr(&hycapi_driver, cinfo->capi_ctrl = attach_capi_ctr(&hycapi_driver,
cinfo->cardname, cinfo); cinfo->cardname, cinfo);
ctrl = cinfo->capi_ctrl; ctrl = cinfo->capi_ctrl;
if (!ctrl) { if (!ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", printk(KERN_ERR "%s: attach controller failed.\n",
......
/* $Id: capidev.h,v 1.6.6.2 2001/09/23 22:24:33 kai Exp $
*
* CAPI 2.0 Interface for Linux
*
* Copyright 1996 by Carsten Paeth <calle@calle.de>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
struct capidev {
struct capidev *next;
struct file *file;
__u16 applid;
__u16 errcode;
unsigned int minor;
struct sk_buff_head recv_queue;
wait_queue_head_t recv_wait;
/* Statistic */
unsigned long nrecvctlpkt;
unsigned long nrecvdatapkt;
unsigned long nsentctlpkt;
unsigned long nsentdatapkt;
};
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#ifndef __CAPILLI_H__ #ifndef __CAPILLI_H__
#define __CAPILLI_H__ #define __CAPILLI_H__
#include <linux/list.h>
typedef struct capiloaddatapart { typedef struct capiloaddatapart {
int user; /* data in userspace ? */ int user; /* data in userspace ? */
int len; int len;
...@@ -34,7 +36,7 @@ typedef struct capicardparams { ...@@ -34,7 +36,7 @@ typedef struct capicardparams {
struct capi_driver; struct capi_driver;
struct capi_ctr { struct capi_ctr {
struct capi_ctr *next; /* next ctr of same driver */ struct list_head driver_list; /* contrs by driver */
struct capi_driver *driver; struct capi_driver *driver;
int cnr; /* controller number */ int cnr; /* controller number */
char name[32]; /* name of controller */ char name[32]; /* name of controller */
...@@ -57,8 +59,6 @@ struct capi_ctr { ...@@ -57,8 +59,6 @@ struct capi_ctr {
void (*resume_output)(struct capi_ctr * card); void (*resume_output)(struct capi_ctr * card);
void (*handle_capimsg)(struct capi_ctr * card, void (*handle_capimsg)(struct capi_ctr * card,
__u16 appl, struct sk_buff *skb); __u16 appl, struct sk_buff *skb);
void (*appl_registered)(struct capi_ctr * card, __u16 appl);
void (*appl_released)(struct capi_ctr * card, __u16 appl);
void (*new_ncci)(struct capi_ctr * card, void (*new_ncci)(struct capi_ctr * card,
__u16 appl, __u32 ncci, __u32 winsize); __u16 appl, __u32 ncci, __u32 winsize);
...@@ -75,39 +75,38 @@ struct capi_ctr { ...@@ -75,39 +75,38 @@ struct capi_ctr {
char procfn[128]; char procfn[128];
}; };
struct capi_driver_interface {
struct capi_ctr *(*attach_ctr)(struct capi_driver *driver, char *name, void *data);
int (*detach_ctr)(struct capi_ctr *);
};
struct capi_driver { struct capi_driver {
char name[32]; /* driver name */ struct module *owner;
char revision[32]; char name[32]; /* driver name */
int (*load_firmware)(struct capi_ctr *, capiloaddata *); char revision[32];
void (*reset_ctr)(struct capi_ctr *); int (*load_firmware)(struct capi_ctr *, capiloaddata *);
void (*remove_ctr)(struct capi_ctr *); void (*reset_ctr)(struct capi_ctr *);
void (*register_appl)(struct capi_ctr *, __u16 appl, void (*remove_ctr)(struct capi_ctr *);
capi_register_params *); void (*register_appl)(struct capi_ctr *, __u16 appl,
void (*release_appl)(struct capi_ctr *, __u16 appl); capi_register_params *);
void (*send_message)(struct capi_ctr *, struct sk_buff *skb); void (*release_appl)(struct capi_ctr *, __u16 appl);
void (*send_message)(struct capi_ctr *, struct sk_buff *skb);
char *(*procinfo)(struct capi_ctr *);
int (*ctr_read_proc)(char *page, char **start, off_t off, char *(*procinfo)(struct capi_ctr *);
int count, int *eof, struct capi_ctr *card); int (*ctr_read_proc)(char *page, char **start, off_t off,
int (*driver_read_proc)(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *card);
int count, int *eof, struct capi_driver *driver); int (*driver_read_proc)(char *page, char **start, off_t off,
int count, int *eof, struct capi_driver *driver);
int (*add_card)(struct capi_driver *driver, capicardparams *data);
int (*add_card)(struct capi_driver *driver, capicardparams *data);
/* intitialized by kcapi */
struct capi_ctr *controller; /* list of controllers */ /* intitialized by kcapi */
struct capi_driver *next; struct list_head contr_head; /* list of controllers */
int ncontroller; struct list_head driver_list;
struct proc_dir_entry *procent; int ncontroller;
char procfn[128]; struct proc_dir_entry *procent;
char procfn[128];
}; };
struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver); void attach_capi_driver(struct capi_driver *driver);
void detach_capi_driver(struct capi_driver *driver); void detach_capi_driver(struct capi_driver *driver);
struct capi_ctr *attach_capi_ctr(struct capi_driver *driver, char *name, void *data);
int detach_capi_ctr(struct capi_ctr *);
#endif /* __CAPILLI_H__ */ #endif /* __CAPILLI_H__ */
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#ifndef __KERNELCAPI_H__ #ifndef __KERNELCAPI_H__
#define __KERNELCAPI_H__ #define __KERNELCAPI_H__
#include <linux/list.h>
#define CAPI_MAXAPPL 128 /* maximum number of applications */ #define CAPI_MAXAPPL 128 /* maximum number of applications */
#define CAPI_MAXCONTR 16 /* maximum number of controller */ #define CAPI_MAXCONTR 16 /* maximum number of controller */
#define CAPI_MAXDATAWINDOW 8 #define CAPI_MAXDATAWINDOW 8
...@@ -81,7 +83,7 @@ struct capi_interface_user { ...@@ -81,7 +83,7 @@ struct capi_interface_user {
char name[20]; char name[20];
void (*callback) (unsigned int cmd, __u32 contr, void *data); void (*callback) (unsigned int cmd, __u32 contr, void *data);
/* internal */ /* internal */
struct capi_interface_user *next; struct list_head user_list;
}; };
struct capi_interface *attach_capi_interface(struct capi_interface_user *); struct capi_interface *attach_capi_interface(struct capi_interface_user *);
......
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