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