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