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