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