• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/isdn/hisax/
1/* $Id: elsa_ser.c,v 2.14.2.3 2004/02/11 13:21:33 Exp $
2 *
3 * stuff for the serial modem on ELSA cards
4 *
5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference.
7 *
8 */
9
10#include <linux/serial.h>
11#include <linux/serial_reg.h>
12#include <linux/slab.h>
13
14#define MAX_MODEM_BUF	256
15#define WAKEUP_CHARS	(MAX_MODEM_BUF/2)
16#define RS_ISR_PASS_LIMIT 256
17#define BASE_BAUD ( 1843200 / 16 )
18
19//#define SERIAL_DEBUG_OPEN 1
20//#define SERIAL_DEBUG_INTR 1
21//#define SERIAL_DEBUG_FLOW 1
22#undef SERIAL_DEBUG_OPEN
23#undef SERIAL_DEBUG_INTR
24#undef SERIAL_DEBUG_FLOW
25#undef SERIAL_DEBUG_REG
26//#define SERIAL_DEBUG_REG 1
27
28#ifdef SERIAL_DEBUG_REG
29static u_char deb[32];
30const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
31const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
32#endif
33
34static char *MInit_1 = "AT&F&C1E0&D2\r\0";
35static char *MInit_2 = "ATL2M1S64=13\r\0";
36static char *MInit_3 = "AT+FCLASS=0\r\0";
37static char *MInit_4 = "ATV1S2=128X1\r\0";
38static char *MInit_5 = "AT\\V8\\N3\r\0";
39static char *MInit_6 = "ATL0M0&G0%E1\r\0";
40static char *MInit_7 = "AT%L1%M0%C3\r\0";
41
42static char *MInit_speed28800 = "AT%G0%B28800\r\0";
43
44static char *MInit_dialout = "ATs7=60 x1 d\r\0";
45static char *MInit_dialin = "ATs7=60 x1 a\r\0";
46
47
48static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
49{
50#ifdef SERIAL_DEBUG_REG
51	u_int val = inb(cs->hw.elsa.base + 8 + offset);
52	debugl1(cs,"in   %s %02x",ModemIn[offset], val);
53	return(val);
54#else
55	return inb(cs->hw.elsa.base + 8 + offset);
56#endif
57}
58
59static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
60{
61#ifdef SERIAL_DEBUG_REG
62#ifdef ELSA_SERIAL_NOPAUSE_IO
63	u_int val = inb(cs->hw.elsa.base + 8 + offset);
64	debugl1(cs,"inp  %s %02x",ModemIn[offset], val);
65#else
66	u_int val = inb_p(cs->hw.elsa.base + 8 + offset);
67	debugl1(cs,"inP  %s %02x",ModemIn[offset], val);
68#endif
69	return(val);
70#else
71#ifdef ELSA_SERIAL_NOPAUSE_IO
72	return inb(cs->hw.elsa.base + 8 + offset);
73#else
74	return inb_p(cs->hw.elsa.base + 8 + offset);
75#endif
76#endif
77}
78
79static inline void serial_out(struct IsdnCardState *cs, int offset, int value)
80{
81#ifdef SERIAL_DEBUG_REG
82	debugl1(cs,"out  %s %02x",ModemOut[offset], value);
83#endif
84	outb(value, cs->hw.elsa.base + 8 + offset);
85}
86
87static inline void serial_outp(struct IsdnCardState *cs, int offset,
88			       int value)
89{
90#ifdef SERIAL_DEBUG_REG
91#ifdef ELSA_SERIAL_NOPAUSE_IO
92	debugl1(cs,"outp %s %02x",ModemOut[offset], value);
93#else
94	debugl1(cs,"outP %s %02x",ModemOut[offset], value);
95#endif
96#endif
97#ifdef ELSA_SERIAL_NOPAUSE_IO
98	outb(value, cs->hw.elsa.base + 8 + offset);
99#else
100    	outb_p(value, cs->hw.elsa.base + 8 + offset);
101#endif
102}
103
104/*
105 * This routine is called to set the UART divisor registers to match
106 * the specified baud rate for a serial port.
107 */
108static void change_speed(struct IsdnCardState *cs, int baud)
109{
110	int	quot = 0, baud_base;
111	unsigned cval, fcr = 0;
112	int	bits;
113
114
115	/* byte size and parity */
116	cval = 0x03; bits = 10;
117	/* Determine divisor based on baud rate */
118	baud_base = BASE_BAUD;
119	quot = baud_base / baud;
120	/* If the quotient is ever zero, default to 9600 bps */
121	if (!quot)
122		quot = baud_base / 9600;
123
124	/* Set up FIFO's */
125	if ((baud_base / quot) < 2400)
126		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
127	else
128		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
129	serial_outp(cs, UART_FCR, fcr);
130	/* CTS flow control flag and modem status interrupts */
131	cs->hw.elsa.IER &= ~UART_IER_MSI;
132	cs->hw.elsa.IER |= UART_IER_MSI;
133	serial_outp(cs, UART_IER, cs->hw.elsa.IER);
134
135	debugl1(cs,"modem quot=0x%x", quot);
136	serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
137	serial_outp(cs, UART_DLL, quot & 0xff);		/* LS of divisor */
138	serial_outp(cs, UART_DLM, quot >> 8);		/* MS of divisor */
139	serial_outp(cs, UART_LCR, cval);		/* reset DLAB */
140	serial_inp(cs, UART_RX);
141}
142
143static int mstartup(struct IsdnCardState *cs)
144{
145	int	retval=0;
146
147	/*
148	 * Clear the FIFO buffers and disable them
149	 * (they will be reenabled in change_speed())
150	 */
151	serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
152
153	/*
154	 * At this point there's no way the LSR could still be 0xFF;
155	 * if it is, then bail out, because there's likely no UART
156	 * here.
157	 */
158	if (serial_inp(cs, UART_LSR) == 0xff) {
159		retval = -ENODEV;
160		goto errout;
161	}
162
163	/*
164	 * Clear the interrupt registers.
165	 */
166	(void) serial_inp(cs, UART_RX);
167	(void) serial_inp(cs, UART_IIR);
168	(void) serial_inp(cs, UART_MSR);
169
170	/*
171	 * Now, initialize the UART
172	 */
173	serial_outp(cs, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
174
175	cs->hw.elsa.MCR = 0;
176	cs->hw.elsa.MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
177	serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
178
179	/*
180	 * Finally, enable interrupts
181	 */
182	cs->hw.elsa.IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
183	serial_outp(cs, UART_IER, cs->hw.elsa.IER);	/* enable interrupts */
184
185	/*
186	 * And clear the interrupt registers again for luck.
187	 */
188	(void)serial_inp(cs, UART_LSR);
189	(void)serial_inp(cs, UART_RX);
190	(void)serial_inp(cs, UART_IIR);
191	(void)serial_inp(cs, UART_MSR);
192
193	cs->hw.elsa.transcnt = cs->hw.elsa.transp = 0;
194	cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp =0;
195
196	/*
197	 * and set the speed of the serial port
198	 */
199	change_speed(cs, BASE_BAUD);
200	cs->hw.elsa.MFlag = 1;
201errout:
202	return retval;
203}
204
205/*
206 * This routine will shutdown a serial port; interrupts are disabled, and
207 * DTR is dropped if the hangup on close termio flag is on.
208 */
209static void mshutdown(struct IsdnCardState *cs)
210{
211
212#ifdef SERIAL_DEBUG_OPEN
213	printk(KERN_DEBUG"Shutting down serial ....");
214#endif
215
216	/*
217	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
218	 * here so the queue might never be waken up
219	 */
220
221	cs->hw.elsa.IER = 0;
222	serial_outp(cs, UART_IER, 0x00);	/* disable all intrs */
223	cs->hw.elsa.MCR &= ~UART_MCR_OUT2;
224
225	/* disable break condition */
226	serial_outp(cs, UART_LCR, serial_inp(cs, UART_LCR) & ~UART_LCR_SBC);
227
228	cs->hw.elsa.MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
229	serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
230
231	/* disable FIFO's */
232	serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
233	serial_inp(cs, UART_RX);    /* read data port to reset things */
234
235#ifdef SERIAL_DEBUG_OPEN
236	printk(" done\n");
237#endif
238}
239
240static inline int
241write_modem(struct BCState *bcs) {
242	int ret=0;
243	struct IsdnCardState *cs = bcs->cs;
244	int count, len, fp;
245
246	if (!bcs->tx_skb)
247		return 0;
248	if (bcs->tx_skb->len <= 0)
249		return 0;
250	len = bcs->tx_skb->len;
251	if (len > MAX_MODEM_BUF - cs->hw.elsa.transcnt)
252		len = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
253	fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
254	fp &= (MAX_MODEM_BUF -1);
255	count = len;
256	if (count > MAX_MODEM_BUF - fp) {
257		count = MAX_MODEM_BUF - fp;
258		skb_copy_from_linear_data(bcs->tx_skb,
259					  cs->hw.elsa.transbuf + fp, count);
260		skb_pull(bcs->tx_skb, count);
261		cs->hw.elsa.transcnt += count;
262		ret = count;
263		count = len - count;
264		fp = 0;
265	}
266	skb_copy_from_linear_data(bcs->tx_skb,
267				  cs->hw.elsa.transbuf + fp, count);
268	skb_pull(bcs->tx_skb, count);
269	cs->hw.elsa.transcnt += count;
270	ret += count;
271
272	if (cs->hw.elsa.transcnt &&
273	    !(cs->hw.elsa.IER & UART_IER_THRI)) {
274			cs->hw.elsa.IER |= UART_IER_THRI;
275		serial_outp(cs, UART_IER, cs->hw.elsa.IER);
276	}
277	return(ret);
278}
279
280static inline void
281modem_fill(struct BCState *bcs) {
282
283	if (bcs->tx_skb) {
284		if (bcs->tx_skb->len) {
285			write_modem(bcs);
286			return;
287		} else {
288			if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
289				(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
290				u_long	flags;
291				spin_lock_irqsave(&bcs->aclock, flags);
292				bcs->ackcnt += bcs->hw.hscx.count;
293				spin_unlock_irqrestore(&bcs->aclock, flags);
294				schedule_event(bcs, B_ACKPENDING);
295			}
296			dev_kfree_skb_any(bcs->tx_skb);
297			bcs->tx_skb = NULL;
298		}
299	}
300	if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
301		bcs->hw.hscx.count = 0;
302		test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
303		write_modem(bcs);
304	} else {
305		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
306		schedule_event(bcs, B_XMTBUFREADY);
307	}
308}
309
310static inline void receive_chars(struct IsdnCardState *cs,
311				 int *status)
312{
313	unsigned char ch;
314	struct sk_buff *skb;
315
316	do {
317		ch = serial_in(cs, UART_RX);
318		if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF)
319			break;
320		cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch;
321#ifdef SERIAL_DEBUG_INTR
322		printk("DR%02x:%02x...", ch, *status);
323#endif
324		if (*status & (UART_LSR_BI | UART_LSR_PE |
325			       UART_LSR_FE | UART_LSR_OE)) {
326
327#ifdef SERIAL_DEBUG_INTR
328			printk("handling exept....");
329#endif
330		}
331		*status = serial_inp(cs, UART_LSR);
332	} while (*status & UART_LSR_DR);
333	if (cs->hw.elsa.MFlag == 2) {
334		if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
335			printk(KERN_WARNING "ElsaSER: receive out of memory\n");
336		else {
337			memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf,
338				cs->hw.elsa.rcvcnt);
339			skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb);
340		}
341		schedule_event(cs->hw.elsa.bcs, B_RCVBUFREADY);
342	} else {
343		char tmp[128];
344		char *t = tmp;
345
346		t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt);
347		QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt);
348		debugl1(cs, tmp);
349	}
350	cs->hw.elsa.rcvcnt = 0;
351}
352
353static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
354{
355	int count;
356
357	debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp,
358		cs->hw.elsa.transcnt);
359
360	if (cs->hw.elsa.transcnt <= 0) {
361		cs->hw.elsa.IER &= ~UART_IER_THRI;
362		serial_out(cs, UART_IER, cs->hw.elsa.IER);
363		return;
364	}
365	count = 16;
366	do {
367		serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
368		if (cs->hw.elsa.transp >= MAX_MODEM_BUF)
369			cs->hw.elsa.transp=0;
370		if (--cs->hw.elsa.transcnt <= 0)
371			break;
372	} while (--count > 0);
373	if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2))
374		modem_fill(cs->hw.elsa.bcs);
375
376#ifdef SERIAL_DEBUG_INTR
377	printk("THRE...");
378#endif
379	if (intr_done)
380		*intr_done = 0;
381	if (cs->hw.elsa.transcnt <= 0) {
382		cs->hw.elsa.IER &= ~UART_IER_THRI;
383		serial_outp(cs, UART_IER, cs->hw.elsa.IER);
384	}
385}
386
387
388static void rs_interrupt_elsa(struct IsdnCardState *cs)
389{
390	int status, iir, msr;
391	int pass_counter = 0;
392
393#ifdef SERIAL_DEBUG_INTR
394	printk(KERN_DEBUG "rs_interrupt_single(%d)...", cs->irq);
395#endif
396
397	do {
398		status = serial_inp(cs, UART_LSR);
399		debugl1(cs,"rs LSR %02x", status);
400#ifdef SERIAL_DEBUG_INTR
401		printk("status = %x...", status);
402#endif
403		if (status & UART_LSR_DR)
404			receive_chars(cs, &status);
405		if (status & UART_LSR_THRE)
406			transmit_chars(cs, NULL);
407		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
408			printk("rs_single loop break.\n");
409			break;
410		}
411		iir = serial_inp(cs, UART_IIR);
412		debugl1(cs,"rs IIR %02x", iir);
413		if ((iir & 0xf) == 0) {
414			msr = serial_inp(cs, UART_MSR);
415			debugl1(cs,"rs MSR %02x", msr);
416		}
417	} while (!(iir & UART_IIR_NO_INT));
418#ifdef SERIAL_DEBUG_INTR
419	printk("end.\n");
420#endif
421}
422
423extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
424extern void modehscx(struct BCState *bcs, int mode, int bc);
425extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
426
427static void
428close_elsastate(struct BCState *bcs)
429{
430	modehscx(bcs, 0, bcs->channel);
431	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
432		if (bcs->hw.hscx.rcvbuf) {
433			if (bcs->mode != L1_MODE_MODEM)
434				kfree(bcs->hw.hscx.rcvbuf);
435			bcs->hw.hscx.rcvbuf = NULL;
436		}
437		skb_queue_purge(&bcs->rqueue);
438		skb_queue_purge(&bcs->squeue);
439		if (bcs->tx_skb) {
440			dev_kfree_skb_any(bcs->tx_skb);
441			bcs->tx_skb = NULL;
442			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
443		}
444	}
445}
446
447static void
448modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
449	int count, fp;
450	u_char *msg = buf;
451
452	if (!len)
453		return;
454	if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) {
455		return;
456	}
457	fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
458	fp &= (MAX_MODEM_BUF -1);
459	count = len;
460	if (count > MAX_MODEM_BUF - fp) {
461		count = MAX_MODEM_BUF - fp;
462		memcpy(cs->hw.elsa.transbuf + fp, msg, count);
463		cs->hw.elsa.transcnt += count;
464		msg += count;
465		count = len - count;
466		fp = 0;
467	}
468	memcpy(cs->hw.elsa.transbuf + fp, msg, count);
469	cs->hw.elsa.transcnt += count;
470	if (cs->hw.elsa.transcnt &&
471	    !(cs->hw.elsa.IER & UART_IER_THRI)) {
472		cs->hw.elsa.IER |= UART_IER_THRI;
473		serial_outp(cs, UART_IER, cs->hw.elsa.IER);
474	}
475}
476
477static void
478modem_set_init(struct IsdnCardState *cs) {
479	int timeout;
480
481#define RCV_DELAY 20
482	modem_write_cmd(cs, MInit_1, strlen(MInit_1));
483	timeout = 1000;
484	while(timeout-- && cs->hw.elsa.transcnt)
485		udelay(1000);
486	debugl1(cs, "msi tout=%d", timeout);
487	mdelay(RCV_DELAY);
488	modem_write_cmd(cs, MInit_2, strlen(MInit_2));
489	timeout = 1000;
490	while(timeout-- && cs->hw.elsa.transcnt)
491		udelay(1000);
492	debugl1(cs, "msi tout=%d", timeout);
493	mdelay(RCV_DELAY);
494	modem_write_cmd(cs, MInit_3, strlen(MInit_3));
495	timeout = 1000;
496	while(timeout-- && cs->hw.elsa.transcnt)
497		udelay(1000);
498	debugl1(cs, "msi tout=%d", timeout);
499	mdelay(RCV_DELAY);
500	modem_write_cmd(cs, MInit_4, strlen(MInit_4));
501	timeout = 1000;
502	while(timeout-- && cs->hw.elsa.transcnt)
503		udelay(1000);
504	debugl1(cs, "msi tout=%d", timeout);
505	mdelay(RCV_DELAY);
506	modem_write_cmd(cs, MInit_5, strlen(MInit_5));
507	timeout = 1000;
508	while(timeout-- && cs->hw.elsa.transcnt)
509		udelay(1000);
510	debugl1(cs, "msi tout=%d", timeout);
511	mdelay(RCV_DELAY);
512	modem_write_cmd(cs, MInit_6, strlen(MInit_6));
513	timeout = 1000;
514	while(timeout-- && cs->hw.elsa.transcnt)
515		udelay(1000);
516	debugl1(cs, "msi tout=%d", timeout);
517	mdelay(RCV_DELAY);
518	modem_write_cmd(cs, MInit_7, strlen(MInit_7));
519	timeout = 1000;
520	while(timeout-- && cs->hw.elsa.transcnt)
521		udelay(1000);
522	debugl1(cs, "msi tout=%d", timeout);
523	mdelay(RCV_DELAY);
524}
525
526static void
527modem_set_dial(struct IsdnCardState *cs, int outgoing) {
528	int timeout;
529#define RCV_DELAY 20
530
531	modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
532	timeout = 1000;
533	while(timeout-- && cs->hw.elsa.transcnt)
534		udelay(1000);
535	debugl1(cs, "msi tout=%d", timeout);
536	mdelay(RCV_DELAY);
537	if (outgoing)
538		modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
539	else
540		modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
541	timeout = 1000;
542	while(timeout-- && cs->hw.elsa.transcnt)
543		udelay(1000);
544	debugl1(cs, "msi tout=%d", timeout);
545	mdelay(RCV_DELAY);
546}
547
548static void
549modem_l2l1(struct PStack *st, int pr, void *arg)
550{
551	struct BCState *bcs = st->l1.bcs;
552	struct sk_buff *skb = arg;
553	u_long flags;
554
555	if (pr == (PH_DATA | REQUEST)) {
556		spin_lock_irqsave(&bcs->cs->lock, flags);
557		if (bcs->tx_skb) {
558			skb_queue_tail(&bcs->squeue, skb);
559		} else {
560			bcs->tx_skb = skb;
561			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
562			bcs->hw.hscx.count = 0;
563			write_modem(bcs);
564		}
565		spin_unlock_irqrestore(&bcs->cs->lock, flags);
566	} else if (pr == (PH_ACTIVATE | REQUEST)) {
567		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
568		st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
569		set_arcofi(bcs->cs, st->l1.bc);
570		mstartup(bcs->cs);
571		modem_set_dial(bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
572		bcs->cs->hw.elsa.MFlag=2;
573	} else if (pr == (PH_DEACTIVATE | REQUEST)) {
574		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
575		bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
576		arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0);
577		interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait);
578		bcs->cs->hw.elsa.MFlag=1;
579	} else {
580		printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
581	}
582}
583
584static int
585setstack_elsa(struct PStack *st, struct BCState *bcs)
586{
587
588	bcs->channel = st->l1.bc;
589	switch (st->l1.mode) {
590		case L1_MODE_HDLC:
591		case L1_MODE_TRANS:
592			if (open_hscxstate(st->l1.hardware, bcs))
593				return (-1);
594			st->l2.l2l1 = hscx_l2l1;
595			break;
596		case L1_MODE_MODEM:
597			bcs->mode = L1_MODE_MODEM;
598			if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
599				bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
600				skb_queue_head_init(&bcs->rqueue);
601				skb_queue_head_init(&bcs->squeue);
602			}
603			bcs->tx_skb = NULL;
604			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
605			bcs->event = 0;
606			bcs->hw.hscx.rcvidx = 0;
607			bcs->tx_cnt = 0;
608			bcs->cs->hw.elsa.bcs = bcs;
609			st->l2.l2l1 = modem_l2l1;
610			break;
611	}
612	st->l1.bcs = bcs;
613	setstack_manager(st);
614	bcs->st = st;
615	setstack_l1_B(st);
616	return (0);
617}
618
619static void
620init_modem(struct IsdnCardState *cs) {
621
622	cs->bcs[0].BC_SetStack = setstack_elsa;
623	cs->bcs[1].BC_SetStack = setstack_elsa;
624	cs->bcs[0].BC_Close = close_elsastate;
625	cs->bcs[1].BC_Close = close_elsastate;
626	if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
627		GFP_ATOMIC))) {
628		printk(KERN_WARNING
629			"Elsa: No modem mem hw.elsa.rcvbuf\n");
630		return;
631	}
632	if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF,
633		GFP_ATOMIC))) {
634		printk(KERN_WARNING
635			"Elsa: No modem mem hw.elsa.transbuf\n");
636		kfree(cs->hw.elsa.rcvbuf);
637		cs->hw.elsa.rcvbuf = NULL;
638		return;
639	}
640	if (mstartup(cs)) {
641		printk(KERN_WARNING "Elsa: problem startup modem\n");
642	}
643	modem_set_init(cs);
644}
645
646static void
647release_modem(struct IsdnCardState *cs) {
648
649	cs->hw.elsa.MFlag = 0;
650	if (cs->hw.elsa.transbuf) {
651		if (cs->hw.elsa.rcvbuf) {
652			mshutdown(cs);
653			kfree(cs->hw.elsa.rcvbuf);
654			cs->hw.elsa.rcvbuf = NULL;
655		}
656		kfree(cs->hw.elsa.transbuf);
657		cs->hw.elsa.transbuf = NULL;
658	}
659}
660