File: /usr/src/linux/drivers/isdn/isdn_tty.c

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