1 /* $Id: isdn_tty.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
2  *
3  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
4  *
5  * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
6  * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
7  *
8  * This software may be used and distributed according to the terms
9  * of the GNU General Public License, incorporated herein by reference.
10  *
11  */
12 #undef ISDN_TTY_STAT_DEBUG
13 
14 #include <linux/config.h>
15 #include <linux/isdn.h>
16 #include "isdn_common.h"
17 #include "isdn_tty.h"
18 #ifdef CONFIG_ISDN_AUDIO
19 #include "isdn_audio.h"
20 #define VBUF 0x3e0
21 #define VBUFX (VBUF/16)
22 #endif
23 
24 #define FIX_FILE_TRANSFER
25 #define	DUMMY_HAYES_AT
26 
27 /* Prototypes */
28 
29 static int isdn_tty_edit_at(const char *, int, modem_info *, int);
30 static void isdn_tty_check_esc(const u_char *, u_char, int, int *, int *, int);
31 static void isdn_tty_modem_reset_regs(modem_info *, int);
32 static void isdn_tty_cmd_ATA(modem_info *);
33 static void isdn_tty_flush_buffer(struct tty_struct *);
34 static void isdn_tty_modem_result(int, modem_info *);
35 #ifdef CONFIG_ISDN_AUDIO
36 static int isdn_tty_countDLE(unsigned char *, int);
37 #endif
38 
39 /* Leave this unchanged unless you know what you do! */
40 #define MODEM_PARANOIA_CHECK
41 #define MODEM_DO_RESTART
42 
43 #ifdef CONFIG_DEVFS_FS
44 static char *isdn_ttyname_ttyI = "isdn/ttyI%d";
45 static char *isdn_ttyname_cui = "isdn/cui%d";
46 #else
47 static char *isdn_ttyname_ttyI = "ttyI";
48 static char *isdn_ttyname_cui = "cui";
49 #endif
50 
51 static int bit2si[8] =
52 {1, 5, 7, 7, 7, 7, 7, 7};
53 static int si2bit[8] =
54 {4, 1, 4, 4, 4, 4, 4, 4};
55 
56 char *isdn_tty_revision = "$Revision: 1.1.4.1 $";
57 
58 
59 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
60  * to stuff incoming data directly into a tty's flip-buffer. This
61  * is done to speed up tty-receiving if the receive-queue is empty.
62  * This routine MUST be called with interrupts off.
63  * Return:
64  *  1 = Success
65  *  0 = Failure, data has to be buffered and later processed by
66  *      isdn_tty_readmodem().
67  */
68 static int
isdn_tty_try_read(modem_info * info,struct sk_buff * skb)69 isdn_tty_try_read(modem_info * info, struct sk_buff *skb)
70 {
71 	int c;
72 	int len;
73 	struct tty_struct *tty;
74 
75 	if (info->online) {
76 		if ((tty = info->tty)) {
77 			if (info->mcr & UART_MCR_RTS) {
78 				c = TTY_FLIPBUF_SIZE - tty->flip.count;
79 				len = skb->len
80 #ifdef CONFIG_ISDN_AUDIO
81 					+ ISDN_AUDIO_SKB_DLECOUNT(skb)
82 #endif
83 					;
84 				if (c >= len) {
85 #ifdef CONFIG_ISDN_AUDIO
86 					if (ISDN_AUDIO_SKB_DLECOUNT(skb))
87 						while (skb->len--) {
88 							if (*skb->data == DLE)
89 								tty_insert_flip_char(tty, DLE, 0);
90 							tty_insert_flip_char(tty, *skb->data++, 0);
91 					} else {
92 #endif
93 						memcpy(tty->flip.char_buf_ptr,
94 						       skb->data, len);
95 						tty->flip.count += len;
96 						tty->flip.char_buf_ptr += len;
97 						memset(tty->flip.flag_buf_ptr, 0, len);
98 						tty->flip.flag_buf_ptr += len;
99 #ifdef CONFIG_ISDN_AUDIO
100 					}
101 #endif
102 					if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP)
103 						tty->flip.flag_buf_ptr[len - 1] = 0xff;
104 					queue_task(&tty->flip.tqueue, &tq_timer);
105 					kfree_skb(skb);
106 					return 1;
107 				}
108 			}
109 		}
110 	}
111 	return 0;
112 }
113 
114 /* isdn_tty_readmodem() is called periodically from within timer-interrupt.
115  * It tries getting received data from the receive queue an stuff it into
116  * the tty's flip-buffer.
117  */
118 void
isdn_tty_readmodem(void)119 isdn_tty_readmodem(void)
120 {
121 	int resched = 0;
122 	int midx;
123 	int i;
124 	int c;
125 	int r;
126 	ulong flags;
127 	struct tty_struct *tty;
128 	modem_info *info;
129 
130 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
131 		if ((midx = dev->m_idx[i]) >= 0) {
132 			info = &dev->mdm.info[midx];
133 			if (info->online) {
134 				r = 0;
135 #ifdef CONFIG_ISDN_AUDIO
136 				isdn_audio_eval_dtmf(info);
137 				if ((info->vonline & 1) && (info->emu.vpar[1]))
138 					isdn_audio_eval_silence(info);
139 #endif
140 				if ((tty = info->tty)) {
141 					if (info->mcr & UART_MCR_RTS) {
142 						c = TTY_FLIPBUF_SIZE - tty->flip.count;
143 						if (c > 0) {
144 							save_flags(flags);
145 							cli();
146 							r = isdn_readbchan(info->isdn_driver, info->isdn_channel,
147 									   tty->flip.char_buf_ptr,
148 									   tty->flip.flag_buf_ptr, c, 0);
149 							/* CISCO AsyncPPP Hack */
150 							if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
151 								memset(tty->flip.flag_buf_ptr, 0, r);
152 							tty->flip.count += r;
153 							tty->flip.flag_buf_ptr += r;
154 							tty->flip.char_buf_ptr += r;
155 							if (r)
156 								queue_task(&tty->flip.tqueue, &tq_timer);
157 							restore_flags(flags);
158 						}
159 					} else
160 						r = 1;
161 				} else
162 					r = 1;
163 				if (r) {
164 					info->rcvsched = 0;
165 					resched = 1;
166 				} else
167 					info->rcvsched = 1;
168 			}
169 		}
170 	}
171 	if (!resched)
172 		isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 0);
173 }
174 
175 int
isdn_tty_rcv_skb(int i,int di,int channel,struct sk_buff * skb)176 isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
177 {
178 	ulong flags;
179 	int midx;
180 #ifdef CONFIG_ISDN_AUDIO
181 	int ifmt;
182 #endif
183 	modem_info *info;
184 
185 	if ((midx = dev->m_idx[i]) < 0) {
186 		/* if midx is invalid, packet is not for tty */
187 		return 0;
188 	}
189 	info = &dev->mdm.info[midx];
190 #ifdef CONFIG_ISDN_AUDIO
191 	ifmt = 1;
192 
193 	if ((info->vonline) && (!info->emu.vpar[4]))
194 		isdn_audio_calc_dtmf(info, skb->data, skb->len, ifmt);
195 	if ((info->vonline & 1) && (info->emu.vpar[1]))
196 		isdn_audio_calc_silence(info, skb->data, skb->len, ifmt);
197 #endif
198 	if ((info->online < 2)
199 #ifdef CONFIG_ISDN_AUDIO
200 	    && (!(info->vonline & 1))
201 #endif
202 		) {
203 		/* If Modem not listening, drop data */
204 		kfree_skb(skb);
205 		return 1;
206 	}
207 	if (info->emu.mdmreg[REG_T70] & BIT_T70) {
208 		if (info->emu.mdmreg[REG_T70] & BIT_T70_EXT) {
209 			/* T.70 decoding: throw away the T.70 header (2 or 4 bytes)   */
210 			if (skb->data[0] == 3) /* pure data packet -> 4 byte headers  */
211 				skb_pull(skb, 4);
212 			else
213 				if (skb->data[0] == 1) /* keepalive packet -> 2 byte hdr  */
214 					skb_pull(skb, 2);
215 		} else
216 			/* T.70 decoding: Simply throw away the T.70 header (4 bytes) */
217 			if ((skb->data[0] == 1) && ((skb->data[1] == 0) || (skb->data[1] == 1)))
218 				skb_pull(skb, 4);
219 	}
220 #ifdef CONFIG_ISDN_AUDIO
221 	if (skb_headroom(skb) < sizeof(isdn_audio_skb)) {
222 		printk(KERN_WARNING
223 		       "isdn_audio: insufficient skb_headroom, dropping\n");
224 		kfree_skb(skb);
225 		return 1;
226 	}
227 	ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
228 	ISDN_AUDIO_SKB_LOCK(skb) = 0;
229 	if (info->vonline & 1) {
230 		/* voice conversion/compression */
231 		switch (info->emu.vpar[3]) {
232 			case 2:
233 			case 3:
234 			case 4:
235 				/* adpcm
236 				 * Since compressed data takes less
237 				 * space, we can overwrite the buffer.
238 				 */
239 				skb_trim(skb, isdn_audio_xlaw2adpcm(info->adpcmr,
240 								    ifmt,
241 								    skb->data,
242 								    skb->data,
243 								    skb->len));
244 				break;
245 			case 5:
246 				/* a-law */
247 				if (!ifmt)
248 					isdn_audio_ulaw2alaw(skb->data, skb->len);
249 				break;
250 			case 6:
251 				/* u-law */
252 				if (ifmt)
253 					isdn_audio_alaw2ulaw(skb->data, skb->len);
254 				break;
255 		}
256 		ISDN_AUDIO_SKB_DLECOUNT(skb) =
257 			isdn_tty_countDLE(skb->data, skb->len);
258 	}
259 #ifdef CONFIG_ISDN_TTY_FAX
260 	else {
261 		if (info->faxonline & 2) {
262 			isdn_tty_fax_bitorder(info, skb);
263 			ISDN_AUDIO_SKB_DLECOUNT(skb) =
264 				isdn_tty_countDLE(skb->data, skb->len);
265 		}
266 	}
267 #endif
268 #endif
269 	/* Try to deliver directly via tty-flip-buf if queue is empty */
270 	save_flags(flags);
271 	cli();
272 	if (skb_queue_empty(&dev->drv[di]->rpqueue[channel]))
273 		if (isdn_tty_try_read(info, skb)) {
274 			restore_flags(flags);
275 			return 1;
276 		}
277 	/* Direct deliver failed or queue wasn't empty.
278 	 * Queue up for later dequeueing via timer-irq.
279 	 */
280 	__skb_queue_tail(&dev->drv[di]->rpqueue[channel], skb);
281 	dev->drv[di]->rcvcount[channel] +=
282 		(skb->len
283 #ifdef CONFIG_ISDN_AUDIO
284 		 + ISDN_AUDIO_SKB_DLECOUNT(skb)
285 #endif
286 			);
287 	restore_flags(flags);
288 	/* Schedule dequeuing */
289 	if ((dev->modempoll) && (info->rcvsched))
290 		isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
291 	return 1;
292 }
293 
294 void
isdn_tty_cleanup_xmit(modem_info * info)295 isdn_tty_cleanup_xmit(modem_info * info)
296 {
297 	unsigned long flags;
298 
299 	save_flags(flags);
300 	cli();
301 	skb_queue_purge(&info->xmit_queue);
302 #ifdef CONFIG_ISDN_AUDIO
303 	skb_queue_purge(&info->dtmf_queue);
304 #endif
305 	restore_flags(flags);
306 }
307 
308 static void
isdn_tty_tint(modem_info * info)309 isdn_tty_tint(modem_info * info)
310 {
311 	struct sk_buff *skb = skb_dequeue(&info->xmit_queue);
312 	int len,
313 	 slen;
314 
315 	if (!skb)
316 		return;
317 	len = skb->len;
318 	if ((slen = isdn_writebuf_skb_stub(info->isdn_driver,
319 					   info->isdn_channel, 1, skb)) == len) {
320 		struct tty_struct *tty = info->tty;
321 		info->send_outstanding++;
322 		info->msr &= ~UART_MSR_CTS;
323 		info->lsr &= ~UART_LSR_TEMT;
324 		tty_wakeup(tty);
325 		return;
326 	}
327 	if (slen < 0) {
328 		/* Error: no channel, already shutdown, or wrong parameter */
329 		dev_kfree_skb(skb);
330 		return;
331 	}
332 	skb_queue_head(&info->xmit_queue, skb);
333 }
334 
335 #ifdef CONFIG_ISDN_AUDIO
336 static int
isdn_tty_countDLE(unsigned char * buf,int len)337 isdn_tty_countDLE(unsigned char *buf, int len)
338 {
339 	int count = 0;
340 
341 	while (len--)
342 		if (*buf++ == DLE)
343 			count++;
344 	return count;
345 }
346 
347 /* This routine is called from within isdn_tty_write() to perform
348  * DLE-decoding when sending audio-data.
349  */
350 static int
isdn_tty_handleDLEdown(modem_info * info,atemu * m,int len)351 isdn_tty_handleDLEdown(modem_info * info, atemu * m, int len)
352 {
353 	unsigned char *p = &info->xmit_buf[info->xmit_count];
354 	int count = 0;
355 
356 	while (len > 0) {
357 		if (m->lastDLE) {
358 			m->lastDLE = 0;
359 			switch (*p) {
360 				case DLE:
361 					/* Escape code */
362 					if (len > 1)
363 						memmove(p, p + 1, len - 1);
364 					p--;
365 					count++;
366 					break;
367 				case ETX:
368 					/* End of data */
369 					info->vonline |= 4;
370 					return count;
371 				case DC4:
372 					/* Abort RX */
373 					info->vonline &= ~1;
374 #ifdef ISDN_DEBUG_MODEM_VOICE
375 					printk(KERN_DEBUG
376 					       "DLEdown: got DLE-DC4, send DLE-ETX on ttyI%d\n",
377 					       info->line);
378 #endif
379 					isdn_tty_at_cout("\020\003", info);
380 					if (!info->vonline) {
381 #ifdef ISDN_DEBUG_MODEM_VOICE
382 						printk(KERN_DEBUG
383 						       "DLEdown: send VCON on ttyI%d\n",
384 						       info->line);
385 #endif
386 						isdn_tty_at_cout("\r\nVCON\r\n", info);
387 					}
388 					/* Fall through */
389 				case 'q':
390 				case 's':
391 					/* Silence */
392 					if (len > 1)
393 						memmove(p, p + 1, len - 1);
394 					p--;
395 					break;
396 			}
397 		} else {
398 			if (*p == DLE)
399 				m->lastDLE = 1;
400 			else
401 				count++;
402 		}
403 		p++;
404 		len--;
405 	}
406 	if (len < 0) {
407 		printk(KERN_WARNING "isdn_tty: len<0 in DLEdown\n");
408 		return 0;
409 	}
410 	return count;
411 }
412 
413 /* This routine is called from within isdn_tty_write() when receiving
414  * audio-data. It interrupts receiving, if an character other than
415  * ^S or ^Q is sent.
416  */
417 static int
isdn_tty_end_vrx(const char * buf,int c,int from_user)418 isdn_tty_end_vrx(const char *buf, int c, int from_user)
419 {
420 	char ch;
421 
422 	while (c--) {
423 		if (from_user)
424 			get_user(ch, buf);
425 		else
426 			ch = *buf;
427 		if ((ch != 0x11) && (ch != 0x13))
428 			return 1;
429 		buf++;
430 	}
431 	return 0;
432 }
433 
434 static int voice_cf[7] =
435 {0, 0, 4, 3, 2, 0, 0};
436 
437 #endif                          /* CONFIG_ISDN_AUDIO */
438 
439 /* isdn_tty_senddown() is called either directly from within isdn_tty_write()
440  * or via timer-interrupt from within isdn_tty_modem_xmit(). It pulls
441  * outgoing data from the tty's xmit-buffer, handles voice-decompression or
442  * T.70 if necessary, and finally queues it up for sending via isdn_tty_tint.
443  */
444 static void
isdn_tty_senddown(modem_info * info)445 isdn_tty_senddown(modem_info * info)
446 {
447 	int buflen;
448 	int skb_res;
449 #ifdef CONFIG_ISDN_AUDIO
450 	int audio_len;
451 #endif
452 	struct sk_buff *skb;
453 
454 #ifdef CONFIG_ISDN_AUDIO
455 	if (info->vonline & 4) {
456 		info->vonline &= ~6;
457 		if (!info->vonline) {
458 #ifdef ISDN_DEBUG_MODEM_VOICE
459 			printk(KERN_DEBUG
460 			       "senddown: send VCON on ttyI%d\n",
461 			       info->line);
462 #endif
463 			isdn_tty_at_cout("\r\nVCON\r\n", info);
464 		}
465 	}
466 #endif
467 	if (!(buflen = info->xmit_count))
468 		return;
469  	if ((info->emu.mdmreg[REG_CTS] & BIT_CTS) != 0)
470 		info->msr &= ~UART_MSR_CTS;
471 	info->lsr &= ~UART_LSR_TEMT;
472 	/* info->xmit_count is modified here and in isdn_tty_write().
473 	 * So we return here if isdn_tty_write() is in the
474 	 * critical section.
475 	 */
476 	atomic_inc(&info->xmit_lock);
477 	if (!(atomic_dec_and_test(&info->xmit_lock)))
478 		return;
479 	if (info->isdn_driver < 0) {
480 		info->xmit_count = 0;
481 		return;
482 	}
483 	skb_res = dev->drv[info->isdn_driver]->interface->hl_hdrlen + 4;
484 #ifdef CONFIG_ISDN_AUDIO
485 	if (info->vonline & 2)
486 		audio_len = buflen * voice_cf[info->emu.vpar[3]];
487 	else
488 		audio_len = 0;
489 	skb = dev_alloc_skb(skb_res + buflen + audio_len);
490 #else
491 	skb = dev_alloc_skb(skb_res + buflen);
492 #endif
493 	if (!skb) {
494 		printk(KERN_WARNING
495 		       "isdn_tty: Out of memory in ttyI%d senddown\n",
496 		       info->line);
497 		return;
498 	}
499 	skb_reserve(skb, skb_res);
500 	memcpy(skb_put(skb, buflen), info->xmit_buf, buflen);
501 	info->xmit_count = 0;
502 #ifdef CONFIG_ISDN_AUDIO
503 	if (info->vonline & 2) {
504 		/* For now, ifmt is fixed to 1 (alaw), since this
505 		 * is used with ISDN everywhere in the world, except
506 		 * US, Canada and Japan.
507 		 * Later, when US-ISDN protocols are implemented,
508 		 * this setting will depend on the D-channel protocol.
509 		 */
510 		int ifmt = 1;
511 
512 		/* voice conversion/decompression */
513 		switch (info->emu.vpar[3]) {
514 			case 2:
515 			case 3:
516 			case 4:
517 				/* adpcm, compatible to ZyXel 1496 modem
518 				 * with ROM revision 6.01
519 				 */
520 				audio_len = isdn_audio_adpcm2xlaw(info->adpcms,
521 								  ifmt,
522 								  skb->data,
523 						    skb_put(skb, audio_len),
524 								  buflen);
525 				skb_pull(skb, buflen);
526 				skb_trim(skb, audio_len);
527 				break;
528 			case 5:
529 				/* a-law */
530 				if (!ifmt)
531 					isdn_audio_alaw2ulaw(skb->data,
532 							     buflen);
533 				break;
534 			case 6:
535 				/* u-law */
536 				if (ifmt)
537 					isdn_audio_ulaw2alaw(skb->data,
538 							     buflen);
539 				break;
540 		}
541 	}
542 #endif                          /* CONFIG_ISDN_AUDIO */
543 	if (info->emu.mdmreg[REG_T70] & BIT_T70) {
544 		/* Add T.70 simplified header */
545 		if (info->emu.mdmreg[REG_T70] & BIT_T70_EXT)
546 			memcpy(skb_push(skb, 2), "\1\0", 2);
547 		else
548 			memcpy(skb_push(skb, 4), "\1\0\1\0", 4);
549 	}
550 	skb_queue_tail(&info->xmit_queue, skb);
551 }
552 
553 /************************************************************
554  *
555  * Modem-functions
556  *
557  * mostly "stolen" from original Linux-serial.c and friends.
558  *
559  ************************************************************/
560 
561 /* The next routine is called once from within timer-interrupt
562  * triggered within isdn_tty_modem_ncarrier(). It calls
563  * isdn_tty_modem_result() to stuff a "NO CARRIER" Message
564  * into the tty's flip-buffer.
565  */
566 static void
isdn_tty_modem_do_ncarrier(unsigned long data)567 isdn_tty_modem_do_ncarrier(unsigned long data)
568 {
569 	modem_info *info = (modem_info *) data;
570 	isdn_tty_modem_result(RESULT_NO_CARRIER, info);
571 }
572 
573 /* Next routine is called, whenever the DTR-signal is raised.
574  * It checks the ncarrier-flag, and triggers the above routine
575  * when necessary. The ncarrier-flag is set, whenever DTR goes
576  * low.
577  */
578 static void
isdn_tty_modem_ncarrier(modem_info * info)579 isdn_tty_modem_ncarrier(modem_info * info)
580 {
581 	if (info->ncarrier) {
582 		info->nc_timer.expires = jiffies + HZ;
583 		info->nc_timer.function = isdn_tty_modem_do_ncarrier;
584 		info->nc_timer.data = (unsigned long) info;
585 		add_timer(&info->nc_timer);
586 	}
587 }
588 
589 /*
590  * return the usage calculated by si and layer 2 protocol
591  */
592 int
isdn_calc_usage(int si,int l2)593 isdn_calc_usage(int si, int l2)
594 {
595 	int usg = ISDN_USAGE_MODEM;
596 
597 #ifdef CONFIG_ISDN_AUDIO
598 	if (si == 1) {
599 		switch(l2) {
600 			case ISDN_PROTO_L2_MODEM:
601 				usg = ISDN_USAGE_MODEM;
602 				break;
603 #ifdef CONFIG_ISDN_TTY_FAX
604 			case ISDN_PROTO_L2_FAX:
605 				usg = ISDN_USAGE_FAX;
606 				break;
607 #endif
608 			case ISDN_PROTO_L2_TRANS:
609 			default:
610 				usg = ISDN_USAGE_VOICE;
611 				break;
612 		}
613 	}
614 #endif
615 	return(usg);
616 }
617 
618 /* isdn_tty_dial() performs dialing of a tty an the necessary
619  * setup of the lower levels before that.
620  */
621 static void
isdn_tty_dial(char * n,modem_info * info,atemu * m)622 isdn_tty_dial(char *n, modem_info * info, atemu * m)
623 {
624 	int usg = ISDN_USAGE_MODEM;
625 	int si = 7;
626 	int l2 = m->mdmreg[REG_L2PROT];
627 	isdn_ctrl cmd;
628 	ulong flags;
629 	int i;
630 	int j;
631 
632 	for (j = 7; j >= 0; j--)
633 		if (m->mdmreg[REG_SI1] & (1 << j)) {
634 			si = bit2si[j];
635 			break;
636 		}
637 	usg = isdn_calc_usage(si, l2);
638 #ifdef CONFIG_ISDN_AUDIO
639 	if ((si == 1) &&
640 		(l2 != ISDN_PROTO_L2_MODEM)
641 #ifdef CONFIG_ISDN_TTY_FAX
642 		&& (l2 != ISDN_PROTO_L2_FAX)
643 #endif
644 		) {
645 		l2 = ISDN_PROTO_L2_TRANS;
646 		usg = ISDN_USAGE_VOICE;
647 	}
648 #endif
649 	m->mdmreg[REG_SI1I] = si2bit[si];
650 	save_flags(flags);
651 	cli();
652 	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
653 	if (i < 0) {
654 		restore_flags(flags);
655 		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
656 	} else {
657 		info->isdn_driver = dev->drvmap[i];
658 		info->isdn_channel = dev->chanmap[i];
659 		info->drv_index = i;
660 		dev->m_idx[i] = info->line;
661 		dev->usage[i] |= ISDN_USAGE_OUTGOING;
662 		info->last_dir = 1;
663 		strcpy(info->last_num, n);
664 		isdn_info_update();
665 		restore_flags(flags);
666 		cmd.driver = info->isdn_driver;
667 		cmd.arg = info->isdn_channel;
668 		cmd.command = ISDN_CMD_CLREAZ;
669 		isdn_command(&cmd);
670 		strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver));
671 		cmd.driver = info->isdn_driver;
672 		cmd.command = ISDN_CMD_SETEAZ;
673 		isdn_command(&cmd);
674 		cmd.driver = info->isdn_driver;
675 		cmd.command = ISDN_CMD_SETL2;
676 		info->last_l2 = l2;
677 		cmd.arg = info->isdn_channel + (l2 << 8);
678 		isdn_command(&cmd);
679 		cmd.driver = info->isdn_driver;
680 		cmd.command = ISDN_CMD_SETL3;
681 		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
682 #ifdef CONFIG_ISDN_TTY_FAX
683 		if (l2 == ISDN_PROTO_L2_FAX) {
684 			cmd.parm.fax = info->fax;
685 			info->fax->direction = ISDN_TTY_FAX_CONN_OUT;
686 		}
687 #endif
688 		isdn_command(&cmd);
689 		cmd.driver = info->isdn_driver;
690 		cmd.arg = info->isdn_channel;
691 		sprintf(cmd.parm.setup.phone, "%s", n);
692 		sprintf(cmd.parm.setup.eazmsn, "%s",
693 			isdn_map_eaz2msn(m->msn, info->isdn_driver));
694 		cmd.parm.setup.si1 = si;
695 		cmd.parm.setup.si2 = m->mdmreg[REG_SI2];
696 		cmd.command = ISDN_CMD_DIAL;
697 		info->dialing = 1;
698 		info->emu.carrierwait = 0;
699 		strcpy(dev->num[i], n);
700 		isdn_info_update();
701 		isdn_command(&cmd);
702 		isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
703 	}
704 }
705 
706 /* isdn_tty_hangup() disassociates a tty from the real
707  * ISDN-line (hangup). The usage-status is cleared
708  * and some cleanup is done also.
709  */
710 void
isdn_tty_modem_hup(modem_info * info,int local)711 isdn_tty_modem_hup(modem_info * info, int local)
712 {
713 	isdn_ctrl cmd;
714 	int di, ch;
715 
716 	if (!info)
717 		return;
718 
719 	di = info->isdn_driver;
720 	ch = info->isdn_channel;
721 	if (di < 0 || ch < 0)
722 		return;
723 
724 	info->isdn_driver = -1;
725 	info->isdn_channel = -1;
726 
727 #ifdef ISDN_DEBUG_MODEM_HUP
728 	printk(KERN_DEBUG "Mhup ttyI%d\n", info->line);
729 #endif
730 	info->rcvsched = 0;
731 	isdn_tty_flush_buffer(info->tty);
732 	if (info->online) {
733 		info->last_lhup = local;
734 		info->online = 0;
735 		isdn_tty_modem_result(RESULT_NO_CARRIER, info);
736 	}
737 #ifdef CONFIG_ISDN_AUDIO
738 	info->vonline = 0;
739 #ifdef CONFIG_ISDN_TTY_FAX
740 	info->faxonline = 0;
741 	info->fax->phase = ISDN_FAX_PHASE_IDLE;
742 #endif
743 	info->emu.vpar[4] = 0;
744 	info->emu.vpar[5] = 8;
745 	if (info->dtmf_state) {
746 		kfree(info->dtmf_state);
747 		info->dtmf_state = NULL;
748 	}
749 	if (info->silence_state) {
750 		kfree(info->silence_state);
751 		info->silence_state = NULL;
752 	}
753 	if (info->adpcms) {
754 		kfree(info->adpcms);
755 		info->adpcms = NULL;
756 	}
757 	if (info->adpcmr) {
758 		kfree(info->adpcmr);
759 		info->adpcmr = NULL;
760 	}
761 #endif
762 	if ((info->msr & UART_MSR_RI) &&
763 		(info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
764 		isdn_tty_modem_result(RESULT_RUNG, info);
765 	info->msr &= ~(UART_MSR_DCD | UART_MSR_RI);
766 	info->lsr |= UART_LSR_TEMT;
767 
768 	if (local) {
769 		cmd.driver = di;
770 		cmd.command = ISDN_CMD_HANGUP;
771 		cmd.arg = ch;
772 		isdn_command(&cmd);
773 	}
774 
775 	isdn_all_eaz(di, ch);
776 	info->emu.mdmreg[REG_RINGCNT] = 0;
777 	isdn_free_channel(di, ch, 0);
778 
779 	if (info->drv_index >= 0) {
780 		dev->m_idx[info->drv_index] = -1;
781 		info->drv_index = -1;
782 	}
783 }
784 
785 /*
786  * Begin of a CAPI like interface, currently used only for
787  * supplementary service (CAPI 2.0 part III)
788  */
789 #include "avmb1/capicmd.h"  /* this should be moved in a common place */
790 
791 int
isdn_tty_capi_facility(capi_msg * cm)792 isdn_tty_capi_facility(capi_msg *cm) {
793 	return(-1); /* dummy */
794 }
795 
796 /* isdn_tty_suspend() tries to suspend the current tty connection
797  */
798 static void
isdn_tty_suspend(char * id,modem_info * info,atemu * m)799 isdn_tty_suspend(char *id, modem_info * info, atemu * m)
800 {
801 	isdn_ctrl cmd;
802 
803 	int l;
804 
805 	if (!info)
806 		return;
807 
808 #ifdef ISDN_DEBUG_MODEM_SERVICES
809 	printk(KERN_DEBUG "Msusp ttyI%d\n", info->line);
810 #endif
811 	l = strlen(id);
812 	if ((info->isdn_driver >= 0)) {
813 		cmd.parm.cmsg.Length = l+18;
814 		cmd.parm.cmsg.Command = CAPI_FACILITY;
815 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
816 		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
817 		cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */
818 		cmd.parm.cmsg.para[1] = 0;
819 		cmd.parm.cmsg.para[2] = l + 3;
820 		cmd.parm.cmsg.para[3] = 4; /* 16 bit 0x0004 Suspend */
821 		cmd.parm.cmsg.para[4] = 0;
822 		cmd.parm.cmsg.para[5] = l;
823 		strncpy(&cmd.parm.cmsg.para[6], id, l);
824 		cmd.command = CAPI_PUT_MESSAGE;
825 		cmd.driver = info->isdn_driver;
826 		cmd.arg = info->isdn_channel;
827 		isdn_command(&cmd);
828 	}
829 }
830 
831 /* isdn_tty_resume() tries to resume a suspended call
832  * setup of the lower levels before that. unfortunatly here is no
833  * checking for compatibility of used protocols implemented by Q931
834  * It does the same things like isdn_tty_dial, the last command
835  * is different, may be we can merge it.
836  */
837 
838 static void
isdn_tty_resume(char * id,modem_info * info,atemu * m)839 isdn_tty_resume(char *id, modem_info * info, atemu * m)
840 {
841 	int usg = ISDN_USAGE_MODEM;
842 	int si = 7;
843 	int l2 = m->mdmreg[REG_L2PROT];
844 	isdn_ctrl cmd;
845 	ulong flags;
846 	int i;
847 	int j;
848 	int l;
849 
850 	l = strlen(id);
851 	for (j = 7; j >= 0; j--)
852 		if (m->mdmreg[REG_SI1] & (1 << j)) {
853 			si = bit2si[j];
854 			break;
855 		}
856 	usg = isdn_calc_usage(si, l2);
857 #ifdef CONFIG_ISDN_AUDIO
858 	if ((si == 1) &&
859 		(l2 != ISDN_PROTO_L2_MODEM)
860 #ifdef CONFIG_ISDN_TTY_FAX
861 		&& (l2 != ISDN_PROTO_L2_FAX)
862 #endif
863 		) {
864 		l2 = ISDN_PROTO_L2_TRANS;
865 		usg = ISDN_USAGE_VOICE;
866 	}
867 #endif
868 	m->mdmreg[REG_SI1I] = si2bit[si];
869 	save_flags(flags);
870 	cli();
871 	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
872 	if (i < 0) {
873 		restore_flags(flags);
874 		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
875 	} else {
876 		info->isdn_driver = dev->drvmap[i];
877 		info->isdn_channel = dev->chanmap[i];
878 		info->drv_index = i;
879 		dev->m_idx[i] = info->line;
880 		dev->usage[i] |= ISDN_USAGE_OUTGOING;
881 		info->last_dir = 1;
882 //		strcpy(info->last_num, n);
883 		isdn_info_update();
884 		restore_flags(flags);
885 		cmd.driver = info->isdn_driver;
886 		cmd.arg = info->isdn_channel;
887 		cmd.command = ISDN_CMD_CLREAZ;
888 		isdn_command(&cmd);
889 		strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver));
890 		cmd.driver = info->isdn_driver;
891 		cmd.command = ISDN_CMD_SETEAZ;
892 		isdn_command(&cmd);
893 		cmd.driver = info->isdn_driver;
894 		cmd.command = ISDN_CMD_SETL2;
895 		info->last_l2 = l2;
896 		cmd.arg = info->isdn_channel + (l2 << 8);
897 		isdn_command(&cmd);
898 		cmd.driver = info->isdn_driver;
899 		cmd.command = ISDN_CMD_SETL3;
900 		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
901 		isdn_command(&cmd);
902 		cmd.driver = info->isdn_driver;
903 		cmd.arg = info->isdn_channel;
904 		cmd.parm.cmsg.Length = l+18;
905 		cmd.parm.cmsg.Command = CAPI_FACILITY;
906 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
907 		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
908 		cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */
909 		cmd.parm.cmsg.para[1] = 0;
910 		cmd.parm.cmsg.para[2] = l+3;
911 		cmd.parm.cmsg.para[3] = 5; /* 16 bit 0x0005 Resume */
912 		cmd.parm.cmsg.para[4] = 0;
913 		cmd.parm.cmsg.para[5] = l;
914 		strncpy(&cmd.parm.cmsg.para[6], id, l);
915 		cmd.command =CAPI_PUT_MESSAGE;
916 		info->dialing = 1;
917 //		strcpy(dev->num[i], n);
918 		isdn_info_update();
919 		isdn_command(&cmd);
920 		isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
921 	}
922 }
923 
924 /* isdn_tty_send_msg() sends a message to a HL driver
925  * This is used for hybrid modem cards to send AT commands to it
926  */
927 
928 static void
isdn_tty_send_msg(modem_info * info,atemu * m,char * msg)929 isdn_tty_send_msg(modem_info * info, atemu * m, char *msg)
930 {
931 	int usg = ISDN_USAGE_MODEM;
932 	int si = 7;
933 	int l2 = m->mdmreg[REG_L2PROT];
934 	isdn_ctrl cmd;
935 	ulong flags;
936 	int i;
937 	int j;
938 	int l;
939 
940 	l = strlen(msg);
941 	if (!l) {
942 		isdn_tty_modem_result(RESULT_ERROR, info);
943 		return;
944 	}
945 	for (j = 7; j >= 0; j--)
946 		if (m->mdmreg[REG_SI1] & (1 << j)) {
947 			si = bit2si[j];
948 			break;
949 		}
950 	usg = isdn_calc_usage(si, l2);
951 #ifdef CONFIG_ISDN_AUDIO
952 	if ((si == 1) &&
953 		(l2 != ISDN_PROTO_L2_MODEM)
954 #ifdef CONFIG_ISDN_TTY_FAX
955 		&& (l2 != ISDN_PROTO_L2_FAX)
956 #endif
957 		) {
958 		l2 = ISDN_PROTO_L2_TRANS;
959 		usg = ISDN_USAGE_VOICE;
960 	}
961 #endif
962 	m->mdmreg[REG_SI1I] = si2bit[si];
963 	save_flags(flags);
964 	cli();
965 	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
966 	if (i < 0) {
967 		restore_flags(flags);
968 		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
969 	} else {
970 		info->isdn_driver = dev->drvmap[i];
971 		info->isdn_channel = dev->chanmap[i];
972 		info->drv_index = i;
973 		dev->m_idx[i] = info->line;
974 		dev->usage[i] |= ISDN_USAGE_OUTGOING;
975 		info->last_dir = 1;
976 		isdn_info_update();
977 		restore_flags(flags);
978 		cmd.driver = info->isdn_driver;
979 		cmd.arg = info->isdn_channel;
980 		cmd.command = ISDN_CMD_CLREAZ;
981 		isdn_command(&cmd);
982 		strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver));
983 		cmd.driver = info->isdn_driver;
984 		cmd.command = ISDN_CMD_SETEAZ;
985 		isdn_command(&cmd);
986 		cmd.driver = info->isdn_driver;
987 		cmd.command = ISDN_CMD_SETL2;
988 		info->last_l2 = l2;
989 		cmd.arg = info->isdn_channel + (l2 << 8);
990 		isdn_command(&cmd);
991 		cmd.driver = info->isdn_driver;
992 		cmd.command = ISDN_CMD_SETL3;
993 		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
994 		isdn_command(&cmd);
995 		cmd.driver = info->isdn_driver;
996 		cmd.arg = info->isdn_channel;
997 		cmd.parm.cmsg.Length = l+14;
998 		cmd.parm.cmsg.Command = CAPI_MANUFACTURER;
999 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
1000 		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
1001 		cmd.parm.cmsg.para[0] = l+1;
1002 		strncpy(&cmd.parm.cmsg.para[1], msg, l);
1003 		cmd.parm.cmsg.para[l+1] = 0xd;
1004 		cmd.command =CAPI_PUT_MESSAGE;
1005 /*		info->dialing = 1;
1006 		strcpy(dev->num[i], n);
1007 		isdn_info_update();
1008 */
1009 		isdn_command(&cmd);
1010 	}
1011 }
1012 
1013 static inline int
isdn_tty_paranoia_check(modem_info * info,kdev_t device,const char * routine)1014 isdn_tty_paranoia_check(modem_info * info, kdev_t device, const char *routine)
1015 {
1016 #ifdef MODEM_PARANOIA_CHECK
1017 	if (!info) {
1018 		printk(KERN_WARNING "isdn_tty: null info_struct for (%d, %d) in %s\n",
1019 		       MAJOR(device), MINOR(device), routine);
1020 		return 1;
1021 	}
1022 	if (info->magic != ISDN_ASYNC_MAGIC) {
1023 		printk(KERN_WARNING "isdn_tty: bad magic for modem struct (%d, %d) in %s\n",
1024 		       MAJOR(device), MINOR(device), routine);
1025 		return 1;
1026 	}
1027 #endif
1028 	return 0;
1029 }
1030 
1031 /*
1032  * This routine is called to set the UART divisor registers to match
1033  * the specified baud rate for a serial port.
1034  */
1035 static void
isdn_tty_change_speed(modem_info * info)1036 isdn_tty_change_speed(modem_info * info)
1037 {
1038 	uint cflag,
1039 	 cval,
1040 	 fcr,
1041 	 quot;
1042 	int i;
1043 
1044 	if (!info->tty || !info->tty->termios)
1045 		return;
1046 	cflag = info->tty->termios->c_cflag;
1047 
1048 	quot = i = cflag & CBAUD;
1049 	if (i & CBAUDEX) {
1050 		i &= ~CBAUDEX;
1051 		if (i < 1 || i > 2)
1052 			info->tty->termios->c_cflag &= ~CBAUDEX;
1053 		else
1054 			i += 15;
1055 	}
1056 	if (quot) {
1057 		info->mcr |= UART_MCR_DTR;
1058 		isdn_tty_modem_ncarrier(info);
1059 	} else {
1060 		info->mcr &= ~UART_MCR_DTR;
1061 		if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) {
1062 #ifdef ISDN_DEBUG_MODEM_HUP
1063 			printk(KERN_DEBUG "Mhup in changespeed\n");
1064 #endif
1065 			if (info->online)
1066 				info->ncarrier = 1;
1067 			isdn_tty_modem_reset_regs(info, 0);
1068 			isdn_tty_modem_hup(info, 1);
1069 		}
1070 		return;
1071 	}
1072 	/* byte size and parity */
1073 	cval = cflag & (CSIZE | CSTOPB);
1074 	cval >>= 4;
1075 	if (cflag & PARENB)
1076 		cval |= UART_LCR_PARITY;
1077 	if (!(cflag & PARODD))
1078 		cval |= UART_LCR_EPAR;
1079 	fcr = 0;
1080 
1081 	/* CTS flow control flag and modem status interrupts */
1082 	if (cflag & CRTSCTS) {
1083 		info->flags |= ISDN_ASYNC_CTS_FLOW;
1084 	} else
1085 		info->flags &= ~ISDN_ASYNC_CTS_FLOW;
1086 	if (cflag & CLOCAL)
1087 		info->flags &= ~ISDN_ASYNC_CHECK_CD;
1088 	else {
1089 		info->flags |= ISDN_ASYNC_CHECK_CD;
1090 	}
1091 }
1092 
1093 static int
isdn_tty_startup(modem_info * info)1094 isdn_tty_startup(modem_info * info)
1095 {
1096 	ulong flags;
1097 
1098 	if (info->flags & ISDN_ASYNC_INITIALIZED)
1099 		return 0;
1100 	save_flags(flags);
1101 	cli();
1102 	isdn_MOD_INC_USE_COUNT();
1103 #ifdef ISDN_DEBUG_MODEM_OPEN
1104 	printk(KERN_DEBUG "starting up ttyi%d ...\n", info->line);
1105 #endif
1106 	/*
1107 	 * Now, initialize the UART
1108 	 */
1109 	info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
1110 	if (info->tty)
1111 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
1112 	/*
1113 	 * and set the speed of the serial port
1114 	 */
1115 	isdn_tty_change_speed(info);
1116 
1117 	info->flags |= ISDN_ASYNC_INITIALIZED;
1118 	info->msr |= (UART_MSR_DSR | UART_MSR_CTS);
1119 	info->send_outstanding = 0;
1120 	restore_flags(flags);
1121 	return 0;
1122 }
1123 
1124 /*
1125  * This routine will shutdown a serial port; interrupts are disabled, and
1126  * DTR is dropped if the hangup on close termio flag is on.
1127  */
1128 static void
isdn_tty_shutdown(modem_info * info)1129 isdn_tty_shutdown(modem_info * info)
1130 {
1131 	ulong flags;
1132 
1133 	if (!(info->flags & ISDN_ASYNC_INITIALIZED))
1134 		return;
1135 #ifdef ISDN_DEBUG_MODEM_OPEN
1136 	printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line);
1137 #endif
1138 	save_flags(flags);
1139 	cli();                  /* Disable interrupts */
1140 	isdn_MOD_DEC_USE_COUNT();
1141 	info->msr &= ~UART_MSR_RI;
1142 	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
1143 		info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
1144 		if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) {
1145 			isdn_tty_modem_reset_regs(info, 0);
1146 #ifdef ISDN_DEBUG_MODEM_HUP
1147 			printk(KERN_DEBUG "Mhup in isdn_tty_shutdown\n");
1148 #endif
1149 			isdn_tty_modem_hup(info, 1);
1150 		}
1151 	}
1152 	if (info->tty)
1153 		set_bit(TTY_IO_ERROR, &info->tty->flags);
1154 
1155 	info->flags &= ~ISDN_ASYNC_INITIALIZED;
1156 	restore_flags(flags);
1157 }
1158 
1159 /* isdn_tty_write() is the main send-routine. It is called from the upper
1160  * levels within the kernel to perform sending data. Depending on the
1161  * online-flag it either directs output to the at-command-interpreter or
1162  * to the lower level. Additional tasks done here:
1163  *  - If online, check for escape-sequence (+++)
1164  *  - If sending audio-data, call isdn_tty_DLEdown() to parse DLE-codes.
1165  *  - If receiving audio-data, call isdn_tty_end_vrx() to abort if needed.
1166  *  - If dialing, abort dial.
1167  */
1168 static int
isdn_tty_write(struct tty_struct * tty,int from_user,const u_char * buf,int count)1169 isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int count)
1170 {
1171 	int c;
1172 	int total = 0;
1173 	modem_info *info = (modem_info *) tty->driver_data;
1174 	atemu *m = &info->emu;
1175 
1176 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_write"))
1177 		return 0;
1178 	if (from_user)
1179 		down(&info->write_sem);
1180 	/* See isdn_tty_senddown() */
1181 	atomic_inc(&info->xmit_lock);
1182 	while (1) {
1183 		c = count;
1184 		if (c > info->xmit_size - info->xmit_count)
1185 			c = info->xmit_size - info->xmit_count;
1186 		if (info->isdn_driver >= 0 && c > dev->drv[info->isdn_driver]->maxbufsize)
1187 			c = dev->drv[info->isdn_driver]->maxbufsize;
1188 		if (c <= 0)
1189 			break;
1190 		if ((info->online > 1)
1191 #ifdef CONFIG_ISDN_AUDIO
1192 		    || (info->vonline & 3)
1193 #endif
1194 			) {
1195 #ifdef CONFIG_ISDN_AUDIO
1196 			if (!info->vonline)
1197 #endif
1198 				isdn_tty_check_esc(buf, m->mdmreg[REG_ESC], c,
1199 						   &(m->pluscount),
1200 						   &(m->lastplus),
1201 						   from_user);
1202 			if (from_user)
1203 				copy_from_user(&(info->xmit_buf[info->xmit_count]), buf, c);
1204 			else
1205 				memcpy(&(info->xmit_buf[info->xmit_count]), buf, c);
1206 #ifdef CONFIG_ISDN_AUDIO
1207 			if (info->vonline) {
1208 				int cc = isdn_tty_handleDLEdown(info, m, c);
1209 				if (info->vonline & 2) {
1210 					if (!cc) {
1211 						/* If DLE decoding results in zero-transmit, but
1212 						 * c originally was non-zero, do a wakeup.
1213 						 */
1214 						tty_wakeup(tty);
1215 						info->msr |= UART_MSR_CTS;
1216 						info->lsr |= UART_LSR_TEMT;
1217 					}
1218 					info->xmit_count += cc;
1219 				}
1220 				if ((info->vonline & 3) == 1) {
1221 					/* Do NOT handle Ctrl-Q or Ctrl-S
1222 					 * when in full-duplex audio mode.
1223 					 */
1224 					if (isdn_tty_end_vrx(buf, c, from_user)) {
1225 						info->vonline &= ~1;
1226 #ifdef ISDN_DEBUG_MODEM_VOICE
1227 						printk(KERN_DEBUG
1228 						       "got !^Q/^S, send DLE-ETX,VCON on ttyI%d\n",
1229 						       info->line);
1230 #endif
1231 						isdn_tty_at_cout("\020\003\r\nVCON\r\n", info);
1232 					}
1233 				}
1234 			} else
1235 			if (TTY_IS_FCLASS1(info)) {
1236 				int cc = isdn_tty_handleDLEdown(info, m, c);
1237 
1238 				if (info->vonline & 4) { /* ETX seen */
1239 					isdn_ctrl c;
1240 
1241 					c.command = ISDN_CMD_FAXCMD;
1242 					c.driver = info->isdn_driver;
1243 					c.arg = info->isdn_channel;
1244 					c.parm.aux.cmd = ISDN_FAX_CLASS1_CTRL;
1245 					c.parm.aux.subcmd = ETX;
1246 					isdn_command(&c);
1247 				}
1248 				info->vonline = 0;
1249 #ifdef ISDN_DEBUG_MODEM_VOICE
1250 				printk(KERN_DEBUG "fax dle cc/c %d/%d\n", cc, c);
1251 #endif
1252 				info->xmit_count += cc;
1253 			} else
1254 #endif
1255 				info->xmit_count += c;
1256 		} else {
1257 			info->msr |= UART_MSR_CTS;
1258 			info->lsr |= UART_LSR_TEMT;
1259 			if (info->dialing) {
1260 				info->dialing = 0;
1261 #ifdef ISDN_DEBUG_MODEM_HUP
1262 				printk(KERN_DEBUG "Mhup in isdn_tty_write\n");
1263 #endif
1264 				isdn_tty_modem_result(RESULT_NO_CARRIER, info);
1265 				isdn_tty_modem_hup(info, 1);
1266 			} else
1267 				c = isdn_tty_edit_at(buf, c, info, from_user);
1268 		}
1269 		buf += c;
1270 		count -= c;
1271 		total += c;
1272 	}
1273 	atomic_dec(&info->xmit_lock);
1274 	if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue))) {
1275 		if (m->mdmreg[REG_DXMT] & BIT_DXMT) {
1276 			isdn_tty_senddown(info);
1277 			isdn_tty_tint(info);
1278 		}
1279 		isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1);
1280 	}
1281 	if (from_user)
1282 		up(&info->write_sem);
1283 	return total;
1284 }
1285 
1286 static int
isdn_tty_write_room(struct tty_struct * tty)1287 isdn_tty_write_room(struct tty_struct *tty)
1288 {
1289 	modem_info *info = (modem_info *) tty->driver_data;
1290 	int ret;
1291 
1292 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_write_room"))
1293 		return 0;
1294 	if (!info->online)
1295 		return info->xmit_size;
1296 	ret = info->xmit_size - info->xmit_count;
1297 	return (ret < 0) ? 0 : ret;
1298 }
1299 
1300 static int
isdn_tty_chars_in_buffer(struct tty_struct * tty)1301 isdn_tty_chars_in_buffer(struct tty_struct *tty)
1302 {
1303 	modem_info *info = (modem_info *) tty->driver_data;
1304 
1305 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_chars_in_buffer"))
1306 		return 0;
1307 	if (!info->online)
1308 		return 0;
1309 	return (info->xmit_count);
1310 }
1311 
1312 static void
isdn_tty_flush_buffer(struct tty_struct * tty)1313 isdn_tty_flush_buffer(struct tty_struct *tty)
1314 {
1315 	modem_info *info;
1316 	unsigned long flags;
1317 
1318 	save_flags(flags);
1319 	cli();
1320 	if (!tty) {
1321 		restore_flags(flags);
1322 		return;
1323 	}
1324 	info = (modem_info *) tty->driver_data;
1325 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_flush_buffer")) {
1326 		restore_flags(flags);
1327 		return;
1328 	}
1329 	isdn_tty_cleanup_xmit(info);
1330 	info->xmit_count = 0;
1331 	restore_flags(flags);
1332 	tty_wakeup(tty);
1333 }
1334 
1335 static void
isdn_tty_flush_chars(struct tty_struct * tty)1336 isdn_tty_flush_chars(struct tty_struct *tty)
1337 {
1338 	modem_info *info = (modem_info *) tty->driver_data;
1339 
1340 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_flush_chars"))
1341 		return;
1342 	if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue)))
1343 		isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1);
1344 }
1345 
1346 /*
1347  * ------------------------------------------------------------
1348  * isdn_tty_throttle()
1349  *
1350  * This routine is called by the upper-layer tty layer to signal that
1351  * incoming characters should be throttled.
1352  * ------------------------------------------------------------
1353  */
1354 static void
isdn_tty_throttle(struct tty_struct * tty)1355 isdn_tty_throttle(struct tty_struct *tty)
1356 {
1357 	modem_info *info = (modem_info *) tty->driver_data;
1358 
1359 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_throttle"))
1360 		return;
1361 	if (I_IXOFF(tty))
1362 		info->x_char = STOP_CHAR(tty);
1363 	info->mcr &= ~UART_MCR_RTS;
1364 }
1365 
1366 static void
isdn_tty_unthrottle(struct tty_struct * tty)1367 isdn_tty_unthrottle(struct tty_struct *tty)
1368 {
1369 	modem_info *info = (modem_info *) tty->driver_data;
1370 
1371 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_unthrottle"))
1372 		return;
1373 	if (I_IXOFF(tty)) {
1374 		if (info->x_char)
1375 			info->x_char = 0;
1376 		else
1377 			info->x_char = START_CHAR(tty);
1378 	}
1379 	info->mcr |= UART_MCR_RTS;
1380 }
1381 
1382 /*
1383  * ------------------------------------------------------------
1384  * isdn_tty_ioctl() and friends
1385  * ------------------------------------------------------------
1386  */
1387 
1388 /*
1389  * isdn_tty_get_lsr_info - get line status register info
1390  *
1391  * Purpose: Let user call ioctl() to get info when the UART physically
1392  *          is emptied.  On bus types like RS485, the transmitter must
1393  *          release the bus after transmitting. This must be done when
1394  *          the transmit shift register is empty, not be done when the
1395  *          transmit holding register is empty.  This functionality
1396  *          allows RS485 driver to be written in user space.
1397  */
1398 static int
isdn_tty_get_lsr_info(modem_info * info,uint * value)1399 isdn_tty_get_lsr_info(modem_info * info, uint * value)
1400 {
1401 	u_char status;
1402 	uint result;
1403 	ulong flags;
1404 
1405 	save_flags(flags);
1406 	cli();
1407 	status = info->lsr;
1408 	restore_flags(flags);
1409 	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
1410 	return put_user(result, (uint *) value);
1411 }
1412 
1413 
1414 static int
isdn_tty_get_modem_info(modem_info * info,uint * value)1415 isdn_tty_get_modem_info(modem_info * info, uint * value)
1416 {
1417 	u_char control,
1418 	 status;
1419 	uint result;
1420 	ulong flags;
1421 
1422 	control = info->mcr;
1423 	save_flags(flags);
1424 	cli();
1425 	status = info->msr;
1426 	restore_flags(flags);
1427 	result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
1428 	    | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
1429 	    | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
1430 	    | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
1431 	    | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
1432 	    | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
1433 	return put_user(result, (uint *) value);
1434 }
1435 
1436 static int
isdn_tty_set_modem_info(modem_info * info,uint cmd,uint * value)1437 isdn_tty_set_modem_info(modem_info * info, uint cmd, uint * value)
1438 {
1439 	uint arg;
1440 	int pre_dtr;
1441 
1442 	if (get_user(arg, (uint *) value))
1443 		return -EFAULT;
1444 	switch (cmd) {
1445 		case TIOCMBIS:
1446 #ifdef ISDN_DEBUG_MODEM_IOCTL
1447 			printk(KERN_DEBUG "ttyI%d ioctl TIOCMBIS\n", info->line);
1448 #endif
1449 			if (arg & TIOCM_RTS) {
1450 				info->mcr |= UART_MCR_RTS;
1451 			}
1452 			if (arg & TIOCM_DTR) {
1453 				info->mcr |= UART_MCR_DTR;
1454 				isdn_tty_modem_ncarrier(info);
1455 			}
1456 			break;
1457 		case TIOCMBIC:
1458 #ifdef ISDN_DEBUG_MODEM_IOCTL
1459 			printk(KERN_DEBUG "ttyI%d ioctl TIOCMBIC\n", info->line);
1460 #endif
1461 			if (arg & TIOCM_RTS) {
1462 				info->mcr &= ~UART_MCR_RTS;
1463 			}
1464 			if (arg & TIOCM_DTR) {
1465 				info->mcr &= ~UART_MCR_DTR;
1466 				if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) {
1467 					isdn_tty_modem_reset_regs(info, 0);
1468 #ifdef ISDN_DEBUG_MODEM_HUP
1469 					printk(KERN_DEBUG "Mhup in TIOCMBIC\n");
1470 #endif
1471 					if (info->online)
1472 						info->ncarrier = 1;
1473 					isdn_tty_modem_hup(info, 1);
1474 				}
1475 			}
1476 			break;
1477 		case TIOCMSET:
1478 #ifdef ISDN_DEBUG_MODEM_IOCTL
1479 			printk(KERN_DEBUG "ttyI%d ioctl TIOCMSET\n", info->line);
1480 #endif
1481 			pre_dtr = (info->mcr & UART_MCR_DTR);
1482 			info->mcr = ((info->mcr & ~(UART_MCR_RTS | UART_MCR_DTR))
1483 				 | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
1484 			       | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
1485 			if (pre_dtr |= (info->mcr & UART_MCR_DTR)) {
1486 				if (!(info->mcr & UART_MCR_DTR)) {
1487 					if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) {
1488 						isdn_tty_modem_reset_regs(info, 0);
1489 #ifdef ISDN_DEBUG_MODEM_HUP
1490 						printk(KERN_DEBUG "Mhup in TIOCMSET\n");
1491 #endif
1492 						if (info->online)
1493 							info->ncarrier = 1;
1494 						isdn_tty_modem_hup(info, 1);
1495 					}
1496 				} else
1497 					isdn_tty_modem_ncarrier(info);
1498 			}
1499 			break;
1500 		default:
1501 			return -EINVAL;
1502 	}
1503 	return 0;
1504 }
1505 
1506 static int
isdn_tty_ioctl(struct tty_struct * tty,struct file * file,uint cmd,ulong arg)1507 isdn_tty_ioctl(struct tty_struct *tty, struct file *file,
1508 	       uint cmd, ulong arg)
1509 {
1510 	modem_info *info = (modem_info *) tty->driver_data;
1511 	int retval;
1512 
1513 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_ioctl"))
1514 		return -ENODEV;
1515 	if (tty->flags & (1 << TTY_IO_ERROR))
1516 		return -EIO;
1517 	switch (cmd) {
1518 		case TCSBRK:   /* SVID version: non-zero arg --> no break */
1519 #ifdef ISDN_DEBUG_MODEM_IOCTL
1520 			printk(KERN_DEBUG "ttyI%d ioctl TCSBRK\n", info->line);
1521 #endif
1522 			retval = tty_check_change(tty);
1523 			if (retval)
1524 				return retval;
1525 			tty_wait_until_sent(tty, 0);
1526 			return 0;
1527 		case TCSBRKP:  /* support for POSIX tcsendbreak() */
1528 #ifdef ISDN_DEBUG_MODEM_IOCTL
1529 			printk(KERN_DEBUG "ttyI%d ioctl TCSBRKP\n", info->line);
1530 #endif
1531 			retval = tty_check_change(tty);
1532 			if (retval)
1533 				return retval;
1534 			tty_wait_until_sent(tty, 0);
1535 			return 0;
1536 		case TIOCGSOFTCAR:
1537 #ifdef ISDN_DEBUG_MODEM_IOCTL
1538 			printk(KERN_DEBUG "ttyI%d ioctl TIOCGSOFTCAR\n", info->line);
1539 #endif
1540 			return put_user(C_CLOCAL(tty) ? 1 : 0, (ulong *) arg);
1541 		case TIOCSSOFTCAR:
1542 #ifdef ISDN_DEBUG_MODEM_IOCTL
1543 			printk(KERN_DEBUG "ttyI%d ioctl TIOCSSOFTCAR\n", info->line);
1544 #endif
1545 			if (get_user(arg, (ulong *) arg))
1546 				return -EFAULT;
1547 			tty->termios->c_cflag =
1548 			    ((tty->termios->c_cflag & ~CLOCAL) |
1549 			     (arg ? CLOCAL : 0));
1550 			return 0;
1551 		case TIOCMGET:
1552 #ifdef ISDN_DEBUG_MODEM_IOCTL
1553 			printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line);
1554 #endif
1555 			return isdn_tty_get_modem_info(info, (uint *) arg);
1556 		case TIOCMBIS:
1557 		case TIOCMBIC:
1558 		case TIOCMSET:
1559 			return isdn_tty_set_modem_info(info, cmd, (uint *) arg);
1560 		case TIOCSERGETLSR:	/* Get line status register */
1561 #ifdef ISDN_DEBUG_MODEM_IOCTL
1562 			printk(KERN_DEBUG "ttyI%d ioctl TIOCSERGETLSR\n", info->line);
1563 #endif
1564 			return isdn_tty_get_lsr_info(info, (uint *) arg);
1565 		default:
1566 #ifdef ISDN_DEBUG_MODEM_IOCTL
1567 			printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on ttyi%d\n", cmd, info->line);
1568 #endif
1569 			return -ENOIOCTLCMD;
1570 	}
1571 	return 0;
1572 }
1573 
1574 static void
isdn_tty_set_termios(struct tty_struct * tty,struct termios * old_termios)1575 isdn_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
1576 {
1577 	modem_info *info = (modem_info *) tty->driver_data;
1578 
1579 	if (!old_termios)
1580 		isdn_tty_change_speed(info);
1581 	else {
1582 		if (tty->termios->c_cflag == old_termios->c_cflag)
1583 			return;
1584 		isdn_tty_change_speed(info);
1585 		if ((old_termios->c_cflag & CRTSCTS) &&
1586 		    !(tty->termios->c_cflag & CRTSCTS)) {
1587 			tty->hw_stopped = 0;
1588 		}
1589 	}
1590 }
1591 
1592 /*
1593  * ------------------------------------------------------------
1594  * isdn_tty_open() and friends
1595  * ------------------------------------------------------------
1596  */
1597 static int
isdn_tty_block_til_ready(struct tty_struct * tty,struct file * filp,modem_info * info)1598 isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info * info)
1599 {
1600 	DECLARE_WAITQUEUE(wait, NULL);
1601 	int do_clocal = 0;
1602 	unsigned long flags;
1603 	int retval;
1604 
1605 	/*
1606 	 * If the device is in the middle of being closed, then block
1607 	 * until it's done, and then try again.
1608 	 */
1609 	if (tty_hung_up_p(filp) ||
1610 	    (info->flags & ISDN_ASYNC_CLOSING)) {
1611 		if (info->flags & ISDN_ASYNC_CLOSING)
1612 			interruptible_sleep_on(&info->close_wait);
1613 #ifdef MODEM_DO_RESTART
1614 		if (info->flags & ISDN_ASYNC_HUP_NOTIFY)
1615 			return -EAGAIN;
1616 		else
1617 			return -ERESTARTSYS;
1618 #else
1619 		return -EAGAIN;
1620 #endif
1621 	}
1622 	/*
1623 	 * If this is a callout device, then just make sure the normal
1624 	 * device isn't being used.
1625 	 */
1626 	if (tty->driver.subtype == ISDN_SERIAL_TYPE_CALLOUT) {
1627 		if (info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
1628 			return -EBUSY;
1629 		if ((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
1630 		    (info->flags & ISDN_ASYNC_SESSION_LOCKOUT) &&
1631 		    (info->session != current->session))
1632 			return -EBUSY;
1633 		if ((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
1634 		    (info->flags & ISDN_ASYNC_PGRP_LOCKOUT) &&
1635 		    (info->pgrp != current->pgrp))
1636 			return -EBUSY;
1637 		info->flags |= ISDN_ASYNC_CALLOUT_ACTIVE;
1638 		return 0;
1639 	}
1640 	/*
1641 	 * If non-blocking mode is set, then make the check up front
1642 	 * and then exit.
1643 	 */
1644 	if ((filp->f_flags & O_NONBLOCK) ||
1645 	    (tty->flags & (1 << TTY_IO_ERROR))) {
1646 		if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
1647 			return -EBUSY;
1648 		info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
1649 		return 0;
1650 	}
1651 	if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) {
1652 		if (info->normal_termios.c_cflag & CLOCAL)
1653 			do_clocal = 1;
1654 	} else {
1655 		if (tty->termios->c_cflag & CLOCAL)
1656 			do_clocal = 1;
1657 	}
1658 	/*
1659 	 * Block waiting for the carrier detect and the line to become
1660 	 * free (i.e., not in use by the callout).  While we are in
1661 	 * this loop, info->count is dropped by one, so that
1662 	 * isdn_tty_close() knows when to free things.  We restore it upon
1663 	 * exit, either normal or abnormal.
1664 	 */
1665 	retval = 0;
1666 	add_wait_queue(&info->open_wait, &wait);
1667 #ifdef ISDN_DEBUG_MODEM_OPEN
1668 	printk(KERN_DEBUG "isdn_tty_block_til_ready before block: ttyi%d, count = %d\n",
1669 	       info->line, info->count);
1670 #endif
1671 	save_flags(flags);
1672 	cli();
1673 	if (!(tty_hung_up_p(filp)))
1674 		info->count--;
1675 	restore_flags(flags);
1676 	info->blocked_open++;
1677 	while (1) {
1678 		set_current_state(TASK_INTERRUPTIBLE);
1679 		if (tty_hung_up_p(filp) ||
1680 		    !(info->flags & ISDN_ASYNC_INITIALIZED)) {
1681 #ifdef MODEM_DO_RESTART
1682 			if (info->flags & ISDN_ASYNC_HUP_NOTIFY)
1683 				retval = -EAGAIN;
1684 			else
1685 				retval = -ERESTARTSYS;
1686 #else
1687 			retval = -EAGAIN;
1688 #endif
1689 			break;
1690 		}
1691 		if (!(info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
1692 		    !(info->flags & ISDN_ASYNC_CLOSING) &&
1693 		    (do_clocal || (info->msr & UART_MSR_DCD))) {
1694 			break;
1695 		}
1696 		if (signal_pending(current)) {
1697 			retval = -ERESTARTSYS;
1698 			break;
1699 		}
1700 #ifdef ISDN_DEBUG_MODEM_OPEN
1701 		printk(KERN_DEBUG "isdn_tty_block_til_ready blocking: ttyi%d, count = %d\n",
1702 		       info->line, info->count);
1703 #endif
1704 		schedule();
1705 	}
1706 	current->state = TASK_RUNNING;
1707 	remove_wait_queue(&info->open_wait, &wait);
1708 	if (!tty_hung_up_p(filp))
1709 		info->count++;
1710 	info->blocked_open--;
1711 #ifdef ISDN_DEBUG_MODEM_OPEN
1712 	printk(KERN_DEBUG "isdn_tty_block_til_ready after blocking: ttyi%d, count = %d\n",
1713 	       info->line, info->count);
1714 #endif
1715 	if (retval)
1716 		return retval;
1717 	info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
1718 	return 0;
1719 }
1720 
1721 /*
1722  * This routine is called whenever a serial port is opened.  It
1723  * enables interrupts for a serial port, linking in its async structure into
1724  * the IRQ chain.   It also performs the serial-specific
1725  * initialization for the tty structure.
1726  */
1727 static int
isdn_tty_open(struct tty_struct * tty,struct file * filp)1728 isdn_tty_open(struct tty_struct *tty, struct file *filp)
1729 {
1730 	modem_info *info;
1731 	int retval,
1732 	 line;
1733 
1734 	line = MINOR(tty->device) - tty->driver.minor_start;
1735 	if (line < 0 || line > ISDN_MAX_CHANNELS)
1736 		return -ENODEV;
1737 	info = &dev->mdm.info[line];
1738 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_open"))
1739 		return -ENODEV;
1740 #ifdef ISDN_DEBUG_MODEM_OPEN
1741 	printk(KERN_DEBUG "isdn_tty_open %s%d, count = %d\n", tty->driver.name,
1742 	       info->line, info->count);
1743 #endif
1744 	info->count++;
1745 	tty->driver_data = info;
1746 	info->tty = tty;
1747 	/*
1748 	 * Start up serial port
1749 	 */
1750 	retval = isdn_tty_startup(info);
1751 	if (retval) {
1752 #ifdef ISDN_DEBUG_MODEM_OPEN
1753 		printk(KERN_DEBUG "isdn_tty_open return after startup\n");
1754 #endif
1755 		return retval;
1756 	}
1757 	retval = isdn_tty_block_til_ready(tty, filp, info);
1758 	if (retval) {
1759 #ifdef ISDN_DEBUG_MODEM_OPEN
1760 		printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n");
1761 #endif
1762 		return retval;
1763 	}
1764 	if ((info->count == 1) && (info->flags & ISDN_ASYNC_SPLIT_TERMIOS)) {
1765 		if (tty->driver.subtype == ISDN_SERIAL_TYPE_NORMAL)
1766 			*tty->termios = info->normal_termios;
1767 		else
1768 			*tty->termios = info->callout_termios;
1769 		isdn_tty_change_speed(info);
1770 	}
1771 	info->session = current->session;
1772 	info->pgrp = current->pgrp;
1773 #ifdef ISDN_DEBUG_MODEM_OPEN
1774 	printk(KERN_DEBUG "isdn_tty_open ttyi%d successful...\n", info->line);
1775 #endif
1776 	dev->modempoll++;
1777 #ifdef ISDN_DEBUG_MODEM_OPEN
1778 	printk(KERN_DEBUG "isdn_tty_open normal exit\n");
1779 #endif
1780 	return 0;
1781 }
1782 
1783 static void
isdn_tty_close(struct tty_struct * tty,struct file * filp)1784 isdn_tty_close(struct tty_struct *tty, struct file *filp)
1785 {
1786 	modem_info *info = (modem_info *) tty->driver_data;
1787 	ulong flags;
1788 	ulong timeout;
1789 
1790 	if (!info || isdn_tty_paranoia_check(info, tty->device, "isdn_tty_close"))
1791 		return;
1792 	save_flags(flags);
1793 	cli();
1794 	if (tty_hung_up_p(filp)) {
1795 		restore_flags(flags);
1796 #ifdef ISDN_DEBUG_MODEM_OPEN
1797 		printk(KERN_DEBUG "isdn_tty_close return after tty_hung_up_p\n");
1798 #endif
1799 		return;
1800 	}
1801 	if ((tty->count == 1) && (info->count != 1)) {
1802 		/*
1803 		 * Uh, oh.  tty->count is 1, which means that the tty
1804 		 * structure will be freed.  Info->count should always
1805 		 * be one in these conditions.  If it's greater than
1806 		 * one, we've got real problems, since it means the
1807 		 * serial port won't be shutdown.
1808 		 */
1809 		printk(KERN_ERR "isdn_tty_close: bad port count; tty->count is 1, "
1810 		       "info->count is %d\n", info->count);
1811 		info->count = 1;
1812 	}
1813 	if (--info->count < 0) {
1814 		printk(KERN_ERR "isdn_tty_close: bad port count for ttyi%d: %d\n",
1815 		       info->line, info->count);
1816 		info->count = 0;
1817 	}
1818 	if (info->count) {
1819 		restore_flags(flags);
1820 #ifdef ISDN_DEBUG_MODEM_OPEN
1821 		printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n");
1822 #endif
1823 		return;
1824 	}
1825 	info->flags |= ISDN_ASYNC_CLOSING;
1826 	/*
1827 	 * Save the termios structure, since this port may have
1828 	 * separate termios for callout and dialin.
1829 	 */
1830 	if (info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
1831 		info->normal_termios = *tty->termios;
1832 	if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
1833 		info->callout_termios = *tty->termios;
1834 
1835 	tty->closing = 1;
1836 	/*
1837 	 * At this point we stop accepting input.  To do this, we
1838 	 * disable the receive line status interrupts, and tell the
1839 	 * interrupt driver to stop checking the data ready bit in the
1840 	 * line status register.
1841 	 */
1842 	if (info->flags & ISDN_ASYNC_INITIALIZED) {
1843 		tty_wait_until_sent(tty, 3000);	/* 30 seconds timeout */
1844 		/*
1845 		 * Before we drop DTR, make sure the UART transmitter
1846 		 * has completely drained; this is especially
1847 		 * important if there is a transmit FIFO!
1848 		 */
1849 		timeout = jiffies + HZ;
1850 		while (!(info->lsr & UART_LSR_TEMT)) {
1851 			set_current_state(TASK_INTERRUPTIBLE);
1852 			schedule_timeout(20);
1853 			if (time_after(jiffies,timeout))
1854 				break;
1855 		}
1856 	}
1857 	dev->modempoll--;
1858 	isdn_tty_shutdown(info);
1859 	if (tty->driver.flush_buffer)
1860 		tty->driver.flush_buffer(tty);
1861 	tty_ldisc_flush(tty);
1862 	info->tty = 0;
1863 	info->ncarrier = 0;
1864 	tty->closing = 0;
1865 	if (info->blocked_open) {
1866 		set_current_state(TASK_INTERRUPTIBLE);
1867 		schedule_timeout(50);
1868 		wake_up_interruptible(&info->open_wait);
1869 	}
1870 	info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE |
1871 			 ISDN_ASYNC_CLOSING);
1872 	wake_up_interruptible(&info->close_wait);
1873 	restore_flags(flags);
1874 #ifdef ISDN_DEBUG_MODEM_OPEN
1875 	printk(KERN_DEBUG "isdn_tty_close normal exit\n");
1876 #endif
1877 }
1878 
1879 /*
1880  * isdn_tty_hangup() --- called by tty_hangup() when a hangup is signaled.
1881  */
1882 static void
isdn_tty_hangup(struct tty_struct * tty)1883 isdn_tty_hangup(struct tty_struct *tty)
1884 {
1885 	modem_info *info = (modem_info *) tty->driver_data;
1886 
1887 	if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_hangup"))
1888 		return;
1889 	isdn_tty_shutdown(info);
1890 	info->count = 0;
1891 	info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE);
1892 	info->tty = 0;
1893 	wake_up_interruptible(&info->open_wait);
1894 }
1895 
1896 /* This routine initializes all emulator-data.
1897  */
1898 static void
isdn_tty_reset_profile(atemu * m)1899 isdn_tty_reset_profile(atemu * m)
1900 {
1901 	m->profile[0] = 0;
1902 	m->profile[1] = 0;
1903 	m->profile[2] = 43;
1904 	m->profile[3] = 13;
1905 	m->profile[4] = 10;
1906 	m->profile[5] = 8;
1907 	m->profile[6] = 3;
1908 	m->profile[7] = 60;
1909 	m->profile[8] = 2;
1910 	m->profile[9] = 6;
1911 	m->profile[10] = 7;
1912 	m->profile[11] = 70;
1913 	m->profile[12] = 0x45;
1914 	m->profile[13] = 4;
1915 	m->profile[14] = ISDN_PROTO_L2_X75I;
1916 	m->profile[15] = ISDN_PROTO_L3_TRANS;
1917 	m->profile[16] = ISDN_SERIAL_XMIT_SIZE / 16;
1918 	m->profile[17] = ISDN_MODEM_WINSIZE;
1919 	m->profile[18] = 4;
1920 	m->profile[19] = 0;
1921 	m->profile[20] = 0;
1922 	m->profile[23] = 0;
1923 	m->pmsn[0] = '\0';
1924 	m->plmsn[0] = '\0';
1925 }
1926 
1927 #ifdef CONFIG_ISDN_AUDIO
1928 static void
isdn_tty_modem_reset_vpar(atemu * m)1929 isdn_tty_modem_reset_vpar(atemu * m)
1930 {
1931 	m->vpar[0] = 2;         /* Voice-device            (2 = phone line) */
1932 	m->vpar[1] = 0;         /* Silence detection level (0 = none      ) */
1933 	m->vpar[2] = 70;        /* Silence interval        (7 sec.        ) */
1934 	m->vpar[3] = 2;         /* Compression type        (1 = ADPCM-2   ) */
1935 	m->vpar[4] = 0;         /* DTMF detection level    (0 = softcode  ) */
1936 	m->vpar[5] = 8;         /* DTMF interval           (8 * 5 ms.     ) */
1937 }
1938 #endif
1939 
1940 #ifdef CONFIG_ISDN_TTY_FAX
1941 static void
isdn_tty_modem_reset_faxpar(modem_info * info)1942 isdn_tty_modem_reset_faxpar(modem_info * info)
1943 {
1944 	T30_s *f = info->fax;
1945 
1946 	f->code = 0;
1947 	f->phase = ISDN_FAX_PHASE_IDLE;
1948 	f->direction = 0;
1949 	f->resolution = 1;	/* fine */
1950 	f->rate = 5;		/* 14400 bit/s */
1951 	f->width = 0;
1952 	f->length = 0;
1953 	f->compression = 0;
1954 	f->ecm = 0;
1955 	f->binary = 0;
1956 	f->scantime = 0;
1957 	memset(&f->id[0], 32, FAXIDLEN - 1);
1958 	f->id[FAXIDLEN - 1] = 0;
1959 	f->badlin = 0;
1960 	f->badmul = 0;
1961 	f->bor = 0;
1962 	f->nbc = 0;
1963 	f->cq = 0;
1964 	f->cr = 0;
1965 	f->ctcrty = 0;
1966 	f->minsp = 0;
1967 	f->phcto = 30;
1968 	f->rel = 0;
1969 	memset(&f->pollid[0], 32, FAXIDLEN - 1);
1970 	f->pollid[FAXIDLEN - 1] = 0;
1971 }
1972 #endif
1973 
1974 static void
isdn_tty_modem_reset_regs(modem_info * info,int force)1975 isdn_tty_modem_reset_regs(modem_info * info, int force)
1976 {
1977 	atemu *m = &info->emu;
1978 	if ((m->mdmreg[REG_DTRR] & BIT_DTRR) || force) {
1979 		memcpy(m->mdmreg, m->profile, ISDN_MODEM_NUMREG);
1980 		memcpy(m->msn, m->pmsn, ISDN_MSNLEN);
1981 		memcpy(m->lmsn, m->plmsn, ISDN_LMSNLEN);
1982 		info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
1983 	}
1984 #ifdef CONFIG_ISDN_AUDIO
1985 	isdn_tty_modem_reset_vpar(m);
1986 #endif
1987 #ifdef CONFIG_ISDN_TTY_FAX
1988 	isdn_tty_modem_reset_faxpar(info);
1989 #endif
1990 	m->mdmcmdl = 0;
1991 }
1992 
1993 static void
modem_write_profile(atemu * m)1994 modem_write_profile(atemu * m)
1995 {
1996 	memcpy(m->profile, m->mdmreg, ISDN_MODEM_NUMREG);
1997 	memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
1998 	memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
1999 	if (dev->profd)
2000 		send_sig(SIGIO, dev->profd, 1);
2001 }
2002 
2003 int
isdn_tty_modem_init(void)2004 isdn_tty_modem_init(void)
2005 {
2006 	modem *m;
2007 	int i;
2008 	modem_info *info;
2009 
2010 	m = &dev->mdm;
2011 	memset(&m->tty_modem, 0, sizeof(struct tty_driver));
2012 	m->tty_modem.magic = TTY_DRIVER_MAGIC;
2013 	m->tty_modem.name = isdn_ttyname_ttyI;
2014 	m->tty_modem.major = ISDN_TTY_MAJOR;
2015 	m->tty_modem.minor_start = 0;
2016 	m->tty_modem.num = ISDN_MAX_CHANNELS;
2017 	m->tty_modem.type = TTY_DRIVER_TYPE_SERIAL;
2018 	m->tty_modem.subtype = ISDN_SERIAL_TYPE_NORMAL;
2019 	m->tty_modem.init_termios = tty_std_termios;
2020 	m->tty_modem.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2021 	m->tty_modem.flags = TTY_DRIVER_REAL_RAW;
2022 	m->tty_modem.refcount = &m->refcount;
2023 	m->tty_modem.table = m->modem_table;
2024 	m->tty_modem.termios = m->modem_termios;
2025 	m->tty_modem.termios_locked = m->modem_termios_locked;
2026 	m->tty_modem.open = isdn_tty_open;
2027 	m->tty_modem.close = isdn_tty_close;
2028 	m->tty_modem.write = isdn_tty_write;
2029 	m->tty_modem.put_char = NULL;
2030 	m->tty_modem.flush_chars = isdn_tty_flush_chars;
2031 	m->tty_modem.write_room = isdn_tty_write_room;
2032 	m->tty_modem.chars_in_buffer = isdn_tty_chars_in_buffer;
2033 	m->tty_modem.flush_buffer = isdn_tty_flush_buffer;
2034 	m->tty_modem.ioctl = isdn_tty_ioctl;
2035 	m->tty_modem.throttle = isdn_tty_throttle;
2036 	m->tty_modem.unthrottle = isdn_tty_unthrottle;
2037 	m->tty_modem.set_termios = isdn_tty_set_termios;
2038 	m->tty_modem.stop = NULL;
2039 	m->tty_modem.start = NULL;
2040 	m->tty_modem.hangup = isdn_tty_hangup;
2041 	m->tty_modem.driver_name = "isdn_tty";
2042 	/*
2043 	 * The callout device is just like normal device except for
2044 	 * major number and the subtype code.
2045 	 */
2046 	m->cua_modem = m->tty_modem;
2047 	m->cua_modem.name = isdn_ttyname_cui;
2048 	m->cua_modem.major = ISDN_TTYAUX_MAJOR;
2049 	m->tty_modem.minor_start = 0;
2050 	m->cua_modem.subtype = ISDN_SERIAL_TYPE_CALLOUT;
2051 
2052 	if (tty_register_driver(&m->tty_modem)) {
2053 		printk(KERN_WARNING "isdn_tty: Couldn't register modem-device\n");
2054 		return -1;
2055 	}
2056 	if (tty_register_driver(&m->cua_modem)) {
2057 		printk(KERN_WARNING "isdn_tty: Couldn't register modem-callout-device\n");
2058 		return -2;
2059 	}
2060 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
2061 		info = &m->info[i];
2062 #ifdef CONFIG_ISDN_TTY_FAX
2063 		if (!(info->fax = kmalloc(sizeof(T30_s), GFP_KERNEL))) {
2064 			printk(KERN_ERR "Could not allocate fax t30-buffer\n");
2065 			return -3;
2066 		}
2067 #endif
2068 		init_MUTEX(&info->write_sem);
2069 		sprintf(info->last_cause, "0000");
2070 		sprintf(info->last_num, "none");
2071 		info->last_dir = 0;
2072 		info->last_lhup = 1;
2073 		info->last_l2 = -1;
2074 		info->last_si = 0;
2075 		isdn_tty_reset_profile(&info->emu);
2076 		isdn_tty_modem_reset_regs(info, 1);
2077 		info->magic = ISDN_ASYNC_MAGIC;
2078 		info->line = i;
2079 		info->tty = 0;
2080 		info->x_char = 0;
2081 		info->count = 0;
2082 		info->blocked_open = 0;
2083 		info->callout_termios = m->cua_modem.init_termios;
2084 		info->normal_termios = m->tty_modem.init_termios;
2085 		init_waitqueue_head(&info->open_wait);
2086 		init_waitqueue_head(&info->close_wait);
2087 		info->isdn_driver = -1;
2088 		info->isdn_channel = -1;
2089 		info->drv_index = -1;
2090 		info->xmit_size = ISDN_SERIAL_XMIT_SIZE;
2091 		skb_queue_head_init(&info->xmit_queue);
2092 #ifdef CONFIG_ISDN_AUDIO
2093 		skb_queue_head_init(&info->dtmf_queue);
2094 #endif
2095 		if (!(info->xmit_buf = kmalloc(ISDN_SERIAL_XMIT_MAX + 5, GFP_KERNEL))) {
2096 			printk(KERN_ERR "Could not allocate modem xmit-buffer\n");
2097 			return -3;
2098 		}
2099 		/* Make room for T.70 header */
2100 		info->xmit_buf += 4;
2101 	}
2102 	return 0;
2103 }
2104 
2105 
2106 /*
2107  * isdn_tty_match_icall(char *MSN, atemu *tty_emulator, int dev_idx)
2108  *      match the MSN against the MSNs (glob patterns) defined for tty_emulator,
2109  *      and return 0 for match, 1 for no match, 2 if MSN could match if longer.
2110  */
2111 
2112 static int
isdn_tty_match_icall(char * cid,atemu * emu,int di)2113 isdn_tty_match_icall(char *cid, atemu *emu, int di)
2114 {
2115 #ifdef ISDN_DEBUG_MODEM_ICALL
2116 	printk(KERN_DEBUG "m_fi: msn=%s lmsn=%s mmsn=%s mreg[SI1]=%d mreg[SI2]=%d\n",
2117 	       emu->msn, emu->lmsn, isdn_map_eaz2msn(emu->msn, di),
2118 	       emu->mdmreg[REG_SI1], emu->mdmreg[REG_SI2]);
2119 #endif
2120 	if (strlen(emu->lmsn)) {
2121 		char *p = emu->lmsn;
2122 		char *q;
2123 		int  tmp;
2124 		int  ret = 0;
2125 
2126 		while (1) {
2127 			if ((q = strchr(p, ';')))
2128 				*q = '\0';
2129 			if ((tmp = isdn_msncmp(cid, isdn_map_eaz2msn(p, di))) > ret)
2130 				ret = tmp;
2131 #ifdef ISDN_DEBUG_MODEM_ICALL
2132 			printk(KERN_DEBUG "m_fi: lmsnX=%s mmsn=%s -> tmp=%d\n",
2133 			       p, isdn_map_eaz2msn(emu->msn, di), tmp);
2134 #endif
2135 			if (q) {
2136 				*q = ';';
2137 				p = q;
2138 				p++;
2139 			}
2140 			if (!tmp)
2141 				return 0;
2142 			if (!q)
2143 				break;
2144 		}
2145 		return ret;
2146 	} else {
2147 		int tmp;
2148 		tmp = isdn_msncmp(cid, isdn_map_eaz2msn(emu->msn, di));
2149 #ifdef ISDN_DEBUG_MODEM_ICALL
2150 			printk(KERN_DEBUG "m_fi: mmsn=%s -> tmp=%d\n",
2151 			       isdn_map_eaz2msn(emu->msn, di), tmp);
2152 #endif
2153 		return tmp;
2154 	}
2155 }
2156 
2157 /*
2158  * An incoming call-request has arrived.
2159  * Search the tty-devices for an appropriate device and bind
2160  * it to the ISDN-Channel.
2161  * Return:
2162  *
2163  *  0 = No matching device found.
2164  *  1 = A matching device found.
2165  *  3 = No match found, but eventually would match, if
2166  *      CID is longer.
2167  */
2168 int
isdn_tty_find_icall(int di,int ch,setup_parm * setup)2169 isdn_tty_find_icall(int di, int ch, setup_parm *setup)
2170 {
2171 	char *eaz;
2172 	int i;
2173 	int wret;
2174 	int idx;
2175 	int si1;
2176 	int si2;
2177 	char *nr;
2178 	ulong flags;
2179 
2180 	if (!setup->phone[0]) {
2181 		nr = "0";
2182 		printk(KERN_INFO "isdn_tty: Incoming call without OAD, assuming '0'\n");
2183 	} else
2184 		nr = setup->phone;
2185 	si1 = (int) setup->si1;
2186 	si2 = (int) setup->si2;
2187 	if (!setup->eazmsn[0]) {
2188 		printk(KERN_WARNING "isdn_tty: Incoming call without CPN, assuming '0'\n");
2189 		eaz = "0";
2190 	} else
2191 		eaz = setup->eazmsn;
2192 #ifdef ISDN_DEBUG_MODEM_ICALL
2193 	printk(KERN_DEBUG "m_fi: eaz=%s si1=%d si2=%d\n", eaz, si1, si2);
2194 #endif
2195 	wret = 0;
2196 	save_flags(flags);
2197 	cli();
2198 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
2199 		modem_info *info = &dev->mdm.info[i];
2200 
2201                 if (info->count == 0)
2202                     continue;
2203 		if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) &&  /* SI1 is matching */
2204 		    (info->emu.mdmreg[REG_SI2] == si2))	{         /* SI2 is matching */
2205 			idx = isdn_dc2minor(di, ch);
2206 #ifdef ISDN_DEBUG_MODEM_ICALL
2207 			printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret);
2208 			printk(KERN_DEBUG "m_fi: idx=%d flags=%08lx drv=%d ch=%d usg=%d\n", idx,
2209 			       info->flags, info->isdn_driver, info->isdn_channel,
2210 			       dev->usage[idx]);
2211 #endif
2212 			if (
2213 #ifndef FIX_FILE_TRANSFER
2214 				(info->flags & ISDN_ASYNC_NORMAL_ACTIVE) &&
2215 #endif
2216 				(info->isdn_driver == -1) &&
2217 				(info->isdn_channel == -1) &&
2218 				(USG_NONE(dev->usage[idx]))) {
2219 				int matchret;
2220 
2221 				if ((matchret = isdn_tty_match_icall(eaz, &info->emu, di)) > wret)
2222 					wret = matchret;
2223 				if (!matchret) {                  /* EAZ is matching */
2224 					info->isdn_driver = di;
2225 					info->isdn_channel = ch;
2226 					info->drv_index = idx;
2227 					dev->m_idx[idx] = info->line;
2228 					dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
2229 					dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]);
2230 					strcpy(dev->num[idx], nr);
2231 					strcpy(info->emu.cpn, eaz);
2232 					info->emu.mdmreg[REG_SI1I] = si2bit[si1];
2233 					info->emu.mdmreg[REG_PLAN] = setup->plan;
2234 					info->emu.mdmreg[REG_SCREEN] = setup->screen;
2235 					isdn_info_update();
2236 					restore_flags(flags);
2237 					printk(KERN_INFO "isdn_tty: call from %s, -> RING on ttyI%d\n", nr,
2238 					       info->line);
2239 					info->msr |= UART_MSR_RI;
2240 					isdn_tty_modem_result(RESULT_RING, info);
2241 					isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1);
2242 					return 1;
2243 				}
2244 			}
2245 		}
2246 	}
2247 	restore_flags(flags);
2248 	printk(KERN_INFO "isdn_tty: call from %s -> %s %s\n", nr, eaz,
2249 	       ((dev->drv[di]->flags & DRV_FLAG_REJBUS) && (wret != 2))? "rejected" : "ignored");
2250 	return (wret == 2)?3:0;
2251 }
2252 
2253 #define TTY_IS_ACTIVE(info) \
2254 	(info->flags & (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE))
2255 
2256 int
isdn_tty_stat_callback(int i,isdn_ctrl * c)2257 isdn_tty_stat_callback(int i, isdn_ctrl *c)
2258 {
2259 	int mi;
2260 	modem_info *info;
2261 	char *e;
2262 
2263 	if (i < 0)
2264 		return 0;
2265 	if ((mi = dev->m_idx[i]) >= 0) {
2266 		info = &dev->mdm.info[mi];
2267 		switch (c->command) {
2268                         case ISDN_STAT_CINF:
2269                                 printk(KERN_DEBUG "CHARGEINFO on ttyI%d: %ld %s\n", info->line, c->arg, c->parm.num);
2270                                 info->emu.charge = (unsigned) simple_strtoul(c->parm.num, &e, 10);
2271                                 if (e == (char *)c->parm.num)
2272 					info->emu.charge = 0;
2273 
2274                                 break;
2275 			case ISDN_STAT_BSENT:
2276 #ifdef ISDN_TTY_STAT_DEBUG
2277 				printk(KERN_DEBUG "tty_STAT_BSENT ttyI%d\n", info->line);
2278 #endif
2279 				if ((info->isdn_driver == c->driver) &&
2280 				    (info->isdn_channel == c->arg)) {
2281 					info->msr |= UART_MSR_CTS;
2282 					if (info->send_outstanding)
2283 						if (!(--info->send_outstanding))
2284 							info->lsr |= UART_LSR_TEMT;
2285 					isdn_tty_tint(info);
2286 					return 1;
2287 				}
2288 				break;
2289 			case ISDN_STAT_CAUSE:
2290 #ifdef ISDN_TTY_STAT_DEBUG
2291 				printk(KERN_DEBUG "tty_STAT_CAUSE ttyI%d\n", info->line);
2292 #endif
2293 				/* Signal cause to tty-device */
2294 				strncpy(info->last_cause, c->parm.num, 5);
2295 				return 1;
2296 			case ISDN_STAT_DISPLAY:
2297 #ifdef ISDN_TTY_STAT_DEBUG
2298 				printk(KERN_DEBUG "tty_STAT_DISPLAY ttyI%d\n", info->line);
2299 #endif
2300 				/* Signal display to tty-device */
2301 				if ((info->emu.mdmreg[REG_DISPLAY] & BIT_DISPLAY) &&
2302 					!(info->emu.mdmreg[REG_RESPNUM] & BIT_RESPNUM)) {
2303 				  isdn_tty_at_cout("\r\n", info);
2304 				  isdn_tty_at_cout("DISPLAY: ", info);
2305 				  isdn_tty_at_cout(c->parm.display, info);
2306 				  isdn_tty_at_cout("\r\n", info);
2307 				}
2308 				return 1;
2309 			case ISDN_STAT_DCONN:
2310 #ifdef ISDN_TTY_STAT_DEBUG
2311 				printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line);
2312 #endif
2313 				if (TTY_IS_ACTIVE(info)) {
2314 					if (info->dialing == 1) {
2315 						info->dialing = 2;
2316 						return 1;
2317 					}
2318 				}
2319 				break;
2320 			case ISDN_STAT_DHUP:
2321 #ifdef ISDN_TTY_STAT_DEBUG
2322 				printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line);
2323 #endif
2324 				if (TTY_IS_ACTIVE(info)) {
2325 					if (info->dialing == 1)
2326 						isdn_tty_modem_result(RESULT_BUSY, info);
2327 					if (info->dialing > 1)
2328 						isdn_tty_modem_result(RESULT_NO_CARRIER, info);
2329 					info->dialing = 0;
2330 #ifdef ISDN_DEBUG_MODEM_HUP
2331 					printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n");
2332 #endif
2333 					isdn_tty_modem_hup(info, 0);
2334 					return 1;
2335 				}
2336 				break;
2337 			case ISDN_STAT_BCONN:
2338 #ifdef ISDN_TTY_STAT_DEBUG
2339 				printk(KERN_DEBUG "tty_STAT_BCONN ttyI%d\n", info->line);
2340 #endif
2341 				/* Wake up any processes waiting
2342 				 * for incoming call of this device when
2343 				 * DCD follow the state of incoming carrier
2344 				 */
2345 				if (info->blocked_open &&
2346 				   (info->emu.mdmreg[REG_DCD] & BIT_DCD)) {
2347 					wake_up_interruptible(&info->open_wait);
2348 				}
2349 
2350 				/* Schedule CONNECT-Message to any tty
2351 				 * waiting for it and
2352 				 * set DCD-bit of its modem-status.
2353 				 */
2354 				if (TTY_IS_ACTIVE(info) ||
2355 				    (info->blocked_open && (info->emu.mdmreg[REG_DCD] & BIT_DCD))) {
2356 					info->msr |= UART_MSR_DCD;
2357 					info->emu.charge = 0;
2358 					if (info->dialing & 0xf)
2359 						info->last_dir = 1;
2360 					else
2361 						info->last_dir = 0;
2362 					info->dialing = 0;
2363 					info->rcvsched = 1;
2364 					if (USG_MODEM(dev->usage[i])) {
2365 						if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) {
2366 							strcpy(info->emu.connmsg, c->parm.num);
2367 							isdn_tty_modem_result(RESULT_CONNECT, info);
2368 						} else
2369 							isdn_tty_modem_result(RESULT_CONNECT64000, info);
2370 					}
2371 					if (USG_VOICE(dev->usage[i]))
2372 						isdn_tty_modem_result(RESULT_VCON, info);
2373 					return 1;
2374 				}
2375 				break;
2376 			case ISDN_STAT_BHUP:
2377 #ifdef ISDN_TTY_STAT_DEBUG
2378 				printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line);
2379 #endif
2380 				if (TTY_IS_ACTIVE(info)) {
2381 #ifdef ISDN_DEBUG_MODEM_HUP
2382 					printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n");
2383 #endif
2384 					isdn_tty_modem_hup(info, 0);
2385 					return 1;
2386 				}
2387 				break;
2388 			case ISDN_STAT_NODCH:
2389 #ifdef ISDN_TTY_STAT_DEBUG
2390 				printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line);
2391 #endif
2392 				if (TTY_IS_ACTIVE(info)) {
2393 					if (info->dialing) {
2394 						info->dialing = 0;
2395 						info->last_l2 = -1;
2396 						info->last_si = 0;
2397 						sprintf(info->last_cause, "0000");
2398 						isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
2399 					}
2400 					isdn_tty_modem_hup(info, 0);
2401 					return 1;
2402 				}
2403 				break;
2404 			case ISDN_STAT_UNLOAD:
2405 #ifdef ISDN_TTY_STAT_DEBUG
2406 				printk(KERN_DEBUG "tty_STAT_UNLOAD ttyI%d\n", info->line);
2407 #endif
2408 				for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
2409 					info = &dev->mdm.info[i];
2410 					if (info->isdn_driver == c->driver) {
2411 						if (info->online)
2412 							isdn_tty_modem_hup(info, 1);
2413 					}
2414 				}
2415 				return 1;
2416 #ifdef CONFIG_ISDN_TTY_FAX
2417 			case ISDN_STAT_FAXIND:
2418 				if (TTY_IS_ACTIVE(info)) {
2419 					isdn_tty_fax_command(info, c);
2420 				}
2421 				break;
2422 #endif
2423 #ifdef CONFIG_ISDN_AUDIO
2424 			case ISDN_STAT_AUDIO:
2425 				if (TTY_IS_ACTIVE(info)) {
2426 					switch(c->parm.num[0]) {
2427 						case ISDN_AUDIO_DTMF:
2428 							if (info->vonline) {
2429 								isdn_audio_put_dle_code(info,
2430 									c->parm.num[1]);
2431 							}
2432 							break;
2433 					}
2434 				}
2435 				break;
2436 #endif
2437 		}
2438 	}
2439 	return 0;
2440 }
2441 
2442 /*********************************************************************
2443  Modem-Emulator-Routines
2444  *********************************************************************/
2445 
2446 #define cmdchar(c) ((c>=' ')&&(c<=0x7f))
2447 
2448 /*
2449  * Put a message from the AT-emulator into receive-buffer of tty,
2450  * convert CR, LF, and BS to values in modem-registers 3, 4 and 5.
2451  */
2452 void
isdn_tty_at_cout(char * msg,modem_info * info)2453 isdn_tty_at_cout(char *msg, modem_info * info)
2454 {
2455 	struct tty_struct *tty;
2456 	atemu *m = &info->emu;
2457 	char *p;
2458 	char c;
2459 	ulong flags;
2460 	struct sk_buff *skb = 0;
2461 	char *sp = 0;
2462 
2463 	if (!msg) {
2464 		printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n");
2465 		return;
2466 	}
2467 	save_flags(flags);
2468 	cli();
2469 	tty = info->tty;
2470 	if ((info->flags & ISDN_ASYNC_CLOSING) || (!tty)) {
2471 		restore_flags(flags);
2472 		return;
2473 	}
2474 
2475 	/* use queue instead of direct flip, if online and */
2476 	/* data is in queue or flip buffer is full */
2477 	if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) ||
2478 	    (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) {
2479 		skb = alloc_skb(strlen(msg)
2480 #ifdef CONFIG_ISDN_AUDIO
2481 			+ sizeof(isdn_audio_skb)
2482 #endif
2483 			, GFP_ATOMIC);
2484 		if (!skb) {
2485 			restore_flags(flags);
2486 			return;
2487 		}
2488 #ifdef CONFIG_ISDN_AUDIO
2489 		skb_reserve(skb, sizeof(isdn_audio_skb));
2490 #endif
2491 		sp = skb_put(skb, strlen(msg));
2492 #ifdef CONFIG_ISDN_AUDIO
2493 		ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
2494 		ISDN_AUDIO_SKB_LOCK(skb) = 0;
2495 #endif
2496 	}
2497 
2498 	for (p = msg; *p; p++) {
2499 		switch (*p) {
2500 			case '\r':
2501 				c = m->mdmreg[REG_CR];
2502 				break;
2503 			case '\n':
2504 				c = m->mdmreg[REG_LF];
2505 				break;
2506 			case '\b':
2507 				c = m->mdmreg[REG_BS];
2508 				break;
2509 			default:
2510 				c = *p;
2511 		}
2512 		if (skb) {
2513 			*sp++ = c;
2514 		} else {
2515 			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
2516 				break;
2517 			tty_insert_flip_char(tty, c, 0);
2518 		}
2519 	}
2520 	if (skb) {
2521 		__skb_queue_tail(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel], skb);
2522 		dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len;
2523 		restore_flags(flags);
2524 		/* Schedule dequeuing */
2525 		if ((dev->modempoll) && (info->rcvsched))
2526 			isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
2527 
2528 	} else {
2529 		restore_flags(flags);
2530 		queue_task(&tty->flip.tqueue, &tq_timer);
2531 	}
2532 }
2533 
2534 /*
2535  * Perform ATH Hangup
2536  */
2537 static void
isdn_tty_on_hook(modem_info * info)2538 isdn_tty_on_hook(modem_info * info)
2539 {
2540 	if (info->isdn_channel >= 0) {
2541 #ifdef ISDN_DEBUG_MODEM_HUP
2542 		printk(KERN_DEBUG "Mhup in isdn_tty_on_hook\n");
2543 #endif
2544 		isdn_tty_modem_hup(info, 1);
2545 	}
2546 }
2547 
2548 static void
isdn_tty_off_hook(void)2549 isdn_tty_off_hook(void)
2550 {
2551 	printk(KERN_DEBUG "isdn_tty_off_hook\n");
2552 }
2553 
2554 #define PLUSWAIT1 (HZ/2)        /* 0.5 sec. */
2555 #define PLUSWAIT2 (HZ*3/2)      /* 1.5 sec */
2556 
2557 /*
2558  * Check Buffer for Modem-escape-sequence, activate timer-callback to
2559  * isdn_tty_modem_escape() if sequence found.
2560  *
2561  * Parameters:
2562  *   p          pointer to databuffer
2563  *   plus       escape-character
2564  *   count      length of buffer
2565  *   pluscount  count of valid escape-characters so far
2566  *   lastplus   timestamp of last character
2567  */
2568 static void
isdn_tty_check_esc(const u_char * p,u_char plus,int count,int * pluscount,int * lastplus,int from_user)2569 isdn_tty_check_esc(const u_char * p, u_char plus, int count, int *pluscount,
2570 		   int *lastplus, int from_user)
2571 {
2572 	char cbuf[3];
2573 
2574 	if (plus > 127)
2575 		return;
2576 	if (count > 3) {
2577 		p += count - 3;
2578 		count = 3;
2579 		*pluscount = 0;
2580 	}
2581 	if (from_user) {
2582 		copy_from_user(cbuf, p, count);
2583 		p = cbuf;
2584 	}
2585 	while (count > 0) {
2586 		if (*(p++) == plus) {
2587 			if ((*pluscount)++) {
2588 				/* Time since last '+' > 0.5 sec. ? */
2589 				if (time_after(jiffies, *lastplus + PLUSWAIT1))
2590 					*pluscount = 1;
2591 			} else {
2592 				/* Time since last non-'+' < 1.5 sec. ? */
2593 				if (time_before(jiffies, *lastplus + PLUSWAIT2))
2594 					*pluscount = 0;
2595 			}
2596 			if ((*pluscount == 3) && (count == 1))
2597 				isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, 1);
2598 			if (*pluscount > 3)
2599 				*pluscount = 1;
2600 		} else
2601 			*pluscount = 0;
2602 		*lastplus = jiffies;
2603 		count--;
2604 	}
2605 }
2606 
2607 /*
2608  * Return result of AT-emulator to tty-receive-buffer, depending on
2609  * modem-register 12, bit 0 and 1.
2610  * For CONNECT-messages also switch to online-mode.
2611  * For RING-message handle auto-ATA if register 0 != 0
2612  */
2613 
2614 static void
isdn_tty_modem_result(int code,modem_info * info)2615 isdn_tty_modem_result(int code, modem_info * info)
2616 {
2617 	atemu *m = &info->emu;
2618 	static char *msg[] =
2619 	{"OK", "CONNECT", "RING", "NO CARRIER", "ERROR",
2620 	 "CONNECT 64000", "NO DIALTONE", "BUSY", "NO ANSWER",
2621 	 "RINGING", "NO MSN/EAZ", "VCON", "RUNG"};
2622 	ulong flags;
2623 	char s[ISDN_MSNLEN+10];
2624 
2625 	switch (code) {
2626 		case RESULT_RING:
2627 			m->mdmreg[REG_RINGCNT]++;
2628 			if (m->mdmreg[REG_RINGCNT] == m->mdmreg[REG_RINGATA])
2629 				/* Automatically accept incoming call */
2630 				isdn_tty_cmd_ATA(info);
2631 			break;
2632 		case RESULT_NO_CARRIER:
2633 #ifdef ISDN_DEBUG_MODEM_HUP
2634 			printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
2635 			       (info->flags & ISDN_ASYNC_CLOSING),
2636 			       (!info->tty));
2637 #endif
2638 			save_flags(flags);
2639 			cli();
2640 			m->mdmreg[REG_RINGCNT] = 0;
2641 			del_timer(&info->nc_timer);
2642 			info->ncarrier = 0;
2643 			if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
2644 				restore_flags(flags);
2645 				return;
2646 			}
2647 			restore_flags(flags);
2648 #ifdef CONFIG_ISDN_AUDIO
2649 			if (info->vonline & 1) {
2650 #ifdef ISDN_DEBUG_MODEM_VOICE
2651 				printk(KERN_DEBUG "res3: send DLE-ETX on ttyI%d\n",
2652 				       info->line);
2653 #endif
2654 				/* voice-recording, add DLE-ETX */
2655 				isdn_tty_at_cout("\020\003", info);
2656 			}
2657 			if (info->vonline & 2) {
2658 #ifdef ISDN_DEBUG_MODEM_VOICE
2659 				printk(KERN_DEBUG "res3: send DLE-DC4 on ttyI%d\n",
2660 				       info->line);
2661 #endif
2662 				/* voice-playing, add DLE-DC4 */
2663 				isdn_tty_at_cout("\020\024", info);
2664 			}
2665 #endif
2666 			break;
2667 		case RESULT_CONNECT:
2668 		case RESULT_CONNECT64000:
2669 			sprintf(info->last_cause, "0000");
2670 			if (!info->online)
2671 				info->online = 2;
2672 			break;
2673 		case RESULT_VCON:
2674 #ifdef ISDN_DEBUG_MODEM_VOICE
2675 			printk(KERN_DEBUG "res3: send VCON on ttyI%d\n",
2676 			       info->line);
2677 #endif
2678 			sprintf(info->last_cause, "0000");
2679 			if (!info->online)
2680 				info->online = 1;
2681 			break;
2682 	} /* switch(code) */
2683 
2684 	if (m->mdmreg[REG_RESP] & BIT_RESP) {
2685 		/* Show results */
2686 		if (m->mdmreg[REG_RESPNUM] & BIT_RESPNUM) {
2687 			/* Show numeric results only */
2688 			sprintf(s, "\r\n%d\r\n", code);
2689 			isdn_tty_at_cout(s, info);
2690 		} else {
2691 			if (code == RESULT_RING) {
2692 			    /* return if "show RUNG" and ringcounter>1 */
2693 			    if ((m->mdmreg[REG_RUNG] & BIT_RUNG) &&
2694 				    (m->mdmreg[REG_RINGCNT] > 1))
2695 						return;
2696 			    /* print CID, _before_ _every_ ring */
2697 			    if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) {
2698 				    isdn_tty_at_cout("\r\nCALLER NUMBER: ", info);
2699 				    isdn_tty_at_cout(dev->num[info->drv_index], info);
2700 				    if (m->mdmreg[REG_CDN] & BIT_CDN) {
2701 					    isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
2702 					    isdn_tty_at_cout(info->emu.cpn, info);
2703 				    }
2704 			    }
2705 			}
2706 			isdn_tty_at_cout("\r\n", info);
2707 			isdn_tty_at_cout(msg[code], info);
2708 			switch (code) {
2709 				case RESULT_CONNECT:
2710 					switch (m->mdmreg[REG_L2PROT]) {
2711 						case ISDN_PROTO_L2_MODEM:
2712 							isdn_tty_at_cout(" ", info);
2713 							isdn_tty_at_cout(m->connmsg, info);
2714 							break;
2715 					}
2716 					break;
2717 				case RESULT_RING:
2718 					/* Append CPN, if enabled */
2719 					if ((m->mdmreg[REG_CPN] & BIT_CPN)) {
2720 						sprintf(s, "/%s", m->cpn);
2721 						isdn_tty_at_cout(s, info);
2722 					}
2723 					/* Print CID only once, _after_ 1st RING */
2724 					if ((m->mdmreg[REG_CIDONCE] & BIT_CIDONCE) &&
2725 					    (m->mdmreg[REG_RINGCNT] == 1)) {
2726 						isdn_tty_at_cout("\r\n", info);
2727 						isdn_tty_at_cout("CALLER NUMBER: ", info);
2728 						isdn_tty_at_cout(dev->num[info->drv_index], info);
2729 						if (m->mdmreg[REG_CDN] & BIT_CDN) {
2730 							isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
2731 							isdn_tty_at_cout(info->emu.cpn, info);
2732 						}
2733 					}
2734 					break;
2735 				case RESULT_NO_CARRIER:
2736 				case RESULT_NO_DIALTONE:
2737 				case RESULT_BUSY:
2738 				case RESULT_NO_ANSWER:
2739 					m->mdmreg[REG_RINGCNT] = 0;
2740 					/* Append Cause-Message if enabled */
2741 					if (m->mdmreg[REG_RESPXT] & BIT_RESPXT) {
2742 						sprintf(s, "/%s", info->last_cause);
2743 						isdn_tty_at_cout(s, info);
2744 					}
2745 					break;
2746 				case RESULT_CONNECT64000:
2747 					/* Append Protocol to CONNECT message */
2748 					switch (m->mdmreg[REG_L2PROT]) {
2749 						case ISDN_PROTO_L2_X75I:
2750 						case ISDN_PROTO_L2_X75UI:
2751 						case ISDN_PROTO_L2_X75BUI:
2752 							isdn_tty_at_cout("/X.75", info);
2753 							break;
2754 						case ISDN_PROTO_L2_HDLC:
2755 							isdn_tty_at_cout("/HDLC", info);
2756 							break;
2757 						case ISDN_PROTO_L2_V11096:
2758 							isdn_tty_at_cout("/V110/9600", info);
2759 							break;
2760 						case ISDN_PROTO_L2_V11019:
2761 							isdn_tty_at_cout("/V110/19200", info);
2762 							break;
2763 						case ISDN_PROTO_L2_V11038:
2764 							isdn_tty_at_cout("/V110/38400", info);
2765 							break;
2766 					}
2767 					if (m->mdmreg[REG_T70] & BIT_T70) {
2768 						isdn_tty_at_cout("/T.70", info);
2769 						if (m->mdmreg[REG_T70] & BIT_T70_EXT)
2770 							isdn_tty_at_cout("+", info);
2771 					}
2772 					break;
2773 			}
2774 			isdn_tty_at_cout("\r\n", info);
2775 		}
2776 	}
2777 	if (code == RESULT_NO_CARRIER) {
2778 		save_flags(flags);
2779 		cli();
2780 		if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
2781 			restore_flags(flags);
2782 			return;
2783 		}
2784 		tty_ldisc_flush(info->tty);
2785 		if ((info->flags & ISDN_ASYNC_CHECK_CD) &&
2786 		    (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
2787 		       (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) {
2788 			tty_hangup(info->tty);
2789 		}
2790 		restore_flags(flags);
2791 	}
2792 }
2793 
2794 
2795 /*
2796  * Display a modem-register-value.
2797  */
2798 static void
isdn_tty_show_profile(int ridx,modem_info * info)2799 isdn_tty_show_profile(int ridx, modem_info * info)
2800 {
2801 	char v[6];
2802 
2803 	sprintf(v, "\r\n%d", info->emu.mdmreg[ridx]);
2804 	isdn_tty_at_cout(v, info);
2805 }
2806 
2807 /*
2808  * Get MSN-string from char-pointer, set pointer to end of number
2809  */
2810 static void
isdn_tty_get_msnstr(char * n,char ** p)2811 isdn_tty_get_msnstr(char *n, char **p)
2812 {
2813 	int limit = ISDN_MSNLEN - 1;
2814 
2815 	while (((*p[0] >= '0' && *p[0] <= '9') ||
2816 		/* Why a comma ??? */
2817 		(*p[0] == ',') || (*p[0] == ':')) &&
2818 		(limit--))
2819 		*n++ = *p[0]++;
2820 	*n = '\0';
2821 }
2822 
2823 /*
2824  * Get phone-number from modem-commandbuffer
2825  */
2826 static void
isdn_tty_getdial(char * p,char * q,int cnt)2827 isdn_tty_getdial(char *p, char *q,int cnt)
2828 {
2829 	int first = 1;
2830 	int limit = ISDN_MSNLEN - 1;	/* MUST match the size of interface var to avoid
2831 					buffer overflow */
2832 
2833 	while (strchr(" 0123456789,#.*WPTS-", *p) && *p && --cnt>0) {
2834 		if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) ||
2835 		    (*p == '*') || (*p == '#')) {
2836 			*q++ = *p;
2837 			limit--;
2838 		}
2839 		if(!limit)
2840 			break;
2841 		p++;
2842 		first = 0;
2843 	}
2844 	*q = 0;
2845 }
2846 
2847 #define PARSE_ERROR { isdn_tty_modem_result(RESULT_ERROR, info); return; }
2848 #define PARSE_ERROR1 { isdn_tty_modem_result(RESULT_ERROR, info); return 1; }
2849 
2850 static void
isdn_tty_report(modem_info * info)2851 isdn_tty_report(modem_info * info)
2852 {
2853 	atemu *m = &info->emu;
2854 	char s[80];
2855 
2856 	isdn_tty_at_cout("\r\nStatistics of last connection:\r\n\r\n", info);
2857 	sprintf(s, "    Remote Number:    %s\r\n", info->last_num);
2858 	isdn_tty_at_cout(s, info);
2859 	sprintf(s, "    Direction:        %s\r\n", info->last_dir ? "outgoing" : "incoming");
2860 	isdn_tty_at_cout(s, info);
2861 	isdn_tty_at_cout("    Layer-2 Protocol: ", info);
2862 	switch (info->last_l2) {
2863 		case ISDN_PROTO_L2_X75I:
2864 			isdn_tty_at_cout("X.75i", info);
2865 			break;
2866 		case ISDN_PROTO_L2_X75UI:
2867 			isdn_tty_at_cout("X.75ui", info);
2868 			break;
2869 		case ISDN_PROTO_L2_X75BUI:
2870 			isdn_tty_at_cout("X.75bui", info);
2871 			break;
2872 		case ISDN_PROTO_L2_HDLC:
2873 			isdn_tty_at_cout("HDLC", info);
2874 			break;
2875 		case ISDN_PROTO_L2_V11096:
2876 			isdn_tty_at_cout("V.110 9600 Baud", info);
2877 			break;
2878 		case ISDN_PROTO_L2_V11019:
2879 			isdn_tty_at_cout("V.110 19200 Baud", info);
2880 			break;
2881 		case ISDN_PROTO_L2_V11038:
2882 			isdn_tty_at_cout("V.110 38400 Baud", info);
2883 			break;
2884 		case ISDN_PROTO_L2_TRANS:
2885 			isdn_tty_at_cout("transparent", info);
2886 			break;
2887 		case ISDN_PROTO_L2_MODEM:
2888 			isdn_tty_at_cout("modem", info);
2889 			break;
2890 		case ISDN_PROTO_L2_FAX:
2891 			isdn_tty_at_cout("fax", info);
2892 			break;
2893 		default:
2894 			isdn_tty_at_cout("unknown", info);
2895 			break;
2896 	}
2897 	if (m->mdmreg[REG_T70] & BIT_T70) {
2898 		isdn_tty_at_cout("/T.70", info);
2899 		if (m->mdmreg[REG_T70] & BIT_T70_EXT)
2900 			isdn_tty_at_cout("+", info);
2901 	}
2902 	isdn_tty_at_cout("\r\n", info);
2903 	isdn_tty_at_cout("    Service:          ", info);
2904 	switch (info->last_si) {
2905 		case 1:
2906 			isdn_tty_at_cout("audio\r\n", info);
2907 			break;
2908 		case 5:
2909 			isdn_tty_at_cout("btx\r\n", info);
2910 			break;
2911 		case 7:
2912 			isdn_tty_at_cout("data\r\n", info);
2913 			break;
2914 		default:
2915 			sprintf(s, "%d\r\n", info->last_si);
2916 			isdn_tty_at_cout(s, info);
2917 			break;
2918 	}
2919 	sprintf(s, "    Hangup location:  %s\r\n", info->last_lhup ? "local" : "remote");
2920 	isdn_tty_at_cout(s, info);
2921 	sprintf(s, "    Last cause:       %s\r\n", info->last_cause);
2922 	isdn_tty_at_cout(s, info);
2923 }
2924 
2925 /*
2926  * Parse AT&.. commands.
2927  */
2928 static int
isdn_tty_cmd_ATand(char ** p,modem_info * info)2929 isdn_tty_cmd_ATand(char **p, modem_info * info)
2930 {
2931 	atemu *m = &info->emu;
2932 	int i;
2933 	char rb[100];
2934 
2935 #define MAXRB (sizeof(rb) - 1)
2936 
2937 	switch (*p[0]) {
2938 		case 'B':
2939 			/* &B - Set Buffersize */
2940 			p[0]++;
2941 			i = isdn_getnum(p);
2942 			if ((i < 0) || (i > ISDN_SERIAL_XMIT_MAX))
2943 				PARSE_ERROR1;
2944 #ifdef CONFIG_ISDN_AUDIO
2945 			if ((m->mdmreg[REG_SI1] & 1) && (i > VBUF))
2946 				PARSE_ERROR1;
2947 #endif
2948 			m->mdmreg[REG_PSIZE] = i / 16;
2949 			info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
2950 			switch (m->mdmreg[REG_L2PROT]) {
2951 				case ISDN_PROTO_L2_V11096:
2952 				case ISDN_PROTO_L2_V11019:
2953 				case ISDN_PROTO_L2_V11038:
2954 					info->xmit_size /= 10;
2955 			}
2956 			break;
2957 		case 'C':
2958 			/* &C - DCD Status */
2959 			p[0]++;
2960 			switch (isdn_getnum(p)) {
2961 				case 0:
2962 					m->mdmreg[REG_DCD] &= ~BIT_DCD;
2963 					break;
2964 				case 1:
2965 					m->mdmreg[REG_DCD] |= BIT_DCD;
2966 					break;
2967 				default:
2968 					PARSE_ERROR1
2969 			}
2970 			break;
2971 		case 'D':
2972 			/* &D - Set DTR-Low-behavior */
2973 			p[0]++;
2974 			switch (isdn_getnum(p)) {
2975 				case 0:
2976 					m->mdmreg[REG_DTRHUP] &= ~BIT_DTRHUP;
2977 					m->mdmreg[REG_DTRR] &= ~BIT_DTRR;
2978 					break;
2979 				case 2:
2980 					m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP;
2981 					m->mdmreg[REG_DTRR] &= ~BIT_DTRR;
2982 					break;
2983 				case 3:
2984 					m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP;
2985 					m->mdmreg[REG_DTRR] |= BIT_DTRR;
2986 					break;
2987 				default:
2988 					PARSE_ERROR1
2989 			}
2990 			break;
2991 		case 'E':
2992 			/* &E -Set EAZ/MSN */
2993 			p[0]++;
2994 			isdn_tty_get_msnstr(m->msn, p);
2995 			break;
2996 		case 'F':
2997 			/* &F -Set Factory-Defaults */
2998 			p[0]++;
2999 			if (info->msr & UART_MSR_DCD)
3000 				PARSE_ERROR1;
3001 			isdn_tty_reset_profile(m);
3002 			isdn_tty_modem_reset_regs(info, 1);
3003 			break;
3004 #ifdef DUMMY_HAYES_AT
3005 		case 'K':
3006 			/* only for be compilant with common scripts */
3007 			/* &K Flowcontrol - no function */
3008 			p[0]++;
3009 			isdn_getnum(p);
3010 			break;
3011 #endif
3012 		case 'L':
3013 			/* &L -Set Numbers to listen on */
3014 			p[0]++;
3015 			i = 0;
3016 			while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) &&
3017 			       (i < ISDN_LMSNLEN))
3018 				m->lmsn[i++] = *p[0]++;
3019 			m->lmsn[i] = '\0';
3020 			break;
3021 		case 'R':
3022 			/* &R - Set V.110 bitrate adaption */
3023 			p[0]++;
3024 			i = isdn_getnum(p);
3025 			switch (i) {
3026 				case 0:
3027 					/* Switch off V.110, back to X.75 */
3028 					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
3029 					m->mdmreg[REG_SI2] = 0;
3030 					info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
3031 					break;
3032 				case 9600:
3033 					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11096;
3034 					m->mdmreg[REG_SI2] = 197;
3035 					info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
3036 					break;
3037 				case 19200:
3038 					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11019;
3039 					m->mdmreg[REG_SI2] = 199;
3040 					info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
3041 					break;
3042 				case 38400:
3043 					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11038;
3044 					m->mdmreg[REG_SI2] = 198; /* no existing standard for this */
3045 					info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
3046 					break;
3047 				default:
3048 					PARSE_ERROR1;
3049 			}
3050 			/* Switch off T.70 */
3051 			m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT);
3052 			/* Set Service 7 */
3053 			m->mdmreg[REG_SI1] |= 4;
3054 			break;
3055 		case 'S':
3056 			/* &S - Set Windowsize */
3057 			p[0]++;
3058 			i = isdn_getnum(p);
3059 			if ((i > 0) && (i < 9))
3060 				m->mdmreg[REG_WSIZE] = i;
3061 			else
3062 				PARSE_ERROR1;
3063 			break;
3064 		case 'V':
3065 			/* &V - Show registers */
3066 			p[0]++;
3067 			isdn_tty_at_cout("\r\n", info);
3068 			for (i = 0; i < ISDN_MODEM_NUMREG; i++) {
3069 				sprintf(rb, "S%02d=%03d%s", i,
3070 					m->mdmreg[i], ((i + 1) % 10) ? " " : "\r\n");
3071 				isdn_tty_at_cout(rb, info);
3072 			}
3073 			sprintf(rb, "\r\nEAZ/MSN: %.50s\r\n",
3074 				strlen(m->msn) ? m->msn : "None");
3075 			isdn_tty_at_cout(rb, info);
3076 			if (strlen(m->lmsn)) {
3077 				isdn_tty_at_cout("\r\nListen: ", info);
3078 				isdn_tty_at_cout(m->lmsn, info);
3079 				isdn_tty_at_cout("\r\n", info);
3080 			}
3081 			break;
3082 		case 'W':
3083 			/* &W - Write Profile */
3084 			p[0]++;
3085 			switch (*p[0]) {
3086 				case '0':
3087 					p[0]++;
3088 					modem_write_profile(m);
3089 					break;
3090 				default:
3091 					PARSE_ERROR1;
3092 			}
3093 			break;
3094 		case 'X':
3095 			/* &X - Switch to BTX-Mode and T.70 */
3096 			p[0]++;
3097 			switch (isdn_getnum(p)) {
3098 				case 0:
3099 					m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT);
3100 					info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
3101 					break;
3102 				case 1:
3103 					m->mdmreg[REG_T70] |= BIT_T70;
3104 					m->mdmreg[REG_T70] &= ~BIT_T70_EXT;
3105 					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
3106 					info->xmit_size = 112;
3107 					m->mdmreg[REG_SI1] = 4;
3108 					m->mdmreg[REG_SI2] = 0;
3109 					break;
3110 				case 2:
3111 					m->mdmreg[REG_T70] |= (BIT_T70 | BIT_T70_EXT);
3112 					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
3113 					info->xmit_size = 112;
3114 					m->mdmreg[REG_SI1] = 4;
3115 					m->mdmreg[REG_SI2] = 0;
3116 					break;
3117 				default:
3118 					PARSE_ERROR1;
3119 			}
3120 			break;
3121 		default:
3122 			PARSE_ERROR1;
3123 	}
3124 	return 0;
3125 }
3126 
3127 static int
isdn_tty_check_ats(int mreg,int mval,modem_info * info,atemu * m)3128 isdn_tty_check_ats(int mreg, int mval, modem_info * info, atemu * m)
3129 {
3130 	/* Some plausibility checks */
3131 	switch (mreg) {
3132 		case REG_L2PROT:
3133 			if (mval > ISDN_PROTO_L2_MAX)
3134 				return 1;
3135 			break;
3136 		case REG_PSIZE:
3137 			if ((mval * 16) > ISDN_SERIAL_XMIT_MAX)
3138 				return 1;
3139 #ifdef CONFIG_ISDN_AUDIO
3140 			if ((m->mdmreg[REG_SI1] & 1) && (mval > VBUFX))
3141 				return 1;
3142 #endif
3143 			info->xmit_size = mval * 16;
3144 			switch (m->mdmreg[REG_L2PROT]) {
3145 				case ISDN_PROTO_L2_V11096:
3146 				case ISDN_PROTO_L2_V11019:
3147 				case ISDN_PROTO_L2_V11038:
3148 					info->xmit_size /= 10;
3149 			}
3150 			break;
3151 		case REG_SI1I:
3152 		case REG_PLAN:
3153 		case REG_SCREEN:
3154 			/* readonly registers */
3155 			return 1;
3156 	}
3157 	return 0;
3158 }
3159 
3160 /*
3161  * Perform ATS command
3162  */
3163 static int
isdn_tty_cmd_ATS(char ** p,modem_info * info)3164 isdn_tty_cmd_ATS(char **p, modem_info * info)
3165 {
3166 	atemu *m = &info->emu;
3167 	int bitpos;
3168 	int mreg;
3169 	int mval;
3170 	int bval;
3171 
3172 	mreg = isdn_getnum(p);
3173 	if (mreg < 0 || mreg >= ISDN_MODEM_NUMREG)
3174 		PARSE_ERROR1;
3175 	switch (*p[0]) {
3176 		case '=':
3177 			p[0]++;
3178 			mval = isdn_getnum(p);
3179 			if (mval < 0 || mval > 255)
3180 				PARSE_ERROR1;
3181 			if (isdn_tty_check_ats(mreg, mval, info, m))
3182 				PARSE_ERROR1;
3183 			m->mdmreg[mreg] = mval;
3184 			break;
3185 		case '.':
3186 			/* Set/Clear a single bit */
3187 			p[0]++;
3188 			bitpos = isdn_getnum(p);
3189 			if ((bitpos < 0) || (bitpos > 7))
3190 				PARSE_ERROR1;
3191 			switch (*p[0]) {
3192 				case '=':
3193 					p[0]++;
3194 					bval = isdn_getnum(p);
3195 					if (bval < 0 || bval > 1)
3196 						PARSE_ERROR1;
3197 					if (bval)
3198 						mval = m->mdmreg[mreg] | (1 << bitpos);
3199 					else
3200 						mval = m->mdmreg[mreg] & ~(1 << bitpos);
3201 					if (isdn_tty_check_ats(mreg, mval, info, m))
3202 						PARSE_ERROR1;
3203 					m->mdmreg[mreg] = mval;
3204 					break;
3205 				case '?':
3206 					p[0]++;
3207 					isdn_tty_at_cout("\r\n", info);
3208 					isdn_tty_at_cout((m->mdmreg[mreg] & (1 << bitpos)) ? "1" : "0",
3209 							 info);
3210 					break;
3211 				default:
3212 					PARSE_ERROR1;
3213 			}
3214 			break;
3215 		case '?':
3216 			p[0]++;
3217 			isdn_tty_show_profile(mreg, info);
3218 			break;
3219 		default:
3220 			PARSE_ERROR1;
3221 			break;
3222 	}
3223 	return 0;
3224 }
3225 
3226 /*
3227  * Perform ATA command
3228  */
3229 static void
isdn_tty_cmd_ATA(modem_info * info)3230 isdn_tty_cmd_ATA(modem_info * info)
3231 {
3232 	atemu *m = &info->emu;
3233 	isdn_ctrl cmd;
3234 	int l2;
3235 
3236 	if (info->msr & UART_MSR_RI) {
3237 		/* Accept incoming call */
3238 		info->last_dir = 0;
3239 		strcpy(info->last_num, dev->num[info->drv_index]);
3240 		m->mdmreg[REG_RINGCNT] = 0;
3241 		info->msr &= ~UART_MSR_RI;
3242 		l2 = m->mdmreg[REG_L2PROT];
3243 #ifdef CONFIG_ISDN_AUDIO
3244 		/* If more than one bit set in reg18, autoselect Layer2 */
3245 		if ((m->mdmreg[REG_SI1] & m->mdmreg[REG_SI1I]) != m->mdmreg[REG_SI1]) {
3246 			if (m->mdmreg[REG_SI1I] == 1) {
3247 				if ((l2 != ISDN_PROTO_L2_MODEM) && (l2 != ISDN_PROTO_L2_FAX))
3248 					l2 = ISDN_PROTO_L2_TRANS;
3249 			} else
3250 				l2 = ISDN_PROTO_L2_X75I;
3251 		}
3252 #endif
3253 		cmd.driver = info->isdn_driver;
3254 		cmd.command = ISDN_CMD_SETL2;
3255 		cmd.arg = info->isdn_channel + (l2 << 8);
3256 		info->last_l2 = l2;
3257 		isdn_command(&cmd);
3258 		cmd.driver = info->isdn_driver;
3259 		cmd.command = ISDN_CMD_SETL3;
3260 		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
3261 #ifdef CONFIG_ISDN_TTY_FAX
3262 		if (l2 == ISDN_PROTO_L2_FAX) {
3263 			cmd.parm.fax = info->fax;
3264 			info->fax->direction = ISDN_TTY_FAX_CONN_IN;
3265 		}
3266 #endif
3267 		isdn_command(&cmd);
3268 		cmd.driver = info->isdn_driver;
3269 		cmd.arg = info->isdn_channel;
3270 		cmd.command = ISDN_CMD_ACCEPTD;
3271 		info->dialing = 16;
3272 		info->emu.carrierwait = 0;
3273 		isdn_command(&cmd);
3274 		isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
3275 	} else
3276 		isdn_tty_modem_result(RESULT_NO_ANSWER, info);
3277 }
3278 
3279 #ifdef CONFIG_ISDN_AUDIO
3280 /*
3281  * Parse AT+F.. commands
3282  */
3283 static int
isdn_tty_cmd_PLUSF(char ** p,modem_info * info)3284 isdn_tty_cmd_PLUSF(char **p, modem_info * info)
3285 {
3286 	atemu *m = &info->emu;
3287 	char rs[20];
3288 
3289 	if (!strncmp(p[0], "CLASS", 5)) {
3290 		p[0] += 5;
3291 		switch (*p[0]) {
3292 			case '?':
3293 				p[0]++;
3294 				sprintf(rs, "\r\n%d",
3295 					(m->mdmreg[REG_SI1] & 1) ? 8 : 0);
3296 #ifdef CONFIG_ISDN_TTY_FAX
3297 				if (TTY_IS_FCLASS2(info))
3298 						sprintf(rs, "\r\n2");
3299 				else if (TTY_IS_FCLASS1(info))
3300 						sprintf(rs, "\r\n1");
3301 #endif
3302 				isdn_tty_at_cout(rs, info);
3303 				break;
3304 			case '=':
3305 				p[0]++;
3306 				switch (*p[0]) {
3307 					case '0':
3308 						p[0]++;
3309 						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
3310 						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
3311 						m->mdmreg[REG_SI1] = 4;
3312 						info->xmit_size =
3313 						    m->mdmreg[REG_PSIZE] * 16;
3314 						break;
3315 #ifdef CONFIG_ISDN_TTY_FAX
3316 					case '1':
3317 						p[0]++;
3318 						if (!(dev->global_features &
3319 							ISDN_FEATURE_L3_FCLASS1))
3320 							PARSE_ERROR1;
3321 						m->mdmreg[REG_SI1] = 1;
3322 						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX;
3323 						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS1;
3324 						info->xmit_size =
3325 						    m->mdmreg[REG_PSIZE] * 16;
3326 						break;
3327 					case '2':
3328 						p[0]++;
3329 						if (!(dev->global_features &
3330 							ISDN_FEATURE_L3_FCLASS2))
3331 							PARSE_ERROR1;
3332 						m->mdmreg[REG_SI1] = 1;
3333 						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX;
3334 						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS2;
3335 						info->xmit_size =
3336 						    m->mdmreg[REG_PSIZE] * 16;
3337 						break;
3338 #endif
3339 					case '8':
3340 						p[0]++;
3341 						/* L2 will change on dialout with si=1 */
3342 						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
3343 						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
3344 						m->mdmreg[REG_SI1] = 5;
3345 						info->xmit_size = VBUF;
3346 						break;
3347 					case '?':
3348 						p[0]++;
3349 						strcpy(rs, "\r\n0,");
3350 #ifdef CONFIG_ISDN_TTY_FAX
3351 						if (dev->global_features &
3352 							ISDN_FEATURE_L3_FCLASS1)
3353 							strcat(rs, "1,");
3354 						if (dev->global_features &
3355 							ISDN_FEATURE_L3_FCLASS2)
3356 							strcat(rs, "2,");
3357 #endif
3358 						strcat(rs, "8");
3359 						isdn_tty_at_cout(rs, info);
3360 						break;
3361 					default:
3362 						PARSE_ERROR1;
3363 				}
3364 				break;
3365 			default:
3366 				PARSE_ERROR1;
3367 		}
3368 		return 0;
3369 	}
3370 #ifdef CONFIG_ISDN_TTY_FAX
3371 	return (isdn_tty_cmd_PLUSF_FAX(p, info));
3372 #else
3373 	PARSE_ERROR1;
3374 #endif
3375 }
3376 
3377 /*
3378  * Parse AT+V.. commands
3379  */
3380 static int
isdn_tty_cmd_PLUSV(char ** p,modem_info * info)3381 isdn_tty_cmd_PLUSV(char **p, modem_info * info)
3382 {
3383 	atemu *m = &info->emu;
3384 	isdn_ctrl cmd;
3385 	static char *vcmd[] =
3386 	{"NH", "IP", "LS", "RX", "SD", "SM", "TX", "DD", NULL};
3387 	int i;
3388 	int par1;
3389 	int par2;
3390 	char rs[20];
3391 
3392 	i = 0;
3393 	while (vcmd[i]) {
3394 		if (!strncmp(vcmd[i], p[0], 2)) {
3395 			p[0] += 2;
3396 			break;
3397 		}
3398 		i++;
3399 	}
3400 	switch (i) {
3401 		case 0:
3402 			/* AT+VNH - Auto hangup feature */
3403 			switch (*p[0]) {
3404 				case '?':
3405 					p[0]++;
3406 					isdn_tty_at_cout("\r\n1", info);
3407 					break;
3408 				case '=':
3409 					p[0]++;
3410 					switch (*p[0]) {
3411 						case '1':
3412 							p[0]++;
3413 							break;
3414 						case '?':
3415 							p[0]++;
3416 							isdn_tty_at_cout("\r\n1", info);
3417 							break;
3418 						default:
3419 							PARSE_ERROR1;
3420 					}
3421 					break;
3422 				default:
3423 					PARSE_ERROR1;
3424 			}
3425 			break;
3426 		case 1:
3427 			/* AT+VIP - Reset all voice parameters */
3428 			isdn_tty_modem_reset_vpar(m);
3429 			break;
3430 		case 2:
3431 			/* AT+VLS - Select device, accept incoming call */
3432 			switch (*p[0]) {
3433 				case '?':
3434 					p[0]++;
3435 					sprintf(rs, "\r\n%d", m->vpar[0]);
3436 					isdn_tty_at_cout(rs, info);
3437 					break;
3438 				case '=':
3439 					p[0]++;
3440 					switch (*p[0]) {
3441 						case '0':
3442 							p[0]++;
3443 							m->vpar[0] = 0;
3444 							break;
3445 						case '2':
3446 							p[0]++;
3447 							m->vpar[0] = 2;
3448 							break;
3449 						case '?':
3450 							p[0]++;
3451 							isdn_tty_at_cout("\r\n0,2", info);
3452 							break;
3453 						default:
3454 							PARSE_ERROR1;
3455 					}
3456 					break;
3457 				default:
3458 					PARSE_ERROR1;
3459 			}
3460 			break;
3461 		case 3:
3462 			/* AT+VRX - Start recording */
3463 			if (!m->vpar[0])
3464 				PARSE_ERROR1;
3465 			if (info->online != 1) {
3466 				isdn_tty_modem_result(RESULT_NO_ANSWER, info);
3467 				return 1;
3468 			}
3469 			info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
3470 			if (!info->dtmf_state) {
3471 				printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
3472 				PARSE_ERROR1;
3473 			}
3474 			info->silence_state = isdn_audio_silence_init(info->silence_state);
3475 			if (!info->silence_state) {
3476 				printk(KERN_WARNING "isdn_tty: Couldn't malloc silence state\n");
3477 				PARSE_ERROR1;
3478 			}
3479 			if (m->vpar[3] < 5) {
3480 				info->adpcmr = isdn_audio_adpcm_init(info->adpcmr, m->vpar[3]);
3481 				if (!info->adpcmr) {
3482 					printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
3483 					PARSE_ERROR1;
3484 				}
3485 			}
3486 #ifdef ISDN_DEBUG_AT
3487 			printk(KERN_DEBUG "AT: +VRX\n");
3488 #endif
3489 			info->vonline |= 1;
3490 			isdn_tty_modem_result(RESULT_CONNECT, info);
3491 			return 0;
3492 			break;
3493 		case 4:
3494 			/* AT+VSD - Silence detection */
3495 			switch (*p[0]) {
3496 				case '?':
3497 					p[0]++;
3498 					sprintf(rs, "\r\n<%d>,<%d>",
3499 						m->vpar[1],
3500 						m->vpar[2]);
3501 					isdn_tty_at_cout(rs, info);
3502 					break;
3503 				case '=':
3504 					p[0]++;
3505 					if ((*p[0]>='0') && (*p[0]<='9')) {
3506 						par1 = isdn_getnum(p);
3507 						if ((par1 < 0) || (par1 > 31))
3508 							PARSE_ERROR1;
3509 						if (*p[0] != ',')
3510 							PARSE_ERROR1;
3511 						p[0]++;
3512 						par2 = isdn_getnum(p);
3513 						if ((par2 < 0) || (par2 > 255))
3514 							PARSE_ERROR1;
3515 						m->vpar[1] = par1;
3516 						m->vpar[2] = par2;
3517 						break;
3518 					} else
3519 					if (*p[0] == '?') {
3520 						p[0]++;
3521 						isdn_tty_at_cout("\r\n<0-31>,<0-255>",
3522 							   info);
3523 						break;
3524 					} else
3525 					PARSE_ERROR1;
3526 					break;
3527 				default:
3528 					PARSE_ERROR1;
3529 			}
3530 			break;
3531 		case 5:
3532 			/* AT+VSM - Select compression */
3533 			switch (*p[0]) {
3534 				case '?':
3535 					p[0]++;
3536 					sprintf(rs, "\r\n<%d>,<%d><8000>",
3537 						m->vpar[3],
3538 						m->vpar[1]);
3539 					isdn_tty_at_cout(rs, info);
3540 					break;
3541 				case '=':
3542 					p[0]++;
3543 					switch (*p[0]) {
3544 						case '2':
3545 						case '3':
3546 						case '4':
3547 						case '5':
3548 						case '6':
3549 							par1 = isdn_getnum(p);
3550 							if ((par1 < 2) || (par1 > 6))
3551 								PARSE_ERROR1;
3552 							m->vpar[3] = par1;
3553 							break;
3554 						case '?':
3555 							p[0]++;
3556 							isdn_tty_at_cout("\r\n2;ADPCM;2;0;(8000)\r\n",
3557 								   info);
3558 							isdn_tty_at_cout("3;ADPCM;3;0;(8000)\r\n",
3559 								   info);
3560 							isdn_tty_at_cout("4;ADPCM;4;0;(8000)\r\n",
3561 								   info);
3562 							isdn_tty_at_cout("5;ALAW;8;0;(8000)\r\n",
3563 								   info);
3564 							isdn_tty_at_cout("6;ULAW;8;0;(8000)\r\n",
3565 								   info);
3566 							break;
3567 						default:
3568 							PARSE_ERROR1;
3569 					}
3570 					break;
3571 				default:
3572 					PARSE_ERROR1;
3573 			}
3574 			break;
3575 		case 6:
3576 			/* AT+VTX - Start sending */
3577 			if (!m->vpar[0])
3578 				PARSE_ERROR1;
3579 			if (info->online != 1) {
3580 				isdn_tty_modem_result(RESULT_NO_ANSWER, info);
3581 				return 1;
3582 			}
3583 			info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
3584 			if (!info->dtmf_state) {
3585 				printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
3586 				PARSE_ERROR1;
3587 			}
3588 			if (m->vpar[3] < 5) {
3589 				info->adpcms = isdn_audio_adpcm_init(info->adpcms, m->vpar[3]);
3590 				if (!info->adpcms) {
3591 					printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
3592 					PARSE_ERROR1;
3593 				}
3594 			}
3595 #ifdef ISDN_DEBUG_AT
3596 			printk(KERN_DEBUG "AT: +VTX\n");
3597 #endif
3598 			m->lastDLE = 0;
3599 			info->vonline |= 2;
3600 			isdn_tty_modem_result(RESULT_CONNECT, info);
3601 			return 0;
3602 			break;
3603 		case 7:
3604 			/* AT+VDD - DTMF detection */
3605 			switch (*p[0]) {
3606 				case '?':
3607 					p[0]++;
3608 					sprintf(rs, "\r\n<%d>,<%d>",
3609 						m->vpar[4],
3610 						m->vpar[5]);
3611 					isdn_tty_at_cout(rs, info);
3612 					break;
3613 				case '=':
3614 					p[0]++;
3615 					if ((*p[0]>='0') && (*p[0]<='9')) {
3616 						if (info->online != 1)
3617 							PARSE_ERROR1;
3618 						par1 = isdn_getnum(p);
3619 						if ((par1 < 0) || (par1 > 15))
3620 							PARSE_ERROR1;
3621 						if (*p[0] != ',')
3622 							PARSE_ERROR1;
3623 						p[0]++;
3624 						par2 = isdn_getnum(p);
3625 						if ((par2 < 0) || (par2 > 255))
3626 							PARSE_ERROR1;
3627 						m->vpar[4] = par1;
3628 						m->vpar[5] = par2;
3629 						cmd.driver = info->isdn_driver;
3630 						cmd.command = ISDN_CMD_AUDIO;
3631 						cmd.arg = info->isdn_channel + (ISDN_AUDIO_SETDD << 8);
3632 						cmd.parm.num[0] = par1;
3633 						cmd.parm.num[1] = par2;
3634 						isdn_command(&cmd);
3635 						break;
3636 					} else
3637 					if (*p[0] == '?') {
3638 						p[0]++;
3639 						isdn_tty_at_cout("\r\n<0-15>,<0-255>",
3640 							info);
3641 						break;
3642 					} else
3643 					PARSE_ERROR1;
3644 					break;
3645 				default:
3646 					PARSE_ERROR1;
3647 			}
3648 			break;
3649 		default:
3650 			PARSE_ERROR1;
3651 	}
3652 	return 0;
3653 }
3654 #endif                          /* CONFIG_ISDN_AUDIO */
3655 
3656 /*
3657  * Parse and perform an AT-command-line.
3658  */
3659 static void
isdn_tty_parse_at(modem_info * info)3660 isdn_tty_parse_at(modem_info * info)
3661 {
3662 	atemu *m = &info->emu;
3663 	char *p;
3664 	char ds[40];
3665 
3666 #ifdef ISDN_DEBUG_AT
3667 	printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd);
3668 #endif
3669 	for (p = &m->mdmcmd[2]; *p;) {
3670 		switch (*p) {
3671 			case ' ':
3672 				p++;
3673 				break;
3674 			case 'A':
3675 				/* A - Accept incoming call */
3676 				p++;
3677 				isdn_tty_cmd_ATA(info);
3678 				return;
3679 				break;
3680 			case 'D':
3681 				/* D - Dial */
3682 				if (info->msr & UART_MSR_DCD)
3683 					PARSE_ERROR;
3684 				if (info->msr & UART_MSR_RI) {
3685 					isdn_tty_modem_result(RESULT_NO_CARRIER, info);
3686 					return;
3687 				}
3688 				isdn_tty_getdial(++p, ds, sizeof ds);
3689 				p += strlen(p);
3690 				if (!strlen(m->msn))
3691 					isdn_tty_modem_result(RESULT_NO_MSN_EAZ, info);
3692 				else if (strlen(ds))
3693 					isdn_tty_dial(ds, info, m);
3694 				else
3695 					PARSE_ERROR;
3696 				return;
3697 			case 'E':
3698 				/* E - Turn Echo on/off */
3699 				p++;
3700 				switch (isdn_getnum(&p)) {
3701 					case 0:
3702 						m->mdmreg[REG_ECHO] &= ~BIT_ECHO;
3703 						break;
3704 					case 1:
3705 						m->mdmreg[REG_ECHO] |= BIT_ECHO;
3706 						break;
3707 					default:
3708 						PARSE_ERROR;
3709 				}
3710 				break;
3711 			case 'H':
3712 				/* H - On/Off-hook */
3713 				p++;
3714 				switch (*p) {
3715 					case '0':
3716 						p++;
3717 						isdn_tty_on_hook(info);
3718 						break;
3719 					case '1':
3720 						p++;
3721 						isdn_tty_off_hook();
3722 						break;
3723 					default:
3724 						isdn_tty_on_hook(info);
3725 						break;
3726 				}
3727 				break;
3728 			case 'I':
3729 				/* I - Information */
3730 				p++;
3731 				isdn_tty_at_cout("\r\nLinux ISDN", info);
3732 				switch (*p) {
3733 					case '0':
3734 					case '1':
3735 						p++;
3736 						break;
3737 					case '2':
3738 						p++;
3739 						isdn_tty_report(info);
3740 						break;
3741 					case '3':
3742                                                 p++;
3743                                                 sprintf(ds, "\r\n%d", info->emu.charge);
3744                                                 isdn_tty_at_cout(ds, info);
3745                                                 break;
3746 					default:;
3747 				}
3748 				break;
3749 #ifdef DUMMY_HAYES_AT
3750 			case 'L':
3751 			case 'M':
3752 				/* only for be compilant with common scripts */
3753 				/* no function */
3754 				p++;
3755 				isdn_getnum(&p);
3756 				break;
3757 #endif
3758 			case 'O':
3759 				/* O - Go online */
3760 				p++;
3761 				if (info->msr & UART_MSR_DCD)
3762 					/* if B-Channel is up */
3763 					isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? RESULT_CONNECT:RESULT_CONNECT64000, info);
3764 				else
3765 					isdn_tty_modem_result(RESULT_NO_CARRIER, info);
3766 				return;
3767 			case 'Q':
3768 				/* Q - Turn Emulator messages on/off */
3769 				p++;
3770 				switch (isdn_getnum(&p)) {
3771 					case 0:
3772 						m->mdmreg[REG_RESP] |= BIT_RESP;
3773 						break;
3774 					case 1:
3775 						m->mdmreg[REG_RESP] &= ~BIT_RESP;
3776 						break;
3777 					default:
3778 						PARSE_ERROR;
3779 				}
3780 				break;
3781 			case 'S':
3782 				/* S - Set/Get Register */
3783 				p++;
3784 				if (isdn_tty_cmd_ATS(&p, info))
3785 					return;
3786 				break;
3787 			case 'V':
3788 				/* V - Numeric or ASCII Emulator-messages */
3789 				p++;
3790 				switch (isdn_getnum(&p)) {
3791 					case 0:
3792 						m->mdmreg[REG_RESP] |= BIT_RESPNUM;
3793 						break;
3794 					case 1:
3795 						m->mdmreg[REG_RESP] &= ~BIT_RESPNUM;
3796 						break;
3797 					default:
3798 						PARSE_ERROR;
3799 				}
3800 				break;
3801 			case 'Z':
3802 				/* Z - Load Registers from Profile */
3803 				p++;
3804 				if (info->msr & UART_MSR_DCD) {
3805 					info->online = 0;
3806 					isdn_tty_on_hook(info);
3807 				}
3808 				isdn_tty_modem_reset_regs(info, 1);
3809 				break;
3810 			case '+':
3811 				p++;
3812 				switch (*p) {
3813 #ifdef CONFIG_ISDN_AUDIO
3814 					case 'F':
3815 						p++;
3816 						if (isdn_tty_cmd_PLUSF(&p, info))
3817 							return;
3818 						break;
3819 					case 'V':
3820 						if ((!(m->mdmreg[REG_SI1] & 1)) ||
3821 							(m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM))
3822 							PARSE_ERROR;
3823 						p++;
3824 						if (isdn_tty_cmd_PLUSV(&p, info))
3825 							return;
3826 						break;
3827 #endif                          /* CONFIG_ISDN_AUDIO */
3828 					case 'S':	/* SUSPEND */
3829 						p++;
3830 						isdn_tty_get_msnstr(ds, &p);
3831 						isdn_tty_suspend(ds, info, m);
3832 						break;
3833 					case 'R':	/* RESUME */
3834 						p++;
3835 						isdn_tty_get_msnstr(ds, &p);
3836 						isdn_tty_resume(ds, info, m);
3837 						break;
3838 					case 'M':	/* MESSAGE */
3839 						p++;
3840 						isdn_tty_send_msg(info, m, p);
3841 						break;
3842 					default:
3843 						PARSE_ERROR;
3844 				}
3845 				break;
3846 			case '&':
3847 				p++;
3848 				if (isdn_tty_cmd_ATand(&p, info))
3849 					return;
3850 				break;
3851 			default:
3852 				PARSE_ERROR;
3853 		}
3854 	}
3855 #ifdef CONFIG_ISDN_AUDIO
3856 	if (!info->vonline)
3857 #endif
3858 		isdn_tty_modem_result(RESULT_OK, info);
3859 }
3860 
3861 /* Need own toupper() because standard-toupper is not available
3862  * within modules.
3863  */
3864 #define my_toupper(c) (((c>='a')&&(c<='z'))?(c&0xdf):c)
3865 
3866 /*
3867  * Perform line-editing of AT-commands
3868  *
3869  * Parameters:
3870  *   p        inputbuffer
3871  *   count    length of buffer
3872  *   channel  index to line (minor-device)
3873  *   user     flag: buffer is in userspace
3874  */
3875 static int
isdn_tty_edit_at(const char * p,int count,modem_info * info,int user)3876 isdn_tty_edit_at(const char *p, int count, modem_info * info, int user)
3877 {
3878 	atemu *m = &info->emu;
3879 	int total = 0;
3880 	u_char c;
3881 	char eb[2];
3882 	int cnt;
3883 
3884 	for (cnt = count; cnt > 0; p++, cnt--) {
3885 		if (user)
3886 			get_user(c, p);
3887 		else
3888 			c = *p;
3889 		total++;
3890 		if (c == m->mdmreg[REG_CR] || c == m->mdmreg[REG_LF]) {
3891 			/* Separator (CR or LF) */
3892 			m->mdmcmd[m->mdmcmdl] = 0;
3893 			if (m->mdmreg[REG_ECHO] & BIT_ECHO) {
3894 				eb[0] = c;
3895 				eb[1] = 0;
3896 				isdn_tty_at_cout(eb, info);
3897 			}
3898 			if ((m->mdmcmdl >= 2) && (!(strncmp(m->mdmcmd, "AT", 2))))
3899 				isdn_tty_parse_at(info);
3900 			m->mdmcmdl = 0;
3901 			continue;
3902 		}
3903 		if (c == m->mdmreg[REG_BS] && m->mdmreg[REG_BS] < 128) {
3904 			/* Backspace-Function */
3905 			if ((m->mdmcmdl > 2) || (!m->mdmcmdl)) {
3906 				if (m->mdmcmdl)
3907 					m->mdmcmdl--;
3908 				if (m->mdmreg[REG_ECHO] & BIT_ECHO)
3909 					isdn_tty_at_cout("\b", info);
3910 			}
3911 			continue;
3912 		}
3913 		if (cmdchar(c)) {
3914 			if (m->mdmreg[REG_ECHO] & BIT_ECHO) {
3915 				eb[0] = c;
3916 				eb[1] = 0;
3917 				isdn_tty_at_cout(eb, info);
3918 			}
3919 			if (m->mdmcmdl < 255) {
3920 				c = my_toupper(c);
3921 				switch (m->mdmcmdl) {
3922 					case 1:
3923 						if (c == 'T') {
3924 							m->mdmcmd[m->mdmcmdl] = c;
3925 							m->mdmcmd[++m->mdmcmdl] = 0;
3926 							break;
3927 						} else
3928 							m->mdmcmdl = 0;
3929 						/* Fall through, check for 'A' */
3930 					case 0:
3931 						if (c == 'A') {
3932 							m->mdmcmd[m->mdmcmdl] = c;
3933 							m->mdmcmd[++m->mdmcmdl] = 0;
3934 						}
3935 						break;
3936 					default:
3937 						m->mdmcmd[m->mdmcmdl] = c;
3938 						m->mdmcmd[++m->mdmcmdl] = 0;
3939 				}
3940 			}
3941 		}
3942 	}
3943 	return total;
3944 }
3945 
3946 /*
3947  * Switch all modem-channels who are online and got a valid
3948  * escape-sequence 1.5 seconds ago, to command-mode.
3949  * This function is called every second via timer-interrupt from within
3950  * timer-dispatcher isdn_timer_function()
3951  */
3952 void
isdn_tty_modem_escape(void)3953 isdn_tty_modem_escape(void)
3954 {
3955 	int ton = 0;
3956 	int i;
3957 	int midx;
3958 
3959 	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
3960 		if (USG_MODEM(dev->usage[i]))
3961 			if ((midx = dev->m_idx[i]) >= 0) {
3962 				modem_info *info = &dev->mdm.info[midx];
3963 				if (info->online) {
3964 					ton = 1;
3965 					if ((info->emu.pluscount == 3) &&
3966 					    time_after(jiffies , info->emu.lastplus + PLUSWAIT2)) {
3967 						info->emu.pluscount = 0;
3968 						info->online = 0;
3969 						isdn_tty_modem_result(RESULT_OK, info);
3970 					}
3971 				}
3972 			}
3973 	isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, ton);
3974 }
3975 
3976 /*
3977  * Put a RING-message to all modem-channels who have the RI-bit set.
3978  * This function is called every second via timer-interrupt from within
3979  * timer-dispatcher isdn_timer_function()
3980  */
3981 void
isdn_tty_modem_ring(void)3982 isdn_tty_modem_ring(void)
3983 {
3984 	int ton = 0;
3985 	int i;
3986 
3987 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
3988 		modem_info *info = &dev->mdm.info[i];
3989 		if (info->msr & UART_MSR_RI) {
3990 			ton = 1;
3991 			isdn_tty_modem_result(RESULT_RING, info);
3992 		}
3993 	}
3994 	isdn_timer_ctrl(ISDN_TIMER_MODEMRING, ton);
3995 }
3996 
3997 /*
3998  * For all online tty's, try sending data to
3999  * the lower levels.
4000  */
4001 void
isdn_tty_modem_xmit(void)4002 isdn_tty_modem_xmit(void)
4003 {
4004 	int ton = 1;
4005 	int i;
4006 
4007 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
4008 		modem_info *info = &dev->mdm.info[i];
4009 		if (info->online) {
4010 			ton = 1;
4011 			isdn_tty_senddown(info);
4012 			isdn_tty_tint(info);
4013 		}
4014 	}
4015 	isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, ton);
4016 }
4017 
4018 /*
4019  * Check all channels if we have a 'no carrier' timeout.
4020  * Timeout value is set by Register S7.
4021  */
4022 void
isdn_tty_carrier_timeout(void)4023 isdn_tty_carrier_timeout(void)
4024 {
4025 	int ton = 0;
4026 	int i;
4027 
4028 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
4029 		modem_info *info = &dev->mdm.info[i];
4030 		if (info->dialing) {
4031 			if (info->emu.carrierwait++ > info->emu.mdmreg[REG_WAITC]) {
4032 				info->dialing = 0;
4033 				isdn_tty_modem_result(RESULT_NO_CARRIER, info);
4034 				isdn_tty_modem_hup(info, 1);
4035 			}
4036 			else
4037 				ton = 1;
4038 		}
4039 	}
4040 	isdn_timer_ctrl(ISDN_TIMER_CARRIER, ton);
4041 }
4042