VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / s390 / net / ctctty.c
1 /*
2  * $Id: ctctty.c,v 1.26 2004/08/04 11:06:55 mschwide Exp $
3  *
4  * CTC / ESCON network driver, tty interface.
5  *
6  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24
25 #include <linux/config.h>
26 #include <linux/module.h>
27 #include <linux/tty.h>
28 #include <linux/serial_reg.h>
29 #include <linux/interrupt.h>
30 #include <linux/delay.h>
31 #include <asm/uaccess.h>
32 #include <linux/devfs_fs_kernel.h>
33 #include "ctctty.h"
34 #include "ctcdbug.h"
35
36 #define CTC_TTY_MAJOR       43
37 #define CTC_TTY_MAX_DEVICES 64
38
39 #define CTC_ASYNC_MAGIC          0x49344C01 /* for paranoia-checking        */
40 #define CTC_ASYNC_INITIALIZED    0x80000000 /* port was initialized         */
41 #define CTC_ASYNC_NORMAL_ACTIVE  0x20000000 /* Normal device active         */
42 #define CTC_ASYNC_CLOSING        0x08000000 /* Serial port is closing       */
43 #define CTC_ASYNC_CTS_FLOW       0x04000000 /* Do CTS flow control          */
44 #define CTC_ASYNC_CHECK_CD       0x02000000 /* i.e., CLOCAL                 */
45 #define CTC_ASYNC_HUP_NOTIFY         0x0001 /* Notify tty on hangups/closes */
46 #define CTC_ASYNC_NETDEV_OPEN        0x0002 /* Underlying netdev is open    */
47 #define CTC_ASYNC_TX_LINESTAT        0x0004 /* Must send line status        */
48 #define CTC_ASYNC_SPLIT_TERMIOS      0x0008 /* Sep. termios for dialin/out  */
49 #define CTC_TTY_XMIT_SIZE              1024 /* Default bufsize for write    */
50 #define CTC_SERIAL_XMIT_MAX            4000 /* Maximum bufsize for write    */
51
52 /* Private data (similar to async_struct in <linux/serial.h>) */
53 typedef struct {
54   int                   magic;
55   int                   flags;           /* defined in tty.h               */
56   int                   mcr;             /* Modem control register         */
57   int                   msr;             /* Modem status register          */
58   int                   lsr;             /* Line status register           */
59   int                   line;
60   int                   count;           /* # of fd on device              */
61   int                   blocked_open;    /* # of blocked opens             */
62   struct net_device     *netdev;
63   struct sk_buff_head   tx_queue;        /* transmit queue                 */
64   struct sk_buff_head   rx_queue;        /* receive queue                  */
65   struct tty_struct     *tty;            /* Pointer to corresponding tty   */
66   wait_queue_head_t     open_wait;
67   wait_queue_head_t     close_wait;
68   struct semaphore      write_sem;
69   struct tasklet_struct tasklet;
70   struct timer_list     stoptimer;
71 } ctc_tty_info;
72
73 /* Description of one CTC-tty */
74 typedef struct {
75   struct tty_driver  *ctc_tty_device;              /* tty-device             */
76   ctc_tty_info       info[CTC_TTY_MAX_DEVICES];    /* Private data           */
77 } ctc_tty_driver;
78
79 static ctc_tty_driver *driver;
80
81 /* Leave this unchanged unless you know what you do! */
82 #define MODEM_PARANOIA_CHECK
83 #define MODEM_DO_RESTART
84
85 #define CTC_TTY_NAME "ctctty"
86
87 static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC;
88 static int ctc_tty_shuttingdown = 0;
89
90 static spinlock_t ctc_tty_lock;
91
92 /* ctc_tty_try_read() is called from within ctc_tty_rcv_skb()
93  * to stuff incoming data directly into a tty's flip-buffer. If the
94  * flip buffer is full, the packet gets queued up.
95  *
96  * Return:
97  *  1 = Success
98  *  0 = Failure, data has to be buffered and later processed by
99  *      ctc_tty_readmodem().
100  */
101 static int
102 ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb)
103 {
104         int c;
105         int len;
106         struct tty_struct *tty;
107
108         DBF_TEXT(trace, 5, __FUNCTION__);
109         if ((tty = info->tty)) {
110                 if (info->mcr & UART_MCR_RTS) {
111                         c = TTY_FLIPBUF_SIZE - tty->flip.count;
112                         len = skb->len;
113                         if (c >= len) {
114                                 memcpy(tty->flip.char_buf_ptr, skb->data, len);
115                                 memset(tty->flip.flag_buf_ptr, 0, len);
116                                 tty->flip.count += len;
117                                 tty->flip.char_buf_ptr += len;
118                                 tty->flip.flag_buf_ptr += len;
119                                 tty_flip_buffer_push(tty);
120                                 kfree_skb(skb);
121                                 return 1;
122                         }
123                 }
124         }
125         return 0;
126 }
127
128 /* ctc_tty_readmodem() is called periodically from within timer-interrupt.
129  * It tries getting received data from the receive queue an stuff it into
130  * the tty's flip-buffer.
131  */
132 static int
133 ctc_tty_readmodem(ctc_tty_info *info)
134 {
135         int ret = 1;
136         struct tty_struct *tty;
137
138         DBF_TEXT(trace, 5, __FUNCTION__);
139         if ((tty = info->tty)) {
140                 if (info->mcr & UART_MCR_RTS) {
141                         int c = TTY_FLIPBUF_SIZE - tty->flip.count;
142                         struct sk_buff *skb;
143                         
144                         if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) {
145                                 int len = skb->len;
146                                 if (len > c)
147                                         len = c;
148                                 memcpy(tty->flip.char_buf_ptr, skb->data, len);
149                                 skb_pull(skb, len);
150                                 memset(tty->flip.flag_buf_ptr, 0, len);
151                                 tty->flip.count += len;
152                                 tty->flip.char_buf_ptr += len;
153                                 tty->flip.flag_buf_ptr += len;
154                                 tty_flip_buffer_push(tty);
155                                 if (skb->len > 0)
156                                         skb_queue_head(&info->rx_queue, skb);
157                                 else {
158                                         kfree_skb(skb);
159                                         ret = skb_queue_len(&info->rx_queue);
160                                 }
161                         }
162                 }
163         }
164         return ret;
165 }
166
167 void
168 ctc_tty_setcarrier(struct net_device *netdev, int on)
169 {
170         int i;
171
172         DBF_TEXT(trace, 4, __FUNCTION__);
173         if ((!driver) || ctc_tty_shuttingdown)
174                 return;
175         for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
176                 if (driver->info[i].netdev == netdev) {
177                         ctc_tty_info *info = &driver->info[i];
178                         if (on)
179                                 info->msr |= UART_MSR_DCD;
180                         else
181                                 info->msr &= ~UART_MSR_DCD;
182                         if ((info->flags & CTC_ASYNC_CHECK_CD) && (!on))
183                                 tty_hangup(info->tty);
184                 }
185 }
186
187 void
188 ctc_tty_netif_rx(struct sk_buff *skb)
189 {
190         int i;
191         ctc_tty_info *info = NULL;
192
193         DBF_TEXT(trace, 5, __FUNCTION__);
194         if (!skb)
195                 return;
196         if ((!skb->dev) || (!driver) || ctc_tty_shuttingdown) {
197                 dev_kfree_skb(skb);
198                 return;
199         }
200         for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
201                 if (driver->info[i].netdev == skb->dev) {
202                         info = &driver->info[i];
203                         break;
204                 }
205         if (!info) {
206                 dev_kfree_skb(skb);
207                 return;
208         }
209         if (skb->len < 6) {
210                 dev_kfree_skb(skb);
211                 return;
212         }
213         if (memcmp(skb->data, &ctc_tty_magic, sizeof(__u32))) {
214                 dev_kfree_skb(skb);
215                 return;
216         }
217         skb_pull(skb, sizeof(__u32));
218
219         i = *((int *)skb->data);
220         skb_pull(skb, sizeof(info->mcr));
221         if (i & UART_MCR_RTS) {
222                 info->msr |= UART_MSR_CTS;
223                 if (info->flags & CTC_ASYNC_CTS_FLOW)
224                         info->tty->hw_stopped = 0;
225         } else {
226                 info->msr &= ~UART_MSR_CTS;
227                 if (info->flags & CTC_ASYNC_CTS_FLOW)
228                         info->tty->hw_stopped = 1;
229         }
230         if (i & UART_MCR_DTR)
231                 info->msr |= UART_MSR_DSR;
232         else
233                 info->msr &= ~UART_MSR_DSR;
234         if (skb->len <= 0) {
235                 kfree_skb(skb);
236                 return;
237         }
238         /* Try to deliver directly via tty-flip-buf if queue is empty */
239         if (skb_queue_empty(&info->rx_queue))
240                 if (ctc_tty_try_read(info, skb))
241                         return;
242         /* Direct deliver failed or queue wasn't empty.
243          * Queue up for later dequeueing via timer-irq.
244          */
245         skb_queue_tail(&info->rx_queue, skb);
246         /* Schedule dequeuing */
247         tasklet_schedule(&info->tasklet);
248 }
249
250 static int
251 ctc_tty_tint(ctc_tty_info * info)
252 {
253         struct sk_buff *skb = skb_dequeue(&info->tx_queue);
254         int stopped = (info->tty->hw_stopped || info->tty->stopped);
255         int wake = 1;
256         int rc;
257
258         DBF_TEXT(trace, 4, __FUNCTION__);
259         if (!info->netdev) {
260                 if (skb)
261                         kfree_skb(skb);
262                 return 0;
263         }
264         if (info->flags & CTC_ASYNC_TX_LINESTAT) {
265                 int skb_res = info->netdev->hard_header_len +
266                         sizeof(info->mcr) + sizeof(__u32);
267                 /* If we must update line status,
268                  * create an empty dummy skb and insert it.
269                  */
270                 if (skb)
271                         skb_queue_head(&info->tx_queue, skb);
272
273                 skb = dev_alloc_skb(skb_res);
274                 if (!skb) {
275                         printk(KERN_WARNING
276                                "ctc_tty: Out of memory in %s%d tint\n",
277                                CTC_TTY_NAME, info->line);
278                         return 1;
279                 }
280                 skb_reserve(skb, skb_res);
281                 stopped = 0;
282                 wake = 0;
283         }
284         if (!skb)
285                 return 0;
286         if (stopped) {
287                 skb_queue_head(&info->tx_queue, skb);
288                 return 1;
289         }
290 #if 0
291         if (skb->len > 0)
292                 printk(KERN_DEBUG "tint: %d %02x\n", skb->len, *(skb->data));
293         else
294                 printk(KERN_DEBUG "tint: %d STAT\n", skb->len);
295 #endif
296         memcpy(skb_push(skb, sizeof(info->mcr)), &info->mcr, sizeof(info->mcr));
297         memcpy(skb_push(skb, sizeof(__u32)), &ctc_tty_magic, sizeof(__u32));
298         rc = info->netdev->hard_start_xmit(skb, info->netdev);
299         if (rc) {
300                 skb_pull(skb, sizeof(info->mcr) + sizeof(__u32));
301                 if (skb->len > 0)
302                         skb_queue_head(&info->tx_queue, skb);
303                 else
304                         kfree_skb(skb);
305         } else {
306                 struct tty_struct *tty = info->tty;
307
308                 info->flags &= ~CTC_ASYNC_TX_LINESTAT;
309                 if (tty) {
310                         if (wake && (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
311                             tty->ldisc.write_wakeup)
312                                 (tty->ldisc.write_wakeup)(tty);
313                         wake_up_interruptible(&tty->write_wait);
314                 }
315         }
316         return (skb_queue_empty(&info->tx_queue) ? 0 : 1);
317 }
318
319 /************************************************************
320  *
321  * Modem-functions
322  *
323  * mostly "stolen" from original Linux-serial.c and friends.
324  *
325  ************************************************************/
326
327 static inline int
328 ctc_tty_paranoia_check(ctc_tty_info * info, char *name, const char *routine)
329 {
330 #ifdef MODEM_PARANOIA_CHECK
331         if (!info) {
332                 printk(KERN_WARNING "ctc_tty: null info_struct for %s in %s\n",
333                        name, routine);
334                 return 1;
335         }
336         if (info->magic != CTC_ASYNC_MAGIC) {
337                 printk(KERN_WARNING "ctc_tty: bad magic for info struct %s in %s\n",
338                        name, routine);
339                 return 1;
340         }
341 #endif
342         return 0;
343 }
344
345 static void
346 ctc_tty_inject(ctc_tty_info *info, char c)
347 {
348         int skb_res;
349         struct sk_buff *skb;
350         
351         DBF_TEXT(trace, 4, __FUNCTION__);
352         if (ctc_tty_shuttingdown)
353                 return;
354         skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
355                 sizeof(__u32) + 1;
356         skb = dev_alloc_skb(skb_res);
357         if (!skb) {
358                 printk(KERN_WARNING
359                        "ctc_tty: Out of memory in %s%d tx_inject\n",
360                        CTC_TTY_NAME, info->line);
361                 return;
362         }
363         skb_reserve(skb, skb_res);
364         *(skb_put(skb, 1)) = c;
365         skb_queue_head(&info->tx_queue, skb);
366         tasklet_schedule(&info->tasklet);
367 }
368
369 static void
370 ctc_tty_transmit_status(ctc_tty_info *info)
371 {
372         DBF_TEXT(trace, 5, __FUNCTION__);
373         if (ctc_tty_shuttingdown)
374                 return;
375         info->flags |= CTC_ASYNC_TX_LINESTAT;
376         tasklet_schedule(&info->tasklet);
377 }
378
379 static void
380 ctc_tty_change_speed(ctc_tty_info * info)
381 {
382         unsigned int cflag;
383         unsigned int quot;
384         int i;
385
386         DBF_TEXT(trace, 3, __FUNCTION__);
387         if (!info->tty || !info->tty->termios)
388                 return;
389         cflag = info->tty->termios->c_cflag;
390
391         quot = i = cflag & CBAUD;
392         if (i & CBAUDEX) {
393                 i &= ~CBAUDEX;
394                 if (i < 1 || i > 2)
395                         info->tty->termios->c_cflag &= ~CBAUDEX;
396                 else
397                         i += 15;
398         }
399         if (quot) {
400                 info->mcr |= UART_MCR_DTR;
401                 info->mcr |= UART_MCR_RTS;
402                 ctc_tty_transmit_status(info);
403         } else {
404                 info->mcr &= ~UART_MCR_DTR;
405                 info->mcr &= ~UART_MCR_RTS;
406                 ctc_tty_transmit_status(info);
407                 return;
408         }
409
410         /* CTS flow control flag and modem status interrupts */
411         if (cflag & CRTSCTS) {
412                 info->flags |= CTC_ASYNC_CTS_FLOW;
413         } else
414                 info->flags &= ~CTC_ASYNC_CTS_FLOW;
415         if (cflag & CLOCAL)
416                 info->flags &= ~CTC_ASYNC_CHECK_CD;
417         else {
418                 info->flags |= CTC_ASYNC_CHECK_CD;
419         }
420 }
421
422 static int
423 ctc_tty_startup(ctc_tty_info * info)
424 {
425         DBF_TEXT(trace, 3, __FUNCTION__);
426         if (info->flags & CTC_ASYNC_INITIALIZED)
427                 return 0;
428 #ifdef CTC_DEBUG_MODEM_OPEN
429         printk(KERN_DEBUG "starting up %s%d ...\n", CTC_TTY_NAME, info->line);
430 #endif
431         /*
432          * Now, initialize the UART
433          */
434         info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
435         if (info->tty)
436                 clear_bit(TTY_IO_ERROR, &info->tty->flags);
437         /*
438          * and set the speed of the serial port
439          */
440         ctc_tty_change_speed(info);
441
442         info->flags |= CTC_ASYNC_INITIALIZED;
443         if (!(info->flags & CTC_ASYNC_NETDEV_OPEN))
444                 info->netdev->open(info->netdev);
445         info->flags |= CTC_ASYNC_NETDEV_OPEN;
446         return 0;
447 }
448
449 static void
450 ctc_tty_stopdev(unsigned long data)
451 {
452         ctc_tty_info *info = (ctc_tty_info *)data;
453
454         if ((!info) || (!info->netdev) ||
455             (info->flags & CTC_ASYNC_INITIALIZED))
456                 return;
457         info->netdev->stop(info->netdev);
458         info->flags &= ~CTC_ASYNC_NETDEV_OPEN;
459 }
460
461 /*
462  * This routine will shutdown a serial port; interrupts are disabled, and
463  * DTR is dropped if the hangup on close termio flag is on.
464  */
465 static void
466 ctc_tty_shutdown(ctc_tty_info * info)
467 {
468         DBF_TEXT(trace, 3, __FUNCTION__);
469         if (!(info->flags & CTC_ASYNC_INITIALIZED))
470                 return;
471 #ifdef CTC_DEBUG_MODEM_OPEN
472         printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line);
473 #endif
474         info->msr &= ~UART_MSR_RI;
475         if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
476                 info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
477         if (info->tty)
478                 set_bit(TTY_IO_ERROR, &info->tty->flags);
479         mod_timer(&info->stoptimer, jiffies + (10 * HZ));
480         skb_queue_purge(&info->tx_queue);
481         skb_queue_purge(&info->rx_queue);
482         info->flags &= ~CTC_ASYNC_INITIALIZED;
483 }
484
485 /* ctc_tty_write() is the main send-routine. It is called from the upper
486  * levels within the kernel to perform sending data. Depending on the
487  * online-flag it either directs output to the at-command-interpreter or
488  * to the lower level. Additional tasks done here:
489  *  - If online, check for escape-sequence (+++)
490  *  - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes.
491  *  - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed.
492  *  - If dialing, abort dial.
493  */
494 static int
495 ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int count)
496 {
497         int c;
498         int total = 0;
499         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
500
501         DBF_TEXT(trace, 5, __FUNCTION__);
502         if (ctc_tty_shuttingdown)
503                 goto ex;
504         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write"))
505                 goto ex;
506         if (!tty)
507                 goto ex;
508         if (!info->netdev) {
509                 total = -ENODEV;
510                 goto ex;
511         }
512         if (from_user)
513                 down(&info->write_sem);
514         while (1) {
515                 struct sk_buff *skb;
516                 int skb_res;
517
518                 c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE;
519                 if (c <= 0)
520                         break;
521                 
522                 skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
523                         + sizeof(__u32);
524                 skb = dev_alloc_skb(skb_res + c);
525                 if (!skb) {
526                         printk(KERN_WARNING
527                                "ctc_tty: Out of memory in %s%d write\n",
528                                CTC_TTY_NAME, info->line);
529                         break;
530                 }
531                 skb_reserve(skb, skb_res);
532                 if (from_user)
533                         copy_from_user(skb_put(skb, c),
534                                         (const u_char __user *)buf, c);
535                 else
536                         memcpy(skb_put(skb, c), buf, c);
537                 skb_queue_tail(&info->tx_queue, skb);
538                 buf += c;
539                 total += c;
540                 count -= c;
541         }
542         if (skb_queue_len(&info->tx_queue)) {
543                 info->lsr &= ~UART_LSR_TEMT;
544                 tasklet_schedule(&info->tasklet);
545         }
546         if (from_user)
547                 up(&info->write_sem);
548 ex:
549         DBF_TEXT(trace, 6, __FUNCTION__);
550         return total;
551 }
552
553 static int
554 ctc_tty_write_room(struct tty_struct *tty)
555 {
556         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
557
558         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room"))
559                 return 0;
560         return CTC_TTY_XMIT_SIZE;
561 }
562
563 static int
564 ctc_tty_chars_in_buffer(struct tty_struct *tty)
565 {
566         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
567
568         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_chars_in_buffer"))
569                 return 0;
570         return 0;
571 }
572
573 static void
574 ctc_tty_flush_buffer(struct tty_struct *tty)
575 {
576         ctc_tty_info *info;
577         unsigned long flags;
578
579         DBF_TEXT(trace, 4, __FUNCTION__);
580         if (!tty)
581                 goto ex;
582         spin_lock_irqsave(&ctc_tty_lock, flags);
583         info = (ctc_tty_info *) tty->driver_data;
584         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_buffer")) {
585                 spin_unlock_irqrestore(&ctc_tty_lock, flags);
586                 goto ex;
587         }
588         skb_queue_purge(&info->tx_queue);
589         info->lsr |= UART_LSR_TEMT;
590         spin_unlock_irqrestore(&ctc_tty_lock, flags);
591         wake_up_interruptible(&tty->write_wait);
592         if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
593             tty->ldisc.write_wakeup)
594                 (tty->ldisc.write_wakeup) (tty);
595 ex:
596         DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__);
597         return;
598 }
599
600 static void
601 ctc_tty_flush_chars(struct tty_struct *tty)
602 {
603         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
604
605         DBF_TEXT(trace, 4, __FUNCTION__);
606         if (ctc_tty_shuttingdown)
607                 return;
608         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
609                 return;
610         if (tty->stopped || tty->hw_stopped || (!skb_queue_len(&info->tx_queue)))
611                 return;
612         tasklet_schedule(&info->tasklet);
613 }
614
615 /*
616  * ------------------------------------------------------------
617  * ctc_tty_throttle()
618  *
619  * This routine is called by the upper-layer tty layer to signal that
620  * incoming characters should be throttled.
621  * ------------------------------------------------------------
622  */
623 static void
624 ctc_tty_throttle(struct tty_struct *tty)
625 {
626         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
627
628         DBF_TEXT(trace, 4, __FUNCTION__);
629         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle"))
630                 return;
631         info->mcr &= ~UART_MCR_RTS;
632         if (I_IXOFF(tty))
633                 ctc_tty_inject(info, STOP_CHAR(tty));
634         ctc_tty_transmit_status(info);
635 }
636
637 static void
638 ctc_tty_unthrottle(struct tty_struct *tty)
639 {
640         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
641
642         DBF_TEXT(trace, 4, __FUNCTION__);
643         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle"))
644                 return;
645         info->mcr |= UART_MCR_RTS;
646         if (I_IXOFF(tty))
647                 ctc_tty_inject(info, START_CHAR(tty));
648         ctc_tty_transmit_status(info);
649 }
650
651 /*
652  * ------------------------------------------------------------
653  * ctc_tty_ioctl() and friends
654  * ------------------------------------------------------------
655  */
656
657 /*
658  * ctc_tty_get_lsr_info - get line status register info
659  *
660  * Purpose: Let user call ioctl() to get info when the UART physically
661  *          is emptied.  On bus types like RS485, the transmitter must
662  *          release the bus after transmitting. This must be done when
663  *          the transmit shift register is empty, not be done when the
664  *          transmit holding register is empty.  This functionality
665  *          allows RS485 driver to be written in user space.
666  */
667 static int
668 ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
669 {
670         u_char status;
671         uint result;
672         ulong flags;
673
674         DBF_TEXT(trace, 4, __FUNCTION__);
675         spin_lock_irqsave(&ctc_tty_lock, flags);
676         status = info->lsr;
677         spin_unlock_irqrestore(&ctc_tty_lock, flags);
678         result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
679         put_user(result, value);
680         return 0;
681 }
682
683
684 static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file)
685 {
686         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
687         u_char control,
688          status;
689         uint result;
690         ulong flags;
691
692         DBF_TEXT(trace, 4, __FUNCTION__);
693         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
694                 return -ENODEV;
695         if (tty->flags & (1 << TTY_IO_ERROR))
696                 return -EIO;
697
698         control = info->mcr;
699         spin_lock_irqsave(&ctc_tty_lock, flags);
700         status = info->msr;
701         spin_unlock_irqrestore(&ctc_tty_lock, flags);
702         result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
703             | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
704             | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
705             | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
706             | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
707             | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
708         return result;
709 }
710
711 static int
712 ctc_tty_tiocmset(struct tty_struct *tty, struct file *file,
713                  unsigned int set, unsigned int clear)
714 {
715         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
716
717         DBF_TEXT(trace, 4, __FUNCTION__);
718         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
719                 return -ENODEV;
720         if (tty->flags & (1 << TTY_IO_ERROR))
721                 return -EIO;
722
723         if (set & TIOCM_RTS)
724                 info->mcr |= UART_MCR_RTS;
725         if (set & TIOCM_DTR)
726                 info->mcr |= UART_MCR_DTR;
727
728         if (clear & TIOCM_RTS)
729                 info->mcr &= ~UART_MCR_RTS;
730         if (clear & TIOCM_DTR)
731                 info->mcr &= ~UART_MCR_DTR;
732
733         if ((set | clear) & (TIOCM_RTS|TIOCM_DTR))
734                 ctc_tty_transmit_status(info);
735         return 0;
736 }
737
738 static int
739 ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
740                uint cmd, ulong arg)
741 {
742         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
743         int error;
744         int retval;
745
746         DBF_TEXT(trace, 4, __FUNCTION__);
747         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
748                 return -ENODEV;
749         if (tty->flags & (1 << TTY_IO_ERROR))
750                 return -EIO;
751         switch (cmd) {
752                 case TCSBRK:   /* SVID version: non-zero arg --> no break */
753 #ifdef CTC_DEBUG_MODEM_IOCTL
754                         printk(KERN_DEBUG "%s%d ioctl TCSBRK\n", CTC_TTY_NAME, info->line);
755 #endif
756                         retval = tty_check_change(tty);
757                         if (retval)
758                                 return retval;
759                         tty_wait_until_sent(tty, 0);
760                         return 0;
761                 case TCSBRKP:  /* support for POSIX tcsendbreak() */
762 #ifdef CTC_DEBUG_MODEM_IOCTL
763                         printk(KERN_DEBUG "%s%d ioctl TCSBRKP\n", CTC_TTY_NAME, info->line);
764 #endif
765                         retval = tty_check_change(tty);
766                         if (retval)
767                                 return retval;
768                         tty_wait_until_sent(tty, 0);
769                         return 0;
770                 case TIOCGSOFTCAR:
771 #ifdef CTC_DEBUG_MODEM_IOCTL
772                         printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,
773                                info->line);
774 #endif
775                         error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
776                         return error;
777                 case TIOCSSOFTCAR:
778 #ifdef CTC_DEBUG_MODEM_IOCTL
779                         printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,
780                                info->line);
781 #endif
782                         error = get_user(arg, (ulong __user *) arg);
783                         if (error)
784                                 return error;
785                         tty->termios->c_cflag =
786                             ((tty->termios->c_cflag & ~CLOCAL) |
787                              (arg ? CLOCAL : 0));
788                         return 0;
789                 case TIOCSERGETLSR:     /* Get line status register */
790 #ifdef CTC_DEBUG_MODEM_IOCTL
791                         printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
792                                info->line);
793 #endif
794                         error = verify_area(VERIFY_WRITE, (void __user *) arg, sizeof(uint));
795                         if (error)
796                                 return error;
797                         else
798                                 return ctc_tty_get_lsr_info(info, (uint __user *) arg);
799                 default:
800 #ifdef CTC_DEBUG_MODEM_IOCTL
801                         printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
802                                CTC_TTY_NAME, info->line);
803 #endif
804                         return -ENOIOCTLCMD;
805         }
806         return 0;
807 }
808
809 static void
810 ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
811 {
812         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
813         unsigned int cflag = tty->termios->c_cflag;
814
815         DBF_TEXT(trace, 4, __FUNCTION__);
816         ctc_tty_change_speed(info);
817
818         /* Handle transition to B0 */
819         if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) {
820                 info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS);
821                 ctc_tty_transmit_status(info);
822         }
823
824         /* Handle transition from B0 to other */
825         if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
826                 info->mcr |= UART_MCR_DTR;
827                 if (!(tty->termios->c_cflag & CRTSCTS) ||
828                     !test_bit(TTY_THROTTLED, &tty->flags)) {
829                         info->mcr |= UART_MCR_RTS;
830                 }
831                 ctc_tty_transmit_status(info);
832         }
833
834         /* Handle turning off CRTSCTS */
835         if ((old_termios->c_cflag & CRTSCTS) &&
836             !(tty->termios->c_cflag & CRTSCTS))
837                 tty->hw_stopped = 0;
838 }
839
840 /*
841  * ------------------------------------------------------------
842  * ctc_tty_open() and friends
843  * ------------------------------------------------------------
844  */
845 static int
846 ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info *info)
847 {
848         DECLARE_WAITQUEUE(wait, NULL);
849         int do_clocal = 0;
850         unsigned long flags;
851         int retval;
852
853         DBF_TEXT(trace, 4, __FUNCTION__);
854         /*
855          * If the device is in the middle of being closed, then block
856          * until it's done, and then try again.
857          */
858         if (tty_hung_up_p(filp) ||
859             (info->flags & CTC_ASYNC_CLOSING)) {
860                 if (info->flags & CTC_ASYNC_CLOSING)
861                         wait_event(info->close_wait, 
862                                    !(info->flags & CTC_ASYNC_CLOSING));
863 #ifdef MODEM_DO_RESTART
864                 if (info->flags & CTC_ASYNC_HUP_NOTIFY)
865                         return -EAGAIN;
866                 else
867                         return -ERESTARTSYS;
868 #else
869                 return -EAGAIN;
870 #endif
871         }
872         /*
873          * If non-blocking mode is set, then make the check up front
874          * and then exit.
875          */
876         if ((filp->f_flags & O_NONBLOCK) ||
877             (tty->flags & (1 << TTY_IO_ERROR))) {
878                 info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
879                 return 0;
880         }
881         if (tty->termios->c_cflag & CLOCAL)
882                 do_clocal = 1;
883         /*
884          * Block waiting for the carrier detect and the line to become
885          * free (i.e., not in use by the callout).  While we are in
886          * this loop, info->count is dropped by one, so that
887          * ctc_tty_close() knows when to free things.  We restore it upon
888          * exit, either normal or abnormal.
889          */
890         retval = 0;
891         add_wait_queue(&info->open_wait, &wait);
892 #ifdef CTC_DEBUG_MODEM_OPEN
893         printk(KERN_DEBUG "ctc_tty_block_til_ready before block: %s%d, count = %d\n",
894                CTC_TTY_NAME, info->line, info->count);
895 #endif
896         spin_lock_irqsave(&ctc_tty_lock, flags);
897         if (!(tty_hung_up_p(filp)))
898                 info->count--;
899         spin_unlock_irqrestore(&ctc_tty_lock, flags);
900         info->blocked_open++;
901         while (1) {
902                 set_current_state(TASK_INTERRUPTIBLE);
903                 if (tty_hung_up_p(filp) ||
904                     !(info->flags & CTC_ASYNC_INITIALIZED)) {
905 #ifdef MODEM_DO_RESTART
906                         if (info->flags & CTC_ASYNC_HUP_NOTIFY)
907                                 retval = -EAGAIN;
908                         else
909                                 retval = -ERESTARTSYS;
910 #else
911                         retval = -EAGAIN;
912 #endif
913                         break;
914                 }
915                 if (!(info->flags & CTC_ASYNC_CLOSING) &&
916                     (do_clocal || (info->msr & UART_MSR_DCD))) {
917                         break;
918                 }
919                 if (signal_pending(current)) {
920                         retval = -ERESTARTSYS;
921                         break;
922                 }
923 #ifdef CTC_DEBUG_MODEM_OPEN
924                 printk(KERN_DEBUG "ctc_tty_block_til_ready blocking: %s%d, count = %d\n",
925                        CTC_TTY_NAME, info->line, info->count);
926 #endif
927                 schedule();
928         }
929         current->state = TASK_RUNNING;
930         remove_wait_queue(&info->open_wait, &wait);
931         if (!tty_hung_up_p(filp))
932                 info->count++;
933         info->blocked_open--;
934 #ifdef CTC_DEBUG_MODEM_OPEN
935         printk(KERN_DEBUG "ctc_tty_block_til_ready after blocking: %s%d, count = %d\n",
936                CTC_TTY_NAME, info->line, info->count);
937 #endif
938         if (retval)
939                 return retval;
940         info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
941         return 0;
942 }
943
944 /*
945  * This routine is called whenever a serial port is opened.  It
946  * enables interrupts for a serial port, linking in its async structure into
947  * the IRQ chain.   It also performs the serial-specific
948  * initialization for the tty structure.
949  */
950 static int
951 ctc_tty_open(struct tty_struct *tty, struct file *filp)
952 {
953         ctc_tty_info *info;
954         unsigned long saveflags;
955         int retval,
956          line;
957
958         DBF_TEXT(trace, 3, __FUNCTION__);
959         line = tty->index;
960         if (line < 0 || line > CTC_TTY_MAX_DEVICES)
961                 return -ENODEV;
962         info = &driver->info[line];
963         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_open"))
964                 return -ENODEV;
965         if (!info->netdev)
966                 return -ENODEV;
967 #ifdef CTC_DEBUG_MODEM_OPEN
968         printk(KERN_DEBUG "ctc_tty_open %s, count = %d\n", tty->name,
969                info->count);
970 #endif
971         spin_lock_irqsave(&ctc_tty_lock, saveflags);
972         info->count++;
973         tty->driver_data = info;
974         info->tty = tty;
975         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
976         /*
977          * Start up serial port
978          */
979         retval = ctc_tty_startup(info);
980         if (retval) {
981 #ifdef CTC_DEBUG_MODEM_OPEN
982                 printk(KERN_DEBUG "ctc_tty_open return after startup\n");
983 #endif
984                 return retval;
985         }
986         retval = ctc_tty_block_til_ready(tty, filp, info);
987         if (retval) {
988 #ifdef CTC_DEBUG_MODEM_OPEN
989                 printk(KERN_DEBUG "ctc_tty_open return after ctc_tty_block_til_ready \n");
990 #endif
991                 return retval;
992         }
993 #ifdef CTC_DEBUG_MODEM_OPEN
994         printk(KERN_DEBUG "ctc_tty_open %s successful...\n", tty->name);
995 #endif
996         return 0;
997 }
998
999 static void
1000 ctc_tty_close(struct tty_struct *tty, struct file *filp)
1001 {
1002         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
1003         ulong flags;
1004         ulong timeout;
1005         DBF_TEXT(trace, 3, __FUNCTION__);
1006         if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close"))
1007                 return;
1008         spin_lock_irqsave(&ctc_tty_lock, flags);
1009         if (tty_hung_up_p(filp)) {
1010                 spin_unlock_irqrestore(&ctc_tty_lock, flags);
1011 #ifdef CTC_DEBUG_MODEM_OPEN
1012                 printk(KERN_DEBUG "ctc_tty_close return after tty_hung_up_p\n");
1013 #endif
1014                 return;
1015         }
1016         if ((tty->count == 1) && (info->count != 1)) {
1017                 /*
1018                  * Uh, oh.  tty->count is 1, which means that the tty
1019                  * structure will be freed.  Info->count should always
1020                  * be one in these conditions.  If it's greater than
1021                  * one, we've got real problems, since it means the
1022                  * serial port won't be shutdown.
1023                  */
1024                 printk(KERN_ERR "ctc_tty_close: bad port count; tty->count is 1, "
1025                        "info->count is %d\n", info->count);
1026                 info->count = 1;
1027         }
1028         if (--info->count < 0) {
1029                 printk(KERN_ERR "ctc_tty_close: bad port count for %s%d: %d\n",
1030                        CTC_TTY_NAME, info->line, info->count);
1031                 info->count = 0;
1032         }
1033         if (info->count) {
1034                 local_irq_restore(flags);
1035 #ifdef CTC_DEBUG_MODEM_OPEN
1036                 printk(KERN_DEBUG "ctc_tty_close after info->count != 0\n");
1037 #endif
1038                 return;
1039         }
1040         info->flags |= CTC_ASYNC_CLOSING;
1041         tty->closing = 1;
1042         /*
1043          * At this point we stop accepting input.  To do this, we
1044          * disable the receive line status interrupts, and tell the
1045          * interrupt driver to stop checking the data ready bit in the
1046          * line status register.
1047          */
1048         if (info->flags & CTC_ASYNC_INITIALIZED) {
1049                 tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
1050                 /*
1051                  * Before we drop DTR, make sure the UART transmitter
1052                  * has completely drained; this is especially
1053                  * important if there is a transmit FIFO!
1054                  */
1055                 timeout = jiffies + HZ;
1056                 while (!(info->lsr & UART_LSR_TEMT)) {
1057                         spin_unlock_irqrestore(&ctc_tty_lock, flags);
1058                         msleep(500);
1059                         spin_lock_irqsave(&ctc_tty_lock, flags);
1060                         if (time_after(jiffies,timeout))
1061                                 break;
1062                 }
1063         }
1064         ctc_tty_shutdown(info);
1065         if (tty->driver->flush_buffer) {
1066                 skb_queue_purge(&info->tx_queue);
1067                 info->lsr |= UART_LSR_TEMT;
1068         }
1069         if (tty->ldisc.flush_buffer)
1070                 tty->ldisc.flush_buffer(tty);
1071         info->tty = 0;
1072         tty->closing = 0;
1073         if (info->blocked_open) {
1074                 set_current_state(TASK_INTERRUPTIBLE);
1075                 schedule_timeout(HZ/2);
1076                 wake_up_interruptible(&info->open_wait);
1077         }
1078         info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
1079         wake_up_interruptible(&info->close_wait);
1080         spin_unlock_irqrestore(&ctc_tty_lock, flags);
1081 #ifdef CTC_DEBUG_MODEM_OPEN
1082         printk(KERN_DEBUG "ctc_tty_close normal exit\n");
1083 #endif
1084 }
1085
1086 /*
1087  * ctc_tty_hangup() --- called by tty_hangup() when a hangup is signaled.
1088  */
1089 static void
1090 ctc_tty_hangup(struct tty_struct *tty)
1091 {
1092         ctc_tty_info *info = (ctc_tty_info *)tty->driver_data;
1093         unsigned long saveflags;
1094         DBF_TEXT(trace, 3, __FUNCTION__);
1095         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_hangup"))
1096                 return;
1097         ctc_tty_shutdown(info);
1098         info->count = 0;
1099         info->flags &= ~CTC_ASYNC_NORMAL_ACTIVE;
1100         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1101         info->tty = 0;
1102         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1103         wake_up_interruptible(&info->open_wait);
1104 }
1105
1106
1107 /*
1108  * For all online tty's, try sending data to
1109  * the lower levels.
1110  */
1111 static void
1112 ctc_tty_task(unsigned long arg)
1113 {
1114         ctc_tty_info *info = (void *)arg;
1115         unsigned long saveflags;
1116         int again;
1117
1118         DBF_TEXT(trace, 3, __FUNCTION__);
1119         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1120         if ((!ctc_tty_shuttingdown) && info) {
1121                 again = ctc_tty_tint(info);
1122                 if (!again)
1123                         info->lsr |= UART_LSR_TEMT;
1124                 again |= ctc_tty_readmodem(info);
1125                 if (again) {
1126                         tasklet_schedule(&info->tasklet);
1127                 }
1128         }
1129         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1130 }
1131
1132 static struct tty_operations ctc_ops = {
1133         .open = ctc_tty_open,
1134         .close = ctc_tty_close,
1135         .write = ctc_tty_write,
1136         .flush_chars = ctc_tty_flush_chars,
1137         .write_room = ctc_tty_write_room,
1138         .chars_in_buffer = ctc_tty_chars_in_buffer,
1139         .flush_buffer = ctc_tty_flush_buffer,
1140         .ioctl = ctc_tty_ioctl,
1141         .throttle = ctc_tty_throttle,
1142         .unthrottle = ctc_tty_unthrottle,
1143         .set_termios = ctc_tty_set_termios,
1144         .hangup = ctc_tty_hangup,
1145         .tiocmget = ctc_tty_tiocmget,
1146         .tiocmset = ctc_tty_tiocmset,
1147 };
1148
1149 int
1150 ctc_tty_init(void)
1151 {
1152         int i;
1153         ctc_tty_info *info;
1154         struct tty_driver *device;
1155
1156         DBF_TEXT(trace, 2, __FUNCTION__);
1157         driver = kmalloc(sizeof(ctc_tty_driver), GFP_KERNEL);
1158         if (driver == NULL) {
1159                 printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
1160                 return -ENOMEM;
1161         }
1162         memset(driver, 0, sizeof(ctc_tty_driver));
1163         device = alloc_tty_driver(CTC_TTY_MAX_DEVICES);
1164         if (!device) {
1165                 kfree(driver);
1166                 printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
1167                 return -ENOMEM;
1168         }
1169
1170         device->devfs_name = "ctc/" CTC_TTY_NAME;
1171         device->name = CTC_TTY_NAME;
1172         device->major = CTC_TTY_MAJOR;
1173         device->minor_start = 0;
1174         device->type = TTY_DRIVER_TYPE_SERIAL;
1175         device->subtype = SERIAL_TYPE_NORMAL;
1176         device->init_termios = tty_std_termios;
1177         device->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1178         device->flags = TTY_DRIVER_REAL_RAW;
1179         device->driver_name = "ctc_tty",
1180         tty_set_operations(device, &ctc_ops);
1181         if (tty_register_driver(device)) {
1182                 printk(KERN_WARNING "ctc_tty: Couldn't register serial-device\n");
1183                 put_tty_driver(device);
1184                 kfree(driver);
1185                 return -1;
1186         }
1187         driver->ctc_tty_device = device;
1188         for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) {
1189                 info = &driver->info[i];
1190                 init_MUTEX(&info->write_sem);
1191                 tasklet_init(&info->tasklet, ctc_tty_task,
1192                                 (unsigned long) info);
1193                 info->magic = CTC_ASYNC_MAGIC;
1194                 info->line = i;
1195                 info->tty = 0;
1196                 info->count = 0;
1197                 info->blocked_open = 0;
1198                 init_waitqueue_head(&info->open_wait);
1199                 init_waitqueue_head(&info->close_wait);
1200                 skb_queue_head_init(&info->tx_queue);
1201                 skb_queue_head_init(&info->rx_queue);
1202                 init_timer(&info->stoptimer);
1203                 info->stoptimer.function = ctc_tty_stopdev;
1204                 info->stoptimer.data = (unsigned long)info;
1205                 info->mcr = UART_MCR_RTS;
1206         }
1207         return 0;
1208 }
1209
1210 int
1211 ctc_tty_register_netdev(struct net_device *dev) {
1212         int ttynum;
1213         char *err;
1214         char *p;
1215
1216         DBF_TEXT(trace, 2, __FUNCTION__);
1217         if ((!dev) || (!dev->name)) {
1218                 printk(KERN_WARNING
1219                        "ctc_tty_register_netdev called "
1220                        "with NULL dev or NULL dev-name\n");
1221                 return -1;
1222         }
1223
1224         /*
1225          *      If the name is a format string the caller wants us to
1226          *      do a name allocation : format string must end with %d
1227          */
1228         if (strchr(dev->name, '%'))
1229         {
1230                 int err = dev_alloc_name(dev, dev->name);       // dev->name is changed by this
1231                 if (err < 0) {
1232                         printk(KERN_DEBUG "dev_alloc returned error %d\n", err);
1233                         return err;
1234                 }
1235
1236         }
1237
1238         for (p = dev->name; p && ((*p < '0') || (*p > '9')); p++);
1239         ttynum = simple_strtoul(p, &err, 0);
1240         if ((ttynum < 0) || (ttynum >= CTC_TTY_MAX_DEVICES) ||
1241             (err && *err)) {
1242                 printk(KERN_WARNING
1243                        "ctc_tty_register_netdev called "
1244                        "with number in name '%s'\n", dev->name);
1245                 return -1;
1246         }
1247         if (driver->info[ttynum].netdev) {
1248                 printk(KERN_WARNING
1249                        "ctc_tty_register_netdev called "
1250                        "for already registered device '%s'\n",
1251                        dev->name);
1252                 return -1;
1253         }
1254         driver->info[ttynum].netdev = dev;
1255         return 0;
1256 }
1257
1258 void
1259 ctc_tty_unregister_netdev(struct net_device *dev) {
1260         int i;
1261         unsigned long saveflags;
1262         ctc_tty_info *info = NULL;
1263
1264         DBF_TEXT(trace, 2, __FUNCTION__);
1265         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1266         for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
1267                 if (driver->info[i].netdev == dev) {
1268                         info = &driver->info[i];
1269                         break;
1270                 }
1271         if (info) {
1272                 info->netdev = NULL;
1273                 skb_queue_purge(&info->tx_queue);
1274                 skb_queue_purge(&info->rx_queue);
1275         }
1276         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1277 }
1278
1279 void
1280 ctc_tty_cleanup(void) {
1281         unsigned long saveflags;
1282         
1283         DBF_TEXT(trace, 2, __FUNCTION__);
1284         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1285         ctc_tty_shuttingdown = 1;
1286         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1287         tty_unregister_driver(driver->ctc_tty_device);
1288         put_tty_driver(driver->ctc_tty_device);
1289         kfree(driver);
1290         driver = NULL;
1291 }