📄 isar.c
字号:
case PSEV_DSR_ON: if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev DSR ON"); 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 voidisar_pump_statev_fax(struct BCState *bcs, u_char devt) { struct IsdnCardState *cs = bcs->cs; u_char dps = SET_DPS(bcs->hw.isar.dpath); u_char p1; switch(devt) { case PSEV_10MS_TIMER: if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev TIMER"); break; case PSEV_RSP_READY: if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev RSP_READY"); bcs->hw.isar.state = STFAX_READY; l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL); if (test_bit(BC_FLG_ORIG, &bcs->Flag)) { isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FRH, 3); } else { isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FTH, 3); } break; case PSEV_LINE_TX_H: if (bcs->hw.isar.state == STFAX_LINE) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev LINE_TX_H"); bcs->hw.isar.state = STFAX_CONT; sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); } else { if (cs->debug & L1_DEB_WARN) debugl1(cs, "pump stev LINE_TX_H wrong st %x", bcs->hw.isar.state); } break; case PSEV_LINE_RX_H: if (bcs->hw.isar.state == STFAX_LINE) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev LINE_RX_H"); bcs->hw.isar.state = STFAX_CONT; sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); } else { if (cs->debug & L1_DEB_WARN) debugl1(cs, "pump stev LINE_RX_H wrong st %x", bcs->hw.isar.state); } break; case PSEV_LINE_TX_B: if (bcs->hw.isar.state == STFAX_LINE) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev LINE_TX_B"); bcs->hw.isar.state = STFAX_CONT; sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); } else { if (cs->debug & L1_DEB_WARN) debugl1(cs, "pump stev LINE_TX_B wrong st %x", bcs->hw.isar.state); } break; case PSEV_LINE_RX_B: if (bcs->hw.isar.state == STFAX_LINE) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev LINE_RX_B"); bcs->hw.isar.state = STFAX_CONT; sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL); } else { if (cs->debug & L1_DEB_WARN) debugl1(cs, "pump stev LINE_RX_B wrong st %x", bcs->hw.isar.state); } break; case PSEV_RSP_CONN: if (bcs->hw.isar.state == STFAX_CONT) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev RSP_CONN"); bcs->hw.isar.state = STFAX_ACTIV; test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags); sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) { /* 1s Flags before data */ if (test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag)) del_timer(&bcs->hw.isar.ftimer); /* 1000 ms */ bcs->hw.isar.ftimer.expires = jiffies + ((1000 * HZ)/1000); test_and_set_bit(BC_FLG_LL_CONN, &bcs->Flag); add_timer(&bcs->hw.isar.ftimer); } else { isar_sched_event(bcs, B_LL_CONNECT); } } else { if (cs->debug & L1_DEB_WARN) debugl1(cs, "pump stev RSP_CONN wrong st %x", bcs->hw.isar.state); } break; case PSEV_FLAGS_DET: if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev FLAGS_DET"); break; case PSEV_RSP_DISC: 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_FTM: 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_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; bcs->hw.isar.newcmd = 0; sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, bcs->hw.isar.cmd, 1, &p1); bcs->hw.isar.state = STFAX_LINE; bcs->hw.isar.try_mod = 3; break; default: if (cs->debug & L1_DEB_HSCX) debugl1(cs, "RSP_DISC unknown newcmd %x", bcs->hw.isar.newcmd); break; } } else if (bcs->hw.isar.state == STFAX_ACTIV) { if (test_and_clear_bit(BC_FLG_LL_OK, &bcs->Flag)) { isar_sched_event(bcs, B_LL_OK); } else if (bcs->hw.isar.cmd == PCTRL_CMD_FRM) { send_DLE_ETX(bcs); isar_sched_event(bcs, B_LL_NOCARRIER); } else { ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR); } bcs->hw.isar.state = STFAX_READY; } else { bcs->hw.isar.state = STFAX_READY; ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR); } break; case PSEV_RSP_SILDET: if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev RSP_SILDET"); if (bcs->hw.isar.state == STFAX_SILDET) { p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod; bcs->hw.isar.newmod = 0; bcs->hw.isar.cmd = bcs->hw.isar.newcmd; bcs->hw.isar.newcmd = 0; sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, bcs->hw.isar.cmd, 1, &p1); bcs->hw.isar.state = STFAX_LINE; bcs->hw.isar.try_mod = 3; } break; case PSEV_RSP_SILOFF: if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev RSP_SILOFF"); break; case PSEV_RSP_FCERR: if (bcs->hw.isar.state == STFAX_LINE) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev RSP_FCERR try %d", bcs->hw.isar.try_mod); if (bcs->hw.isar.try_mod--) { sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, bcs->hw.isar.cmd, 1, &bcs->hw.isar.mod); break; } } if (cs->debug & L1_DEB_HSCX) debugl1(cs, "pump stev RSP_FCERR"); bcs->hw.isar.state = STFAX_ESCAPE; sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL); ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR); break; default: break; }}static char debbuf[128];voidisar_int_main(struct IsdnCardState *cs){ long flags; struct isar_reg *ireg = cs->bcs[0].hw.isar.reg; struct BCState *bcs; save_flags(flags); cli(); get_irq_infos(cs, ireg); switch (ireg->iis & ISAR_IIS_MSCMSD) { case ISAR_IIS_RDATA: if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { isar_rcv_frame(cs, bcs); } else { debugl1(cs, "isar spurious IIS_RDATA %x/%x/%x", ireg->iis, ireg->cmsb, ireg->clsb); cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); } break; case ISAR_IIS_GSTEV: cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); ireg->bstat |= ireg->cmsb; check_send(cs, ireg->cmsb); break; case ISAR_IIS_BSTEV:#ifdef ERROR_STATISTIC if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { if (ireg->cmsb == BSTEV_TBO) bcs->err_tx++; if (ireg->cmsb == BSTEV_RBO) bcs->err_rdo++; }#endif if (cs->debug & L1_DEB_WARN) debugl1(cs, "Buffer STEV dpath%d msb(%x)", ireg->iis>>6, ireg->cmsb); cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); break; case ISAR_IIS_PSTEV: if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { rcv_mbox(cs, ireg, (u_char *)ireg->par); if (bcs->mode == L1_MODE_V32) { 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", bcs->mode, ireg->cmsb); } } else { debugl1(cs, "isar spurious IIS_PSTEV %x/%x/%x", ireg->iis, ireg->cmsb, ireg->clsb); cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); } break; case ISAR_IIS_PSTRSP: 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); 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); if ((cs->debug & (L1_DEB_HSCX | L1_DEB_HSCX_FIFO)) == L1_DEB_HSCX) { u_char *tp=debbuf; tp += sprintf(debbuf, "msg iis(%x) msb(%x)", ireg->iis, ireg->cmsb); QuickHex(tp, (u_char *)ireg->par, ireg->clsb); debugl1(cs, debbuf); } break; case ISAR_IIS_INVMSG: rcv_mbox(cs, ireg, debbuf); if (cs->debug & L1_DEB_WARN) debugl1(cs, "invalid msg his:%x", ireg->cmsb); break; default: rcv_mbox(cs, ireg, debbuf); if (cs->debug & L1_DEB_WARN) debugl1(cs, "unhandled msg iis(%x) ctrl(%x/%x)", ireg->iis, ireg->cmsb, ireg->clsb); break; } restore_flags(flags);}static voidftimer_handler(struct BCState *bcs) { if (bcs->cs->debug) debugl1(bcs->cs, "ftimer flags %04x", bcs->Flag); test_and_clear_bit(BC_FLG_FTI_RUN, &bcs->Flag); 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 voidsetup_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: case L1_MODE_HDLC: sendmsg(cs, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL); 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] = 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; param[3] = PV32P4_UT144; param[4] = PV32P5_UT144; sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param); 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] = para_TOA; /* 6 db */ sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param); bcs->hw.isar.state = STFAX_NULL; bcs->hw.isar.newcmd = 0; bcs->hw.isar.newmod = 0; test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag); break; } udelay(1000); sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); udelay(1000);}static voidsetup_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: sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, 0, NULL); break; case L1_MODE_TRANS: sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, 2, "\0\0"); break; case L1_MODE_HDLC: param[0] = 0; sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1, param); break; case L1_MODE_V32: ctrl = SMODE_V14 | SCTRL_HDMC_BOTH; param[0] = S_P1_CHS_8; param[1] = S_P2_BFT_DEF; 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); udelay(1000);}static voidsetup_iom2(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; u_char dps = SET_DPS(bcs->hw.isar.dpath); 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: break; case L1_MODE_V32: case L1_MODE_FAX: cmsb |= IOM_CTRL_ALAW | IOM_CTRL_RCV; break; } sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg); udelay(1000); sendmsg(cs, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL); udelay(1000);}intmodeisar(struct BCState *bcs, int mode, int bc){ struct IsdnCardState *cs = bcs->cs; /* Here we are selecting the best datapath for requested mode */ if(bcs->mode == L1_MODE_NULL) { /* New Setup */ bcs->channel = bc; switch (mode) { case L1_MODE_NULL: /* init */ if (!bcs->hw.isar.dpath) /* no init for dpath 0 */ return(0); break; case L1_MODE_TRANS: case L1_MODE_HDLC: /* best is datapath 2 */ if (!test_and_set_bit(ISAR_DP2_USE, &bcs->hw.isar.reg->Flags)) bcs->hw.isar.dpath = 2; else if (!test_and_set_bit(ISAR_DP1_USE, &bcs->hw.isar.reg->Flags)) bcs->hw.isar.dpath = 1; else { printk(KERN_WARNING"isar modeisar both pathes in use\n"); return(1); } break; case L1_MODE_V32: case L1_MODE_FAX:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -