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