patch-2.3.4 linux/drivers/isdn/avmb1/b1capi.c
Next file: linux/drivers/isdn/avmb1/b1lli.c
Previous file: linux/drivers/isdn/act2000/module.c
Back to the patch index
Back to the overall index
- Lines: 385
- Date:
Sun May 23 10:03:41 1999
- Orig file:
v2.3.3/linux/drivers/isdn/avmb1/b1capi.c
- Orig date:
Thu Nov 5 09:58:43 1998
diff -u --recursive --new-file v2.3.3/linux/drivers/isdn/avmb1/b1capi.c linux/drivers/isdn/avmb1/b1capi.c
@@ -1,11 +1,49 @@
/*
- * $Id: b1capi.c,v 1.10 1998/02/13 07:09:10 calle Exp $
+ * $Id: b1capi.c,v 1.14 1999/04/15 19:49:29 calle Exp $
*
* CAPI 2.0 Module for AVM B1-card.
*
* (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
*
* $Log: b1capi.c,v $
+ * Revision 1.14 1999/04/15 19:49:29 calle
+ * fix fuer die B1-PCI. Jetzt geht z.B. auch IRQ 17 ...
+ *
+ * Revision 1.13 1999/01/05 18:29:31 he
+ * merged remaining schedule_timeout() changes from 2.1.127
+ *
+ * Revision 1.12 1998/10/25 14:38:58 fritz
+ * Backported from MIPS (Cobalt).
+ *
+ * Revision 1.11 1998/03/29 16:05:58 calle
+ * changes from 2.0 tree merged.
+ *
+ * Revision 1.4.2.18 1998/03/20 20:34:37 calle
+ * port valid check now only for T1, because of the PCI and PCMCIA cards.
+ *
+ * Revision 1.4.2.17 1998/03/20 14:38:17 calle
+ * capidrv: prepared state machines for suspend/resume/hold
+ * capidrv: fix bug in state machine if B1/T1 is out of nccis
+ * b1capi: changed some errno returns.
+ * b1capi: detect if you try to add same T1 to different io address.
+ * b1capi: change number of nccis depending on number of channels.
+ * b1lli: cosmetics
+ *
+ * Revision 1.4.2.16 1998/03/20 09:01:08 calle
+ * Changes capi_register handling to get full support for 30 bchannels.
+ *
+ * Revision 1.4.2.15 1998/03/18 17:43:26 calle
+ * T1 with fastlink, bugfix for multicontroller support in capidrv.c
+ *
+ * Revision 1.4.2.14 1998/03/04 17:33:47 calle
+ * Changes for T1.
+ *
+ * Revision 1.4.2.13 1998/02/27 15:40:41 calle
+ * T1 running with slow link. bugfix in capi_release.
+ *
+ * Revision 1.4.2.12 1998/02/24 17:58:25 calle
+ * changes for T1.
+ *
* Revision 1.10 1998/02/13 07:09:10 calle
* change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
*
@@ -76,7 +114,7 @@
#include "capicmd.h"
#include "capiutil.h"
-static char *revision = "$Revision: 1.10 $";
+static char *revision = "$Revision: 1.14 $";
/* ------------------------------------------------------------- */
@@ -84,7 +122,7 @@
int loaddebug = 0;
MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
-MODULE_PARM(showcapimsgs, "0-3i");
+MODULE_PARM(showcapimsgs, "0-5i");
MODULE_PARM(loaddebug, "0-1i");
/* ------------------------------------------------------------- */
@@ -150,10 +188,11 @@
{
switch (cardtype) {
default:
- case AVM_CARDTYPE_B1: return "B1";
- case AVM_CARDTYPE_M1: return "M1";
- case AVM_CARDTYPE_M2: return "M2";
- case AVM_CARDTYPE_T1: return "T1";
+ case AVM_CARDTYPE_B1: return "B1-ISA";
+ case AVM_CARDTYPE_B1PCI: return "B1-PCI";
+ case AVM_CARDTYPE_M1: return "M1";
+ case AVM_CARDTYPE_M2: return "M2";
+ case AVM_CARDTYPE_T1: return "T1";
}
}
@@ -300,7 +339,7 @@
}
}
APPL(appl)->releasing--;
- if (APPL(appl)->releasing == 0) {
+ if (APPL(appl)->releasing <= 0) {
APPL(appl)->signal = 0;
APPL_MARK_FREE(appl);
printk(KERN_INFO "b1capi: appl %d down\n", appl);
@@ -433,6 +472,7 @@
/* -------- card ready callback ------------------------------- */
+
void avmb1_card_ready(avmb1_card * card)
{
struct capi_profile *profp =
@@ -441,6 +481,7 @@
__u16 appl;
char *cardname, cname[20];
__u32 flag;
+ int nbchan = profp->nbchannel;
card->cversion.majorversion = 2;
card->cversion.minorversion = 0;
@@ -453,9 +494,14 @@
for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
if (VALID_APPLID(appl) && !APPL(appl)->releasing) {
+ int nconn, want = APPL(appl)->rparam.level3cnt;
+
+ if (want > 0) nconn = want;
+ else nconn = nbchan * -want;
+ if (nconn == 0) nconn = nbchan;
+
B1_send_register(card->port, appl,
- 1024 * (APPL(appl)->rparam.level3cnt+1),
- APPL(appl)->rparam.level3cnt,
+ 1024 * (nconn+1), nconn,
APPL(appl)->rparam.datablkcnt,
APPL(appl)->rparam.datablklen);
}
@@ -553,8 +599,8 @@
SA_SHIRQ, card->name, card)) != 0) {
printk(KERN_ERR "b1capi: unable to get IRQ %d (irqval=%d).\n",
irq, irqval);
- release_region((unsigned short) port, AVMB1_PORTLEN);
- return -EIO;
+ release_region(port, AVMB1_PORTLEN);
+ return -EBUSY;
}
card->cardstate = CARD_DETECTED;
@@ -578,8 +624,14 @@
if (!B1_valid_irq(irq, cardtype)) {
printk(KERN_WARNING "b1capi: irq %d not valid for %s-card.\n",
irq, cardtype2str(cardtype));
- return -EIO;
+ return -EINVAL;
+ }
+ if (!B1_valid_port(port, cardtype)) {
+ printk(KERN_WARNING "b1capi: port 0x%x not valid for %s-card.\n",
+ port, cardtype2str(cardtype));
+ return -EINVAL;
}
+ B1_reset(port);
if ((rc = B1_detect(port, cardtype)) != 0) {
printk(KERN_NOTICE "b1capi: NO %s-card at 0x%x (%d)\n",
cardtype2str(cardtype), port, rc);
@@ -591,10 +643,10 @@
case AVM_CARDTYPE_M1:
case AVM_CARDTYPE_M2:
case AVM_CARDTYPE_B1:
+ case AVM_CARDTYPE_B1PCI:
printk(KERN_NOTICE "b1capi: AVM-%s-Controller detected at 0x%x\n", cardtype2str(cardtype), port);
break;
case AVM_CARDTYPE_T1:
- printk(KERN_NOTICE "b1capi: AVM-%s-Controller may be at 0x%x\n", cardtype2str(cardtype), port);
break;
}
@@ -603,11 +655,11 @@
int avmb1_probecard(int port, int irq, int cardtype)
{
- if (check_region((unsigned short) port, AVMB1_PORTLEN)) {
+ if (check_region(port, AVMB1_PORTLEN)) {
printk(KERN_WARNING
"b1capi: ports 0x%03x-0x%03x in use.\n",
port, port + AVMB1_PORTLEN);
- return -EIO;
+ return -EBUSY;
}
return avmb1_detectcard(port, irq, cardtype);
}
@@ -618,11 +670,16 @@
if (!VALID_CARD(cnr))
return -ESRCH;
card = CARD(cnr);
+
if (card->cardstate == CARD_FREE)
return -ESRCH;
if (card->cardstate == CARD_RUNNING)
avmb1_card_down(card, freeio);
+ if (card->cardstate != CARD_FREE)
+ if (card->cardtype == AVM_CARDTYPE_T1)
+ T1_reset(card->port);
+
free_irq(card->irq, card);
if (freeio)
release_region(card->port, AVMB1_PORTLEN);
@@ -667,6 +724,7 @@
static __u16 capi_register(capi_register_params * rparam, __u16 * applidp)
{
+ int nconn, want = rparam->level3cnt;
int i;
int appl;
@@ -686,13 +744,20 @@
memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params));
for (i = 0; i < CAPI_MAXCONTR; i++) {
+ struct capi_profile *profp =
+ (struct capi_profile *)cards[i].version[VER_PROFILE];
+
if (cards[i].cardstate != CARD_RUNNING)
continue;
+
+ if (want > 0) nconn = want;
+ else nconn = profp->nbchannel * -want;
+ if (nconn == 0) nconn = profp->nbchannel;
+
B1_send_register(cards[i].port, appl,
- 1024 * (APPL(appl)->rparam.level3cnt + 1),
- APPL(appl)->rparam.level3cnt,
- APPL(appl)->rparam.datablkcnt,
- APPL(appl)->rparam.datablklen);
+ 1024 * (nconn+1), nconn,
+ APPL(appl)->rparam.datablkcnt,
+ APPL(appl)->rparam.datablklen);
}
*applidp = appl;
printk(KERN_INFO "b1capi: appl %d up\n", appl);
@@ -705,8 +770,6 @@
struct sk_buff *skb;
int i;
- if (ncards == 0)
- return CAPI_REGNOTINSTALLED;
if (!VALID_APPLID(applid) || APPL(applid)->releasing)
return CAPI_ILLAPPNR;
while ((skb = skb_dequeue(&APPL(applid)->recv_queue)) != 0)
@@ -718,7 +781,7 @@
APPL(applid)->releasing++;
B1_send_release(cards[i].port, applid);
}
- if (APPL(applid)->releasing == 0) {
+ if (APPL(applid)->releasing <= 0) {
APPL(applid)->signal = 0;
APPL_MARK_FREE(applid);
printk(KERN_INFO "b1capi: appl %d down\n", applid);
@@ -863,7 +926,43 @@
if ((rc = avmb1_probecard(cdef.port, cdef.irq, cdef.cardtype)) != 0)
return rc;
- return avmb1_addcard(cdef.port, cdef.irq, cdef.cardtype);
+ if (cdef.cardtype == AVM_CARDTYPE_T1) {
+ int i;
+ for (i=0; i < CAPI_MAXCONTR; i++) {
+ if ( cards[i].cardstate != CARD_FREE
+ && cards[i].cardtype == AVM_CARDTYPE_T1
+ && cards[i].cardnr == cdef.cardnr) {
+ printk(KERN_ERR
+ "b1capi: T1-HEMA-card-%d already at 0x%x\n",
+ cdef.cardnr, cards[i].port);
+ return -EBUSY;
+ }
+ }
+ rc = T1_detectandinit(cdef.port,cdef.irq,cdef.cardnr);
+ if (rc) {
+ printk(KERN_NOTICE "b1capi: NO T1-HEMA-card-%d at 0x%x (%d)\n",
+ cdef.cardnr, cdef.port, rc);
+ return -EIO;
+ }
+ printk(KERN_NOTICE "b1capi: T1-HEMA-card-%d at 0x%x\n",
+ cdef.cardnr, cdef.port);
+ }
+
+ rc = avmb1_addcard(cdef.port, cdef.irq, cdef.cardtype);
+ if (rc < 0)
+ return rc;
+ /* don't want to change interface t
+ addcard/probecard/registercard */
+ if (cdef.cardtype == AVM_CARDTYPE_T1) {
+ int i;
+ for (i=0; i < CAPI_MAXCONTR; i++) {
+ if (cards[i].cnr == rc) {
+ cards[i].cardnr = cdef.cardnr;
+ break;
+ }
+ }
+ }
+ return rc;
case AVMB1_LOAD:
case AVMB1_LOAD_AND_CONFIG:
@@ -883,8 +982,7 @@
return -ESRCH;
if (ldef.t4file.len <= 0) {
- if (loaddebug)
- printk(KERN_DEBUG "b1capi: load: invalid parameter length of t4file is %d ?\n", ldef.t4file.len);
+ printk(KERN_DEBUG "b1capi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
return -EINVAL;
}
@@ -906,12 +1004,19 @@
}
B1_reset(card->port);
+
+ if (loaddebug) {
+ printk(KERN_DEBUG "b1capi: loading contr %d\n",
+ ldef.contr);
+ }
+
if ((rc = B1_load_t4file(card->port, &ldef.t4file))) {
B1_reset(card->port);
printk(KERN_ERR "b1capi: failed to load t4file!!\n");
card->cardstate = CARD_DETECTED;
return rc;
}
+
B1_disable_irq(card->port);
if (ldef.t4config.len > 0) { /* load config */
@@ -944,8 +1049,7 @@
card->cardstate = CARD_INITSTATE;
save_flags(flags);
cli();
- B1_assign_irq(card->port, card->irq, card->cardtype);
- B1_enable_irq(card->port);
+ B1_setinterrupt(card->port, card->irq, card->cardtype);
restore_flags(flags);
if (loaddebug) {
@@ -956,7 +1060,14 @@
/*
* init card
*/
- B1_send_init(card->port, AVM_NAPPS, AVM_NNCCI, card->cnr - 1);
+ if (card->cardtype == AVM_CARDTYPE_T1)
+ B1_send_init(card->port, AVM_NAPPS,
+ AVM_NNCCI_PER_CHANNEL*30,
+ card->cnr - 1);
+ else
+ B1_send_init(card->port, AVM_NAPPS,
+ AVM_NNCCI_PER_CHANNEL*2,
+ card->cnr - 1);
if (loaddebug) {
printk(KERN_DEBUG "b1capi: load: waiting for init reply contr %d\n",
@@ -998,6 +1109,19 @@
return rc;
return 0;
+ case AVMB1_REMOVECARD:
+ if ((rc = copy_from_user((void *) &rdef, data,
+ sizeof(avmb1_resetdef))))
+ return rc;
+ if (!VALID_CARD(rdef.contr))
+ return -ESRCH;
+
+ card = CARD(rdef.contr);
+
+ if (card->cardstate != CARD_DETECTED)
+ return -EBUSY;
+
+ return avmb1_unregistercard(rdef.contr, 1);
}
return -EINVAL;
}
@@ -1035,6 +1159,7 @@
userp->next = capi_users;
capi_users = userp;
MOD_INC_USE_COUNT;
+ printk(KERN_NOTICE "b1capi: %s attached\n", userp->name);
return &avmb1_interface;
}
@@ -1048,6 +1173,7 @@
*pp = userp->next;
userp->next = 0;
MOD_DEC_USE_COUNT;
+ printk(KERN_NOTICE "b1capi: %s detached\n", userp->name);
return 0;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)