1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#include <linux/slab.h>
40#include <linux/tty.h>
41#include <linux/tty_flip.h>
42#include <linux/device.h>
43#include <linux/sched.h>
44#include <linux/uaccess.h>
45
46#include "dgrp_common.h"
47
48#ifndef _POSIX_VDISABLE
49#define _POSIX_VDISABLE ('\0')
50#endif
51
52
53
54
55
56static void drp_param(struct ch_struct *);
57static void dgrp_tty_close(struct tty_struct *, struct file *);
58
59
60static int set_modem_info(struct ch_struct *, unsigned int, unsigned int *);
61static int get_modem_info(struct ch_struct *, unsigned int *);
62static void dgrp_set_custom_speed(struct ch_struct *, int);
63static int dgrp_tty_digigetedelay(struct tty_struct *, int *);
64static int dgrp_tty_digisetedelay(struct tty_struct *, int *);
65static int dgrp_send_break(struct ch_struct *, int);
66
67static ushort tty_to_ch_flags(struct tty_struct *, char);
68static tcflag_t ch_to_tty_flags(unsigned short, char);
69
70static void dgrp_tty_input_start(struct tty_struct *);
71static void dgrp_tty_input_stop(struct tty_struct *);
72
73static void drp_wmove(struct ch_struct *, int, void*, int);
74
75static int dgrp_tty_open(struct tty_struct *, struct file *);
76static void dgrp_tty_close(struct tty_struct *, struct file *);
77static int dgrp_tty_write(struct tty_struct *, const unsigned char *, int);
78static int dgrp_tty_write_room(struct tty_struct *);
79static void dgrp_tty_flush_buffer(struct tty_struct *);
80static int dgrp_tty_chars_in_buffer(struct tty_struct *);
81static int dgrp_tty_ioctl(struct tty_struct *, unsigned int, unsigned long);
82static void dgrp_tty_set_termios(struct tty_struct *, struct ktermios *);
83static void dgrp_tty_stop(struct tty_struct *);
84static void dgrp_tty_start(struct tty_struct *);
85static void dgrp_tty_throttle(struct tty_struct *);
86static void dgrp_tty_unthrottle(struct tty_struct *);
87static void dgrp_tty_hangup(struct tty_struct *);
88static int dgrp_tty_put_char(struct tty_struct *, unsigned char);
89static int dgrp_tty_tiocmget(struct tty_struct *);
90static int dgrp_tty_tiocmset(struct tty_struct *, unsigned int, unsigned int);
91static int dgrp_tty_send_break(struct tty_struct *, int);
92static void dgrp_tty_send_xchar(struct tty_struct *, char);
93
94
95
96
97#define SERIAL_TYPE_NORMAL 1
98#define SERIAL_TYPE_CALLOUT 2
99#define SERIAL_TYPE_XPRINT 3
100
101
102
103
104
105
106
107#define PORTSERVER_DIVIDEND 1843200
108
109
110
111
112static struct digi_struct digi_init = {
113 .digi_flags = DIGI_COOK,
114 .digi_maxcps = 100,
115 .digi_maxchar = 50,
116 .digi_bufsize = 100,
117 .digi_onlen = 4,
118 .digi_offlen = 4,
119 .digi_onstr = "\033[5i",
120 .digi_offstr = "\033[4i",
121 .digi_term = "ansi"
122};
123
124
125
126
127
128
129
130
131static struct ktermios DefaultTermios = {
132 .c_iflag = (ICRNL | IXON),
133 .c_oflag = (OPOST | ONLCR),
134 .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
135 .c_lflag = (ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL
136 | ECHOKE | IEXTEN),
137 .c_cc = INIT_C_CC,
138 .c_line = 0,
139};
140
141
142static const struct tty_operations dgrp_tty_ops = {
143 .open = dgrp_tty_open,
144 .close = dgrp_tty_close,
145 .write = dgrp_tty_write,
146 .write_room = dgrp_tty_write_room,
147 .flush_buffer = dgrp_tty_flush_buffer,
148 .chars_in_buffer = dgrp_tty_chars_in_buffer,
149 .flush_chars = NULL,
150 .ioctl = dgrp_tty_ioctl,
151 .set_termios = dgrp_tty_set_termios,
152 .stop = dgrp_tty_stop,
153 .start = dgrp_tty_start,
154 .throttle = dgrp_tty_throttle,
155 .unthrottle = dgrp_tty_unthrottle,
156 .hangup = dgrp_tty_hangup,
157 .put_char = dgrp_tty_put_char,
158 .tiocmget = dgrp_tty_tiocmget,
159 .tiocmset = dgrp_tty_tiocmset,
160 .break_ctl = dgrp_tty_send_break,
161 .send_xchar = dgrp_tty_send_xchar
162};
163
164
165static int calc_baud_rate(struct un_struct *un)
166{
167 int i;
168 int brate;
169
170 struct baud_rates {
171 unsigned int rate;
172 unsigned int cflag;
173 };
174
175 static struct baud_rates baud_rates[] = {
176 { 921600, B921600 },
177 { 460800, B460800 },
178 { 230400, B230400 },
179 { 115200, B115200 },
180 { 57600, B57600 },
181 { 38400, B38400 },
182 { 19200, B19200 },
183 { 9600, B9600 },
184 { 4800, B4800 },
185 { 2400, B2400 },
186 { 1200, B1200 },
187 { 600, B600 },
188 { 300, B300 },
189 { 200, B200 },
190 { 150, B150 },
191 { 134, B134 },
192 { 110, B110 },
193 { 75, B75 },
194 { 50, B50 },
195 { 0, B9600 }
196 };
197
198 brate = C_BAUD(un->un_tty);
199
200 for (i = 0; baud_rates[i].rate; i++) {
201 if (baud_rates[i].cflag == brate)
202 break;
203 }
204
205 return baud_rates[i].rate;
206}
207
208static int calc_fastbaud_rate(struct un_struct *un, struct ktermios *uts)
209{
210 int i;
211 int brate;
212
213 ulong bauds[2][16] = {
214 {
215 0, 57600, 76800, 115200,
216 131657, 153600, 230400, 460800,
217 921600, 1200, 1800, 2400,
218 4800, 9600, 19200, 38400 },
219 {
220 0, 57600, 115200, 230400,
221 460800, 150, 200, 921600,
222 600, 1200, 1800, 2400,
223 4800, 9600, 19200, 38400 }
224 };
225
226 brate = C_BAUD(un->un_tty) & 0xff;
227
228 i = (uts->c_cflag & CBAUDEX) ? 1 : 0;
229
230
231 if ((i >= 0) && (i < 2) && (brate >= 0) && (brate < 16))
232 brate = bauds[i][brate];
233 else
234 brate = 0;
235
236 return brate;
237}
238
239
240
241
242
243
244
245
246
247static void drp_param(struct ch_struct *ch)
248{
249 struct nd_struct *nd;
250 struct un_struct *un;
251 int brate;
252 int mflow;
253 int xflag;
254 int iflag;
255 struct ktermios *tts, *pts, *uts;
256
257 nd = ch->ch_nd;
258
259
260
261
262
263
264 if (ch->ch_tun.un_open_count) {
265
266 un = &ch->ch_tun;
267 tts = &ch->ch_tun.un_tty->termios;
268
269
270
271
272
273
274
275
276 if (ch->ch_pun.un_open_count) {
277
278 pts = &ch->ch_pun.un_tty->termios;
279
280 pts->c_cflag ^=
281 (pts->c_cflag ^ tts->c_cflag) &
282 (CBAUD | CSIZE | CSTOPB | CREAD | PARENB |
283 PARODD | HUPCL | CLOCAL);
284
285 pts->c_iflag ^=
286 (pts->c_iflag ^ tts->c_iflag) &
287 (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK |
288 ISTRIP | IXON | IXANY | IXOFF);
289
290 pts->c_cc[VSTART] = tts->c_cc[VSTART];
291 pts->c_cc[VSTOP] = tts->c_cc[VSTOP];
292 }
293 } else if (ch->ch_pun.un_open_count == 0) {
294 pr_warn("%s - ch_pun.un_open_count shouldn't be 0\n",
295 __func__);
296 return;
297 } else {
298 un = &ch->ch_pun;
299 }
300
301 uts = &un->un_tty->termios;
302
303
304
305
306
307 if ((ch->ch_digi.digi_flags & DIGI_COOK) != 0 &&
308 (ch->ch_tun.un_open_count != 0) &&
309 !((un->un_tty)->ldisc->ops->flags & LDISC_FLAG_DEFINED) &&
310 !(L_XCASE(un->un_tty))) {
311 ch->ch_flag |= CH_FAST_WRITE;
312 } else {
313 ch->ch_flag &= ~CH_FAST_WRITE;
314 }
315
316
317
318
319
320
321 if ((ch->ch_flag & CH_FAST_WRITE) &&
322 O_OPOST(un->un_tty) != 0) {
323 int oflag = tty_to_ch_flags(un->un_tty, 'o');
324
325
326 ch->ch_ocook |= oflag & (OF_OLCUC |
327 OF_ONLCR |
328 OF_OCRNL |
329 OF_ONLRET |
330 OF_TABDLY);
331
332
333
334
335
336
337
338 oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
339 uts->c_oflag &= ~oflag;
340
341 } else {
342
343 int oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
344 uts->c_oflag |= oflag;
345 ch->ch_ocook = 0;
346 }
347
348 ch->ch_oflag = ch->ch_ocook;
349
350
351 ch->ch_flag &= ~CH_FAST_READ;
352
353
354
355
356
357 if (C_BAUD(un->un_tty) == B0) {
358 if (!(ch->ch_flag & CH_BAUD0)) {
359
360
361
362 ch->ch_tout = ch->ch_tin;
363 ch->ch_rout = ch->ch_rin;
364
365 ch->ch_break_time = 0;
366
367 ch->ch_send |= RR_TX_FLUSH | RR_RX_FLUSH;
368
369 ch->ch_mout &= ~(DM_DTR | DM_RTS);
370
371 ch->ch_flag |= CH_BAUD0;
372 }
373 } else if (ch->ch_custom_speed) {
374 ch->ch_brate = PORTSERVER_DIVIDEND / ch->ch_custom_speed ;
375
376 if (ch->ch_flag & CH_BAUD0) {
377 ch->ch_mout |= DM_DTR | DM_RTS;
378
379 ch->ch_flag &= ~CH_BAUD0;
380 }
381 } else {
382
383
384
385
386
387
388
389
390
391
392
393 if (!(ch->ch_digi.digi_flags & DIGI_FAST))
394 brate = calc_baud_rate(un);
395 else
396 brate = calc_fastbaud_rate(un, uts);
397
398 if (brate == 0)
399 brate = 9600;
400
401 ch->ch_brate = PORTSERVER_DIVIDEND / brate;
402
403 if (ch->ch_flag & CH_BAUD0) {
404 ch->ch_mout |= DM_DTR | DM_RTS;
405
406 ch->ch_flag &= ~CH_BAUD0;
407 }
408 }
409
410
411
412
413
414 ch->ch_cflag = tty_to_ch_flags(un->un_tty, 'c');
415
416
417
418
419
420 iflag = (int) tty_to_ch_flags(un->un_tty, 'i');
421
422 if (START_CHAR(un->un_tty) == _POSIX_VDISABLE ||
423 STOP_CHAR(un->un_tty) == _POSIX_VDISABLE) {
424 iflag &= ~(IF_IXON | IF_IXANY | IF_IXOFF);
425 }
426
427 ch->ch_iflag = iflag;
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444 if (uts->c_cc[VSTART] != _POSIX_VDISABLE)
445 ch->ch_xon = uts->c_cc[VSTART];
446 if (uts->c_cc[VSTOP] != _POSIX_VDISABLE)
447 ch->ch_xoff = uts->c_cc[VSTOP];
448
449 ch->ch_lnext = (uts->c_cc[VLNEXT] == _POSIX_VDISABLE ? 0 :
450 uts->c_cc[VLNEXT]);
451
452
453
454
455
456
457
458
459 if ((uts->c_cc[VSTART] == _POSIX_VDISABLE) ||
460 (uts->c_cc[VSTOP] == _POSIX_VDISABLE))
461 ch->ch_iflag &= ~(IF_IXOFF | IF_IXON);
462
463
464
465
466
467 xflag = 0;
468
469 if (ch->ch_digi.digi_flags & DIGI_AIXON)
470 xflag = XF_XIXON;
471
472 if ((ch->ch_xxon == _POSIX_VDISABLE) ||
473 (ch->ch_xxoff == _POSIX_VDISABLE))
474 xflag &= ~XF_XIXON;
475
476 ch->ch_xflag = xflag;
477
478
479
480
481
482
483 if (C_CLOCAL(un->un_tty))
484 ch->ch_flag |= CH_CLOCAL;
485 else
486 ch->ch_flag &= ~CH_CLOCAL;
487
488
489
490
491
492 dgrp_carrier(ch);
493
494
495
496
497
498 mflow = 0;
499
500 if (C_CRTSCTS(un->un_tty))
501 mflow |= (DM_RTS | DM_CTS);
502
503 if (ch->ch_digi.digi_flags & RTSPACE)
504 mflow |= DM_RTS;
505
506 if (ch->ch_digi.digi_flags & DTRPACE)
507 mflow |= DM_DTR;
508
509 if (ch->ch_digi.digi_flags & CTSPACE)
510 mflow |= DM_CTS;
511
512 if (ch->ch_digi.digi_flags & DSRPACE)
513 mflow |= DM_DSR;
514
515 if (ch->ch_digi.digi_flags & DCDPACE)
516 mflow |= DM_CD;
517
518 if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
519 mflow |= DM_RTS_TOGGLE;
520
521 ch->ch_mflow = mflow;
522
523
524
525
526
527 ch->ch_flag |= CH_PARAM;
528 (ch->ch_nd)->nd_tx_work = 1;
529
530 if (waitqueue_active(&ch->ch_flag_wait))
531 wake_up_interruptible(&ch->ch_flag_wait);
532}
533
534
535
536
537
538static void wake_up_drp_sleep_timer(unsigned long ptr)
539{
540 struct ch_struct *ch = (struct ch_struct *) ptr;
541 if (ch)
542 wake_up(&ch->ch_sleep);
543}
544
545
546
547
548
549
550static void drp_my_sleep(struct ch_struct *ch)
551{
552 struct timer_list drp_wakeup_timer;
553 DECLARE_WAITQUEUE(wait, current);
554
555
556
557
558
559 add_wait_queue(&ch->ch_sleep, &wait);
560 current->state = TASK_UNINTERRUPTIBLE;
561
562
563
564
565
566
567 init_timer(&drp_wakeup_timer);
568 drp_wakeup_timer.function = wake_up_drp_sleep_timer;
569 drp_wakeup_timer.data = (unsigned long) ch;
570 drp_wakeup_timer.expires = jiffies + (1 * HZ);
571 add_timer(&drp_wakeup_timer);
572
573 schedule();
574
575 del_timer(&drp_wakeup_timer);
576
577 remove_wait_queue(&ch->ch_sleep, &wait);
578}
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594static int dgrp_tty_open(struct tty_struct *tty, struct file *file)
595{
596 int retval = 0;
597 struct nd_struct *nd;
598 struct ch_struct *ch;
599 struct un_struct *un;
600 int port;
601 int delay_error;
602 int otype;
603 int unf;
604 int wait_carrier;
605 int category;
606 int counts_were_incremented = 0;
607 ulong lock_flags;
608 DECLARE_WAITQUEUE(wait, current);
609
610
611
612
613
614 nd = nd_struct_get(MAJOR(tty_devnum(tty)));
615 port = PORT_NUM(MINOR(tty_devnum(tty)));
616 category = OPEN_CATEGORY(MINOR(tty_devnum(tty)));
617
618 if (!nd)
619 return -ENODEV;
620
621 if (port >= CHAN_MAX)
622 return -ENODEV;
623
624
625
626
627
628 ch = nd->nd_chan + port;
629
630 un = IS_PRINT(MINOR(tty_devnum(tty))) ? &ch->ch_pun : &ch->ch_tun;
631 un->un_tty = tty;
632 tty->driver_data = un;
633
634
635
636
637
638 if (tty_hung_up_p(file)) {
639 retval = ((un->un_flag & UN_HUP_NOTIFY) ?
640 -EAGAIN : -ERESTARTSYS);
641 goto done;
642 }
643
644
645
646
647
648 retval = wait_event_interruptible(un->un_close_wait,
649 ((un->un_flag & UN_CLOSING) == 0));
650
651 if (retval)
652 goto done;
653
654
655
656
657
658 retval = wait_event_interruptible(ch->ch_flag_wait,
659 ((ch->ch_flag & CH_PORT_GONE) == 0));
660
661 if (retval)
662 goto done;
663
664
665
666
667
668
669 if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
670 if (un->un_flag & UN_NORMAL_ACTIVE) {
671 retval = -EBUSY;
672 goto done;
673 } else {
674 un->un_flag |= UN_CALLOUT_ACTIVE;
675 }
676 }
677
678
679
680
681
682 spin_lock_irqsave(&nd->nd_lock, lock_flags);
683
684 nd->nd_tx_work = 1;
685
686 for (;;) {
687 wait_carrier = 0;
688
689
690
691
692
693
694
695
696 if (test_bit(TTY_IO_ERROR, &tty->flags)) {
697
698 if (un->un_flag & UN_CALLOUT_ACTIVE)
699 retval = -EBUSY;
700 else
701 un->un_flag |= UN_NORMAL_ACTIVE;
702 goto unlock;
703 }
704
705 if (file->f_flags & O_NONBLOCK) {
706
707
708
709
710
711
712 otype = OTYPE_IMMEDIATE;
713 delay_error = -EAGAIN;
714
715 } else if (!OPEN_WAIT_AVAIL(category) ||
716 (file->f_flags & O_NDELAY) != 0) {
717 otype = OTYPE_IMMEDIATE;
718 delay_error = -EBUSY;
719
720 } else if (!OPEN_WAIT_CARRIER(category) ||
721 ((ch->ch_digi.digi_flags & DIGI_FORCEDCD) != 0) ||
722 C_CLOCAL(tty)) {
723 otype = OTYPE_PERSISTENT;
724 delay_error = 0;
725
726 } else {
727 otype = OTYPE_INCOMING;
728 delay_error = 0;
729 }
730
731
732
733
734
735 if (port >= nd->nd_chan_count) {
736 if (otype == OTYPE_IMMEDIATE) {
737 retval = (nd->nd_state == NS_READY) ?
738 -ENXIO : -EAGAIN;
739 goto unlock;
740 }
741 }
742
743
744
745
746
747 else if (ch->ch_open_count == 0) {
748
749
750
751
752
753 if (ch->ch_open_error != 0 && otype == ch->ch_otype) {
754 retval = (ch->ch_open_error <= 2) ?
755 delay_error : -ENXIO ;
756 goto unlock;
757 }
758
759
760
761
762
763
764 if (nd->nd_state != NS_READY &&
765 otype == OTYPE_IMMEDIATE) {
766 retval = -EAGAIN;
767 goto unlock;
768 }
769
770
771
772
773
774
775 if (ch->ch_state == CS_READY && ch->ch_otype == otype)
776 break;
777 }
778
779
780
781
782
783
784 else if ((ch->ch_category == category) ||
785 IS_PRINT(MINOR(tty_devnum(tty)))) {
786
787
788
789
790 unf = ch->ch_tun.un_flag | ch->ch_pun.un_flag;
791
792 if ((file->f_flags & O_EXCL) || (unf & UN_EXCL)) {
793 retval = -EBUSY;
794 goto unlock;
795 }
796
797
798
799
800
801
802
803
804 if (ch->ch_flag & CH_HANGUP) {
805 retval = -ENXIO;
806 goto unlock;
807 }
808
809
810
811
812
813
814 if (ch->ch_state == CS_READY &&
815 (otype != OTYPE_INCOMING ||
816 ch->ch_flag & CH_VIRT_CD))
817 break;
818
819 wait_carrier = 1;
820 }
821
822
823
824
825
826 else {
827 if (otype == OTYPE_IMMEDIATE) {
828 retval = delay_error;
829 goto unlock;
830 }
831 }
832
833
834
835
836
837
838 ch->ch_wait_count[otype]++;
839
840 if (wait_carrier)
841 ch->ch_wait_carrier++;
842
843
844
845
846
847
848 add_wait_queue(&ch->ch_flag_wait, &wait);
849 current->state = TASK_INTERRUPTIBLE;
850
851 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
852
853
854
855
856
857 schedule();
858 remove_wait_queue(&ch->ch_flag_wait, &wait);
859
860 spin_lock_irqsave(&nd->nd_lock, lock_flags);
861
862 current->state = TASK_RUNNING;
863
864 ch->ch_wait_count[otype]--;
865
866 if (wait_carrier)
867 ch->ch_wait_carrier--;
868
869 nd->nd_tx_work = 1;
870
871 if (signal_pending(current)) {
872 retval = -EINTR;
873 goto unlock;
874 }
875 }
876
877
878
879
880 counts_were_incremented = 1;
881 un->un_open_count++;
882 ch->ch_open_count++;
883
884
885
886
887
888 if (ch->ch_open_count == 1) {
889 ch->ch_flag = 0;
890 ch->ch_inwait = 0;
891 ch->ch_category = category;
892 ch->ch_pscan_state = 0;
893
894
895
896
897 ch->ch_send = RR_TX_START | RR_RX_START;
898
899 if (C_CLOCAL(tty) ||
900 ch->ch_s_mlast & DM_CD ||
901 ch->ch_digi.digi_flags & DIGI_FORCEDCD)
902 ch->ch_flag |= CH_VIRT_CD;
903 else if (OPEN_FORCES_CARRIER(category))
904 ch->ch_flag |= CH_VIRT_CD;
905
906 }
907
908
909
910
911
912 if (un->un_open_count == 1) {
913
914
915
916
917
918 un->un_flag &= ~UN_DIGI_MASK;
919
920 if (file->f_flags & O_EXCL)
921 un->un_flag |= UN_EXCL;
922
923
924
925
926
927
928
929
930
931 drp_param(ch);
932
933 }
934
935 un->un_flag |= UN_INITIALIZED;
936
937 retval = 0;
938
939unlock:
940
941 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
942
943done:
944
945
946
947 if (!counts_were_incremented) {
948 un->un_open_count++;
949 ch->ch_open_count++;
950 }
951
952 if (retval)
953 dev_err(tty->dev, "tty open bad return (%i)\n", retval);
954
955 return retval;
956}
957
958
959
960
961
962
963
964static void dgrp_tty_close(struct tty_struct *tty, struct file *file)
965{
966 struct ch_struct *ch;
967 struct un_struct *un;
968 struct nd_struct *nd;
969 int tpos;
970 int port;
971 int err = 0;
972 int s = 0;
973 ulong waketime;
974 ulong lock_flags;
975 int sent_printer_offstr = 0;
976
977 port = PORT_NUM(MINOR(tty_devnum(tty)));
978
979 un = tty->driver_data;
980
981 if (!un)
982 return;
983
984 ch = un->un_ch;
985
986 if (!ch)
987 return;
988
989 nd = ch->ch_nd;
990
991 if (!nd)
992 return;
993
994 spin_lock_irqsave(&nd->nd_lock, lock_flags);
995
996
997
998 if (un->un_open_count != 1)
999 goto unlock;
1000
1001
1002
1003
1004 un->un_flag |= UN_CLOSING;
1005
1006
1007
1008
1009 tty->closing = 1;
1010
1011
1012
1013
1014
1015
1016 if (ch->ch_open_count == 1) {
1017
1018
1019
1020
1021 if (IS_PRINT(MINOR(tty_devnum(tty))) &&
1022 (((ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK) <
1023 ch->ch_digi.digi_offlen))
1024 ch->ch_tin = ch->ch_tout;
1025
1026
1027
1028
1029
1030
1031
1032
1033 if ((ch->ch_flag & CH_PRON) != 0) {
1034 drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
1035 ch->ch_digi.digi_offlen);
1036 ch->ch_flag &= ~CH_PRON;
1037 sent_printer_offstr = 1;
1038 }
1039 }
1040
1041
1042
1043
1044
1045
1046 tpos = ch->ch_s_tpos;
1047
1048 waketime = jiffies + 15 * HZ;
1049
1050 for (;;) {
1051
1052
1053
1054
1055
1056 if (port >= nd->nd_chan_count) {
1057 err = 1;
1058 break;
1059 }
1060
1061 if (signal_pending(current)) {
1062 err = 1;
1063 break;
1064 }
1065
1066
1067
1068
1069
1070
1071 if (ch->ch_state == CS_IDLE)
1072 break;
1073
1074 nd->nd_tx_work = 1;
1075
1076
1077
1078
1079
1080
1081
1082 if ((un->un_tty)->ops->chars_in_buffer ?
1083 ((un->un_tty)->ops->chars_in_buffer)(un->un_tty) == 0 : 1) {
1084
1085
1086
1087
1088
1089
1090 if (ch->ch_open_count != un->un_open_count)
1091 break;
1092
1093
1094
1095
1096
1097
1098 if (ch->ch_tin == ch->ch_tout &&
1099 ch->ch_s_tin == ch->ch_s_tpos &&
1100 (ch->ch_send & RR_TX_BREAK) == 0) {
1101 break;
1102 }
1103 }
1104
1105
1106
1107
1108
1109
1110
1111 if ((file->f_flags & (O_NDELAY | O_NONBLOCK)) ||
1112 ((long)(jiffies - waketime) >= 0 &&
1113 (ch->ch_digi.digi_flags & DIGI_PRINTER) == 0)) {
1114
1115
1116
1117
1118
1119
1120 if (!sent_printer_offstr)
1121 dgrp_tty_flush_buffer(tty);
1122
1123 tty_ldisc_flush(tty);
1124 break;
1125 }
1126
1127
1128
1129
1130
1131 ch->ch_flag |= CH_DRAIN;
1132
1133 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
1134
1135 schedule_timeout_interruptible(1);
1136 s = signal_pending(current);
1137
1138 spin_lock_irqsave(&nd->nd_lock, lock_flags);
1139
1140 if (s) {
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159 if (sent_printer_offstr) {
1160 spin_unlock_irqrestore(&nd->nd_lock,
1161 lock_flags);
1162 drp_my_sleep(ch);
1163 spin_lock_irqsave(&nd->nd_lock, lock_flags);
1164 } else {
1165 err = 1;
1166 break;
1167 }
1168 }
1169
1170
1171
1172
1173
1174 if (ch->ch_s_tpos != tpos) {
1175 tpos = ch->ch_s_tpos;
1176
1177
1178 waketime = jiffies + 15 * HZ;
1179 }
1180 }
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 if (!IS_PRINT(MINOR(tty_devnum(tty))))
1199 ch->ch_rout = ch->ch_rin;
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214 if ((err != 1) && (ch->ch_state != CS_IDLE)) {
1215 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
1216 s = wait_event_interruptible(ch->ch_flag_wait,
1217 ((ch->ch_flag & (CH_WAITING_SYNC | CH_PARAM)) == 0));
1218 spin_lock_irqsave(&nd->nd_lock, lock_flags);
1219 }
1220
1221
1222
1223
1224
1225 if (ch->ch_open_count == 1) {
1226 ch->ch_flag = 0;
1227 ch->ch_category = 0;
1228 ch->ch_send = 0;
1229 ch->ch_expect = 0;
1230 ch->ch_tout = ch->ch_tin;
1231
1232
1233 if (ch->ch_state == CS_READY)
1234 ch->ch_state = CS_SEND_CLOSE;
1235 }
1236
1237
1238
1239
1240 if (ch->ch_state != CS_IDLE) {
1241 ch->ch_flag |= CH_PARAM;
1242 wake_up_interruptible(&ch->ch_flag_wait);
1243 }
1244
1245 nd->nd_tx_work = 1;
1246 nd->nd_tx_ready = 1;
1247
1248unlock:
1249 tty->closing = 0;
1250
1251 if (ch->ch_open_count <= 0)
1252 dev_info(tty->dev,
1253 "%s - unexpected value for ch->ch_open_count: %i\n",
1254 __func__, ch->ch_open_count);
1255 else
1256 ch->ch_open_count--;
1257
1258 if (un->un_open_count <= 0)
1259 dev_info(tty->dev,
1260 "%s - unexpected value for un->un_open_count: %i\n",
1261 __func__, un->un_open_count);
1262 else
1263 un->un_open_count--;
1264
1265 un->un_flag &= ~(UN_NORMAL_ACTIVE | UN_CALLOUT_ACTIVE | UN_CLOSING);
1266 if (waitqueue_active(&un->un_close_wait))
1267 wake_up_interruptible(&un->un_close_wait);
1268
1269 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
1270
1271 return;
1272
1273}
1274
1275static void drp_wmove(struct ch_struct *ch, int from_user, void *buf, int count)
1276{
1277 int n;
1278 int ret = 0;
1279
1280 ch->ch_nd->nd_tx_work = 1;
1281
1282 n = TBUF_MAX - ch->ch_tin;
1283
1284 if (count >= n) {
1285 if (from_user)
1286 ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
1287 (void __user *) buf, n);
1288 else
1289 memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);
1290
1291 buf = (char *) buf + n;
1292 count -= n;
1293 ch->ch_tin = 0;
1294 }
1295
1296 if (from_user)
1297 ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
1298 (void __user *) buf, count);
1299 else
1300 memcpy(ch->ch_tbuf + ch->ch_tin, buf, count);
1301
1302 ch->ch_tin += count;
1303}
1304
1305
1306static int dgrp_calculate_txprint_bounds(struct ch_struct *ch, int space,
1307 int *un_flag)
1308{
1309 clock_t tt;
1310 clock_t mt;
1311 unsigned short tmax = 0;
1312
1313
1314
1315
1316
1317
1318 if (ch->ch_tun.un_open_count != 0 &&
1319 ch->ch_tun.un_tty->ops->chars_in_buffer &&
1320 ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) {
1321 *un_flag = UN_PWAIT;
1322 return 0;
1323 }
1324
1325
1326
1327
1328
1329
1330 space -= ch->ch_digi.digi_offlen;
1331
1332 if (space <= 0) {
1333 *un_flag = UN_EMPTY;
1334 return 0;
1335 }
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358 tt = jiffies - ch->ch_cpstime;
1359
1360
1361
1362
1363
1364
1365 mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375 if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
1376 tmax = ch->ch_digi.digi_bufsize;
1377 ch->ch_cpstime = jiffies - mt;
1378 } else {
1379 tmax = ch->ch_digi.digi_maxcps * tt / HZ;
1380 }
1381
1382
1383
1384
1385
1386
1387
1388 if (tmax < space) {
1389 *un_flag = UN_TIME;
1390 space = tmax;
1391 }
1392
1393
1394
1395
1396
1397
1398
1399 tmax = (ch->ch_digi.digi_maxchar -
1400 ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
1401 ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));
1402
1403
1404
1405
1406
1407
1408
1409
1410 if (space > tmax) {
1411 *un_flag = UN_EMPTY;
1412 space = tmax;
1413 }
1414
1415 if (space <= 0)
1416 *un_flag |= UN_EMPTY;
1417
1418 return space;
1419}
1420
1421
1422static int dgrp_tty_write(struct tty_struct *tty,
1423 const unsigned char *buf,
1424 int count)
1425{
1426 struct nd_struct *nd;
1427 struct un_struct *un;
1428 struct ch_struct *ch;
1429 int space;
1430 int n;
1431 int t;
1432 int sendcount;
1433 int un_flag;
1434 ulong lock_flags;
1435
1436 if (tty == NULL)
1437 return 0;
1438
1439 un = tty->driver_data;
1440 if (!un)
1441 return 0;
1442
1443 ch = un->un_ch;
1444 if (!ch)
1445 return 0;
1446
1447 nd = ch->ch_nd;
1448 if (!nd)
1449 return 0;
1450
1451
1452
1453
1454 if (ch->ch_state != CS_READY)
1455 return 0;
1456
1457 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
1458
1459
1460
1461
1462 if ((un->un_flag & (UN_EMPTY | UN_LOW | UN_TIME | UN_PWAIT)) != 0) {
1463 count = 0;
1464 goto out;
1465 }
1466
1467
1468
1469
1470
1471 if (nd->nd_dpa_debug && nd->nd_dpa_flag & DPA_WAIT_SPACE &&
1472 nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))) {
1473 count = 0;
1474 goto out;
1475 }
1476
1477
1478
1479
1480
1481 sendcount = 0;
1482
1483 space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
1484
1485
1486
1487
1488
1489 un_flag = UN_LOW;
1490
1491 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1492 clock_t tt;
1493 clock_t mt;
1494 unsigned short tmax = 0;
1495
1496
1497
1498
1499
1500
1501 if (ch->ch_tun.un_open_count != 0 &&
1502 ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) {
1503 un->un_flag |= UN_PWAIT;
1504 count = 0;
1505 goto out;
1506 }
1507
1508
1509
1510
1511
1512
1513 space -= ch->ch_digi.digi_offlen;
1514
1515
1516
1517
1518
1519 if ((ch->ch_flag & CH_PRON) == 0) {
1520 space -= ch->ch_digi.digi_onlen;
1521
1522 if (space < 0) {
1523 un->un_flag |= UN_EMPTY;
1524 (ch->ch_nd)->nd_tx_work = 1;
1525 count = 0;
1526 goto out;
1527 }
1528
1529 drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
1530 ch->ch_digi.digi_onlen);
1531
1532 ch->ch_flag |= CH_PRON;
1533 }
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556 tt = jiffies - ch->ch_cpstime;
1557
1558
1559
1560
1561
1562
1563 mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573 if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
1574 tmax = ch->ch_digi.digi_bufsize;
1575 ch->ch_cpstime = jiffies - mt;
1576 } else {
1577 tmax = ch->ch_digi.digi_maxcps * tt / HZ;
1578 }
1579
1580
1581
1582
1583
1584
1585
1586 if (tmax < space) {
1587 space = tmax;
1588 un_flag = UN_TIME;
1589 }
1590
1591
1592
1593
1594
1595
1596
1597 tmax = (ch->ch_digi.digi_maxchar -
1598 ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
1599 ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));
1600
1601
1602
1603
1604
1605
1606
1607
1608 if (space > tmax) {
1609 space = tmax;
1610 un_flag = UN_EMPTY;
1611 }
1612
1613 }
1614
1615
1616
1617 else {
1618
1619
1620
1621
1622
1623 if ((ch->ch_flag & CH_PRON) != 0) {
1624
1625 space -= ch->ch_digi.digi_offlen;
1626
1627 drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
1628 ch->ch_digi.digi_offlen);
1629
1630 ch->ch_flag &= ~CH_PRON;
1631 }
1632 }
1633
1634
1635
1636
1637
1638
1639
1640
1641 if (space <= 0) {
1642
1643
1644
1645 un->un_flag |= UN_EMPTY;
1646 (ch->ch_nd)->nd_tx_work = 1;
1647 count = 0;
1648 goto out;
1649 }
1650
1651 count = min(count, space);
1652
1653 if (count > 0) {
1654
1655 un->un_tbusy++;
1656
1657
1658
1659
1660
1661
1662 t = TBUF_MAX - ch->ch_tin;
1663 n = count;
1664
1665 if (n >= t) {
1666 memcpy(ch->ch_tbuf + ch->ch_tin, buf, t);
1667 if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty))))
1668 dgrp_dpa_data(nd, 0, (char *) buf, t);
1669 buf += t;
1670 n -= t;
1671 ch->ch_tin = 0;
1672 sendcount += n;
1673 }
1674
1675 memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);
1676 if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty))))
1677 dgrp_dpa_data(nd, 0, (char *) buf, n);
1678 buf += n;
1679 ch->ch_tin += n;
1680 sendcount += n;
1681
1682 un->un_tbusy--;
1683 (ch->ch_nd)->nd_tx_work = 1;
1684 if (ch->ch_edelay != DGRP_RTIME) {
1685 (ch->ch_nd)->nd_tx_ready = 1;
1686 wake_up_interruptible(&nd->nd_tx_waitq);
1687 }
1688 }
1689
1690 ch->ch_txcount += count;
1691
1692 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1693
1694
1695
1696
1697
1698
1699 if (sendcount > 0) {
1700 int cc = HZ * sendcount + ch->ch_cpsrem;
1701
1702 ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
1703 ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps;
1704 }
1705
1706
1707
1708
1709
1710
1711
1712 if ((un_flag & UN_TIME) != 0) {
1713 ch->ch_waketime = (ch->ch_cpstime +
1714 (ch->ch_digi.digi_maxchar * HZ /
1715 ch->ch_digi.digi_maxcps));
1716 }
1717 }
1718
1719
1720
1721
1722
1723
1724 if ((ch->ch_pun.un_flag & UN_PWAIT) != 0)
1725 (ch->ch_nd)->nd_tx_work = 1;
1726
1727out:
1728 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
1729
1730 return count;
1731}
1732
1733
1734
1735
1736
1737
1738
1739
1740static int dgrp_tty_put_char(struct tty_struct *tty, unsigned char new_char)
1741{
1742 struct un_struct *un;
1743 struct ch_struct *ch;
1744 ulong lock_flags;
1745 int space;
1746 int retval = 0;
1747
1748 if (tty == NULL)
1749 return 0;
1750
1751 un = tty->driver_data;
1752 if (!un)
1753 return 0;
1754
1755 ch = un->un_ch;
1756 if (!ch)
1757 return 0;
1758
1759 if (ch->ch_state != CS_READY)
1760 return 0;
1761
1762 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
1763
1764
1765
1766
1767
1768
1769
1770
1771 space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
1772
1773 un->un_tbusy++;
1774
1775
1776
1777
1778 if (IS_PRINT(MINOR(tty_devnum(tty))) && (ch->ch_flag & CH_PRON) == 0) {
1779 if (space < ch->ch_digi.digi_onlen) {
1780 un->un_tbusy--;
1781 goto out;
1782 }
1783 space -= ch->ch_digi.digi_onlen;
1784 drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
1785 ch->ch_digi.digi_onlen);
1786 ch->ch_flag |= CH_PRON;
1787 }
1788
1789
1790
1791
1792
1793 if (!IS_PRINT(MINOR(tty_devnum(tty))) &&
1794 ((ch->ch_flag & CH_PRON) != 0)) {
1795 if (space < ch->ch_digi.digi_offlen) {
1796 un->un_tbusy--;
1797 goto out;
1798 }
1799
1800 space -= ch->ch_digi.digi_offlen;
1801 drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
1802 ch->ch_digi.digi_offlen);
1803 ch->ch_flag &= ~CH_PRON;
1804 }
1805
1806 if (!space) {
1807 un->un_tbusy--;
1808 goto out;
1809 }
1810
1811
1812
1813
1814
1815 ch->ch_tbuf[ch->ch_tin] = new_char;
1816 ch->ch_tin = (1 + ch->ch_tin) & TBUF_MASK;
1817
1818 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1819
1820
1821
1822
1823
1824
1825 int cc = HZ + ch->ch_cpsrem;
1826
1827 ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
1828 ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps;
1829
1830
1831
1832
1833
1834
1835
1836 ch->ch_waketime = (ch->ch_cpstime +
1837 (ch->ch_digi.digi_maxchar * HZ /
1838 ch->ch_digi.digi_maxcps));
1839 }
1840
1841
1842 un->un_tbusy--;
1843 (ch->ch_nd)->nd_tx_work = 1;
1844
1845 retval = 1;
1846out:
1847 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
1848 return retval;
1849}
1850
1851
1852
1853
1854
1855
1856
1857
1858static void dgrp_tty_flush_buffer(struct tty_struct *tty)
1859{
1860 struct un_struct *un;
1861 struct ch_struct *ch;
1862
1863 if (!tty)
1864 return;
1865 un = tty->driver_data;
1866 if (!un)
1867 return;
1868
1869 ch = un->un_ch;
1870 if (!ch)
1871 return;
1872
1873 ch->ch_tout = ch->ch_tin;
1874
1875
1876
1877
1878 ch->ch_send |= RR_TX_FLUSH;
1879 (ch->ch_nd)->nd_tx_ready = 1;
1880 (ch->ch_nd)->nd_tx_work = 1;
1881 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
1882
1883 if (waitqueue_active(&tty->write_wait))
1884 wake_up_interruptible(&tty->write_wait);
1885
1886 tty_wakeup(tty);
1887
1888}
1889
1890
1891
1892
1893
1894static int dgrp_tty_write_room(struct tty_struct *tty)
1895{
1896 struct un_struct *un;
1897 struct ch_struct *ch;
1898 int count;
1899
1900 if (!tty)
1901 return 0;
1902
1903 un = tty->driver_data;
1904 if (!un)
1905 return 0;
1906
1907 ch = un->un_ch;
1908 if (!ch)
1909 return 0;
1910
1911 count = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
1912
1913
1914
1915
1916
1917
1918 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1919 int un_flag = 0;
1920 count = dgrp_calculate_txprint_bounds(ch, count, &un_flag);
1921 if (count <= 0)
1922 count = 0;
1923
1924 ch->ch_pun.un_flag |= un_flag;
1925 (ch->ch_nd)->nd_tx_work = 1;
1926 }
1927
1928 return count;
1929}
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941static int dgrp_tty_chars_in_buffer(struct tty_struct *tty)
1942{
1943 struct un_struct *un;
1944 struct ch_struct *ch;
1945 int count;
1946 int count1;
1947
1948 if (!tty)
1949 return 0;
1950
1951 un = tty->driver_data;
1952 if (!un)
1953 return 0;
1954
1955 ch = un->un_ch;
1956 if (!ch)
1957 return 0;
1958
1959 count1 = count = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1960 count += (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff;
1961
1962
1963
1964
1965
1966 count += un->un_tbusy;
1967
1968 return count;
1969}
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988static tcflag_t ch_to_tty_flags(ushort ch_flag, char flagtype)
1989{
1990 tcflag_t retval = 0;
1991
1992 switch (flagtype) {
1993 case 'i':
1994 retval = ((ch_flag & IF_IGNBRK) ? IGNBRK : 0)
1995 | ((ch_flag & IF_BRKINT) ? BRKINT : 0)
1996 | ((ch_flag & IF_IGNPAR) ? IGNPAR : 0)
1997 | ((ch_flag & IF_PARMRK) ? PARMRK : 0)
1998 | ((ch_flag & IF_INPCK) ? INPCK : 0)
1999 | ((ch_flag & IF_ISTRIP) ? ISTRIP : 0)
2000 | ((ch_flag & IF_IXON) ? IXON : 0)
2001 | ((ch_flag & IF_IXANY) ? IXANY : 0)
2002 | ((ch_flag & IF_IXOFF) ? IXOFF : 0);
2003 break;
2004
2005 case 'o':
2006 retval = ((ch_flag & OF_OLCUC) ? OLCUC : 0)
2007 | ((ch_flag & OF_ONLCR) ? ONLCR : 0)
2008 | ((ch_flag & OF_OCRNL) ? OCRNL : 0)
2009 | ((ch_flag & OF_ONOCR) ? ONOCR : 0)
2010 | ((ch_flag & OF_ONLRET) ? ONLRET : 0)
2011
2012 | ((ch_flag & OF_TABDLY) ? TABDLY : 0);
2013 break;
2014
2015 case 'c':
2016 retval = ((ch_flag & CF_CSTOPB) ? CSTOPB : 0)
2017 | ((ch_flag & CF_CREAD) ? CREAD : 0)
2018 | ((ch_flag & CF_PARENB) ? PARENB : 0)
2019 | ((ch_flag & CF_PARODD) ? PARODD : 0)
2020 | ((ch_flag & CF_HUPCL) ? HUPCL : 0);
2021
2022 switch (ch_flag & CF_CSIZE) {
2023 case CF_CS5:
2024 retval |= CS5;
2025 break;
2026 case CF_CS6:
2027 retval |= CS6;
2028 break;
2029 case CF_CS7:
2030 retval |= CS7;
2031 break;
2032 case CF_CS8:
2033 retval |= CS8;
2034 break;
2035 default:
2036 retval |= CS8;
2037 break;
2038 }
2039 break;
2040 case 'x':
2041 break;
2042 case 'l':
2043 break;
2044 default:
2045 return 0;
2046 }
2047
2048 return retval;
2049}
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061static ushort tty_to_ch_flags(struct tty_struct *tty, char flagtype)
2062{
2063 ushort retval = 0;
2064 tcflag_t tflag = 0;
2065
2066 switch (flagtype) {
2067 case 'i':
2068 tflag = tty->termios.c_iflag;
2069 retval = (I_IGNBRK(tty) ? IF_IGNBRK : 0)
2070 | (I_BRKINT(tty) ? IF_BRKINT : 0)
2071 | (I_IGNPAR(tty) ? IF_IGNPAR : 0)
2072 | (I_PARMRK(tty) ? IF_PARMRK : 0)
2073 | (I_INPCK(tty) ? IF_INPCK : 0)
2074 | (I_ISTRIP(tty) ? IF_ISTRIP : 0)
2075 | (I_IXON(tty) ? IF_IXON : 0)
2076 | (I_IXANY(tty) ? IF_IXANY : 0)
2077 | (I_IXOFF(tty) ? IF_IXOFF : 0);
2078 break;
2079 case 'o':
2080 tflag = tty->termios.c_oflag;
2081
2082
2083
2084
2085
2086
2087 if (!O_OPOST(tty))
2088 retval = 0;
2089 else
2090 retval = (O_OLCUC(tty) ? OF_OLCUC : 0)
2091 | (O_ONLCR(tty) ? OF_ONLCR : 0)
2092 | (O_OCRNL(tty) ? OF_OCRNL : 0)
2093 | (O_ONOCR(tty) ? OF_ONOCR : 0)
2094 | (O_ONLRET(tty) ? OF_ONLRET : 0)
2095
2096 | (O_TABDLY(tty) ? OF_TABDLY : 0);
2097 break;
2098 case 'c':
2099 tflag = tty->termios.c_cflag;
2100 retval = (C_CSTOPB(tty) ? CF_CSTOPB : 0)
2101 | (C_CREAD(tty) ? CF_CREAD : 0)
2102 | (C_PARENB(tty) ? CF_PARENB : 0)
2103 | (C_PARODD(tty) ? CF_PARODD : 0)
2104 | (C_HUPCL(tty) ? CF_HUPCL : 0);
2105 switch (C_CSIZE(tty)) {
2106 case CS8:
2107 retval |= CF_CS8;
2108 break;
2109 case CS7:
2110 retval |= CF_CS7;
2111 break;
2112 case CS6:
2113 retval |= CF_CS6;
2114 break;
2115 case CS5:
2116 retval |= CF_CS5;
2117 break;
2118 default:
2119 retval |= CF_CS8;
2120 break;
2121 }
2122 break;
2123 case 'x':
2124 break;
2125 case 'l':
2126 break;
2127 default:
2128 return 0;
2129 }
2130
2131 return retval;
2132}
2133
2134
2135static int dgrp_tty_send_break(struct tty_struct *tty, int msec)
2136{
2137 struct un_struct *un;
2138 struct ch_struct *ch;
2139 int ret = -EIO;
2140
2141 if (!tty)
2142 return ret;
2143
2144 un = tty->driver_data;
2145 if (!un)
2146 return ret;
2147
2148 ch = un->un_ch;
2149 if (!ch)
2150 return ret;
2151
2152 dgrp_send_break(ch, msec);
2153 return 0;
2154}
2155
2156
2157
2158
2159
2160
2161
2162static int dgrp_send_break(struct ch_struct *ch, int msec)
2163{
2164 ulong x;
2165
2166 wait_event_interruptible(ch->ch_flag_wait,
2167 ((ch->ch_flag & CH_TX_BREAK) == 0));
2168 ch->ch_break_time += max(msec, 250);
2169 ch->ch_send |= RR_TX_BREAK;
2170 ch->ch_flag |= CH_TX_BREAK;
2171 (ch->ch_nd)->nd_tx_work = 1;
2172
2173 x = (msec * HZ) / 1000;
2174 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2175
2176 return 0;
2177}
2178
2179
2180
2181
2182
2183static int dgrp_tty_tiocmget(struct tty_struct *tty)
2184{
2185 unsigned int mlast;
2186 struct un_struct *un = tty->driver_data;
2187 struct ch_struct *ch;
2188
2189 if (!un)
2190 return -ENODEV;
2191
2192 ch = un->un_ch;
2193 if (!ch)
2194 return -ENODEV;
2195
2196 mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
2197 (ch->ch_mout & (DM_RTS | DM_DTR)));
2198
2199
2200 mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0)
2201 | ((mlast & DM_DTR) ? TIOCM_DTR : 0)
2202 | ((mlast & DM_CD) ? TIOCM_CAR : 0)
2203 | ((mlast & DM_RI) ? TIOCM_RNG : 0)
2204 | ((mlast & DM_DSR) ? TIOCM_DSR : 0)
2205 | ((mlast & DM_CTS) ? TIOCM_CTS : 0);
2206
2207 return mlast;
2208}
2209
2210
2211
2212
2213
2214static int dgrp_tty_tiocmset(struct tty_struct *tty,
2215 unsigned int set, unsigned int clear)
2216{
2217 ulong lock_flags;
2218 struct un_struct *un = tty->driver_data;
2219 struct ch_struct *ch;
2220
2221 if (!un)
2222 return -ENODEV;
2223
2224 ch = un->un_ch;
2225 if (!ch)
2226 return -ENODEV;
2227
2228 if (set & TIOCM_RTS)
2229 ch->ch_mout |= DM_RTS;
2230
2231 if (set & TIOCM_DTR)
2232 ch->ch_mout |= DM_DTR;
2233
2234 if (clear & TIOCM_RTS)
2235 ch->ch_mout &= ~(DM_RTS);
2236
2237 if (clear & TIOCM_DTR)
2238 ch->ch_mout &= ~(DM_DTR);
2239
2240 spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);
2241 ch->ch_flag |= CH_PARAM;
2242 (ch->ch_nd)->nd_tx_work = 1;
2243 wake_up_interruptible(&ch->ch_flag_wait);
2244
2245 spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);
2246
2247 return 0;
2248}
2249
2250
2251
2252
2253
2254
2255static int get_modem_info(struct ch_struct *ch, unsigned int *value)
2256{
2257 unsigned int mlast;
2258
2259 mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
2260 (ch->ch_mout & (DM_RTS | DM_DTR)));
2261
2262
2263 mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0)
2264 | ((mlast & DM_DTR) ? TIOCM_DTR : 0)
2265 | ((mlast & DM_CD) ? TIOCM_CAR : 0)
2266 | ((mlast & DM_RI) ? TIOCM_RNG : 0)
2267 | ((mlast & DM_DSR) ? TIOCM_DSR : 0)
2268 | ((mlast & DM_CTS) ? TIOCM_CTS : 0);
2269 return put_user(mlast, (unsigned int __user *) value);
2270}
2271
2272
2273
2274
2275static int set_modem_info(struct ch_struct *ch, unsigned int command,
2276 unsigned int *value)
2277{
2278 int error;
2279 unsigned int arg;
2280 int mval = 0;
2281 ulong lock_flags;
2282
2283 error = access_ok(VERIFY_READ, (void __user *) value, sizeof(int));
2284 if (error == 0)
2285 return -EFAULT;
2286
2287 if (get_user(arg, (unsigned int __user *) value))
2288 return -EFAULT;
2289 mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0)
2290 | ((arg & TIOCM_DTR) ? DM_DTR : 0);
2291
2292 switch (command) {
2293 case TIOCMBIS:
2294 ch->ch_mout |= mval;
2295 break;
2296 case TIOCMBIC:
2297 ch->ch_mout &= ~mval;
2298 break;
2299 case TIOCMSET:
2300 ch->ch_mout = mval;
2301 break;
2302 default:
2303 return -EINVAL;
2304 }
2305
2306 spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);
2307
2308 ch->ch_flag |= CH_PARAM;
2309 (ch->ch_nd)->nd_tx_work = 1;
2310 wake_up_interruptible(&ch->ch_flag_wait);
2311
2312 spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);
2313
2314 return 0;
2315}
2316
2317
2318
2319
2320
2321static void dgrp_set_custom_speed(struct ch_struct *ch, int newrate)
2322{
2323 int testdiv;
2324 int testrate_high;
2325 int testrate_low;
2326
2327 int deltahigh, deltalow;
2328
2329 if (newrate < 0)
2330 newrate = 0;
2331
2332
2333
2334
2335
2336
2337 if (newrate && newrate < ((PORTSERVER_DIVIDEND / 0xFFFF) + 1))
2338 newrate = ((PORTSERVER_DIVIDEND / 0xFFFF) + 1);
2339 if (newrate && newrate > PORTSERVER_DIVIDEND)
2340 newrate = PORTSERVER_DIVIDEND;
2341
2342 while (newrate > 0) {
2343 testdiv = PORTSERVER_DIVIDEND / newrate;
2344
2345
2346
2347
2348
2349
2350
2351
2352 testrate_high = PORTSERVER_DIVIDEND / testdiv;
2353 testrate_low = PORTSERVER_DIVIDEND / (testdiv + 1);
2354
2355
2356
2357
2358
2359 if (testrate_high == newrate)
2360 break;
2361
2362
2363
2364
2365
2366 deltahigh = testrate_high - newrate;
2367 deltalow = newrate - testrate_low;
2368
2369 if (deltahigh < deltalow)
2370 newrate = testrate_high;
2371 else
2372 newrate = testrate_low;
2373
2374 break;
2375 }
2376
2377 ch->ch_custom_speed = newrate;
2378
2379 drp_param(ch);
2380
2381 return;
2382}
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392static int dgrp_tty_digiseta(struct tty_struct *tty,
2393 struct digi_struct *new_info)
2394{
2395 struct un_struct *un = tty->driver_data;
2396 struct ch_struct *ch;
2397
2398 if (!un)
2399 return -ENODEV;
2400
2401 ch = un->un_ch;
2402 if (!ch)
2403 return -ENODEV;
2404
2405 if (copy_from_user(&ch->ch_digi, (void __user *) new_info,
2406 sizeof(struct digi_struct)))
2407 return -EFAULT;
2408
2409 if ((ch->ch_digi.digi_flags & RTSPACE) ||
2410 (ch->ch_digi.digi_flags & CTSPACE))
2411 tty->termios.c_cflag |= CRTSCTS;
2412 else
2413 tty->termios.c_cflag &= ~CRTSCTS;
2414
2415 if (ch->ch_digi.digi_maxcps < 1)
2416 ch->ch_digi.digi_maxcps = 1;
2417
2418 if (ch->ch_digi.digi_maxcps > 10000)
2419 ch->ch_digi.digi_maxcps = 10000;
2420
2421 if (ch->ch_digi.digi_bufsize < 10)
2422 ch->ch_digi.digi_bufsize = 10;
2423
2424 if (ch->ch_digi.digi_maxchar < 1)
2425 ch->ch_digi.digi_maxchar = 1;
2426
2427 if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
2428 ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
2429
2430 if (ch->ch_digi.digi_onlen > DIGI_PLEN)
2431 ch->ch_digi.digi_onlen = DIGI_PLEN;
2432
2433 if (ch->ch_digi.digi_offlen > DIGI_PLEN)
2434 ch->ch_digi.digi_offlen = DIGI_PLEN;
2435
2436
2437 drp_param(ch);
2438
2439 return 0;
2440}
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452static int dgrp_tty_digigetedelay(struct tty_struct *tty, int *retinfo)
2453{
2454 struct un_struct *un;
2455 struct ch_struct *ch;
2456 int tmp;
2457
2458 if (!retinfo)
2459 return -EFAULT;
2460
2461 if (!tty || tty->magic != TTY_MAGIC)
2462 return -EFAULT;
2463
2464 un = tty->driver_data;
2465
2466 if (!un)
2467 return -ENODEV;
2468
2469 ch = un->un_ch;
2470 if (!ch)
2471 return -ENODEV;
2472
2473 tmp = ch->ch_edelay;
2474
2475 if (copy_to_user((void __user *) retinfo, &tmp, sizeof(*retinfo)))
2476 return -EFAULT;
2477
2478 return 0;
2479}
2480
2481
2482
2483
2484
2485
2486
2487
2488static int dgrp_tty_digisetedelay(struct tty_struct *tty, int *new_info)
2489{
2490 struct un_struct *un;
2491 struct ch_struct *ch;
2492 int new_digi;
2493
2494 if (!tty || tty->magic != TTY_MAGIC)
2495 return -EFAULT;
2496
2497 un = tty->driver_data;
2498
2499 if (!un)
2500 return -ENODEV;
2501
2502 ch = un->un_ch;
2503 if (!ch)
2504 return -ENODEV;
2505
2506 if (copy_from_user(&new_digi, (void __user *)new_info, sizeof(int)))
2507 return -EFAULT;
2508
2509 ch->ch_edelay = new_digi;
2510
2511
2512 drp_param(ch);
2513
2514 return 0;
2515}
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
2528 unsigned long arg)
2529{
2530 struct un_struct *un;
2531 struct ch_struct *ch;
2532 int rc;
2533 struct digiflow_struct dflow;
2534
2535 if (!tty)
2536 return -ENODEV;
2537
2538 un = tty->driver_data;
2539 if (!un)
2540 return -ENODEV;
2541
2542 ch = un->un_ch;
2543 if (!ch)
2544 return -ENODEV;
2545
2546 switch (cmd) {
2547
2548
2549
2550
2551
2552 case TCSBRK:
2553
2554
2555
2556
2557
2558
2559
2560
2561 rc = tty_check_change(tty);
2562 if (rc)
2563 return rc;
2564 tty_wait_until_sent(tty, 0);
2565
2566 if (!arg)
2567 rc = dgrp_send_break(ch, 250);
2568
2569 if (dgrp_tty_chars_in_buffer(tty) != 0)
2570 return -EINTR;
2571
2572 return 0;
2573
2574 case TCSBRKP:
2575
2576
2577
2578
2579
2580
2581 rc = tty_check_change(tty);
2582 if (rc)
2583 return rc;
2584 tty_wait_until_sent(tty, 0);
2585
2586 rc = dgrp_send_break(ch, arg ? arg*250 : 250);
2587
2588 if (dgrp_tty_chars_in_buffer(tty) != 0)
2589 return -EINTR;
2590 return 0;
2591
2592 case TIOCSBRK:
2593 rc = tty_check_change(tty);
2594 if (rc)
2595 return rc;
2596 tty_wait_until_sent(tty, 0);
2597
2598
2599
2600
2601
2602
2603 rc = dgrp_send_break(ch, 250);
2604
2605 if (dgrp_tty_chars_in_buffer(tty) != 0)
2606 return -EINTR;
2607 return 0;
2608
2609 case TIOCCBRK:
2610
2611
2612
2613
2614
2615
2616 return 0;
2617
2618 case TIOCMGET:
2619 rc = access_ok(VERIFY_WRITE, (void __user *) arg,
2620 sizeof(unsigned int));
2621 if (rc == 0)
2622 return -EFAULT;
2623 return get_modem_info(ch, (unsigned int *) arg);
2624
2625 case TIOCMBIS:
2626 case TIOCMBIC:
2627 case TIOCMSET:
2628 return set_modem_info(ch, cmd, (unsigned int *) arg);
2629
2630
2631
2632
2633
2634 case TCFLSH:
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644 rc = tty_check_change(tty);
2645 if (rc)
2646 return rc;
2647
2648 switch (arg) {
2649 case TCIFLUSH:
2650 case TCIOFLUSH:
2651
2652 if (!IS_PRINT(MINOR(tty_devnum(tty)))) {
2653 ch->ch_rout = ch->ch_rin;
2654 ch->ch_send |= RR_RX_FLUSH;
2655 (ch->ch_nd)->nd_tx_work = 1;
2656 (ch->ch_nd)->nd_tx_ready = 1;
2657 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2658 }
2659 if (arg == TCIFLUSH)
2660 break;
2661
2662 case TCOFLUSH:
2663
2664
2665
2666
2667 break;
2668
2669 default:
2670
2671 return -EINVAL;
2672 }
2673
2674 return -ENOIOCTLCMD;
2675
2676#ifdef TIOCGETP
2677 case TIOCGETP:
2678#endif
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698 case TCGETS:
2699 case TCGETA:
2700 return -ENOIOCTLCMD;
2701
2702 case TCSETAW:
2703 case TCSETAF:
2704 case TCSETSF:
2705 case TCSETSW:
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722 if (!IS_PRINT(MINOR(tty_devnum(tty))) ||
2723 !ch->ch_tun.un_open_count) {
2724 rc = tty_check_change(tty);
2725 if (rc)
2726 return rc;
2727 }
2728
2729
2730 tty_wait_until_sent(tty, 0);
2731
2732 if ((cmd == TCSETSF) || (cmd == TCSETAF)) {
2733
2734
2735 ch->ch_send |= RR_RX_FLUSH;
2736 (ch->ch_nd)->nd_tx_ready = 1;
2737 (ch->ch_nd)->nd_tx_work = 1;
2738 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2739
2740 ch->ch_rout = ch->ch_rin;
2741 }
2742
2743
2744 return -ENOIOCTLCMD;
2745
2746 case TCXONC:
2747
2748
2749
2750
2751
2752
2753
2754 rc = tty_check_change(tty);
2755 if (rc)
2756 return rc;
2757
2758 switch (arg) {
2759 case TCOON:
2760 dgrp_tty_start(tty);
2761 return 0;
2762 case TCOOFF:
2763 dgrp_tty_stop(tty);
2764 return 0;
2765 case TCION:
2766 dgrp_tty_input_start(tty);
2767 return 0;
2768 case TCIOFF:
2769 dgrp_tty_input_stop(tty);
2770 return 0;
2771 default:
2772 return -EINVAL;
2773 }
2774
2775 case DIGI_GETA:
2776
2777 if (copy_to_user((struct digi_struct __user *) arg,
2778 &ch->ch_digi, sizeof(struct digi_struct)))
2779 return -EFAULT;
2780 break;
2781
2782 case DIGI_SETAW:
2783 case DIGI_SETAF:
2784
2785 tty_wait_until_sent(tty, 0);
2786
2787 if (cmd == DIGI_SETAF) {
2788
2789
2790 ch->ch_send |= RR_RX_FLUSH;
2791 (ch->ch_nd)->nd_tx_ready = 1;
2792 (ch->ch_nd)->nd_tx_work = 1;
2793 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2794
2795 ch->ch_rout = ch->ch_rin;
2796 }
2797
2798
2799
2800 case DIGI_SETA:
2801 return dgrp_tty_digiseta(tty, (struct digi_struct *) arg);
2802
2803 case DIGI_SEDELAY:
2804 return dgrp_tty_digisetedelay(tty, (int *) arg);
2805
2806 case DIGI_GEDELAY:
2807 return dgrp_tty_digigetedelay(tty, (int *) arg);
2808
2809 case DIGI_GETFLOW:
2810 case DIGI_GETAFLOW:
2811 if (cmd == (DIGI_GETFLOW)) {
2812 dflow.startc = tty->termios.c_cc[VSTART];
2813 dflow.stopc = tty->termios.c_cc[VSTOP];
2814 } else {
2815 dflow.startc = ch->ch_xxon;
2816 dflow.stopc = ch->ch_xxoff;
2817 }
2818
2819 if (copy_to_user((char __user *)arg, &dflow, sizeof(dflow)))
2820 return -EFAULT;
2821 break;
2822
2823 case DIGI_SETFLOW:
2824 case DIGI_SETAFLOW:
2825
2826 if (copy_from_user(&dflow, (char __user *)arg, sizeof(dflow)))
2827 return -EFAULT;
2828
2829 if (cmd == (DIGI_SETFLOW)) {
2830 tty->termios.c_cc[VSTART] = dflow.startc;
2831 tty->termios.c_cc[VSTOP] = dflow.stopc;
2832 } else {
2833 ch->ch_xxon = dflow.startc;
2834 ch->ch_xxoff = dflow.stopc;
2835 }
2836 break;
2837
2838 case DIGI_GETCUSTOMBAUD:
2839 if (put_user(ch->ch_custom_speed, (unsigned int __user *) arg))
2840 return -EFAULT;
2841 break;
2842
2843 case DIGI_SETCUSTOMBAUD:
2844 {
2845 int new_rate;
2846
2847 if (get_user(new_rate, (unsigned int __user *) arg))
2848 return -EFAULT;
2849 dgrp_set_custom_speed(ch, new_rate);
2850
2851 break;
2852 }
2853
2854 default:
2855 return -ENOIOCTLCMD;
2856 }
2857
2858 return 0;
2859}
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870static void dgrp_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
2871{
2872 struct ktermios *ts;
2873 struct ch_struct *ch;
2874 struct un_struct *un;
2875
2876
2877 if (!tty)
2878 return;
2879
2880 un = tty->driver_data;
2881 if (!un)
2882 return;
2883
2884 ts = &tty->termios;
2885
2886 ch = un->un_ch;
2887 if (!ch)
2888 return;
2889
2890 drp_param(ch);
2891
2892
2893 if (!(old->c_cflag & CLOCAL) && C_CLOCAL(tty))
2894 wake_up_interruptible(&un->un_open_wait);
2895}
2896
2897
2898
2899
2900
2901
2902
2903static void dgrp_tty_throttle(struct tty_struct *tty)
2904{
2905 struct ch_struct *ch;
2906
2907 if (!tty)
2908 return;
2909
2910 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2911 if (!ch)
2912 return;
2913
2914 ch->ch_flag |= CH_RXSTOP;
2915}
2916
2917
2918static void dgrp_tty_unthrottle(struct tty_struct *tty)
2919{
2920 struct ch_struct *ch;
2921
2922 if (!tty)
2923 return;
2924
2925 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2926 if (!ch)
2927 return;
2928
2929 ch->ch_flag &= ~CH_RXSTOP;
2930}
2931
2932
2933
2934
2935static void dgrp_tty_stop(struct tty_struct *tty)
2936{
2937 struct ch_struct *ch;
2938
2939 if (!tty)
2940 return;
2941
2942 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2943 if (!ch)
2944 return;
2945
2946 ch->ch_send |= RR_TX_STOP;
2947 ch->ch_send &= ~RR_TX_START;
2948
2949
2950 (ch->ch_nd)->nd_tx_ready = 1;
2951 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
2952 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2953}
2954
2955
2956
2957
2958static void dgrp_tty_start(struct tty_struct *tty)
2959{
2960 struct ch_struct *ch;
2961
2962 if (!tty)
2963 return;
2964
2965 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2966 if (!ch)
2967 return;
2968
2969
2970
2971 ch->ch_send |= RR_TX_START;
2972 ch->ch_send &= ~RR_TX_STOP;
2973
2974
2975 (ch->ch_nd)->nd_tx_ready = 1;
2976 (ch->ch_nd)->nd_tx_work = 1;
2977 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
2978 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2979
2980}
2981
2982
2983
2984
2985static void dgrp_tty_input_stop(struct tty_struct *tty)
2986{
2987 struct ch_struct *ch;
2988
2989 if (!tty)
2990 return;
2991
2992 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2993 if (!ch)
2994 return;
2995
2996 ch->ch_send |= RR_RX_STOP;
2997 ch->ch_send &= ~RR_RX_START;
2998 (ch->ch_nd)->nd_tx_ready = 1;
2999 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
3000 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
3001
3002}
3003
3004
3005static void dgrp_tty_send_xchar(struct tty_struct *tty, char c)
3006{
3007 struct un_struct *un;
3008 struct ch_struct *ch;
3009
3010 if (!tty)
3011 return;
3012
3013 un = tty->driver_data;
3014 if (!un)
3015 return;
3016
3017 ch = un->un_ch;
3018 if (!ch)
3019 return;
3020 if (c == STOP_CHAR(tty))
3021 ch->ch_send |= RR_RX_STOP;
3022 else if (c == START_CHAR(tty))
3023 ch->ch_send |= RR_RX_START;
3024
3025 ch->ch_nd->nd_tx_ready = 1;
3026 ch->ch_nd->nd_tx_work = 1;
3027
3028 return;
3029}
3030
3031
3032static void dgrp_tty_input_start(struct tty_struct *tty)
3033{
3034 struct ch_struct *ch;
3035
3036 if (!tty)
3037 return;
3038
3039 ch = ((struct un_struct *) tty->driver_data)->un_ch;
3040 if (!ch)
3041 return;
3042
3043 ch->ch_send |= RR_RX_START;
3044 ch->ch_send &= ~RR_RX_STOP;
3045 (ch->ch_nd)->nd_tx_ready = 1;
3046 (ch->ch_nd)->nd_tx_work = 1;
3047 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
3048 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
3049
3050}
3051
3052
3053
3054
3055
3056
3057
3058
3059static void dgrp_tty_hangup(struct tty_struct *tty)
3060{
3061 struct ch_struct *ch;
3062 struct nd_struct *nd;
3063 struct un_struct *un;
3064
3065 if (!tty)
3066 return;
3067
3068 un = tty->driver_data;
3069 if (!un)
3070 return;
3071
3072 ch = un->un_ch;
3073 if (!ch)
3074 return;
3075
3076 nd = ch->ch_nd;
3077
3078 if (C_HUPCL(tty)) {
3079
3080 ch->ch_mout &= ~DM_DTR;
3081
3082
3083 ch->ch_nd->nd_tx_ready = 1;
3084 ch->ch_nd->nd_tx_work = 1;
3085 if (waitqueue_active(&ch->ch_flag_wait))
3086 wake_up_interruptible(&ch->ch_flag_wait);
3087 }
3088
3089}
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103void
3104dgrp_tty_uninit(struct nd_struct *nd)
3105{
3106 unsigned int i;
3107 char id[3];
3108
3109 ID_TO_CHAR(nd->nd_ID, id);
3110
3111 if (nd->nd_ttdriver_flags & SERIAL_TTDRV_REG) {
3112 tty_unregister_driver(nd->nd_serial_ttdriver);
3113
3114 kfree(nd->nd_serial_ttdriver->ttys);
3115 nd->nd_serial_ttdriver->ttys = NULL;
3116
3117 put_tty_driver(nd->nd_serial_ttdriver);
3118 nd->nd_ttdriver_flags &= ~SERIAL_TTDRV_REG;
3119 }
3120
3121 if (nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG) {
3122 tty_unregister_driver(nd->nd_callout_ttdriver);
3123
3124 kfree(nd->nd_callout_ttdriver->ttys);
3125 nd->nd_callout_ttdriver->ttys = NULL;
3126
3127 put_tty_driver(nd->nd_callout_ttdriver);
3128 nd->nd_ttdriver_flags &= ~CALLOUT_TTDRV_REG;
3129 }
3130
3131 if (nd->nd_ttdriver_flags & XPRINT_TTDRV_REG) {
3132 tty_unregister_driver(nd->nd_xprint_ttdriver);
3133
3134 kfree(nd->nd_xprint_ttdriver->ttys);
3135 nd->nd_xprint_ttdriver->ttys = NULL;
3136
3137 put_tty_driver(nd->nd_xprint_ttdriver);
3138 nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG;
3139 }
3140 for (i = 0; i < CHAN_MAX; i++)
3141 tty_port_destroy(&nd->nd_chan[i].port);
3142}
3143
3144
3145
3146
3147
3148
3149int
3150dgrp_tty_init(struct nd_struct *nd)
3151{
3152 char id[3];
3153 int rc;
3154 int i;
3155
3156 ID_TO_CHAR(nd->nd_ID, id);
3157
3158
3159
3160
3161
3162 nd->nd_serial_ttdriver = alloc_tty_driver(CHAN_MAX);
3163 if (!nd->nd_serial_ttdriver)
3164 return -ENOMEM;
3165
3166 sprintf(nd->nd_serial_name, "tty_dgrp_%s_", id);
3167
3168 nd->nd_serial_ttdriver->owner = THIS_MODULE;
3169 nd->nd_serial_ttdriver->name = nd->nd_serial_name;
3170 nd->nd_serial_ttdriver->name_base = 0;
3171 nd->nd_serial_ttdriver->major = 0;
3172 nd->nd_serial_ttdriver->minor_start = 0;
3173 nd->nd_serial_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
3174 nd->nd_serial_ttdriver->subtype = SERIAL_TYPE_NORMAL;
3175 nd->nd_serial_ttdriver->init_termios = DefaultTermios;
3176 nd->nd_serial_ttdriver->driver_name = "dgrp";
3177 nd->nd_serial_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
3178 TTY_DRIVER_DYNAMIC_DEV |
3179 TTY_DRIVER_HARDWARE_BREAK);
3180
3181
3182 nd->nd_serial_ttdriver->ttys =
3183 kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
3184 if (!nd->nd_serial_ttdriver->ttys)
3185 return -ENOMEM;
3186
3187 tty_set_operations(nd->nd_serial_ttdriver, &dgrp_tty_ops);
3188
3189 if (!(nd->nd_ttdriver_flags & SERIAL_TTDRV_REG)) {
3190
3191
3192
3193 rc = tty_register_driver(nd->nd_serial_ttdriver);
3194 if (rc < 0) {
3195
3196
3197
3198
3199
3200
3201
3202
3203 if (rc == -EBUSY) {
3204 int i;
3205 int max_majors = 1U << (32 - MINORBITS);
3206 for (i = 256; i < max_majors; i++) {
3207 nd->nd_serial_ttdriver->major = i;
3208 rc = tty_register_driver(nd->nd_serial_ttdriver);
3209 if (rc >= 0)
3210 break;
3211 }
3212
3213
3214 if (i == max_majors)
3215 return rc;
3216
3217 } else {
3218 return rc;
3219 }
3220 }
3221 nd->nd_ttdriver_flags |= SERIAL_TTDRV_REG;
3222 }
3223
3224 nd->nd_callout_ttdriver = alloc_tty_driver(CHAN_MAX);
3225 if (!nd->nd_callout_ttdriver)
3226 return -ENOMEM;
3227
3228 sprintf(nd->nd_callout_name, "cu_dgrp_%s_", id);
3229
3230 nd->nd_callout_ttdriver->owner = THIS_MODULE;
3231 nd->nd_callout_ttdriver->name = nd->nd_callout_name;
3232 nd->nd_callout_ttdriver->name_base = 0;
3233 nd->nd_callout_ttdriver->major = nd->nd_serial_ttdriver->major;
3234 nd->nd_callout_ttdriver->minor_start = 0x40;
3235 nd->nd_callout_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
3236 nd->nd_callout_ttdriver->subtype = SERIAL_TYPE_CALLOUT;
3237 nd->nd_callout_ttdriver->init_termios = DefaultTermios;
3238 nd->nd_callout_ttdriver->driver_name = "dgrp";
3239 nd->nd_callout_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
3240 TTY_DRIVER_DYNAMIC_DEV |
3241 TTY_DRIVER_HARDWARE_BREAK);
3242
3243
3244 nd->nd_callout_ttdriver->ttys =
3245 kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
3246 if (!nd->nd_callout_ttdriver->ttys)
3247 return -ENOMEM;
3248
3249 tty_set_operations(nd->nd_callout_ttdriver, &dgrp_tty_ops);
3250
3251 if (dgrp_register_cudevices) {
3252 if (!(nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG)) {
3253
3254
3255
3256 rc = tty_register_driver(nd->nd_callout_ttdriver);
3257 if (rc < 0)
3258 return rc;
3259 nd->nd_ttdriver_flags |= CALLOUT_TTDRV_REG;
3260 }
3261 }
3262
3263
3264 nd->nd_xprint_ttdriver = alloc_tty_driver(CHAN_MAX);
3265 if (!nd->nd_xprint_ttdriver)
3266 return -ENOMEM;
3267
3268 sprintf(nd->nd_xprint_name, "pr_dgrp_%s_", id);
3269
3270 nd->nd_xprint_ttdriver->owner = THIS_MODULE;
3271 nd->nd_xprint_ttdriver->name = nd->nd_xprint_name;
3272 nd->nd_xprint_ttdriver->name_base = 0;
3273 nd->nd_xprint_ttdriver->major = nd->nd_serial_ttdriver->major;
3274 nd->nd_xprint_ttdriver->minor_start = 0x80;
3275 nd->nd_xprint_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
3276 nd->nd_xprint_ttdriver->subtype = SERIAL_TYPE_XPRINT;
3277 nd->nd_xprint_ttdriver->init_termios = DefaultTermios;
3278 nd->nd_xprint_ttdriver->driver_name = "dgrp";
3279 nd->nd_xprint_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
3280 TTY_DRIVER_DYNAMIC_DEV |
3281 TTY_DRIVER_HARDWARE_BREAK);
3282
3283
3284 nd->nd_xprint_ttdriver->ttys =
3285 kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
3286 if (!nd->nd_xprint_ttdriver->ttys)
3287 return -ENOMEM;
3288
3289 tty_set_operations(nd->nd_xprint_ttdriver, &dgrp_tty_ops);
3290
3291 if (dgrp_register_prdevices) {
3292 if (!(nd->nd_ttdriver_flags & XPRINT_TTDRV_REG)) {
3293
3294
3295
3296 rc = tty_register_driver(nd->nd_xprint_ttdriver);
3297 if (rc < 0)
3298 return rc;
3299 nd->nd_ttdriver_flags |= XPRINT_TTDRV_REG;
3300 }
3301 }
3302
3303 for (i = 0; i < CHAN_MAX; i++) {
3304 struct ch_struct *ch = nd->nd_chan + i;
3305
3306 ch->ch_nd = nd;
3307 ch->ch_digi = digi_init;
3308 ch->ch_edelay = 100;
3309 ch->ch_custom_speed = 0;
3310 ch->ch_portnum = i;
3311 ch->ch_tun.un_ch = ch;
3312 ch->ch_pun.un_ch = ch;
3313 ch->ch_tun.un_type = SERIAL_TYPE_NORMAL;
3314 ch->ch_pun.un_type = SERIAL_TYPE_XPRINT;
3315
3316 init_waitqueue_head(&(ch->ch_flag_wait));
3317 init_waitqueue_head(&(ch->ch_sleep));
3318
3319 init_waitqueue_head(&(ch->ch_tun.un_open_wait));
3320 init_waitqueue_head(&(ch->ch_tun.un_close_wait));
3321
3322 init_waitqueue_head(&(ch->ch_pun.un_open_wait));
3323 init_waitqueue_head(&(ch->ch_pun.un_close_wait));
3324 tty_port_init(&ch->port);
3325 }
3326 return 0;
3327}
3328