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#include <linux/module.h>
37#include <linux/proc_fs.h>
38#include <linux/types.h>
39#include <linux/string.h>
40#include <linux/tty.h>
41#include <linux/tty_flip.h>
42#include <linux/spinlock.h>
43#include <linux/poll.h>
44#include <linux/sched.h>
45#include <linux/ratelimit.h>
46#include <asm/unaligned.h>
47
48#define MYFLIPLEN TBUF_MAX
49
50#include "dgrp_common.h"
51
52#define TTY_FLIPBUF_SIZE 512
53#define DEVICE_NAME_SIZE 50
54
55
56
57
58static void parity_scan(struct ch_struct *ch, unsigned char *cbuf,
59 unsigned char *fbuf, int *len);
60
61
62
63
64static int dgrp_net_open(struct inode *, struct file *);
65static int dgrp_net_release(struct inode *, struct file *);
66static ssize_t dgrp_net_read(struct file *, char __user *, size_t, loff_t *);
67static ssize_t dgrp_net_write(struct file *, const char __user *, size_t,
68 loff_t *);
69static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
70 unsigned long arg);
71static unsigned int dgrp_net_select(struct file *file,
72 struct poll_table_struct *table);
73
74static const struct file_operations net_ops = {
75 .owner = THIS_MODULE,
76 .read = dgrp_net_read,
77 .write = dgrp_net_write,
78 .poll = dgrp_net_select,
79 .unlocked_ioctl = dgrp_net_ioctl,
80 .open = dgrp_net_open,
81 .release = dgrp_net_release,
82};
83
84static struct inode_operations net_inode_ops = {
85 .permission = dgrp_inode_permission
86};
87
88void dgrp_register_net_hook(struct proc_dir_entry *de)
89{
90 struct nd_struct *node = de->data;
91
92 de->proc_iops = &net_inode_ops;
93 de->proc_fops = &net_ops;
94 node->nd_net_de = de;
95 sema_init(&node->nd_net_semaphore, 1);
96 node->nd_state = NS_CLOSED;
97 dgrp_create_node_class_sysfs_files(node);
98}
99
100
101
102
103
104
105
106static void dgrp_dump(u8 *mem, int len)
107{
108 int i;
109
110 pr_debug("dgrp dump length = %d, data = ", len);
111 for (i = 0; i < len; ++i)
112 pr_debug("%.2x ", mem[i]);
113 pr_debug("\n");
114}
115
116
117
118
119
120
121
122static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf,
123 int flipbuf_size)
124{
125 int t;
126 int n;
127
128 if (flipbuf_size <= 0)
129 return;
130
131 t = RBUF_MAX - ch->ch_rout;
132 n = flipbuf_size;
133
134 if (n >= t) {
135 memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, t);
136 flipbuf += t;
137 n -= t;
138 ch->ch_rout = 0;
139 }
140
141 memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, n);
142 flipbuf += n;
143 ch->ch_rout += n;
144}
145
146
147
148
149
150
151
152
153
154
155
156
157static void dgrp_input(struct ch_struct *ch)
158{
159 struct nd_struct *nd;
160 struct tty_struct *tty;
161 int remain;
162 int data_len;
163 int len;
164 int flip_len;
165 int tty_count;
166 ulong lock_flags;
167 struct tty_ldisc *ld;
168 u8 *myflipbuf;
169 u8 *myflipflagbuf;
170
171 if (!ch)
172 return;
173
174 nd = ch->ch_nd;
175
176 if (!nd)
177 return;
178
179 spin_lock_irqsave(&nd->nd_lock, lock_flags);
180
181 myflipbuf = nd->nd_inputbuf;
182 myflipflagbuf = nd->nd_inputflagbuf;
183
184 if (!ch->ch_open_count) {
185 ch->ch_rout = ch->ch_rin;
186 goto out;
187 }
188
189 if (ch->ch_tun.un_flag & UN_CLOSING) {
190 ch->ch_rout = ch->ch_rin;
191 goto out;
192 }
193
194 tty = (ch->ch_tun).un_tty;
195
196
197 if (!tty || tty->magic != TTY_MAGIC) {
198 ch->ch_rout = ch->ch_rin;
199 goto out;
200 }
201
202 tty_count = tty->count;
203 if (!tty_count) {
204 ch->ch_rout = ch->ch_rin;
205 goto out;
206 }
207
208 if (tty->closing || test_bit(TTY_CLOSING, &tty->flags)) {
209 ch->ch_rout = ch->ch_rin;
210 goto out;
211 }
212
213 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
214
215
216 if (dgrp_rawreadok && tty->real_raw)
217 flip_len = MYFLIPLEN;
218 else
219 flip_len = TTY_FLIPBUF_SIZE;
220
221
222 data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK;
223 remain = data_len;
224
225
226 len = min(data_len, flip_len);
227
228
229 len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt);
230
231 ld = tty_ldisc_ref(tty);
232
233
234
235
236
237
238 if (!ld) {
239 len = 0;
240 } else if (!ld->ops->receive_buf) {
241 spin_lock_irqsave(&nd->nd_lock, lock_flags);
242 ch->ch_rout = ch->ch_rin;
243 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
244 len = 0;
245 }
246
247
248 if ((nd->nd_dpa_debug) &&
249 (nd->nd_dpa_flag & DPA_WAIT_SPACE) &&
250 (nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))))
251 len = 0;
252
253 if ((len) && !(ch->ch_flag & CH_RXSTOP)) {
254
255 dgrp_read_data_block(ch, myflipbuf, len);
256
257
258
259
260
261 if (!dgrp_rawreadok || !tty->real_raw) {
262 if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
263 parity_scan(ch, myflipbuf, myflipflagbuf, &len);
264 else
265 memset(myflipflagbuf, TTY_NORMAL, len);
266 }
267
268 if ((nd->nd_dpa_debug) &&
269 (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty)))))
270 dgrp_dpa_data(nd, 1, myflipbuf, len);
271
272
273
274
275
276 if (dgrp_rawreadok && tty->real_raw)
277 ld->ops->receive_buf(tty, myflipbuf, NULL, len);
278 else {
279 len = tty_buffer_request_room(tty, len);
280 tty_insert_flip_string_flags(tty, myflipbuf,
281 myflipflagbuf, len);
282
283
284 tty_flip_buffer_push(tty);
285 }
286
287 ch->ch_rxcount += len;
288 }
289
290 if (ld)
291 tty_ldisc_deref(ld);
292
293
294
295
296
297 wake_up_interruptible(&ch->ch_flag_wait);
298 return;
299
300out:
301 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
302}
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326static void parity_scan(struct ch_struct *ch, unsigned char *cbuf,
327 unsigned char *fbuf, int *len)
328{
329 int l = *len;
330 int count = 0;
331 int DOS = ((ch->ch_iflag & IF_DOSMODE) == 0 ? 0 : 1);
332 unsigned char *cout;
333 unsigned char *fout;
334 unsigned char *in;
335 unsigned char c;
336
337 in = cbuf;
338 cout = cbuf;
339 fout = fbuf;
340
341 while (l--) {
342 c = *in;
343 in++;
344
345 switch (ch->ch_pscan_state) {
346 default:
347
348 ch->ch_pscan_state = 0 ;
349
350 case 0:
351
352 if (c == 0xff)
353 ch->ch_pscan_state = 1;
354 else {
355 *cout++ = c;
356 *fout++ = TTY_NORMAL;
357 count += 1;
358 }
359 break;
360
361 case 1:
362
363 if (c == 0xff) {
364
365 *cout++ = c;
366 *fout++ = TTY_NORMAL;
367 count += 1;
368 ch->ch_pscan_state = 0;
369 } else {
370
371 ch->ch_pscan_savechar = c;
372 ch->ch_pscan_state = 2;
373 }
374 break;
375
376 case 2:
377
378 *cout++ = c;
379 if (DOS) {
380 if (ch->ch_pscan_savechar & 0x10)
381 *fout++ = TTY_BREAK;
382 else if (ch->ch_pscan_savechar & 0x08)
383 *fout++ = TTY_FRAME;
384 else
385
386
387
388
389
390 *fout++ = TTY_PARITY;
391 } else {
392
393 if (ch->ch_pscan_savechar & 0xff) {
394
395 pr_info("%s: parity_scan: error unexpected byte\n",
396 __func__);
397 *fout++ = TTY_PARITY;
398 }
399
400 else if (c == 0xff)
401 *fout++ = TTY_PARITY;
402
403 else
404 *fout++ = TTY_BREAK;
405
406 }
407 count += 1;
408 ch->ch_pscan_state = 0;
409 }
410 }
411 *len = count;
412}
413
414
415
416
417
418
419static void dgrp_net_idle(struct nd_struct *nd)
420{
421 struct ch_struct *ch;
422 int i;
423
424 nd->nd_tx_work = 1;
425
426 nd->nd_state = NS_IDLE;
427 nd->nd_flag = 0;
428
429 for (i = nd->nd_seq_out; ; i = (i + 1) & SEQ_MASK) {
430 if (!nd->nd_seq_wait[i]) {
431 nd->nd_seq_wait[i] = 0;
432 wake_up_interruptible(&nd->nd_seq_wque[i]);
433 }
434
435 if (i == nd->nd_seq_in)
436 break;
437 }
438
439 nd->nd_seq_out = nd->nd_seq_in;
440
441 nd->nd_unack = 0;
442 nd->nd_remain = 0;
443
444 nd->nd_tx_module = 0x10;
445 nd->nd_rx_module = 0x00;
446
447 for (i = 0, ch = nd->nd_chan; i < CHAN_MAX; i++, ch++) {
448 ch->ch_state = CS_IDLE;
449
450 ch->ch_otype = 0;
451 ch->ch_otype_waiting = 0;
452 }
453}
454
455
456
457
458
459
460static void increase_channel_count(struct nd_struct *nd, int n)
461{
462 struct ch_struct *ch;
463 struct device *classp;
464 char name[DEVICE_NAME_SIZE];
465 int ret;
466 u8 *buf;
467 int i;
468
469 for (i = nd->nd_chan_count; i < n; ++i) {
470 ch = nd->nd_chan + i;
471
472
473 buf = kmalloc(TBUF_MAX, GFP_KERNEL);
474 if (!buf)
475 return;
476
477 if (ch->ch_tbuf)
478 pr_info_ratelimited("%s - ch_tbuf was not NULL\n",
479 __func__);
480
481 ch->ch_tbuf = buf;
482
483 buf = kmalloc(RBUF_MAX, GFP_KERNEL);
484 if (!buf)
485 return;
486
487 if (ch->ch_rbuf)
488 pr_info("%s - ch_rbuf was not NULL\n",
489 __func__);
490 ch->ch_rbuf = buf;
491
492 classp = tty_port_register_device(&ch->port,
493 nd->nd_serial_ttdriver, i,
494 NULL);
495
496 ch->ch_tun.un_sysfs = classp;
497 snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);
498
499 dgrp_create_tty_sysfs(&ch->ch_tun, classp);
500 ret = sysfs_create_link(&nd->nd_class_dev->kobj,
501 &classp->kobj, name);
502
503
504
505
506 if (dgrp_register_prdevices) {
507 classp = tty_register_device(nd->nd_xprint_ttdriver,
508 i, NULL);
509 ch->ch_pun.un_sysfs = classp;
510 snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);
511
512 dgrp_create_tty_sysfs(&ch->ch_pun, classp);
513 ret = sysfs_create_link(&nd->nd_class_dev->kobj,
514 &classp->kobj, name);
515 }
516
517 nd->nd_chan_count = i + 1;
518 wake_up_interruptible(&ch->ch_flag_wait);
519 }
520}
521
522
523
524
525
526static void decrease_channel_count(struct nd_struct *nd, int n)
527{
528 struct ch_struct *ch;
529 char name[DEVICE_NAME_SIZE];
530 int i;
531
532 for (i = nd->nd_chan_count - 1; i >= n; --i) {
533 ch = nd->nd_chan + i;
534
535
536
537
538 ch->ch_state = CS_IDLE;
539
540 ch->ch_otype = 0;
541 ch->ch_otype_waiting = 0;
542
543
544
545
546
547 if (ch->ch_open_count != 0) {
548 ch->ch_flag |= CH_HANGUP;
549 dgrp_carrier(ch);
550 }
551
552
553
554
555
556
557 if (ch->ch_open_count != 0)
558 ch->ch_flag |= CH_PORT_GONE;
559
560 wake_up_interruptible(&ch->ch_flag_wait);
561
562 nd->nd_chan_count = i;
563
564 kfree(ch->ch_tbuf);
565 ch->ch_tbuf = NULL;
566
567 kfree(ch->ch_rbuf);
568 ch->ch_rbuf = NULL;
569
570 nd->nd_chan_count = i;
571
572 dgrp_remove_tty_sysfs(ch->ch_tun.un_sysfs);
573 snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);
574 sysfs_remove_link(&nd->nd_class_dev->kobj, name);
575 tty_unregister_device(nd->nd_serial_ttdriver, i);
576
577
578
579
580
581
582 if (dgrp_register_prdevices) {
583 dgrp_remove_tty_sysfs(ch->ch_pun.un_sysfs);
584 snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);
585 sysfs_remove_link(&nd->nd_class_dev->kobj, name);
586 tty_unregister_device(nd->nd_xprint_ttdriver, i);
587 }
588 }
589}
590
591
592
593
594
595
596
597
598
599
600
601static void dgrp_chan_count(struct nd_struct *nd, int n)
602{
603 if (n == nd->nd_chan_count)
604 return;
605
606 if (n > nd->nd_chan_count)
607 increase_channel_count(nd, n);
608
609 if (n < nd->nd_chan_count)
610 decrease_channel_count(nd, n);
611}
612
613
614
615
616
617
618
619
620
621
622
623static void dgrp_monitor(struct nd_struct *nd, u8 *buf, int len)
624{
625 int n;
626 int r;
627 int rtn;
628
629
630
631
632 down(&nd->nd_mon_semaphore);
633
634
635
636
637 while ((len > 0) && (nd->nd_mon_buf)) {
638
639
640
641
642
643 n = (nd->nd_mon_out - nd->nd_mon_in - 1) & MON_MASK;
644
645 if (!n) {
646 nd->nd_mon_flag |= MON_WAIT_SPACE;
647
648 up(&nd->nd_mon_semaphore);
649
650
651
652
653 rtn = wait_event_interruptible(nd->nd_mon_wqueue,
654 ((nd->nd_mon_flag & MON_WAIT_SPACE) == 0));
655
656
657
658
659
660
661
662
663 down(&nd->nd_mon_semaphore);
664
665 continue;
666 }
667
668
669
670
671
672 if (n > len)
673 n = len;
674
675 r = MON_MAX - nd->nd_mon_in;
676
677 if (r <= n) {
678 memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, r);
679
680 n -= r;
681
682 nd->nd_mon_in = 0;
683
684 buf += r;
685 len -= r;
686 }
687
688 memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, n);
689
690 nd->nd_mon_in += n;
691
692 buf += n;
693 len -= n;
694
695 if (nd->nd_mon_in >= MON_MAX)
696 pr_info_ratelimited("%s - nd_mon_in (%i) >= MON_MAX\n",
697 __func__, nd->nd_mon_in);
698
699
700
701
702
703 if (nd->nd_mon_flag & MON_WAIT_DATA) {
704 nd->nd_mon_flag &= ~MON_WAIT_DATA;
705 wake_up_interruptible(&nd->nd_mon_wqueue);
706 }
707 }
708
709
710
711
712 up(&nd->nd_mon_semaphore);
713}
714
715
716
717
718
719
720
721
722
723static void dgrp_encode_time(struct nd_struct *nd, u8 *buf)
724{
725 ulong t;
726
727
728
729
730
731 t = jiffies - nd->nd_mon_lbolt;
732 t = 1000 * (t / HZ) + 1000 * (t % HZ) / HZ;
733
734 put_unaligned_be32((uint)(t & 0xffffffff), buf);
735}
736
737
738
739
740
741
742
743
744static void dgrp_monitor_message(struct nd_struct *nd, char *message)
745{
746 u8 header[7];
747 int n;
748
749 header[0] = RPDUMP_MESSAGE;
750
751 dgrp_encode_time(nd, header + 1);
752
753 n = strlen(message);
754
755 put_unaligned_be16(n, header + 5);
756
757 dgrp_monitor(nd, header, sizeof(header));
758 dgrp_monitor(nd, (u8 *) message, n);
759}
760
761
762
763
764
765
766
767static void dgrp_monitor_reset(struct nd_struct *nd)
768{
769 u8 header[5];
770
771 header[0] = RPDUMP_RESET;
772
773 dgrp_encode_time(nd, header + 1);
774
775 dgrp_monitor(nd, header, sizeof(header));
776}
777
778
779
780
781
782
783
784
785static void dgrp_monitor_data(struct nd_struct *nd, u8 type, u8 *buf, int size)
786{
787 u8 header[7];
788
789 header[0] = type;
790
791 dgrp_encode_time(nd, header + 1);
792
793 put_unaligned_be16(size, header + 5);
794
795 dgrp_monitor(nd, header, sizeof(header));
796 dgrp_monitor(nd, buf, size);
797}
798
799static int alloc_nd_buffers(struct nd_struct *nd)
800{
801
802 nd->nd_iobuf = NULL;
803 nd->nd_writebuf = NULL;
804 nd->nd_inputbuf = NULL;
805 nd->nd_inputflagbuf = NULL;
806
807
808
809
810 nd->nd_iobuf = kzalloc(UIO_MAX + 10, GFP_KERNEL);
811 if (!nd->nd_iobuf)
812 goto out_err;
813
814
815
816
817
818 nd->nd_writebuf = kzalloc(WRITEBUFLEN, GFP_KERNEL);
819 if (!nd->nd_writebuf)
820 goto out_err;
821
822
823
824
825
826 nd->nd_inputbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
827 if (!nd->nd_inputbuf)
828 goto out_err;
829
830
831
832
833
834 nd->nd_inputflagbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
835 if (!nd->nd_inputflagbuf)
836 goto out_err;
837
838 return 0;
839
840out_err:
841 kfree(nd->nd_iobuf);
842 kfree(nd->nd_writebuf);
843 kfree(nd->nd_inputbuf);
844 kfree(nd->nd_inputflagbuf);
845 return -ENOMEM;
846}
847
848
849
850
851static int dgrp_net_open(struct inode *inode, struct file *file)
852{
853 struct nd_struct *nd;
854 struct proc_dir_entry *de;
855 ulong lock_flags;
856 int rtn;
857
858 rtn = try_module_get(THIS_MODULE);
859 if (!rtn)
860 return -EAGAIN;
861
862 if (!capable(CAP_SYS_ADMIN)) {
863 rtn = -EPERM;
864 goto done;
865 }
866
867
868
869
870 if (file->private_data) {
871 rtn = -EINVAL;
872 goto done;
873 }
874
875
876
877
878 de = PDE(inode);
879 if (!de) {
880 rtn = -ENXIO;
881 goto done;
882 }
883
884 nd = (struct nd_struct *) de->data;
885 if (!nd) {
886 rtn = -ENXIO;
887 goto done;
888 }
889
890 file->private_data = (void *) nd;
891
892
893
894
895 down(&nd->nd_net_semaphore);
896
897 if (nd->nd_state != NS_CLOSED) {
898 rtn = -EBUSY;
899 goto unlock;
900 }
901
902
903
904
905
906 nd->nd_link.lk_fast_rate = UIO_MAX;
907 nd->nd_link.lk_slow_rate = UIO_MAX;
908
909 nd->nd_link.lk_fast_delay = 1000;
910 nd->nd_link.lk_slow_delay = 1000;
911
912 nd->nd_link.lk_header_size = 46;
913
914
915 rtn = alloc_nd_buffers(nd);
916 if (rtn)
917 goto unlock;
918
919
920
921
922 dgrp_net_idle(nd);
923
924 nd->nd_tx_time = jiffies;
925
926
927
928
929 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
930
931 if (!dgrp_poll_data.node_active_count) {
932 dgrp_poll_data.node_active_count = 2;
933 dgrp_poll_data.timer.expires = jiffies +
934 dgrp_poll_tick * HZ / 1000;
935 add_timer(&dgrp_poll_data.timer);
936 }
937
938 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
939
940 dgrp_monitor_message(nd, "Net Open");
941
942unlock:
943
944
945
946 up(&nd->nd_net_semaphore);
947
948done:
949 if (rtn)
950 module_put(THIS_MODULE);
951
952 return rtn;
953}
954
955
956static int dgrp_net_release(struct inode *inode, struct file *file)
957{
958 struct nd_struct *nd;
959 ulong lock_flags;
960
961 nd = (struct nd_struct *)(file->private_data);
962 if (!nd)
963 goto done;
964
965
966
967
968
969
970
971
972
973
974
975
976
977 down(&nd->nd_net_semaphore);
978
979
980
981
982
983 dgrp_net_idle(nd);
984
985 nd->nd_state = NS_CLOSED;
986 nd->nd_flag = 0;
987
988
989
990
991
992
993
994 if (waitqueue_active(&nd->nd_tx_waitq))
995 pr_info("%s - expected waitqueue_active to be false\n",
996 __func__);
997
998 nd->nd_send = 0;
999
1000 kfree(nd->nd_iobuf);
1001 nd->nd_iobuf = NULL;
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012 kfree(nd->nd_writebuf);
1013 nd->nd_writebuf = NULL;
1014
1015 kfree(nd->nd_inputbuf);
1016 nd->nd_inputbuf = NULL;
1017
1018 kfree(nd->nd_inputflagbuf);
1019 nd->nd_inputflagbuf = NULL;
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 dgrp_chan_count(nd, 0);
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 up(&nd->nd_net_semaphore);
1046
1047
1048
1049
1050
1051 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
1052
1053 if (dgrp_poll_data.node_active_count == 2) {
1054 del_timer(&dgrp_poll_data.timer);
1055 dgrp_poll_data.node_active_count = 0;
1056 }
1057
1058 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
1059
1060done:
1061 down(&nd->nd_net_semaphore);
1062
1063 dgrp_monitor_message(nd, "Net Close");
1064
1065 up(&nd->nd_net_semaphore);
1066
1067 module_put(THIS_MODULE);
1068 file->private_data = NULL;
1069 return 0;
1070}
1071
1072
1073static inline u8 *set_cmd_header(u8 *b, u8 port, u8 cmd)
1074{
1075 *b++ = 0xb0 + (port & 0x0f);
1076 *b++ = cmd;
1077 return b;
1078}
1079
1080
1081
1082
1083
1084
1085
1086
1087static int dgrp_send(struct nd_struct *nd, long tmax)
1088{
1089 struct ch_struct *ch = nd->nd_chan;
1090 u8 *b;
1091 u8 *buf;
1092 u8 *mbuf;
1093 u8 port;
1094 int mod;
1095 long send;
1096 int maxport;
1097 long lastport = -1;
1098 ushort rwin;
1099 long in;
1100 ushort n;
1101 long t;
1102 long ttotal;
1103 long tchan;
1104 long tsend;
1105 ushort tsafe;
1106 long work;
1107 long send_sync;
1108 long wanted_sync_port = -1;
1109 ushort tdata[CHAN_MAX];
1110 long used_buffer;
1111
1112 mbuf = nd->nd_iobuf + UIO_BASE;
1113 buf = b = mbuf;
1114
1115 send_sync = nd->nd_link.lk_slow_rate < UIO_MAX;
1116
1117 ttotal = 0;
1118 tchan = 0;
1119
1120 memset(tdata, 0, sizeof(tdata));
1121
1122
1123
1124
1125
1126
1127 if (nd->nd_send & NR_PASSWORD) {
1128
1129
1130
1131
1132
1133 b[0] = 0xfc;
1134 b[1] = 0x20;
1135 put_unaligned_be16(strlen(nd->password), b + 2);
1136 b += 4;
1137 b += strlen(nd->password);
1138 nd->nd_send &= ~(NR_PASSWORD);
1139 }
1140
1141
1142
1143
1144
1145
1146
1147 for (mod = 0, port = 0; port < nd->nd_chan_count; mod++) {
1148
1149
1150
1151
1152
1153 if (mod != nd->nd_tx_module)
1154 mbuf = ++b;
1155
1156
1157
1158
1159
1160 maxport = port + 16;
1161
1162 if (maxport > nd->nd_chan_count)
1163 maxport = nd->nd_chan_count;
1164
1165 for (; port < maxport; port++, ch++) {
1166
1167
1168
1169
1170 switch (ch->ch_state) {
1171
1172
1173
1174
1175
1176 case CS_IDLE:
1177
1178
1179
1180
1181
1182
1183 if (ch->ch_open_error) {
1184 if (ch->ch_wait_count[ch->ch_otype]) {
1185 work = 1;
1186 break;
1187 }
1188
1189 ch->ch_open_error = 0;
1190 }
1191
1192
1193
1194
1195
1196
1197
1198 if ((ch->ch_flag & CH_HANGUP) != 0)
1199 break;
1200
1201
1202
1203
1204
1205
1206 if ((ch->ch_flag & CH_PORT_GONE) ||
1207 ch->ch_wait_count[OTYPE_IMMEDIATE] != 0) {
1208 b = set_cmd_header(b, port, 10);
1209 *b++ = 0;
1210
1211 ch->ch_state = CS_WAIT_OPEN;
1212 ch->ch_otype = OTYPE_IMMEDIATE;
1213 break;
1214 }
1215
1216
1217
1218
1219
1220
1221
1222 if (ch->ch_otype_waiting == 0) {
1223 if (ch->ch_wait_count[OTYPE_PERSISTENT] != 0) {
1224 b = set_cmd_header(b, port, 10);
1225 *b++ = 1;
1226
1227 ch->ch_state = CS_WAIT_OPEN;
1228 ch->ch_otype = OTYPE_PERSISTENT;
1229 } else if (ch->ch_wait_count[OTYPE_INCOMING] != 0) {
1230 b = set_cmd_header(b, port, 10);
1231 *b++ = 2;
1232
1233 ch->ch_state = CS_WAIT_OPEN;
1234 ch->ch_otype = OTYPE_INCOMING;
1235 }
1236 break;
1237 }
1238
1239
1240
1241
1242
1243
1244
1245 if (ch->ch_wait_count[ch->ch_otype_waiting] == 0) {
1246 b = set_cmd_header(b, port, 10);
1247 *b++ = 4;
1248
1249 ch->ch_state = CS_WAIT_CANCEL;
1250 ch->ch_otype = ch->ch_otype_waiting;
1251 }
1252 break;
1253
1254
1255
1256
1257 case CS_SEND_QUERY:
1258
1259
1260
1261
1262
1263 ch->ch_flag |= CH_PARAM;
1264
1265 ch->ch_flag &= ~CH_RX_FLUSH;
1266
1267 ch->ch_expect = 0;
1268
1269 ch->ch_s_tin = 0;
1270 ch->ch_s_tpos = 0;
1271 ch->ch_s_tsize = 0;
1272 ch->ch_s_treq = 0;
1273 ch->ch_s_elast = 0;
1274
1275 ch->ch_s_rin = 0;
1276 ch->ch_s_rwin = 0;
1277 ch->ch_s_rsize = 0;
1278
1279 ch->ch_s_tmax = 0;
1280 ch->ch_s_ttime = 0;
1281 ch->ch_s_rmax = 0;
1282 ch->ch_s_rtime = 0;
1283 ch->ch_s_rlow = 0;
1284 ch->ch_s_rhigh = 0;
1285
1286 ch->ch_s_brate = 0;
1287 ch->ch_s_iflag = 0;
1288 ch->ch_s_cflag = 0;
1289 ch->ch_s_oflag = 0;
1290 ch->ch_s_xflag = 0;
1291
1292 ch->ch_s_mout = 0;
1293 ch->ch_s_mflow = 0;
1294 ch->ch_s_mctrl = 0;
1295 ch->ch_s_xon = 0;
1296 ch->ch_s_xoff = 0;
1297 ch->ch_s_lnext = 0;
1298 ch->ch_s_xxon = 0;
1299 ch->ch_s_xxoff = 0;
1300
1301
1302 b = set_cmd_header(b, port, 14);
1303
1304
1305 b = set_cmd_header(b, port, 42);
1306 put_unaligned_be16(0x02c0, b);
1307 b += 2;
1308 *b++ = (DM_DTR | DM_RTS | DM_CTS |
1309 DM_DSR | DM_RI | DM_CD);
1310
1311
1312 b = set_cmd_header(b, port, 16);
1313
1314
1315 b = set_cmd_header(b, port, 20);
1316
1317
1318 b = set_cmd_header(b, port, 22);
1319
1320 ch->ch_expect = (RR_SEQUENCE |
1321 RR_STATUS |
1322 RR_BUFFER |
1323 RR_CAPABILITY);
1324
1325 ch->ch_state = CS_WAIT_QUERY;
1326
1327
1328 b = set_cmd_header(b, port, 44);
1329
1330 if (ch->ch_flag & CH_PORT_GONE)
1331 ch->ch_s_mout = ch->ch_mout;
1332 else
1333 ch->ch_s_mout = ch->ch_mout = DM_DTR | DM_RTS;
1334
1335 *b++ = ch->ch_mout;
1336 *b++ = ch->ch_s_mflow = 0;
1337 *b++ = ch->ch_s_mctrl = ch->ch_mctrl = 0;
1338
1339 if (ch->ch_flag & CH_PORT_GONE)
1340 ch->ch_flag &= ~CH_PORT_GONE;
1341
1342 break;
1343
1344
1345
1346
1347
1348 case CS_READY:
1349
1350
1351
1352
1353
1354
1355
1356 if (ch->ch_open_count == 0 &&
1357 ch->ch_wait_count[ch->ch_otype] == 0) {
1358 goto send_close;
1359 }
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370 if (ch->ch_rin != ch->ch_rout) {
1371 if (ch->ch_tun.un_open_count == 0 ||
1372 (ch->ch_tun.un_flag & UN_CLOSING) ||
1373 (ch->ch_cflag & CF_CREAD) == 0) {
1374 ch->ch_rout = ch->ch_rin;
1375 } else if ((ch->ch_flag & CH_FAST_READ) == 0 ||
1376 ch->ch_inwait != 0) {
1377 dgrp_input(ch);
1378
1379 if (ch->ch_rin != ch->ch_rout)
1380 work = 1;
1381 }
1382 }
1383
1384
1385
1386
1387
1388
1389 if (ch->ch_flag & (CH_RX_FLUSH | CH_PARAM)) {
1390
1391
1392
1393
1394
1395 if (ch->ch_flag & CH_RX_FLUSH) {
1396 if (((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >
1397 ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK))
1398 ch->ch_flag &= ~CH_RX_FLUSH;
1399 else
1400 work = 1;
1401 }
1402
1403
1404
1405
1406
1407 if (ch->ch_s_tmax != ch->ch_tmax ||
1408 ch->ch_s_ttime != ch->ch_ttime) {
1409 b = set_cmd_header(b, port, 48);
1410
1411 ch->ch_s_tmax = ch->ch_tmax;
1412 ch->ch_s_ttime = ch->ch_ttime;
1413
1414 put_unaligned_be16(ch->ch_s_tmax,
1415 b);
1416 b += 2;
1417
1418 put_unaligned_be16(ch->ch_s_ttime,
1419 b);
1420 b += 2;
1421 }
1422
1423
1424
1425
1426
1427 if (ch->ch_s_rlow != ch->ch_rlow ||
1428 ch->ch_s_rhigh != ch->ch_rhigh) {
1429 b = set_cmd_header(b, port, 45);
1430
1431 ch->ch_s_rlow = ch->ch_rlow;
1432 ch->ch_s_rhigh = ch->ch_rhigh;
1433
1434 put_unaligned_be16(ch->ch_s_rlow,
1435 b);
1436 b += 2;
1437
1438 put_unaligned_be16(ch->ch_s_rhigh,
1439 b);
1440 b += 2;
1441 }
1442
1443
1444
1445
1446
1447
1448 if (ch->ch_s_brate != ch->ch_brate ||
1449 ch->ch_s_cflag != ch->ch_cflag ||
1450 ch->ch_s_iflag != ch->ch_iflag ||
1451 ch->ch_s_oflag != ch->ch_oflag ||
1452 ch->ch_s_xflag != ch->ch_xflag) {
1453 b = set_cmd_header(b, port, 40);
1454
1455 ch->ch_s_brate = ch->ch_brate;
1456 ch->ch_s_cflag = ch->ch_cflag;
1457 ch->ch_s_iflag = ch->ch_iflag;
1458 ch->ch_s_oflag = ch->ch_oflag;
1459 ch->ch_s_xflag = ch->ch_xflag;
1460
1461 put_unaligned_be16(ch->ch_s_brate,
1462 b);
1463 b += 2;
1464
1465 put_unaligned_be16(ch->ch_s_cflag,
1466 b);
1467 b += 2;
1468
1469 put_unaligned_be16(ch->ch_s_iflag,
1470 b);
1471 b += 2;
1472
1473 put_unaligned_be16(ch->ch_s_oflag,
1474 b);
1475 b += 2;
1476
1477 put_unaligned_be16(ch->ch_s_xflag,
1478 b);
1479 b += 2;
1480 }
1481
1482
1483
1484
1485
1486 if (ch->ch_s_mout != ch->ch_mout ||
1487 ch->ch_s_mflow != ch->ch_mflow ||
1488 ch->ch_s_mctrl != ch->ch_mctrl) {
1489 b = set_cmd_header(b, port, 44);
1490
1491 *b++ = ch->ch_s_mout = ch->ch_mout;
1492 *b++ = ch->ch_s_mflow = ch->ch_mflow;
1493 *b++ = ch->ch_s_mctrl = ch->ch_mctrl;
1494 }
1495
1496
1497
1498
1499
1500 if (ch->ch_s_xon != ch->ch_xon ||
1501 ch->ch_s_xoff != ch->ch_xoff ||
1502 ch->ch_s_lnext != ch->ch_lnext ||
1503 ch->ch_s_xxon != ch->ch_xxon ||
1504 ch->ch_s_xxoff != ch->ch_xxoff) {
1505 b = set_cmd_header(b, port, 46);
1506
1507 *b++ = ch->ch_s_xon = ch->ch_xon;
1508 *b++ = ch->ch_s_xoff = ch->ch_xoff;
1509 *b++ = ch->ch_s_lnext = ch->ch_lnext;
1510 *b++ = ch->ch_s_xxon = ch->ch_xxon;
1511 *b++ = ch->ch_s_xxoff = ch->ch_xxoff;
1512 }
1513
1514
1515
1516
1517
1518 if (ch->ch_s_rmax != ch->ch_rmax ||
1519 ch->ch_s_rtime != ch->ch_rtime) {
1520 b = set_cmd_header(b, port, 47);
1521
1522 ch->ch_s_rmax = ch->ch_rmax;
1523 ch->ch_s_rtime = ch->ch_rtime;
1524
1525 put_unaligned_be16(ch->ch_s_rmax,
1526 b);
1527 b += 2;
1528
1529 put_unaligned_be16(ch->ch_s_rtime,
1530 b);
1531 b += 2;
1532 }
1533
1534 ch->ch_flag &= ~CH_PARAM;
1535 wake_up_interruptible(&ch->ch_flag_wait);
1536 }
1537
1538
1539
1540
1541
1542
1543 if (ch->ch_send != 0) {
1544
1545 send = ch->ch_send & ~ch->ch_expect;
1546
1547
1548 if ((send & RR_TX_ICHAR) != 0) {
1549 b = set_cmd_header(b, port, 60);
1550
1551 *b++ = ch->ch_xon;
1552 ch->ch_expect |= RR_TX_ICHAR;
1553 }
1554
1555
1556 if ((send & RR_TX_BREAK) != 0) {
1557 if (ch->ch_break_time != 0) {
1558 b = set_cmd_header(b, port, 61);
1559 put_unaligned_be16(ch->ch_break_time,
1560 b);
1561 b += 2;
1562
1563 ch->ch_expect |= RR_TX_BREAK;
1564 ch->ch_break_time = 0;
1565 } else {
1566 ch->ch_send &= ~RR_TX_BREAK;
1567 ch->ch_flag &= ~CH_TX_BREAK;
1568 wake_up_interruptible(&ch->ch_flag_wait);
1569 }
1570 }
1571
1572
1573
1574
1575
1576 if ((send & (RR_RX_FLUSH | RR_TX_FLUSH)) != 0) {
1577 b = set_cmd_header(b, port, 62);
1578
1579 *b++ = ((send & RR_TX_FLUSH) == 0 ? 1 :
1580 (send & RR_RX_FLUSH) == 0 ? 2 : 3);
1581
1582 if (send & RR_RX_FLUSH) {
1583 ch->ch_flush_seq = nd->nd_seq_in;
1584 ch->ch_flag |= CH_RX_FLUSH;
1585 work = 1;
1586 send_sync = 1;
1587 wanted_sync_port = port;
1588 }
1589
1590 ch->ch_send &= ~(RR_RX_FLUSH | RR_TX_FLUSH);
1591 }
1592
1593
1594 if ((send & (RR_RX_STOP | RR_TX_STOP)) != 0) {
1595 b = set_cmd_header(b, port, 63);
1596 *b = 0;
1597
1598 if ((send & RR_TX_STOP) != 0)
1599 *b |= EV_OPU;
1600
1601 if ((send & RR_RX_STOP) != 0)
1602 *b |= EV_IPU;
1603
1604 b++;
1605
1606 ch->ch_send &= ~(RR_RX_STOP | RR_TX_STOP);
1607 }
1608
1609
1610 if ((send & (RR_RX_START | RR_TX_START)) != 0) {
1611 b = set_cmd_header(b, port, 64);
1612 *b = 0;
1613
1614 if ((send & RR_TX_START) != 0)
1615 *b |= EV_OPU | EV_OPS | EV_OPX;
1616
1617 if ((send & RR_RX_START) != 0)
1618 *b |= EV_IPU | EV_IPS;
1619
1620 b++;
1621
1622 ch->ch_send &= ~(RR_RX_START | RR_TX_START);
1623 }
1624 }
1625
1626
1627
1628
1629
1630
1631 rwin = (ch->ch_s_rin +
1632 ((ch->ch_rout - ch->ch_rin - 1) & RBUF_MASK));
1633
1634 n = (rwin - ch->ch_s_rwin) & 0xffff;
1635
1636 if (n >= RBUF_MAX / 4) {
1637 b[0] = 0xa0 + (port & 0xf);
1638 ch->ch_s_rwin = rwin;
1639 put_unaligned_be16(rwin, b + 1);
1640 b += 3;
1641 }
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1652
1653 if ((ch->ch_tun.un_flag & (UN_EMPTY|UN_LOW)) != 0) {
1654 if ((ch->ch_tun.un_flag & UN_LOW) != 0 ?
1655 (n <= TBUF_LOW) :
1656 (n == 0 && ch->ch_s_tpos == ch->ch_s_tin)) {
1657 ch->ch_tun.un_flag &= ~(UN_EMPTY|UN_LOW);
1658
1659 if (waitqueue_active(&((ch->ch_tun.un_tty)->write_wait)))
1660 wake_up_interruptible(&((ch->ch_tun.un_tty)->write_wait));
1661 tty_wakeup(ch->ch_tun.un_tty);
1662 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1663 }
1664 }
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674 if (ch->ch_pun.un_open_count &&
1675 (ch->ch_pun.un_flag &
1676 (UN_EMPTY|UN_TIME|UN_LOW|UN_PWAIT)) != 0) {
1677
1678 if ((ch->ch_pun.un_flag & UN_LOW) != 0 ?
1679 (n <= TBUF_LOW) :
1680 (ch->ch_pun.un_flag & UN_TIME) != 0 ?
1681 ((jiffies - ch->ch_waketime) >= 0) :
1682 (n == 0 && ch->ch_s_tpos == ch->ch_s_tin) &&
1683 ((ch->ch_pun.un_flag & UN_EMPTY) != 0 ||
1684 ((ch->ch_tun.un_open_count &&
1685 ch->ch_tun.un_tty->ops->chars_in_buffer) ?
1686 (ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) == 0
1687 : 1
1688 )
1689 )) {
1690 ch->ch_pun.un_flag &= ~(UN_EMPTY | UN_TIME | UN_LOW | UN_PWAIT);
1691
1692 if (waitqueue_active(&((ch->ch_pun.un_tty)->write_wait)))
1693 wake_up_interruptible(&((ch->ch_pun.un_tty)->write_wait));
1694 tty_wakeup(ch->ch_pun.un_tty);
1695 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1696
1697 } else if ((ch->ch_pun.un_flag & UN_TIME) != 0) {
1698 work = 1;
1699 }
1700 }
1701
1702
1703
1704
1705
1706
1707
1708
1709 t = ((ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff);
1710
1711 if (n > t)
1712 n = t;
1713
1714 if (n != 0) {
1715 n += (n <= 8 ? 1 : n <= 255 ? 2 : 3);
1716
1717 tdata[tchan++] = n;
1718 ttotal += n;
1719 }
1720 break;
1721
1722
1723
1724
1725
1726send_close:
1727 case CS_SEND_CLOSE:
1728 b = set_cmd_header(b, port, 10);
1729 if (ch->ch_otype == OTYPE_IMMEDIATE)
1730 *b++ = 3;
1731 else
1732 *b++ = 4;
1733
1734 ch->ch_state = CS_WAIT_CLOSE;
1735 break;
1736
1737
1738
1739
1740
1741 case CS_WAIT_OPEN:
1742 case CS_WAIT_CANCEL:
1743 case CS_WAIT_FAIL:
1744 case CS_WAIT_QUERY:
1745 case CS_WAIT_CLOSE:
1746 break;
1747
1748 default:
1749 pr_info("%s - unexpected channel state (%i)\n",
1750 __func__, ch->ch_state);
1751 }
1752 }
1753
1754
1755
1756
1757
1758
1759 if (mod != nd->nd_tx_module) {
1760 if (b != mbuf) {
1761 mbuf[-1] = 0xf0 | mod;
1762 nd->nd_tx_module = mod;
1763 } else {
1764 b--;
1765 }
1766 }
1767 }
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777 n = UIO_MAX - UIO_BASE;
1778
1779 if (tmax > n)
1780 tmax = n;
1781
1782 tmax -= 64;
1783
1784 tsafe = tmax;
1785
1786
1787
1788
1789
1790
1791 tmax -= 5 + 3 + 4 * nd->nd_chan_count;
1792
1793
1794
1795
1796
1797
1798
1799 n = nd->nd_tx_deposit - nd->nd_tx_charge - nd->nd_link.lk_header_size;
1800
1801 if (tmax > n)
1802 tmax = n;
1803
1804
1805
1806
1807
1808
1809 tmax -= b - buf;
1810
1811
1812
1813
1814
1815 if (tmax < 2 * nd->nd_chan_count) {
1816 tsend = 1;
1817
1818 } else if (tchan > 1 && ttotal > tmax) {
1819
1820
1821
1822
1823
1824
1825
1826 long tm = tmax;
1827 int tc = tchan;
1828 int try;
1829
1830 tsend = tm / tc;
1831
1832 for (try = 0; try < 3; try++) {
1833 int i;
1834 int c = 0;
1835
1836 for (i = 0; i < tc; i++) {
1837 if (tsend < tdata[i])
1838 tdata[c++] = tdata[i];
1839 else
1840 tm -= tdata[i];
1841 }
1842
1843 if (c == tc)
1844 break;
1845
1846 tsend = tm / c;
1847
1848 if (c == 1)
1849 break;
1850
1851 tc = c;
1852 }
1853
1854 tsend = tm / nd->nd_chan_count;
1855
1856 if (tsend < 2)
1857 tsend = 1;
1858
1859 } else {
1860
1861
1862
1863
1864
1865
1866 tsend = tmax;
1867 }
1868
1869 tsend -= (tsend <= 9) ? 1 : (tsend <= 257) ? 2 : 3;
1870
1871
1872
1873
1874
1875 port = 0;
1876 ch = nd->nd_chan;
1877 used_buffer = tmax;
1878
1879 for (mod = 0; port < nd->nd_chan_count; mod++) {
1880
1881
1882
1883
1884
1885 if (mod != nd->nd_tx_module)
1886 mbuf = ++b;
1887
1888
1889
1890
1891
1892 maxport = port + 16;
1893
1894 if (maxport > nd->nd_chan_count)
1895 maxport = nd->nd_chan_count;
1896
1897 for (; port < maxport; port++, ch++) {
1898 if (ch->ch_state != CS_READY)
1899 continue;
1900
1901 lastport = port;
1902
1903 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1904
1905
1906
1907
1908
1909 if (n != 0 && used_buffer > 0) {
1910 t = (ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff;
1911
1912 if (n > t)
1913 n = t;
1914
1915 if (n > tsend) {
1916 work = 1;
1917 n = tsend;
1918 }
1919
1920 if (n > used_buffer) {
1921 work = 1;
1922 n = used_buffer;
1923 }
1924
1925 if (n <= 0)
1926 continue;
1927
1928
1929
1930
1931
1932
1933 if (n <= 8) {
1934
1935 b[0] = ((n - 1) << 4) + (port & 0xf);
1936 b += 1;
1937
1938 } else if (n <= 255) {
1939
1940 b[0] = 0x80 + (port & 0xf);
1941 b[1] = n;
1942 b += 2;
1943
1944 } else {
1945
1946 b[0] = 0x90 + (port & 0xf);
1947 put_unaligned_be16(n, b + 1);
1948 b += 3;
1949 }
1950
1951 ch->ch_s_tin = (ch->ch_s_tin + n) & 0xffff;
1952
1953
1954
1955
1956
1957 t = TBUF_MAX - ch->ch_tout;
1958
1959 if (n >= t) {
1960 memcpy(b, ch->ch_tbuf + ch->ch_tout, t);
1961 b += t;
1962 n -= t;
1963 used_buffer -= t;
1964 ch->ch_tout = 0;
1965 }
1966
1967 memcpy(b, ch->ch_tbuf + ch->ch_tout, n);
1968 b += n;
1969 used_buffer -= n;
1970 ch->ch_tout += n;
1971 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1972 }
1973
1974
1975
1976
1977
1978
1979 if (n > TBUF_LOW)
1980 continue;
1981
1982 if ((ch->ch_flag & CH_LOW) != 0) {
1983 ch->ch_flag &= ~CH_LOW;
1984 wake_up_interruptible(&ch->ch_flag_wait);
1985 }
1986
1987
1988 if (ch->ch_tun.un_open_count) {
1989 struct tty_struct *tty = (ch->ch_tun.un_tty);
1990
1991 if (waitqueue_active(&tty->write_wait))
1992 wake_up_interruptible(&tty->write_wait);
1993
1994 tty_wakeup(tty);
1995 }
1996
1997 if (ch->ch_pun.un_open_count) {
1998 struct tty_struct *tty = (ch->ch_pun.un_tty);
1999
2000 if (waitqueue_active(&tty->write_wait))
2001 wake_up_interruptible(&tty->write_wait);
2002
2003 tty_wakeup(tty);
2004 }
2005
2006
2007
2008
2009
2010 if (n != 0)
2011 continue;
2012
2013 if ((ch->ch_flag & (CH_EMPTY | CH_DRAIN)) != 0 ||
2014 (ch->ch_pun.un_flag & UN_EMPTY) != 0) {
2015
2016
2017
2018
2019
2020 if (ch->ch_s_treq != ch->ch_s_tin) {
2021 b = set_cmd_header(b, port, 43);
2022
2023 ch->ch_s_treq = ch->ch_s_tin;
2024 put_unaligned_be16(ch->ch_s_treq,
2025 b);
2026 b += 2;
2027 }
2028
2029
2030
2031
2032
2033
2034 else if ((ch->ch_flag & CH_EMPTY) != 0 &&
2035 (ch->ch_send & RR_TX_BREAK) == 0) {
2036 ch->ch_flag &= ~CH_EMPTY;
2037
2038 wake_up_interruptible(&ch->ch_flag_wait);
2039 }
2040 }
2041 }
2042
2043
2044
2045
2046
2047
2048 if (mod != nd->nd_tx_module) {
2049 if (b != mbuf) {
2050 mbuf[-1] = 0xf0 | mod;
2051 nd->nd_tx_module = mod;
2052 } else {
2053 b--;
2054 }
2055 }
2056 }
2057
2058
2059
2060
2061
2062
2063
2064 in = nd->nd_seq_in;
2065
2066 if ((send_sync || nd->nd_seq_wait[in] != 0) && lastport >= 0) {
2067 u8 *bb = b;
2068
2069
2070
2071
2072
2073
2074
2075
2076 if (wanted_sync_port >= 0)
2077 lastport = wanted_sync_port;
2078
2079
2080
2081
2082
2083 ch = nd->nd_chan + lastport;
2084 ch->ch_flag |= CH_WAITING_SYNC;
2085
2086 mod = lastport >> 4;
2087
2088 if (mod != nd->nd_tx_module) {
2089 bb[0] = 0xf0 + mod;
2090 bb += 1;
2091
2092 nd->nd_tx_module = mod;
2093 }
2094
2095 bb = set_cmd_header(bb, lastport, 12);
2096 *bb++ = in;
2097
2098 nd->nd_seq_size[in] = bb - buf;
2099 nd->nd_seq_time[in] = jiffies;
2100
2101 if (++in >= SEQ_MAX)
2102 in = 0;
2103
2104 if (in != nd->nd_seq_out) {
2105 b = bb;
2106 nd->nd_seq_in = in;
2107 nd->nd_unack += b - buf;
2108 }
2109 }
2110
2111
2112
2113
2114
2115
2116
2117 else if (nd->nd_seq_wait[in] != 0) {
2118 nd->nd_seq_wait[in] = 0;
2119
2120 wake_up_interruptible(&nd->nd_seq_wque[in]);
2121 }
2122
2123
2124
2125
2126
2127
2128 if (b != buf) {
2129 nd->nd_tx_time = jiffies;
2130 } else if ((ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX) {
2131 *b++ = 0xf0 | nd->nd_tx_module;
2132 nd->nd_tx_time = jiffies;
2133 }
2134
2135 n = b - buf;
2136
2137 if (n >= tsafe)
2138 pr_info("%s - n(%i) >= tsafe(%i)\n",
2139 __func__, n, tsafe);
2140
2141 if (tsend < 0)
2142 dgrp_dump(buf, n);
2143
2144 nd->nd_tx_work = work;
2145
2146 return n;
2147}
2148
2149
2150
2151
2152
2153static ssize_t dgrp_net_read(struct file *file, char __user *buf, size_t count,
2154 loff_t *ppos)
2155{
2156 struct nd_struct *nd;
2157 long n;
2158 u8 *local_buf;
2159 u8 *b;
2160 ssize_t rtn;
2161
2162
2163
2164
2165 nd = (struct nd_struct *)(file->private_data);
2166 if (!nd)
2167 return -ENXIO;
2168
2169 if (count < UIO_MIN)
2170 return -EINVAL;
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180 down(&nd->nd_net_semaphore);
2181
2182 nd->nd_read_count++;
2183
2184 nd->nd_tx_ready = 0;
2185
2186
2187
2188
2189
2190 if (nd->nd_remain > UIO_BASE)
2191 pr_info_ratelimited("%s - nd_remain(%i) > UIO_BASE\n",
2192 __func__, nd->nd_remain);
2193
2194 b = local_buf = nd->nd_iobuf + UIO_BASE;
2195
2196
2197
2198
2199
2200 switch (nd->nd_state) {
2201
2202
2203
2204
2205 case NS_IDLE:
2206 if (nd->nd_mon_buf)
2207 dgrp_monitor_reset(nd);
2208
2209
2210
2211
2212
2213 b[0] = 0xfb;
2214 b[1] = 0x01;
2215 b += 2;
2216
2217 nd->nd_expect |= NR_IDENT;
2218
2219
2220
2221
2222
2223 b[0] = 0xfb;
2224 b[1] = 0x02;
2225 b += 2;
2226
2227 nd->nd_expect |= NR_CAPABILITY;
2228
2229
2230
2231
2232
2233 b[0] = 0xfb;
2234 b[1] = 0x18;
2235 b += 2;
2236
2237 nd->nd_expect |= NR_VPD;
2238
2239 nd->nd_state = NS_WAIT_QUERY;
2240 break;
2241
2242
2243
2244
2245
2246
2247 case NS_READY:
2248 b = dgrp_send(nd, count) + local_buf;
2249 break;
2250
2251
2252
2253
2254
2255
2256 case NS_SEND_ERROR:
2257 n = strlen(nd->nd_error);
2258
2259 b[0] = 0xff;
2260 b[1] = n;
2261 memcpy(b + 2, nd->nd_error, n);
2262 b += 2 + n;
2263
2264 dgrp_net_idle(nd);
2265
2266
2267
2268 dgrp_chan_count(nd, 0);
2269 break;
2270
2271 default:
2272 break;
2273 }
2274
2275 n = b - local_buf;
2276
2277 if (n != 0) {
2278 nd->nd_send_count++;
2279
2280 nd->nd_tx_byte += n + nd->nd_link.lk_header_size;
2281 nd->nd_tx_charge += n + nd->nd_link.lk_header_size;
2282 }
2283
2284 rtn = copy_to_user((void __user *)buf, local_buf, n);
2285 if (rtn) {
2286 rtn = -EFAULT;
2287 goto done;
2288 }
2289
2290 *ppos += n;
2291
2292 rtn = n;
2293
2294 if (nd->nd_mon_buf)
2295 dgrp_monitor_data(nd, RPDUMP_CLIENT, local_buf, n);
2296
2297
2298
2299
2300done:
2301 up(&nd->nd_net_semaphore);
2302
2303 return rtn;
2304}
2305
2306
2307
2308
2309
2310static void dgrp_receive(struct nd_struct *nd)
2311{
2312 struct ch_struct *ch;
2313 u8 *buf;
2314 u8 *b;
2315 u8 *dbuf;
2316 char *error;
2317 long port;
2318 long dlen;
2319 long plen;
2320 long remain;
2321 long n;
2322 long mlast;
2323 long elast;
2324 long mstat;
2325 long estat;
2326
2327 char ID[3];
2328
2329 nd->nd_tx_time = jiffies;
2330
2331 ID_TO_CHAR(nd->nd_ID, ID);
2332
2333 b = buf = nd->nd_iobuf;
2334 remain = nd->nd_remain;
2335
2336
2337
2338
2339
2340 while (remain > 0) {
2341 int n0 = b[0] >> 4;
2342 int n1 = b[0] & 0x0f;
2343
2344 if (n0 <= 12) {
2345 port = (nd->nd_rx_module << 4) + n1;
2346
2347 if (port >= nd->nd_chan_count) {
2348 error = "Improper Port Number";
2349 goto prot_error;
2350 }
2351
2352 ch = nd->nd_chan + port;
2353 } else {
2354 port = -1;
2355 ch = NULL;
2356 }
2357
2358
2359
2360
2361
2362 switch (n0) {
2363
2364
2365
2366
2367
2368 case 0:
2369 case 1:
2370 case 2:
2371 case 3:
2372 case 4:
2373 case 5:
2374 case 6:
2375 case 7:
2376 dlen = n0 + 1;
2377 plen = dlen + 1;
2378
2379 dbuf = b + 1;
2380 goto data;
2381
2382
2383
2384
2385
2386 case 8:
2387 if (remain < 3)
2388 goto done;
2389
2390 dlen = b[1];
2391 plen = dlen + 2;
2392
2393 dbuf = b + 2;
2394 goto data;
2395
2396
2397
2398
2399
2400 case 9:
2401 if (remain < 4)
2402 goto done;
2403
2404 dlen = get_unaligned_be16(b + 1);
2405 plen = dlen + 3;
2406
2407 dbuf = b + 3;
2408
2409
2410
2411
2412
2413data:
2414 nd->nd_tx_work = 1;
2415
2416
2417
2418
2419
2420
2421 if (ch->ch_state < CS_READY) {
2422 error = "Data received before RWIN established";
2423 goto prot_error;
2424 }
2425
2426
2427
2428
2429
2430
2431 n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff;
2432
2433 if (dlen > n) {
2434 error = "Receive data overrun";
2435 goto prot_error;
2436 }
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448 if (ch->ch_edelay != DGRP_RTIME) {
2449 if (ch->ch_rtime != ch->ch_edelay) {
2450 ch->ch_rtime = ch->ch_edelay;
2451 ch->ch_flag |= CH_PARAM;
2452 }
2453 } else if (dlen <= 3) {
2454 if (ch->ch_rtime != 10) {
2455 ch->ch_rtime = 10;
2456 ch->ch_flag |= CH_PARAM;
2457 }
2458 } else {
2459 if (ch->ch_rtime != DGRP_RTIME) {
2460 ch->ch_rtime = DGRP_RTIME;
2461 ch->ch_flag |= CH_PARAM;
2462 }
2463 }
2464
2465
2466
2467
2468
2469
2470
2471 if (remain < plen)
2472 dlen -= plen - remain;
2473
2474
2475
2476
2477
2478 if ((ch->ch_flag & CH_RX_FLUSH) != 0 &&
2479 ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >=
2480 ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) {
2481 ch->ch_flag &= ~CH_RX_FLUSH;
2482 }
2483
2484
2485
2486
2487
2488
2489 ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff;
2490
2491 if (ch->ch_state == CS_READY &&
2492 (ch->ch_tun.un_open_count != 0) &&
2493 (ch->ch_tun.un_flag & UN_CLOSING) == 0 &&
2494 (ch->ch_cflag & CF_CREAD) != 0 &&
2495 (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 &&
2496 (ch->ch_send & RR_RX_FLUSH) == 0) {
2497
2498 if (ch->ch_rin + dlen >= RBUF_MAX) {
2499 n = RBUF_MAX - ch->ch_rin;
2500
2501 memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n);
2502
2503 ch->ch_rin = 0;
2504 dbuf += n;
2505 dlen -= n;
2506 }
2507
2508 memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen);
2509
2510 ch->ch_rin += dlen;
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520 if ((ch->ch_flag & CH_FAST_READ) == 0 ||
2521 ch->ch_inwait != 0) {
2522 dgrp_input(ch);
2523 }
2524
2525
2526
2527
2528
2529
2530
2531 if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) &&
2532 (ch->ch_flag & CH_FAST_READ) != 0)
2533 wake_up_interruptible(&ch->ch_tun.un_tty->read_wait);
2534
2535
2536
2537
2538
2539
2540 if ((ch->ch_flag & CH_INPUT) != 0) {
2541 ch->ch_flag &= ~CH_INPUT;
2542
2543 wake_up_interruptible(&ch->ch_flag_wait);
2544 }
2545 }
2546
2547
2548
2549
2550
2551
2552 if (remain < plen) {
2553 dlen = plen - remain;
2554 b = buf;
2555
2556 b[0] = 0x90 + n1;
2557 put_unaligned_be16(dlen, b + 1);
2558
2559 remain = 3;
2560 goto done;
2561 }
2562 break;
2563
2564
2565
2566
2567
2568 case 10:
2569 plen = 3;
2570 if (remain < plen)
2571 goto done;
2572
2573 nd->nd_tx_work = 1;
2574
2575 {
2576 ushort tpos = get_unaligned_be16(b + 1);
2577
2578 ushort ack = (tpos - ch->ch_s_tpos) & 0xffff;
2579 ushort unack = (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff;
2580 ushort notify = (ch->ch_s_treq - ch->ch_s_tpos) & 0xffff;
2581
2582 if (ch->ch_state < CS_READY || ack > unack) {
2583 error = "Improper Window Sequence";
2584 goto prot_error;
2585 }
2586
2587 ch->ch_s_tpos = tpos;
2588
2589 if (notify <= ack)
2590 ch->ch_s_treq = tpos;
2591 }
2592 break;
2593
2594
2595
2596
2597
2598 case 11:
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614 if (remain < 2)
2615 goto done;
2616
2617
2618 switch (b[1]) {
2619
2620
2621
2622
2623
2624 case 11:
2625 plen = 6;
2626 if (remain < plen)
2627 goto done;
2628
2629 nd->nd_tx_work = 1;
2630
2631 {
2632 int req = b[2];
2633 int resp = b[3];
2634 port = get_unaligned_be16(b + 4);
2635
2636 if (port >= nd->nd_chan_count) {
2637 error = "Open channel number out of range";
2638 goto prot_error;
2639 }
2640
2641 ch = nd->nd_chan + port;
2642
2643
2644
2645
2646
2647
2648 switch (ch->ch_state) {
2649 case CS_IDLE:
2650
2651
2652
2653
2654
2655 if (ch->ch_otype_waiting != 0 &&
2656 req == ch->ch_otype_waiting &&
2657 resp == 0) {
2658 ch->ch_otype = req;
2659 ch->ch_otype_waiting = 0;
2660 ch->ch_state = CS_SEND_QUERY;
2661 break;
2662 }
2663 goto open_error;
2664
2665 case CS_WAIT_OPEN:
2666
2667
2668
2669
2670
2671 if (req == ch->ch_otype) {
2672 switch (resp) {
2673
2674
2675
2676
2677
2678
2679 case 0:
2680 ch->ch_state = CS_SEND_QUERY;
2681 break;
2682
2683
2684
2685
2686
2687
2688 case 1:
2689 case 2:
2690 if (req != OTYPE_IMMEDIATE) {
2691 ch->ch_otype_waiting = req;
2692 ch->ch_state = CS_IDLE;
2693 break;
2694 }
2695
2696
2697
2698
2699
2700
2701 default:
2702 if (ch->ch_open_count != 0) {
2703 ch->ch_flag |= CH_HANGUP;
2704 dgrp_carrier(ch);
2705 ch->ch_state = CS_IDLE;
2706 break;
2707 }
2708
2709 ch->ch_open_error = resp;
2710 ch->ch_state = CS_IDLE;
2711
2712 wake_up_interruptible(&ch->ch_flag_wait);
2713 }
2714 break;
2715 }
2716
2717
2718
2719
2720
2721
2722 if (ch->ch_otype_waiting != 0 &&
2723 req == ch->ch_otype_waiting &&
2724 resp == 0) {
2725 ch->ch_otype = ch->ch_otype_waiting;
2726 ch->ch_otype_waiting = 0;
2727 ch->ch_state = CS_WAIT_FAIL;
2728 break;
2729 }
2730 goto open_error;
2731
2732
2733 case CS_WAIT_FAIL:
2734
2735
2736
2737
2738
2739
2740 if (req == OTYPE_IMMEDIATE) {
2741 ch->ch_state = CS_SEND_QUERY;
2742 break;
2743 }
2744 goto open_error;
2745
2746
2747 case CS_WAIT_CANCEL:
2748
2749
2750
2751
2752
2753 if (req == ch->ch_otype_waiting &&
2754 resp == 0) {
2755 ch->ch_otype_waiting = 0;
2756 break;
2757 }
2758
2759
2760
2761
2762
2763 if (req == 4 && resp == 0) {
2764 ch->ch_otype_waiting = 0;
2765 ch->ch_state = CS_IDLE;
2766 break;
2767 }
2768 goto open_error;
2769
2770
2771 case CS_WAIT_CLOSE:
2772
2773
2774
2775
2776
2777 if (req >= 3) {
2778 ch->ch_state = CS_IDLE;
2779 break;
2780 }
2781 goto open_error;
2782
2783open_error:
2784 default:
2785 {
2786 error = "Improper Open Response";
2787 goto prot_error;
2788 }
2789 }
2790 }
2791 break;
2792
2793
2794
2795
2796
2797 case 13:
2798 plen = 3;
2799 if (remain < plen)
2800 goto done;
2801 {
2802 int seq = b[2];
2803 int s;
2804
2805
2806
2807
2808
2809
2810 if (ch->ch_flag & CH_WAITING_SYNC) {
2811 ch->ch_flag &= ~(CH_WAITING_SYNC);
2812 wake_up_interruptible(&ch->ch_flag_wait);
2813 }
2814
2815 if (((seq - nd->nd_seq_out) & SEQ_MASK) >=
2816 ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) {
2817 break;
2818 }
2819
2820 for (s = nd->nd_seq_out;; s = (s + 1) & SEQ_MASK) {
2821 if (nd->nd_seq_wait[s] != 0) {
2822 nd->nd_seq_wait[s] = 0;
2823
2824 wake_up_interruptible(&nd->nd_seq_wque[s]);
2825 }
2826
2827 nd->nd_unack -= nd->nd_seq_size[s];
2828
2829 if (s == seq)
2830 break;
2831 }
2832
2833 nd->nd_seq_out = (seq + 1) & SEQ_MASK;
2834 }
2835 break;
2836
2837
2838
2839
2840
2841 case 15:
2842 plen = 6;
2843 if (remain < plen)
2844 goto done;
2845
2846 {
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857 ch->ch_send &= ~RR_SEQUENCE;
2858 ch->ch_expect &= ~RR_SEQUENCE;
2859 }
2860 goto check_query;
2861
2862
2863
2864
2865
2866 case 17:
2867 plen = 5;
2868 if (remain < plen)
2869 goto done;
2870
2871 {
2872 ch->ch_s_elast = get_unaligned_be16(b + 2);
2873 ch->ch_s_mlast = b[4];
2874
2875 ch->ch_expect &= ~RR_STATUS;
2876 ch->ch_send &= ~RR_STATUS;
2877
2878
2879
2880
2881
2882
2883
2884 ch->ch_flag &= ~CH_PHYS_CD;
2885
2886 dgrp_carrier(ch);
2887 }
2888 goto check_query;
2889
2890
2891
2892
2893
2894 case 19:
2895 plen = 14;
2896 if (remain < plen)
2897 goto done;
2898
2899 break;
2900
2901
2902
2903
2904
2905 case 21:
2906 plen = 6;
2907 if (remain < plen)
2908 goto done;
2909
2910 {
2911 ch->ch_s_rsize = get_unaligned_be16(b + 2);
2912 ch->ch_s_tsize = get_unaligned_be16(b + 4);
2913
2914 ch->ch_send &= ~RR_BUFFER;
2915 ch->ch_expect &= ~RR_BUFFER;
2916 }
2917 goto check_query;
2918
2919
2920
2921
2922
2923 case 23:
2924 plen = 32;
2925 if (remain < plen)
2926 goto done;
2927
2928 {
2929 ch->ch_send &= ~RR_CAPABILITY;
2930 ch->ch_expect &= ~RR_CAPABILITY;
2931 }
2932
2933
2934
2935
2936
2937
2938
2939check_query:
2940 if (ch->ch_state == CS_WAIT_QUERY &&
2941 (ch->ch_expect & (RR_SEQUENCE |
2942 RR_STATUS |
2943 RR_BUFFER |
2944 RR_CAPABILITY)) == 0) {
2945 ch->ch_tmax = ch->ch_s_tsize / 4;
2946
2947 if (ch->ch_edelay == DGRP_TTIME)
2948 ch->ch_ttime = DGRP_TTIME;
2949 else
2950 ch->ch_ttime = ch->ch_edelay;
2951
2952 ch->ch_rmax = ch->ch_s_rsize / 4;
2953
2954 if (ch->ch_edelay == DGRP_RTIME)
2955 ch->ch_rtime = DGRP_RTIME;
2956 else
2957 ch->ch_rtime = ch->ch_edelay;
2958
2959 ch->ch_rlow = 2 * ch->ch_s_rsize / 8;
2960 ch->ch_rhigh = 6 * ch->ch_s_rsize / 8;
2961
2962 ch->ch_state = CS_READY;
2963
2964 nd->nd_tx_work = 1;
2965 wake_up_interruptible(&ch->ch_flag_wait);
2966
2967 }
2968 break;
2969
2970 default:
2971 goto decode_error;
2972 }
2973 break;
2974
2975
2976
2977
2978
2979 case 12:
2980 plen = 4;
2981 if (remain < plen)
2982 goto done;
2983
2984 mlast = ch->ch_s_mlast;
2985 elast = ch->ch_s_elast;
2986
2987 mstat = ch->ch_s_mlast = b[1];
2988 estat = ch->ch_s_elast = get_unaligned_be16(b + 2);
2989
2990
2991
2992
2993
2994 if (((mstat ^ mlast) & DM_CD) != 0)
2995 dgrp_carrier(ch);
2996
2997
2998
2999
3000
3001
3002 if ((estat & ~elast & EV_RXB) != 0 &&
3003 (ch->ch_tun.un_open_count != 0) &&
3004 I_BRKINT(ch->ch_tun.un_tty) &&
3005 !(I_IGNBRK(ch->ch_tun.un_tty))) {
3006
3007 tty_buffer_request_room(ch->ch_tun.un_tty, 1);
3008 tty_insert_flip_char(ch->ch_tun.un_tty, 0, TTY_BREAK);
3009 tty_flip_buffer_push(ch->ch_tun.un_tty);
3010
3011 }
3012
3013
3014
3015
3016
3017
3018
3019 if ((~estat & elast & EV_TXB) != 0 &&
3020 (ch->ch_expect & RR_TX_BREAK) != 0) {
3021
3022 nd->nd_tx_work = 1;
3023
3024 ch->ch_expect &= ~RR_TX_BREAK;
3025
3026 if (ch->ch_break_time != 0) {
3027 ch->ch_send |= RR_TX_BREAK;
3028 } else {
3029 ch->ch_send &= ~RR_TX_BREAK;
3030 ch->ch_flag &= ~CH_TX_BREAK;
3031 wake_up_interruptible(&ch->ch_flag_wait);
3032 }
3033 }
3034 break;
3035
3036 case 13:
3037 case 14:
3038 error = "Unrecognized command";
3039 goto prot_error;
3040
3041
3042
3043
3044
3045 case 15:
3046 switch (n1) {
3047
3048
3049
3050
3051 case 0:
3052 case 1:
3053 case 2:
3054 case 3:
3055 case 4:
3056 case 5:
3057 case 6:
3058 case 7:
3059 plen = 1;
3060 nd->nd_rx_module = n1;
3061 break;
3062
3063
3064
3065
3066
3067 case 8:
3068 plen = 2;
3069 if (remain < plen)
3070 goto done;
3071
3072 nd->nd_rx_module = b[1];
3073 break;
3074
3075
3076
3077
3078
3079 case 11:
3080 if (remain < 4)
3081 goto done;
3082
3083 plen = get_unaligned_be16(b + 2);
3084
3085 if (plen < 12 || plen > 1000) {
3086 error = "Response Packet length error";
3087 goto prot_error;
3088 }
3089
3090 nd->nd_tx_work = 1;
3091
3092 switch (b[1]) {
3093
3094
3095
3096
3097 case 0:
3098 nd->nd_send |= NR_ECHO;
3099 break;
3100
3101
3102
3103
3104
3105 case 1:
3106 nd->nd_send |= NR_IDENT;
3107 break;
3108
3109
3110
3111
3112
3113 case 32:
3114 nd->nd_send |= NR_PASSWORD;
3115 break;
3116
3117 }
3118 break;
3119
3120
3121
3122
3123
3124 case 12:
3125 if (remain < 4)
3126 goto done;
3127
3128 plen = get_unaligned_be16(b + 2);
3129
3130 if (plen < 4 || plen > 1000) {
3131 error = "Response Packet length error";
3132 goto prot_error;
3133 }
3134
3135 nd->nd_tx_work = 1;
3136
3137 switch (b[1]) {
3138
3139
3140
3141
3142 case 0:
3143 nd->nd_expect &= ~NR_ECHO;
3144 break;
3145
3146
3147
3148
3149
3150 case 1:
3151 {
3152 int desclen;
3153
3154 nd->nd_hw_ver = (b[8] << 8) | b[9];
3155 nd->nd_sw_ver = (b[10] << 8) | b[11];
3156 nd->nd_hw_id = b[6];
3157 desclen = ((plen - 12) > MAX_DESC_LEN) ? MAX_DESC_LEN :
3158 plen - 12;
3159
3160 if (desclen <= 0) {
3161 error = "Response Packet desclen error";
3162 goto prot_error;
3163 }
3164
3165 strncpy(nd->nd_ps_desc, b + 12, desclen);
3166 nd->nd_ps_desc[desclen] = 0;
3167 }
3168
3169 nd->nd_expect &= ~NR_IDENT;
3170 break;
3171
3172
3173
3174
3175
3176 case 2:
3177 {
3178 int nn = get_unaligned_be16(b + 4);
3179
3180 if (nn > CHAN_MAX)
3181 nn = CHAN_MAX;
3182
3183 dgrp_chan_count(nd, nn);
3184 }
3185
3186 nd->nd_expect &= ~NR_CAPABILITY;
3187 break;
3188
3189
3190
3191
3192
3193 case 15:
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205 case 24:
3206
3207
3208
3209
3210
3211
3212 if (plen > 4) {
3213 memcpy(nd->nd_vpd, b + 4, min(plen - 4, (long) VPDSIZE));
3214 nd->nd_vpd_len = min(plen - 4, (long) VPDSIZE);
3215 }
3216
3217 nd->nd_expect &= ~NR_VPD;
3218 break;
3219
3220 default:
3221 goto decode_error;
3222 }
3223
3224 if (nd->nd_expect == 0 &&
3225 nd->nd_state == NS_WAIT_QUERY) {
3226 nd->nd_state = NS_READY;
3227 }
3228 break;
3229
3230
3231
3232
3233
3234 case 14:
3235 if (remain < 4)
3236 goto done;
3237
3238 plen = get_unaligned_be16(b + 2) + 4;
3239
3240 if (plen > 1000) {
3241 error = "Debug Packet too large";
3242 goto prot_error;
3243 }
3244
3245 if (remain < plen)
3246 goto done;
3247 break;
3248
3249
3250
3251
3252
3253 case 15:
3254 if (remain < 2)
3255 goto done;
3256
3257 plen = 2 + b[1];
3258
3259 if (remain < plen)
3260 goto done;
3261
3262 nd->nd_tx_work = 1;
3263
3264 n = b[plen];
3265 b[plen] = 0;
3266
3267 b[plen] = n;
3268
3269 error = "Client Reset Acknowledge";
3270 goto prot_error;
3271
3272 default:
3273 goto decode_error;
3274 }
3275 break;
3276
3277 default:
3278 goto decode_error;
3279 }
3280
3281 b += plen;
3282 remain -= plen;
3283 }
3284
3285
3286
3287
3288
3289
3290
3291done:
3292 if (remain > 0 && b != buf)
3293 memcpy(buf, b, remain);
3294
3295 nd->nd_remain = remain;
3296 return;
3297
3298
3299
3300
3301
3302decode_error:
3303 error = "Protocol decode error";
3304
3305
3306
3307
3308
3309prot_error:
3310 nd->nd_remain = 0;
3311 nd->nd_state = NS_SEND_ERROR;
3312 nd->nd_error = error;
3313}
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323static ssize_t dgrp_net_write(struct file *file, const char __user *buf,
3324 size_t count, loff_t *ppos)
3325{
3326 struct nd_struct *nd;
3327 ssize_t rtn = 0;
3328 long n;
3329 long total = 0;
3330
3331
3332
3333
3334 nd = (struct nd_struct *)(file->private_data);
3335 if (!nd)
3336 return -ENXIO;
3337
3338
3339
3340
3341 down(&nd->nd_net_semaphore);
3342
3343 nd->nd_write_count++;
3344
3345
3346
3347
3348
3349 if (count == 0) {
3350 dgrp_net_idle(nd);
3351
3352
3353
3354 dgrp_chan_count(nd, 0);
3355 goto unlock;
3356 }
3357
3358
3359
3360
3361
3362 while (count > 0) {
3363 n = UIO_MAX - nd->nd_remain;
3364
3365 if (n > count)
3366 n = count;
3367
3368 nd->nd_rx_byte += n + nd->nd_link.lk_header_size;
3369
3370 rtn = copy_from_user(nd->nd_iobuf + nd->nd_remain,
3371 (void __user *) buf + total, n);
3372 if (rtn) {
3373 rtn = -EFAULT;
3374 goto unlock;
3375 }
3376
3377 *ppos += n;
3378
3379 total += n;
3380
3381 count -= n;
3382
3383 if (nd->nd_mon_buf)
3384 dgrp_monitor_data(nd, RPDUMP_SERVER,
3385 nd->nd_iobuf + nd->nd_remain, n);
3386
3387 nd->nd_remain += n;
3388
3389 dgrp_receive(nd);
3390 }
3391
3392 rtn = total;
3393
3394unlock:
3395
3396
3397
3398 up(&nd->nd_net_semaphore);
3399
3400 return rtn;
3401}
3402
3403
3404
3405
3406
3407
3408
3409static unsigned int dgrp_net_select(struct file *file,
3410 struct poll_table_struct *table)
3411{
3412 unsigned int retval = 0;
3413 struct nd_struct *nd = file->private_data;
3414
3415 poll_wait(file, &nd->nd_tx_waitq, table);
3416
3417 if (nd->nd_tx_ready)
3418 retval |= POLLIN | POLLRDNORM;
3419
3420 retval |= POLLOUT | POLLWRNORM;
3421
3422 return retval;
3423}
3424
3425
3426
3427
3428
3429
3430
3431
3432static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
3433 unsigned long arg)
3434{
3435 struct nd_struct *nd;
3436 int rtn = 0;
3437 long size = _IOC_SIZE(cmd);
3438 struct link_struct link;
3439
3440 nd = file->private_data;
3441
3442 if (_IOC_DIR(cmd) & _IOC_READ)
3443 rtn = access_ok(VERIFY_WRITE, (void __user *) arg, size);
3444 else if (_IOC_DIR(cmd) & _IOC_WRITE)
3445 rtn = access_ok(VERIFY_READ, (void __user *) arg, size);
3446
3447 if (!rtn)
3448 return rtn;
3449
3450 switch (cmd) {
3451 case DIGI_SETLINK:
3452 if (size != sizeof(struct link_struct))
3453 return -EINVAL;
3454
3455 if (copy_from_user((void *)(&link), (void __user *) arg, size))
3456 return -EFAULT;
3457
3458 if (link.lk_fast_rate < 9600)
3459 link.lk_fast_rate = 9600;
3460
3461 if (link.lk_slow_rate < 2400)
3462 link.lk_slow_rate = 2400;
3463
3464 if (link.lk_fast_rate > 10000000)
3465 link.lk_fast_rate = 10000000;
3466
3467 if (link.lk_slow_rate > link.lk_fast_rate)
3468 link.lk_slow_rate = link.lk_fast_rate;
3469
3470 if (link.lk_fast_delay > 2000)
3471 link.lk_fast_delay = 2000;
3472
3473 if (link.lk_slow_delay > 10000)
3474 link.lk_slow_delay = 10000;
3475
3476 if (link.lk_fast_delay < 60)
3477 link.lk_fast_delay = 60;
3478
3479 if (link.lk_slow_delay < link.lk_fast_delay)
3480 link.lk_slow_delay = link.lk_fast_delay;
3481
3482 if (link.lk_header_size < 2)
3483 link.lk_header_size = 2;
3484
3485 if (link.lk_header_size > 128)
3486 link.lk_header_size = 128;
3487
3488 link.lk_fast_rate /= 8 * 1000 / dgrp_poll_tick;
3489 link.lk_slow_rate /= 8 * 1000 / dgrp_poll_tick;
3490
3491 link.lk_fast_delay /= dgrp_poll_tick;
3492 link.lk_slow_delay /= dgrp_poll_tick;
3493
3494 nd->nd_link = link;
3495
3496 break;
3497
3498 case DIGI_GETLINK:
3499 if (size != sizeof(struct link_struct))
3500 return -EINVAL;
3501
3502 if (copy_to_user((void __user *)arg, (void *)(&nd->nd_link),
3503 size))
3504 return -EFAULT;
3505
3506 break;
3507
3508 default:
3509 return -EINVAL;
3510
3511 }
3512
3513 return 0;
3514}
3515
3516
3517
3518
3519
3520
3521
3522
3523void dgrp_poll_handler(unsigned long arg)
3524{
3525 struct dgrp_poll_data *poll_data;
3526 struct nd_struct *nd;
3527 struct link_struct *lk;
3528 ulong time;
3529 ulong poll_time;
3530 ulong freq;
3531 ulong lock_flags;
3532
3533 poll_data = (struct dgrp_poll_data *) arg;
3534 freq = 1000 / poll_data->poll_tick;
3535 poll_data->poll_round += 17;
3536
3537 if (poll_data->poll_round >= freq)
3538 poll_data->poll_round -= freq;
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549 list_for_each_entry(nd, &nd_struct_list, list) {
3550
3551 lk = &nd->nd_link;
3552
3553
3554
3555
3556
3557
3558
3559 nd->nd_read_count -= (nd->nd_read_count +
3560 poll_data->poll_round) / freq;
3561 nd->nd_write_count -= (nd->nd_write_count +
3562 poll_data->poll_round) / freq;
3563 nd->nd_send_count -= (nd->nd_send_count +
3564 poll_data->poll_round) / freq;
3565 nd->nd_tx_byte -= (nd->nd_tx_byte +
3566 poll_data->poll_round) / freq;
3567 nd->nd_rx_byte -= (nd->nd_rx_byte +
3568 poll_data->poll_round) / freq;
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581 if (lk->lk_slow_rate >= UIO_MAX) {
3582
3583 nd->nd_delay = 0;
3584 nd->nd_rate = UIO_MAX;
3585
3586 nd->nd_tx_deposit = nd->nd_tx_charge + 3 * UIO_MAX;
3587 nd->nd_tx_credit = 3 * UIO_MAX;
3588
3589 } else {
3590
3591 long rate;
3592 long delay;
3593 long deposit;
3594 long charge;
3595 long size;
3596 long excess;
3597
3598 long seq_in = nd->nd_seq_in;
3599 long seq_out = nd->nd_seq_out;
3600
3601
3602
3603
3604
3605
3606 if (seq_in == seq_out) {
3607 delay = 0;
3608 rate = lk->lk_fast_rate;
3609 }
3610
3611
3612
3613
3614
3615
3616 else {
3617
3618
3619
3620
3621
3622
3623
3624 delay = ((jiffies - nd->nd_seq_time[seq_out])
3625 - (nd->nd_seq_size[seq_out] /
3626 lk->lk_fast_rate));
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636 rate =
3637 (delay <= lk->lk_fast_delay ?
3638 lk->lk_fast_rate :
3639 delay >= lk->lk_slow_delay ?
3640 lk->lk_slow_rate :
3641 (lk->lk_slow_rate +
3642 (lk->lk_slow_delay - delay) *
3643 (lk->lk_fast_rate - lk->lk_slow_rate) /
3644 (lk->lk_slow_delay - lk->lk_fast_delay)
3645 )
3646 );
3647 }
3648
3649 nd->nd_delay = delay;
3650 nd->nd_rate = rate;
3651
3652
3653
3654
3655
3656
3657 deposit = nd->nd_tx_deposit;
3658 charge = nd->nd_tx_charge;
3659
3660 deposit += rate;
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671 size = 2 * nd->nd_link.lk_header_size;
3672
3673 if (size < rate)
3674 size = rate;
3675
3676 size *= 3;
3677
3678 excess = deposit - charge - size;
3679
3680 if (excess > 0)
3681 deposit -= excess;
3682
3683 nd->nd_tx_deposit = deposit;
3684 nd->nd_tx_credit = deposit - charge;
3685
3686
3687
3688
3689
3690
3691 size = 3 * lk->lk_header_size;
3692
3693 if (nd->nd_tx_credit < size)
3694 continue;
3695 }
3696
3697
3698
3699
3700
3701
3702
3703 if (waitqueue_active(&nd->nd_tx_waitq) &&
3704 (nd->nd_tx_work != 0 ||
3705 (ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX)) {
3706 nd->nd_tx_ready = 1;
3707
3708 wake_up_interruptible(&nd->nd_tx_waitq);
3709
3710
3711
3712 }
3713 }
3714
3715
3716
3717
3718
3719 spin_lock_irqsave(&poll_data->poll_lock, lock_flags);
3720
3721 poll_data->node_active_count--;
3722 if (poll_data->node_active_count > 0) {
3723 poll_data->node_active_count++;
3724 poll_time = poll_data->timer.expires +
3725 poll_data->poll_tick * HZ / 1000;
3726
3727 time = poll_time - jiffies;
3728
3729 if (time >= 2 * poll_data->poll_tick)
3730 poll_time = jiffies + dgrp_poll_tick * HZ / 1000;
3731
3732 poll_data->timer.expires = poll_time;
3733 add_timer(&poll_data->timer);
3734 }
3735
3736 spin_unlock_irqrestore(&poll_data->poll_lock, lock_flags);
3737}
3738