📄 elsa_ser.c
字号:
} while (*status & UART_LSR_DR); if (cs->hw.elsa.MFlag == 2) { if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt))) printk(KERN_WARNING "ElsaSER: receive out of memory\n"); else { memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt); skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb); } schedule_event(cs->hw.elsa.bcs, B_RCVBUFREADY); } else { char tmp[128]; char *t = tmp; t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt); QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt); debugl1(cs, tmp); } cs->hw.elsa.rcvcnt = 0;}static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done){ int count; debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp, cs->hw.elsa.transcnt); if (cs->hw.elsa.transcnt <= 0) { cs->hw.elsa.IER &= ~UART_IER_THRI; serial_out(cs, UART_IER, cs->hw.elsa.IER); return; } count = 16; do { serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]); if (cs->hw.elsa.transp >= MAX_MODEM_BUF) cs->hw.elsa.transp=0; if (--cs->hw.elsa.transcnt <= 0) break; } 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); }}static 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, NULL); 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);static voidclose_elsastate(struct BCState *bcs){ 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; } skb_queue_purge(&bcs->rqueue); skb_queue_purge(&bcs->squeue); if (bcs->tx_skb) { dev_kfree_skb_any(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } }}static voidmodem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { int count, fp; u_char *msg = buf; if (!len) return; if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) { return; } fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp; fp &= (MAX_MODEM_BUF -1); count = len; if (count > MAX_MODEM_BUF - fp) { count = MAX_MODEM_BUF - fp; 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); }}static voidmodem_set_init(struct IsdnCardState *cs) { int timeout;#define RCV_DELAY 20000 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);}static voidmodem_set_dial(struct IsdnCardState *cs, int outgoing) { int timeout;#define RCV_DELAY 20000 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);}static voidmodem_l2l1(struct PStack *st, int pr, void *arg){ struct BCState *bcs = st->l1.bcs; struct sk_buff *skb = arg; u_long flags; if (pr == (PH_DATA | REQUEST)) { spin_lock_irqsave(&bcs->cs->lock, flags); if (bcs->tx_skb) { skb_queue_tail(&bcs->squeue, skb); } else { bcs->tx_skb = skb; test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); bcs->hw.hscx.count = 0; write_modem(bcs); } spin_unlock_irqrestore(&bcs->cs->lock, flags); } else if (pr == (PH_ACTIVATE | REQUEST)) { test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); set_arcofi(bcs->cs, st->l1.bc); mstartup(bcs->cs); modem_set_dial(bcs->cs, test_bit(FLG_ORIG, &st->l2.flag)); bcs->cs->hw.elsa.MFlag=2; } else if (pr == (PH_DEACTIVATE | REQUEST)) { test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); bcs->cs->dc.isac.arcofi_bc = st->l1.bc; arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0); interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait); bcs->cs->hw.elsa.MFlag=1; } else { printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr); }}static 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);}static 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);}static 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 + -