patch-2.4.21 linux-2.4.21/drivers/isdn/hisax/isar.c
Next file: linux-2.4.21/drivers/isdn/hisax/isar.h
Previous file: linux-2.4.21/drivers/isdn/hisax/hisax.h
Back to the patch index
Back to the overall index
- Lines: 353
- Date:
2003-06-13 07:51:34.000000000 -0700
- Orig file:
linux-2.4.20/drivers/isdn/hisax/isar.c
- Orig date:
2001-12-21 09:41:54.000000000 -0800
diff -urN linux-2.4.20/drivers/isdn/hisax/isar.c linux-2.4.21/drivers/isdn/hisax/isar.c
@@ -21,10 +21,12 @@
#define DLE 0x10
#define ETX 0x03
-
-const u_char faxmodulation_s[] = "3,24,48,72,73,74,96,97,98,121,122,145,146";
-const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
-#define FAXMODCNT 13
+#define FAXMODCNT 13
+const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
+static u_int modmask = 0x1fff;
+static int frm_extra_delay = 2;
+static int para_TOA = 6;
+const u_char *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
void isar_setup(struct IsdnCardState *cs);
static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para);
@@ -125,7 +127,7 @@
ireg->clsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_L);
#if DUMP_MBOXFRAME
if (cs->debug & L1_DEB_HSCX)
- debugl1(cs, "rcv_mbox(%02x,%02x,%d)", ireg->iis, ireg->cmsb,
+ debugl1(cs, "irq_stat(%02x,%02x,%d)", ireg->iis, ireg->cmsb,
ireg->clsb);
#endif
}
@@ -412,6 +414,7 @@
}
cs->debug = debug;
isar_setup(cs);
+
ret = 0;
reterrflg:
restore_flags(flags);
@@ -581,7 +584,6 @@
if (ireg->cmsb & SART_NMD) { /* ABORT */
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "isar_rcv_frame: no more data");
- cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
bcs->hw.isar.rcvidx = 0;
send_DLE_ETX(bcs);
sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) |
@@ -592,7 +594,6 @@
}
} else {
printk(KERN_WARNING "HiSax: skb out of memory\n");
- cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
}
break;
}
@@ -617,8 +618,9 @@
bcs->hw.isar.rcvidx = 0;
cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
} else {
- if (ireg->cmsb & HDLC_FSD)
+ if (ireg->cmsb & HDLC_FSD) {
bcs->hw.isar.rcvidx = 0;
+ }
ptr = bcs->hw.isar.rcvbuf + bcs->hw.isar.rcvidx;
bcs->hw.isar.rcvidx += ireg->clsb;
rcv_mbox(cs, ireg, ptr);
@@ -629,6 +631,8 @@
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "isar frame to short %d",
bcs->hw.isar.rcvidx);
+ printk(KERN_WARNING "ISAR: frame to short %d\n",
+ bcs->hw.isar.rcvidx);
} else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx))) {
printk(KERN_WARNING "ISAR: receive out of memory\n");
} else {
@@ -639,6 +643,7 @@
isar_sched_event(bcs, B_RCVBUFREADY);
send_DLE_ETX(bcs);
isar_sched_event(bcs, B_LL_OK);
+ test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
}
bcs->hw.isar.rcvidx = 0;
}
@@ -646,13 +651,14 @@
if (ireg->cmsb & SART_NMD) { /* ABORT */
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "isar_rcv_frame: no more data");
- cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
bcs->hw.isar.rcvidx = 0;
- send_DLE_ETX(bcs);
sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) |
ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
bcs->hw.isar.state = STFAX_ESCAPE;
- isar_sched_event(bcs, B_LL_NOCARRIER);
+ if (test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag)) {
+ send_DLE_ETX(bcs);
+ isar_sched_event(bcs, B_LL_NOCARRIER);
+ }
}
break;
default:
@@ -1075,19 +1081,22 @@
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "pump stev RSP_DISC");
if (bcs->hw.isar.state == STFAX_ESCAPE) {
+ p1 = 5;
switch(bcs->hw.isar.newcmd) {
case 0:
bcs->hw.isar.state = STFAX_READY;
break;
- case PCTRL_CMD_FTH:
case PCTRL_CMD_FTM:
- p1 = 10;
+ p1 = 2;
+ case PCTRL_CMD_FTH:
sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
PCTRL_CMD_SILON, 1, &p1);
bcs->hw.isar.state = STFAX_SILDET;
break;
- case PCTRL_CMD_FRH:
case PCTRL_CMD_FRM:
+ if (frm_extra_delay)
+ mdelay(frm_extra_delay);
+ case PCTRL_CMD_FRH:
p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod;
bcs->hw.isar.newmod = 0;
bcs->hw.isar.cmd = bcs->hw.isar.newcmd;
@@ -1206,6 +1215,9 @@
isar_pump_statev_modem(bcs, ireg->cmsb);
} else if (bcs->mode == L1_MODE_FAX) {
isar_pump_statev_fax(bcs, ireg->cmsb);
+ } else if (ireg->cmsb == PSEV_10MS_TIMER) {
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "pump stev TIMER");
} else {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "isar IIS_PSTEV pmode %d stat %x",
@@ -1266,6 +1278,9 @@
if (test_and_clear_bit(BC_FLG_LL_CONN, &bcs->Flag)) {
isar_sched_event(bcs, B_LL_CONNECT);
}
+ if (test_and_clear_bit(BC_FLG_FTI_FTS, &bcs->Flag)) {
+ isar_sched_event(bcs, B_LL_OK);
+ }
}
static void
@@ -1288,7 +1303,7 @@
} else {
param[5] = PV32P6_ATN;
}
- param[0] = 6; /* 6 db */
+ param[0] = para_TOA; /* 6 db */
param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
PV32P2_V22C | PV32P2_V21 | PV32P2_BEL;
param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
@@ -1304,7 +1319,7 @@
} else {
param[1] = PFAXP2_ATN;
}
- param[0] = 6; /* 6 db */
+ param[0] = para_TOA; /* 6 db */
sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
bcs->hw.isar.state = STFAX_NULL;
bcs->hw.isar.newcmd = 0;
@@ -1333,7 +1348,6 @@
"\0\0");
break;
case L1_MODE_HDLC:
- case L1_MODE_FAX:
param[0] = 0;
sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1,
param);
@@ -1345,6 +1359,9 @@
sendmsg(cs, dps | ISAR_HIS_SARTCFG, ctrl, 2,
param);
break;
+ case L1_MODE_FAX:
+ /* SART must not configured with FAX */
+ break;
}
udelay(1000);
sendmsg(cs, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
@@ -1448,6 +1465,7 @@
switch(cmd) {
case ISDN_FAX_CLASS1_FTM:
+ test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
if (bcs->hw.isar.state == STFAX_READY) {
p1 = para;
ctrl = PCTRL_CMD_FTM;
@@ -1471,6 +1489,7 @@
}
break;
case ISDN_FAX_CLASS1_FTH:
+ test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
if (bcs->hw.isar.state == STFAX_READY) {
p1 = para;
ctrl = PCTRL_CMD_FTH;
@@ -1494,6 +1513,7 @@
}
break;
case ISDN_FAX_CLASS1_FRM:
+ test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
if (bcs->hw.isar.state == STFAX_READY) {
p1 = para;
ctrl = PCTRL_CMD_FRM;
@@ -1517,6 +1537,7 @@
}
break;
case ISDN_FAX_CLASS1_FRH:
+ test_and_set_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
if (bcs->hw.isar.state == STFAX_READY) {
p1 = para;
ctrl = PCTRL_CMD_FRH;
@@ -1539,6 +1560,11 @@
bcs->hw.isar.state = STFAX_ESCAPE;
}
break;
+ case ISDN_FAXPUMP_HALT:
+ bcs->hw.isar.state = STFAX_NULL;
+ nom = 0;
+ ctrl = PCTRL_CMD_HALT;
+ break;
}
if (ctrl)
sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
@@ -1632,6 +1658,15 @@
l1_msg_b(st, pr, arg);
break;
case (PH_DEACTIVATE | CONFIRM):
+ switch(st->l1.mode) {
+ case L1_MODE_TRANS:
+ case L1_MODE_HDLC:
+ case L1_MODE_V32:
+ break;
+ case L1_MODE_FAX:
+ isar_pump_cmd(st->l1.bcs, ISDN_FAXPUMP_HALT, 0);
+ break;
+ }
test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
@@ -1723,6 +1758,51 @@
test_and_set_bit(BC_FLG_DLEETX,
&bcs->Flag);
break;
+ case ISDN_FAX_CLASS1_FTS:
+ if (ic->parm.aux.subcmd == AT_QUERY) {
+ ic->command = ISDN_STAT_FAXIND;
+ ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK;
+ cs->iif.statcallb(ic);
+ return(0);
+ } else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
+ strcpy(ic->parm.aux.para, "0-255");
+ ic->command = ISDN_STAT_FAXIND;
+ ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
+ cs->iif.statcallb(ic);
+ return(0);
+ } else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "isar_auxcmd %s=%d",
+ FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
+ if (bcs->hw.isar.state == STFAX_READY) {
+ if (! ic->parm.aux.para[0]) {
+ ic->command = ISDN_STAT_FAXIND;
+ ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK;
+ cs->iif.statcallb(ic);
+ return(0);
+ }
+ if (! test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag)) {
+ /* n*10 ms */
+ bcs->hw.isar.ftimer.expires =
+ jiffies + ((ic->parm.aux.para[0] * 10 * HZ)/1000);
+ test_and_set_bit(BC_FLG_FTI_FTS, &bcs->Flag);
+ add_timer(&bcs->hw.isar.ftimer);
+ return(0);
+ } else {
+ if (cs->debug)
+ debugl1(cs, "isar FTS=%d and FTI busy",
+ ic->parm.aux.para[0]);
+ }
+ } else {
+ if (cs->debug)
+ debugl1(cs, "isar FTS=%d and isar.state not ready(%x)",
+ ic->parm.aux.para[0],bcs->hw.isar.state);
+ }
+ ic->command = ISDN_STAT_FAXIND;
+ ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR;
+ cs->iif.statcallb(ic);
+ }
+ break;
case ISDN_FAX_CLASS1_FRM:
case ISDN_FAX_CLASS1_FRH:
case ISDN_FAX_CLASS1_FTM:
@@ -1735,16 +1815,24 @@
cs->iif.statcallb(ic);
return(0);
} else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
- strcpy(ic->parm.aux.para, faxmodulation_s);
+ char *p = ic->parm.aux.para;
+ for(i=0;i<FAXMODCNT;i++)
+ if ((1<<i) & modmask)
+ p += sprintf(p, "%d,", faxmodulation[i]);
+ p--;
+ *p=0;
ic->command = ISDN_STAT_FAXIND;
ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
cs->iif.statcallb(ic);
return(0);
} else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
+ if (cs->debug & L1_DEB_HSCX)
+ debugl1(cs, "isar_auxcmd %s=%d",
+ FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
for(i=0;i<FAXMODCNT;i++)
if (faxmodulation[i]==ic->parm.aux.para[0])
break;
- if ((FAXMODCNT > i) &&
+ if ((i < FAXMODCNT) && ((1<<i) & modmask) &&
test_bit(BC_FLG_INIT, &bcs->Flag)) {
isar_pump_cmd(bcs,
ic->parm.aux.cmd,
@@ -1762,7 +1850,7 @@
break;
case (ISDN_CMD_IOCTL):
switch (ic->arg) {
- case (9): /* load firmware */
+ case 9: /* load firmware */
features = ISDN_FEATURE_L2_MODEM |
ISDN_FEATURE_L2_FAX |
ISDN_FEATURE_L3_FCLASS1;
@@ -1772,6 +1860,26 @@
else
ll_run(cs, features);
break;
+ case 20:
+ features = *(unsigned int *) ic->parm.num;
+ printk(KERN_DEBUG "HiSax: max modulation old(%04x) new(%04x)\n",
+ modmask, features);
+ modmask = features;
+ break;
+ case 21:
+ features = *(unsigned int *) ic->parm.num;
+ printk(KERN_DEBUG "HiSax: FRM extra delay old(%d) new(%d) ms\n",
+ frm_extra_delay, features);
+ if (features >= 0)
+ frm_extra_delay = features;
+ break;
+ case 22:
+ features = *(unsigned int *) ic->parm.num;
+ printk(KERN_DEBUG "HiSax: TOA old(%d) new(%d) db\n",
+ para_TOA, features);
+ if (features >= 0 && features < 32)
+ para_TOA = features;
+ break;
default:
printk(KERN_DEBUG "HiSax: invalid ioctl %d\n",
(int) ic->arg);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)