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