⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elsa_ser.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	} 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 + -