vserver 1.9.3
[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                         tty_wakeup(tty);
311                 }
312         }
313         return (skb_queue_empty(&info->tx_queue) ? 0 : 1);
314 }
315
316 /************************************************************
317  *
318  * Modem-functions
319  *
320  * mostly "stolen" from original Linux-serial.c and friends.
321  *
322  ************************************************************/
323
324 static inline int
325 ctc_tty_paranoia_check(ctc_tty_info * info, char *name, const char *routine)
326 {
327 #ifdef MODEM_PARANOIA_CHECK
328         if (!info) {
329                 printk(KERN_WARNING "ctc_tty: null info_struct for %s in %s\n",
330                        name, routine);
331                 return 1;
332         }
333         if (info->magic != CTC_ASYNC_MAGIC) {
334                 printk(KERN_WARNING "ctc_tty: bad magic for info struct %s in %s\n",
335                        name, routine);
336                 return 1;
337         }
338 #endif
339         return 0;
340 }
341
342 static void
343 ctc_tty_inject(ctc_tty_info *info, char c)
344 {
345         int skb_res;
346         struct sk_buff *skb;
347         
348         DBF_TEXT(trace, 4, __FUNCTION__);
349         if (ctc_tty_shuttingdown)
350                 return;
351         skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
352                 sizeof(__u32) + 1;
353         skb = dev_alloc_skb(skb_res);
354         if (!skb) {
355                 printk(KERN_WARNING
356                        "ctc_tty: Out of memory in %s%d tx_inject\n",
357                        CTC_TTY_NAME, info->line);
358                 return;
359         }
360         skb_reserve(skb, skb_res);
361         *(skb_put(skb, 1)) = c;
362         skb_queue_head(&info->tx_queue, skb);
363         tasklet_schedule(&info->tasklet);
364 }
365
366 static void
367 ctc_tty_transmit_status(ctc_tty_info *info)
368 {
369         DBF_TEXT(trace, 5, __FUNCTION__);
370         if (ctc_tty_shuttingdown)
371                 return;
372         info->flags |= CTC_ASYNC_TX_LINESTAT;
373         tasklet_schedule(&info->tasklet);
374 }
375
376 static void
377 ctc_tty_change_speed(ctc_tty_info * info)
378 {
379         unsigned int cflag;
380         unsigned int quot;
381         int i;
382
383         DBF_TEXT(trace, 3, __FUNCTION__);
384         if (!info->tty || !info->tty->termios)
385                 return;
386         cflag = info->tty->termios->c_cflag;
387
388         quot = i = cflag & CBAUD;
389         if (i & CBAUDEX) {
390                 i &= ~CBAUDEX;
391                 if (i < 1 || i > 2)
392                         info->tty->termios->c_cflag &= ~CBAUDEX;
393                 else
394                         i += 15;
395         }
396         if (quot) {
397                 info->mcr |= UART_MCR_DTR;
398                 info->mcr |= UART_MCR_RTS;
399                 ctc_tty_transmit_status(info);
400         } else {
401                 info->mcr &= ~UART_MCR_DTR;
402                 info->mcr &= ~UART_MCR_RTS;
403                 ctc_tty_transmit_status(info);
404                 return;
405         }
406
407         /* CTS flow control flag and modem status interrupts */
408         if (cflag & CRTSCTS) {
409                 info->flags |= CTC_ASYNC_CTS_FLOW;
410         } else
411                 info->flags &= ~CTC_ASYNC_CTS_FLOW;
412         if (cflag & CLOCAL)
413                 info->flags &= ~CTC_ASYNC_CHECK_CD;
414         else {
415                 info->flags |= CTC_ASYNC_CHECK_CD;
416         }
417 }
418
419 static int
420 ctc_tty_startup(ctc_tty_info * info)
421 {
422         DBF_TEXT(trace, 3, __FUNCTION__);
423         if (info->flags & CTC_ASYNC_INITIALIZED)
424                 return 0;
425 #ifdef CTC_DEBUG_MODEM_OPEN
426         printk(KERN_DEBUG "starting up %s%d ...\n", CTC_TTY_NAME, info->line);
427 #endif
428         /*
429          * Now, initialize the UART
430          */
431         info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
432         if (info->tty)
433                 clear_bit(TTY_IO_ERROR, &info->tty->flags);
434         /*
435          * and set the speed of the serial port
436          */
437         ctc_tty_change_speed(info);
438
439         info->flags |= CTC_ASYNC_INITIALIZED;
440         if (!(info->flags & CTC_ASYNC_NETDEV_OPEN))
441                 info->netdev->open(info->netdev);
442         info->flags |= CTC_ASYNC_NETDEV_OPEN;
443         return 0;
444 }
445
446 static void
447 ctc_tty_stopdev(unsigned long data)
448 {
449         ctc_tty_info *info = (ctc_tty_info *)data;
450
451         if ((!info) || (!info->netdev) ||
452             (info->flags & CTC_ASYNC_INITIALIZED))
453                 return;
454         info->netdev->stop(info->netdev);
455         info->flags &= ~CTC_ASYNC_NETDEV_OPEN;
456 }
457
458 /*
459  * This routine will shutdown a serial port; interrupts are disabled, and
460  * DTR is dropped if the hangup on close termio flag is on.
461  */
462 static void
463 ctc_tty_shutdown(ctc_tty_info * info)
464 {
465         DBF_TEXT(trace, 3, __FUNCTION__);
466         if (!(info->flags & CTC_ASYNC_INITIALIZED))
467                 return;
468 #ifdef CTC_DEBUG_MODEM_OPEN
469         printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line);
470 #endif
471         info->msr &= ~UART_MSR_RI;
472         if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
473                 info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
474         if (info->tty)
475                 set_bit(TTY_IO_ERROR, &info->tty->flags);
476         mod_timer(&info->stoptimer, jiffies + (10 * HZ));
477         skb_queue_purge(&info->tx_queue);
478         skb_queue_purge(&info->rx_queue);
479         info->flags &= ~CTC_ASYNC_INITIALIZED;
480 }
481
482 /* ctc_tty_write() is the main send-routine. It is called from the upper
483  * levels within the kernel to perform sending data. Depending on the
484  * online-flag it either directs output to the at-command-interpreter or
485  * to the lower level. Additional tasks done here:
486  *  - If online, check for escape-sequence (+++)
487  *  - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes.
488  *  - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed.
489  *  - If dialing, abort dial.
490  */
491 static int
492 ctc_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int count)
493 {
494         int c;
495         int total = 0;
496         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
497
498         DBF_TEXT(trace, 5, __FUNCTION__);
499         if (ctc_tty_shuttingdown)
500                 goto ex;
501         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write"))
502                 goto ex;
503         if (!tty)
504                 goto ex;
505         if (!info->netdev) {
506                 total = -ENODEV;
507                 goto ex;
508         }
509         if (from_user)
510                 down(&info->write_sem);
511         while (1) {
512                 struct sk_buff *skb;
513                 int skb_res;
514
515                 c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE;
516                 if (c <= 0)
517                         break;
518                 
519                 skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
520                         + sizeof(__u32);
521                 skb = dev_alloc_skb(skb_res + c);
522                 if (!skb) {
523                         printk(KERN_WARNING
524                                "ctc_tty: Out of memory in %s%d write\n",
525                                CTC_TTY_NAME, info->line);
526                         break;
527                 }
528                 skb_reserve(skb, skb_res);
529                 if (from_user)
530                         copy_from_user(skb_put(skb, c),
531                                         (const u_char __user *)buf, c);
532                 else
533                         memcpy(skb_put(skb, c), buf, c);
534                 skb_queue_tail(&info->tx_queue, skb);
535                 buf += c;
536                 total += c;
537                 count -= c;
538         }
539         if (skb_queue_len(&info->tx_queue)) {
540                 info->lsr &= ~UART_LSR_TEMT;
541                 tasklet_schedule(&info->tasklet);
542         }
543         if (from_user)
544                 up(&info->write_sem);
545 ex:
546         DBF_TEXT(trace, 6, __FUNCTION__);
547         return total;
548 }
549
550 static int
551 ctc_tty_write_room(struct tty_struct *tty)
552 {
553         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
554
555         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room"))
556                 return 0;
557         return CTC_TTY_XMIT_SIZE;
558 }
559
560 static int
561 ctc_tty_chars_in_buffer(struct tty_struct *tty)
562 {
563         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
564
565         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_chars_in_buffer"))
566                 return 0;
567         return 0;
568 }
569
570 static void
571 ctc_tty_flush_buffer(struct tty_struct *tty)
572 {
573         ctc_tty_info *info;
574         unsigned long flags;
575
576         DBF_TEXT(trace, 4, __FUNCTION__);
577         if (!tty)
578                 goto ex;
579         spin_lock_irqsave(&ctc_tty_lock, flags);
580         info = (ctc_tty_info *) tty->driver_data;
581         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_buffer")) {
582                 spin_unlock_irqrestore(&ctc_tty_lock, flags);
583                 goto ex;
584         }
585         skb_queue_purge(&info->tx_queue);
586         info->lsr |= UART_LSR_TEMT;
587         spin_unlock_irqrestore(&ctc_tty_lock, flags);
588         wake_up_interruptible(&tty->write_wait);
589         tty_wakeup(tty);
590 ex:
591         DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__);
592         return;
593 }
594
595 static void
596 ctc_tty_flush_chars(struct tty_struct *tty)
597 {
598         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
599
600         DBF_TEXT(trace, 4, __FUNCTION__);
601         if (ctc_tty_shuttingdown)
602                 return;
603         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
604                 return;
605         if (tty->stopped || tty->hw_stopped || (!skb_queue_len(&info->tx_queue)))
606                 return;
607         tasklet_schedule(&info->tasklet);
608 }
609
610 /*
611  * ------------------------------------------------------------
612  * ctc_tty_throttle()
613  *
614  * This routine is called by the upper-layer tty layer to signal that
615  * incoming characters should be throttled.
616  * ------------------------------------------------------------
617  */
618 static void
619 ctc_tty_throttle(struct tty_struct *tty)
620 {
621         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
622
623         DBF_TEXT(trace, 4, __FUNCTION__);
624         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle"))
625                 return;
626         info->mcr &= ~UART_MCR_RTS;
627         if (I_IXOFF(tty))
628                 ctc_tty_inject(info, STOP_CHAR(tty));
629         ctc_tty_transmit_status(info);
630 }
631
632 static void
633 ctc_tty_unthrottle(struct tty_struct *tty)
634 {
635         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
636
637         DBF_TEXT(trace, 4, __FUNCTION__);
638         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle"))
639                 return;
640         info->mcr |= UART_MCR_RTS;
641         if (I_IXOFF(tty))
642                 ctc_tty_inject(info, START_CHAR(tty));
643         ctc_tty_transmit_status(info);
644 }
645
646 /*
647  * ------------------------------------------------------------
648  * ctc_tty_ioctl() and friends
649  * ------------------------------------------------------------
650  */
651
652 /*
653  * ctc_tty_get_lsr_info - get line status register info
654  *
655  * Purpose: Let user call ioctl() to get info when the UART physically
656  *          is emptied.  On bus types like RS485, the transmitter must
657  *          release the bus after transmitting. This must be done when
658  *          the transmit shift register is empty, not be done when the
659  *          transmit holding register is empty.  This functionality
660  *          allows RS485 driver to be written in user space.
661  */
662 static int
663 ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
664 {
665         u_char status;
666         uint result;
667         ulong flags;
668
669         DBF_TEXT(trace, 4, __FUNCTION__);
670         spin_lock_irqsave(&ctc_tty_lock, flags);
671         status = info->lsr;
672         spin_unlock_irqrestore(&ctc_tty_lock, flags);
673         result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
674         put_user(result, value);
675         return 0;
676 }
677
678
679 static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file)
680 {
681         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
682         u_char control,
683          status;
684         uint result;
685         ulong flags;
686
687         DBF_TEXT(trace, 4, __FUNCTION__);
688         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
689                 return -ENODEV;
690         if (tty->flags & (1 << TTY_IO_ERROR))
691                 return -EIO;
692
693         control = info->mcr;
694         spin_lock_irqsave(&ctc_tty_lock, flags);
695         status = info->msr;
696         spin_unlock_irqrestore(&ctc_tty_lock, flags);
697         result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
698             | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
699             | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
700             | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
701             | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
702             | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
703         return result;
704 }
705
706 static int
707 ctc_tty_tiocmset(struct tty_struct *tty, struct file *file,
708                  unsigned int set, unsigned int clear)
709 {
710         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
711
712         DBF_TEXT(trace, 4, __FUNCTION__);
713         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
714                 return -ENODEV;
715         if (tty->flags & (1 << TTY_IO_ERROR))
716                 return -EIO;
717
718         if (set & TIOCM_RTS)
719                 info->mcr |= UART_MCR_RTS;
720         if (set & TIOCM_DTR)
721                 info->mcr |= UART_MCR_DTR;
722
723         if (clear & TIOCM_RTS)
724                 info->mcr &= ~UART_MCR_RTS;
725         if (clear & TIOCM_DTR)
726                 info->mcr &= ~UART_MCR_DTR;
727
728         if ((set | clear) & (TIOCM_RTS|TIOCM_DTR))
729                 ctc_tty_transmit_status(info);
730         return 0;
731 }
732
733 static int
734 ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
735                uint cmd, ulong arg)
736 {
737         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
738         int error;
739         int retval;
740
741         DBF_TEXT(trace, 4, __FUNCTION__);
742         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
743                 return -ENODEV;
744         if (tty->flags & (1 << TTY_IO_ERROR))
745                 return -EIO;
746         switch (cmd) {
747                 case TCSBRK:   /* SVID version: non-zero arg --> no break */
748 #ifdef CTC_DEBUG_MODEM_IOCTL
749                         printk(KERN_DEBUG "%s%d ioctl TCSBRK\n", CTC_TTY_NAME, info->line);
750 #endif
751                         retval = tty_check_change(tty);
752                         if (retval)
753                                 return retval;
754                         tty_wait_until_sent(tty, 0);
755                         return 0;
756                 case TCSBRKP:  /* support for POSIX tcsendbreak() */
757 #ifdef CTC_DEBUG_MODEM_IOCTL
758                         printk(KERN_DEBUG "%s%d ioctl TCSBRKP\n", CTC_TTY_NAME, info->line);
759 #endif
760                         retval = tty_check_change(tty);
761                         if (retval)
762                                 return retval;
763                         tty_wait_until_sent(tty, 0);
764                         return 0;
765                 case TIOCGSOFTCAR:
766 #ifdef CTC_DEBUG_MODEM_IOCTL
767                         printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,
768                                info->line);
769 #endif
770                         error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
771                         return error;
772                 case TIOCSSOFTCAR:
773 #ifdef CTC_DEBUG_MODEM_IOCTL
774                         printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,
775                                info->line);
776 #endif
777                         error = get_user(arg, (ulong __user *) arg);
778                         if (error)
779                                 return error;
780                         tty->termios->c_cflag =
781                             ((tty->termios->c_cflag & ~CLOCAL) |
782                              (arg ? CLOCAL : 0));
783                         return 0;
784                 case TIOCSERGETLSR:     /* Get line status register */
785 #ifdef CTC_DEBUG_MODEM_IOCTL
786                         printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
787                                info->line);
788 #endif
789                         error = verify_area(VERIFY_WRITE, (void __user *) arg, sizeof(uint));
790                         if (error)
791                                 return error;
792                         else
793                                 return ctc_tty_get_lsr_info(info, (uint __user *) arg);
794                 default:
795 #ifdef CTC_DEBUG_MODEM_IOCTL
796                         printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
797                                CTC_TTY_NAME, info->line);
798 #endif
799                         return -ENOIOCTLCMD;
800         }
801         return 0;
802 }
803
804 static void
805 ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
806 {
807         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
808         unsigned int cflag = tty->termios->c_cflag;
809
810         DBF_TEXT(trace, 4, __FUNCTION__);
811         ctc_tty_change_speed(info);
812
813         /* Handle transition to B0 */
814         if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) {
815                 info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS);
816                 ctc_tty_transmit_status(info);
817         }
818
819         /* Handle transition from B0 to other */
820         if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
821                 info->mcr |= UART_MCR_DTR;
822                 if (!(tty->termios->c_cflag & CRTSCTS) ||
823                     !test_bit(TTY_THROTTLED, &tty->flags)) {
824                         info->mcr |= UART_MCR_RTS;
825                 }
826                 ctc_tty_transmit_status(info);
827         }
828
829         /* Handle turning off CRTSCTS */
830         if ((old_termios->c_cflag & CRTSCTS) &&
831             !(tty->termios->c_cflag & CRTSCTS))
832                 tty->hw_stopped = 0;
833 }
834
835 /*
836  * ------------------------------------------------------------
837  * ctc_tty_open() and friends
838  * ------------------------------------------------------------
839  */
840 static int
841 ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info *info)
842 {
843         DECLARE_WAITQUEUE(wait, NULL);
844         int do_clocal = 0;
845         unsigned long flags;
846         int retval;
847
848         DBF_TEXT(trace, 4, __FUNCTION__);
849         /*
850          * If the device is in the middle of being closed, then block
851          * until it's done, and then try again.
852          */
853         if (tty_hung_up_p(filp) ||
854             (info->flags & CTC_ASYNC_CLOSING)) {
855                 if (info->flags & CTC_ASYNC_CLOSING)
856                         wait_event(info->close_wait, 
857                                    !(info->flags & CTC_ASYNC_CLOSING));
858 #ifdef MODEM_DO_RESTART
859                 if (info->flags & CTC_ASYNC_HUP_NOTIFY)
860                         return -EAGAIN;
861                 else
862                         return -ERESTARTSYS;
863 #else
864                 return -EAGAIN;
865 #endif
866         }
867         /*
868          * If non-blocking mode is set, then make the check up front
869          * and then exit.
870          */
871         if ((filp->f_flags & O_NONBLOCK) ||
872             (tty->flags & (1 << TTY_IO_ERROR))) {
873                 info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
874                 return 0;
875         }
876         if (tty->termios->c_cflag & CLOCAL)
877                 do_clocal = 1;
878         /*
879          * Block waiting for the carrier detect and the line to become
880          * free (i.e., not in use by the callout).  While we are in
881          * this loop, info->count is dropped by one, so that
882          * ctc_tty_close() knows when to free things.  We restore it upon
883          * exit, either normal or abnormal.
884          */
885         retval = 0;
886         add_wait_queue(&info->open_wait, &wait);
887 #ifdef CTC_DEBUG_MODEM_OPEN
888         printk(KERN_DEBUG "ctc_tty_block_til_ready before block: %s%d, count = %d\n",
889                CTC_TTY_NAME, info->line, info->count);
890 #endif
891         spin_lock_irqsave(&ctc_tty_lock, flags);
892         if (!(tty_hung_up_p(filp)))
893                 info->count--;
894         spin_unlock_irqrestore(&ctc_tty_lock, flags);
895         info->blocked_open++;
896         while (1) {
897                 set_current_state(TASK_INTERRUPTIBLE);
898                 if (tty_hung_up_p(filp) ||
899                     !(info->flags & CTC_ASYNC_INITIALIZED)) {
900 #ifdef MODEM_DO_RESTART
901                         if (info->flags & CTC_ASYNC_HUP_NOTIFY)
902                                 retval = -EAGAIN;
903                         else
904                                 retval = -ERESTARTSYS;
905 #else
906                         retval = -EAGAIN;
907 #endif
908                         break;
909                 }
910                 if (!(info->flags & CTC_ASYNC_CLOSING) &&
911                     (do_clocal || (info->msr & UART_MSR_DCD))) {
912                         break;
913                 }
914                 if (signal_pending(current)) {
915                         retval = -ERESTARTSYS;
916                         break;
917                 }
918 #ifdef CTC_DEBUG_MODEM_OPEN
919                 printk(KERN_DEBUG "ctc_tty_block_til_ready blocking: %s%d, count = %d\n",
920                        CTC_TTY_NAME, info->line, info->count);
921 #endif
922                 schedule();
923         }
924         current->state = TASK_RUNNING;
925         remove_wait_queue(&info->open_wait, &wait);
926         if (!tty_hung_up_p(filp))
927                 info->count++;
928         info->blocked_open--;
929 #ifdef CTC_DEBUG_MODEM_OPEN
930         printk(KERN_DEBUG "ctc_tty_block_til_ready after blocking: %s%d, count = %d\n",
931                CTC_TTY_NAME, info->line, info->count);
932 #endif
933         if (retval)
934                 return retval;
935         info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
936         return 0;
937 }
938
939 /*
940  * This routine is called whenever a serial port is opened.  It
941  * enables interrupts for a serial port, linking in its async structure into
942  * the IRQ chain.   It also performs the serial-specific
943  * initialization for the tty structure.
944  */
945 static int
946 ctc_tty_open(struct tty_struct *tty, struct file *filp)
947 {
948         ctc_tty_info *info;
949         unsigned long saveflags;
950         int retval,
951          line;
952
953         DBF_TEXT(trace, 3, __FUNCTION__);
954         line = tty->index;
955         if (line < 0 || line > CTC_TTY_MAX_DEVICES)
956                 return -ENODEV;
957         info = &driver->info[line];
958         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_open"))
959                 return -ENODEV;
960         if (!info->netdev)
961                 return -ENODEV;
962 #ifdef CTC_DEBUG_MODEM_OPEN
963         printk(KERN_DEBUG "ctc_tty_open %s, count = %d\n", tty->name,
964                info->count);
965 #endif
966         spin_lock_irqsave(&ctc_tty_lock, saveflags);
967         info->count++;
968         tty->driver_data = info;
969         info->tty = tty;
970         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
971         /*
972          * Start up serial port
973          */
974         retval = ctc_tty_startup(info);
975         if (retval) {
976 #ifdef CTC_DEBUG_MODEM_OPEN
977                 printk(KERN_DEBUG "ctc_tty_open return after startup\n");
978 #endif
979                 return retval;
980         }
981         retval = ctc_tty_block_til_ready(tty, filp, info);
982         if (retval) {
983 #ifdef CTC_DEBUG_MODEM_OPEN
984                 printk(KERN_DEBUG "ctc_tty_open return after ctc_tty_block_til_ready \n");
985 #endif
986                 return retval;
987         }
988 #ifdef CTC_DEBUG_MODEM_OPEN
989         printk(KERN_DEBUG "ctc_tty_open %s successful...\n", tty->name);
990 #endif
991         return 0;
992 }
993
994 static void
995 ctc_tty_close(struct tty_struct *tty, struct file *filp)
996 {
997         ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
998         ulong flags;
999         ulong timeout;
1000         DBF_TEXT(trace, 3, __FUNCTION__);
1001         if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close"))
1002                 return;
1003         spin_lock_irqsave(&ctc_tty_lock, flags);
1004         if (tty_hung_up_p(filp)) {
1005                 spin_unlock_irqrestore(&ctc_tty_lock, flags);
1006 #ifdef CTC_DEBUG_MODEM_OPEN
1007                 printk(KERN_DEBUG "ctc_tty_close return after tty_hung_up_p\n");
1008 #endif
1009                 return;
1010         }
1011         if ((tty->count == 1) && (info->count != 1)) {
1012                 /*
1013                  * Uh, oh.  tty->count is 1, which means that the tty
1014                  * structure will be freed.  Info->count should always
1015                  * be one in these conditions.  If it's greater than
1016                  * one, we've got real problems, since it means the
1017                  * serial port won't be shutdown.
1018                  */
1019                 printk(KERN_ERR "ctc_tty_close: bad port count; tty->count is 1, "
1020                        "info->count is %d\n", info->count);
1021                 info->count = 1;
1022         }
1023         if (--info->count < 0) {
1024                 printk(KERN_ERR "ctc_tty_close: bad port count for %s%d: %d\n",
1025                        CTC_TTY_NAME, info->line, info->count);
1026                 info->count = 0;
1027         }
1028         if (info->count) {
1029                 local_irq_restore(flags);
1030 #ifdef CTC_DEBUG_MODEM_OPEN
1031                 printk(KERN_DEBUG "ctc_tty_close after info->count != 0\n");
1032 #endif
1033                 return;
1034         }
1035         info->flags |= CTC_ASYNC_CLOSING;
1036         tty->closing = 1;
1037         /*
1038          * At this point we stop accepting input.  To do this, we
1039          * disable the receive line status interrupts, and tell the
1040          * interrupt driver to stop checking the data ready bit in the
1041          * line status register.
1042          */
1043         if (info->flags & CTC_ASYNC_INITIALIZED) {
1044                 tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
1045                 /*
1046                  * Before we drop DTR, make sure the UART transmitter
1047                  * has completely drained; this is especially
1048                  * important if there is a transmit FIFO!
1049                  */
1050                 timeout = jiffies + HZ;
1051                 while (!(info->lsr & UART_LSR_TEMT)) {
1052                         spin_unlock_irqrestore(&ctc_tty_lock, flags);
1053                         msleep(500);
1054                         spin_lock_irqsave(&ctc_tty_lock, flags);
1055                         if (time_after(jiffies,timeout))
1056                                 break;
1057                 }
1058         }
1059         ctc_tty_shutdown(info);
1060         if (tty->driver->flush_buffer) {
1061                 skb_queue_purge(&info->tx_queue);
1062                 info->lsr |= UART_LSR_TEMT;
1063         }
1064         tty_ldisc_flush(tty);
1065         info->tty = 0;
1066         tty->closing = 0;
1067         if (info->blocked_open) {
1068                 set_current_state(TASK_INTERRUPTIBLE);
1069                 schedule_timeout(HZ/2);
1070                 wake_up_interruptible(&info->open_wait);
1071         }
1072         info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
1073         wake_up_interruptible(&info->close_wait);
1074         spin_unlock_irqrestore(&ctc_tty_lock, flags);
1075 #ifdef CTC_DEBUG_MODEM_OPEN
1076         printk(KERN_DEBUG "ctc_tty_close normal exit\n");
1077 #endif
1078 }
1079
1080 /*
1081  * ctc_tty_hangup() --- called by tty_hangup() when a hangup is signaled.
1082  */
1083 static void
1084 ctc_tty_hangup(struct tty_struct *tty)
1085 {
1086         ctc_tty_info *info = (ctc_tty_info *)tty->driver_data;
1087         unsigned long saveflags;
1088         DBF_TEXT(trace, 3, __FUNCTION__);
1089         if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_hangup"))
1090                 return;
1091         ctc_tty_shutdown(info);
1092         info->count = 0;
1093         info->flags &= ~CTC_ASYNC_NORMAL_ACTIVE;
1094         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1095         info->tty = 0;
1096         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1097         wake_up_interruptible(&info->open_wait);
1098 }
1099
1100
1101 /*
1102  * For all online tty's, try sending data to
1103  * the lower levels.
1104  */
1105 static void
1106 ctc_tty_task(unsigned long arg)
1107 {
1108         ctc_tty_info *info = (void *)arg;
1109         unsigned long saveflags;
1110         int again;
1111
1112         DBF_TEXT(trace, 3, __FUNCTION__);
1113         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1114         if ((!ctc_tty_shuttingdown) && info) {
1115                 again = ctc_tty_tint(info);
1116                 if (!again)
1117                         info->lsr |= UART_LSR_TEMT;
1118                 again |= ctc_tty_readmodem(info);
1119                 if (again) {
1120                         tasklet_schedule(&info->tasklet);
1121                 }
1122         }
1123         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1124 }
1125
1126 static struct tty_operations ctc_ops = {
1127         .open = ctc_tty_open,
1128         .close = ctc_tty_close,
1129         .write = ctc_tty_write,
1130         .flush_chars = ctc_tty_flush_chars,
1131         .write_room = ctc_tty_write_room,
1132         .chars_in_buffer = ctc_tty_chars_in_buffer,
1133         .flush_buffer = ctc_tty_flush_buffer,
1134         .ioctl = ctc_tty_ioctl,
1135         .throttle = ctc_tty_throttle,
1136         .unthrottle = ctc_tty_unthrottle,
1137         .set_termios = ctc_tty_set_termios,
1138         .hangup = ctc_tty_hangup,
1139         .tiocmget = ctc_tty_tiocmget,
1140         .tiocmset = ctc_tty_tiocmset,
1141 };
1142
1143 int
1144 ctc_tty_init(void)
1145 {
1146         int i;
1147         ctc_tty_info *info;
1148         struct tty_driver *device;
1149
1150         DBF_TEXT(trace, 2, __FUNCTION__);
1151         driver = kmalloc(sizeof(ctc_tty_driver), GFP_KERNEL);
1152         if (driver == NULL) {
1153                 printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
1154                 return -ENOMEM;
1155         }
1156         memset(driver, 0, sizeof(ctc_tty_driver));
1157         device = alloc_tty_driver(CTC_TTY_MAX_DEVICES);
1158         if (!device) {
1159                 kfree(driver);
1160                 printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
1161                 return -ENOMEM;
1162         }
1163
1164         device->devfs_name = "ctc/" CTC_TTY_NAME;
1165         device->name = CTC_TTY_NAME;
1166         device->major = CTC_TTY_MAJOR;
1167         device->minor_start = 0;
1168         device->type = TTY_DRIVER_TYPE_SERIAL;
1169         device->subtype = SERIAL_TYPE_NORMAL;
1170         device->init_termios = tty_std_termios;
1171         device->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1172         device->flags = TTY_DRIVER_REAL_RAW;
1173         device->driver_name = "ctc_tty",
1174         tty_set_operations(device, &ctc_ops);
1175         if (tty_register_driver(device)) {
1176                 printk(KERN_WARNING "ctc_tty: Couldn't register serial-device\n");
1177                 put_tty_driver(device);
1178                 kfree(driver);
1179                 return -1;
1180         }
1181         driver->ctc_tty_device = device;
1182         for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) {
1183                 info = &driver->info[i];
1184                 init_MUTEX(&info->write_sem);
1185                 tasklet_init(&info->tasklet, ctc_tty_task,
1186                                 (unsigned long) info);
1187                 info->magic = CTC_ASYNC_MAGIC;
1188                 info->line = i;
1189                 info->tty = 0;
1190                 info->count = 0;
1191                 info->blocked_open = 0;
1192                 init_waitqueue_head(&info->open_wait);
1193                 init_waitqueue_head(&info->close_wait);
1194                 skb_queue_head_init(&info->tx_queue);
1195                 skb_queue_head_init(&info->rx_queue);
1196                 init_timer(&info->stoptimer);
1197                 info->stoptimer.function = ctc_tty_stopdev;
1198                 info->stoptimer.data = (unsigned long)info;
1199                 info->mcr = UART_MCR_RTS;
1200         }
1201         return 0;
1202 }
1203
1204 int
1205 ctc_tty_register_netdev(struct net_device *dev) {
1206         int ttynum;
1207         char *err;
1208         char *p;
1209
1210         DBF_TEXT(trace, 2, __FUNCTION__);
1211         if ((!dev) || (!dev->name)) {
1212                 printk(KERN_WARNING
1213                        "ctc_tty_register_netdev called "
1214                        "with NULL dev or NULL dev-name\n");
1215                 return -1;
1216         }
1217
1218         /*
1219          *      If the name is a format string the caller wants us to
1220          *      do a name allocation : format string must end with %d
1221          */
1222         if (strchr(dev->name, '%'))
1223         {
1224                 int err = dev_alloc_name(dev, dev->name);       // dev->name is changed by this
1225                 if (err < 0) {
1226                         printk(KERN_DEBUG "dev_alloc returned error %d\n", err);
1227                         return err;
1228                 }
1229
1230         }
1231
1232         for (p = dev->name; p && ((*p < '0') || (*p > '9')); p++);
1233         ttynum = simple_strtoul(p, &err, 0);
1234         if ((ttynum < 0) || (ttynum >= CTC_TTY_MAX_DEVICES) ||
1235             (err && *err)) {
1236                 printk(KERN_WARNING
1237                        "ctc_tty_register_netdev called "
1238                        "with number in name '%s'\n", dev->name);
1239                 return -1;
1240         }
1241         if (driver->info[ttynum].netdev) {
1242                 printk(KERN_WARNING
1243                        "ctc_tty_register_netdev called "
1244                        "for already registered device '%s'\n",
1245                        dev->name);
1246                 return -1;
1247         }
1248         driver->info[ttynum].netdev = dev;
1249         return 0;
1250 }
1251
1252 void
1253 ctc_tty_unregister_netdev(struct net_device *dev) {
1254         int i;
1255         unsigned long saveflags;
1256         ctc_tty_info *info = NULL;
1257
1258         DBF_TEXT(trace, 2, __FUNCTION__);
1259         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1260         for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
1261                 if (driver->info[i].netdev == dev) {
1262                         info = &driver->info[i];
1263                         break;
1264                 }
1265         if (info) {
1266                 info->netdev = NULL;
1267                 skb_queue_purge(&info->tx_queue);
1268                 skb_queue_purge(&info->rx_queue);
1269         }
1270         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1271 }
1272
1273 void
1274 ctc_tty_cleanup(void) {
1275         unsigned long saveflags;
1276         
1277         DBF_TEXT(trace, 2, __FUNCTION__);
1278         spin_lock_irqsave(&ctc_tty_lock, saveflags);
1279         ctc_tty_shuttingdown = 1;
1280         spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
1281         tty_unregister_driver(driver->ctc_tty_device);
1282         put_tty_driver(driver->ctc_tty_device);
1283         kfree(driver);
1284         driver = NULL;
1285 }