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