1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/kernel.h>
22#include <linux/sched/signal.h>
23#include <linux/interrupt.h>
24#include <linux/module.h>
25#include <linux/ctype.h>
26#include <linux/tty.h>
27#include <linux/tty_flip.h>
28#include <linux/types.h>
29#include <linux/serial_reg.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32#include <linux/uaccess.h>
33#include <linux/pci.h>
34#include "dgnc_driver.h"
35#include "dgnc_tty.h"
36#include "dgnc_neo.h"
37#include "dgnc_cls.h"
38#include "dgnc_utils.h"
39
40
41
42static const struct digi_t dgnc_digi_init = {
43 .digi_flags = DIGI_COOK,
44 .digi_maxcps = 100,
45 .digi_maxchar = 50,
46 .digi_bufsize = 100,
47 .digi_onlen = 4,
48 .digi_offlen = 4,
49 .digi_onstr = "\033[5i",
50 .digi_offstr = "\033[4i",
51 .digi_term = "ansi"
52};
53
54
55
56
57
58
59
60
61static struct ktermios default_termios = {
62 .c_iflag = (DEFAULT_IFLAGS),
63 .c_oflag = (DEFAULT_OFLAGS),
64 .c_cflag = (DEFAULT_CFLAGS),
65 .c_lflag = (DEFAULT_LFLAGS),
66 .c_cc = INIT_C_CC,
67 .c_line = 0,
68};
69
70
71static int dgnc_tty_open(struct tty_struct *tty, struct file *file);
72static void dgnc_tty_close(struct tty_struct *tty, struct file *file);
73static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file,
74 struct channel_t *ch);
75static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
76 unsigned long arg);
77static int dgnc_tty_digigeta(struct tty_struct *tty,
78 struct digi_t __user *retinfo);
79static int dgnc_tty_digiseta(struct tty_struct *tty,
80 struct digi_t __user *new_info);
81static int dgnc_tty_write_room(struct tty_struct *tty);
82static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c);
83static int dgnc_tty_chars_in_buffer(struct tty_struct *tty);
84static void dgnc_tty_start(struct tty_struct *tty);
85static void dgnc_tty_stop(struct tty_struct *tty);
86static void dgnc_tty_throttle(struct tty_struct *tty);
87static void dgnc_tty_unthrottle(struct tty_struct *tty);
88static void dgnc_tty_flush_chars(struct tty_struct *tty);
89static void dgnc_tty_flush_buffer(struct tty_struct *tty);
90static void dgnc_tty_hangup(struct tty_struct *tty);
91static int dgnc_set_modem_info(struct channel_t *ch, unsigned int command,
92 unsigned int __user *value);
93static int dgnc_get_modem_info(struct channel_t *ch,
94 unsigned int __user *value);
95static int dgnc_tty_tiocmget(struct tty_struct *tty);
96static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set,
97 unsigned int clear);
98static int dgnc_tty_send_break(struct tty_struct *tty, int msec);
99static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout);
100static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf,
101 int count);
102static void dgnc_tty_set_termios(struct tty_struct *tty,
103 struct ktermios *old_termios);
104static void dgnc_tty_send_xchar(struct tty_struct *tty, char ch);
105static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char line);
106static void dgnc_wake_up_unit(struct un_t *unit);
107
108static const struct tty_operations dgnc_tty_ops = {
109 .open = dgnc_tty_open,
110 .close = dgnc_tty_close,
111 .write = dgnc_tty_write,
112 .write_room = dgnc_tty_write_room,
113 .flush_buffer = dgnc_tty_flush_buffer,
114 .chars_in_buffer = dgnc_tty_chars_in_buffer,
115 .flush_chars = dgnc_tty_flush_chars,
116 .ioctl = dgnc_tty_ioctl,
117 .set_termios = dgnc_tty_set_termios,
118 .stop = dgnc_tty_stop,
119 .start = dgnc_tty_start,
120 .throttle = dgnc_tty_throttle,
121 .unthrottle = dgnc_tty_unthrottle,
122 .hangup = dgnc_tty_hangup,
123 .put_char = dgnc_tty_put_char,
124 .tiocmget = dgnc_tty_tiocmget,
125 .tiocmset = dgnc_tty_tiocmset,
126 .break_ctl = dgnc_tty_send_break,
127 .wait_until_sent = dgnc_tty_wait_until_sent,
128 .send_xchar = dgnc_tty_send_xchar
129};
130
131
132
133
134
135
136
137
138int dgnc_tty_register(struct dgnc_board *brd)
139{
140 int rc;
141
142 brd->serial_driver = tty_alloc_driver(brd->maxports,
143 TTY_DRIVER_REAL_RAW |
144 TTY_DRIVER_DYNAMIC_DEV |
145 TTY_DRIVER_HARDWARE_BREAK);
146
147 if (IS_ERR(brd->serial_driver))
148 return PTR_ERR(brd->serial_driver);
149
150 snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_",
151 brd->boardnum);
152
153 brd->serial_driver->name = brd->serial_name;
154 brd->serial_driver->name_base = 0;
155 brd->serial_driver->major = 0;
156 brd->serial_driver->minor_start = 0;
157 brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
158 brd->serial_driver->subtype = SERIAL_TYPE_NORMAL;
159 brd->serial_driver->init_termios = default_termios;
160 brd->serial_driver->driver_name = DRVSTR;
161
162
163
164
165
166 tty_set_operations(brd->serial_driver, &dgnc_tty_ops);
167
168 rc = tty_register_driver(brd->serial_driver);
169 if (rc < 0) {
170 dev_dbg(&brd->pdev->dev,
171 "Can't register tty device (%d)\n", rc);
172 goto free_serial_driver;
173 }
174
175
176
177
178
179
180 brd->print_driver = tty_alloc_driver(brd->maxports,
181 TTY_DRIVER_REAL_RAW |
182 TTY_DRIVER_DYNAMIC_DEV |
183 TTY_DRIVER_HARDWARE_BREAK);
184
185 if (IS_ERR(brd->print_driver)) {
186 rc = PTR_ERR(brd->print_driver);
187 goto unregister_serial_driver;
188 }
189
190 snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum);
191
192 brd->print_driver->name = brd->print_name;
193 brd->print_driver->name_base = 0;
194 brd->print_driver->major = brd->serial_driver->major;
195 brd->print_driver->minor_start = 0x80;
196 brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL;
197 brd->print_driver->subtype = SERIAL_TYPE_NORMAL;
198 brd->print_driver->init_termios = default_termios;
199 brd->print_driver->driver_name = DRVSTR;
200
201
202
203
204
205 tty_set_operations(brd->print_driver, &dgnc_tty_ops);
206
207 rc = tty_register_driver(brd->print_driver);
208 if (rc < 0) {
209 dev_dbg(&brd->pdev->dev,
210 "Can't register Transparent Print device(%d)\n",
211 rc);
212 goto free_print_driver;
213 }
214
215 return 0;
216
217free_print_driver:
218 put_tty_driver(brd->print_driver);
219unregister_serial_driver:
220 tty_unregister_driver(brd->serial_driver);
221free_serial_driver:
222 put_tty_driver(brd->serial_driver);
223
224 return rc;
225}
226
227void dgnc_tty_unregister(struct dgnc_board *brd)
228{
229 tty_unregister_driver(brd->print_driver);
230 tty_unregister_driver(brd->serial_driver);
231 put_tty_driver(brd->print_driver);
232 put_tty_driver(brd->serial_driver);
233}
234
235
236
237
238
239
240
241int dgnc_tty_init(struct dgnc_board *brd)
242{
243 int i;
244 void __iomem *vaddr;
245 struct channel_t *ch;
246
247 if (!brd)
248 return -ENXIO;
249
250
251
252 vaddr = brd->re_map_membase;
253
254 brd->nasync = brd->maxports;
255
256 for (i = 0; i < brd->nasync; i++) {
257
258
259
260
261 brd->channels[i] = kzalloc(sizeof(*brd->channels[i]),
262 GFP_KERNEL);
263 if (!brd->channels[i])
264 goto err_free_channels;
265 }
266
267 ch = brd->channels[0];
268 vaddr = brd->re_map_membase;
269
270
271 for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {
272 spin_lock_init(&ch->ch_lock);
273
274
275 ch->magic = DGNC_CHANNEL_MAGIC;
276 ch->ch_tun.magic = DGNC_UNIT_MAGIC;
277 ch->ch_tun.un_ch = ch;
278 ch->ch_tun.un_type = DGNC_SERIAL;
279 ch->ch_tun.un_dev = i;
280
281 ch->ch_pun.magic = DGNC_UNIT_MAGIC;
282 ch->ch_pun.un_ch = ch;
283 ch->ch_pun.un_type = DGNC_PRINT;
284 ch->ch_pun.un_dev = i + 128;
285
286 if (brd->bd_uart_offset == 0x200)
287 ch->ch_neo_uart = vaddr + (brd->bd_uart_offset * i);
288 else
289 ch->ch_cls_uart = vaddr + (brd->bd_uart_offset * i);
290
291 ch->ch_bd = brd;
292 ch->ch_portnum = i;
293 ch->ch_digi = dgnc_digi_init;
294
295
296 ch->ch_close_delay = 250;
297
298 init_waitqueue_head(&ch->ch_flags_wait);
299 init_waitqueue_head(&ch->ch_tun.un_flags_wait);
300 init_waitqueue_head(&ch->ch_pun.un_flags_wait);
301
302 {
303 struct device *classp;
304
305 classp = tty_register_device(brd->serial_driver, i,
306 &ch->ch_bd->pdev->dev);
307 ch->ch_tun.un_sysfs = classp;
308
309 classp = tty_register_device(brd->print_driver, i,
310 &ch->ch_bd->pdev->dev);
311 ch->ch_pun.un_sysfs = classp;
312 }
313 }
314
315 return 0;
316
317err_free_channels:
318 for (i = i - 1; i >= 0; --i) {
319 kfree(brd->channels[i]);
320 brd->channels[i] = NULL;
321 }
322 return -ENOMEM;
323}
324
325
326
327
328
329
330
331void dgnc_cleanup_tty(struct dgnc_board *brd)
332{
333 int i = 0;
334
335 for (i = 0; i < brd->nasync; i++)
336 tty_unregister_device(brd->serial_driver, i);
337
338 tty_unregister_driver(brd->serial_driver);
339
340 for (i = 0; i < brd->nasync; i++)
341 tty_unregister_device(brd->print_driver, i);
342
343 tty_unregister_driver(brd->print_driver);
344
345 put_tty_driver(brd->serial_driver);
346 put_tty_driver(brd->print_driver);
347}
348
349
350
351
352
353
354
355
356static void dgnc_wmove(struct channel_t *ch, char *buf, uint n)
357{
358 int remain;
359 uint head;
360
361 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
362 return;
363
364 head = ch->ch_w_head & WQUEUEMASK;
365
366
367
368
369
370
371 remain = WQUEUESIZE - head;
372
373 if (n >= remain) {
374 n -= remain;
375 memcpy(ch->ch_wqueue + head, buf, remain);
376 head = 0;
377 buf += remain;
378 }
379
380 if (n > 0) {
381
382 remain = n;
383 memcpy(ch->ch_wqueue + head, buf, remain);
384 head += remain;
385 }
386
387 head &= WQUEUEMASK;
388 ch->ch_w_head = head;
389}
390
391
392
393
394
395
396void dgnc_input(struct channel_t *ch)
397{
398 struct dgnc_board *bd;
399 struct tty_struct *tp;
400 struct tty_ldisc *ld = NULL;
401 uint rmask;
402 ushort head;
403 ushort tail;
404 int data_len;
405 unsigned long flags;
406 int flip_len;
407 int len = 0;
408 int n = 0;
409 int s = 0;
410 int i = 0;
411
412 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
413 return;
414
415 tp = ch->ch_tun.un_tty;
416
417 bd = ch->ch_bd;
418 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
419 return;
420
421 spin_lock_irqsave(&ch->ch_lock, flags);
422
423
424
425
426
427 rmask = RQUEUEMASK;
428 head = ch->ch_r_head & rmask;
429 tail = ch->ch_r_tail & rmask;
430 data_len = (head - tail) & rmask;
431
432 if (data_len == 0)
433 goto exit_unlock;
434
435
436
437
438
439 if (!tp || (tp->magic != TTY_MAGIC) ||
440 !(ch->ch_tun.un_flags & UN_ISOPEN) ||
441 !C_CREAD(tp) ||
442 (ch->ch_tun.un_flags & UN_CLOSING)) {
443 ch->ch_r_head = tail;
444
445
446 dgnc_check_queue_flow_control(ch);
447
448 goto exit_unlock;
449 }
450
451
452
453 if (ch->ch_flags & CH_FORCED_STOPI)
454 goto exit_unlock;
455
456 flip_len = TTY_FLIPBUF_SIZE;
457
458
459 len = min(data_len, flip_len);
460 len = min(len, (N_TTY_BUF_SIZE - 1));
461
462 ld = tty_ldisc_ref(tp);
463
464
465
466
467
468
469 if (!ld) {
470 len = 0;
471 } else {
472
473
474
475
476
477 if (!ld->ops->receive_buf) {
478 ch->ch_r_head = ch->ch_r_tail;
479 len = 0;
480 }
481 }
482
483 if (len <= 0)
484 goto exit_unlock;
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500 len = tty_buffer_request_room(tp->port, len);
501 n = len;
502
503
504
505
506
507
508 while (n) {
509 unsigned char *ch_pos = ch->ch_equeue + tail;
510
511 s = ((head >= tail) ? head : RQUEUESIZE) - tail;
512 s = min(s, n);
513
514 if (s <= 0)
515 break;
516
517
518
519
520
521
522
523 if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
524 for (i = 0; i < s; i++) {
525 unsigned char ch = *(ch_pos + i);
526 char flag = TTY_NORMAL;
527
528 if (ch & UART_LSR_BI)
529 flag = TTY_BREAK;
530 else if (ch & UART_LSR_PE)
531 flag = TTY_PARITY;
532 else if (ch & UART_LSR_FE)
533 flag = TTY_FRAME;
534
535 tty_insert_flip_char(tp->port, ch, flag);
536 }
537 } else {
538 tty_insert_flip_string(tp->port, ch_pos, s);
539 }
540
541 tail += s;
542 n -= s;
543
544 tail &= rmask;
545 }
546
547 ch->ch_r_tail = tail & rmask;
548 ch->ch_e_tail = tail & rmask;
549 dgnc_check_queue_flow_control(ch);
550 spin_unlock_irqrestore(&ch->ch_lock, flags);
551
552
553 tty_flip_buffer_push(tp->port);
554
555 if (ld)
556 tty_ldisc_deref(ld);
557 return;
558
559exit_unlock:
560 spin_unlock_irqrestore(&ch->ch_lock, flags);
561 if (ld)
562 tty_ldisc_deref(ld);
563}
564
565
566
567
568
569void dgnc_carrier(struct channel_t *ch)
570{
571 int virt_carrier = 0;
572 int phys_carrier = 0;
573
574 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
575 return;
576
577 if (ch->ch_mistat & UART_MSR_DCD)
578 phys_carrier = 1;
579
580 if (ch->ch_digi.digi_flags & DIGI_FORCEDCD)
581 virt_carrier = 1;
582
583 if (ch->ch_c_cflag & CLOCAL)
584 virt_carrier = 1;
585
586
587
588 if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
589
590
591
592
593 if (waitqueue_active(&ch->ch_flags_wait))
594 wake_up_interruptible(&ch->ch_flags_wait);
595 }
596
597
598
599 if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
600
601
602
603
604 if (waitqueue_active(&ch->ch_flags_wait))
605 wake_up_interruptible(&ch->ch_flags_wait);
606 }
607
608
609
610
611
612
613
614
615
616
617 if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0) &&
618 (phys_carrier == 0)) {
619
620
621
622
623
624
625
626
627
628
629
630
631 if (waitqueue_active(&ch->ch_flags_wait))
632 wake_up_interruptible(&ch->ch_flags_wait);
633
634 if (ch->ch_tun.un_open_count > 0)
635 tty_hangup(ch->ch_tun.un_tty);
636
637 if (ch->ch_pun.un_open_count > 0)
638 tty_hangup(ch->ch_pun.un_tty);
639 }
640
641
642
643 if (virt_carrier == 1)
644 ch->ch_flags |= CH_FCAR;
645 else
646 ch->ch_flags &= ~CH_FCAR;
647
648 if (phys_carrier == 1)
649 ch->ch_flags |= CH_CD;
650 else
651 ch->ch_flags &= ~CH_CD;
652}
653
654
655
656static void dgnc_set_custom_speed(struct channel_t *ch, uint newrate)
657{
658 int testdiv;
659 int testrate_high;
660 int testrate_low;
661 int deltahigh;
662 int deltalow;
663
664 if (newrate <= 0) {
665 ch->ch_custom_speed = 0;
666 return;
667 }
668
669
670
671
672
673
674 if (newrate && newrate < ((ch->ch_bd->bd_dividend / 0xFFFF) + 1))
675 newrate = (ch->ch_bd->bd_dividend / 0xFFFF) + 1;
676
677 if (newrate && newrate > ch->ch_bd->bd_dividend)
678 newrate = ch->ch_bd->bd_dividend;
679
680 if (newrate > 0) {
681 testdiv = ch->ch_bd->bd_dividend / newrate;
682
683
684
685
686
687
688
689
690 testrate_high = ch->ch_bd->bd_dividend / testdiv;
691 testrate_low = ch->ch_bd->bd_dividend / (testdiv + 1);
692
693
694
695
696
697 if (testrate_high != newrate) {
698
699
700
701
702 deltahigh = testrate_high - newrate;
703 deltalow = newrate - testrate_low;
704
705 if (deltahigh < deltalow)
706 newrate = testrate_high;
707 else
708 newrate = testrate_low;
709 }
710 }
711
712 ch->ch_custom_speed = newrate;
713}
714
715void dgnc_check_queue_flow_control(struct channel_t *ch)
716{
717 int qleft;
718
719
720 qleft = ch->ch_r_tail - ch->ch_r_head - 1;
721 if (qleft < 0)
722 qleft += RQUEUEMASK + 1;
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739 if (qleft < 256) {
740
741 if (ch->ch_digi.digi_flags & CTSPACE ||
742 ch->ch_c_cflag & CRTSCTS) {
743 if (!(ch->ch_flags & CH_RECEIVER_OFF)) {
744 ch->ch_bd->bd_ops->disable_receiver(ch);
745 ch->ch_flags |= (CH_RECEIVER_OFF);
746 }
747 }
748
749 else if (ch->ch_c_iflag & IXOFF) {
750 if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
751 ch->ch_bd->bd_ops->send_stop_character(ch);
752 ch->ch_stops_sent++;
753 }
754 }
755 }
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772 if (qleft > (RQUEUESIZE / 2)) {
773
774 if (ch->ch_digi.digi_flags & RTSPACE ||
775 ch->ch_c_cflag & CRTSCTS) {
776 if (ch->ch_flags & CH_RECEIVER_OFF) {
777 ch->ch_bd->bd_ops->enable_receiver(ch);
778 ch->ch_flags &= ~(CH_RECEIVER_OFF);
779 }
780 }
781
782 else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
783 ch->ch_stops_sent = 0;
784 ch->ch_bd->bd_ops->send_start_character(ch);
785 }
786 }
787}
788
789static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char sig)
790{
791 ch->ch_mostat &= ~(sig);
792 ch->ch_bd->bd_ops->assert_modem_signals(ch);
793}
794
795void dgnc_wakeup_writes(struct channel_t *ch)
796{
797 int qlen = 0;
798 unsigned long flags;
799
800 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
801 return;
802
803 spin_lock_irqsave(&ch->ch_lock, flags);
804
805
806
807 qlen = ch->ch_w_head - ch->ch_w_tail;
808 if (qlen < 0)
809 qlen += WQUEUESIZE;
810
811 if (qlen >= (WQUEUESIZE - 256)) {
812 spin_unlock_irqrestore(&ch->ch_lock, flags);
813 return;
814 }
815
816 if (ch->ch_tun.un_flags & UN_ISOPEN) {
817 tty_wakeup(ch->ch_tun.un_tty);
818
819
820
821
822
823 if (ch->ch_tun.un_flags & UN_EMPTY) {
824 if ((qlen == 0) &&
825 (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0)) {
826 ch->ch_tun.un_flags &= ~(UN_EMPTY);
827
828
829
830
831
832 if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
833 dgnc_set_signal_low(ch, UART_MCR_RTS);
834
835
836
837
838
839 if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)
840 dgnc_set_signal_low(ch, UART_MCR_DTR);
841 }
842 }
843
844 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
845 }
846
847 if (ch->ch_pun.un_flags & UN_ISOPEN) {
848 tty_wakeup(ch->ch_pun.un_tty);
849
850
851
852
853
854 if (ch->ch_pun.un_flags & UN_EMPTY) {
855 if ((qlen == 0) &&
856 (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0))
857 ch->ch_pun.un_flags &= ~(UN_EMPTY);
858 }
859
860 wake_up_interruptible(&ch->ch_pun.un_flags_wait);
861 }
862
863 spin_unlock_irqrestore(&ch->ch_lock, flags);
864}
865
866static struct dgnc_board *find_board_by_major(unsigned int major)
867{
868 int i;
869
870 for (i = 0; i < MAXBOARDS; i++) {
871 struct dgnc_board *brd = dgnc_board[i];
872
873 if (!brd)
874 return NULL;
875
876 if (major == brd->serial_driver->major ||
877 major == brd->print_driver->major)
878 return brd;
879 }
880
881 return NULL;
882}
883
884
885
886
887
888static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
889{
890 struct dgnc_board *brd;
891 struct channel_t *ch;
892 struct un_t *un;
893 uint major = 0;
894 uint minor = 0;
895 int rc = 0;
896 unsigned long flags;
897
898 rc = 0;
899
900 major = MAJOR(tty_devnum(tty));
901 minor = MINOR(tty_devnum(tty));
902
903 if (major > 255)
904 return -ENXIO;
905
906
907 brd = find_board_by_major(major);
908 if (!brd)
909 return -ENXIO;
910
911
912
913
914
915 rc = wait_event_interruptible(brd->state_wait,
916 (brd->state & BOARD_READY));
917
918 if (rc)
919 return rc;
920
921 spin_lock_irqsave(&brd->bd_lock, flags);
922
923
924 if (PORT_NUM(minor) >= brd->nasync) {
925 spin_unlock_irqrestore(&brd->bd_lock, flags);
926 return -ENXIO;
927 }
928
929 ch = brd->channels[PORT_NUM(minor)];
930 if (!ch) {
931 spin_unlock_irqrestore(&brd->bd_lock, flags);
932 return -ENXIO;
933 }
934
935
936 spin_unlock_irqrestore(&brd->bd_lock, flags);
937
938
939 spin_lock_irqsave(&ch->ch_lock, flags);
940
941
942 if (!IS_PRINT(minor)) {
943 un = &brd->channels[PORT_NUM(minor)]->ch_tun;
944 un->un_type = DGNC_SERIAL;
945 } else if (IS_PRINT(minor)) {
946 un = &brd->channels[PORT_NUM(minor)]->ch_pun;
947 un->un_type = DGNC_PRINT;
948 } else {
949 spin_unlock_irqrestore(&ch->ch_lock, flags);
950 return -ENXIO;
951 }
952
953
954
955
956
957
958 spin_unlock_irqrestore(&ch->ch_lock, flags);
959
960 rc = wait_event_interruptible(ch->ch_flags_wait,
961 ((ch->ch_flags & CH_OPENING) == 0));
962
963
964 if (rc)
965 return -EINTR;
966
967
968
969
970
971
972
973
974 rc = wait_event_interruptible(
975 ch->ch_flags_wait,
976 (((ch->ch_tun.un_flags |
977 ch->ch_pun.un_flags) & UN_CLOSING) == 0));
978
979
980 if (rc)
981 return -EINTR;
982
983 spin_lock_irqsave(&ch->ch_lock, flags);
984
985
986 tty->driver_data = un;
987
988
989
990 if (!(un->un_flags & UN_ISOPEN)) {
991
992 un->un_tty = tty;
993
994
995 }
996
997
998
999
1000
1001 ch->ch_flags |= (CH_OPENING);
1002
1003
1004 spin_unlock_irqrestore(&ch->ch_lock, flags);
1005
1006 if (!ch->ch_rqueue)
1007 ch->ch_rqueue = kzalloc(RQUEUESIZE, GFP_KERNEL);
1008 if (!ch->ch_equeue)
1009 ch->ch_equeue = kzalloc(EQUEUESIZE, GFP_KERNEL);
1010 if (!ch->ch_wqueue)
1011 ch->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL);
1012
1013 if (!ch->ch_rqueue || !ch->ch_equeue || !ch->ch_wqueue) {
1014 kfree(ch->ch_rqueue);
1015 kfree(ch->ch_equeue);
1016 kfree(ch->ch_wqueue);
1017
1018 return -ENOMEM;
1019 }
1020
1021 spin_lock_irqsave(&ch->ch_lock, flags);
1022
1023 ch->ch_flags &= ~(CH_OPENING);
1024 wake_up_interruptible(&ch->ch_flags_wait);
1025
1026
1027
1028 if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
1029
1030 ch->ch_r_head = 0;
1031 ch->ch_r_tail = 0;
1032 ch->ch_e_head = 0;
1033 ch->ch_e_tail = 0;
1034 ch->ch_w_head = 0;
1035 ch->ch_w_tail = 0;
1036
1037 brd->bd_ops->flush_uart_write(ch);
1038 brd->bd_ops->flush_uart_read(ch);
1039
1040 ch->ch_flags = 0;
1041 ch->ch_cached_lsr = 0;
1042 ch->ch_stop_sending_break = 0;
1043 ch->ch_stops_sent = 0;
1044
1045 ch->ch_c_cflag = tty->termios.c_cflag;
1046 ch->ch_c_iflag = tty->termios.c_iflag;
1047 ch->ch_c_oflag = tty->termios.c_oflag;
1048 ch->ch_c_lflag = tty->termios.c_lflag;
1049 ch->ch_startc = tty->termios.c_cc[VSTART];
1050 ch->ch_stopc = tty->termios.c_cc[VSTOP];
1051
1052
1053
1054
1055
1056 if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
1057 ch->ch_mostat |= (UART_MCR_RTS);
1058 if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
1059 ch->ch_mostat |= (UART_MCR_DTR);
1060
1061
1062 brd->bd_ops->uart_init(ch);
1063 }
1064
1065
1066
1067 brd->bd_ops->param(tty);
1068
1069 dgnc_carrier(ch);
1070
1071
1072
1073 spin_unlock_irqrestore(&ch->ch_lock, flags);
1074
1075 rc = dgnc_block_til_ready(tty, file, ch);
1076
1077
1078 spin_lock_irqsave(&ch->ch_lock, flags);
1079 ch->ch_open_count++;
1080 un->un_open_count++;
1081 un->un_flags |= (UN_ISOPEN);
1082 spin_unlock_irqrestore(&ch->ch_lock, flags);
1083
1084 return rc;
1085}
1086
1087
1088
1089
1090
1091
1092static int dgnc_block_til_ready(struct tty_struct *tty,
1093 struct file *file,
1094 struct channel_t *ch)
1095{
1096 int retval = 0;
1097 struct un_t *un = tty->driver_data;
1098 unsigned long flags;
1099 uint old_flags = 0;
1100 int sleep_on_un_flags = 0;
1101
1102 if (!file)
1103 return -ENXIO;
1104
1105 spin_lock_irqsave(&ch->ch_lock, flags);
1106
1107 ch->ch_wopen++;
1108
1109
1110 while (1) {
1111 sleep_on_un_flags = 0;
1112
1113
1114
1115
1116
1117 if (ch->ch_bd->state == BOARD_FAILED) {
1118 retval = -ENXIO;
1119 break;
1120 }
1121
1122
1123 if (tty_hung_up_p(file)) {
1124 retval = -EAGAIN;
1125 break;
1126 }
1127
1128
1129
1130
1131
1132
1133
1134
1135 if (!((ch->ch_tun.un_flags |
1136 ch->ch_pun.un_flags) &
1137 UN_CLOSING)) {
1138
1139
1140
1141
1142
1143
1144
1145 if (file->f_flags & O_NONBLOCK)
1146 break;
1147
1148 if (tty_io_error(tty)) {
1149 retval = -EIO;
1150 break;
1151 }
1152
1153 if (ch->ch_flags & CH_CD)
1154 break;
1155
1156 if (ch->ch_flags & CH_FCAR)
1157 break;
1158 } else {
1159 sleep_on_un_flags = 1;
1160 }
1161
1162
1163
1164
1165
1166
1167 if (signal_pending(current)) {
1168 retval = -ERESTARTSYS;
1169 break;
1170 }
1171
1172
1173
1174 if (sleep_on_un_flags)
1175 old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags;
1176 else
1177 old_flags = ch->ch_flags;
1178
1179
1180
1181
1182
1183
1184
1185 spin_unlock_irqrestore(&ch->ch_lock, flags);
1186
1187
1188
1189
1190
1191 if (sleep_on_un_flags)
1192 retval = wait_event_interruptible
1193 (un->un_flags_wait,
1194 (old_flags != (ch->ch_tun.un_flags |
1195 ch->ch_pun.un_flags)));
1196 else
1197 retval = wait_event_interruptible(
1198 ch->ch_flags_wait,
1199 (old_flags != ch->ch_flags));
1200
1201
1202
1203
1204
1205 spin_lock_irqsave(&ch->ch_lock, flags);
1206 }
1207
1208 ch->ch_wopen--;
1209
1210 spin_unlock_irqrestore(&ch->ch_lock, flags);
1211
1212 return retval;
1213}
1214
1215
1216
1217
1218
1219
1220static void dgnc_tty_hangup(struct tty_struct *tty)
1221{
1222 if (!tty || tty->magic != TTY_MAGIC)
1223 return;
1224
1225
1226 dgnc_tty_flush_buffer(tty);
1227}
1228
1229
1230
1231static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
1232{
1233 struct dgnc_board *bd;
1234 struct channel_t *ch;
1235 struct un_t *un;
1236 unsigned long flags;
1237
1238 if (!tty || tty->magic != TTY_MAGIC)
1239 return;
1240
1241 un = tty->driver_data;
1242 if (!un || un->magic != DGNC_UNIT_MAGIC)
1243 return;
1244
1245 ch = un->un_ch;
1246 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1247 return;
1248
1249 bd = ch->ch_bd;
1250 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
1251 return;
1252
1253 spin_lock_irqsave(&ch->ch_lock, flags);
1254
1255
1256
1257
1258
1259 if ((tty->count == 1) && (un->un_open_count != 1)) {
1260
1261
1262
1263
1264
1265
1266
1267 dev_dbg(tty->dev,
1268 "tty->count is 1, un open count is %d\n",
1269 un->un_open_count);
1270 un->un_open_count = 1;
1271 }
1272
1273 if (un->un_open_count)
1274 un->un_open_count--;
1275 else
1276 dev_dbg(tty->dev,
1277 "bad serial port open count of %d\n",
1278 un->un_open_count);
1279
1280 ch->ch_open_count--;
1281
1282 if (ch->ch_open_count && un->un_open_count) {
1283 spin_unlock_irqrestore(&ch->ch_lock, flags);
1284 return;
1285 }
1286
1287
1288 un->un_flags |= UN_CLOSING;
1289
1290 tty->closing = 1;
1291
1292
1293
1294
1295
1296 if ((ch->ch_open_count == 0) &&
1297 !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
1298 ch->ch_flags &= ~(CH_STOPI | CH_FORCED_STOPI);
1299
1300
1301
1302 if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
1303 dgnc_wmove(ch, ch->ch_digi.digi_offstr,
1304 (int)ch->ch_digi.digi_offlen);
1305 ch->ch_flags &= ~CH_PRON;
1306 }
1307
1308 spin_unlock_irqrestore(&ch->ch_lock, flags);
1309
1310
1311
1312 bd->bd_ops->drain(tty, 0);
1313
1314 dgnc_tty_flush_buffer(tty);
1315 tty_ldisc_flush(tty);
1316
1317 spin_lock_irqsave(&ch->ch_lock, flags);
1318
1319 tty->closing = 0;
1320
1321
1322
1323 if (ch->ch_c_cflag & HUPCL) {
1324
1325 ch->ch_mostat &= ~(UART_MCR_DTR | UART_MCR_RTS);
1326 bd->bd_ops->assert_modem_signals(ch);
1327
1328
1329
1330
1331
1332 if (ch->ch_close_delay) {
1333 spin_unlock_irqrestore(&ch->ch_lock,
1334 flags);
1335 dgnc_ms_sleep(ch->ch_close_delay);
1336 spin_lock_irqsave(&ch->ch_lock, flags);
1337 }
1338 }
1339
1340 ch->ch_old_baud = 0;
1341
1342
1343 ch->ch_bd->bd_ops->uart_off(ch);
1344 } else {
1345
1346
1347 if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
1348 dgnc_wmove(ch, ch->ch_digi.digi_offstr,
1349 (int)ch->ch_digi.digi_offlen);
1350 ch->ch_flags &= ~CH_PRON;
1351 }
1352 }
1353
1354 un->un_tty = NULL;
1355 un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);
1356
1357 wake_up_interruptible(&ch->ch_flags_wait);
1358 wake_up_interruptible(&un->un_flags_wait);
1359
1360 spin_unlock_irqrestore(&ch->ch_lock, flags);
1361}
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
1372{
1373 struct channel_t *ch = NULL;
1374 struct un_t *un = NULL;
1375 ushort thead;
1376 ushort ttail;
1377 uint tmask;
1378 uint chars = 0;
1379 unsigned long flags;
1380
1381 if (!tty)
1382 return 0;
1383
1384 un = tty->driver_data;
1385 if (!un || un->magic != DGNC_UNIT_MAGIC)
1386 return 0;
1387
1388 ch = un->un_ch;
1389 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1390 return 0;
1391
1392 spin_lock_irqsave(&ch->ch_lock, flags);
1393
1394 tmask = WQUEUEMASK;
1395 thead = ch->ch_w_head & tmask;
1396 ttail = ch->ch_w_tail & tmask;
1397
1398 spin_unlock_irqrestore(&ch->ch_lock, flags);
1399
1400 if (ttail == thead) {
1401 chars = 0;
1402 } else {
1403 if (thead >= ttail)
1404 chars = thead - ttail;
1405 else
1406 chars = thead - ttail + WQUEUESIZE;
1407 }
1408
1409 return chars;
1410}
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available)
1421{
1422 if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
1423 int cps_limit = 0;
1424 unsigned long current_time = jiffies;
1425 unsigned long buffer_time = current_time +
1426 (HZ * ch->ch_digi.digi_bufsize) /
1427 ch->ch_digi.digi_maxcps;
1428
1429 if (ch->ch_cpstime < current_time) {
1430
1431 ch->ch_cpstime = current_time;
1432 cps_limit = ch->ch_digi.digi_bufsize;
1433 } else if (ch->ch_cpstime < buffer_time) {
1434
1435 cps_limit = ((buffer_time - ch->ch_cpstime) *
1436 ch->ch_digi.digi_maxcps) / HZ;
1437 } else {
1438
1439 cps_limit = 0;
1440 }
1441
1442 bytes_available = min(cps_limit, bytes_available);
1443 }
1444
1445 return bytes_available;
1446}
1447
1448
1449
1450
1451
1452
1453static int dgnc_tty_write_room(struct tty_struct *tty)
1454{
1455 struct channel_t *ch = NULL;
1456 struct un_t *un = NULL;
1457 ushort head;
1458 ushort tail;
1459 ushort tmask;
1460 int ret = 0;
1461 unsigned long flags;
1462
1463 if (!tty)
1464 return 0;
1465
1466 un = tty->driver_data;
1467 if (!un || un->magic != DGNC_UNIT_MAGIC)
1468 return 0;
1469
1470 ch = un->un_ch;
1471 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1472 return 0;
1473
1474 spin_lock_irqsave(&ch->ch_lock, flags);
1475
1476 tmask = WQUEUEMASK;
1477 head = (ch->ch_w_head) & tmask;
1478 tail = (ch->ch_w_tail) & tmask;
1479
1480 ret = tail - head - 1;
1481 if (ret < 0)
1482 ret += WQUEUESIZE;
1483
1484
1485 if (un->un_type != DGNC_PRINT)
1486 ret = dgnc_maxcps_room(ch, ret);
1487
1488
1489
1490
1491
1492 if (un->un_type == DGNC_PRINT) {
1493 if (!(ch->ch_flags & CH_PRON))
1494 ret -= ch->ch_digi.digi_onlen;
1495 ret -= ch->ch_digi.digi_offlen;
1496 } else {
1497 if (ch->ch_flags & CH_PRON)
1498 ret -= ch->ch_digi.digi_offlen;
1499 }
1500
1501 if (ret < 0)
1502 ret = 0;
1503
1504 spin_unlock_irqrestore(&ch->ch_lock, flags);
1505
1506 return ret;
1507}
1508
1509
1510
1511
1512
1513
1514
1515
1516static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c)
1517{
1518
1519
1520 dgnc_tty_write(tty, &c, 1);
1521 return 1;
1522}
1523
1524
1525
1526
1527
1528
1529
1530static int dgnc_tty_write(struct tty_struct *tty,
1531 const unsigned char *buf, int count)
1532{
1533 struct channel_t *ch = NULL;
1534 struct un_t *un = NULL;
1535 int bufcount = 0, n = 0;
1536 unsigned long flags;
1537 ushort head;
1538 ushort tail;
1539 ushort tmask;
1540 uint remain;
1541
1542 if (!tty)
1543 return 0;
1544
1545 un = tty->driver_data;
1546 if (!un || un->magic != DGNC_UNIT_MAGIC)
1547 return 0;
1548
1549 ch = un->un_ch;
1550 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1551 return 0;
1552
1553 if (!count)
1554 return 0;
1555
1556
1557
1558
1559
1560
1561
1562 spin_lock_irqsave(&ch->ch_lock, flags);
1563
1564
1565 tmask = WQUEUEMASK;
1566 head = (ch->ch_w_head) & tmask;
1567 tail = (ch->ch_w_tail) & tmask;
1568
1569 bufcount = tail - head - 1;
1570 if (bufcount < 0)
1571 bufcount += WQUEUESIZE;
1572
1573
1574
1575
1576
1577 if (un->un_type != DGNC_PRINT)
1578 bufcount = dgnc_maxcps_room(ch, bufcount);
1579
1580
1581
1582
1583
1584 count = min(count, bufcount);
1585
1586
1587
1588 if (count <= 0)
1589 goto exit_retry;
1590
1591
1592
1593
1594
1595 if ((un->un_type == DGNC_PRINT) && !(ch->ch_flags & CH_PRON)) {
1596 dgnc_wmove(ch, ch->ch_digi.digi_onstr,
1597 (int)ch->ch_digi.digi_onlen);
1598 head = (ch->ch_w_head) & tmask;
1599 ch->ch_flags |= CH_PRON;
1600 }
1601
1602
1603
1604
1605
1606 if ((un->un_type != DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
1607 dgnc_wmove(ch, ch->ch_digi.digi_offstr,
1608 (int)ch->ch_digi.digi_offlen);
1609 head = (ch->ch_w_head) & tmask;
1610 ch->ch_flags &= ~CH_PRON;
1611 }
1612
1613 n = count;
1614
1615
1616
1617
1618
1619
1620 remain = WQUEUESIZE - head;
1621
1622 if (n >= remain) {
1623 n -= remain;
1624 memcpy(ch->ch_wqueue + head, buf, remain);
1625 head = 0;
1626 buf += remain;
1627 }
1628
1629 if (n > 0) {
1630
1631 remain = n;
1632 memcpy(ch->ch_wqueue + head, buf, remain);
1633 head += remain;
1634 }
1635
1636 if (count) {
1637 head &= tmask;
1638 ch->ch_w_head = head;
1639 }
1640
1641
1642 if ((un->un_type == DGNC_PRINT) && (ch->ch_digi.digi_maxcps > 0) &&
1643 (ch->ch_digi.digi_bufsize > 0)) {
1644 ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
1645 }
1646
1647 spin_unlock_irqrestore(&ch->ch_lock, flags);
1648
1649 if (count) {
1650
1651
1652
1653
1654 ch->ch_bd->bd_ops->copy_data_from_queue_to_uart(ch);
1655 }
1656
1657 return count;
1658
1659exit_retry:
1660
1661 spin_unlock_irqrestore(&ch->ch_lock, flags);
1662 return 0;
1663}
1664
1665
1666
1667static int dgnc_tty_tiocmget(struct tty_struct *tty)
1668{
1669 struct channel_t *ch;
1670 struct un_t *un;
1671 int result = -EIO;
1672 unsigned char mstat = 0;
1673 unsigned long flags;
1674
1675 if (!tty || tty->magic != TTY_MAGIC)
1676 return result;
1677
1678 un = tty->driver_data;
1679 if (!un || un->magic != DGNC_UNIT_MAGIC)
1680 return result;
1681
1682 ch = un->un_ch;
1683 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1684 return result;
1685
1686 spin_lock_irqsave(&ch->ch_lock, flags);
1687
1688 mstat = ch->ch_mostat | ch->ch_mistat;
1689
1690 spin_unlock_irqrestore(&ch->ch_lock, flags);
1691
1692 result = 0;
1693
1694 if (mstat & UART_MCR_DTR)
1695 result |= TIOCM_DTR;
1696 if (mstat & UART_MCR_RTS)
1697 result |= TIOCM_RTS;
1698 if (mstat & UART_MSR_CTS)
1699 result |= TIOCM_CTS;
1700 if (mstat & UART_MSR_DSR)
1701 result |= TIOCM_DSR;
1702 if (mstat & UART_MSR_RI)
1703 result |= TIOCM_RI;
1704 if (mstat & UART_MSR_DCD)
1705 result |= TIOCM_CD;
1706
1707 return result;
1708}
1709
1710
1711
1712
1713
1714
1715
1716static int dgnc_tty_tiocmset(struct tty_struct *tty,
1717 unsigned int set, unsigned int clear)
1718{
1719 struct dgnc_board *bd;
1720 struct channel_t *ch;
1721 struct un_t *un;
1722 int ret = -EIO;
1723 unsigned long flags;
1724
1725 if (!tty || tty->magic != TTY_MAGIC)
1726 return ret;
1727
1728 un = tty->driver_data;
1729 if (!un || un->magic != DGNC_UNIT_MAGIC)
1730 return ret;
1731
1732 ch = un->un_ch;
1733 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1734 return ret;
1735
1736 bd = ch->ch_bd;
1737 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
1738 return ret;
1739
1740 spin_lock_irqsave(&ch->ch_lock, flags);
1741
1742 if (set & TIOCM_RTS)
1743 ch->ch_mostat |= UART_MCR_RTS;
1744
1745 if (set & TIOCM_DTR)
1746 ch->ch_mostat |= UART_MCR_DTR;
1747
1748 if (clear & TIOCM_RTS)
1749 ch->ch_mostat &= ~(UART_MCR_RTS);
1750
1751 if (clear & TIOCM_DTR)
1752 ch->ch_mostat &= ~(UART_MCR_DTR);
1753
1754 ch->ch_bd->bd_ops->assert_modem_signals(ch);
1755
1756 spin_unlock_irqrestore(&ch->ch_lock, flags);
1757
1758 return 0;
1759}
1760
1761
1762
1763
1764
1765
1766static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
1767{
1768 struct dgnc_board *bd;
1769 struct channel_t *ch;
1770 struct un_t *un;
1771 int ret = -EIO;
1772 unsigned long flags;
1773
1774 if (!tty || tty->magic != TTY_MAGIC)
1775 return ret;
1776
1777 un = tty->driver_data;
1778 if (!un || un->magic != DGNC_UNIT_MAGIC)
1779 return ret;
1780
1781 ch = un->un_ch;
1782 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1783 return ret;
1784
1785 bd = ch->ch_bd;
1786 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
1787 return ret;
1788
1789 switch (msec) {
1790 case -1:
1791 msec = 0xFFFF;
1792 break;
1793 case 0:
1794 msec = 0;
1795 break;
1796 default:
1797 break;
1798 }
1799
1800 spin_lock_irqsave(&ch->ch_lock, flags);
1801
1802 ch->ch_bd->bd_ops->send_break(ch, msec);
1803
1804 spin_unlock_irqrestore(&ch->ch_lock, flags);
1805
1806 return 0;
1807}
1808
1809
1810
1811
1812
1813
1814static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1815{
1816 struct dgnc_board *bd;
1817 struct channel_t *ch;
1818 struct un_t *un;
1819
1820 if (!tty || tty->magic != TTY_MAGIC)
1821 return;
1822
1823 un = tty->driver_data;
1824 if (!un || un->magic != DGNC_UNIT_MAGIC)
1825 return;
1826
1827 ch = un->un_ch;
1828 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1829 return;
1830
1831 bd = ch->ch_bd;
1832 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
1833 return;
1834
1835 bd->bd_ops->drain(tty, 0);
1836}
1837
1838
1839
1840
1841
1842
1843static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
1844{
1845 struct dgnc_board *bd;
1846 struct channel_t *ch;
1847 struct un_t *un;
1848 unsigned long flags;
1849
1850 if (!tty || tty->magic != TTY_MAGIC)
1851 return;
1852
1853 un = tty->driver_data;
1854 if (!un || un->magic != DGNC_UNIT_MAGIC)
1855 return;
1856
1857 ch = un->un_ch;
1858 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1859 return;
1860
1861 bd = ch->ch_bd;
1862 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
1863 return;
1864
1865 dev_dbg(tty->dev, "dgnc_tty_send_xchar start\n");
1866
1867 spin_lock_irqsave(&ch->ch_lock, flags);
1868 bd->bd_ops->send_immediate_char(ch, c);
1869 spin_unlock_irqrestore(&ch->ch_lock, flags);
1870
1871 dev_dbg(tty->dev, "dgnc_tty_send_xchar finish\n");
1872}
1873
1874
1875
1876static inline int dgnc_get_mstat(struct channel_t *ch)
1877{
1878 unsigned char mstat;
1879 int result = 0;
1880 unsigned long flags;
1881
1882 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1883 return -ENXIO;
1884
1885 spin_lock_irqsave(&ch->ch_lock, flags);
1886
1887 mstat = ch->ch_mostat | ch->ch_mistat;
1888
1889 spin_unlock_irqrestore(&ch->ch_lock, flags);
1890
1891 if (mstat & UART_MCR_DTR)
1892 result |= TIOCM_DTR;
1893 if (mstat & UART_MCR_RTS)
1894 result |= TIOCM_RTS;
1895 if (mstat & UART_MSR_CTS)
1896 result |= TIOCM_CTS;
1897 if (mstat & UART_MSR_DSR)
1898 result |= TIOCM_DSR;
1899 if (mstat & UART_MSR_RI)
1900 result |= TIOCM_RI;
1901 if (mstat & UART_MSR_DCD)
1902 result |= TIOCM_CD;
1903
1904 return result;
1905}
1906
1907
1908
1909static int dgnc_get_modem_info(struct channel_t *ch,
1910 unsigned int __user *value)
1911{
1912 return put_user(dgnc_get_mstat(ch), value);
1913}
1914
1915
1916
1917
1918
1919
1920static int dgnc_set_modem_info(struct channel_t *ch,
1921 unsigned int command,
1922 unsigned int __user *value)
1923{
1924 int ret = -ENXIO;
1925 unsigned int arg = 0;
1926 unsigned long flags;
1927
1928 ret = get_user(arg, value);
1929 if (ret)
1930 return ret;
1931
1932 switch (command) {
1933 case TIOCMBIS:
1934 if (arg & TIOCM_RTS)
1935 ch->ch_mostat |= UART_MCR_RTS;
1936
1937 if (arg & TIOCM_DTR)
1938 ch->ch_mostat |= UART_MCR_DTR;
1939
1940 break;
1941
1942 case TIOCMBIC:
1943 if (arg & TIOCM_RTS)
1944 ch->ch_mostat &= ~(UART_MCR_RTS);
1945
1946 if (arg & TIOCM_DTR)
1947 ch->ch_mostat &= ~(UART_MCR_DTR);
1948
1949 break;
1950
1951 case TIOCMSET:
1952
1953 if (arg & TIOCM_RTS)
1954 ch->ch_mostat |= UART_MCR_RTS;
1955 else
1956 ch->ch_mostat &= ~(UART_MCR_RTS);
1957
1958 if (arg & TIOCM_DTR)
1959 ch->ch_mostat |= UART_MCR_DTR;
1960 else
1961 ch->ch_mostat &= ~(UART_MCR_DTR);
1962
1963 break;
1964
1965 default:
1966 return -EINVAL;
1967 }
1968
1969 spin_lock_irqsave(&ch->ch_lock, flags);
1970
1971 ch->ch_bd->bd_ops->assert_modem_signals(ch);
1972
1973 spin_unlock_irqrestore(&ch->ch_lock, flags);
1974
1975 return 0;
1976}
1977
1978
1979
1980
1981
1982
1983static int dgnc_tty_digigeta(struct tty_struct *tty,
1984 struct digi_t __user *retinfo)
1985{
1986 struct channel_t *ch;
1987 struct un_t *un;
1988 struct digi_t tmp;
1989 unsigned long flags;
1990
1991 if (!retinfo)
1992 return -EFAULT;
1993
1994 if (!tty || tty->magic != TTY_MAGIC)
1995 return -EFAULT;
1996
1997 un = tty->driver_data;
1998 if (!un || un->magic != DGNC_UNIT_MAGIC)
1999 return -EFAULT;
2000
2001 ch = un->un_ch;
2002 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2003 return -EFAULT;
2004
2005 memset(&tmp, 0, sizeof(tmp));
2006
2007 spin_lock_irqsave(&ch->ch_lock, flags);
2008 memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
2009 spin_unlock_irqrestore(&ch->ch_lock, flags);
2010
2011 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2012 return -EFAULT;
2013
2014 return 0;
2015}
2016
2017
2018
2019
2020
2021
2022static int dgnc_tty_digiseta(struct tty_struct *tty,
2023 struct digi_t __user *new_info)
2024{
2025 struct dgnc_board *bd;
2026 struct channel_t *ch;
2027 struct un_t *un;
2028 struct digi_t new_digi;
2029 unsigned long flags;
2030
2031 if (!tty || tty->magic != TTY_MAGIC)
2032 return -EFAULT;
2033
2034 un = tty->driver_data;
2035 if (!un || un->magic != DGNC_UNIT_MAGIC)
2036 return -EFAULT;
2037
2038 ch = un->un_ch;
2039 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2040 return -EFAULT;
2041
2042 bd = ch->ch_bd;
2043 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2044 return -EFAULT;
2045
2046 if (copy_from_user(&new_digi, new_info, sizeof(new_digi)))
2047 return -EFAULT;
2048
2049 spin_lock_irqsave(&ch->ch_lock, flags);
2050
2051
2052
2053 if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) &&
2054 (new_digi.digi_flags & DIGI_RTS_TOGGLE))
2055 ch->ch_mostat &= ~(UART_MCR_RTS);
2056 if ((ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) &&
2057 !(new_digi.digi_flags & DIGI_RTS_TOGGLE))
2058 ch->ch_mostat |= (UART_MCR_RTS);
2059
2060
2061
2062 if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) &&
2063 (new_digi.digi_flags & DIGI_DTR_TOGGLE))
2064 ch->ch_mostat &= ~(UART_MCR_DTR);
2065 if ((ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) &&
2066 !(new_digi.digi_flags & DIGI_DTR_TOGGLE))
2067 ch->ch_mostat |= (UART_MCR_DTR);
2068
2069 memcpy(&ch->ch_digi, &new_digi, sizeof(new_digi));
2070
2071 if (ch->ch_digi.digi_maxcps < 1)
2072 ch->ch_digi.digi_maxcps = 1;
2073
2074 if (ch->ch_digi.digi_maxcps > 10000)
2075 ch->ch_digi.digi_maxcps = 10000;
2076
2077 if (ch->ch_digi.digi_bufsize < 10)
2078 ch->ch_digi.digi_bufsize = 10;
2079
2080 if (ch->ch_digi.digi_maxchar < 1)
2081 ch->ch_digi.digi_maxchar = 1;
2082
2083 if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
2084 ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
2085
2086 if (ch->ch_digi.digi_onlen > DIGI_PLEN)
2087 ch->ch_digi.digi_onlen = DIGI_PLEN;
2088
2089 if (ch->ch_digi.digi_offlen > DIGI_PLEN)
2090 ch->ch_digi.digi_offlen = DIGI_PLEN;
2091
2092 ch->ch_bd->bd_ops->param(tty);
2093
2094 spin_unlock_irqrestore(&ch->ch_lock, flags);
2095
2096 return 0;
2097}
2098
2099
2100
2101static void dgnc_tty_set_termios(struct tty_struct *tty,
2102 struct ktermios *old_termios)
2103{
2104 struct dgnc_board *bd;
2105 struct channel_t *ch;
2106 struct un_t *un;
2107 unsigned long flags;
2108
2109 if (!tty || tty->magic != TTY_MAGIC)
2110 return;
2111
2112 un = tty->driver_data;
2113 if (!un || un->magic != DGNC_UNIT_MAGIC)
2114 return;
2115
2116 ch = un->un_ch;
2117 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2118 return;
2119
2120 bd = ch->ch_bd;
2121 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2122 return;
2123
2124 spin_lock_irqsave(&ch->ch_lock, flags);
2125
2126 ch->ch_c_cflag = tty->termios.c_cflag;
2127 ch->ch_c_iflag = tty->termios.c_iflag;
2128 ch->ch_c_oflag = tty->termios.c_oflag;
2129 ch->ch_c_lflag = tty->termios.c_lflag;
2130 ch->ch_startc = tty->termios.c_cc[VSTART];
2131 ch->ch_stopc = tty->termios.c_cc[VSTOP];
2132
2133 ch->ch_bd->bd_ops->param(tty);
2134 dgnc_carrier(ch);
2135
2136 spin_unlock_irqrestore(&ch->ch_lock, flags);
2137}
2138
2139static void dgnc_tty_throttle(struct tty_struct *tty)
2140{
2141 struct channel_t *ch;
2142 struct un_t *un;
2143 unsigned long flags;
2144
2145 if (!tty || tty->magic != TTY_MAGIC)
2146 return;
2147
2148 un = tty->driver_data;
2149 if (!un || un->magic != DGNC_UNIT_MAGIC)
2150 return;
2151
2152 ch = un->un_ch;
2153 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2154 return;
2155
2156 spin_lock_irqsave(&ch->ch_lock, flags);
2157
2158 ch->ch_flags |= (CH_FORCED_STOPI);
2159
2160 spin_unlock_irqrestore(&ch->ch_lock, flags);
2161}
2162
2163static void dgnc_tty_unthrottle(struct tty_struct *tty)
2164{
2165 struct channel_t *ch;
2166 struct un_t *un;
2167 unsigned long flags;
2168
2169 if (!tty || tty->magic != TTY_MAGIC)
2170 return;
2171
2172 un = tty->driver_data;
2173 if (!un || un->magic != DGNC_UNIT_MAGIC)
2174 return;
2175
2176 ch = un->un_ch;
2177 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2178 return;
2179
2180 spin_lock_irqsave(&ch->ch_lock, flags);
2181
2182 ch->ch_flags &= ~(CH_FORCED_STOPI);
2183
2184 spin_unlock_irqrestore(&ch->ch_lock, flags);
2185}
2186
2187static void dgnc_tty_start(struct tty_struct *tty)
2188{
2189 struct dgnc_board *bd;
2190 struct channel_t *ch;
2191 struct un_t *un;
2192 unsigned long flags;
2193
2194 if (!tty || tty->magic != TTY_MAGIC)
2195 return;
2196
2197 un = tty->driver_data;
2198 if (!un || un->magic != DGNC_UNIT_MAGIC)
2199 return;
2200
2201 ch = un->un_ch;
2202 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2203 return;
2204
2205 bd = ch->ch_bd;
2206 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2207 return;
2208
2209 spin_lock_irqsave(&ch->ch_lock, flags);
2210
2211 ch->ch_flags &= ~(CH_FORCED_STOP);
2212
2213 spin_unlock_irqrestore(&ch->ch_lock, flags);
2214}
2215
2216static void dgnc_tty_stop(struct tty_struct *tty)
2217{
2218 struct dgnc_board *bd;
2219 struct channel_t *ch;
2220 struct un_t *un;
2221 unsigned long flags;
2222
2223 if (!tty || tty->magic != TTY_MAGIC)
2224 return;
2225
2226 un = tty->driver_data;
2227 if (!un || un->magic != DGNC_UNIT_MAGIC)
2228 return;
2229
2230 ch = un->un_ch;
2231 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2232 return;
2233
2234 bd = ch->ch_bd;
2235 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2236 return;
2237
2238 spin_lock_irqsave(&ch->ch_lock, flags);
2239
2240 ch->ch_flags |= (CH_FORCED_STOP);
2241
2242 spin_unlock_irqrestore(&ch->ch_lock, flags);
2243}
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258static void dgnc_tty_flush_chars(struct tty_struct *tty)
2259{
2260 struct dgnc_board *bd;
2261 struct channel_t *ch;
2262 struct un_t *un;
2263 unsigned long flags;
2264
2265 if (!tty || tty->magic != TTY_MAGIC)
2266 return;
2267
2268 un = tty->driver_data;
2269 if (!un || un->magic != DGNC_UNIT_MAGIC)
2270 return;
2271
2272 ch = un->un_ch;
2273 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2274 return;
2275
2276 bd = ch->ch_bd;
2277 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2278 return;
2279
2280 spin_lock_irqsave(&ch->ch_lock, flags);
2281
2282
2283
2284 spin_unlock_irqrestore(&ch->ch_lock, flags);
2285}
2286
2287
2288
2289
2290
2291
2292static void dgnc_tty_flush_buffer(struct tty_struct *tty)
2293{
2294 struct channel_t *ch;
2295 struct un_t *un;
2296 unsigned long flags;
2297
2298 if (!tty || tty->magic != TTY_MAGIC)
2299 return;
2300
2301 un = tty->driver_data;
2302 if (!un || un->magic != DGNC_UNIT_MAGIC)
2303 return;
2304
2305 ch = un->un_ch;
2306 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2307 return;
2308
2309 spin_lock_irqsave(&ch->ch_lock, flags);
2310
2311 ch->ch_flags &= ~CH_STOP;
2312
2313
2314 ch->ch_w_head = ch->ch_w_tail;
2315
2316
2317 ch->ch_bd->bd_ops->flush_uart_write(ch);
2318
2319 if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) {
2320 ch->ch_tun.un_flags &= ~(UN_LOW | UN_EMPTY);
2321 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
2322 }
2323 if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY)) {
2324 ch->ch_pun.un_flags &= ~(UN_LOW | UN_EMPTY);
2325 wake_up_interruptible(&ch->ch_pun.un_flags_wait);
2326 }
2327
2328 spin_unlock_irqrestore(&ch->ch_lock, flags);
2329}
2330
2331
2332
2333
2334
2335
2336static void dgnc_wake_up_unit(struct un_t *unit)
2337{
2338 unit->un_flags &= ~(UN_LOW | UN_EMPTY);
2339 wake_up_interruptible(&unit->un_flags_wait);
2340}
2341
2342
2343
2344
2345
2346
2347
2348
2349static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
2350 unsigned long arg)
2351{
2352 struct dgnc_board *bd;
2353 struct board_ops *ch_bd_ops;
2354 struct channel_t *ch;
2355 struct un_t *un;
2356 int rc;
2357 unsigned long flags;
2358 void __user *uarg = (void __user *)arg;
2359
2360 if (!tty || tty->magic != TTY_MAGIC)
2361 return -ENODEV;
2362
2363 un = tty->driver_data;
2364 if (!un || un->magic != DGNC_UNIT_MAGIC)
2365 return -ENODEV;
2366
2367 ch = un->un_ch;
2368 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2369 return -ENODEV;
2370
2371 bd = ch->ch_bd;
2372 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2373 return -ENODEV;
2374
2375 ch_bd_ops = bd->bd_ops;
2376
2377 spin_lock_irqsave(&ch->ch_lock, flags);
2378
2379 if (un->un_open_count <= 0) {
2380 spin_unlock_irqrestore(&ch->ch_lock, flags);
2381 return -EIO;
2382 }
2383
2384 switch (cmd) {
2385
2386
2387 case TCSBRK:
2388
2389
2390
2391
2392
2393
2394
2395
2396 rc = tty_check_change(tty);
2397 spin_unlock_irqrestore(&ch->ch_lock, flags);
2398 if (rc)
2399 return rc;
2400
2401 rc = ch_bd_ops->drain(tty, 0);
2402
2403 if (rc)
2404 return -EINTR;
2405
2406 spin_lock_irqsave(&ch->ch_lock, flags);
2407
2408 if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP))
2409 ch_bd_ops->send_break(ch, 250);
2410
2411 spin_unlock_irqrestore(&ch->ch_lock, flags);
2412
2413 return 0;
2414
2415 case TCSBRKP:
2416
2417
2418
2419
2420
2421
2422 rc = tty_check_change(tty);
2423 spin_unlock_irqrestore(&ch->ch_lock, flags);
2424 if (rc)
2425 return rc;
2426
2427 rc = ch_bd_ops->drain(tty, 0);
2428 if (rc)
2429 return -EINTR;
2430
2431 spin_lock_irqsave(&ch->ch_lock, flags);
2432
2433 ch_bd_ops->send_break(ch, 250);
2434
2435 spin_unlock_irqrestore(&ch->ch_lock, flags);
2436
2437 return 0;
2438
2439 case TIOCSBRK:
2440 rc = tty_check_change(tty);
2441 spin_unlock_irqrestore(&ch->ch_lock, flags);
2442 if (rc)
2443 return rc;
2444
2445 rc = ch_bd_ops->drain(tty, 0);
2446 if (rc)
2447 return -EINTR;
2448
2449 spin_lock_irqsave(&ch->ch_lock, flags);
2450
2451 ch_bd_ops->send_break(ch, 250);
2452
2453 spin_unlock_irqrestore(&ch->ch_lock, flags);
2454
2455 return 0;
2456
2457 case TIOCCBRK:
2458
2459 spin_unlock_irqrestore(&ch->ch_lock, flags);
2460 return 0;
2461
2462 case TIOCGSOFTCAR:
2463
2464 spin_unlock_irqrestore(&ch->ch_lock, flags);
2465
2466 return put_user(C_CLOCAL(tty) ? 1 : 0,
2467 (unsigned long __user *)arg);
2468
2469 case TIOCSSOFTCAR:
2470
2471 spin_unlock_irqrestore(&ch->ch_lock, flags);
2472 rc = get_user(arg, (unsigned long __user *)arg);
2473 if (rc)
2474 return rc;
2475
2476 spin_lock_irqsave(&ch->ch_lock, flags);
2477 tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) |
2478 (arg ? CLOCAL : 0));
2479 ch_bd_ops->param(tty);
2480 spin_unlock_irqrestore(&ch->ch_lock, flags);
2481
2482 return 0;
2483
2484 case TIOCMGET:
2485 spin_unlock_irqrestore(&ch->ch_lock, flags);
2486 return dgnc_get_modem_info(ch, uarg);
2487
2488 case TIOCMBIS:
2489 case TIOCMBIC:
2490 case TIOCMSET:
2491 spin_unlock_irqrestore(&ch->ch_lock, flags);
2492 return dgnc_set_modem_info(ch, cmd, uarg);
2493
2494
2495
2496 case TCFLSH:
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506 rc = tty_check_change(tty);
2507 if (rc) {
2508 spin_unlock_irqrestore(&ch->ch_lock, flags);
2509 return rc;
2510 }
2511
2512 if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
2513 ch->ch_r_head = ch->ch_r_tail;
2514 ch_bd_ops->flush_uart_read(ch);
2515
2516 dgnc_check_queue_flow_control(ch);
2517 }
2518
2519 if ((arg == TCOFLUSH) || (arg == TCIOFLUSH)) {
2520 if (!(un->un_type == DGNC_PRINT)) {
2521 ch->ch_w_head = ch->ch_w_tail;
2522 ch_bd_ops->flush_uart_write(ch);
2523
2524 if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY))
2525 dgnc_wake_up_unit(&ch->ch_tun);
2526
2527 if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY))
2528 dgnc_wake_up_unit(&ch->ch_pun);
2529 }
2530 }
2531
2532
2533 spin_unlock_irqrestore(&ch->ch_lock, flags);
2534 return -ENOIOCTLCMD;
2535 case TCSETSF:
2536 case TCSETSW:
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546 if (cmd == TCSETSF) {
2547
2548 ch->ch_flags &= ~CH_STOP;
2549 ch->ch_r_head = ch->ch_r_tail;
2550 ch_bd_ops->flush_uart_read(ch);
2551
2552 dgnc_check_queue_flow_control(ch);
2553 }
2554
2555
2556 spin_unlock_irqrestore(&ch->ch_lock, flags);
2557 rc = ch_bd_ops->drain(tty, 0);
2558 if (rc)
2559 return -EINTR;
2560
2561
2562 return -ENOIOCTLCMD;
2563
2564 case TCSETAW:
2565
2566 spin_unlock_irqrestore(&ch->ch_lock, flags);
2567 rc = ch_bd_ops->drain(tty, 0);
2568 if (rc)
2569 return -EINTR;
2570
2571
2572 return -ENOIOCTLCMD;
2573
2574 case TCXONC:
2575 spin_unlock_irqrestore(&ch->ch_lock, flags);
2576
2577 return -ENOIOCTLCMD;
2578
2579 case DIGI_GETA:
2580
2581 spin_unlock_irqrestore(&ch->ch_lock, flags);
2582 return dgnc_tty_digigeta(tty, uarg);
2583
2584 case DIGI_SETAW:
2585 case DIGI_SETAF:
2586
2587
2588 if (cmd == (DIGI_SETAW)) {
2589 spin_unlock_irqrestore(&ch->ch_lock, flags);
2590 rc = ch_bd_ops->drain(tty, 0);
2591
2592 if (rc)
2593 return -EINTR;
2594
2595 spin_lock_irqsave(&ch->ch_lock, flags);
2596 } else {
2597 tty_ldisc_flush(tty);
2598 }
2599
2600
2601 case DIGI_SETA:
2602 spin_unlock_irqrestore(&ch->ch_lock, flags);
2603 return dgnc_tty_digiseta(tty, uarg);
2604
2605 case DIGI_LOOPBACK:
2606 {
2607 uint loopback = 0;
2608
2609
2610
2611
2612 spin_unlock_irqrestore(&ch->ch_lock, flags);
2613 rc = get_user(loopback, (unsigned int __user *)arg);
2614 if (rc)
2615 return rc;
2616 spin_lock_irqsave(&ch->ch_lock, flags);
2617
2618
2619 if (loopback)
2620 ch->ch_flags |= CH_LOOPBACK;
2621 else
2622 ch->ch_flags &= ~(CH_LOOPBACK);
2623
2624 ch_bd_ops->param(tty);
2625 spin_unlock_irqrestore(&ch->ch_lock, flags);
2626 return 0;
2627 }
2628
2629 case DIGI_GETCUSTOMBAUD:
2630 spin_unlock_irqrestore(&ch->ch_lock, flags);
2631 return put_user(ch->ch_custom_speed,
2632 (unsigned int __user *)arg);
2633
2634 case DIGI_SETCUSTOMBAUD:
2635 {
2636 int new_rate;
2637
2638 spin_unlock_irqrestore(&ch->ch_lock, flags);
2639 rc = get_user(new_rate, (int __user *)arg);
2640 if (rc)
2641 return rc;
2642 spin_lock_irqsave(&ch->ch_lock, flags);
2643 dgnc_set_custom_speed(ch, new_rate);
2644 ch_bd_ops->param(tty);
2645 spin_unlock_irqrestore(&ch->ch_lock, flags);
2646 return 0;
2647 }
2648
2649
2650
2651
2652
2653
2654
2655
2656 case DIGI_REALPORT_SENDIMMEDIATE:
2657 {
2658 unsigned char c;
2659
2660 spin_unlock_irqrestore(&ch->ch_lock, flags);
2661 rc = get_user(c, (unsigned char __user *)arg);
2662 if (rc)
2663 return rc;
2664 spin_lock_irqsave(&ch->ch_lock, flags);
2665 ch_bd_ops->send_immediate_char(ch, c);
2666 spin_unlock_irqrestore(&ch->ch_lock, flags);
2667 return 0;
2668 }
2669
2670
2671
2672
2673
2674
2675
2676 case DIGI_REALPORT_GETCOUNTERS:
2677 {
2678 struct digi_getcounter buf;
2679
2680 buf.norun = ch->ch_err_overrun;
2681 buf.noflow = 0;
2682 buf.nframe = ch->ch_err_frame;
2683 buf.nparity = ch->ch_err_parity;
2684 buf.nbreak = ch->ch_err_break;
2685 buf.rbytes = ch->ch_rxcount;
2686 buf.tbytes = ch->ch_txcount;
2687
2688 spin_unlock_irqrestore(&ch->ch_lock, flags);
2689
2690 if (copy_to_user(uarg, &buf, sizeof(buf)))
2691 return -EFAULT;
2692
2693 return 0;
2694 }
2695
2696
2697
2698
2699
2700
2701
2702 case DIGI_REALPORT_GETEVENTS:
2703 {
2704 unsigned int events = 0;
2705
2706
2707 if (ch->ch_flags & CH_BREAK_SENDING)
2708 events |= EV_TXB;
2709 if ((ch->ch_flags & CH_STOP) ||
2710 (ch->ch_flags & CH_FORCED_STOP))
2711 events |= (EV_OPU | EV_OPS);
2712
2713 if ((ch->ch_flags & CH_STOPI) ||
2714 (ch->ch_flags & CH_FORCED_STOPI))
2715 events |= (EV_IPU | EV_IPS);
2716
2717 spin_unlock_irqrestore(&ch->ch_lock, flags);
2718 return put_user(events, (unsigned int __user *)arg);
2719 }
2720
2721
2722
2723
2724
2725
2726
2727 case DIGI_REALPORT_GETBUFFERS:
2728 {
2729 struct digi_getbuffer buf;
2730 int tdist;
2731 int count;
2732
2733 spin_unlock_irqrestore(&ch->ch_lock, flags);
2734
2735
2736
2737 if (copy_from_user(&buf, uarg, sizeof(buf)))
2738 return -EFAULT;
2739
2740 spin_lock_irqsave(&ch->ch_lock, flags);
2741
2742
2743
2744 buf.rxbuf = (ch->ch_r_head - ch->ch_r_tail) & RQUEUEMASK;
2745 buf.txbuf = (ch->ch_w_head - ch->ch_w_tail) & WQUEUEMASK;
2746
2747
2748
2749
2750
2751
2752 count = buf.txbuf + ch_bd_ops->get_uart_bytes_left(ch);
2753
2754
2755
2756
2757
2758 tdist = (buf.tx_in - buf.tx_out) & 0xffff;
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768 if (buf.txbuf > tdist)
2769 buf.txbuf = tdist;
2770
2771
2772
2773 if (count)
2774 buf.txdone = 0;
2775 else
2776 buf.txdone = 1;
2777
2778 spin_unlock_irqrestore(&ch->ch_lock, flags);
2779
2780 if (copy_to_user(uarg, &buf, sizeof(buf)))
2781 return -EFAULT;
2782
2783 return 0;
2784 }
2785 default:
2786 spin_unlock_irqrestore(&ch->ch_lock, flags);
2787
2788 return -ENOIOCTLCMD;
2789 }
2790}
2791