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