1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <linux/config.h>
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/init.h>
36#include <linux/serial.h>
37#include <linux/delay.h>
38#include <linux/ctype.h>
39#include <linux/tty.h>
40#include <linux/tty_flip.h>
41#include <linux/slab.h>
42#include <linux/ioport.h>
43#include <asm/uaccess.h>
44#include <asm/io.h>
45
46#ifdef CONFIG_PCI
47#define ENABLE_PCI
48#endif
49
50#define putUser(arg1, arg2) put_user(arg1, (unsigned long *)arg2)
51#define getUser(arg1, arg2) get_user(arg1, (unsigned int *)arg2)
52
53#ifdef ENABLE_PCI
54#include <linux/pci.h>
55#include "digiPCI.h"
56#endif
57
58#include "digi1.h"
59#include "digiFep1.h"
60#include "epca.h"
61#include "epcaconfig.h"
62
63#if BITS_PER_LONG != 32
64# error FIXME: this driver only works on 32-bit platforms
65#endif
66
67
68
69#define VERSION "1.3.0.1-LK"
70
71
72
73#define DIGIINFOMAJOR 35
74
75
76#define MIN(a,b) ((a) < (b) ? (a) : (b))
77#define MAXCARDS 7
78#define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg)
79
80#define PFX "epca: "
81
82
83
84static char mesg[100];
85static int pc_refcount, nbdevs, num_cards, liloconfig;
86static int digi_poller_inhibited = 1 ;
87
88static int setup_error_code;
89static int invalid_lilo_config;
90
91
92
93
94
95static struct board_info boards[MAXBOARDS];
96
97
98
99
100struct tty_driver pc_driver;
101struct tty_driver pc_callout;
102struct tty_driver pc_info;
103
104
105
106
107
108
109
110static struct tty_struct *pc_table[MAX_ALLOC];
111static struct termios *pc_termios[MAX_ALLOC];
112static struct termios *pc_termios_locked[MAX_ALLOC];
113
114
115
116
117
118
119
120
121
122
123
124
125static struct channel digi_channels[MAX_ALLOC];
126
127
128
129
130
131
132static struct channel *card_ptr[MAXCARDS];
133
134static struct timer_list epca_timer;
135
136
137
138
139
140
141
142
143
144
145#ifdef MODULE
146int init_module(void);
147void cleanup_module(void);
148#endif
149
150static inline void memwinon(struct board_info *b, unsigned int win);
151static inline void memwinoff(struct board_info *b, unsigned int win);
152static inline void globalwinon(struct channel *ch);
153static inline void rxwinon(struct channel *ch);
154static inline void txwinon(struct channel *ch);
155static inline void memoff(struct channel *ch);
156static inline void assertgwinon(struct channel *ch);
157static inline void assertmemoff(struct channel *ch);
158
159
160
161static inline void pcxem_memwinon(struct board_info *b, unsigned int win);
162static inline void pcxem_memwinoff(struct board_info *b, unsigned int win);
163static inline void pcxem_globalwinon(struct channel *ch);
164static inline void pcxem_rxwinon(struct channel *ch);
165static inline void pcxem_txwinon(struct channel *ch);
166static inline void pcxem_memoff(struct channel *ch);
167
168
169
170static inline void pcxe_memwinon(struct board_info *b, unsigned int win);
171static inline void pcxe_memwinoff(struct board_info *b, unsigned int win);
172static inline void pcxe_globalwinon(struct channel *ch);
173static inline void pcxe_rxwinon(struct channel *ch);
174static inline void pcxe_txwinon(struct channel *ch);
175static inline void pcxe_memoff(struct channel *ch);
176
177
178
179
180static inline void pcxi_memwinon(struct board_info *b, unsigned int win);
181static inline void pcxi_memwinoff(struct board_info *b, unsigned int win);
182static inline void pcxi_globalwinon(struct channel *ch);
183static inline void pcxi_rxwinon(struct channel *ch);
184static inline void pcxi_txwinon(struct channel *ch);
185static inline void pcxi_memoff(struct channel *ch);
186
187
188
189static inline void dummy_memwinon(struct board_info *b, unsigned int win);
190static inline void dummy_memwinoff(struct board_info *b, unsigned int win);
191static inline void dummy_globalwinon(struct channel *ch);
192static inline void dummy_rxwinon(struct channel *ch);
193static inline void dummy_txwinon(struct channel *ch);
194static inline void dummy_memoff(struct channel *ch);
195static inline void dummy_assertgwinon(struct channel *ch);
196static inline void dummy_assertmemoff(struct channel *ch);
197
198
199
200static inline struct channel *verifyChannel(register struct tty_struct *);
201static inline void pc_sched_event(struct channel *, int);
202static void epca_error(int, char *);
203static void pc_close(struct tty_struct *, struct file *);
204static void shutdown(struct channel *);
205static void pc_hangup(struct tty_struct *);
206static void pc_put_char(struct tty_struct *, unsigned char);
207static int pc_write_room(struct tty_struct *);
208static int pc_chars_in_buffer(struct tty_struct *);
209static void pc_flush_buffer(struct tty_struct *);
210static void pc_flush_chars(struct tty_struct *);
211static int block_til_ready(struct tty_struct *, struct file *,
212 struct channel *);
213static int pc_open(struct tty_struct *, struct file *);
214static void post_fep_init(unsigned int crd);
215static void epcapoll(unsigned long);
216static void doevent(int);
217static void fepcmd(struct channel *, int, int, int, int, int);
218static unsigned termios2digi_h(struct channel *ch, unsigned);
219static unsigned termios2digi_i(struct channel *ch, unsigned);
220static unsigned termios2digi_c(struct channel *ch, unsigned);
221static void epcaparam(struct tty_struct *, struct channel *);
222static void receive_data(struct channel *);
223static int pc_ioctl(struct tty_struct *, struct file *,
224 unsigned int, unsigned long);
225static void pc_set_termios(struct tty_struct *, struct termios *);
226static void do_softint(void *);
227static void pc_stop(struct tty_struct *);
228static void pc_start(struct tty_struct *);
229static void pc_throttle(struct tty_struct * tty);
230static void pc_unthrottle(struct tty_struct *tty);
231static void digi_send_break(struct channel *ch, int msec);
232static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
233void epca_setup(char *, int *);
234void console_print(const char *);
235
236static int get_termio(struct tty_struct *, struct termio *);
237static int pc_write(struct tty_struct *, int, const unsigned char *, int);
238int pc_init(void);
239
240#ifdef ENABLE_PCI
241static int init_PCI(void);
242#endif
243
244
245
246
247
248
249
250
251
252
253
254
255
256static inline void memwinon(struct board_info *b, unsigned int win)
257{
258 (b->memwinon)(b, win);
259}
260
261static inline void memwinoff(struct board_info *b, unsigned int win)
262{
263 (b->memwinoff)(b, win);
264}
265
266static inline void globalwinon(struct channel *ch)
267{
268 (ch->board->globalwinon)(ch);
269}
270
271static inline void rxwinon(struct channel *ch)
272{
273 (ch->board->rxwinon)(ch);
274}
275
276static inline void txwinon(struct channel *ch)
277{
278 (ch->board->txwinon)(ch);
279}
280
281static inline void memoff(struct channel *ch)
282{
283 (ch->board->memoff)(ch);
284}
285static inline void assertgwinon(struct channel *ch)
286{
287 (ch->board->assertgwinon)(ch);
288}
289
290static inline void assertmemoff(struct channel *ch)
291{
292 (ch->board->assertmemoff)(ch);
293}
294
295
296
297
298
299
300static inline void pcxem_memwinon(struct board_info *b, unsigned int win)
301{
302 outb_p(FEPWIN|win, (int)b->port + 1);
303}
304
305static inline void pcxem_memwinoff(struct board_info *b, unsigned int win)
306{
307 outb_p(0, (int)b->port + 1);
308}
309
310static inline void pcxem_globalwinon(struct channel *ch)
311{
312 outb_p( FEPWIN, (int)ch->board->port + 1);
313}
314
315static inline void pcxem_rxwinon(struct channel *ch)
316{
317 outb_p(ch->rxwin, (int)ch->board->port + 1);
318}
319
320static inline void pcxem_txwinon(struct channel *ch)
321{
322 outb_p(ch->txwin, (int)ch->board->port + 1);
323}
324
325static inline void pcxem_memoff(struct channel *ch)
326{
327 outb_p(0, (int)ch->board->port + 1);
328}
329
330
331
332static inline void pcxe_memwinon(struct board_info *b, unsigned int win)
333{
334 outb_p(FEPWIN | win, (int)b->port + 1);
335}
336
337static inline void pcxe_memwinoff(struct board_info *b, unsigned int win)
338{
339 outb_p(inb((int)b->port) & ~FEPMEM,
340 (int)b->port + 1);
341 outb_p(0, (int)b->port + 1);
342}
343
344static inline void pcxe_globalwinon(struct channel *ch)
345{
346 outb_p( FEPWIN, (int)ch->board->port + 1);
347}
348
349static inline void pcxe_rxwinon(struct channel *ch)
350{
351 outb_p(ch->rxwin, (int)ch->board->port + 1);
352}
353
354static inline void pcxe_txwinon(struct channel *ch)
355{
356 outb_p(ch->txwin, (int)ch->board->port + 1);
357}
358
359static inline void pcxe_memoff(struct channel *ch)
360{
361 outb_p(0, (int)ch->board->port);
362 outb_p(0, (int)ch->board->port + 1);
363}
364
365
366
367static inline void pcxi_memwinon(struct board_info *b, unsigned int win)
368{
369 outb_p(inb((int)b->port) | FEPMEM, (int)b->port);
370}
371
372static inline void pcxi_memwinoff(struct board_info *b, unsigned int win)
373{
374 outb_p(inb((int)b->port) & ~FEPMEM, (int)b->port);
375}
376
377static inline void pcxi_globalwinon(struct channel *ch)
378{
379 outb_p(FEPMEM, (int)ch->board->port);
380}
381
382static inline void pcxi_rxwinon(struct channel *ch)
383{
384 outb_p(FEPMEM, (int)ch->board->port);
385}
386
387static inline void pcxi_txwinon(struct channel *ch)
388{
389 outb_p(FEPMEM, (int)ch->board->port);
390}
391
392static inline void pcxi_memoff(struct channel *ch)
393{
394 outb_p(0, (int)ch->board->port);
395}
396
397static inline void pcxi_assertgwinon(struct channel *ch)
398{
399 epcaassert(inb((int)ch->board->port) & FEPMEM, "Global memory off");
400}
401
402static inline void pcxi_assertmemoff(struct channel *ch)
403{
404 epcaassert(!(inb((int)ch->board->port) & FEPMEM), "Memory on");
405}
406
407
408
409
410
411
412
413
414
415
416
417static inline void dummy_memwinon(struct board_info *b, unsigned int win)
418{
419}
420
421static inline void dummy_memwinoff(struct board_info *b, unsigned int win)
422{
423}
424
425static inline void dummy_globalwinon(struct channel *ch)
426{
427}
428
429static inline void dummy_rxwinon(struct channel *ch)
430{
431}
432
433static inline void dummy_txwinon(struct channel *ch)
434{
435}
436
437static inline void dummy_memoff(struct channel *ch)
438{
439}
440
441static inline void dummy_assertgwinon(struct channel *ch)
442{
443}
444
445static inline void dummy_assertmemoff(struct channel *ch)
446{
447}
448
449
450static inline struct channel *verifyChannel(register struct tty_struct *tty)
451{
452
453
454
455
456
457
458
459
460 if (tty)
461 {
462
463 register struct channel *ch = (struct channel *)tty->driver_data;
464
465 if ((ch >= &digi_channels[0]) && (ch < &digi_channels[nbdevs]))
466 {
467 if (ch->magic == EPCA_MAGIC)
468 return ch;
469 }
470
471 }
472
473
474 return NULL;
475
476}
477
478
479
480static inline void pc_sched_event(struct channel *ch, int event)
481{
482
483
484
485
486
487
488
489 ch->event |= 1 << event;
490 MOD_INC_USE_COUNT;
491 if (schedule_task(&ch->tqueue) == 0)
492 MOD_DEC_USE_COUNT;
493
494
495}
496
497
498
499static void epca_error(int line, char *msg)
500{
501
502 printk(KERN_ERR "epca_error (Digi): line = %d %s\n",line,msg);
503 return;
504
505}
506
507
508static void pc_close(struct tty_struct * tty, struct file * filp)
509{
510
511 struct channel *ch;
512 unsigned long flags;
513
514 if (tty->driver.subtype == SERIAL_TYPE_INFO)
515 {
516 return;
517 }
518
519
520
521
522
523
524
525 if ((ch = verifyChannel(tty)) != NULL)
526 {
527
528 save_flags(flags);
529 cli();
530
531 if (tty_hung_up_p(filp))
532 {
533 restore_flags(flags);
534 return;
535 }
536
537
538 if (ch->count-- > 1)
539 {
540
541
542
543
544
545
546 restore_flags(flags);
547 return;
548 }
549
550
551
552 if (ch->count < 0)
553 {
554 ch->count = 0;
555 }
556
557
558
559
560
561
562
563 ch->asyncflags |= ASYNC_CLOSING;
564
565
566
567
568
569
570 if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
571 ch->normal_termios = *tty->termios;
572
573 if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
574 ch->callout_termios = *tty->termios;
575
576 tty->closing = 1;
577
578 if (ch->asyncflags & ASYNC_INITIALIZED)
579 {
580
581 setup_empty_event(tty, ch);
582 tty_wait_until_sent(tty, 3000);
583 }
584
585 if (tty->driver.flush_buffer)
586 tty->driver.flush_buffer(tty);
587
588 if (tty->ldisc.flush_buffer)
589 tty->ldisc.flush_buffer(tty);
590
591 shutdown(ch);
592 tty->closing = 0;
593 ch->event = 0;
594 ch->tty = NULL;
595
596 if (ch->blocked_open)
597 {
598
599 if (ch->close_delay)
600 {
601 current->state = TASK_INTERRUPTIBLE;
602 schedule_timeout(ch->close_delay);
603 }
604
605 wake_up_interruptible(&ch->open_wait);
606
607 }
608
609 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
610 ASYNC_CALLOUT_ACTIVE | ASYNC_CLOSING);
611 wake_up_interruptible(&ch->close_wait);
612
613 MOD_DEC_USE_COUNT;
614
615 restore_flags(flags);
616
617 }
618
619}
620
621
622
623static void shutdown(struct channel *ch)
624{
625
626 unsigned long flags;
627 struct tty_struct *tty;
628 volatile struct board_chan *bc;
629
630 if (!(ch->asyncflags & ASYNC_INITIALIZED))
631 return;
632
633 save_flags(flags);
634 cli();
635 globalwinon(ch);
636
637 bc = ch->brdchan;
638
639
640
641
642
643
644
645 if (bc)
646 bc->idata = 0;
647
648 tty = ch->tty;
649
650
651
652
653
654 if (tty->termios->c_cflag & HUPCL)
655 {
656 ch->omodem &= ~(ch->m_rts | ch->m_dtr);
657 fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1);
658 }
659
660 memoff(ch);
661
662
663
664
665
666
667
668
669 ch->asyncflags &= ~ASYNC_INITIALIZED;
670 restore_flags(flags);
671
672}
673
674
675
676static void pc_hangup(struct tty_struct *tty)
677{
678
679 struct channel *ch;
680
681
682
683
684
685
686 if ((ch = verifyChannel(tty)) != NULL)
687 {
688
689 unsigned long flags;
690
691 save_flags(flags);
692 cli();
693 if (tty->driver.flush_buffer)
694 tty->driver.flush_buffer(tty);
695
696 if (tty->ldisc.flush_buffer)
697 tty->ldisc.flush_buffer(tty);
698
699 shutdown(ch);
700
701 if (ch->count)
702 MOD_DEC_USE_COUNT;
703
704
705 ch->tty = NULL;
706 ch->event = 0;
707 ch->count = 0;
708 restore_flags(flags);
709 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | ASYNC_CALLOUT_ACTIVE);
710 wake_up_interruptible(&ch->open_wait);
711
712 }
713
714}
715
716
717
718static int pc_write(struct tty_struct * tty, int from_user,
719 const unsigned char *buf, int bytesAvailable)
720{
721
722 register unsigned int head, tail;
723 register int dataLen;
724 register int size;
725 register int amountCopied;
726
727
728 struct channel *ch;
729 unsigned long flags;
730 int remain;
731 volatile struct board_chan *bc;
732
733
734
735
736
737
738
739
740
741
742
743
744
745 if (tty->driver.subtype == SERIAL_TYPE_INFO)
746 {
747 return (0) ;
748 }
749
750
751
752
753
754
755 if ((ch = verifyChannel(tty)) == NULL)
756 return 0;
757
758
759
760 bc = ch->brdchan;
761 size = ch->txbufsize;
762
763 if (from_user)
764 {
765
766 save_flags(flags);
767 cli();
768
769 globalwinon(ch);
770
771
772
773
774
775
776
777
778
779
780 head = bc->tin & (size - 1);
781
782
783
784 tail = bc->tout;
785
786
787
788 if (tail != bc->tout)
789 tail = bc->tout;
790
791
792
793
794
795
796
797
798 tail &= (size - 1);
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865 dataLen = (head >= tail) ? (size - (head - tail) - 1) : (tail - head - 1);
866
867
868
869
870
871
872
873
874
875 bytesAvailable = MIN(dataLen, bytesAvailable);
876
877
878
879 memoff(ch);
880 restore_flags(flags);
881
882 if (bytesAvailable)
883 {
884
885
886 if (verify_area(VERIFY_READ, (char*)buf, bytesAvailable))
887 bytesAvailable = 0;
888 else
889 {
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911 if (copy_from_user(ch->tmp_buf, buf,
912 bytesAvailable))
913 return -EFAULT;
914
915 }
916
917 }
918
919
920
921
922
923 buf = ch->tmp_buf;
924
925 }
926
927
928
929 amountCopied = 0;
930 save_flags(flags);
931 cli();
932
933 globalwinon(ch);
934
935 head = bc->tin & (size - 1);
936 tail = bc->tout;
937
938 if (tail != bc->tout)
939 tail = bc->tout;
940 tail &= (size - 1);
941
942
943 if (head >= tail)
944 {
945
946
947
948
949
950
951
952
953
954 dataLen = size - head;
955 remain = size - (head - tail) - 1;
956
957 }
958 else
959 {
960
961 remain = tail - head - 1;
962 dataLen = remain;
963
964 }
965
966
967
968
969
970
971 bytesAvailable = MIN(remain, bytesAvailable);
972
973 txwinon(ch);
974 while (bytesAvailable > 0)
975 {
976
977
978
979
980
981
982 dataLen = MIN(bytesAvailable, dataLen);
983 memcpy(ch->txptr + head, buf, dataLen);
984 buf += dataLen;
985 head += dataLen;
986 amountCopied += dataLen;
987 bytesAvailable -= dataLen;
988
989 if (head >= size)
990 {
991 head = 0;
992 dataLen = tail;
993 }
994
995 }
996
997 ch->statusflags |= TXBUSY;
998 globalwinon(ch);
999 bc->tin = head;
1000
1001 if ((ch->statusflags & LOWWAIT) == 0)
1002 {
1003 ch->statusflags |= LOWWAIT;
1004 bc->ilow = 1;
1005 }
1006 memoff(ch);
1007 restore_flags(flags);
1008
1009 return(amountCopied);
1010
1011}
1012
1013
1014
1015static void pc_put_char(struct tty_struct *tty, unsigned char c)
1016{
1017
1018
1019 pc_write(tty, 0, &c, 1);
1020 return;
1021
1022}
1023
1024
1025
1026static int pc_write_room(struct tty_struct *tty)
1027{
1028
1029 int remain;
1030 struct channel *ch;
1031 unsigned long flags;
1032 unsigned int head, tail;
1033 volatile struct board_chan *bc;
1034
1035 remain = 0;
1036
1037
1038
1039
1040
1041
1042 if ((ch = verifyChannel(tty)) != NULL)
1043 {
1044 save_flags(flags);
1045 cli();
1046 globalwinon(ch);
1047
1048 bc = ch->brdchan;
1049 head = bc->tin & (ch->txbufsize - 1);
1050 tail = bc->tout;
1051
1052 if (tail != bc->tout)
1053 tail = bc->tout;
1054
1055 tail &= (ch->txbufsize - 1);
1056
1057 if ((remain = tail - head - 1) < 0 )
1058 remain += ch->txbufsize;
1059
1060 if (remain && (ch->statusflags & LOWWAIT) == 0)
1061 {
1062 ch->statusflags |= LOWWAIT;
1063 bc->ilow = 1;
1064 }
1065 memoff(ch);
1066 restore_flags(flags);
1067 }
1068
1069
1070 return remain;
1071
1072}
1073
1074
1075
1076static int pc_chars_in_buffer(struct tty_struct *tty)
1077{
1078
1079 int chars;
1080 unsigned int ctail, head, tail;
1081 int remain;
1082 unsigned long flags;
1083 struct channel *ch;
1084 volatile struct board_chan *bc;
1085
1086
1087
1088
1089
1090
1091
1092 if ((ch = verifyChannel(tty)) == NULL)
1093 return(0);
1094
1095 save_flags(flags);
1096 cli();
1097 globalwinon(ch);
1098
1099 bc = ch->brdchan;
1100 tail = bc->tout;
1101 head = bc->tin;
1102 ctail = ch->mailbox->cout;
1103
1104 if (tail == head && ch->mailbox->cin == ctail && bc->tbusy == 0)
1105 chars = 0;
1106 else
1107 {
1108
1109 head = bc->tin & (ch->txbufsize - 1);
1110 tail &= (ch->txbufsize - 1);
1111
1112
1113
1114
1115
1116
1117
1118 if ((remain = tail - head - 1) < 0 )
1119 remain += ch->txbufsize;
1120
1121 chars = (int)(ch->txbufsize - remain);
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131 if (!(ch->statusflags & EMPTYWAIT))
1132 setup_empty_event(tty,ch);
1133
1134 }
1135
1136 memoff(ch);
1137 restore_flags(flags);
1138
1139
1140 return(chars);
1141
1142}
1143
1144
1145
1146static void pc_flush_buffer(struct tty_struct *tty)
1147{
1148
1149 unsigned int tail;
1150 unsigned long flags;
1151 struct channel *ch;
1152 volatile struct board_chan *bc;
1153
1154
1155
1156
1157
1158
1159
1160 if ((ch = verifyChannel(tty)) == NULL)
1161 return;
1162
1163 save_flags(flags);
1164 cli();
1165
1166 globalwinon(ch);
1167
1168 bc = ch->brdchan;
1169 tail = bc->tout;
1170
1171
1172
1173 fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0);
1174
1175 memoff(ch);
1176 restore_flags(flags);
1177
1178 wake_up_interruptible(&tty->write_wait);
1179 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
1180 (tty->ldisc.write_wakeup)(tty);
1181
1182}
1183
1184
1185
1186static void pc_flush_chars(struct tty_struct *tty)
1187{
1188
1189 struct channel * ch;
1190
1191
1192
1193
1194
1195
1196 if ((ch = verifyChannel(tty)) != NULL)
1197 {
1198 unsigned long flags;
1199
1200 save_flags(flags);
1201 cli();
1202
1203
1204
1205
1206
1207
1208 if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT))
1209 setup_empty_event(tty,ch);
1210
1211 restore_flags(flags);
1212 }
1213
1214}
1215
1216
1217
1218static int block_til_ready(struct tty_struct *tty,
1219 struct file *filp, struct channel *ch)
1220{
1221
1222 DECLARE_WAITQUEUE(wait,current);
1223 int retval, do_clocal = 0;
1224 unsigned long flags;
1225
1226
1227 if (tty_hung_up_p(filp))
1228 {
1229 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1230 retval = -EAGAIN;
1231 else
1232 retval = -ERESTARTSYS;
1233 return(retval);
1234 }
1235
1236
1237
1238
1239
1240 if (ch->asyncflags & ASYNC_CLOSING)
1241 {
1242 interruptible_sleep_on(&ch->close_wait);
1243
1244 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1245 return -EAGAIN;
1246 else
1247 return -ERESTARTSYS;
1248 }
1249
1250
1251
1252
1253
1254
1255 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT)
1256 {
1257 if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
1258 return -EBUSY;
1259
1260 if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
1261 (ch->asyncflags & ASYNC_SESSION_LOCKOUT) &&
1262 (ch->session != current->session))
1263 return -EBUSY;
1264
1265 if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
1266 (ch->asyncflags & ASYNC_PGRP_LOCKOUT) &&
1267 (ch->pgrp != current->pgrp))
1268 return -EBUSY;
1269
1270 ch->asyncflags |= ASYNC_CALLOUT_ACTIVE;
1271
1272 return 0;
1273 }
1274
1275 if (filp->f_flags & O_NONBLOCK)
1276 {
1277
1278
1279
1280
1281
1282 if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
1283 return -EBUSY;
1284
1285 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1286
1287 return 0;
1288 }
1289
1290
1291 if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
1292 {
1293 if (ch->normal_termios.c_cflag & CLOCAL)
1294 do_clocal = 1;
1295 }
1296 else
1297 {
1298 if (tty->termios->c_cflag & CLOCAL)
1299 do_clocal = 1;
1300 }
1301
1302
1303
1304 retval = 0;
1305 add_wait_queue(&ch->open_wait, &wait);
1306 save_flags(flags);
1307 cli();
1308
1309
1310
1311 if (!tty_hung_up_p(filp))
1312 ch->count--;
1313
1314 restore_flags(flags);
1315
1316 ch->blocked_open++;
1317
1318 while(1)
1319 {
1320
1321 set_current_state(TASK_INTERRUPTIBLE);
1322
1323 if (tty_hung_up_p(filp) ||
1324 !(ch->asyncflags & ASYNC_INITIALIZED))
1325 {
1326 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1327 retval = -EAGAIN;
1328 else
1329 retval = -ERESTARTSYS;
1330 break;
1331 }
1332
1333 if (!(ch->asyncflags & ASYNC_CLOSING) &&
1334 !(ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
1335 (do_clocal || (ch->imodem & ch->dcd)))
1336 break;
1337
1338 if (signal_pending(current))
1339 {
1340 retval = -ERESTARTSYS;
1341 break;
1342 }
1343
1344
1345
1346
1347
1348
1349
1350 schedule();
1351
1352 }
1353
1354 current->state = TASK_RUNNING;
1355 remove_wait_queue(&ch->open_wait, &wait);
1356 cli();
1357 if (!tty_hung_up_p(filp))
1358 ch->count++;
1359 restore_flags(flags);
1360
1361 ch->blocked_open--;
1362
1363 if (retval)
1364 return retval;
1365
1366 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1367
1368 return 0;
1369
1370}
1371
1372
1373
1374static int pc_open(struct tty_struct *tty, struct file * filp)
1375{
1376
1377 struct channel *ch;
1378 unsigned long flags;
1379 int line, retval, boardnum;
1380 volatile struct board_chan *bc;
1381 volatile unsigned int head;
1382
1383
1384
1385 if (tty->driver.subtype == SERIAL_TYPE_INFO)
1386 {
1387 return (0) ;
1388 }
1389
1390 line = MINOR(tty->device) - tty->driver.minor_start;
1391 if (line < 0 || line >= nbdevs)
1392 {
1393 printk(KERN_ERR "<Error> - pc_open : line out of range in pc_open\n");
1394 tty->driver_data = NULL;
1395 return(-ENODEV);
1396 }
1397
1398
1399 MOD_INC_USE_COUNT;
1400
1401 ch = &digi_channels[line];
1402 boardnum = ch->boardnum;
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412 if (invalid_lilo_config)
1413 {
1414 if (setup_error_code & INVALID_BOARD_TYPE)
1415 printk(KERN_ERR "<Error> - pc_open: Invalid board type specified in LILO command\n");
1416
1417 if (setup_error_code & INVALID_NUM_PORTS)
1418 printk(KERN_ERR "<Error> - pc_open: Invalid number of ports specified in LILO command\n");
1419
1420 if (setup_error_code & INVALID_MEM_BASE)
1421 printk(KERN_ERR "<Error> - pc_open: Invalid board memory address specified in LILO command\n");
1422
1423 if (setup_error_code & INVALID_PORT_BASE)
1424 printk(KERN_ERR "<Error> - pc_open: Invalid board port address specified in LILO command\n");
1425
1426 if (setup_error_code & INVALID_BOARD_STATUS)
1427 printk(KERN_ERR "<Error> - pc_open: Invalid board status specified in LILO command\n");
1428
1429 if (setup_error_code & INVALID_ALTPIN)
1430 printk(KERN_ERR "<Error> - pc_open: Invalid board altpin specified in LILO command\n");
1431
1432 tty->driver_data = NULL;
1433 return(-ENODEV);
1434 }
1435
1436 if ((boardnum >= num_cards) || (boards[boardnum].status == DISABLED))
1437 {
1438 tty->driver_data = NULL;
1439 return(-ENODEV);
1440 }
1441
1442 if (( bc = ch->brdchan) == 0)
1443 {
1444 tty->driver_data = NULL;
1445 return(-ENODEV);
1446 }
1447
1448
1449
1450
1451
1452
1453
1454 ch->count++;
1455
1456
1457
1458
1459
1460
1461
1462 tty->driver_data = ch;
1463
1464
1465
1466
1467
1468
1469
1470 if (ch->count == 1)
1471 {
1472 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
1473 *tty->termios = ch->normal_termios;
1474 else
1475 *tty->termios = ch->callout_termios;
1476 }
1477
1478 ch->session = current->session;
1479 ch->pgrp = current->pgrp;
1480
1481 save_flags(flags);
1482 cli();
1483
1484 globalwinon(ch);
1485 ch->statusflags = 0;
1486
1487
1488 ch->imodem = bc->mstat;
1489
1490
1491
1492
1493
1494 head = bc->rin;
1495 bc->rout = head;
1496
1497
1498 ch->tty = tty;
1499
1500
1501
1502
1503
1504 epcaparam(tty,ch);
1505
1506 ch->asyncflags |= ASYNC_INITIALIZED;
1507 memoff(ch);
1508
1509 restore_flags(flags);
1510
1511 retval = block_til_ready(tty, filp, ch);
1512 if (retval)
1513 {
1514 return retval;
1515 }
1516
1517
1518
1519
1520
1521 ch->tty = tty;
1522
1523 save_flags(flags);
1524 cli();
1525 globalwinon(ch);
1526
1527
1528 bc->idata = 1;
1529
1530 memoff(ch);
1531 restore_flags(flags);
1532
1533 return 0;
1534
1535}
1536
1537#ifdef MODULE
1538
1539int __init init_module()
1540{
1541
1542 unsigned long flags;
1543
1544 save_flags(flags);
1545 cli();
1546
1547 pc_init();
1548
1549 restore_flags(flags);
1550
1551 return(0);
1552}
1553
1554#endif
1555
1556#ifdef ENABLE_PCI
1557static struct pci_driver epca_driver;
1558#endif
1559
1560#ifdef MODULE
1561
1562
1563void cleanup_module()
1564{
1565
1566 int count, crd;
1567 struct board_info *bd;
1568 struct channel *ch;
1569 unsigned long flags;
1570
1571 del_timer_sync(&epca_timer);
1572
1573 save_flags(flags);
1574 cli();
1575
1576 if ((tty_unregister_driver(&pc_driver)) ||
1577 (tty_unregister_driver(&pc_callout)) ||
1578 (tty_unregister_driver(&pc_info)))
1579 {
1580 printk(KERN_WARNING "<Error> - DIGI : cleanup_module failed to un-register tty driver\n");
1581 restore_flags(flags);
1582 return;
1583 }
1584
1585 for (crd = 0; crd < num_cards; crd++)
1586 {
1587
1588 bd = &boards[crd];
1589
1590 if (!bd)
1591 {
1592 printk(KERN_ERR "<Error> - Digi : cleanup_module failed\n");
1593 return;
1594 }
1595
1596 ch = card_ptr[crd];
1597
1598 for (count = 0; count < bd->numports; count++, ch++)
1599 {
1600
1601 if (ch)
1602 {
1603 if (ch->tty)
1604 tty_hangup(ch->tty);
1605 kfree(ch->tmp_buf);
1606 }
1607
1608 }
1609 }
1610
1611#ifdef ENABLE_PCI
1612 pci_unregister_driver (&epca_driver);
1613#endif
1614
1615 restore_flags(flags);
1616
1617}
1618#endif
1619
1620
1621
1622int __init pc_init(void)
1623{
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640 ulong flags;
1641 int crd;
1642 struct board_info *bd;
1643 unsigned char board_id = 0;
1644
1645
1646#ifdef ENABLE_PCI
1647 int pci_boards_found, pci_count;
1648
1649 pci_count = 0;
1650#endif
1651
1652
1653
1654
1655
1656
1657
1658 if (!liloconfig)
1659 {
1660
1661 nbdevs = NBDEVS;
1662 num_cards = NUMCARDS;
1663 memcpy((void *)&boards, (void *)&static_boards,
1664 (sizeof(struct board_info) * NUMCARDS));
1665 }
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680 printk(KERN_INFO "DIGI epca driver version %s loaded.\n",VERSION);
1681
1682#ifdef ENABLE_PCI
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704 pci_boards_found = 0;
1705 if (pci_present())
1706 {
1707 if(num_cards < MAXBOARDS)
1708 pci_boards_found += init_PCI();
1709 num_cards += pci_boards_found;
1710 }
1711 else
1712 {
1713 printk(KERN_ERR "<Error> - No PCI BIOS found\n");
1714 }
1715
1716#endif
1717
1718 memset(&pc_driver, 0, sizeof(struct tty_driver));
1719 memset(&pc_callout, 0, sizeof(struct tty_driver));
1720 memset(&pc_info, 0, sizeof(struct tty_driver));
1721
1722 pc_driver.magic = TTY_DRIVER_MAGIC;
1723 pc_driver.name = "ttyD";
1724 pc_driver.major = DIGI_MAJOR;
1725 pc_driver.minor_start = 0;
1726 pc_driver.num = MAX_ALLOC;
1727 pc_driver.type = TTY_DRIVER_TYPE_SERIAL;
1728 pc_driver.subtype = SERIAL_TYPE_NORMAL;
1729 pc_driver.init_termios = tty_std_termios;
1730 pc_driver.init_termios.c_iflag = 0;
1731 pc_driver.init_termios.c_oflag = 0;
1732
1733 pc_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
1734 pc_driver.init_termios.c_lflag = 0;
1735 pc_driver.flags = TTY_DRIVER_REAL_RAW;
1736 pc_driver.refcount = &pc_refcount;
1737 pc_driver.table = pc_table;
1738
1739
1740
1741 pc_driver.termios = pc_termios;
1742 pc_driver.termios_locked = pc_termios_locked;
1743
1744
1745
1746
1747
1748
1749 pc_driver.open = pc_open;
1750 pc_driver.close = pc_close;
1751 pc_driver.write = pc_write;
1752 pc_driver.write_room = pc_write_room;
1753 pc_driver.flush_buffer = pc_flush_buffer;
1754 pc_driver.chars_in_buffer = pc_chars_in_buffer;
1755 pc_driver.flush_chars = pc_flush_chars;
1756 pc_driver.put_char = pc_put_char;
1757 pc_driver.ioctl = pc_ioctl;
1758 pc_driver.set_termios = pc_set_termios;
1759 pc_driver.stop = pc_stop;
1760 pc_driver.start = pc_start;
1761 pc_driver.throttle = pc_throttle;
1762 pc_driver.unthrottle = pc_unthrottle;
1763 pc_driver.hangup = pc_hangup;
1764 pc_callout = pc_driver;
1765
1766 pc_callout.name = "cud";
1767 pc_callout.major = DIGICU_MAJOR;
1768 pc_callout.minor_start = 0;
1769 pc_callout.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
1770 pc_callout.subtype = SERIAL_TYPE_CALLOUT;
1771
1772 pc_info = pc_driver;
1773 pc_info.name = "digi_ctl";
1774 pc_info.major = DIGIINFOMAJOR;
1775 pc_info.minor_start = 0;
1776 pc_info.num = 1;
1777 pc_info.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
1778 pc_info.subtype = SERIAL_TYPE_INFO;
1779
1780
1781 save_flags(flags);
1782 cli();
1783
1784 for (crd = 0; crd < num_cards; crd++)
1785 {
1786
1787
1788
1789
1790
1791
1792
1793 bd = &boards[crd];
1794
1795 switch (bd->type)
1796 {
1797 case PCXEM:
1798 case EISAXEM:
1799 bd->memwinon = pcxem_memwinon ;
1800 bd->memwinoff = pcxem_memwinoff ;
1801 bd->globalwinon = pcxem_globalwinon ;
1802 bd->txwinon = pcxem_txwinon ;
1803 bd->rxwinon = pcxem_rxwinon ;
1804 bd->memoff = pcxem_memoff ;
1805 bd->assertgwinon = dummy_assertgwinon;
1806 bd->assertmemoff = dummy_assertmemoff;
1807 break;
1808
1809 case PCIXEM:
1810 case PCIXRJ:
1811 case PCIXR:
1812 bd->memwinon = dummy_memwinon;
1813 bd->memwinoff = dummy_memwinoff;
1814 bd->globalwinon = dummy_globalwinon;
1815 bd->txwinon = dummy_txwinon;
1816 bd->rxwinon = dummy_rxwinon;
1817 bd->memoff = dummy_memoff;
1818 bd->assertgwinon = dummy_assertgwinon;
1819 bd->assertmemoff = dummy_assertmemoff;
1820 break;
1821
1822 case PCXE:
1823 case PCXEVE:
1824
1825 bd->memwinon = pcxe_memwinon;
1826 bd->memwinoff = pcxe_memwinoff;
1827 bd->globalwinon = pcxe_globalwinon;
1828 bd->txwinon = pcxe_txwinon;
1829 bd->rxwinon = pcxe_rxwinon;
1830 bd->memoff = pcxe_memoff;
1831 bd->assertgwinon = dummy_assertgwinon;
1832 bd->assertmemoff = dummy_assertmemoff;
1833 break;
1834
1835 case PCXI:
1836 case PC64XE:
1837
1838 bd->memwinon = pcxi_memwinon;
1839 bd->memwinoff = pcxi_memwinoff;
1840 bd->globalwinon = pcxi_globalwinon;
1841 bd->txwinon = pcxi_txwinon;
1842 bd->rxwinon = pcxi_rxwinon;
1843 bd->memoff = pcxi_memoff;
1844 bd->assertgwinon = pcxi_assertgwinon;
1845 bd->assertmemoff = pcxi_assertmemoff;
1846 break;
1847
1848 default:
1849 break;
1850
1851 }
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862 switch (bd->type)
1863 {
1864
1865 case PCXE:
1866 case PCXEVE:
1867 case PC64XE:
1868 bd->memory_seg = 0xf000;
1869 break;
1870
1871 case PCXI:
1872 board_id = inb((int)bd->port);
1873 if ((board_id & 0x1) == 0x1)
1874 {
1875
1876
1877 if ((board_id & 0x30) == 0)
1878 bd->memory_seg = 0xf000;
1879
1880
1881 if ((board_id & 0x30) == 0x10)
1882 bd->memory_seg = 0xe000;
1883
1884
1885 if ((board_id & 0x30) == 0x20)
1886 bd->memory_seg = 0xc000;
1887
1888
1889 if ((board_id & 0x30) == 0x30)
1890 bd->memory_seg = 0x8000;
1891
1892 }
1893 else
1894 {
1895 printk(KERN_ERR "<Error> - Board at 0x%x doesn't appear to be an XI\n",(int)bd->port);
1896 }
1897 break;
1898
1899 }
1900
1901 }
1902
1903 if (tty_register_driver(&pc_driver))
1904 panic("Couldn't register Digi PC/ driver");
1905
1906 if (tty_register_driver(&pc_callout))
1907 panic("Couldn't register Digi PC/ callout");
1908
1909 if (tty_register_driver(&pc_info))
1910 panic("Couldn't register Digi PC/ info ");
1911
1912
1913
1914
1915
1916 init_timer(&epca_timer);
1917 epca_timer.function = epcapoll;
1918 mod_timer(&epca_timer, jiffies + HZ/25);
1919
1920 restore_flags(flags);
1921
1922 return 0;
1923
1924}
1925
1926
1927
1928static void post_fep_init(unsigned int crd)
1929{
1930
1931 int i;
1932 unchar *memaddr;
1933 volatile struct global_data *gd;
1934 struct board_info *bd;
1935 volatile struct board_chan *bc;
1936 struct channel *ch;
1937 int shrinkmem = 0, lowwater ;
1938
1939
1940
1941
1942
1943 bd = &boards[crd];
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954 if (bd->type >= PCIXEM)
1955 {
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971 bd->numports = (unsigned short)*(unsigned char *)bus_to_virt((unsigned long)
1972 (bd->re_map_membase + XEMPORTS));
1973
1974
1975 epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports");
1976 nbdevs += (bd->numports);
1977
1978 }
1979
1980 if (crd != 0)
1981 card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports;
1982 else
1983 card_ptr[crd] = &digi_channels[crd];
1984
1985 ch = card_ptr[crd];
1986
1987
1988 epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range");
1989
1990 memaddr = (unchar *)bd->re_map_membase;
1991
1992
1993
1994
1995
1996
1997
1998 memaddr = (unsigned char *)bus_to_virt((unsigned long)memaddr);
1999
2000
2001
2002
2003
2004
2005
2006 bc = (volatile struct board_chan *)((ulong)memaddr + CHANSTRUCT);
2007
2008
2009
2010
2011
2012
2013
2014
2015 gd = (volatile struct global_data *)((ulong)memaddr + GLOBAL);
2016
2017
2018
2019
2020
2021
2022 if (((bd->type == PCXEVE) | (bd->type == PCXE)) &&
2023 (*(ushort *)((ulong)memaddr + XEPORTS) < 3))
2024 shrinkmem = 1;
2025 if (bd->type < PCIXEM)
2026 if (!request_region((int)bd->port, 4, board_desc[bd->type]))
2027 return;
2028
2029 memwinon(bd, 0);
2030
2031
2032
2033
2034
2035
2036
2037
2038 for (i = 0; i < bd->numports; i++, ch++, bc++)
2039 {
2040
2041 ch->brdchan = bc;
2042 ch->mailbox = gd;
2043 ch->tqueue.routine = do_softint;
2044 ch->tqueue.data = ch;
2045 ch->board = &boards[crd];
2046
2047 switch (bd->type)
2048 {
2049
2050
2051
2052
2053
2054
2055 case EISAXEM:
2056 case PCXEM:
2057 case PCIXEM:
2058 case PCIXRJ:
2059 case PCIXR:
2060 ch->m_rts = 0x02 ;
2061 ch->m_dcd = 0x80 ;
2062 ch->m_dsr = 0x20 ;
2063 ch->m_cts = 0x10 ;
2064 ch->m_ri = 0x40 ;
2065 ch->m_dtr = 0x01 ;
2066 break;
2067
2068 case PCXE:
2069 case PCXEVE:
2070 case PCXI:
2071 case PC64XE:
2072 ch->m_rts = 0x02 ;
2073 ch->m_dcd = 0x08 ;
2074 ch->m_dsr = 0x10 ;
2075 ch->m_cts = 0x20 ;
2076 ch->m_ri = 0x40 ;
2077 ch->m_dtr = 0x80 ;
2078 break;
2079
2080 }
2081
2082 if (boards[crd].altpin)
2083 {
2084 ch->dsr = ch->m_dcd;
2085 ch->dcd = ch->m_dsr;
2086 ch->digiext.digi_flags |= DIGI_ALTPIN;
2087 }
2088 else
2089 {
2090 ch->dcd = ch->m_dcd;
2091 ch->dsr = ch->m_dsr;
2092 }
2093
2094 ch->boardnum = crd;
2095 ch->channelnum = i;
2096 ch->magic = EPCA_MAGIC;
2097 ch->tty = 0;
2098
2099 if (shrinkmem)
2100 {
2101 fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
2102 shrinkmem = 0;
2103 }
2104
2105 switch (bd->type)
2106 {
2107
2108 case PCIXEM:
2109 case PCIXRJ:
2110 case PCIXR:
2111
2112 ch->txptr = memaddr + (((bc->tseg) << 4) & 0x1fffff);
2113 ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x1fffff);
2114 ch->txwin = FEPWIN | ((bc->tseg) >> 11);
2115 ch->rxwin = FEPWIN | ((bc->rseg) >> 11);
2116 break;
2117
2118 case PCXEM:
2119 case EISAXEM:
2120
2121
2122 ch->txptr = memaddr + (((bc->tseg) << 4) & 0x7fff);
2123 ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x7fff);
2124 ch->txwin = FEPWIN | ((bc->tseg) >> 11);
2125 ch->rxwin = FEPWIN | ((bc->rseg) >> 11);
2126 break;
2127
2128 case PCXEVE:
2129 case PCXE:
2130 ch->txptr = memaddr + (((bc->tseg - bd->memory_seg) << 4) & 0x1fff);
2131 ch->txwin = FEPWIN | ((bc->tseg - bd->memory_seg) >> 9);
2132 ch->rxptr = memaddr + (((bc->rseg - bd->memory_seg) << 4) & 0x1fff);
2133 ch->rxwin = FEPWIN | ((bc->rseg - bd->memory_seg) >>9 );
2134 break;
2135
2136 case PCXI:
2137 case PC64XE:
2138 ch->txptr = memaddr + ((bc->tseg - bd->memory_seg) << 4);
2139 ch->rxptr = memaddr + ((bc->rseg - bd->memory_seg) << 4);
2140 ch->txwin = ch->rxwin = 0;
2141 break;
2142
2143 }
2144
2145 ch->txbufhead = 0;
2146 ch->txbufsize = bc->tmax + 1;
2147
2148 ch->rxbufhead = 0;
2149 ch->rxbufsize = bc->rmax + 1;
2150
2151 lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2);
2152
2153
2154 fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);
2155
2156
2157
2158 fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0);
2159
2160
2161
2162 fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0);
2163
2164 bc->edelay = 100;
2165 bc->idata = 1;
2166
2167 ch->startc = bc->startc;
2168 ch->stopc = bc->stopc;
2169 ch->startca = bc->startca;
2170 ch->stopca = bc->stopca;
2171
2172 ch->fepcflag = 0;
2173 ch->fepiflag = 0;
2174 ch->fepoflag = 0;
2175 ch->fepstartc = 0;
2176 ch->fepstopc = 0;
2177 ch->fepstartca = 0;
2178 ch->fepstopca = 0;
2179
2180 ch->close_delay = 50;
2181 ch->count = 0;
2182 ch->blocked_open = 0;
2183 ch->callout_termios = pc_callout.init_termios;
2184 ch->normal_termios = pc_driver.init_termios;
2185 init_waitqueue_head(&ch->open_wait);
2186 init_waitqueue_head(&ch->close_wait);
2187 ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
2188 if (!(ch->tmp_buf))
2189 {
2190 printk(KERN_ERR "POST FEP INIT : kmalloc failed for port 0x%x\n",i);
2191 release_region((int)bd->port, 4);
2192 while(i-- > 0)
2193 kfree((ch--)->tmp_buf);
2194 return;
2195 }
2196 else
2197 memset((void *)ch->tmp_buf,0,ch->txbufsize);
2198 }
2199
2200 printk(KERN_INFO
2201 "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
2202 VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports);
2203 sprintf(mesg,
2204 "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
2205 VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports);
2206 console_print(mesg);
2207
2208 memwinoff(bd, 0);
2209
2210}
2211
2212
2213
2214static void epcapoll(unsigned long ignored)
2215{
2216
2217 unsigned long flags;
2218 int crd;
2219 volatile unsigned int head, tail;
2220 struct channel *ch;
2221 struct board_info *bd;
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231 save_flags(flags);
2232 cli();
2233
2234 for (crd = 0; crd < num_cards; crd++)
2235 {
2236
2237 bd = &boards[crd];
2238 ch = card_ptr[crd];
2239
2240 if ((bd->status == DISABLED) || digi_poller_inhibited)
2241 continue;
2242
2243
2244
2245
2246
2247
2248
2249 assertmemoff(ch);
2250
2251 globalwinon(ch);
2252
2253
2254
2255
2256
2257
2258 head = ch->mailbox->ein;
2259 tail = ch->mailbox->eout;
2260
2261
2262
2263 if (head != tail)
2264 doevent(crd);
2265
2266 memoff(ch);
2267
2268 }
2269
2270 mod_timer(&epca_timer, jiffies + (HZ / 25));
2271
2272 restore_flags(flags);
2273}
2274
2275
2276
2277static void doevent(int crd)
2278{
2279
2280 volatile unchar *eventbuf;
2281 struct channel *ch, *chan0;
2282 static struct tty_struct *tty;
2283 volatile struct board_info *bd;
2284 volatile struct board_chan *bc;
2285 register volatile unsigned int tail, head;
2286 register int event, channel;
2287 register int mstat, lstat;
2288
2289
2290
2291
2292
2293
2294 bd = &boards[crd];
2295
2296 chan0 = card_ptr[crd];
2297 epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range");
2298
2299 assertgwinon(chan0);
2300
2301 while ((tail = chan0->mailbox->eout) != (head = chan0->mailbox->ein))
2302 {
2303
2304 assertgwinon(chan0);
2305
2306 eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->re_map_membase + tail + ISTART));
2307
2308
2309 channel = eventbuf[0];
2310
2311
2312 event = eventbuf[1];
2313
2314
2315
2316
2317
2318
2319
2320 mstat = eventbuf[2];
2321 lstat = eventbuf[3];
2322
2323 ch = chan0 + channel;
2324
2325 if ((unsigned)channel >= bd->numports || !ch)
2326 {
2327 if (channel >= bd->numports)
2328 ch = chan0;
2329 bc = ch->brdchan;
2330 goto next;
2331 }
2332
2333 if ((bc = ch->brdchan) == NULL)
2334 goto next;
2335
2336 if (event & DATA_IND)
2337 {
2338
2339 receive_data(ch);
2340 assertgwinon(ch);
2341
2342 }
2343
2344 if (event & MODEMCHG_IND)
2345 {
2346
2347
2348
2349 ch->imodem = mstat;
2350
2351 if (ch->asyncflags & ASYNC_CHECK_CD)
2352 {
2353 if (mstat & ch->dcd)
2354 wake_up_interruptible(&ch->open_wait);
2355 else
2356 pc_sched_event(ch, EPCA_EVENT_HANGUP);
2357 }
2358
2359 }
2360
2361 tty = ch->tty;
2362 if (tty)
2363 {
2364
2365 if (event & BREAK_IND)
2366 {
2367
2368
2369
2370 tty->flip.count++;
2371 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
2372
2373 *tty->flip.char_buf_ptr++ = 0;
2374
2375 tty_schedule_flip(tty);
2376
2377 }
2378 else
2379 if (event & LOWTX_IND)
2380 {
2381
2382 if (ch->statusflags & LOWWAIT)
2383 {
2384
2385 ch->statusflags &= ~LOWWAIT;
2386 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
2387 tty->ldisc.write_wakeup)
2388 (tty->ldisc.write_wakeup)(tty);
2389 wake_up_interruptible(&tty->write_wait);
2390
2391 }
2392
2393 }
2394 else
2395 if (event & EMPTYTX_IND)
2396 {
2397
2398
2399
2400 ch->statusflags &= ~TXBUSY;
2401 if (ch->statusflags & EMPTYWAIT)
2402 {
2403
2404 ch->statusflags &= ~EMPTYWAIT;
2405 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
2406 tty->ldisc.write_wakeup)
2407 (tty->ldisc.write_wakeup)(tty);
2408
2409 wake_up_interruptible(&tty->write_wait);
2410
2411 }
2412
2413 }
2414
2415 }
2416
2417
2418 next:
2419 globalwinon(ch);
2420
2421 if (!bc)
2422 printk(KERN_ERR "<Error> - bc == NULL in doevent!\n");
2423 else
2424 bc->idata = 1;
2425
2426 chan0->mailbox->eout = (tail + 4) & (IMAX - ISTART - 4);
2427 globalwinon(chan0);
2428
2429 }
2430
2431}
2432
2433
2434
2435static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
2436 int byte2, int ncmds, int bytecmd)
2437{
2438
2439 unchar *memaddr;
2440 unsigned int head, cmdTail, cmdStart, cmdMax;
2441 long count;
2442 int n;
2443
2444
2445
2446 if (ch->board->status == DISABLED)
2447 {
2448 return;
2449 }
2450
2451 assertgwinon(ch);
2452
2453
2454 head = ch->mailbox->cin;
2455
2456
2457 cmdStart = ch->mailbox->cstart;
2458
2459
2460
2461
2462
2463
2464
2465 cmdMax = (cmdStart + 4 + (ch->mailbox->cmax));
2466
2467 memaddr = ch->board->re_map_membase;
2468
2469
2470
2471
2472
2473
2474
2475 memaddr = (unsigned char *)bus_to_virt((unsigned long)memaddr);
2476
2477 if (head >= (cmdMax - cmdStart) || (head & 03))
2478 {
2479 printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", __LINE__,
2480 cmd, head);
2481 printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", __LINE__,
2482 cmdMax, cmdStart);
2483 return;
2484 }
2485
2486 if (bytecmd)
2487 {
2488 *(volatile unchar *)(memaddr + head + cmdStart + 0) = (unchar)cmd;
2489
2490 *(volatile unchar *)(memaddr + head + cmdStart + 1) = (unchar)ch->channelnum;
2491
2492 *(volatile unchar *)(memaddr + head + cmdStart + 2) = (unchar)word_or_byte;
2493
2494 *(volatile unchar *)(memaddr + head + cmdStart + 3) = (unchar)byte2;
2495
2496 }
2497 else
2498 {
2499 *(volatile unchar *)(memaddr + head + cmdStart + 0) = (unchar)cmd;
2500 *(volatile unchar *)(memaddr + head + cmdStart + 1) = (unchar)ch->channelnum;
2501 *(volatile ushort*)(memaddr + head + cmdStart + 2) = (ushort)word_or_byte;
2502 }
2503
2504 head = (head + 4) & (cmdMax - cmdStart - 4);
2505 ch->mailbox->cin = head;
2506
2507 count = FEPTIMEOUT;
2508
2509 for (;;)
2510 {
2511
2512 count--;
2513 if (count == 0)
2514 {
2515 printk(KERN_ERR "<Error> - Fep not responding in fepcmd()\n");
2516 return;
2517 }
2518
2519 head = ch->mailbox->cin;
2520 cmdTail = ch->mailbox->cout;
2521
2522 n = (head - cmdTail) & (cmdMax - cmdStart - 4);
2523
2524
2525
2526
2527
2528
2529 if (n <= ncmds * (sizeof(short) * 4))
2530 break;
2531
2532 }
2533
2534}
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545static unsigned termios2digi_h(struct channel *ch, unsigned cflag)
2546{
2547
2548 unsigned res = 0;
2549
2550 if (cflag & CRTSCTS)
2551 {
2552 ch->digiext.digi_flags |= (RTSPACE | CTSPACE);
2553 res |= ((ch->m_cts) | (ch->m_rts));
2554 }
2555
2556 if (ch->digiext.digi_flags & RTSPACE)
2557 res |= ch->m_rts;
2558
2559 if (ch->digiext.digi_flags & DTRPACE)
2560 res |= ch->m_dtr;
2561
2562 if (ch->digiext.digi_flags & CTSPACE)
2563 res |= ch->m_cts;
2564
2565 if (ch->digiext.digi_flags & DSRPACE)
2566 res |= ch->dsr;
2567
2568 if (ch->digiext.digi_flags & DCDPACE)
2569 res |= ch->dcd;
2570
2571 if (res & (ch->m_rts))
2572 ch->digiext.digi_flags |= RTSPACE;
2573
2574 if (res & (ch->m_cts))
2575 ch->digiext.digi_flags |= CTSPACE;
2576
2577 return res;
2578
2579}
2580
2581
2582static unsigned termios2digi_i(struct channel *ch, unsigned iflag)
2583{
2584
2585 unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
2586 INPCK | ISTRIP|IXON|IXANY|IXOFF);
2587
2588 if (ch->digiext.digi_flags & DIGI_AIXON)
2589 res |= IAIXON;
2590 return res;
2591
2592}
2593
2594
2595
2596static unsigned termios2digi_c(struct channel *ch, unsigned cflag)
2597{
2598
2599 unsigned res = 0;
2600
2601#ifdef SPEED_HACK
2602
2603 if ((cflag & CBAUD)== B38400) cflag=cflag - B38400 + B115200;
2604 if ((cflag & CBAUD)== B19200) cflag=cflag - B19200 + B57600;
2605#endif
2606
2607 if (cflag & CBAUDEX)
2608 {
2609
2610 ch->digiext.digi_flags |= DIGI_FAST;
2611
2612
2613
2614
2615
2616
2617 res |= FEP_HUPCL;
2618
2619 }
2620 else ch->digiext.digi_flags &= ~DIGI_FAST;
2621
2622
2623
2624
2625
2626
2627
2628 res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE);
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651 if (cflag & CBAUDEX)
2652 {
2653
2654
2655
2656
2657
2658
2659
2660
2661 if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) ||
2662 (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX))))
2663 {
2664 res += 1;
2665 }
2666 }
2667
2668 return res;
2669
2670}
2671
2672
2673
2674static void epcaparam(struct tty_struct *tty, struct channel *ch)
2675{
2676
2677 unsigned int cmdHead;
2678 struct termios *ts;
2679 volatile struct board_chan *bc;
2680 unsigned mval, hflow, cflag, iflag;
2681
2682 bc = ch->brdchan;
2683 epcaassert(bc !=0, "bc out of range");
2684
2685 assertgwinon(ch);
2686
2687 ts = tty->termios;
2688
2689 if ((ts->c_cflag & CBAUD) == 0)
2690 {
2691
2692 cmdHead = bc->rin;
2693 bc->rout = cmdHead;
2694 cmdHead = bc->tin;
2695
2696
2697
2698
2699
2700
2701
2702 fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0);
2703 mval = 0;
2704
2705 }
2706 else
2707 {
2708
2709
2710
2711
2712
2713
2714 cflag = termios2digi_c(ch, ts->c_cflag);
2715
2716 if (cflag != ch->fepcflag)
2717 {
2718 ch->fepcflag = cflag;
2719
2720 fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0);
2721 }
2722
2723
2724
2725
2726
2727
2728
2729
2730 if ((ts->c_cflag & CLOCAL) || (tty->driver.subtype == SERIAL_TYPE_CALLOUT))
2731 {
2732 ch->asyncflags &= ~ASYNC_CHECK_CD;
2733 }
2734 else
2735 {
2736 ch->asyncflags |= ASYNC_CHECK_CD;
2737 }
2738
2739 mval = ch->m_dtr | ch->m_rts;
2740
2741 }
2742
2743 iflag = termios2digi_i(ch, ts->c_iflag);
2744
2745
2746
2747 if (iflag != ch->fepiflag)
2748 {
2749 ch->fepiflag = iflag;
2750
2751
2752
2753
2754
2755
2756
2757
2758 fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
2759 }
2760
2761
2762
2763
2764
2765
2766 bc->mint = ch->dcd;
2767
2768 if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD))
2769 if (ch->digiext.digi_flags & DIGI_FORCEDCD)
2770 bc->mint = 0;
2771
2772 ch->imodem = bc->mstat;
2773
2774 hflow = termios2digi_h(ch, ts->c_cflag);
2775
2776 if (hflow != ch->hflow)
2777 {
2778 ch->hflow = hflow;
2779
2780
2781
2782
2783
2784
2785 fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1);
2786 }
2787
2788
2789 mval ^= ch->modemfake & (mval ^ ch->modem);
2790
2791 if (ch->omodem ^ mval)
2792 {
2793 ch->omodem = mval;
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804 fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1);
2805 fepcmd(ch, SETMODEM, mval, 0, 0, 1);
2806
2807 }
2808
2809 if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc)
2810 {
2811 ch->fepstartc = ch->startc;
2812 ch->fepstopc = ch->stopc;
2813
2814
2815
2816
2817
2818
2819 fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
2820 }
2821
2822 if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca)
2823 {
2824 ch->fepstartca = ch->startca;
2825 ch->fepstopca = ch->stopca;
2826
2827
2828
2829
2830
2831
2832 fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
2833 }
2834
2835}
2836
2837
2838
2839static void receive_data(struct channel *ch)
2840{
2841
2842 unchar *rptr;
2843 struct termios *ts = 0;
2844 struct tty_struct *tty;
2845 volatile struct board_chan *bc;
2846 register int dataToRead, wrapgap, bytesAvailable;
2847 register unsigned int tail, head;
2848 unsigned int wrapmask;
2849 int rc;
2850
2851
2852
2853
2854
2855
2856
2857 globalwinon(ch);
2858
2859 if (ch->statusflags & RXSTOPPED)
2860 return;
2861
2862 tty = ch->tty;
2863 if (tty)
2864 ts = tty->termios;
2865
2866 bc = ch->brdchan;
2867
2868 if (!bc)
2869 {
2870 printk(KERN_ERR "<Error> - bc is NULL in receive_data!\n");
2871 return;
2872 }
2873
2874 wrapmask = ch->rxbufsize - 1;
2875
2876
2877
2878
2879
2880
2881 head = bc->rin;
2882 head &= wrapmask;
2883 tail = bc->rout & wrapmask;
2884
2885 bytesAvailable = (head - tail) & wrapmask;
2886
2887 if (bytesAvailable == 0)
2888 return;
2889
2890
2891
2892
2893
2894 if (!tty || !ts || !(ts->c_cflag & CREAD))
2895 {
2896 bc->rout = head;
2897 return;
2898 }
2899
2900 if (tty->flip.count == TTY_FLIPBUF_SIZE)
2901 return;
2902
2903 if (bc->orun)
2904 {
2905 bc->orun = 0;
2906 printk(KERN_WARNING "overrun! DigiBoard device minor = %d\n",MINOR(tty->device));
2907 }
2908
2909 rxwinon(ch);
2910 rptr = tty->flip.char_buf_ptr;
2911 rc = tty->flip.count;
2912
2913 while (bytesAvailable > 0)
2914 {
2915
2916 wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
2917
2918
2919
2920
2921
2922
2923
2924 dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable;
2925
2926
2927
2928
2929
2930 if ((rc + dataToRead) > TTY_FLIPBUF_SIZE)
2931 dataToRead = TTY_FLIPBUF_SIZE - rc;
2932
2933 if (dataToRead == 0)
2934 break;
2935
2936
2937
2938
2939
2940
2941 if ((memcpy(rptr, ch->rxptr + tail, dataToRead)) != rptr)
2942 printk(KERN_ERR "<Error> - receive_data : memcpy failed\n");
2943
2944 rc += dataToRead;
2945 rptr += dataToRead;
2946 tail = (tail + dataToRead) & wrapmask;
2947 bytesAvailable -= dataToRead;
2948
2949 }
2950
2951
2952 tty->flip.count = rc;
2953 tty->flip.char_buf_ptr = rptr;
2954 globalwinon(ch);
2955 bc->rout = tail;
2956
2957
2958 tty_schedule_flip(ch->tty);
2959 return;
2960
2961}
2962
2963
2964
2965static int pc_ioctl(struct tty_struct *tty, struct file * file,
2966 unsigned int cmd, unsigned long arg)
2967{
2968
2969 digiflow_t dflow;
2970 int retval, error;
2971 unsigned long flags;
2972 unsigned int mflag, mstat;
2973 unsigned char startc, stopc;
2974 volatile struct board_chan *bc;
2975 struct channel *ch = (struct channel *) tty->driver_data;
2976
2977
2978 if (tty->driver.subtype == SERIAL_TYPE_INFO)
2979 {
2980
2981 switch (cmd)
2982 {
2983
2984 case DIGI_GETINFO:
2985 {
2986
2987 struct digi_info di ;
2988 int brd;
2989
2990 getUser(brd, (unsigned int *)arg);
2991
2992 if ((error = verify_area(VERIFY_WRITE, (char*)arg, sizeof(di))))
2993 {
2994 printk(KERN_ERR "DIGI_GETINFO : verify area size 0x%x failed\n",sizeof(di));
2995 return(error);
2996 }
2997
2998 if ((brd < 0) || (brd >= num_cards) || (num_cards == 0))
2999 return (-ENODEV);
3000
3001 memset(&di, 0, sizeof(di));
3002
3003 di.board = brd ;
3004 di.status = boards[brd].status;
3005 di.type = boards[brd].type ;
3006 di.numports = boards[brd].numports ;
3007 di.port = boards[brd].port ;
3008 di.membase = boards[brd].membase ;
3009
3010 if (copy_to_user((char *)arg, &di, sizeof (di)))
3011 return -EFAULT;
3012 break;
3013
3014 }
3015
3016 case DIGI_POLLER:
3017 {
3018
3019 int brd = arg & 0xff000000 >> 16 ;
3020 unsigned char state = arg & 0xff ;
3021
3022 if ((brd < 0) || (brd >= num_cards))
3023 {
3024 printk(KERN_ERR "<Error> - DIGI POLLER : brd not valid!\n");
3025 return (-ENODEV);
3026 }
3027
3028 digi_poller_inhibited = state ;
3029 break ;
3030
3031 }
3032
3033 case DIGI_INIT:
3034 {
3035
3036
3037
3038
3039
3040
3041
3042
3043 int crd ;
3044 for (crd = 0; crd < num_cards; crd++)
3045 post_fep_init (crd);
3046
3047 break ;
3048
3049 }
3050
3051
3052 default:
3053 return -ENOIOCTLCMD;
3054
3055 }
3056 return (0) ;
3057
3058 }
3059
3060 if (ch)
3061 bc = ch->brdchan;
3062 else
3063 {
3064 printk(KERN_ERR "<Error> - ch is NULL in pc_ioctl!\n");
3065 return(-EINVAL);
3066 }
3067
3068 save_flags(flags);
3069
3070
3071
3072
3073
3074
3075
3076 switch (cmd)
3077 {
3078
3079 case TCGETS:
3080 if (copy_to_user((struct termios *)arg,
3081 tty->termios, sizeof(struct termios)))
3082 return -EFAULT;
3083 return(0);
3084
3085 case TCGETA:
3086 return get_termio(tty, (struct termio *)arg);
3087
3088 case TCSBRK:
3089
3090 retval = tty_check_change(tty);
3091 if (retval)
3092 return retval;
3093
3094
3095
3096 setup_empty_event(tty,ch);
3097 tty_wait_until_sent(tty, 0);
3098 if (!arg)
3099 digi_send_break(ch, HZ/4);
3100 return 0;
3101
3102 case TCSBRKP:
3103
3104 retval = tty_check_change(tty);
3105 if (retval)
3106 return retval;
3107
3108
3109
3110 setup_empty_event(tty,ch);
3111 tty_wait_until_sent(tty, 0);
3112 digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
3113 return 0;
3114
3115 case TIOCGSOFTCAR:
3116
3117 error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
3118 if (error)
3119 return error;
3120
3121 putUser(C_CLOCAL(tty) ? 1 : 0,
3122 (unsigned long *) arg);
3123 return 0;
3124
3125 case TIOCSSOFTCAR:
3126
3127 {
3128 unsigned int value;
3129
3130 getUser(value, (unsigned int *)arg);
3131 tty->termios->c_cflag =
3132 ((tty->termios->c_cflag & ~CLOCAL) |
3133 (value ? CLOCAL : 0));
3134 return 0;
3135 }
3136
3137 case TIOCMODG:
3138 case TIOCMGET:
3139
3140 mflag = 0;
3141
3142 cli();
3143 globalwinon(ch);
3144 mstat = bc->mstat;
3145 memoff(ch);
3146 restore_flags(flags);
3147
3148 if (mstat & ch->m_dtr)
3149 mflag |= TIOCM_DTR;
3150
3151 if (mstat & ch->m_rts)
3152 mflag |= TIOCM_RTS;
3153
3154 if (mstat & ch->m_cts)
3155 mflag |= TIOCM_CTS;
3156
3157 if (mstat & ch->dsr)
3158 mflag |= TIOCM_DSR;
3159
3160 if (mstat & ch->m_ri)
3161 mflag |= TIOCM_RI;
3162
3163 if (mstat & ch->dcd)
3164 mflag |= TIOCM_CD;
3165
3166 error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
3167
3168 if (error)
3169 return error;
3170
3171 putUser(mflag, (unsigned int *) arg);
3172
3173 break;
3174
3175 case TIOCMBIS:
3176 case TIOCMBIC:
3177 case TIOCMODS:
3178 case TIOCMSET:
3179
3180 getUser(mstat, (unsigned int *)arg);
3181
3182 mflag = 0;
3183 if (mstat & TIOCM_DTR)
3184 mflag |= ch->m_dtr;
3185
3186 if (mstat & TIOCM_RTS)
3187 mflag |= ch->m_rts;
3188
3189 switch (cmd)
3190 {
3191
3192 case TIOCMODS:
3193 case TIOCMSET:
3194 ch->modemfake = ch->m_dtr|ch->m_rts;
3195 ch->modem = mflag;
3196 break;
3197
3198 case TIOCMBIS:
3199 ch->modemfake |= mflag;
3200 ch->modem |= mflag;
3201 break;
3202
3203 case TIOCMBIC:
3204 ch->modemfake |= mflag;
3205 ch->modem &= ~mflag;
3206 break;
3207
3208 }
3209
3210 cli();
3211 globalwinon(ch);
3212
3213
3214
3215
3216
3217
3218 epcaparam(tty,ch);
3219 memoff(ch);
3220 restore_flags(flags);
3221 break;
3222
3223 case TIOCSDTR:
3224 ch->omodem |= ch->m_dtr;
3225 cli();
3226 globalwinon(ch);
3227 fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1);
3228 memoff(ch);
3229 restore_flags(flags);
3230 break;
3231
3232 case TIOCCDTR:
3233 ch->omodem &= ~ch->m_dtr;
3234 cli();
3235 globalwinon(ch);
3236 fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1);
3237 memoff(ch);
3238 restore_flags(flags);
3239 break;
3240
3241 case DIGI_GETA:
3242 if (copy_to_user((char*)arg, &ch->digiext,
3243 sizeof(digi_t)))
3244 return -EFAULT;
3245 break;
3246
3247 case DIGI_SETAW:
3248 case DIGI_SETAF:
3249 if ((cmd) == (DIGI_SETAW))
3250 {
3251
3252
3253 setup_empty_event(tty,ch);
3254 tty_wait_until_sent(tty, 0);
3255 }
3256 else
3257 {
3258 if (tty->ldisc.flush_buffer)
3259 tty->ldisc.flush_buffer(tty);
3260 }
3261
3262
3263
3264 case DIGI_SETA:
3265 if (copy_from_user(&ch->digiext, (char*)arg,
3266 sizeof(digi_t)))
3267 return -EFAULT;
3268
3269 if (ch->digiext.digi_flags & DIGI_ALTPIN)
3270 {
3271 ch->dcd = ch->m_dsr;
3272 ch->dsr = ch->m_dcd;
3273 }
3274 else
3275 {
3276 ch->dcd = ch->m_dcd;
3277 ch->dsr = ch->m_dsr;
3278 }
3279
3280 cli();
3281 globalwinon(ch);
3282
3283
3284
3285
3286
3287
3288 epcaparam(tty,ch);
3289 memoff(ch);
3290 restore_flags(flags);
3291 break;
3292
3293 case DIGI_GETFLOW:
3294 case DIGI_GETAFLOW:
3295 cli();
3296 globalwinon(ch);
3297 if ((cmd) == (DIGI_GETFLOW))
3298 {
3299 dflow.startc = bc->startc;
3300 dflow.stopc = bc->stopc;
3301 }
3302 else
3303 {
3304 dflow.startc = bc->startca;
3305 dflow.stopc = bc->stopca;
3306 }
3307 memoff(ch);
3308 restore_flags(flags);
3309
3310 if (copy_to_user((char*)arg, &dflow, sizeof(dflow)))
3311 return -EFAULT;
3312 break;
3313
3314 case DIGI_SETAFLOW:
3315 case DIGI_SETFLOW:
3316 if ((cmd) == (DIGI_SETFLOW))
3317 {
3318 startc = ch->startc;
3319 stopc = ch->stopc;
3320 }
3321 else
3322 {
3323 startc = ch->startca;
3324 stopc = ch->stopca;
3325 }
3326
3327 if (copy_from_user(&dflow, (char*)arg, sizeof(dflow)))
3328 return -EFAULT;
3329
3330 if (dflow.startc != startc || dflow.stopc != stopc)
3331 {
3332 cli();
3333 globalwinon(ch);
3334
3335 if ((cmd) == (DIGI_SETFLOW))
3336 {
3337 ch->fepstartc = ch->startc = dflow.startc;
3338 ch->fepstopc = ch->stopc = dflow.stopc;
3339 fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
3340 }
3341 else
3342 {
3343 ch->fepstartca = ch->startca = dflow.startc;
3344 ch->fepstopca = ch->stopca = dflow.stopc;
3345 fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
3346 }
3347
3348 if (ch->statusflags & TXSTOPPED)
3349 pc_start(tty);
3350
3351 memoff(ch);
3352 restore_flags(flags);
3353
3354 }
3355 break;
3356
3357 default:
3358 return -ENOIOCTLCMD;
3359
3360 }
3361
3362 return 0;
3363
3364}
3365
3366
3367
3368static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios)
3369{
3370
3371 struct channel *ch;
3372 unsigned long flags;
3373
3374
3375
3376
3377
3378
3379 if ((ch = verifyChannel(tty)) != NULL)
3380 {
3381
3382 save_flags(flags);
3383 cli();
3384 globalwinon(ch);
3385 epcaparam(tty, ch);
3386 memoff(ch);
3387
3388 if ((old_termios->c_cflag & CRTSCTS) &&
3389 ((tty->termios->c_cflag & CRTSCTS) == 0))
3390 tty->hw_stopped = 0;
3391
3392 if (!(old_termios->c_cflag & CLOCAL) &&
3393 (tty->termios->c_cflag & CLOCAL))
3394 wake_up_interruptible(&ch->open_wait);
3395
3396 restore_flags(flags);
3397
3398 }
3399
3400}
3401
3402
3403
3404static void do_softint(void *private_)
3405{
3406
3407 struct channel *ch = (struct channel *) private_;
3408
3409
3410
3411
3412 if (ch && ch->magic == EPCA_MAGIC)
3413 {
3414
3415 struct tty_struct *tty = ch->tty;
3416
3417 if (tty && tty->driver_data)
3418 {
3419 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event))
3420 {
3421
3422 tty_hangup(tty);
3423 wake_up_interruptible(&ch->open_wait);
3424 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
3425
3426 }
3427 }
3428
3429 }
3430 MOD_DEC_USE_COUNT;
3431}
3432
3433
3434
3435
3436
3437
3438
3439
3440static void pc_stop(struct tty_struct *tty)
3441{
3442
3443 struct channel *ch;
3444 unsigned long flags;
3445
3446
3447
3448
3449
3450
3451 if ((ch = verifyChannel(tty)) != NULL)
3452 {
3453
3454 save_flags(flags);
3455 cli();
3456
3457 if ((ch->statusflags & TXSTOPPED) == 0)
3458 {
3459
3460 globalwinon(ch);
3461
3462
3463
3464 fepcmd(ch, PAUSETX, 0, 0, 0, 0);
3465
3466 ch->statusflags |= TXSTOPPED;
3467 memoff(ch);
3468
3469 }
3470
3471 restore_flags(flags);
3472
3473 }
3474
3475}
3476
3477
3478
3479static void pc_start(struct tty_struct *tty)
3480{
3481
3482 struct channel *ch;
3483
3484
3485
3486
3487
3488
3489 if ((ch = verifyChannel(tty)) != NULL)
3490 {
3491
3492 unsigned long flags;
3493
3494 save_flags(flags);
3495 cli();
3496
3497
3498 if (ch->statusflags & TXSTOPPED)
3499 {
3500
3501 volatile struct board_chan *bc;
3502
3503 globalwinon(ch);
3504 bc = ch->brdchan;
3505 if (ch->statusflags & LOWWAIT)
3506 bc->ilow = 1;
3507
3508
3509
3510 fepcmd(ch, RESUMETX, 0, 0, 0, 0);
3511
3512 ch->statusflags &= ~TXSTOPPED;
3513 memoff(ch);
3514
3515 }
3516
3517 restore_flags(flags);
3518
3519 }
3520
3521}
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533static void pc_throttle(struct tty_struct * tty)
3534{
3535
3536 struct channel *ch;
3537 unsigned long flags;
3538
3539
3540
3541
3542
3543
3544 if ((ch = verifyChannel(tty)) != NULL)
3545 {
3546
3547
3548 save_flags(flags);
3549 cli();
3550
3551 if ((ch->statusflags & RXSTOPPED) == 0)
3552 {
3553 globalwinon(ch);
3554 fepcmd(ch, PAUSERX, 0, 0, 0, 0);
3555
3556 ch->statusflags |= RXSTOPPED;
3557 memoff(ch);
3558 }
3559 restore_flags(flags);
3560
3561 }
3562
3563}
3564
3565
3566
3567static void pc_unthrottle(struct tty_struct *tty)
3568{
3569
3570 struct channel *ch;
3571 unsigned long flags;
3572 volatile struct board_chan *bc;
3573
3574
3575
3576
3577
3578
3579
3580 if ((ch = verifyChannel(tty)) != NULL)
3581 {
3582
3583
3584
3585 save_flags(flags);
3586 cli();
3587
3588 if (ch->statusflags & RXSTOPPED)
3589 {
3590
3591 globalwinon(ch);
3592 bc = ch->brdchan;
3593 fepcmd(ch, RESUMERX, 0, 0, 0, 0);
3594
3595 ch->statusflags &= ~RXSTOPPED;
3596 memoff(ch);
3597 }
3598 restore_flags(flags);
3599
3600 }
3601
3602}
3603
3604
3605
3606void digi_send_break(struct channel *ch, int msec)
3607{
3608
3609 unsigned long flags;
3610
3611 save_flags(flags);
3612 cli();
3613 globalwinon(ch);
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623 fepcmd(ch, SENDBREAK, msec, 0, 10, 0);
3624 memoff(ch);
3625
3626 restore_flags(flags);
3627
3628}
3629
3630
3631
3632static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
3633{
3634
3635 volatile struct board_chan *bc = ch->brdchan;
3636 unsigned long int flags;
3637
3638 save_flags(flags);
3639 cli();
3640 globalwinon(ch);
3641 ch->statusflags |= EMPTYWAIT;
3642
3643
3644
3645
3646
3647
3648 bc->iempty = 1;
3649 memoff(ch);
3650 restore_flags(flags);
3651
3652}
3653
3654
3655
3656static int get_termio(struct tty_struct * tty, struct termio * termio)
3657{
3658 int error;
3659
3660 error = verify_area(VERIFY_WRITE, termio, sizeof (struct termio));
3661 if (error)
3662 return error;
3663
3664 kernel_termios_to_user_termio(termio, tty->termios);
3665
3666 return 0;
3667}
3668
3669void epca_setup(char *str, int *ints)
3670{
3671
3672 struct board_info board;
3673 int index, loop, last;
3674 char *temp, *t2;
3675 unsigned len;
3676
3677
3678
3679
3680
3681
3682
3683 if (!liloconfig)
3684 liloconfig = 1;
3685
3686 memset(&board, 0, sizeof(board));
3687
3688
3689
3690 for (last = 0, index = 1; index <= ints[0]; index++)
3691 switch(index)
3692 {
3693
3694 case 1:
3695 board.status = ints[index];
3696
3697
3698
3699
3700
3701
3702 if (board.status == 2)
3703 {
3704 nbdevs = 0;
3705 num_cards = 0;
3706 return;
3707 }
3708
3709 if (board.status > 2)
3710 {
3711 printk(KERN_ERR "<Error> - epca_setup: Invalid board status 0x%x\n", board.status);
3712 invalid_lilo_config = 1;
3713 setup_error_code |= INVALID_BOARD_STATUS;
3714 return;
3715 }
3716 last = index;
3717 break;
3718
3719 case 2:
3720 board.type = ints[index];
3721 if (board.type >= PCIXEM)
3722 {
3723 printk(KERN_ERR "<Error> - epca_setup: Invalid board type 0x%x\n", board.type);
3724 invalid_lilo_config = 1;
3725 setup_error_code |= INVALID_BOARD_TYPE;
3726 return;
3727 }
3728 last = index;
3729 break;
3730
3731 case 3:
3732 board.altpin = ints[index];
3733 if (board.altpin > 1)
3734 {
3735 printk(KERN_ERR "<Error> - epca_setup: Invalid board altpin 0x%x\n", board.altpin);
3736 invalid_lilo_config = 1;
3737 setup_error_code |= INVALID_ALTPIN;
3738 return;
3739 }
3740 last = index;
3741 break;
3742
3743 case 4:
3744 board.numports = ints[index];
3745 if ((board.numports < 2) || (board.numports > 256))
3746 {
3747 printk(KERN_ERR "<Error> - epca_setup: Invalid board numports 0x%x\n", board.numports);
3748 invalid_lilo_config = 1;
3749 setup_error_code |= INVALID_NUM_PORTS;
3750 return;
3751 }
3752 nbdevs += board.numports;
3753 last = index;
3754 break;
3755
3756 case 5:
3757 board.port = (unsigned char *)ints[index];
3758 if (ints[index] <= 0)
3759 {
3760 printk(KERN_ERR "<Error> - epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port);
3761 invalid_lilo_config = 1;
3762 setup_error_code |= INVALID_PORT_BASE;
3763 return;
3764 }
3765 last = index;
3766 break;
3767
3768 case 6:
3769 board.membase = (unsigned char *)ints[index];
3770 if (ints[index] <= 0)
3771 {
3772 printk(KERN_ERR "<Error> - epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase);
3773 invalid_lilo_config = 1;
3774 setup_error_code |= INVALID_MEM_BASE;
3775 return;
3776 }
3777 last = index;
3778 break;
3779
3780 default:
3781 printk(KERN_ERR "<Error> - epca_setup: Too many integer parms\n");
3782 return;
3783
3784 }
3785
3786 while (str && *str)
3787 {
3788
3789
3790 temp = str;
3791
3792
3793 while (*temp && (*temp != ','))
3794 temp++;
3795
3796 if (!*temp)
3797 temp = NULL;
3798 else
3799 *temp++ = 0;
3800
3801
3802 index = last + 1;
3803
3804 switch(index)
3805 {
3806 case 1:
3807 len = strlen(str);
3808 if (strncmp("Disable", str, len) == 0)
3809 board.status = 0;
3810 else
3811 if (strncmp("Enable", str, len) == 0)
3812 board.status = 1;
3813 else
3814 {
3815 printk(KERN_ERR "<Error> - epca_setup: Invalid status %s\n", str);
3816 invalid_lilo_config = 1;
3817 setup_error_code |= INVALID_BOARD_STATUS;
3818 return;
3819 }
3820 last = index;
3821 break;
3822
3823 case 2:
3824
3825 for(loop = 0; loop < EPCA_NUM_TYPES; loop++)
3826 if (strcmp(board_desc[loop], str) == 0)
3827 break;
3828
3829
3830
3831
3832
3833
3834
3835 if (index < EPCA_NUM_TYPES)
3836 board.type = loop;
3837 else
3838 {
3839 printk(KERN_ERR "<Error> - epca_setup: Invalid board type: %s\n", str);
3840 invalid_lilo_config = 1;
3841 setup_error_code |= INVALID_BOARD_TYPE;
3842 return;
3843 }
3844 last = index;
3845 break;
3846
3847 case 3:
3848 len = strlen(str);
3849 if (strncmp("Disable", str, len) == 0)
3850 board.altpin = 0;
3851 else
3852 if (strncmp("Enable", str, len) == 0)
3853 board.altpin = 1;
3854 else
3855 {
3856 printk(KERN_ERR "<Error> - epca_setup: Invalid altpin %s\n", str);
3857 invalid_lilo_config = 1;
3858 setup_error_code |= INVALID_ALTPIN;
3859 return;
3860 }
3861 last = index;
3862 break;
3863
3864 case 4:
3865 t2 = str;
3866 while (isdigit(*t2))
3867 t2++;
3868
3869 if (*t2)
3870 {
3871 printk(KERN_ERR "<Error> - epca_setup: Invalid port count %s\n", str);
3872 invalid_lilo_config = 1;
3873 setup_error_code |= INVALID_NUM_PORTS;
3874 return;
3875 }
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890 board.numports = simple_strtoul(str, NULL, 0);
3891 nbdevs += board.numports;
3892 last = index;
3893 break;
3894
3895 case 5:
3896 t2 = str;
3897 while (isxdigit(*t2))
3898 t2++;
3899
3900 if (*t2)
3901 {
3902 printk(KERN_ERR "<Error> - epca_setup: Invalid i/o address %s\n", str);
3903 invalid_lilo_config = 1;
3904 setup_error_code |= INVALID_PORT_BASE;
3905 return;
3906 }
3907
3908 board.port = (unsigned char *)simple_strtoul(str, NULL, 16);
3909 last = index;
3910 break;
3911
3912 case 6:
3913 t2 = str;
3914 while (isxdigit(*t2))
3915 t2++;
3916
3917 if (*t2)
3918 {
3919 printk(KERN_ERR "<Error> - epca_setup: Invalid memory base %s\n",str);
3920 invalid_lilo_config = 1;
3921 setup_error_code |= INVALID_MEM_BASE;
3922 return;
3923 }
3924
3925 board.membase = (unsigned char *)simple_strtoul(str, NULL, 16);
3926 last = index;
3927 break;
3928
3929 default:
3930 printk(KERN_ERR "PC/Xx: Too many string parms\n");
3931 return;
3932 }
3933 str = temp;
3934
3935 }
3936
3937
3938 if (last < 6)
3939 {
3940 printk(KERN_ERR "PC/Xx: Insufficient parms specified\n");
3941 return;
3942 }
3943
3944
3945
3946
3947 memcpy((void *)&boards[num_cards],(void *)&board, sizeof(board));
3948
3949
3950
3951
3952 printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n",
3953 num_cards, board_desc[board.type],
3954 board.numports, (int)board.port, (unsigned int) board.membase);
3955
3956 num_cards++;
3957
3958}
3959
3960
3961
3962#ifdef ENABLE_PCI
3963
3964
3965enum epic_board_types {
3966 brd_xr = 0,
3967 brd_xem,
3968 brd_cx,
3969 brd_xrj,
3970};
3971
3972
3973
3974static struct {
3975 unsigned char board_type;
3976 unsigned bar_idx;
3977} epca_info_tbl[] = {
3978 { PCIXR, 0, },
3979 { PCIXEM, 0, },
3980 { PCICX, 0, },
3981 { PCIXRJ, 2, },
3982};
3983
3984
3985static int __init epca_init_one (struct pci_dev *pdev,
3986 const struct pci_device_id *ent)
3987{
3988 static int board_num = -1;
3989 int board_idx, info_idx = ent->driver_data;
3990 unsigned long addr;
3991
3992 if (pci_enable_device(pdev))
3993 return -EIO;
3994
3995 board_num++;
3996 board_idx = board_num + num_cards;
3997 if (board_idx >= MAXBOARDS)
3998 goto err_out;
3999
4000 addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx);
4001 if (!addr) {
4002 printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n",
4003 epca_info_tbl[info_idx].bar_idx);
4004 goto err_out;
4005 }
4006
4007 boards[board_idx].status = ENABLED;
4008 boards[board_idx].type = epca_info_tbl[info_idx].board_type;
4009 boards[board_idx].numports = 0x0;
4010 boards[board_idx].port =
4011 (unsigned char *)((char *) addr + PCI_IO_OFFSET);
4012 boards[board_idx].membase =
4013 (unsigned char *)((char *) addr);
4014
4015 if (!request_mem_region (addr + PCI_IO_OFFSET, 0x200000, "epca")) {
4016 printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
4017 0x200000, addr + PCI_IO_OFFSET);
4018 goto err_out;
4019 }
4020
4021 boards[board_idx].re_map_port = ioremap(addr + PCI_IO_OFFSET, 0x200000);
4022 if (!boards[board_idx].re_map_port) {
4023 printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
4024 0x200000, addr + PCI_IO_OFFSET);
4025 goto err_out_free_pciio;
4026 }
4027
4028 if (!request_mem_region (addr, 0x200000, "epca")) {
4029 printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
4030 0x200000, addr);
4031 goto err_out_free_iounmap;
4032 }
4033
4034 boards[board_idx].re_map_membase = ioremap(addr, 0x200000);
4035 if (!boards[board_idx].re_map_membase) {
4036 printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
4037 0x200000, addr + PCI_IO_OFFSET);
4038 goto err_out_free_memregion;
4039 }
4040
4041
4042
4043
4044
4045 if (info_idx != brd_xrj) {
4046 pci_write_config_byte(pdev, 0x40, 0);
4047 pci_write_config_byte(pdev, 0x46, 0);
4048 }
4049
4050 return 0;
4051
4052err_out_free_memregion:
4053 release_mem_region (addr, 0x200000);
4054err_out_free_iounmap:
4055 iounmap (boards[board_idx].re_map_port);
4056err_out_free_pciio:
4057 release_mem_region (addr + PCI_IO_OFFSET, 0x200000);
4058err_out:
4059 return -ENODEV;
4060}
4061
4062
4063static struct pci_device_id epca_pci_tbl[] __initdata = {
4064 { PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr },
4065 { PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem },
4066 { PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx },
4067 { PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj },
4068 { 0, }
4069};
4070
4071MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
4072
4073int __init init_PCI (void)
4074{
4075
4076 int pci_count;
4077
4078 memset (&epca_driver, 0, sizeof (epca_driver));
4079 epca_driver.name = "epca";
4080 epca_driver.id_table = epca_pci_tbl;
4081 epca_driver.probe = epca_init_one;
4082
4083 pci_count = pci_register_driver (&epca_driver);
4084
4085 if (pci_count <= 0) {
4086 pci_unregister_driver (&epca_driver);
4087 pci_count = 0;
4088 }
4089
4090 return(pci_count);
4091
4092}
4093
4094#endif
4095
4096MODULE_LICENSE("GPL");
4097