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