patch-2.3.14 linux/drivers/isdn/hisax/isar.c
Next file: linux/drivers/isdn/hisax/isar.h
Previous file: linux/drivers/isdn/hisax/isac.c
Back to the patch index
Back to the overall index
- Lines: 400
- Date:
Thu Aug 12 09:42:33 1999
- Orig file:
v2.3.13/linux/drivers/isdn/hisax/isar.c
- Orig date:
Sun May 23 10:03:41 1999
diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.2 1998/11/15 23:54:53 keil Exp $
+/* $Id: isar.c,v 1.4 1999/08/05 20:43:18 keil Exp $
* isar.c ISAR (Siemens PSB 7110) specific routines
*
@@ -6,6 +6,12 @@
*
*
* $Log: isar.c,v $
+ * Revision 1.4 1999/08/05 20:43:18 keil
+ * ISAR analog modem support
+ *
+ * Revision 1.3 1999/07/01 08:11:45 keil
+ * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel
+ *
* Revision 1.2 1998/11/15 23:54:53 keil
* changes from 2.0
*
@@ -425,7 +431,9 @@
cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
break;
case L1_MODE_TRANS:
+ case L1_MODE_V32:
if ((skb = dev_alloc_skb(ireg->clsb))) {
+ SET_SKB_FREE(skb);
rcv_mbox(cs, ireg, (u_char *)skb_put(skb, ireg->clsb));
skb_queue_tail(&bcs->rqueue, skb);
isar_sched_event(bcs, B_RCVBUFREADY);
@@ -459,6 +467,7 @@
} else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx-2)))
printk(KERN_WARNING "ISAR: receive out of memory\n");
else {
+ SET_SKB_FREE(skb);
memcpy(skb_put(skb, bcs->hw.isar.rcvidx-2),
bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx-2);
skb_queue_tail(&bcs->rqueue, skb);
@@ -512,6 +521,7 @@
printk(KERN_ERR"isar_fill_fifo wrong mode 0\n");
break;
case L1_MODE_TRANS:
+ case L1_MODE_V32:
if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
0, count, ptr)) {
if (cs->debug)
@@ -557,7 +567,7 @@
if (bcs->st->lli.l1writewakeup &&
(PACKET_NOACK != bcs->tx_skb->pkt_type))
bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.isar.txcnt);
- dev_kfree_skb(bcs->tx_skb);
+ idev_kfree_skb(bcs->tx_skb, FREE_WRITE);
bcs->hw.isar.txcnt = 0;
bcs->tx_skb = NULL;
}
@@ -593,6 +603,136 @@
}
}
+const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
+ "300", "600", "1200", "2400", "4800", "7200",
+ "9600nt", "9600t", "12000", "14400", "WRONG"};
+const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
+ "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
+
+static void
+isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) {
+ struct IsdnCardState *cs = bcs->cs;
+ u_char ril = ireg->par[0];
+ u_char rim;
+
+ if (!test_and_clear_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags))
+ return;
+ if (ril > 14) {
+ if (cs->debug & L1_DEB_WARN)
+ debugl1(cs, "wrong pstrsp ril=%d",ril);
+ ril = 15;
+ }
+ switch(ireg->par[1]) {
+ case 0:
+ rim = 0;
+ break;
+ case 0x20:
+ rim = 2;
+ break;
+ case 0x40:
+ rim = 3;
+ break;
+ case 0x41:
+ rim = 4;
+ break;
+ case 0x51:
+ rim = 5;
+ break;
+ case 0x61:
+ rim = 6;
+ break;
+ case 0x71:
+ rim = 7;
+ break;
+ case 0x82:
+ rim = 8;
+ break;
+ case 0x92:
+ rim = 9;
+ break;
+ case 0xa2:
+ rim = 10;
+ break;
+ default:
+ rim = 1;
+ break;
+ }
+ sprintf(bcs->hw.isar.conmsg,"%s %s", dmril[ril], dmrim[rim]);
+ bcs->conmsg = bcs->hw.isar.conmsg;
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump strsp %s", bcs->conmsg);
+}
+
+static void
+isar_pump_status_ev(struct BCState *bcs, u_char devt) {
+ struct IsdnCardState *cs = bcs->cs;
+ u_char dps = SET_DPS(bcs->hw.isar.dpath);
+
+ switch(devt) {
+ case PSEV_10MS_TIMER:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev TIMER");
+ break;
+ case PSEV_CON_ON:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev CONNECT");
+ l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL);
+ break;
+ case PSEV_CON_OFF:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev NO CONNECT");
+ sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+ l1_msg_b(bcs->st, PH_DEACTIVATE | REQUEST, NULL);
+ break;
+ case PSEV_V24_OFF:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev V24 OFF");
+ break;
+ case PSEV_CTS_ON:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev CTS ON");
+ break;
+ case PSEV_CTS_OFF:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev CTS OFF");
+ break;
+ case PSEV_DCD_ON:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev CARRIER ON");
+ test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags);
+ sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+ break;
+ case PSEV_DCD_OFF:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev CARRIER OFF");
+ break;
+ case PSEV_DSR_ON:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev DSR ON");
+// sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, 0xCF, 0, NULL);
+ break;
+ case PSEV_DSR_OFF:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev DSR_OFF");
+ break;
+ case PSEV_REM_RET:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev REMOTE RETRAIN");
+ break;
+ case PSEV_REM_REN:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev REMOTE RENEGOTIATE");
+ break;
+ case PSEV_GSTN_CLR:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev GSTN CLEAR", devt);
+ break;
+ default:
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "unknown pump stev %x", devt);
+ break;
+ }
+}
static char debbuf[64];
@@ -628,10 +768,31 @@
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "Buffer STEV dpath%d msb(%x)",
ireg->iis>>6, ireg->cmsb);
+ case ISAR_IIS_PSTEV:
+ if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
+ rcv_mbox(cs, ireg, (u_char *)ireg->par);
+ isar_pump_status_ev(bcs, ireg->cmsb);
+ } else {
+ debugl1(cs, "isar spurious IIS_PSTEV %x/%x/%x",
+ ireg->iis, ireg->cmsb, ireg->clsb);
+ printk(KERN_WARNING"isar spurious IIS_PSTEV %x/%x/%x\n",
+ ireg->iis, ireg->cmsb, ireg->clsb);
+ cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
+ }
break;
- case ISAR_IIS_DIAG:
case ISAR_IIS_PSTRSP:
- case ISAR_IIS_PSTEV:
+ if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
+ rcv_mbox(cs, ireg, (u_char *)ireg->par);
+ isar_pump_status_rsp(bcs, ireg);
+ } else {
+ debugl1(cs, "isar spurious IIS_PSTRSP %x/%x/%x",
+ ireg->iis, ireg->cmsb, ireg->clsb);
+ printk(KERN_WARNING"isar spurious IIS_PSTRSP %x/%x/%x\n",
+ ireg->iis, ireg->cmsb, ireg->clsb);
+ cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
+ }
+ break;
+ case ISAR_IIS_DIAG:
case ISAR_IIS_BSTRSP:
case ISAR_IIS_IOM2RSP:
rcv_mbox(cs, ireg, (u_char *)ireg->par);
@@ -659,7 +820,8 @@
setup_pump(struct BCState *bcs) {
struct IsdnCardState *cs = bcs->cs;
u_char dps = SET_DPS(bcs->hw.isar.dpath);
-
+ u_char ctrl, param[6];
+
switch (bcs->mode) {
case L1_MODE_NULL:
case L1_MODE_TRANS:
@@ -670,6 +832,44 @@
bcs->hw.isar.dpath);
}
break;
+ case L1_MODE_V32:
+ ctrl = PMOD_DATAMODEM;
+ if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
+ ctrl |= PCTRL_ORIG;
+ param[5] = PV32P6_CTN;
+ } else {
+ param[5] = PV32P6_ATN;
+ }
+ param[0] = 11; /* 11 db */
+// param[1] = PV32P2_V22A | PV32P2_V22B | PV32P2_V21;
+ param[1] = PV32P2_V22A;
+// param[2] = PV32P3_AMOD | PV32P3_V32B;
+ param[2] = PV32P3_AMOD;
+ param[3] = PV32P4_48;
+ param[4] = PV32P5_48;
+// param[3] = PV32P4_UT144;
+// param[4] = PV32P5_UT144;
+ if (!sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param)) {
+ if (cs->debug)
+ debugl1(cs, "isar pump datamodem cfg dp%d failed",
+ bcs->hw.isar.dpath);
+ }
+ break;
+ case L1_MODE_FAX:
+ ctrl = PMOD_FAX;
+ if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
+ ctrl |= PCTRL_ORIG;
+ param[1] = PFAXP2_CTN;
+ } else {
+ param[1] = PFAXP2_ATN;
+ }
+ param[0] = 8; /* 8 db */
+ if (!sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param)) {
+ if (cs->debug)
+ debugl1(cs, "isar pump faxmodem cfg dp%d failed",
+ bcs->hw.isar.dpath);
+ }
+ break;
}
if (!sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL)) {
if (cs->debug)
@@ -682,6 +882,7 @@
setup_sart(struct BCState *bcs) {
struct IsdnCardState *cs = bcs->cs;
u_char dps = SET_DPS(bcs->hw.isar.dpath);
+ u_char ctrl, param[2];
switch (bcs->mode) {
case L1_MODE_NULL:
@@ -701,7 +902,17 @@
case L1_MODE_HDLC:
if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1, "\0")) {
if (cs->debug)
- debugl1(cs, "isar sart binary dp%d failed",
+ debugl1(cs, "isar sart hdlc dp%d failed",
+ bcs->hw.isar.dpath);
+ }
+ break;
+ case L1_MODE_V32:
+ ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
+ param[0] = S_P1_CHS_8;
+ param[1] = S_P2_BFT_DEF;
+ if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, ctrl, 2, param)) {
+ if (cs->debug)
+ debugl1(cs, "isar sart v14 dp%d failed",
bcs->hw.isar.dpath);
}
break;
@@ -717,18 +928,22 @@
setup_iom2(struct BCState *bcs) {
struct IsdnCardState *cs = bcs->cs;
u_char dps = SET_DPS(bcs->hw.isar.dpath);
- u_char cmsb = 0, msg[5] = {0x10,0,0,0,0};
+ u_char cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD,0,0,0,0};
+ if (bcs->channel)
+ msg[1] = msg[3] = 1;
switch (bcs->mode) {
case L1_MODE_NULL:
+ cmsb = 0;
/* dummy slot */
msg[1] = msg[3] = bcs->hw.isar.dpath + 2;
break;
case L1_MODE_TRANS:
case L1_MODE_HDLC:
- cmsb = 0x80;
- if (bcs->channel)
- msg[1] = msg[3] = 1;
+ break;
+ case L1_MODE_V32:
+ case L1_MODE_FAX:
+ cmsb |= IOM_CTRL_ALAW | IOM_CTRL_RCV;
break;
}
if (!sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg)) {
@@ -763,7 +978,18 @@
&bcs->hw.isar.reg->Flags))
bcs->hw.isar.dpath = 1;
else {
- printk(KERN_ERR"isar modeisar both pathes in use\n");
+ printk(KERN_WARNING"isar modeisar both pathes in use\n");
+ return(1);
+ }
+ break;
+ case L1_MODE_V32:
+ /* only datapath 1 */
+ if (!test_and_set_bit(ISAR_DP1_USE,
+ &bcs->hw.isar.reg->Flags))
+ bcs->hw.isar.dpath = 1;
+ else {
+ printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n");
+ debugl1(cs, "isar modeisar analog funktions only with DP1");
return(1);
}
break;
@@ -774,8 +1000,8 @@
bcs->hw.isar.dpath, bcs->mode, mode, bc);
bcs->mode = mode;
setup_pump(bcs);
- setup_sart(bcs);
setup_iom2(bcs);
+ setup_sart(bcs);
if (bcs->mode == L1_MODE_NULL) {
/* Clear resources */
if (bcs->hw.isar.dpath == 1)
@@ -853,8 +1079,24 @@
break;
case (PH_ACTIVATE | REQUEST):
test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
- modeisar(st->l1.bcs, st->l1.mode, st->l1.bc);
- l1_msg_b(st, pr, arg);
+ st->l1.bcs->hw.isar.conmsg[0] = 0;
+ if (test_bit(FLG_ORIG, &st->l2.flag))
+ test_and_set_bit(BC_FLG_ORIG, &st->l1.bcs->Flag);
+ else
+ test_and_clear_bit(BC_FLG_ORIG, &st->l1.bcs->Flag);
+ switch(st->l1.mode) {
+ case L1_MODE_TRANS:
+ case L1_MODE_HDLC:
+ if (modeisar(st->l1.bcs, st->l1.mode, st->l1.bc))
+ l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg);
+ else
+ l1_msg_b(st, PH_ACTIVATE | REQUEST, arg);
+ break;
+ case L1_MODE_V32:
+ if (modeisar(st->l1.bcs, st->l1.mode, st->l1.bc))
+ l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg);
+ break;
+ }
break;
case (PH_DEACTIVATE | REQUEST):
l1_msg_b(st, pr, arg);
@@ -882,7 +1124,7 @@
discard_queue(&bcs->rqueue);
discard_queue(&bcs->squeue);
if (bcs->tx_skb) {
- dev_kfree_skb(bcs->tx_skb);
+ idev_kfree_skb(bcs->tx_skb, FREE_WRITE);
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
if (bcs->cs->debug & L1_DEB_HSCX)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)