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 $";
/* ------------------------------------------------------------- */
#define CARD_FREE 0
#define CARD_DETECTED 1
#define CARD_LOADING 2
#define CARD_RUNNING 3
......@@ -72,7 +71,6 @@ struct capi_ncci {
struct capi_appl {
u16 applid;
capi_register_params rparam;
int releasing;
void *param;
void (*signal) (u16 applid, void *param);
struct sk_buff_head recv_queue;
......@@ -107,32 +105,58 @@ static char capi_manufakturer[64] = "AVM Berlin";
#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 int ncards = 0;
static struct capi_ctr *cards[CAPI_MAXCONTR];
static int ncards;
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 struct capi_driver *drivers;
static LIST_HEAD(users);
static spinlock_t users_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(drivers);
static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
static struct tq_struct tq_state_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 ------------------------------------ */
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 "???";
}
}
......@@ -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,
int count, int *eof, void *data)
{
struct list_head *l;
struct capi_driver *driver;
int len = 0;
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",
driver->name,
driver->ncontroller,
......@@ -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,
int count, int *eof, void *data)
{
struct list_head *l;
struct capi_interface_user *cp;
int len = 0;
spin_lock(&capi_users_lock);
for (cp = capi_users; cp ; cp = cp->next) {
spin_lock(&users_lock);
list_for_each(l, &users) {
cp = list_entry(l, struct capi_interface_user, user_list);
len += sprintf(page+len, "%s\n", cp->name);
if (len <= off) {
off -= len;
......@@ -305,7 +334,7 @@ static int proc_users_read_proc(char *page, char **start, off_t off,
}
}
endloop:
spin_unlock(&capi_users_lock);
spin_unlock(&users_lock);
*start = page+off;
if (len < count)
*eof = 1;
......@@ -326,8 +355,10 @@ static int proc_controller_read_proc(char *page, char **start, off_t off,
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),
......@@ -400,8 +431,9 @@ static int proc_contrstats_read_proc(char *page, char **start, off_t off,
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,
......@@ -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 --------------------------------- */
static struct capi_notifier_list{
......@@ -543,63 +608,75 @@ static int notify_push(unsigned int cmd, u32 controller,
static void notify_up(u32 contr)
{
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(&capi_users_lock);
for (p = capi_users; p; p = p->next) {
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(&capi_users_lock);
spin_unlock(&users_lock);
}
/* -------- KCI_CONTRDOWN ------------------------------------- */
static void notify_down(u32 contr)
{
struct list_head *l;
struct capi_interface_user *p;
printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);
spin_lock(&capi_users_lock);
for (p = capi_users; p; p = p->next) {
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_CONTRDOWN, contr, 0);
}
spin_unlock(&capi_users_lock);
spin_unlock(&users_lock);
}
/* -------- KCI_NCCIUP ---------------------------------------- */
static void notify_ncciup(u32 contr, u16 applid, u32 ncci)
{
struct list_head *l;
struct capi_interface_user *p;
struct capi_ncciinfo n;
n.applid = applid;
n.ncci = ncci;
/*printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);*/
spin_lock(&capi_users_lock);
for (p = capi_users; p; p = p->next) {
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_NCCIUP, contr, &n);
}
spin_unlock(&capi_users_lock);
spin_unlock(&users_lock);
};
/* -------- KCI_NCCIDOWN -------------------------------------- */
static void notify_nccidown(u32 contr, u16 applid, u32 ncci)
{
struct list_head *l;
struct capi_interface_user *p;
struct capi_ncciinfo n;
n.applid = applid;
n.ncci = ncci;
/*printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);*/
spin_lock(&capi_users_lock);
for (p = capi_users; p; p = p->next) {
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_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)
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
*/
......@@ -741,7 +792,7 @@ static void controllercb_new_ncci(struct capi_ctr * card,
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,
......@@ -759,7 +810,7 @@ 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;
}
}
......@@ -868,22 +919,19 @@ static void controllercb_ready(struct capi_ctr * card)
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
if (!VALID_APPLID(appl)) continue;
if (APPL(appl)->releasing) continue;
card->driver->register_appl(card, appl, &APPL(appl)->rparam);
register_appl(card, appl, &APPL(appl)->rparam);
}
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;
......@@ -901,24 +949,25 @@ static void controllercb_reseted(struct capi_ctr * card)
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 {
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)
{
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;
}
}
......@@ -926,7 +975,7 @@ static void controllercb_suspend_output(struct capi_ctr *card)
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;
}
}
......@@ -935,21 +984,27 @@ static void controllercb_resume_output(struct capi_ctr *card)
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;
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;
......@@ -961,14 +1016,10 @@ drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata)
card->suspend_output = controllercb_suspend_output;
card->resume_output = controllercb_resume_output;
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->free_ncci = controllercb_free_ncci;
for (pp = &driver->controller; *pp; pp = &(*pp)->next) ;
card->next = 0;
*pp = card;
list_add_tail(&card->driver_list, &driver->contr_head);
driver->ncontroller++;
sprintf(card->procfn, "capi/controllers/%d", card->cnr);
card->procent = create_proc_entry(card->procfn, 0, 0);
......@@ -985,33 +1036,33 @@ drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata)
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_ctr **pp;
if (card->cardstate == CARD_FREE)
return 0;
if (card->cardstate != CARD_DETECTED)
controllercb_reseted(card);
for (pp = &driver->controller; *pp ; pp = &(*pp)->next) {
if (*pp == card) {
*pp = card->next;
driver->ncontroller--;
ncards--;
break;
}
}
list_del(&card->driver_list);
driver->ncontroller--;
ncards--;
if (card->procent) {
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;
}
EXPORT_SYMBOL(detach_capi_ctr);
/* ------------------------------------------------------------- */
/* 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,
/* ------------------------------------------------------------- */
static struct capi_driver_interface di = {
drivercb_attach_ctr,
drivercb_detach_ctr,
};
struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
void 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);
for (pp = &drivers; *pp; pp = &(*pp)->next) ;
driver->next = 0;
*pp = driver;
list_add_tail(&driver->driver_list, &drivers);
spin_unlock(&drivers_lock);
printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name);
sprintf(driver->procfn, "capi/drivers/%s", driver->name);
driver->procent = create_proc_entry(driver->procfn, 0, 0);
......@@ -1062,28 +1106,25 @@ struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
}
driver->procent->data = driver;
}
return &di;
}
EXPORT_SYMBOL(attach_capi_driver);
void detach_capi_driver(struct capi_driver *driver)
{
struct capi_driver **pp;
spin_lock(&drivers_lock);
for (pp = &drivers; *pp && *pp != driver; pp = &(*pp)->next) ;
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);
}
list_del(&driver->driver_list);
spin_unlock(&drivers_lock);
printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name);
if (driver->procent) {
remove_proc_entry(driver->procfn, 0);
driver->procent = 0;
}
MOD_DEC_USE_COUNT;
}
EXPORT_SYMBOL(detach_capi_driver);
/* ------------------------------------------------------------- */
/* -------- CAPI2.0 Interface ---------------------------------- */
/* ------------------------------------------------------------- */
......@@ -1092,7 +1133,7 @@ static u16 capi_isinstalled(void)
{
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;
......@@ -1120,10 +1161,9 @@ static u16 capi_register(capi_register_params * rparam, u16 * applidp)
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;
cards[i].driver->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);
......@@ -1135,29 +1175,25 @@ static u16 capi_release(u16 applid)
{
int i;
if (!VALID_APPLID(applid) || APPL(applid)->releasing)
if (!VALID_APPLID(applid))
return CAPI_ILLAPPNR;
APPL(applid)->releasing++;
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;
APPL(applid)->releasing++;
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);
release_appl(cards[i], applid);
}
APPL(applid)->signal = 0;
APPL_MARK_FREE(applid);
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_ncci *np;
u32 contr;
int showctl = 0;
u8 cmd, subcmd;
......@@ -1169,13 +1205,13 @@ static u16 capi_put_message(u16 applid, struct sk_buff *skb)
|| !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);
......@@ -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
&& 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;
}
......@@ -1237,64 +1273,81 @@ static u16 capi_set_signal(u16 applid,
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;
}
static struct capi_driver *find_driver(char *name)
{
struct list_head *l;
struct capi_driver *dp;
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)
break;
goto found;
}
dp = NULL;
found:
spin_unlock(&drivers_lock);
return dp;
}
......@@ -1365,11 +1418,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
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);
......@@ -1419,12 +1469,10 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
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;
......@@ -1445,12 +1493,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
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;
......@@ -1469,11 +1513,8 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
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)
......@@ -1481,7 +1522,7 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
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 */
......@@ -1519,11 +1560,10 @@ static int capi_manufacturer(unsigned int cmd, void *data)
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);
......@@ -1591,56 +1631,31 @@ struct capi_interface avmb1_interface =
struct capi_interface *attach_capi_interface(struct capi_interface_user *userp)
{
struct capi_interface_user *p;
MOD_INC_USE_COUNT;
spin_lock(&capi_users_lock);
for (p = capi_users; p; p = p->next) {
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);
spin_lock(&users_lock);
list_add_tail(&userp->user_list, &users);
spin_unlock(&users_lock);
printk(KERN_NOTICE "kcapi: %s attached\n", userp->name);
return &avmb1_interface;
}
EXPORT_SYMBOL(attach_capi_interface);
int detach_capi_interface(struct capi_interface_user *userp)
{
struct capi_interface_user **pp;
spin_lock(&capi_users_lock);
for (pp = &capi_users; *pp; pp = &(*pp)->next) {
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;
spin_lock(&users_lock);
list_del(&userp->user_list);
printk(KERN_NOTICE "kcapi: %s detached\n", userp->name);
return 0;
}
EXPORT_SYMBOL(detach_capi_interface);
/* ------------------------------------------------------------- */
/* -------- 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
*/
......
......@@ -357,8 +357,6 @@ void b1_register_appl(struct capi_ctr *ctrl,
b1_put_word(port, rp->datablkcnt);
b1_put_word(port, rp->datablklen);
restore_flags(flags);
ctrl->appl_registered(ctrl, 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)
if (NCCI != 0xffffffff)
ctrl->free_ncci(ctrl, ApplId, NCCI);
else ctrl->appl_released(ctrl, ApplId);
break;
case RECEIVE_START:
......
......@@ -509,7 +509,7 @@ static void b1dma_handle_rx(avmcard *card)
if (NCCI != 0xffffffff)
ctrl->free_ncci(ctrl, ApplId, NCCI);
else ctrl->appl_released(ctrl, ApplId);
break;
case RECEIVE_START:
......@@ -774,8 +774,6 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
skb_put(skb, (u8 *)p - (u8 *)skb->data);
b1dma_queue_tx(card, skb);
ctrl->appl_registered(ctrl, appl);
}
/* ------------------------------------------------------------- */
......
......@@ -34,10 +34,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static void b1isa_remove_ctr(struct capi_ctr *ctrl)
{
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
......@@ -47,7 +43,7 @@ static void b1isa_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port);
b1_reset(port);
di->detach_ctr(ctrl);
detach_capi_ctr(ctrl);
free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card);
......@@ -111,7 +107,7 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
b1_reset(card->port);
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) {
printk(KERN_ERR "b1isa: attach controller failed.\n");
retval = -EBUSY;
......@@ -154,27 +150,27 @@ static char *b1isa_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */
static struct capi_driver b1isa_driver = {
name: "b1isa",
revision: "0.0",
load_firmware: b1_load_firmware,
reset_ctr: b1_reset_ctr,
remove_ctr: b1isa_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1isa_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: b1isa_add_card,
owner: THIS_MODULE,
name: "b1isa",
revision: "0.0",
load_firmware: b1_load_firmware,
reset_ctr: b1_reset_ctr,
remove_ctr: b1isa_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1isa_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: b1isa_add_card,
};
static int __init b1isa_init(void)
{
struct capi_driver *driver = &b1isa_driver;
char *p;
int retval = 0;
MOD_INC_USE_COUNT;
......@@ -187,15 +183,9 @@ static int __init b1isa_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
retval = -EIO;
}
attach_capi_driver(driver);
MOD_DEC_USE_COUNT;
return retval;
return 0;
}
static void __exit b1isa_exit(void)
......
......@@ -42,10 +42,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static char *b1pci_procinfo(struct capi_ctr *ctrl)
{
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
......@@ -113,7 +109,7 @@ static int b1pci_add_card(struct capi_driver *driver,
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) {
printk(KERN_ERR "%s: attach controller failed.\n",
driver->name);
......@@ -153,7 +149,7 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port);
b1_reset(port);
di->detach_ctr(ctrl);
detach_capi_ctr(ctrl);
free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN);
ctrl->driverdata = 0;
......@@ -165,29 +161,26 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */
static struct capi_driver b1pci_driver = {
name: "b1pci",
revision: "0.0",
load_firmware: b1_load_firmware,
reset_ctr: b1_reset_ctr,
remove_ctr: b1pci_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1pci_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
owner: THIS_MODULE,
name: "b1pci",
revision: "0.0",
load_firmware: b1_load_firmware,
reset_ctr: b1_reset_ctr,
remove_ctr: b1pci_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1pci_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
};
#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
/* ------------------------------------------------------------- */
static struct capi_driver_interface *div4;
/* ------------------------------------------------------------- */
static char *b1pciv4_procinfo(struct capi_ctr *ctrl)
{
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
......@@ -274,7 +267,7 @@ static int b1pciv4_add_card(struct capi_driver *driver,
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) {
printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
retval = -EBUSY;
......@@ -312,7 +305,7 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl)
b1dma_reset(card);
div4->detach_ctr(ctrl);
detach_capi_ctr(ctrl);
free_irq(card->irq, card);
iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN);
......@@ -327,20 +320,21 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl)
static struct capi_driver b1pciv4_driver = {
name: "b1pciv4",
revision: "0.0",
load_firmware: b1dma_load_firmware,
reset_ctr: b1dma_reset_ctr,
remove_ctr: b1pciv4_remove_ctr,
register_appl: b1dma_register_appl,
release_appl: b1dma_release_appl,
send_message: b1dma_send_message,
procinfo: b1pciv4_procinfo,
ctr_read_proc: b1dmactl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
owner: THIS_MODULE,
name: "b1pciv4",
revision: "0.0",
load_firmware: b1dma_load_firmware,
reset_ctr: b1dma_reset_ctr,
remove_ctr: b1pciv4_remove_ctr,
register_appl: b1dma_register_appl,
release_appl: b1dma_release_appl,
send_message: b1dma_send_message,
procinfo: b1pciv4_procinfo,
ctr_read_proc: b1dmactl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
};
#endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
......@@ -432,25 +426,12 @@ static int __init b1pci_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
MOD_DEC_USE_COUNT;
return -ENODEV;
}
attach_capi_driver(driver);
#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
printk(KERN_INFO "%s: revision %s\n", driverv4->name, driverv4->revision);
div4 = 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;
}
attach_capi_driver(driverv4);
#endif
ncards = pci_register_driver(&b1pci_pci_driver);
......
......@@ -35,10 +35,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
{
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
......@@ -48,7 +44,7 @@ static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port);
b1_reset(port);
di->detach_ctr(ctrl);
detach_capi_ctr(ctrl);
free_irq(card->irq, card);
b1_free_card(card);
......@@ -103,7 +99,7 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
b1_reset(card->port);
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) {
printk(KERN_ERR "%s: attach controller failed.\n",
driver->name);
......@@ -152,20 +148,21 @@ static char *b1pcmcia_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */
static struct capi_driver b1pcmcia_driver = {
name: "b1pcmcia",
revision: "0.0",
load_firmware: b1_load_firmware,
reset_ctr: b1_reset_ctr,
remove_ctr: b1pcmcia_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1pcmcia_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0,
owner: THIS_MODULE,
name: "b1pcmcia",
revision: "0.0",
load_firmware: b1_load_firmware,
reset_ctr: b1_reset_ctr,
remove_ctr: b1pcmcia_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: b1_send_message,
procinfo: b1pcmcia_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0,
};
/* ------------------------------------------------------------- */
......@@ -187,10 +184,12 @@ int b1pcmcia_addcard_m2(unsigned int port, unsigned irq)
int b1pcmcia_delcard(unsigned int port, unsigned irq)
{
struct list_head *l;
struct capi_ctr *ctrl;
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;
if (card->port == port && card->irq == irq) {
b1pcmcia_remove_ctr(ctrl);
......@@ -224,13 +223,8 @@ static int __init b1pcmcia_init(void)
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;
return retval;
}
......
......@@ -52,10 +52,6 @@ MODULE_PARM(suppress_pollack, "0-1i");
/* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static void c4_dispatch_tx(avmcard *card);
/* ------------------------------------------------------------- */
......@@ -587,12 +583,6 @@ static void c4_handle_rx(avmcard *card)
ctrl = card->ctrlinfo[cidx].capi_ctrl;
if (ctrl)
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;
......@@ -918,7 +908,7 @@ static void c4_remove_ctr(struct capi_ctr *ctrl)
for (i=0; i < 4; i++) {
cinfo = &card->ctrlinfo[i];
if (cinfo->capi_ctrl) {
di->detach_ctr(cinfo->capi_ctrl);
detach_capi_ctr(cinfo->capi_ctrl);
cinfo->capi_ctrl = NULL;
}
}
......@@ -973,8 +963,6 @@ void c4_register_appl(struct capi_ctr *ctrl,
skb_queue_tail(&card->dma->send_queue, skb);
c4_dispatch_tx(card);
}
ctrl->appl_registered(ctrl, appl);
}
/* ------------------------------------------------------------- */
......@@ -1170,13 +1158,13 @@ static int c4_add_card(struct capi_driver *driver,
for (i=0; i < nr_controllers ; 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) {
printk(KERN_ERR "%s: attach controller failed (%d).\n",
driver->name, i);
for (i--; i >= 0; i--) {
cinfo = &card->ctrlinfo[i];
di->detach_ctr(cinfo->capi_ctrl);
detach_capi_ctr(cinfo->capi_ctrl);
}
goto err_free_irq;
}
......@@ -1208,37 +1196,39 @@ static int c4_add_card(struct capi_driver *driver,
/* ------------------------------------------------------------- */
static struct capi_driver c2_driver = {
name: "c2",
revision: "0.0",
load_firmware: c4_load_firmware,
reset_ctr: c4_reset_ctr,
remove_ctr: c4_remove_ctr,
register_appl: c4_register_appl,
release_appl: c4_release_appl,
send_message: c4_send_message,
procinfo: c4_procinfo,
ctr_read_proc: c4_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
owner: THIS_MODULE,
name: "c2",
revision: "0.0",
load_firmware: c4_load_firmware,
reset_ctr: c4_reset_ctr,
remove_ctr: c4_remove_ctr,
register_appl: c4_register_appl,
release_appl: c4_release_appl,
send_message: c4_send_message,
procinfo: c4_procinfo,
ctr_read_proc: c4_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
};
static struct capi_driver c4_driver = {
name: "c4",
revision: "0.0",
load_firmware: c4_load_firmware,
reset_ctr: c4_reset_ctr,
remove_ctr: c4_remove_ctr,
register_appl: c4_register_appl,
release_appl: c4_release_appl,
send_message: c4_send_message,
procinfo: c4_procinfo,
ctr_read_proc: c4_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
owner: THIS_MODULE,
name: "c4",
revision: "0.0",
load_firmware: c4_load_firmware,
reset_ctr: c4_reset_ctr,
remove_ctr: c4_remove_ctr,
register_appl: c4_register_appl,
release_appl: c4_release_appl,
send_message: c4_send_message,
procinfo: c4_procinfo,
ctr_read_proc: c4_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
};
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);
di = attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
MOD_DEC_USE_COUNT;
return -ENODEV;
}
attach_capi_driver(driver);
return 0;
}
......
......@@ -35,10 +35,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static int hema_irq_table[16] =
{0,
0,
......@@ -199,7 +195,7 @@ static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
if (NCCI != 0xffffffff)
ctrl->free_ncci(ctrl, ApplId, NCCI);
else ctrl->appl_released(ctrl, ApplId);
break;
case RECEIVE_START:
......@@ -331,7 +327,7 @@ static void t1isa_remove_ctr(struct capi_ctr *ctrl)
b1_reset(port);
t1_reset(port);
di->detach_ctr(ctrl);
detach_capi_ctr(ctrl);
free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card);
......@@ -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)
{
struct capi_ctr *ctrl;
struct list_head *l;
avmctrl_info *cinfo;
avmcard *card;
int retval;
......@@ -376,8 +373,11 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
retval = -EINVAL;
goto err_free;
}
for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) {
avmcard *cardp = ((avmctrl_info *)(ctrl->driverdata))->card;
list_for_each(l, &driver->contr_head) {
avmcard *cardp;
ctrl = list_entry(l, struct capi_ctr, driver_list);
cardp = ((avmctrl_info *)(ctrl->driverdata))->card;
if (cardp->cardnr == card->cardnr) {
printk(KERN_WARNING "%s: card with number %d already installed at 0x%x.\n",
driver->name, card->cardnr, cardp->port);
......@@ -408,7 +408,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
t1_disable_irq(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) {
printk(KERN_ERR "%s: attach controller failed.\n",
driver->name);
......@@ -479,20 +479,21 @@ static char *t1isa_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */
static struct capi_driver t1isa_driver = {
name: "t1isa",
revision: "0.0",
load_firmware: t1isa_load_firmware,
reset_ctr: t1isa_reset_ctr,
remove_ctr: t1isa_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: t1isa_send_message,
procinfo: t1isa_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: t1isa_add_card,
owner: THIS_MODULE,
name: "t1isa",
revision: "0.0",
load_firmware: t1isa_load_firmware,
reset_ctr: t1isa_reset_ctr,
remove_ctr: t1isa_remove_ctr,
register_appl: b1_register_appl,
release_appl: b1_release_appl,
send_message: t1isa_send_message,
procinfo: t1isa_procinfo,
ctr_read_proc: b1ctl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: t1isa_add_card,
};
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);
di = attach_capi_driver(driver);
if (!di) {
printk(KERN_ERR "%s: failed to attach capi_driver\n",
driver->name);
retval = -EIO;
}
attach_capi_driver(driver);
MOD_DEC_USE_COUNT;
return retval;
......
......@@ -45,10 +45,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */
static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */
static int t1pci_add_card(struct capi_driver *driver,
struct capicardparams *p,
struct pci_dev *dev)
......@@ -119,7 +115,7 @@ static int t1pci_add_card(struct capi_driver *driver,
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) {
printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
retval = -EBUSY;
......@@ -157,7 +153,7 @@ static void t1pci_remove_ctr(struct capi_ctr *ctrl)
b1dma_reset(card);
di->detach_ctr(ctrl);
detach_capi_ctr(ctrl);
free_irq(card->irq, card);
iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN);
......@@ -189,20 +185,21 @@ static char *t1pci_procinfo(struct capi_ctr *ctrl)
/* ------------------------------------------------------------- */
static struct capi_driver t1pci_driver = {
name: "t1pci",
revision: "0.0",
load_firmware: b1dma_load_firmware,
reset_ctr: b1dma_reset_ctr,
remove_ctr: t1pci_remove_ctr,
register_appl: b1dma_register_appl,
release_appl: b1dma_release_appl,
send_message: b1dma_send_message,
procinfo: t1pci_procinfo,
ctr_read_proc: b1dmactl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
owner: THIS_MODULE,
name: "t1pci",
revision: "0.0",
load_firmware: b1dma_load_firmware,
reset_ctr: b1dma_reset_ctr,
remove_ctr: t1pci_remove_ctr,
register_appl: b1dma_register_appl,
release_appl: b1dma_release_appl,
send_message: b1dma_send_message,
procinfo: t1pci_procinfo,
ctr_read_proc: b1dmactl_read_proc,
driver_read_proc: 0, /* use standard driver_read_proc */
add_card: 0, /* no add_card function */
};
/* ------------------------------------------------------------- */
......@@ -261,13 +258,7 @@ static int __init t1pci_init(void)
printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
di = 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;
}
attach_capi_driver(&t1pci_driver);
ncards = pci_register_driver(&t1pci_pci_driver);
if (ncards) {
......
......@@ -98,7 +98,7 @@ hycapi_remove_ctr(struct capi_ctr *ctrl)
hycapi_applications[i].listen_req[ctrl->cnr-1] = NULL;
}
}
hy_di->detach_ctr(ctrl);
detach_capi_ctr(ctrl);
ctrl->driverdata = 0;
kfree(card->hyctrlinfo);
......@@ -252,7 +252,6 @@ hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
rp, sizeof(capi_register_params));
/* MOD_INC_USE_COUNT; */
ctrl->appl_registered(ctrl, appl);
}
/*********************************************************************
......@@ -313,7 +312,6 @@ hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
{
hycapi_release_internal(ctrl, appl);
}
ctrl->appl_released(ctrl, appl);
/* MOD_DEC_USE_COUNT; */
}
......@@ -666,18 +664,21 @@ hycapi_tx_capiget(hysdn_card *card)
static struct capi_driver hycapi_driver = {
"hysdn",
"0.0",
hycapi_load_firmware,
hycapi_reset_ctr,
hycapi_remove_ctr,
hycapi_register_appl,
hycapi_release_appl,
hycapi_send_message,
hycapi_procinfo,
hycapi_read_proc,
0, /* use standard driver_read_proc */
0, /* no add_card function */
owner: THIS_MODULE,
name: "hysdn",
revision: "0.0",
load_firmware: hycapi_load_firmware,
reset_ctr: hycapi_reset_ctr,
remove_ctr: hycapi_remove_ctr,
register_appl: hycapi_register_appl,
release_appl: hycapi_release_appl,
send_message: hycapi_send_message,
procinfo: hycapi_procinfo,
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()
}
driver = &hycapi_driver;
printk(KERN_NOTICE "HYSDN: Attaching capi-driver\n");
hy_di = attach_capi_driver(driver);
if (!hy_di) {
printk(KERN_ERR "HYCAPI: failed to attach capi_driver\n");
return(-1);
}
attach_capi_driver(driver);
for(i=0;i<CAPI_MAXAPPL;i++) {
memset(&(hycapi_applications[i]), 0, sizeof(hycapi_appl));
}
......@@ -798,8 +796,8 @@ hycapi_capi_create(hysdn_card *card)
default: strcpy(cinfo->cardname,"HYSDN ???"); break;
}
cinfo->capi_ctrl = hy_di->attach_ctr(&hycapi_driver,
cinfo->cardname, cinfo);
cinfo->capi_ctrl = attach_capi_ctr(&hycapi_driver,
cinfo->cardname, cinfo);
ctrl = cinfo->capi_ctrl;
if (!ctrl) {
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 @@
#ifndef __CAPILLI_H__
#define __CAPILLI_H__
#include <linux/list.h>
typedef struct capiloaddatapart {
int user; /* data in userspace ? */
int len;
......@@ -34,7 +36,7 @@ typedef struct capicardparams {
struct capi_driver;
struct capi_ctr {
struct capi_ctr *next; /* next ctr of same driver */
struct list_head driver_list; /* contrs by driver */
struct capi_driver *driver;
int cnr; /* controller number */
char name[32]; /* name of controller */
......@@ -57,8 +59,6 @@ struct capi_ctr {
void (*resume_output)(struct capi_ctr * card);
void (*handle_capimsg)(struct capi_ctr * card,
__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,
__u16 appl, __u32 ncci, __u32 winsize);
......@@ -75,39 +75,38 @@ struct capi_ctr {
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 {
char name[32]; /* driver name */
char revision[32];
int (*load_firmware)(struct capi_ctr *, capiloaddata *);
void (*reset_ctr)(struct capi_ctr *);
void (*remove_ctr)(struct capi_ctr *);
void (*register_appl)(struct capi_ctr *, __u16 appl,
capi_register_params *);
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,
int count, int *eof, struct capi_ctr *card);
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);
/* intitialized by kcapi */
struct capi_ctr *controller; /* list of controllers */
struct capi_driver *next;
int ncontroller;
struct proc_dir_entry *procent;
char procfn[128];
struct module *owner;
char name[32]; /* driver name */
char revision[32];
int (*load_firmware)(struct capi_ctr *, capiloaddata *);
void (*reset_ctr)(struct capi_ctr *);
void (*remove_ctr)(struct capi_ctr *);
void (*register_appl)(struct capi_ctr *, __u16 appl,
capi_register_params *);
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,
int count, int *eof, struct capi_ctr *card);
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);
/* intitialized by kcapi */
struct list_head contr_head; /* list of controllers */
struct list_head driver_list;
int ncontroller;
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);
struct capi_ctr *attach_capi_ctr(struct capi_driver *driver, char *name, void *data);
int detach_capi_ctr(struct capi_ctr *);
#endif /* __CAPILLI_H__ */
......@@ -10,6 +10,8 @@
#ifndef __KERNELCAPI_H__
#define __KERNELCAPI_H__
#include <linux/list.h>
#define CAPI_MAXAPPL 128 /* maximum number of applications */
#define CAPI_MAXCONTR 16 /* maximum number of controller */
#define CAPI_MAXDATAWINDOW 8
......@@ -81,7 +83,7 @@ struct capi_interface_user {
char name[20];
void (*callback) (unsigned int cmd, __u32 contr, void *data);
/* internal */
struct capi_interface_user *next;
struct list_head user_list;
};
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