This source file includes following definitions.
- serial_paranoia_check
- SP
- CP
- CP1
- CP2
- CP4
- CP8
- write_cy_cmd
- cy_stop
- cy_start
- cy_sched_event
- cy_probe
- cy_interrupt
- do_cyclades_bh
- do_softint
- grab_all_interrupts
- free_all_interrupts
- check_wild_interrupts
- get_auto_irq
- do_auto_irq
- startup
- start_xmit
- shutdown
- config_setup
- cy_put_char
- cy_flush_chars
- cy_write
- cy_write_room
- cy_chars_in_buffer
- cy_flush_buffer
- cy_throttle
- cy_unthrottle
- get_serial_info
- set_serial_info
- get_modem_info
- set_modem_info
- send_break
- cy_ioctl
- cy_set_termios
- cy_close
- cy_hangup
- block_til_ready
- cy_open
- show_version
- cy_init_card
- cy_init
- show_status
1 static char rcsid[] =
2 "$Revision: 1.35 $$Date: 1994/12/16 13:54:18 $";
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 #include <linux/errno.h>
173 #include <linux/signal.h>
174 #include <linux/sched.h>
175 #include <linux/timer.h>
176 #include <linux/tty.h>
177 #include <linux/serial.h>
178 #include <linux/interrupt.h>
179 #include <linux/string.h>
180 #include <linux/fcntl.h>
181 #include <linux/ptrace.h>
182 #include <linux/cyclades.h>
183 #include <linux/delay.h>
184 #include <linux/major.h>
185
186 #include <asm/system.h>
187 #include <asm/io.h>
188 #include <asm/segment.h>
189 #include <asm/bitops.h>
190
191 #define small_delay(x) for(j=0;j<x;j++)k++;
192
193
194 #define SERIAL_PARANOIA_CHECK
195 #undef SERIAL_DEBUG_OPEN
196 #undef SERIAL_DEBUG_THROTTLE
197 #undef SERIAL_DEBUG_OTHER
198 #undef SERIAL_DEBUG_IO
199 #undef SERIAL_DEBUG_COUNT
200 #undef SERIAL_DEBUG_DTR
201
202 #ifndef MIN
203 #define MIN(a,b) ((a) < (b) ? (a) : (b))
204 #endif
205
206 #define WAKEUP_CHARS 256
207
208 #define STD_COM_FLAGS (0)
209
210 #define SERIAL_TYPE_NORMAL 1
211 #define SERIAL_TYPE_CALLOUT 2
212
213
214 DECLARE_TASK_QUEUE(tq_cyclades);
215
216 struct tty_driver cy_serial_driver, cy_callout_driver;
217
218 static volatile int cy_irq_triggered;
219 static volatile int cy_triggered;
220 static int cy_wild_int_mask;
221 static unsigned char *intr_base_addr;
222
223
224 struct cyclades_card cy_card[] = {
225
226 {0xD0000,0},
227 {0xD2000,0},
228 {0xD4000,10},
229 {0xD6000,11},
230 {0xD8000,12},
231 {0xDA000,15}
232 };
233
234 #define NR_CARDS (sizeof(cy_card)/sizeof(struct cyclades_card))
235
236
237
238
239
240
241
242
243
244 struct cyclades_port cy_port[] = {
245
246 {-1 },
247 {-1 },
248 {-1 },
249 {-1 },
250 {-1 },
251 {-1 },
252 {-1 },
253 {-1 },
254 {-1 },
255 {-1 },
256 {-1 },
257 {-1 },
258 {-1 },
259 {-1 },
260 {-1 },
261 {-1 },
262 {-1 },
263 {-1 },
264 {-1 },
265 {-1 },
266 {-1 },
267 {-1 },
268 {-1 },
269 {-1 },
270 {-1 },
271 {-1 },
272 {-1 },
273 {-1 },
274 {-1 },
275 {-1 },
276 {-1 },
277 {-1 }
278 };
279 #define NR_PORTS (sizeof(cy_port)/sizeof(struct cyclades_port))
280
281 static int serial_refcount;
282
283 static struct tty_struct *serial_table[NR_PORTS];
284 static struct termios *serial_termios[NR_PORTS];
285 static struct termios *serial_termios_locked[NR_PORTS];
286
287
288
289
290 struct cyclades_card * IRQ_cards[16];
291
292
293
294
295
296
297
298
299
300
301
302 static unsigned char *tmp_buf = 0;
303 static struct semaphore tmp_buf_sem = MUTEX;
304
305
306
307
308
309
310
311
312
313 static int baud_table[] = {
314 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
315 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,115200,150000,
316 0};
317
318 static char baud_co[] = {
319
320
321 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
322 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
323
324 static char baud_bpr[] = {
325 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
326 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15};
327
328 static char baud_cor3[] = {
329 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
330 0x0a, 0x0a, 0x0a, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x01};
331
332
333
334 static void shutdown(struct cyclades_port *);
335 static int startup (struct cyclades_port *);
336 static void cy_throttle(struct tty_struct *);
337 static void cy_unthrottle(struct tty_struct *);
338 static void config_setup(struct cyclades_port *);
339 extern void console_print(const char *);
340 static void show_status(int);
341
342
343
344 static inline int
345 serial_paranoia_check(struct cyclades_port *info,
346 dev_t device, const char *routine)
347 {
348 #ifdef SERIAL_PARANOIA_CHECK
349 static const char *badmagic =
350 "Warning: bad magic number for serial struct (%d, %d) in %s\n";
351 static const char *badinfo =
352 "Warning: null cyclades_port for (%d, %d) in %s\n";
353 static const char *badrange =
354 "Warning: cyclades_port out of range for (%d, %d) in %s\n";
355
356 if (!info) {
357 printk(badinfo, MAJOR(device), MINOR(device), routine);
358 return 1;
359 }
360
361 if( (long)info < (long)(&cy_port[0])
362 || (long)(&cy_port[NR_PORTS]) < (long)info ){
363 printk(badrange, MAJOR(device), MINOR(device), routine);
364 return 1;
365 }
366
367 if (info->magic != CYCLADES_MAGIC) {
368 printk(badmagic, MAJOR(device), MINOR(device), routine);
369 return 1;
370 }
371 #endif
372 return 0;
373 }
374
375
376
377
378 void
379 SP(char *data){
380 unsigned long flags;
381 save_flags(flags); cli();
382 console_print(data);
383 restore_flags(flags);
384 }
385 char scrn[2];
386 void
387 CP(char data){
388 unsigned long flags;
389 save_flags(flags); cli();
390 scrn[0] = data;
391 console_print(scrn);
392 restore_flags(flags);
393 }
394
395 void CP1(int data) { (data<10)? CP(data+'0'): CP(data+'A'-10); }
396 void CP2(int data) { CP1((data>>4) & 0x0f); CP1( data & 0x0f); }
397 void CP4(int data) { CP2((data>>8) & 0xff); CP2(data & 0xff); }
398 void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }
399
400
401
402
403
404
405
406 u_short
407 write_cy_cmd(u_char *base_addr, u_char cmd)
408 {
409 unsigned long flags;
410 volatile int i;
411
412 save_flags(flags); cli();
413
414 for(i = 0 ; i < 10000 ; i++){
415 if (base_addr[CyCCR] == 0){
416 break;
417 }
418 udelay(10L);
419 }
420
421
422 if ( i == 10 ) {
423 restore_flags(flags);
424 return (-1);
425 }
426
427
428 base_addr[CyCCR] = cmd;
429 restore_flags(flags);
430 return(0);
431 }
432
433
434
435
436
437 static void
438 cy_stop(struct tty_struct *tty)
439 {
440 struct cyclades_card *cinfo;
441 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
442 unsigned char *base_addr;
443 int chip,channel;
444 unsigned long flags;
445
446 #ifdef SERIAL_DEBUG_OTHER
447 printk("cy_stop ttyC%d\n", info->line);
448 #endif
449
450 if (serial_paranoia_check(info, tty->device, "cy_stop"))
451 return;
452
453 cinfo = &cy_card[info->card];
454 channel = info->line - cinfo->first_line;
455 chip = channel>>2;
456 channel &= 0x03;
457 base_addr = (unsigned char*)
458 (cy_card[info->card].base_addr + chip * CyRegSize);
459
460 save_flags(flags); cli();
461 base_addr[CyCAR] = (u_char)(channel & 0x0003);
462 base_addr[CySRER] &= ~CyTxMpty;
463 restore_flags(flags);
464
465 return;
466 }
467
468 static void
469 cy_start(struct tty_struct *tty)
470 {
471 struct cyclades_card *cinfo;
472 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
473 unsigned char *base_addr;
474 int chip,channel;
475 unsigned long flags;
476
477 #ifdef SERIAL_DEBUG_OTHER
478 printk("cy_start ttyC%d\n", info->line);
479 #endif
480
481 if (serial_paranoia_check(info, tty->device, "cy_start"))
482 return;
483
484 cinfo = &cy_card[info->card];
485 channel = info->line - cinfo->first_line;
486 chip = channel>>2;
487 channel &= 0x03;
488 base_addr = (unsigned char*)
489 (cy_card[info->card].base_addr + chip * CyRegSize);
490
491 save_flags(flags); cli();
492 base_addr[CyCAR] = (u_char)(channel & 0x0003);
493 base_addr[CySRER] |= CyTxMpty;
494 restore_flags(flags);
495
496 return;
497 }
498
499
500
501
502
503
504
505
506 static inline void
507 cy_sched_event(struct cyclades_port *info, int event)
508 {
509 info->event |= 1 << event;
510 queue_task_irq_off(&info->tqueue, &tq_cyclades);
511 mark_bh(CYCLADES_BH);
512 }
513
514
515
516
517
518
519
520 static void
521 cy_probe(int irq)
522 {
523 cy_irq_triggered = irq;
524 cy_triggered |= 1 << irq;
525 return;
526 }
527
528
529
530
531
532 static void
533 cy_interrupt(int irq)
534 {
535 struct tty_struct *tty;
536 int status;
537 struct cyclades_card *cinfo;
538 struct cyclades_port *info;
539 volatile unsigned char *base_addr, *card_base_addr;
540 int chip;
541 int save_xir, channel, save_car;
542 char data;
543 volatile char vdata;
544 int char_count;
545 int outch;
546 int i,j;
547 int too_many;
548 int had_work;
549 int mdm_change;
550 int mdm_status;
551
552 if((cinfo = IRQ_cards[irq]) == 0){
553 return;
554 }
555
556
557
558
559
560
561 do{
562 had_work = 0;
563 for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) {
564 base_addr = (unsigned char *)(cinfo->base_addr
565 + CyRegSize * chip);
566 too_many = 0;
567 while ( (status = base_addr[CySVRR]) != 0x00) {
568 had_work++;
569
570
571
572
573
574 if(1000<too_many++){
575 break;
576 }
577 if (status & CySRReceive) {
578
579
580 save_xir = (u_char) base_addr[CyRIR];
581 channel = (u_short ) (save_xir & CyIRChannel);
582 i = channel + chip * 4 + cinfo->first_line;
583 info = &cy_port[i];
584 info->last_active = jiffies;
585 save_car = base_addr[CyCAR];
586 base_addr[CyCAR] = save_xir;
587
588
589 if(info->tty == 0){
590 j = (base_addr[CyRIVR] & CyIVRMask);
591 if ( j == CyIVRRxEx ) {
592 data = base_addr[CyRDSR];
593 } else {
594 char_count = base_addr[CyRDCR];
595 while(char_count--){
596 data = base_addr[CyRDSR];
597 }
598 }
599 }else{
600 tty = info->tty;
601 j = (base_addr[CyRIVR] & CyIVRMask);
602 if ( j == CyIVRRxEx ) {
603 data = base_addr[CyRDSR];
604 if(data & info->ignore_status_mask){
605 continue;
606 }
607 if (tty->flip.count < TTY_FLIPBUF_SIZE){
608 tty->flip.count++;
609 if (data & info->read_status_mask){
610 if(data & CyBREAK){
611 *tty->flip.flag_buf_ptr++ =
612 TTY_BREAK;
613 *tty->flip.char_buf_ptr++ =
614 base_addr[CyRDSR];
615 if (info->flags & ASYNC_SAK){
616 do_SAK(tty);
617 }
618 }else if(data & CyFRAME){
619 *tty->flip.flag_buf_ptr++ =
620 TTY_FRAME;
621 *tty->flip.char_buf_ptr++ =
622 base_addr[CyRDSR];
623 }else if(data & CyPARITY){
624 *tty->flip.flag_buf_ptr++ =
625 TTY_PARITY;
626 *tty->flip.char_buf_ptr++ =
627 base_addr[CyRDSR];
628 }else if(data & CyOVERRUN){
629 *tty->flip.flag_buf_ptr++ =
630 TTY_OVERRUN;
631 *tty->flip.char_buf_ptr++ = 0;
632
633
634
635
636 if(tty->flip.count < TTY_FLIPBUF_SIZE){
637 tty->flip.count++;
638 *tty->flip.flag_buf_ptr++ =
639 TTY_NORMAL;
640 *tty->flip.char_buf_ptr++ =
641 base_addr[CyRDSR];
642 }
643
644
645
646
647 }else{
648 *tty->flip.flag_buf_ptr++ = 0;
649 *tty->flip.char_buf_ptr++ = 0;
650 }
651 }else{
652 *tty->flip.flag_buf_ptr++ = 0;
653 *tty->flip.char_buf_ptr++ = 0;
654 }
655 }else{
656
657
658 }
659 } else {
660
661 char_count = base_addr[CyRDCR];
662
663 while(char_count--){
664 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
665 break;
666 }
667 tty->flip.count++;
668 data = base_addr[CyRDSR];
669 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
670 *tty->flip.char_buf_ptr++ = data;
671 }
672 }
673 queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
674 }
675
676 base_addr[CyRIR] = (save_xir & 0x3f);
677 base_addr[CyCAR] = (save_car);
678 }
679
680
681 if (status & CySRTransmit) {
682
683
684
685
686 save_xir = (u_char) base_addr[CyTIR];
687 channel = (u_short ) (save_xir & CyIRChannel);
688 i = channel + chip * 4 + cinfo->first_line;
689 save_car = base_addr[CyCAR];
690 base_addr[CyCAR] = save_xir;
691
692
693 if( (i < 0) || (NR_PORTS <= i) ){
694 base_addr[CySRER] &= ~CyTxMpty;
695 goto txend;
696 }
697 info = &cy_port[i];
698 info->last_active = jiffies;
699 if(info->tty == 0){
700 base_addr[CySRER] &= ~CyTxMpty;
701 goto txdone;
702 }
703
704
705 char_count = info->xmit_fifo_size;
706
707
708 if(info->x_char) {
709 outch = info->x_char;
710 base_addr[CyTDR] = outch;
711 char_count--;
712 info->x_char = 0;
713 }
714
715 if (info->x_break){
716
717
718
719
720
721
722
723
724 base_addr[CyTDR] = 0;
725 base_addr[CyTDR] = 0x81;
726 base_addr[CyTDR] = 0;
727 base_addr[CyTDR] = 0x82;
728 base_addr[CyTDR] = info->x_break*200/HZ;
729 base_addr[CyTDR] = 0;
730 base_addr[CyTDR] = 0x83;
731 char_count -= 7;
732 info->x_break = 0;
733 }
734
735 while (char_count-- > 0){
736 if (!info->xmit_cnt){
737 base_addr[CySRER] &= ~CyTxMpty;
738 goto txdone;
739 }
740 if (info->tty->stopped || info->tty->hw_stopped){
741 base_addr[CySRER] &= ~CyTxMpty;
742 goto txdone;
743 }
744
745
746
747
748
749
750
751
752
753
754
755 outch = info->xmit_buf[info->xmit_tail];
756 if( outch ){
757 info->xmit_cnt--;
758 info->xmit_tail = (info->xmit_tail + 1)
759 & (PAGE_SIZE - 1);
760 base_addr[CyTDR] = outch;
761 }else{
762 if(char_count > 1){
763 info->xmit_cnt--;
764 info->xmit_tail = (info->xmit_tail + 1)
765 & (PAGE_SIZE - 1);
766 base_addr[CyTDR] = outch;
767 base_addr[CyTDR] = 0;
768 char_count--;
769 }else{
770 }
771 }
772 }
773
774 txdone:
775 if (info->xmit_cnt < WAKEUP_CHARS) {
776 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
777 }
778
779 txend:
780
781 base_addr[CyTIR] = (save_xir & 0x3f);
782 base_addr[CyCAR] = (save_car);
783 }
784
785 if (status & CySRModem) {
786
787
788 save_xir = (u_char) base_addr[CyMIR];
789 channel = (u_short ) (save_xir & CyIRChannel);
790 info = &cy_port[channel + chip * 4 + cinfo->first_line];
791 info->last_active = jiffies;
792 save_car = base_addr[CyCAR];
793 base_addr[CyCAR] = save_xir;
794
795 mdm_change = base_addr[CyMISR];
796 mdm_status = base_addr[CyMSVR1];
797
798 if(info->tty == 0){
799 ;
800 }else{
801 if((mdm_change & CyDCD)
802 && (info->flags & ASYNC_CHECK_CD)){
803 if(mdm_status & CyDCD){
804
805 cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
806 }else if(!((info->flags & ASYNC_CALLOUT_ACTIVE)
807 &&(info->flags & ASYNC_CALLOUT_NOHUP))){
808
809 cy_sched_event(info, Cy_EVENT_HANGUP);
810 }
811 }
812 if((mdm_change & CyCTS)
813 && (info->flags & ASYNC_CTS_FLOW)){
814 if(info->tty->stopped){
815 if(mdm_status & CyCTS){
816
817 info->tty->stopped = 0;
818 base_addr[CySRER] |= CyTxMpty;
819 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
820 }
821 }else{
822 if(!(mdm_status & CyCTS)){
823
824 info->tty->stopped = 1;
825 base_addr[CySRER] &= ~CyTxMpty;
826 }
827 }
828 }
829 if(mdm_status & CyDSR){
830 }
831 if(mdm_status & CyRI){
832 }
833 }
834
835 base_addr[CyMIR] = (save_xir & 0x3f);
836 base_addr[CyCAR] = save_car;
837 }
838 }
839 }
840 } while(had_work);
841
842
843 card_base_addr = (unsigned char *)cinfo->base_addr;
844 vdata = *(card_base_addr + Cy_ClrIntr);
845
846 }
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870 static void
871 do_cyclades_bh(void *unused)
872 {
873 run_task_queue(&tq_cyclades);
874 }
875
876 static void
877 do_softint(void *private_)
878 {
879 struct cyclades_port *info = (struct cyclades_port *) private_;
880 struct tty_struct *tty;
881
882 tty = info->tty;
883 if (!tty)
884 return;
885
886 if (clear_bit(Cy_EVENT_HANGUP, &info->event)) {
887 tty_hangup(info->tty);
888 wake_up_interruptible(&info->open_wait);
889 info->flags &= ~(ASYNC_NORMAL_ACTIVE|
890 ASYNC_CALLOUT_ACTIVE);
891 }
892 if (clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
893 wake_up_interruptible(&info->open_wait);
894 }
895 if (clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
896 if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
897 && tty->ldisc.write_wakeup){
898 (tty->ldisc.write_wakeup)(tty);
899 }
900 wake_up_interruptible(&tty->write_wait);
901 }
902 }
903
904
905
906
907
908
909
910
911 static int
912 grab_all_interrupts(int dontgrab)
913 {
914 int irq_lines = 0;
915 int i, mask;
916
917 for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
918 if (!(mask & dontgrab)
919 && !request_irq(i, cy_probe, SA_INTERRUPT, "serial probe")) {
920 irq_lines |= mask;
921 }
922 }
923 return irq_lines;
924 }
925
926
927
928
929 static void
930 free_all_interrupts(int irq_lines)
931 {
932 int i;
933
934 for (i = 0; i < 16; i++) {
935 if (irq_lines & (1 << i))
936 free_irq(i);
937 }
938 }
939
940
941
942
943
944 static int
945 check_wild_interrupts(void)
946 {
947 int i, mask;
948 int wild_interrupts = 0;
949 int irq_lines;
950 unsigned long timeout;
951 unsigned long flags;
952
953
954 save_flags(flags); sti();
955
956 irq_lines = grab_all_interrupts(0);
957
958
959
960
961
962 timeout = jiffies+10;
963 while (timeout >= jiffies)
964 ;
965
966 cy_triggered = 0;
967
968 timeout = jiffies+10;
969 while (timeout >= jiffies)
970 ;
971
972 for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
973 if ((cy_triggered & (1 << i)) &&
974 (irq_lines & (1 << i))) {
975 wild_interrupts |= mask;
976 }
977 }
978 free_all_interrupts(irq_lines);
979 restore_flags(flags);
980 return wild_interrupts;
981 }
982
983
984
985
986
987
988 static int
989 get_auto_irq(int card)
990 {
991 unsigned long timeout;
992 unsigned char *base_addr;
993 int save_xir, save_car;
994 volatile char vdata;
995
996 base_addr = (unsigned char*) (cy_card[card].base_addr);
997 intr_base_addr = base_addr;
998
999
1000
1001
1002 cy_irq_triggered = 0;
1003 cli();
1004 base_addr[CyCAR] = 0;
1005 write_cy_cmd(base_addr,CyCHAN_CTL|CyENB_XMTR);
1006 base_addr[CySRER] |= CyTxMpty;
1007 sti();
1008
1009 timeout = jiffies+2;
1010 while (timeout >= jiffies) {
1011 if (cy_irq_triggered)
1012 break;
1013 }
1014
1015
1016
1017 cli();
1018 if(intr_base_addr[CySVRR] != 0){
1019 save_xir = (u_char) intr_base_addr[CyTIR];
1020 save_car = intr_base_addr[CyCAR];
1021 if ((save_xir & 0x3) != 0){
1022 printk("channel %x requesting unexpected interrupt\n",save_xir);
1023 }
1024 intr_base_addr[CyCAR] = (save_xir & 0x3);
1025 intr_base_addr[CySRER] &= ~CyTxMpty;
1026 intr_base_addr[CyTIR] = (save_xir & 0x3f);
1027 intr_base_addr[CyCAR] = (save_car);
1028 vdata = *(intr_base_addr + Cy_ClrIntr);
1029 }
1030 sti();
1031
1032 return(cy_irq_triggered);
1033 }
1034
1035
1036
1037
1038
1039 static int
1040 do_auto_irq(int card)
1041 {
1042 int irq_lines = 0;
1043 int irq_try_1 = 0, irq_try_2 = 0;
1044 int retries;
1045 unsigned long flags;
1046
1047
1048 save_flags(flags); sti();
1049
1050 cy_wild_int_mask = check_wild_interrupts();
1051
1052 irq_lines = grab_all_interrupts(cy_wild_int_mask);
1053
1054 for (retries = 0; retries < 5; retries++) {
1055 if (!irq_try_1)
1056 irq_try_1 = get_auto_irq(card);
1057 if (!irq_try_2)
1058 irq_try_2 = get_auto_irq(card);
1059 if (irq_try_1 && irq_try_2) {
1060 if (irq_try_1 == irq_try_2)
1061 break;
1062 irq_try_1 = irq_try_2 = 0;
1063 }
1064 }
1065 restore_flags(flags);
1066 free_all_interrupts(irq_lines);
1067 return (irq_try_1 == irq_try_2) ? irq_try_1 : 0;
1068 }
1069
1070
1071
1072
1073
1074 static int
1075 startup(struct cyclades_port * info)
1076 {
1077 unsigned long flags;
1078 unsigned char *base_addr;
1079 int card,chip,channel;
1080
1081 if (info->flags & ASYNC_INITIALIZED){
1082 return 0;
1083 }
1084
1085 if (!info->type){
1086 if (info->tty){
1087 set_bit(TTY_IO_ERROR, &info->tty->flags);
1088 }
1089 return 0;
1090 }
1091 if (!info->xmit_buf){
1092 info->xmit_buf = (unsigned char *) get_free_page (GFP_KERNEL);
1093 if (!info->xmit_buf){
1094 return -ENOMEM;
1095 }
1096 }
1097
1098 config_setup(info);
1099
1100 card = info->card;
1101 channel = (info->line) - (cy_card[card].first_line);
1102 chip = channel>>2;
1103 channel &= 0x03;
1104 base_addr = (unsigned char*)
1105 (cy_card[card].base_addr + chip * CyRegSize);
1106
1107 #ifdef SERIAL_DEBUG_OPEN
1108 printk("startup card %d, chip %d, channel %d, base_addr %lx",
1109 card, chip, channel, (long)base_addr);
1110 #endif
1111
1112 save_flags(flags); cli();
1113 base_addr[CyCAR] = (u_char)channel;
1114
1115 base_addr[CyRTPR] = 0x20;
1116
1117 write_cy_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR);
1118
1119 base_addr[CyCAR] = (u_char)channel;
1120 base_addr[CyMSVR1] = CyRTS;
1121
1122 base_addr[CyMSVR2] = CyDTR;
1123
1124 #ifdef SERIAL_DEBUG_DTR
1125 printk("cyc: %d: raising DTR\n", __LINE__);
1126 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1127 #endif
1128
1129 base_addr[CySRER] |= CyRxData;
1130 info->flags |= ASYNC_INITIALIZED;
1131
1132 if (info->tty){
1133 clear_bit(TTY_IO_ERROR, &info->tty->flags);
1134 }
1135 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1136
1137 restore_flags(flags);
1138
1139 #ifdef SERIAL_DEBUG_OPEN
1140 printk(" done\n");
1141 #endif
1142 return 0;
1143 }
1144
1145 void
1146 start_xmit( struct cyclades_port *info )
1147 {
1148 unsigned long flags;
1149 unsigned char *base_addr;
1150 int card,chip,channel;
1151
1152 card = info->card;
1153 channel = (info->line) - (cy_card[card].first_line);
1154 chip = channel>>2;
1155 channel &= 0x03;
1156 base_addr = (unsigned char*)
1157 (cy_card[card].base_addr + chip * CyRegSize);
1158 save_flags(flags); cli();
1159 base_addr[CyCAR] = channel;
1160 base_addr[CySRER] |= CyTxMpty;
1161 restore_flags(flags);
1162 }
1163
1164
1165
1166
1167
1168 static void
1169 shutdown(struct cyclades_port * info)
1170 {
1171 unsigned long flags;
1172 unsigned char *base_addr;
1173 int card,chip,channel;
1174
1175 if (!(info->flags & ASYNC_INITIALIZED)){
1176
1177 return;
1178 }
1179
1180 card = info->card;
1181 channel = info->line - cy_card[card].first_line;
1182 chip = channel>>2;
1183 channel &= 0x03;
1184 base_addr = (unsigned char*)
1185 (cy_card[card].base_addr + chip * CyRegSize);
1186
1187 #ifdef SERIAL_DEBUG_OPEN
1188 printk("shutdown card %d, chip %d, channel %d, base_addr %lx\n",
1189 card, chip, channel, (long)base_addr);
1190 #endif
1191
1192
1193
1194
1195
1196
1197
1198 save_flags(flags); cli();
1199 if (info->xmit_buf){
1200 free_page((unsigned long) info->xmit_buf);
1201 info->xmit_buf = 0;
1202 }
1203
1204 base_addr[CyCAR] = (u_char)channel;
1205 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
1206 base_addr[CyMSVR1] = ~CyRTS;
1207
1208 base_addr[CyMSVR2] = ~CyDTR;
1209 #ifdef SERIAL_DEBUG_DTR
1210 printk("cyc: %d: dropping DTR\n", __LINE__);
1211 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1212 #endif
1213 }
1214 write_cy_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR);
1215
1216
1217
1218 if (info->tty){
1219 set_bit(TTY_IO_ERROR, &info->tty->flags);
1220 }
1221 info->flags &= ~ASYNC_INITIALIZED;
1222 restore_flags(flags);
1223
1224 #ifdef SERIAL_DEBUG_OPEN
1225 printk(" done\n");
1226 #endif
1227 return;
1228 }
1229
1230
1231
1232
1233 static void
1234 config_setup(struct cyclades_port * info)
1235 {
1236 unsigned long flags;
1237 unsigned char *base_addr;
1238 int card,chip,channel;
1239 unsigned cflag;
1240 int i;
1241
1242 if (!info->tty || !info->tty->termios){
1243 return;
1244 }
1245 if (info->line == -1){
1246 return;
1247 }
1248 cflag = info->tty->termios->c_cflag;
1249
1250
1251 i = cflag & CBAUD;
1252 #ifdef CBAUDEX
1253
1254
1255
1256
1257
1258
1259
1260
1261 if (i & CBAUDEX) {
1262 if (i == B57600)
1263 i = 16;
1264 else if(i == B115200)
1265 i = 18;
1266 #ifdef B78600
1267 else if(i == B78600)
1268 i = 17;
1269 #endif
1270 else
1271 info->tty->termios->c_cflag &= ~CBAUDEX;
1272 }
1273 #endif
1274 if (i == 15) {
1275 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1276 i += 1;
1277 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1278 i += 3;
1279 }
1280 info->tbpr = baud_bpr[i];
1281 info->tco = baud_co[i];
1282 info->rbpr = baud_bpr[i];
1283 info->rco = baud_co[i];
1284 if (baud_table[i] == 134) {
1285 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
1286
1287 } else if (baud_table[i]) {
1288 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
1289
1290 } else {
1291 info->timeout = 0;
1292 }
1293
1294
1295
1296
1297
1298 info->cor5 = 0;
1299 info->cor4 = 0;
1300 info->cor3 = baud_cor3[i];
1301 info->cor2 = CyETC;
1302 switch(cflag & CSIZE){
1303 case CS5:
1304 info->cor1 = Cy_5_BITS;
1305 break;
1306 case CS6:
1307 info->cor1 = Cy_6_BITS;
1308 break;
1309 case CS7:
1310 info->cor1 = Cy_7_BITS;
1311 break;
1312 case CS8:
1313 info->cor1 = Cy_8_BITS;
1314 break;
1315 }
1316 if(cflag & CSTOPB){
1317 info->cor1 |= Cy_2_STOP;
1318 }
1319 if (cflag & PARENB){
1320 if (cflag & PARODD){
1321 info->cor1 |= CyPARITY_O;
1322 }else{
1323 info->cor1 |= CyPARITY_E;
1324 }
1325 }else{
1326 info->cor1 |= CyPARITY_NONE;
1327 }
1328
1329
1330 if (cflag & CRTSCTS)
1331 info->flags |= ASYNC_CTS_FLOW;
1332 else
1333 info->flags &= ~ASYNC_CTS_FLOW;
1334 if (cflag & CLOCAL)
1335 info->flags &= ~ASYNC_CHECK_CD;
1336 else
1337 info->flags |= ASYNC_CHECK_CD;
1338
1339
1340 card = info->card;
1341 channel = (info->line) - (cy_card[card].first_line);
1342 chip = channel>>2;
1343 channel &= 0x03;
1344 base_addr = (unsigned char*)
1345 (cy_card[card].base_addr + chip * CyRegSize);
1346
1347 save_flags(flags); cli();
1348 base_addr[CyCAR] = (u_char)channel;
1349
1350
1351
1352 base_addr[CyTCOR] = info->tco;
1353 base_addr[CyTBPR] = info->tbpr;
1354 base_addr[CyRCOR] = info->rco;
1355 base_addr[CyRBPR] = info->rbpr;
1356
1357
1358
1359 base_addr[CySCHR1] = START_CHAR(info->tty);
1360 base_addr[CySCHR2] = STOP_CHAR(info->tty);
1361 base_addr[CyCOR1] = info->cor1;
1362 base_addr[CyCOR2] = info->cor2;
1363 base_addr[CyCOR3] = info->cor3;
1364 base_addr[CyCOR4] = info->cor4;
1365 base_addr[CyCOR5] = info->cor5;
1366
1367 write_cy_cmd(base_addr,CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch);
1368
1369 base_addr[CyCAR] = (u_char)channel;
1370
1371 base_addr[CyRTPR] = 0x20;
1372
1373 if (C_CLOCAL(info->tty)) {
1374 base_addr[CySRER] |= 0;
1375
1376 base_addr[CyMCOR1] = 0x0;
1377
1378 base_addr[CyMCOR2] = 0x0;
1379 } else {
1380 base_addr[CySRER] |= CyMdmCh;
1381
1382 base_addr[CyMCOR1] = CyDSR|CyCTS|CyRI|CyDCD;
1383
1384 base_addr[CyMCOR2] = CyDSR|CyCTS|CyRI|CyDCD;
1385 }
1386
1387 if(i == 0){
1388 base_addr[CyMSVR2] = ~CyDTR;
1389 #ifdef SERIAL_DEBUG_DTR
1390 printk("cyc: %d: dropping DTR\n", __LINE__);
1391 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1392 #endif
1393 }else{
1394 base_addr[CyMSVR2] = CyDTR;
1395 #ifdef SERIAL_DEBUG_DTR
1396 printk("cyc: %d: raising DTR\n", __LINE__);
1397 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1398 #endif
1399 }
1400
1401
1402
1403
1404
1405
1406
1407
1408 if (C_CRTSCTS(info->tty)) {
1409 info->cor2 |= CyCtsAE;
1410 }else{
1411 info->cor2 &= ~CyCtsAE;
1412 }
1413
1414 if (info->tty){
1415 clear_bit(TTY_IO_ERROR, &info->tty->flags);
1416 }
1417
1418 restore_flags(flags);
1419
1420 }
1421
1422
1423 static void
1424 cy_put_char(struct tty_struct *tty, unsigned char ch)
1425 {
1426 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1427 unsigned long flags;
1428
1429 #ifdef SERIAL_DEBUG_IO
1430 printk("cy_put_char ttyC%d\n", info->line);
1431 #endif
1432
1433 if (serial_paranoia_check(info, tty->device, "cy_put_char"))
1434 return;
1435
1436 if (!tty || !info->xmit_buf)
1437 return;
1438
1439 save_flags(flags); cli();
1440 if (info->xmit_cnt >= PAGE_SIZE - 1) {
1441 restore_flags(flags);
1442 return;
1443 }
1444
1445 info->xmit_buf[info->xmit_head++] = ch;
1446 info->xmit_head &= PAGE_SIZE - 1;
1447 info->xmit_cnt++;
1448 restore_flags(flags);
1449 }
1450
1451
1452 static void
1453 cy_flush_chars(struct tty_struct *tty)
1454 {
1455 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1456 unsigned long flags;
1457 unsigned char *base_addr;
1458 int card,chip,channel;
1459
1460 #ifdef SERIAL_DEBUG_IO
1461 printk("cy_flush_chars ttyC%d\n", info->line);
1462 #endif
1463
1464 if (serial_paranoia_check(info, tty->device, "cy_flush_chars"))
1465 return;
1466
1467 if (info->xmit_cnt <= 0 || tty->stopped
1468 || tty->hw_stopped || !info->xmit_buf)
1469 return;
1470
1471 card = info->card;
1472 channel = info->line - cy_card[card].first_line;
1473 chip = channel>>2;
1474 channel &= 0x03;
1475 base_addr = (unsigned char*)
1476 (cy_card[card].base_addr + chip * CyRegSize);
1477
1478 save_flags(flags); cli();
1479 base_addr[CyCAR] = channel;
1480 base_addr[CySRER] |= CyTxMpty;
1481 restore_flags(flags);
1482 }
1483
1484
1485
1486
1487
1488
1489
1490
1491 static int
1492 cy_write(struct tty_struct * tty, int from_user,
1493 unsigned char *buf, int count)
1494 {
1495 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1496 unsigned long flags;
1497 int c, total = 0;
1498
1499 #ifdef SERIAL_DEBUG_IO
1500 printk("cy_write ttyC%d\n", info->line);
1501 #endif
1502
1503 if (serial_paranoia_check(info, tty->device, "cy_write")){
1504 return 0;
1505 }
1506
1507 if (!tty || !info->xmit_buf || !tmp_buf){
1508 return 0;
1509 }
1510
1511 while (1) {
1512 save_flags(flags); cli();
1513 c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1514 SERIAL_XMIT_SIZE - info->xmit_head));
1515 if (c <= 0){
1516 restore_flags(flags);
1517 break;
1518 }
1519
1520 if (from_user) {
1521 down(&tmp_buf_sem);
1522 memcpy_fromfs(tmp_buf, buf, c);
1523 c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1524 SERIAL_XMIT_SIZE - info->xmit_head));
1525 memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
1526 up(&tmp_buf_sem);
1527 } else
1528 memcpy(info->xmit_buf + info->xmit_head, buf, c);
1529 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1530 info->xmit_cnt += c;
1531 restore_flags(flags);
1532 buf += c;
1533 count -= c;
1534 total += c;
1535 }
1536
1537
1538 if (info->xmit_cnt
1539 && !tty->stopped
1540 && !tty->hw_stopped ) {
1541 start_xmit(info);
1542 }
1543 return total;
1544 }
1545
1546
1547 static int
1548 cy_write_room(struct tty_struct *tty)
1549 {
1550 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1551 int ret;
1552
1553 #ifdef SERIAL_DEBUG_IO
1554 printk("cy_write_room ttyC%d\n", info->line);
1555 #endif
1556
1557 if (serial_paranoia_check(info, tty->device, "cy_write_room"))
1558 return 0;
1559 ret = PAGE_SIZE - info->xmit_cnt - 1;
1560 if (ret < 0)
1561 ret = 0;
1562 return ret;
1563 }
1564
1565
1566 static int
1567 cy_chars_in_buffer(struct tty_struct *tty)
1568 {
1569 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1570
1571 #ifdef SERIAL_DEBUG_IO
1572 printk("cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt);
1573 #endif
1574
1575 if (serial_paranoia_check(info, tty->device, "cy_chars_in_buffer"))
1576 return 0;
1577
1578 return info->xmit_cnt;
1579 }
1580
1581
1582 static void
1583 cy_flush_buffer(struct tty_struct *tty)
1584 {
1585 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1586 unsigned long flags;
1587
1588 #ifdef SERIAL_DEBUG_IO
1589 printk("cy_flush_buffer ttyC%d\n", info->line);
1590 #endif
1591
1592 if (serial_paranoia_check(info, tty->device, "cy_flush_buffer"))
1593 return;
1594 save_flags(flags); cli();
1595 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1596 restore_flags(flags);
1597 wake_up_interruptible(&tty->write_wait);
1598 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
1599 && tty->ldisc.write_wakeup)
1600 (tty->ldisc.write_wakeup)(tty);
1601 }
1602
1603
1604
1605
1606
1607
1608 static void
1609 cy_throttle(struct tty_struct * tty)
1610 {
1611 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1612 unsigned long flags;
1613 unsigned char *base_addr;
1614 int card,chip,channel;
1615
1616 #ifdef SERIAL_DEBUG_THROTTLE
1617 char buf[64];
1618
1619 printk("throttle %s: %d....\n", _tty_name(tty, buf),
1620 tty->ldisc.chars_in_buffer(tty));
1621 printk("cy_throttle ttyC%d\n", info->line);
1622 #endif
1623
1624 if (serial_paranoia_check(info, tty->device, "cy_nthrottle")){
1625 return;
1626 }
1627
1628 if (I_IXOFF(tty)) {
1629 info->x_char = STOP_CHAR(tty);
1630
1631 }
1632
1633 card = info->card;
1634 channel = info->line - cy_card[card].first_line;
1635 chip = channel>>2;
1636 channel &= 0x03;
1637 base_addr = (unsigned char*)
1638 (cy_card[card].base_addr + chip * CyRegSize);
1639
1640 save_flags(flags); cli();
1641 base_addr[CyCAR] = (u_char)channel;
1642 base_addr[CyMSVR1] = ~CyRTS;
1643 restore_flags(flags);
1644
1645 return;
1646 }
1647
1648
1649 static void
1650 cy_unthrottle(struct tty_struct * tty)
1651 {
1652 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1653 unsigned long flags;
1654 unsigned char *base_addr;
1655 int card,chip,channel;
1656
1657 #ifdef SERIAL_DEBUG_THROTTLE
1658 char buf[64];
1659
1660 printk("throttle %s: %d....\n", _tty_name(tty, buf),
1661 tty->ldisc.chars_in_buffer(tty));
1662 printk("cy_unthrottle ttyC%d\n", info->line);
1663 #endif
1664
1665 if (serial_paranoia_check(info, tty->device, "cy_nthrottle")){
1666 return;
1667 }
1668
1669 if (I_IXOFF(tty)) {
1670 info->x_char = START_CHAR(tty);
1671
1672 }
1673
1674 card = info->card;
1675 channel = info->line - cy_card[card].first_line;
1676 chip = channel>>2;
1677 channel &= 0x03;
1678 base_addr = (unsigned char*)
1679 (cy_card[card].base_addr + chip * CyRegSize);
1680
1681 save_flags(flags); cli();
1682 base_addr[CyCAR] = (u_char)channel;
1683 base_addr[CyMSVR1] = CyRTS;
1684 restore_flags(flags);
1685
1686 return;
1687 }
1688
1689 static int
1690 get_serial_info(struct cyclades_port * info,
1691 struct serial_struct * retinfo)
1692 {
1693 struct serial_struct tmp;
1694 struct cyclades_card *cinfo = &cy_card[info->card];
1695
1696
1697 if (!retinfo)
1698 return -EFAULT;
1699 memset(&tmp, 0, sizeof(tmp));
1700 tmp.type = info->type;
1701 tmp.line = info->line;
1702 tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
1703 tmp.irq = cinfo->irq;
1704 tmp.flags = info->flags;
1705 tmp.baud_base = 0;
1706 tmp.close_delay = info->close_delay;
1707 tmp.custom_divisor = 0;
1708 tmp.hub6 = 0;
1709 memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
1710 return 0;
1711 }
1712
1713 static int
1714 set_serial_info(struct cyclades_port * info,
1715 struct serial_struct * new_info)
1716 {
1717 struct serial_struct new_serial;
1718 struct cyclades_port old_info;
1719
1720
1721 if (!new_info)
1722 return -EFAULT;
1723 memcpy_fromfs(&new_serial,new_info,sizeof(new_serial));
1724 old_info = *info;
1725
1726 if (!suser()) {
1727 if ((new_serial.close_delay != info->close_delay) ||
1728 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
1729 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
1730 return -EPERM;
1731 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1732 (new_serial.flags & ASYNC_USR_MASK));
1733 goto check_and_exit;
1734 }
1735
1736
1737
1738
1739
1740
1741
1742 info->flags = ((info->flags & ~ASYNC_FLAGS) |
1743 (new_serial.flags & ASYNC_FLAGS));
1744 info->close_delay = new_serial.close_delay;
1745
1746
1747 check_and_exit:
1748 if (info->flags & ASYNC_INITIALIZED){
1749 config_setup(info);
1750 return 0;
1751 }else{
1752 return startup(info);
1753 }
1754 }
1755
1756 static int
1757 get_modem_info(struct cyclades_port * info, unsigned int *value)
1758 {
1759 int card,chip,channel;
1760 unsigned char *base_addr;
1761 unsigned long flags;
1762 unsigned char status;
1763 unsigned int result;
1764
1765 card = info->card;
1766 channel = (info->line) - (cy_card[card].first_line);
1767 chip = channel>>2;
1768 channel &= 0x03;
1769 base_addr = (unsigned char*)
1770 (cy_card[card].base_addr + chip * CyRegSize);
1771
1772 save_flags(flags); cli();
1773 base_addr[CyCAR] = (u_char)channel;
1774 status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
1775 restore_flags(flags);
1776
1777 result = ((status & CyRTS) ? TIOCM_RTS : 0)
1778 | ((status & CyDTR) ? TIOCM_DTR : 0)
1779 | ((status & CyDCD) ? TIOCM_CAR : 0)
1780 | ((status & CyRI) ? TIOCM_RNG : 0)
1781 | ((status & CyDSR) ? TIOCM_DSR : 0)
1782 | ((status & CyCTS) ? TIOCM_CTS : 0);
1783 put_fs_long(result,(unsigned long *) value);
1784 return 0;
1785 }
1786
1787 static int
1788 set_modem_info(struct cyclades_port * info, unsigned int cmd,
1789 unsigned int *value)
1790 {
1791 int card,chip,channel;
1792 unsigned char *base_addr;
1793 unsigned long flags;
1794 unsigned int arg = get_fs_long((unsigned long *) value);
1795
1796 card = info->card;
1797 channel = (info->line) - (cy_card[card].first_line);
1798 chip = channel>>2;
1799 channel &= 0x03;
1800 base_addr = (unsigned char*)
1801 (cy_card[card].base_addr + chip * CyRegSize);
1802
1803 switch (cmd) {
1804 case TIOCMBIS:
1805 if (arg & TIOCM_RTS){
1806 save_flags(flags); cli();
1807 base_addr[CyCAR] = (u_char)channel;
1808 base_addr[CyMSVR1] = CyRTS;
1809 restore_flags(flags);
1810 }
1811 if (arg & TIOCM_DTR){
1812 save_flags(flags); cli();
1813 base_addr[CyCAR] = (u_char)channel;
1814
1815 base_addr[CyMSVR2] = CyDTR;
1816 #ifdef SERIAL_DEBUG_DTR
1817 printk("cyc: %d: raising DTR\n", __LINE__);
1818 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1819 #endif
1820 restore_flags(flags);
1821 }
1822 break;
1823 case TIOCMBIC:
1824 if (arg & TIOCM_RTS){
1825 save_flags(flags); cli();
1826 base_addr[CyCAR] = (u_char)channel;
1827 base_addr[CyMSVR1] = ~CyRTS;
1828 restore_flags(flags);
1829 }
1830 if (arg & TIOCM_DTR){
1831 save_flags(flags); cli();
1832 base_addr[CyCAR] = (u_char)channel;
1833
1834 base_addr[CyMSVR2] = ~CyDTR;
1835 #ifdef SERIAL_DEBUG_DTR
1836 printk("cyc: %d: dropping DTR\n", __LINE__);
1837 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1838 #endif
1839 restore_flags(flags);
1840 }
1841 break;
1842 case TIOCMSET:
1843 if (arg & TIOCM_RTS){
1844 save_flags(flags); cli();
1845 base_addr[CyCAR] = (u_char)channel;
1846 base_addr[CyMSVR1] = CyRTS;
1847 restore_flags(flags);
1848 }else{
1849 save_flags(flags); cli();
1850 base_addr[CyCAR] = (u_char)channel;
1851 base_addr[CyMSVR1] = ~CyRTS;
1852 restore_flags(flags);
1853 }
1854 if (arg & TIOCM_DTR){
1855 save_flags(flags); cli();
1856 base_addr[CyCAR] = (u_char)channel;
1857
1858 base_addr[CyMSVR2] = CyDTR;
1859 #ifdef SERIAL_DEBUG_DTR
1860 printk("cyc: %d: raising DTR\n", __LINE__);
1861 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1862 #endif
1863 restore_flags(flags);
1864 }else{
1865 save_flags(flags); cli();
1866 base_addr[CyCAR] = (u_char)channel;
1867
1868 base_addr[CyMSVR2] = ~CyDTR;
1869 #ifdef SERIAL_DEBUG_DTR
1870 printk("cyc: %d: dropping DTR\n", __LINE__);
1871 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1872 #endif
1873 restore_flags(flags);
1874 }
1875 break;
1876 default:
1877 return -EINVAL;
1878 }
1879 return 0;
1880 }
1881
1882 static void
1883 send_break( struct cyclades_port * info, int duration)
1884 {
1885
1886
1887 info->x_break = duration;
1888 if (!info->xmit_cnt ) {
1889 start_xmit(info);
1890 }
1891 }
1892
1893
1894 static int
1895 cy_ioctl(struct tty_struct *tty, struct file * file,
1896 unsigned int cmd, unsigned long arg)
1897 {
1898 int error;
1899 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1900 int ret_val = 0;
1901
1902 #ifdef SERIAL_DEBUG_OTHER
1903 printk("cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg);
1904 #endif
1905
1906 switch (cmd) {
1907 case TCSBRK:
1908 ret_val = tty_check_change(tty);
1909 if (ret_val)
1910 return ret_val;
1911 wait_until_sent(tty,0);
1912 if (!arg)
1913 send_break(info, HZ/4);
1914 break;
1915 case TCSBRKP:
1916 ret_val = tty_check_change(tty);
1917 if (ret_val)
1918 return ret_val;
1919 wait_until_sent(tty,0);
1920 send_break(info, arg ? arg*(HZ/10) : HZ/4);
1921 break;
1922 case TIOCMBIS:
1923 case TIOCMBIC:
1924 case TIOCMSET:
1925 ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
1926
1927
1928 case TIOCGSOFTCAR:
1929 error = verify_area(VERIFY_WRITE, (void *) arg
1930 ,sizeof(unsigned int *));
1931 if (error){
1932 ret_val = error;
1933 break;
1934 }
1935 put_fs_long(C_CLOCAL(tty) ? 1 : 0,
1936 (unsigned long *) arg);
1937 break;
1938 case TIOCSSOFTCAR:
1939 arg = get_fs_long((unsigned long *) arg);
1940 tty->termios->c_cflag =
1941 ((tty->termios->c_cflag & ~CLOCAL) |
1942 (arg ? CLOCAL : 0));
1943 break;
1944 case TIOCMGET:
1945 error = verify_area(VERIFY_WRITE, (void *) arg
1946 ,sizeof(unsigned int *));
1947 if (error){
1948 ret_val = error;
1949 break;
1950 }
1951 ret_val = get_modem_info(info, (unsigned int *) arg);
1952 break;
1953 case TIOCGSERIAL:
1954 error = verify_area(VERIFY_WRITE, (void *) arg
1955 ,sizeof(struct serial_struct));
1956 if (error){
1957 ret_val = error;
1958 break;
1959 }
1960 ret_val = get_serial_info(info,
1961 (struct serial_struct *) arg);
1962 break;
1963 case TIOCSSERIAL:
1964 ret_val = set_serial_info(info,
1965 (struct serial_struct *) arg);
1966 break;
1967 default:
1968 ret_val = -ENOIOCTLCMD;
1969 }
1970
1971 #ifdef SERIAL_DEBUG_OTHER
1972 printk("cy_ioctl done\n");
1973 #endif
1974
1975 return ret_val;
1976 }
1977
1978
1979
1980
1981 static void
1982 cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
1983 {
1984 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1985
1986 #ifdef SERIAL_DEBUG_OTHER
1987 printk("cy_set_termios ttyC%d\n", info->line);
1988 #endif
1989
1990 if (tty->termios->c_cflag == old_termios->c_cflag)
1991 return;
1992 config_setup(info);
1993
1994 if ((old_termios->c_cflag & CRTSCTS) &&
1995 !(tty->termios->c_cflag & CRTSCTS)) {
1996 tty->stopped = 0;
1997 cy_start(tty);
1998 }
1999 #ifdef tytso_patch_94Nov25_1726
2000 if (!(old_termios->c_cflag & CLOCAL) &&
2001 (tty->termios->c_cflag & CLOCAL))
2002 wake_up_interruptible(&info->open_wait);
2003 #endif
2004
2005 return;
2006 }
2007
2008
2009 static void
2010 cy_close(struct tty_struct * tty, struct file * filp)
2011 {
2012 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2013
2014
2015 #ifdef SERIAL_DEBUG_OTHER
2016 printk("cy_close ttyC%d\n", info->line);
2017 #endif
2018
2019 if (!info
2020 || serial_paranoia_check(info, tty->device, "cy_close")){
2021 return;
2022 }
2023 #ifdef SERIAL_DEBUG_OPEN
2024 printk("cy_close ttyC%d, count = %d\n", info->line, info->count);
2025 #endif
2026
2027 if ((tty->count == 1) && (info->count != 1)) {
2028
2029
2030
2031
2032
2033
2034
2035 printk("cy_close: bad serial port count; tty->count is 1, "
2036 "info->count is %d\n", info->count);
2037 info->count = 1;
2038 }
2039 #ifdef SERIAL_DEBUG_COUNT
2040 printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count - 1);
2041 #endif
2042 if (--info->count < 0) {
2043 printk("cy_close: bad serial port count for ttys%d: %d\n",
2044 info->line, info->count);
2045 #ifdef SERIAL_DEBUG_COUNT
2046 printk("cyc: %d: setting count to 0\n", __LINE__);
2047 #endif
2048 info->count = 0;
2049 }
2050 if (info->count)
2051 return;
2052 info->flags |= ASYNC_CLOSING;
2053
2054
2055
2056
2057 if (info->flags & ASYNC_NORMAL_ACTIVE)
2058 info->normal_termios = *tty->termios;
2059 if (info->flags & ASYNC_CALLOUT_ACTIVE)
2060 info->callout_termios = *tty->termios;
2061 if (info->flags & ASYNC_INITIALIZED)
2062 wait_until_sent(tty, 3000);
2063 shutdown(info);
2064 if (tty->driver.flush_buffer)
2065 tty->driver.flush_buffer(tty);
2066 if (tty->ldisc.flush_buffer)
2067 tty->ldisc.flush_buffer(tty);
2068 info->event = 0;
2069 info->tty = 0;
2070 if (tty->ldisc.num != ldiscs[N_TTY].num) {
2071 if (tty->ldisc.close)
2072 (tty->ldisc.close)(tty);
2073 tty->ldisc = ldiscs[N_TTY];
2074 tty->termios->c_line = N_TTY;
2075 if (tty->ldisc.open)
2076 (tty->ldisc.open)(tty);
2077 }
2078 if (info->blocked_open) {
2079 if (info->close_delay) {
2080 current->state = TASK_INTERRUPTIBLE;
2081 current->timeout = jiffies + info->close_delay;
2082 schedule();
2083 }
2084 wake_up_interruptible(&info->open_wait);
2085 }
2086 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
2087 ASYNC_CLOSING);
2088 wake_up_interruptible(&info->close_wait);
2089
2090 #ifdef SERIAL_DEBUG_OTHER
2091 printk("cy_close done\n");
2092 #endif
2093
2094 return;
2095 }
2096
2097
2098
2099
2100 void
2101 cy_hangup(struct tty_struct *tty)
2102 {
2103 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2104
2105 #ifdef SERIAL_DEBUG_OTHER
2106 printk("cy_hangup ttyC%d\n", info->line);
2107 #endif
2108
2109 if (serial_paranoia_check(info, tty->device, "cy_hangup"))
2110 return;
2111
2112 shutdown(info);
2113 #if 0
2114 info->event = 0;
2115 info->count = 0;
2116 #ifdef SERIAL_DEBUG_COUNT
2117 printk("cyc: %d: setting count to 0\n", __LINE__);
2118 #endif
2119 info->tty = 0;
2120 #endif
2121 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
2122 wake_up_interruptible(&info->open_wait);
2123 }
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133 static int
2134 block_til_ready(struct tty_struct *tty, struct file * filp,
2135 struct cyclades_port *info)
2136 {
2137 struct wait_queue wait = { current, NULL };
2138 struct cyclades_card *cinfo;
2139 unsigned long flags;
2140 int chip, channel;
2141 int retval;
2142 char *base_addr;
2143
2144
2145
2146
2147
2148 if (info->flags & ASYNC_CLOSING) {
2149 interruptible_sleep_on(&info->close_wait);
2150 if (info->flags & ASYNC_HUP_NOTIFY){
2151 return -EAGAIN;
2152 }else{
2153 return -ERESTARTSYS;
2154 }
2155 }
2156
2157
2158
2159
2160
2161 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
2162 if (info->flags & ASYNC_NORMAL_ACTIVE){
2163 return -EBUSY;
2164 }
2165 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2166 (info->flags & ASYNC_SESSION_LOCKOUT) &&
2167 (info->session != current->session)){
2168 return -EBUSY;
2169 }
2170 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2171 (info->flags & ASYNC_PGRP_LOCKOUT) &&
2172 (info->pgrp != current->pgrp)){
2173 return -EBUSY;
2174 }
2175 info->flags |= ASYNC_CALLOUT_ACTIVE;
2176 return 0;
2177 }
2178
2179
2180
2181
2182
2183 if (filp->f_flags & O_NONBLOCK) {
2184 if (info->flags & ASYNC_CALLOUT_ACTIVE){
2185 return -EBUSY;
2186 }
2187 info->flags |= ASYNC_NORMAL_ACTIVE;
2188 return 0;
2189 }
2190
2191
2192
2193
2194
2195
2196
2197
2198 retval = 0;
2199 add_wait_queue(&info->open_wait, &wait);
2200 #ifdef SERIAL_DEBUG_OPEN
2201 printk("block_til_ready before block: ttyC%d, count = %d\n",
2202 info->line, info->count);
2203 #endif
2204 info->count--;
2205 #ifdef SERIAL_DEBUG_COUNT
2206 printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
2207 #endif
2208 info->blocked_open++;
2209
2210 cinfo = &cy_card[info->card];
2211 channel = info->line - cinfo->first_line;
2212 chip = channel>>2;
2213 channel &= 0x03;
2214 base_addr = (char *) (cinfo->base_addr + chip * CyRegSize);
2215
2216 while (1) {
2217 save_flags(flags); cli();
2218 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)){
2219 base_addr[CyCAR] = (u_char)channel;
2220 base_addr[CyMSVR1] = CyRTS;
2221
2222 base_addr[CyMSVR2] = CyDTR;
2223 #ifdef SERIAL_DEBUG_DTR
2224 printk("cyc: %d: raising DTR\n", __LINE__);
2225 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
2226 #endif
2227 }
2228 restore_flags(flags);
2229 current->state = TASK_INTERRUPTIBLE;
2230 if (tty_hung_up_p(filp)
2231 || !(info->flags & ASYNC_INITIALIZED) ){
2232 if (info->flags & ASYNC_HUP_NOTIFY) {
2233 retval = -EAGAIN;
2234 }else{
2235 retval = -ERESTARTSYS;
2236 }
2237 break;
2238 }
2239 save_flags(flags); cli();
2240 base_addr[CyCAR] = (u_char)channel;
2241
2242 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2243 && !(info->flags & ASYNC_CLOSING)
2244 && (C_CLOCAL(tty)
2245 || (base_addr[CyMSVR1] & CyDCD))) {
2246 restore_flags(flags);
2247 break;
2248 }
2249 restore_flags(flags);
2250 if (current->signal & ~current->blocked) {
2251 retval = -ERESTARTSYS;
2252 break;
2253 }
2254 #ifdef SERIAL_DEBUG_OPEN
2255 printk("block_til_ready blocking: ttyC%d, count = %d\n",
2256 info->line, info->count);
2257 #endif
2258 schedule();
2259 }
2260 current->state = TASK_RUNNING;
2261 remove_wait_queue(&info->open_wait, &wait);
2262 if (!tty_hung_up_p(filp)){
2263 info->count++;
2264 #ifdef SERIAL_DEBUG_COUNT
2265 printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
2266 #endif
2267 }
2268 info->blocked_open--;
2269 #ifdef SERIAL_DEBUG_OPEN
2270 printk("block_til_ready after blocking: ttyC%d, count = %d\n",
2271 info->line, info->count);
2272 #endif
2273 if (retval)
2274 return retval;
2275 info->flags |= ASYNC_NORMAL_ACTIVE;
2276 return 0;
2277 }
2278
2279
2280
2281
2282
2283 int
2284 cy_open(struct tty_struct *tty, struct file * filp)
2285 {
2286 struct cyclades_port *info;
2287 int retval, line;
2288
2289
2290 line = MINOR(tty->device) - tty->driver.minor_start;
2291 if ((line < 0) || (NR_PORTS <= line)){
2292 return -ENODEV;
2293 }
2294 info = &cy_port[line];
2295 #ifdef SERIAL_DEBUG_OTHER
2296 printk("cy_open ttyC%d\n", info->line);
2297 #endif
2298 if (serial_paranoia_check(info, tty->device, "cy_open")){
2299 return -ENODEV;
2300 }
2301 #ifdef SERIAL_DEBUG_OPEN
2302 printk("cy_open ttyC%d, count = %d\n", info->line, info->count);
2303 #endif
2304 info->count++;
2305 #ifdef SERIAL_DEBUG_COUNT
2306 printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
2307 #endif
2308 tty->driver_data = info;
2309 info->tty = tty;
2310
2311 if (!tmp_buf) {
2312 tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
2313 if (!tmp_buf){
2314 return -ENOMEM;
2315 }
2316 }
2317
2318 if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
2319 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
2320 *tty->termios = info->normal_termios;
2321 else
2322 *tty->termios = info->callout_termios;
2323 }
2324
2325
2326
2327 retval = startup(info);
2328 if (retval){
2329 return retval;
2330 }
2331
2332 retval = block_til_ready(tty, filp, info);
2333 if (retval) {
2334 #ifdef SERIAL_DEBUG_OPEN
2335 printk("cy_open returning after block_til_ready with %d\n",
2336 retval);
2337 #endif
2338 return retval;
2339 }
2340
2341 info->session = current->session;
2342 info->pgrp = current->pgrp;
2343
2344 #ifdef SERIAL_DEBUG_OPEN
2345 printk("cy_open done\n");
2346 #endif
2347 return 0;
2348 }
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365 static void
2366 show_version(void)
2367 {
2368 printk("Cyclom driver %s\n",rcsid);
2369 }
2370
2371
2372
2373 int
2374 cy_init_card(unsigned char *base_addr)
2375 {
2376 volatile unsigned short discard;
2377 unsigned int chip_number;
2378
2379 discard = base_addr[Cy_HwReset];
2380 discard = base_addr[Cy_ClrIntr];
2381 udelay(500L);
2382
2383 for(chip_number=0; chip_number<CyMaxChipsPerCard; chip_number++){
2384 udelay(1000L);
2385 if(base_addr[CyCCR] != 0x00){
2386
2387
2388
2389
2390 return chip_number;
2391 }
2392
2393 base_addr[CyGFRCR] = 0;
2394 udelay(10L);
2395
2396 base_addr[CyCCR] = CyCHIP_RESET;
2397 udelay(1000L);
2398
2399 if(base_addr[CyGFRCR] == 0x00){
2400 printk(" chip #%d at %#6lx is not responding (GFRCR stayed 0)\n",
2401 chip_number, (unsigned long)base_addr);
2402 return chip_number;
2403 }
2404 if((0xf0 & base_addr[CyGFRCR]) != 0x40){
2405 printk(" chip #%d at %#6lx is not valid (GFRCR == %#2x)\n",
2406 chip_number, (unsigned long)base_addr, base_addr[CyGFRCR]);
2407 return chip_number;
2408 }
2409 base_addr[CyGCR] = CyCH0_SERIAL;
2410 base_addr[CyPPR] = CyCLOCK_25_1MS * 5;
2411
2412 printk(" chip #%d at %#6lx is rev 0x%2x\n",
2413 chip_number, (unsigned long)base_addr, base_addr[CyGFRCR]);
2414
2415
2416 base_addr += CyRegSize;
2417 }
2418
2419 return chip_number;
2420 }
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438 long
2439 cy_init(long kmem_start)
2440 {
2441 struct cyclades_port *info;
2442 struct cyclades_card *cinfo;
2443 int good_ports = 0;
2444 int port_num = 0;
2445 int index;
2446 #ifdef notyet
2447 struct sigaction sa;
2448 #endif
2449 int retval;
2450
2451 scrn[1] = '\0';
2452 show_version();
2453
2454
2455
2456 memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
2457 cy_serial_driver.magic = TTY_DRIVER_MAGIC;
2458 cy_serial_driver.name = "ttyC";
2459 cy_serial_driver.major = 19 ;
2460 cy_serial_driver.minor_start = 32;
2461 cy_serial_driver.num = NR_PORTS;
2462 cy_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
2463 cy_serial_driver.subtype = SERIAL_TYPE_NORMAL;
2464 cy_serial_driver.init_termios = tty_std_termios;
2465 cy_serial_driver.init_termios.c_cflag =
2466 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2467 cy_serial_driver.flags = TTY_DRIVER_REAL_RAW;
2468 cy_serial_driver.refcount = &serial_refcount;
2469 cy_serial_driver.table = serial_table;
2470 cy_serial_driver.termios = serial_termios;
2471 cy_serial_driver.termios_locked = serial_termios_locked;
2472 cy_serial_driver.open = cy_open;
2473 cy_serial_driver.close = cy_close;
2474 cy_serial_driver.write = cy_write;
2475 cy_serial_driver.put_char = cy_put_char;
2476 cy_serial_driver.flush_chars = cy_flush_chars;
2477 cy_serial_driver.write_room = cy_write_room;
2478 cy_serial_driver.chars_in_buffer = cy_chars_in_buffer;
2479 cy_serial_driver.flush_buffer = cy_flush_buffer;
2480 cy_serial_driver.ioctl = cy_ioctl;
2481 cy_serial_driver.throttle = cy_throttle;
2482 cy_serial_driver.unthrottle = cy_unthrottle;
2483 cy_serial_driver.set_termios = cy_set_termios;
2484 cy_serial_driver.stop = cy_stop;
2485 cy_serial_driver.start = cy_start;
2486 cy_serial_driver.hangup = cy_hangup;
2487
2488
2489
2490
2491
2492 cy_callout_driver = cy_serial_driver;
2493 cy_callout_driver.name = "cub";
2494 cy_callout_driver.major = 20 ;
2495 cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
2496
2497 if (tty_register_driver(&cy_serial_driver))
2498 panic("Couldn't register Cyclom serial driver\n");
2499 if (tty_register_driver(&cy_callout_driver))
2500 panic("Couldn't register Cyclom callout driver\n");
2501
2502 bh_base[CYCLADES_BH].routine = do_cyclades_bh;
2503
2504 for (index = 0; index < 16; index++) {
2505 IRQ_cards[index] = 0;
2506 }
2507
2508 port_num = 0;
2509 info = cy_port;
2510 for (index = 0, cinfo = cy_card; index < NR_CARDS; index++,cinfo++) {
2511
2512 if(0 == (cinfo->num_chips =
2513 cy_init_card((unsigned char *)cinfo->base_addr))){
2514
2515 continue;
2516 }
2517
2518 #ifndef CY_DONT_PROBE
2519
2520 cinfo->irq = do_auto_irq(index);
2521 #endif
2522
2523
2524 if (cinfo->irq) {
2525 retval = request_irq(cinfo->irq, cy_interrupt,
2526 SA_INTERRUPT, "cyclades");
2527 if (retval){
2528 printk("request_irq returned %d\n",retval);
2529
2530 }
2531 IRQ_cards[cinfo->irq] = cinfo;
2532 }else{
2533 printk("couldn't get board's irq\n");
2534 continue;
2535 }
2536
2537 printk(" share IRQ %d: ", cinfo->irq);
2538 good_ports = 4 * cinfo->num_chips;
2539
2540 if(port_num < NR_PORTS){
2541 cinfo->first_line = port_num;
2542 while( good_ports-- && port_num < NR_PORTS){
2543
2544 info->magic = CYCLADES_MAGIC;
2545 info->type = PORT_CIRRUS;
2546 info->card = index;
2547 info->line = port_num;
2548 info->flags = STD_COM_FLAGS;
2549 info->tty = 0;
2550 info->xmit_fifo_size = 12;
2551 info->cor1 = CyPARITY_NONE|Cy_1_STOP|Cy_8_BITS;
2552 info->cor2 = CyETC;
2553 info->cor3 = 0x08;
2554 info->cor4 = 0;
2555 info->cor5 = 0;
2556 info->tbpr = baud_bpr[13];
2557 info->tco = baud_co[13];
2558 info->rbpr = baud_bpr[13];
2559 info->rco = baud_co[13];
2560 info->close_delay = 0;
2561 info->x_char = 0;
2562 info->event = 0;
2563 info->count = 0;
2564 #ifdef SERIAL_DEBUG_COUNT
2565 printk("cyc: %d: setting count to 0\n", __LINE__);
2566 #endif
2567 info->blocked_open = 0;
2568 info->tqueue.routine = do_softint;
2569 info->tqueue.data = info;
2570 info->callout_termios =cy_callout_driver.init_termios;
2571 info->normal_termios = cy_serial_driver.init_termios;
2572 info->open_wait = 0;
2573 info->close_wait = 0;
2574
2575
2576
2577
2578
2579 printk("ttyC%1d ", info->line);
2580 port_num++;info++;
2581 if(!(port_num & 7)){
2582 printk("\n ");
2583 }
2584 }
2585 }else{
2586 cinfo->first_line = -1;
2587 }
2588 printk("\n");
2589 }
2590 while( port_num < NR_PORTS){
2591 info->line = -1;
2592 port_num++;info++;
2593 }
2594 return kmem_start;
2595
2596 }
2597
2598 static void
2599 show_status(int line_num)
2600 {
2601 unsigned char *base_addr;
2602 int card,chip,channel;
2603 struct cyclades_port * info;
2604 unsigned long flags;
2605
2606 info = &cy_port[line_num];
2607 card = info->card;
2608 channel = (info->line) - (cy_card[card].first_line);
2609 chip = channel>>2;
2610 channel &= 0x03;
2611 printk(" card %d, chip %d, channel %d\n", card, chip, channel);
2612
2613 printk(" cy_card\n");
2614 printk(" irq base_addr num_chips first_line = %d %lx %d %d\n",
2615 cy_card[card].irq, (long)cy_card[card].base_addr,
2616 cy_card[card].num_chips, cy_card[card].first_line);
2617
2618 printk(" cy_port\n");
2619 printk(" card line flags = %d %d %x\n",
2620 info->card, info->line, info->flags);
2621 printk(" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
2622 (long)info->tty, info->read_status_mask,
2623 info->timeout, info->xmit_fifo_size);
2624 printk(" cor1,cor2,cor3,cor4,cor5 = %x %x %x %x %x\n",
2625 info->cor1, info->cor2, info->cor3, info->cor4, info->cor5);
2626 printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n",
2627 info->tbpr, info->tco, info->rbpr, info->rco);
2628 printk(" close_delay event count = %d %d %d\n",
2629 info->close_delay, info->event, info->count);
2630 printk(" x_char blocked_open = %x %x\n",
2631 info->x_char, info->blocked_open);
2632 printk(" session pgrp open_wait = %lx %lx %lx\n",
2633 info->session, info->pgrp, (long)info->open_wait);
2634
2635
2636 save_flags(flags); cli();
2637
2638 base_addr = (unsigned char*)
2639 (cy_card[card].base_addr + chip * CyRegSize);
2640
2641
2642
2643 printk(" CyGFRCR %x\n", base_addr[CyGFRCR]);
2644 printk(" CyCAR %x\n", base_addr[CyCAR]);
2645 printk(" CyGCR %x\n", base_addr[CyGCR]);
2646 printk(" CySVRR %x\n", base_addr[CySVRR]);
2647 printk(" CyRICR %x\n", base_addr[CyRICR]);
2648 printk(" CyTICR %x\n", base_addr[CyTICR]);
2649 printk(" CyMICR %x\n", base_addr[CyMICR]);
2650 printk(" CyRIR %x\n", base_addr[CyRIR]);
2651 printk(" CyTIR %x\n", base_addr[CyTIR]);
2652 printk(" CyMIR %x\n", base_addr[CyMIR]);
2653 printk(" CyPPR %x\n", base_addr[CyPPR]);
2654
2655 base_addr[CyCAR] = (u_char)channel;
2656
2657
2658
2659 printk(" CyRIVR %x\n", base_addr[CyRIVR]);
2660 printk(" CyTIVR %x\n", base_addr[CyTIVR]);
2661 printk(" CyMIVR %x\n", base_addr[CyMIVR]);
2662 printk(" CyMISR %x\n", base_addr[CyMISR]);
2663
2664
2665
2666 printk(" CyCCR %x\n", base_addr[CyCCR]);
2667 printk(" CySRER %x\n", base_addr[CySRER]);
2668 printk(" CyCOR1 %x\n", base_addr[CyCOR1]);
2669 printk(" CyCOR2 %x\n", base_addr[CyCOR2]);
2670 printk(" CyCOR3 %x\n", base_addr[CyCOR3]);
2671 printk(" CyCOR4 %x\n", base_addr[CyCOR4]);
2672 printk(" CyCOR5 %x\n", base_addr[CyCOR5]);
2673 printk(" CyCCSR %x\n", base_addr[CyCCSR]);
2674 printk(" CyRDCR %x\n", base_addr[CyRDCR]);
2675 printk(" CySCHR1 %x\n", base_addr[CySCHR1]);
2676 printk(" CySCHR2 %x\n", base_addr[CySCHR2]);
2677 printk(" CySCHR3 %x\n", base_addr[CySCHR3]);
2678 printk(" CySCHR4 %x\n", base_addr[CySCHR4]);
2679 printk(" CySCRL %x\n", base_addr[CySCRL]);
2680 printk(" CySCRH %x\n", base_addr[CySCRH]);
2681 printk(" CyLNC %x\n", base_addr[CyLNC]);
2682 printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]);
2683 printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]);
2684 printk(" CyRTPR %x\n", base_addr[CyRTPR]);
2685 printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]);
2686 printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]);
2687 printk(" CyRBPR %x\n", base_addr[CyRBPR]);
2688 printk(" CyRCOR %x\n", base_addr[CyRCOR]);
2689 printk(" CyTBPR %x\n", base_addr[CyTBPR]);
2690 printk(" CyTCOR %x\n", base_addr[CyTCOR]);
2691
2692 restore_flags(flags);
2693 }
2694
2695