📄 elsa_ser.c
字号:
} while (--count > 0); if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2)) modem_fill(cs->hw.elsa.bcs);#ifdef SERIAL_DEBUG_INTR printk("THRE...");#endif if (intr_done) *intr_done = 0; if (cs->hw.elsa.transcnt <= 0) { cs->hw.elsa.IER &= ~UART_IER_THRI; serial_outp(cs, UART_IER, cs->hw.elsa.IER); }}#if 0static inline void check_modem_status(struct IsdnCardState *cs){ int status; struct async_struct *info = cs->hw.elsa.info; struct async_icount *icount; status = serial_inp(info, UART_MSR); if (status & UART_MSR_ANY_DELTA) { icount = &info->state->icount; /* update input line counters */ if (status & UART_MSR_TERI) icount->rng++; if (status & UART_MSR_DDSR) icount->dsr++; if (status & UART_MSR_DDCD) { icount->dcd++; } if (status & UART_MSR_DCTS) icount->cts++;// wake_up_interruptible(&info->delta_msr_wait); } if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) printk("ttys%d CD now %s...", info->line, (status & UART_MSR_DCD) ? "on" : "off");#endif if (status & UART_MSR_DCD)// wake_up_interruptible(&info->open_wait);; else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && (info->flags & ASYNC_CALLOUT_NOHUP))) {#ifdef SERIAL_DEBUG_OPEN printk("doing serial hangup...");#endif if (info->tty) tty_hangup(info->tty); } }#if 0 if (info->flags & ASYNC_CTS_FLOW) { if (info->tty->hw_stopped) { if (status & UART_MSR_CTS) {#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) printk("CTS tx start...");#endif info->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; serial_outp(info, UART_IER, info->IER);// rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); return; } } else { if (!(status & UART_MSR_CTS)) {#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) printk("CTS tx stop...");#endif info->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; serial_outp(info, UART_IER, info->IER); } } }#endif 0}#endifstatic void rs_interrupt_elsa(int irq, struct IsdnCardState *cs){ int status, iir, msr; int pass_counter = 0; #ifdef SERIAL_DEBUG_INTR printk("rs_interrupt_single(%d)...", irq);#endif do { status = serial_inp(cs, UART_LSR); debugl1(cs,"rs LSR %02x", status);#ifdef SERIAL_DEBUG_INTR printk("status = %x...", status);#endif if (status & UART_LSR_DR) receive_chars(cs, &status); if (status & UART_LSR_THRE) transmit_chars(cs, 0); if (pass_counter++ > RS_ISR_PASS_LIMIT) { printk("rs_single loop break.\n"); break; } iir = serial_inp(cs, UART_IIR); debugl1(cs,"rs IIR %02x", iir); if ((iir & 0xf) == 0) { msr = serial_inp(cs, UART_MSR); debugl1(cs,"rs MSR %02x", msr); } } while (!(iir & UART_IIR_NO_INT));#ifdef SERIAL_DEBUG_INTR printk("end.\n");#endif}extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);extern void modehscx(struct BCState *bcs, int mode, int bc);extern void hscx_l2l1(struct PStack *st, int pr, void *arg);voidclose_elsastate(struct BCState *bcs){ struct sk_buff *skb; modehscx(bcs, 0, bcs->channel); if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { if (bcs->hw.hscx.rcvbuf) { if (bcs->mode != L1_MODE_MODEM) kfree(bcs->hw.hscx.rcvbuf); bcs->hw.hscx.rcvbuf = NULL; } while ((skb = skb_dequeue(&bcs->rqueue))) { dev_kfree_skb(skb, FREE_READ); } while ((skb = skb_dequeue(&bcs->squeue))) { dev_kfree_skb(skb, FREE_WRITE); } if (bcs->tx_skb) { dev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } }}voidmodem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { int count, fp; u_char *msg = buf; long flags; if (!len) return; save_flags(flags); cli(); if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) { restore_flags(flags); return; } fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp; fp &= (MAX_MODEM_BUF -1); count = MIN(len, MAX_MODEM_BUF - fp); if (count < len) { memcpy(cs->hw.elsa.transbuf + fp, msg, count); cs->hw.elsa.transcnt += count; msg += count; count = len - count; fp = 0; } memcpy(cs->hw.elsa.transbuf + fp, msg, count); cs->hw.elsa.transcnt += count; if (cs->hw.elsa.transcnt && !(cs->hw.elsa.IER & UART_IER_THRI)) { cs->hw.elsa.IER |= UART_IER_THRI; serial_outp(cs, UART_IER, cs->hw.elsa.IER); } restore_flags(flags);}voidmodem_set_init(struct IsdnCardState *cs) { long flags; int timeout;#define RCV_DELAY 20000 save_flags(flags); sti(); modem_write_cmd(cs, MInit_1, strlen(MInit_1)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); modem_write_cmd(cs, MInit_2, strlen(MInit_2)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); modem_write_cmd(cs, MInit_3, strlen(MInit_3)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); modem_write_cmd(cs, MInit_4, strlen(MInit_4)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY ); modem_write_cmd(cs, MInit_5, strlen(MInit_5)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); modem_write_cmd(cs, MInit_6, strlen(MInit_6)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); modem_write_cmd(cs, MInit_7, strlen(MInit_7)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); restore_flags(flags);}voidmodem_set_dial(struct IsdnCardState *cs, int outgoing) { long flags; int timeout;#define RCV_DELAY 20000 save_flags(flags); sti(); modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); if (outgoing) modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout)); else modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); restore_flags(flags);}voidmodem_l2l1(struct PStack *st, int pr, void *arg){ struct sk_buff *skb = arg; long flags; if (pr == (PH_DATA | REQUEST)) { save_flags(flags); cli(); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); restore_flags(flags); } else { st->l1.bcs->tx_skb = skb; test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); st->l1.bcs->hw.hscx.count = 0; restore_flags(flags); write_modem(st->l1.bcs); } } else if (pr == (PH_ACTIVATE | REQUEST)) { test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); set_arcofi(st->l1.bcs->cs, st->l1.bc); mstartup(st->l1.bcs->cs); modem_set_dial(st->l1.bcs->cs, test_bit(FLG_ORIG, &st->l2.flag)); st->l1.bcs->cs->hw.elsa.MFlag=2; } else if (pr == (PH_DEACTIVATE | REQUEST)) { test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); send_arcofi(st->l1.bcs->cs, ARCOFI_XOP_0, st->l1.bc, 0); st->l1.bcs->cs->hw.elsa.MFlag=1; } else { printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr); }}intsetstack_elsa(struct PStack *st, struct BCState *bcs){ bcs->channel = st->l1.bc; switch (st->l1.mode) { case L1_MODE_HDLC: case L1_MODE_TRANS: if (open_hscxstate(st->l1.hardware, bcs)) return (-1); st->l2.l2l1 = hscx_l2l1; break; case L1_MODE_MODEM: bcs->mode = L1_MODE_MODEM; if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf; skb_queue_head_init(&bcs->rqueue); skb_queue_head_init(&bcs->squeue); } bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); bcs->event = 0; bcs->hw.hscx.rcvidx = 0; bcs->tx_cnt = 0; bcs->cs->hw.elsa.bcs = bcs; st->l2.l2l1 = modem_l2l1; break; } st->l1.bcs = bcs; setstack_manager(st); bcs->st = st; setstack_l1_B(st); return (0);}voidinit_modem(struct IsdnCardState *cs) { cs->bcs[0].BC_SetStack = setstack_elsa; cs->bcs[1].BC_SetStack = setstack_elsa; cs->bcs[0].BC_Close = close_elsastate; cs->bcs[1].BC_Close = close_elsastate; if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF, GFP_ATOMIC))) { printk(KERN_WARNING "Elsa: No modem mem hw.elsa.rcvbuf\n"); return; } if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF, GFP_ATOMIC))) { printk(KERN_WARNING "Elsa: No modem mem hw.elsa.transbuf\n"); kfree(cs->hw.elsa.rcvbuf); cs->hw.elsa.rcvbuf = NULL; return; } if (mstartup(cs)) { printk(KERN_WARNING "Elsa: problem startup modem\n"); } modem_set_init(cs);}voidrelease_modem(struct IsdnCardState *cs) { cs->hw.elsa.MFlag = 0; if (cs->hw.elsa.transbuf) { if (cs->hw.elsa.rcvbuf) { mshutdown(cs); kfree(cs->hw.elsa.rcvbuf); cs->hw.elsa.rcvbuf = NULL; } kfree(cs->hw.elsa.transbuf); cs->hw.elsa.transbuf = NULL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -