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