[PATCH] TTY layer buffering revamp
[safe/jmp/linux-2.6] / drivers / char / serial167.c
1 /*
2  * linux/drivers/char/serial167.c
3  *
4  * Driver for MVME166/7 board serial ports, which are via a CD2401.
5  * Based very much on cyclades.c.
6  *
7  * MVME166/7 work by Richard Hirst [richard@sleepie.demon.co.uk]
8  *
9  * ==============================================================
10  *
11  * static char rcsid[] =
12  * "$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $";
13  *
14  *  linux/kernel/cyclades.c
15  *
16  * Maintained by Marcio Saito (cyclades@netcom.com) and
17  * Randolph Bentson (bentson@grieg.seaslug.org)
18  *
19  * Much of the design and some of the code came from serial.c
20  * which was copyright (C) 1991, 1992  Linus Torvalds.  It was
21  * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
22  * and then fixed as suggested by Michael K. Johnson 12/12/92.
23  *
24  * This version does not support shared irq's.
25  *
26  * $Log: cyclades.c,v $
27  * Revision 1.36.1.4  1995/03/29  06:14:14  bentson
28  * disambiguate between Cyclom-16Y and Cyclom-32Ye;
29  *
30  * Changes:
31  *
32  * 200 lines of changes record removed - RGH 11-10-95, starting work on
33  * converting this to drive serial ports on mvme166 (cd2401).
34  *
35  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/08/25
36  * - get rid of verify_area
37  * - use get_user to access memory from userspace in set_threshold,
38  *   set_default_threshold and set_timeout
39  * - don't use the panic function in serial167_init
40  * - do resource release on failure on serial167_init
41  * - include missing restore_flags in mvme167_serial_console_setup
42  *
43  * Kars de Jong <jongk@linux-m68k.org> - 2004/09/06
44  * - replace bottom half handler with task queue handler
45  */
46
47 #include <linux/config.h>
48 #include <linux/errno.h>
49 #include <linux/signal.h>
50 #include <linux/sched.h>
51 #include <linux/timer.h>
52 #include <linux/tty.h>
53 #include <linux/interrupt.h>
54 #include <linux/serial.h>
55 #include <linux/serialP.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
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
95 static struct tty_driver *cy_serial_driver;
96 extern int serial_console;
97 static struct cyclades_port *serial_console_info = NULL;
98 static unsigned int serial_console_cflag = 0;
99 u_char initial_console_speed;
100
101 /* Base address of cd2401 chip on mvme166/7 */
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 /* This is the per-port data structure */
113 struct cyclades_port cy_port[] = {
114       /* CARD#  */
115         {-1 },      /* ttyS0 */
116         {-1 },      /* ttyS1 */
117         {-1 },      /* ttyS2 */
118         {-1 },      /* ttyS3 */
119 };
120 #define NR_PORTS        ARRAY_SIZE(cy_port)
121
122 /*
123  * tmp_buf is used as a temporary buffer by serial_write.  We need to
124  * lock it in case the copy_from_user blocks while swapping in a page,
125  * and some other program tries to do a serial write at the same time.
126  * Since the lock will only come under contention when the system is
127  * swapping and available memory is low, it makes sense to share one
128  * buffer across all the serial ports, since it significantly saves
129  * memory if large numbers of serial ports are open.
130  */
131 static unsigned char *tmp_buf = 0;
132 DECLARE_MUTEX(tmp_buf_sem);
133
134 /*
135  * This is used to look up the divisor speeds and the timeouts
136  * We're normally limited to 15 distinct baud rates.  The extra
137  * are accessed via settings in info->flags.
138  *         0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
139  *        10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
140  *                                                  HI            VHI
141  */
142 static int baud_table[] = {
143            0,    50,    75,   110,   134,   150,   200,   300,   600,  1200,
144         1800,  2400,  4800,  9600, 19200, 38400, 57600, 76800,115200,150000,
145         0};
146
147 #if 0
148 static char baud_co[] = {  /* 25 MHz clock option table */
149         /* value =>    00    01   02    03    04 */
150         /* divide by    8    32   128   512  2048 */
151         0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,  0x03,  0x02,
152         0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00};
153
154 static char baud_bpr[] = {  /* 25 MHz baud rate period table */
155         0x00,  0xf5,  0xa3,  0x6f,  0x5c,  0x51,  0xf5,  0xa3,  0x51,  0xa3,
156         0x6d,  0x51,  0xa3,  0x51,  0xa3,  0x51,  0x36,  0x29,  0x1b,  0x15};
157 #endif
158
159 /* I think 166 brd clocks 2401 at 20MHz.... */
160
161 /* These values are written directly to tcor, and >> 5 for writing to rcor */
162 static u_char baud_co[] = {  /* 20 MHz clock option table */
163         0x00,  0x80,  0x80,  0x80,  0x80,  0x80,  0x80,  0x60,  0x60,  0x40,
164         0x40,  0x40,  0x20,  0x20,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00};
165
166 /* These values written directly to tbpr/rbpr */
167 static u_char baud_bpr[] = {  /* 20 MHz baud rate period table */
168         0x00,  0xc0,  0x80,  0x58,  0x6c,  0x40,  0xc0,  0x81,  0x40,  0x81,
169         0x57,  0x40,  0x81,  0x40,  0x81,  0x40,  0x2b,  0x20,  0x15,  0x10};
170
171 static u_char baud_cor4[] = {  /* receive threshold */
172         0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
173         0x0a,  0x0a,  0x0a,  0x09,  0x09,  0x08,  0x08,  0x08,  0x08,  0x07};
174
175
176
177 static void shutdown(struct cyclades_port *);
178 static int startup (struct cyclades_port *);
179 static void cy_throttle(struct tty_struct *);
180 static void cy_unthrottle(struct tty_struct *);
181 static void config_setup(struct cyclades_port *);
182 extern void console_print(const char *);
183 #ifdef CYCLOM_SHOW_STATUS
184 static void show_status(int);
185 #endif
186
187 #ifdef CONFIG_REMOTE_DEBUG
188 static void debug_setup(void);
189 void queueDebugChar (int c);
190 int getDebugChar(void);
191
192 #define DEBUG_PORT      1
193 #define DEBUG_LEN       256
194
195 typedef struct {
196         int     in;
197         int     out;
198         unsigned char   buf[DEBUG_LEN];
199 } debugq;
200
201 debugq debugiq;
202 #endif
203
204 /*
205  * I have my own version of udelay(), as it is needed when initialising
206  * the chip, before the delay loop has been calibrated.  Should probably
207  * reference one of the vmechip2 or pccchip2 counter for an accurate
208  * delay, but this wild guess will do for now.
209  */
210
211 void my_udelay (long us)
212 {
213         u_char x;
214         volatile u_char *p = &x;
215         int i;
216
217         while (us--)
218                 for (i = 100; i; i--)
219                         x |= *p;
220 }
221
222 static inline int
223 serial_paranoia_check(struct cyclades_port *info, char *name,
224                       const char *routine)
225 {
226 #ifdef SERIAL_PARANOIA_CHECK
227     static const char *badmagic =
228         "Warning: bad magic number for serial struct (%s) in %s\n";
229     static const char *badinfo =
230         "Warning: null cyclades_port for (%s) in %s\n";
231     static const char *badrange =
232         "Warning: cyclades_port out of range for (%s) in %s\n";
233
234     if (!info) {
235         printk(badinfo, name, routine);
236         return 1;
237     }
238
239     if( (long)info < (long)(&cy_port[0])
240     || (long)(&cy_port[NR_PORTS]) < (long)info ){
241         printk(badrange, name, routine);
242         return 1;
243     }
244
245     if (info->magic != CYCLADES_MAGIC) {
246         printk(badmagic, name, routine);
247         return 1;
248     }
249 #endif
250         return 0;
251 } /* serial_paranoia_check */
252
253 #if 0
254 /* The following diagnostic routines allow the driver to spew
255    information on the screen, even (especially!) during interrupts.
256  */
257 void
258 SP(char *data){
259   unsigned long flags;
260     local_irq_save(flags);
261         console_print(data);
262     local_irq_restore(flags);
263 }
264 char scrn[2];
265 void
266 CP(char data){
267   unsigned long flags;
268     local_irq_save(flags);
269         scrn[0] = data;
270         console_print(scrn);
271     local_irq_restore(flags);
272 }/* CP */
273
274 void CP1(int data) { (data<10)?  CP(data+'0'): CP(data+'A'-10); }/* CP1 */
275 void CP2(int data) { CP1((data>>4) & 0x0f); CP1( data & 0x0f); }/* CP2 */
276 void CP4(int data) { CP2((data>>8) & 0xff); CP2(data & 0xff); }/* CP4 */
277 void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }/* CP8 */
278 #endif
279
280 /* This routine waits up to 1000 micro-seconds for the previous
281    command to the Cirrus chip to complete and then issues the
282    new command.  An error is returned if the previous command
283    didn't finish within the time limit.
284  */
285 u_short
286 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         /* Check to see that the previous command has completed */
293         for(i = 0 ; i < 100 ; i++){
294             if (base_addr[CyCCR] == 0){
295                 break;
296             }
297             my_udelay(10L);
298         }
299         /* if the CCR never cleared, the previous command
300             didn't finish within the "reasonable time" */
301         if ( i == 10 ) {
302             local_irq_restore(flags);
303             return (-1);
304         }
305
306         /* Issue the new command */
307         base_addr[CyCCR] = cmd;
308     local_irq_restore(flags);
309     return(0);
310 } /* write_cy_cmd */
311
312
313 /* cy_start and cy_stop provide software output flow control as a
314    function of XON/XOFF, software CTS, and other such stuff. */
315
316 static void
317 cy_stop(struct tty_struct *tty)
318 {
319   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
320   volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
321   int channel;
322   unsigned long flags;
323
324 #ifdef SERIAL_DEBUG_OTHER
325     printk("cy_stop %s\n", tty->name); /* */
326 #endif
327
328     if (serial_paranoia_check(info, tty->name, "cy_stop"))
329         return;
330         
331     channel = info->line;
332
333     local_irq_save(flags);
334         base_addr[CyCAR] = (u_char)(channel); /* index channel */
335         base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
336     local_irq_restore(flags);
337
338     return;
339 } /* cy_stop */
340
341 static void
342 cy_start(struct tty_struct *tty)
343 {
344   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
345   volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
346   int channel;
347   unsigned long flags;
348
349 #ifdef SERIAL_DEBUG_OTHER
350     printk("cy_start %s\n", tty->name); /* */
351 #endif
352
353     if (serial_paranoia_check(info, tty->name, "cy_start"))
354         return;
355         
356     channel = info->line;
357
358     local_irq_save(flags);
359         base_addr[CyCAR] = (u_char)(channel);
360         base_addr[CyIER] |= CyTxMpty;
361     local_irq_restore(flags);
362
363     return;
364 } /* cy_start */
365
366
367 /*
368  * This routine is used by the interrupt handler to schedule
369  * processing in the software interrupt portion of the driver
370  * (also known as the "bottom half").  This can be called any
371  * number of times for any channel without harm.
372  */
373 static inline void
374 cy_sched_event(struct cyclades_port *info, int event)
375 {
376     info->event |= 1 << event; /* remember what kind of event and who */
377     schedule_work(&info->tqueue);
378 } /* cy_sched_event */
379
380
381 /* The real interrupt service routines are called
382    whenever the card wants its hand held--chars
383    received, out buffer empty, modem change, etc.
384  */
385 static irqreturn_t
386 cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
387 {
388     struct tty_struct *tty;
389     struct cyclades_port *info;
390     volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
391     unsigned char err, rfoc;
392     int channel;
393     char data;
394
395     /* determine the channel and change to that context */
396     channel = (u_short ) (base_addr[CyLICR] >> 2);
397     info = &cy_port[channel];
398     info->last_active = jiffies;
399
400     if ((err = base_addr[CyRISR]) & CyTIMEOUT) {
401         /* This is a receive timeout interrupt, ignore it */
402         base_addr[CyREOIR] = CyNOTRANS;
403         return IRQ_HANDLED;
404     }
405
406     /* Read a byte of data if there is any - assume the error
407      * is associated with this character */
408
409     if ((rfoc = base_addr[CyRFOC]) != 0)
410         data = base_addr[CyRDR];
411     else
412         data = 0;
413
414     /* if there is nowhere to put the data, discard it */
415     if(info->tty == 0) {
416         base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
417         return IRQ_HANDLED;
418     }
419     else { /* there is an open port for this data */
420         tty = info->tty;
421         if(err & info->ignore_status_mask){
422             base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
423             return IRQ_HANDLED;
424         }
425         if (tty_buffer_request_room(tty, 1) != 0){
426             if (err & info->read_status_mask){
427                 if(err & CyBREAK){
428                     tty_insert_flip_char(tty, data, TTY_BREAK);
429                     if (info->flags & ASYNC_SAK){
430                         do_SAK(tty);
431                     }
432                 }else if(err & CyFRAME){
433                     tty_insert_flip_char(tty, data, TTY_FRAME);
434                 }else if(err & CyPARITY){
435                     tty_insert_flip_char(tty, data, TTY_PARITY);
436                 }else if(err & CyOVERRUN){
437                     tty_insert_flip_char(tty, 0, TTY_OVERRUN);
438                     /*
439                        If the flip buffer itself is
440                        overflowing, we still loose
441                        the next incoming character.
442                      */
443                     tty_insert_flip_char(tty, data, TTY_NORMAL);
444                 }
445                 /* These two conditions may imply */
446                 /* a normal read should be done. */
447                 /* else if(data & CyTIMEOUT) */
448                 /* else if(data & CySPECHAR) */
449                 }else{
450                     tty_insert_flip_char(tty, 0, TTY_NORMAL);
451                 }
452             }else{
453                     tty_insert_flip_char(tty, data, TTY_NORMAL);
454             }
455         }else{
456             /* there was a software buffer overrun
457                and nothing could be done about it!!! */
458         }
459     }
460     schedule_delayed_work(&tty->flip.work, 1);
461     /* end of service */
462     base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
463     return IRQ_HANDLED;
464 } /* cy_rxerr_interrupt */
465
466 static irqreturn_t
467 cd2401_modem_interrupt(int irq, void *dev_id, struct pt_regs *fp)
468 {
469     struct cyclades_port *info;
470     volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
471     int channel;
472     int mdm_change;
473     int mdm_status;
474
475
476     /* determine the channel and change to that context */
477     channel = (u_short ) (base_addr[CyLICR] >> 2);
478     info = &cy_port[channel];
479     info->last_active = jiffies;
480
481     mdm_change = base_addr[CyMISR];
482     mdm_status = base_addr[CyMSVR1];
483
484     if(info->tty == 0){ /* nowhere to put the data, ignore it */
485         ;
486     }else{
487         if((mdm_change & CyDCD)
488         && (info->flags & ASYNC_CHECK_CD)){
489             if(mdm_status & CyDCD){
490 /* CP('!'); */
491                 cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
492             } else {
493 /* CP('@'); */
494                 cy_sched_event(info, Cy_EVENT_HANGUP);
495             }
496         }
497         if((mdm_change & CyCTS)
498         && (info->flags & ASYNC_CTS_FLOW)){
499             if(info->tty->stopped){
500                 if(mdm_status & CyCTS){
501                     /* !!! cy_start isn't used because... */
502                     info->tty->stopped = 0;
503                     base_addr[CyIER] |= CyTxMpty;
504                     cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
505                 }
506             }else{
507                 if(!(mdm_status & CyCTS)){
508                     /* !!! cy_stop isn't used because... */
509                     info->tty->stopped = 1;
510                     base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
511                 }
512             }
513         }
514         if(mdm_status & CyDSR){
515         }
516     }
517     base_addr[CyMEOIR] = 0;
518     return IRQ_HANDLED;
519 } /* cy_modem_interrupt */
520
521 static irqreturn_t
522 cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
523 {
524     struct cyclades_port *info;
525     volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
526     int channel;
527     int char_count, saved_cnt;
528     int outch;
529
530     /* determine the channel and change to that context */
531     channel = (u_short ) (base_addr[CyLICR] >> 2);
532
533 #ifdef CONFIG_REMOTE_DEBUG
534     if (channel == DEBUG_PORT) {
535         panic ("TxInt on debug port!!!");
536     }
537 #endif
538
539     info = &cy_port[channel];
540
541     /* validate the port number (as configured and open) */
542     if( (channel < 0) || (NR_PORTS <= channel) ){
543         base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
544         base_addr[CyTEOIR] = CyNOTRANS;
545         return IRQ_HANDLED;
546     }
547     info->last_active = jiffies;
548     if(info->tty == 0){
549         base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
550         if (info->xmit_cnt < WAKEUP_CHARS) {
551             cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
552         }
553         base_addr[CyTEOIR] = CyNOTRANS;
554         return IRQ_HANDLED;
555     }
556
557     /* load the on-chip space available for outbound data */
558     saved_cnt = char_count = base_addr[CyTFTC];
559
560     if(info->x_char) { /* send special char */
561         outch = info->x_char;
562         base_addr[CyTDR] = outch;
563         char_count--;
564         info->x_char = 0;
565     }
566
567     if (info->x_break){
568         /*  The Cirrus chip requires the "Embedded Transmit
569             Commands" of start break, delay, and end break
570             sequences to be sent.  The duration of the
571             break is given in TICs, which runs at HZ
572             (typically 100) and the PPR runs at 200 Hz,
573             so the delay is duration * 200/HZ, and thus a
574             break can run from 1/100 sec to about 5/4 sec.
575             Need to check these values - RGH 141095.
576          */
577         base_addr[CyTDR] = 0; /* start break */
578         base_addr[CyTDR] = 0x81;
579         base_addr[CyTDR] = 0; /* delay a bit */
580         base_addr[CyTDR] = 0x82;
581         base_addr[CyTDR] = info->x_break*200/HZ;
582         base_addr[CyTDR] = 0; /* terminate break */
583         base_addr[CyTDR] = 0x83;
584         char_count -= 7;
585         info->x_break = 0;
586     }
587
588     while (char_count > 0){
589         if (!info->xmit_cnt){
590             base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
591             break;
592         }
593         if (info->xmit_buf == 0){
594             base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
595             break;
596         }
597         if (info->tty->stopped || info->tty->hw_stopped){
598             base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
599             break;
600         }
601         /* Because the Embedded Transmit Commands have been
602            enabled, we must check to see if the escape
603            character, NULL, is being sent.  If it is, we
604            must ensure that there is room for it to be
605            doubled in the output stream.  Therefore we
606            no longer advance the pointer when the character
607            is fetched, but rather wait until after the check
608            for a NULL output character. (This is necessary
609            because there may not be room for the two chars
610            needed to send a NULL.
611          */
612         outch = info->xmit_buf[info->xmit_tail];
613         if( outch ){
614             info->xmit_cnt--;
615             info->xmit_tail = (info->xmit_tail + 1)
616                                       & (PAGE_SIZE - 1);
617             base_addr[CyTDR] = outch;
618             char_count--;
619         }else{
620             if(char_count > 1){
621                 info->xmit_cnt--;
622                 info->xmit_tail = (info->xmit_tail + 1)
623                                           & (PAGE_SIZE - 1);
624                 base_addr[CyTDR] = outch;
625                 base_addr[CyTDR] = 0;
626                 char_count--;
627                 char_count--;
628             }else{
629                 break;
630             }
631         }
632     }
633
634     if (info->xmit_cnt < WAKEUP_CHARS) {
635         cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
636     }
637     base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS;
638     return IRQ_HANDLED;
639 } /* cy_tx_interrupt */
640
641 static irqreturn_t
642 cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
643 {
644     struct tty_struct *tty;
645     struct cyclades_port *info;
646     volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
647     int channel;
648     char data;
649     int char_count;
650     int save_cnt;
651
652     /* determine the channel and change to that context */
653     channel = (u_short ) (base_addr[CyLICR] >> 2);
654     info = &cy_port[channel];
655     info->last_active = jiffies;
656     save_cnt = char_count = base_addr[CyRFOC];
657
658 #ifdef CONFIG_REMOTE_DEBUG
659     if (channel == DEBUG_PORT) {
660         while (char_count--) {
661             data = base_addr[CyRDR];
662             queueDebugChar(data);
663         }
664     }
665     else
666 #endif
667     /* if there is nowhere to put the data, discard it */
668     if(info->tty == 0){
669         while(char_count--){
670             data = base_addr[CyRDR];
671         }
672     }else{ /* there is an open port for this data */
673         tty = info->tty;
674         /* load # characters available from the chip */
675
676 #ifdef CYCLOM_ENABLE_MONITORING
677         ++info->mon.int_count;
678         info->mon.char_count += char_count;
679         if (char_count > info->mon.char_max)
680             info->mon.char_max = char_count;
681         info->mon.char_last = char_count;
682 #endif
683         while(char_count--){
684             data = base_addr[CyRDR];
685             tty_insert_flip_char(tty, data, TTY_NORMAL);
686 #ifdef CYCLOM_16Y_HACK
687             udelay(10L);
688 #endif
689         }
690         schedule_delayed_work(&tty->flip.work, 1);
691     }
692     /* end of service */
693     base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
694     return IRQ_HANDLED;
695 } /* cy_rx_interrupt */
696
697 /*
698  * This routine is used to handle the "bottom half" processing for the
699  * serial driver, known also the "software interrupt" processing.
700  * This processing is done at the kernel interrupt level, after the
701  * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
702  * is where time-consuming activities which can not be done in the
703  * interrupt driver proper are done; the interrupt driver schedules
704  * them using cy_sched_event(), and they get done here.
705  *
706  * This is done through one level of indirection--the task queue.
707  * When a hardware interrupt service routine wants service by the
708  * driver's bottom half, it enqueues the appropriate tq_struct (one
709  * per port) to the keventd work queue and sets a request flag
710  * that the work queue be processed.
711  *
712  * Although this may seem unwieldy, it gives the system a way to
713  * pass an argument (in this case the pointer to the cyclades_port
714  * structure) to the bottom half of the driver.  Previous kernels
715  * had to poll every port to see if that port needed servicing.
716  */
717 static void
718 do_softint(void *private_)
719 {
720   struct cyclades_port *info = (struct cyclades_port *) private_;
721   struct tty_struct    *tty;
722
723     tty = info->tty;
724     if (!tty)
725         return;
726
727     if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
728         tty_hangup(info->tty);
729         wake_up_interruptible(&info->open_wait);
730         info->flags &= ~ASYNC_NORMAL_ACTIVE;
731     }
732     if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
733         wake_up_interruptible(&info->open_wait);
734     }
735     if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
736         tty_wakeup(tty);
737     }
738 } /* do_softint */
739
740
741 /* This is called whenever a port becomes active;
742    interrupts are enabled and DTR & RTS are turned on.
743  */
744 static int
745 startup(struct cyclades_port * info)
746 {
747   unsigned long flags;
748   volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
749   int channel;
750
751     if (info->flags & ASYNC_INITIALIZED){
752         return 0;
753     }
754
755     if (!info->type){
756         if (info->tty){
757             set_bit(TTY_IO_ERROR, &info->tty->flags);
758         }
759         return 0;
760     }
761     if (!info->xmit_buf){
762         info->xmit_buf = (unsigned char *) get_zeroed_page (GFP_KERNEL);
763         if (!info->xmit_buf){
764             return -ENOMEM;
765         }
766     }
767
768     config_setup(info);
769
770     channel = info->line;
771
772 #ifdef SERIAL_DEBUG_OPEN
773     printk("startup channel %d\n", channel);
774 #endif
775
776     local_irq_save(flags);
777         base_addr[CyCAR] = (u_char)channel;
778         write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR);
779
780         base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
781         base_addr[CyMSVR1] = CyRTS;
782 /* CP('S');CP('1'); */
783         base_addr[CyMSVR2] = CyDTR;
784
785 #ifdef SERIAL_DEBUG_DTR
786         printk("cyc: %d: raising DTR\n", __LINE__);
787         printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
788 #endif
789
790         base_addr[CyIER] |= CyRxData;
791         info->flags |= ASYNC_INITIALIZED;
792
793         if (info->tty){
794             clear_bit(TTY_IO_ERROR, &info->tty->flags);
795         }
796         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
797
798     local_irq_restore(flags);
799
800 #ifdef SERIAL_DEBUG_OPEN
801     printk(" done\n");
802 #endif
803     return 0;
804 } /* startup */
805
806 void
807 start_xmit( struct cyclades_port *info )
808 {
809   unsigned long flags;
810   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
811   int channel;
812
813     channel = info->line;
814     local_irq_save(flags);
815         base_addr[CyCAR] = channel;
816         base_addr[CyIER] |= CyTxMpty;
817     local_irq_restore(flags);
818 } /* start_xmit */
819
820 /*
821  * This routine shuts down a serial port; interrupts are disabled,
822  * and DTR is dropped if the hangup on close termio flag is on.
823  */
824 static void
825 shutdown(struct cyclades_port * info)
826 {
827   unsigned long flags;
828   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
829   int channel;
830
831     if (!(info->flags & ASYNC_INITIALIZED)){
832 /* CP('$'); */
833         return;
834     }
835
836     channel = info->line;
837
838 #ifdef SERIAL_DEBUG_OPEN
839     printk("shutdown channel %d\n", channel);
840 #endif
841
842     /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE
843        SENT BEFORE DROPPING THE LINE !!!  (Perhaps
844        set some flag that is read when XMTY happens.)
845        Other choices are to delay some fixed interval
846        or schedule some later processing.
847      */
848     local_irq_save(flags);
849         if (info->xmit_buf){
850             free_page((unsigned long) info->xmit_buf);
851             info->xmit_buf = 0;
852         }
853
854         base_addr[CyCAR] = (u_char)channel;
855         if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
856             base_addr[CyMSVR1] = 0;
857 /* CP('C');CP('1'); */
858             base_addr[CyMSVR2] = 0;
859 #ifdef SERIAL_DEBUG_DTR
860             printk("cyc: %d: dropping DTR\n", __LINE__);
861             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
862 #endif
863         }
864         write_cy_cmd(base_addr,CyDIS_RCVR);
865          /* it may be appropriate to clear _XMIT at
866            some later date (after testing)!!! */
867
868         if (info->tty){
869             set_bit(TTY_IO_ERROR, &info->tty->flags);
870         }
871         info->flags &= ~ASYNC_INITIALIZED;
872     local_irq_restore(flags);
873
874 #ifdef SERIAL_DEBUG_OPEN
875     printk(" done\n");
876 #endif
877     return;
878 } /* shutdown */
879
880 /*
881  * This routine finds or computes the various line characteristics.
882  */
883 static void
884 config_setup(struct cyclades_port * info)
885 {
886   unsigned long flags;
887   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
888   int channel;
889   unsigned cflag;
890   int   i;
891   unsigned char ti, need_init_chan = 0;
892
893     if (!info->tty || !info->tty->termios){
894         return;
895     }
896     if (info->line == -1){
897         return;
898     }
899     cflag = info->tty->termios->c_cflag;
900
901     /* baud rate */
902     i = cflag & CBAUD;
903 #ifdef CBAUDEX
904 /* Starting with kernel 1.1.65, there is direct support for
905    higher baud rates.  The following code supports those
906    changes.  The conditional aspect allows this driver to be
907    used for earlier as well as later kernel versions.  (The
908    mapping is slightly different from serial.c because there
909    is still the possibility of supporting 75 kbit/sec with
910    the Cyclades board.)
911  */
912     if (i & CBAUDEX) {
913         if (i == B57600)
914             i = 16;
915         else if(i == B115200) 
916             i = 18;
917 #ifdef B78600
918         else if(i == B78600) 
919             i = 17;
920 #endif
921         else
922             info->tty->termios->c_cflag &= ~CBAUDEX;
923     }
924 #endif
925     if (i == 15) {
926             if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
927                     i += 1;
928             if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
929                     i += 3;
930     }
931     /* Don't ever change the speed of the console port.  It will
932      * run at the speed specified in bootinfo, or at 19.2K */
933     /* Actually, it should run at whatever speed 166Bug was using */
934     /* Note info->timeout isn't used at present */
935     if (info != serial_console_info) {
936         info->tbpr = baud_bpr[i]; /* Tx BPR */
937         info->tco = baud_co[i]; /* Tx CO */
938         info->rbpr = baud_bpr[i]; /* Rx BPR */
939         info->rco = baud_co[i] >> 5; /* Rx CO */
940         if (baud_table[i] == 134) {
941             info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
942             /* get it right for 134.5 baud */
943         } else if (baud_table[i]) {
944             info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
945         /* this needs to be propagated into the card info */
946         } else {
947             info->timeout = 0;
948         }
949     }
950     /* By tradition (is it a standard?) a baud rate of zero
951        implies the line should be/has been closed.  A bit
952        later in this routine such a test is performed. */
953
954     /* byte size and parity */
955     info->cor7 = 0;
956     info->cor6 = 0;
957     info->cor5 = 0;
958     info->cor4 = (info->default_threshold
959                   ? info->default_threshold
960                   : baud_cor4[i]); /* receive threshold */
961     /* Following two lines added 101295, RGH. */
962     /* It is obviously wrong to access CyCORx, and not info->corx here,
963      * try and remember to fix it later! */
964     channel = info->line;
965     base_addr[CyCAR] = (u_char)channel;
966     if (C_CLOCAL(info->tty)) {
967         if (base_addr[CyIER] & CyMdmCh)
968             base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */
969                                /* ignore 1->0 modem transitions */
970         if (base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD))
971             base_addr[CyCOR4] &= ~(CyDSR|CyCTS|CyDCD);
972                                /* ignore 0->1 modem transitions */
973         if (base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD))
974             base_addr[CyCOR5] &= ~(CyDSR|CyCTS|CyDCD);
975     } else {
976         if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh)
977             base_addr[CyIER] |= CyMdmCh; /* with modem intr */
978                                /* act on 1->0 modem transitions */
979         if ((base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD))
980             base_addr[CyCOR4] |= CyDSR|CyCTS|CyDCD;
981                                /* act on 0->1 modem transitions */
982         if ((base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD))
983             base_addr[CyCOR5] |= CyDSR|CyCTS|CyDCD;
984     }
985     info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP;
986     info->cor2 = CyETC;
987     switch(cflag & CSIZE){
988     case CS5:
989         info->cor1 = Cy_5_BITS;
990         break;
991     case CS6:
992         info->cor1 = Cy_6_BITS;
993         break;
994     case CS7:
995         info->cor1 = Cy_7_BITS;
996         break;
997     case CS8:
998         info->cor1 = Cy_8_BITS;
999         break;
1000     }
1001     if (cflag & PARENB){
1002         if (cflag & PARODD){
1003             info->cor1 |= CyPARITY_O;
1004         }else{
1005             info->cor1 |= CyPARITY_E;
1006         }
1007     }else{
1008         info->cor1 |= CyPARITY_NONE;
1009     }
1010         
1011     /* CTS flow control flag */
1012 #if 0
1013     /* Don't complcate matters for now! RGH 141095 */
1014     if (cflag & CRTSCTS){
1015         info->flags |= ASYNC_CTS_FLOW;
1016         info->cor2 |= CyCtsAE;
1017     }else{
1018         info->flags &= ~ASYNC_CTS_FLOW;
1019         info->cor2 &= ~CyCtsAE;
1020     }
1021 #endif
1022     if (cflag & CLOCAL)
1023         info->flags &= ~ASYNC_CHECK_CD;
1024     else
1025         info->flags |= ASYNC_CHECK_CD;
1026
1027      /***********************************************
1028         The hardware option, CyRtsAO, presents RTS when
1029         the chip has characters to send.  Since most modems
1030         use RTS as reverse (inbound) flow control, this
1031         option is not used.  If inbound flow control is
1032         necessary, DTR can be programmed to provide the
1033         appropriate signals for use with a non-standard
1034         cable.  Contact Marcio Saito for details.
1035      ***********************************************/
1036
1037     channel = info->line;
1038
1039     local_irq_save(flags);
1040         base_addr[CyCAR] = (u_char)channel;
1041
1042         /* CyCMR set once only in mvme167_init_serial() */
1043         if (base_addr[CyLICR] != channel << 2)
1044             base_addr[CyLICR] = channel << 2;
1045         if (base_addr[CyLIVR] != 0x5c)
1046             base_addr[CyLIVR] = 0x5c;
1047
1048        /* tx and rx baud rate */
1049
1050         if (base_addr[CyCOR1] != info->cor1)
1051             need_init_chan = 1;
1052         if (base_addr[CyTCOR] != info->tco)
1053             base_addr[CyTCOR] = info->tco;
1054         if (base_addr[CyTBPR] != info->tbpr)
1055             base_addr[CyTBPR] = info->tbpr;
1056         if (base_addr[CyRCOR] != info->rco)
1057             base_addr[CyRCOR] = info->rco;
1058         if (base_addr[CyRBPR] != info->rbpr)
1059             base_addr[CyRBPR] = info->rbpr;
1060
1061         /* set line characteristics  according configuration */
1062
1063         if (base_addr[CySCHR1] != START_CHAR(info->tty))
1064             base_addr[CySCHR1] = START_CHAR(info->tty);
1065         if (base_addr[CySCHR2] != STOP_CHAR(info->tty))
1066             base_addr[CySCHR2] = STOP_CHAR(info->tty);
1067         if (base_addr[CySCRL] != START_CHAR(info->tty))
1068             base_addr[CySCRL] = START_CHAR(info->tty);
1069         if (base_addr[CySCRH] != START_CHAR(info->tty))
1070             base_addr[CySCRH] = START_CHAR(info->tty);
1071         if (base_addr[CyCOR1] != info->cor1)
1072             base_addr[CyCOR1] = info->cor1;
1073         if (base_addr[CyCOR2] != info->cor2)
1074             base_addr[CyCOR2] = info->cor2;
1075         if (base_addr[CyCOR3] != info->cor3)
1076             base_addr[CyCOR3] = info->cor3;
1077         if (base_addr[CyCOR4] != info->cor4)
1078             base_addr[CyCOR4] = info->cor4;
1079         if (base_addr[CyCOR5] != info->cor5)
1080             base_addr[CyCOR5] = info->cor5;
1081         if (base_addr[CyCOR6] != info->cor6)
1082             base_addr[CyCOR6] = info->cor6;
1083         if (base_addr[CyCOR7] != info->cor7)
1084             base_addr[CyCOR7] = info->cor7;
1085
1086         if (need_init_chan)
1087             write_cy_cmd(base_addr,CyINIT_CHAN);
1088
1089         base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
1090
1091         /* 2ms default rx timeout */
1092         ti = info->default_timeout ? info->default_timeout : 0x02;
1093         if (base_addr[CyRTPRL] != ti)
1094             base_addr[CyRTPRL] = ti;
1095         if (base_addr[CyRTPRH] != 0)
1096             base_addr[CyRTPRH] = 0;
1097
1098         /* Set up RTS here also ????? RGH 141095 */
1099         if(i == 0){ /* baud rate is zero, turn off line */
1100             if ((base_addr[CyMSVR2] & CyDTR) == CyDTR)
1101                 base_addr[CyMSVR2] = 0;
1102 #ifdef SERIAL_DEBUG_DTR
1103             printk("cyc: %d: dropping DTR\n", __LINE__);
1104             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1105 #endif
1106         }else{
1107             if ((base_addr[CyMSVR2] & CyDTR) != CyDTR)
1108                 base_addr[CyMSVR2] = CyDTR;
1109 #ifdef SERIAL_DEBUG_DTR
1110             printk("cyc: %d: raising DTR\n", __LINE__);
1111             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1112 #endif
1113         }
1114
1115         if (info->tty){
1116             clear_bit(TTY_IO_ERROR, &info->tty->flags);
1117         }
1118
1119     local_irq_restore(flags);
1120
1121 } /* config_setup */
1122
1123
1124 static void
1125 cy_put_char(struct tty_struct *tty, unsigned char ch)
1126 {
1127   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1128   unsigned long flags;
1129
1130 #ifdef SERIAL_DEBUG_IO
1131     printk("cy_put_char %s(0x%02x)\n", tty->name, ch);
1132 #endif
1133
1134     if (serial_paranoia_check(info, tty->name, "cy_put_char"))
1135         return;
1136
1137     if (!tty || !info->xmit_buf)
1138         return;
1139
1140     local_irq_save(flags);
1141         if (info->xmit_cnt >= PAGE_SIZE - 1) {
1142             local_irq_restore(flags);
1143             return;
1144         }
1145
1146         info->xmit_buf[info->xmit_head++] = ch;
1147         info->xmit_head &= PAGE_SIZE - 1;
1148         info->xmit_cnt++;
1149     local_irq_restore(flags);
1150 } /* cy_put_char */
1151
1152
1153 static void
1154 cy_flush_chars(struct tty_struct *tty)
1155 {
1156   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1157   unsigned long flags;
1158   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1159   int channel;
1160                                 
1161 #ifdef SERIAL_DEBUG_IO
1162     printk("cy_flush_chars %s\n", tty->name); /* */
1163 #endif
1164
1165     if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
1166         return;
1167
1168     if (info->xmit_cnt <= 0 || tty->stopped
1169     || tty->hw_stopped || !info->xmit_buf)
1170         return;
1171
1172     channel = info->line;
1173
1174     local_irq_save(flags);
1175         base_addr[CyCAR] = channel;
1176         base_addr[CyIER] |= CyTxMpty;
1177     local_irq_restore(flags);
1178 } /* cy_flush_chars */
1179
1180
1181 /* This routine gets called when tty_write has put something into
1182     the write_queue.  If the port is not already transmitting stuff,
1183     start it off by enabling interrupts.  The interrupt service
1184     routine will then ensure that the characters are sent.  If the
1185     port is already active, there is no need to kick it.
1186  */
1187 static int
1188 cy_write(struct tty_struct * tty,
1189            const unsigned char *buf, int count)
1190 {
1191   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1192   unsigned long flags;
1193   int c, total = 0;
1194
1195 #ifdef SERIAL_DEBUG_IO
1196     printk("cy_write %s\n", tty->name); /* */
1197 #endif
1198
1199     if (serial_paranoia_check(info, tty->name, "cy_write")){
1200         return 0;
1201     }
1202         
1203     if (!tty || !info->xmit_buf || !tmp_buf){
1204         return 0;
1205     }
1206
1207     while (1) {
1208             local_irq_save(flags);
1209             c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1210                                       SERIAL_XMIT_SIZE - info->xmit_head));
1211             if (c <= 0) {
1212                     local_irq_restore(flags);
1213                     break;
1214             }
1215
1216             memcpy(info->xmit_buf + info->xmit_head, buf, c);
1217             info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1218             info->xmit_cnt += c;
1219             local_irq_restore(flags);
1220
1221             buf += c;
1222             count -= c;
1223             total += c;
1224     }
1225
1226     if (info->xmit_cnt
1227     && !tty->stopped
1228     && !tty->hw_stopped ) {
1229         start_xmit(info);
1230     }
1231     return total;
1232 } /* cy_write */
1233
1234
1235 static int
1236 cy_write_room(struct tty_struct *tty)
1237 {
1238   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1239   int   ret;
1240                                 
1241 #ifdef SERIAL_DEBUG_IO
1242     printk("cy_write_room %s\n", tty->name); /* */
1243 #endif
1244
1245     if (serial_paranoia_check(info, tty->name, "cy_write_room"))
1246         return 0;
1247     ret = PAGE_SIZE - info->xmit_cnt - 1;
1248     if (ret < 0)
1249         ret = 0;
1250     return ret;
1251 } /* cy_write_room */
1252
1253
1254 static int
1255 cy_chars_in_buffer(struct tty_struct *tty)
1256 {
1257   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1258                                 
1259 #ifdef SERIAL_DEBUG_IO
1260     printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */
1261 #endif
1262
1263     if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
1264         return 0;
1265
1266     return info->xmit_cnt;
1267 } /* cy_chars_in_buffer */
1268
1269
1270 static void
1271 cy_flush_buffer(struct tty_struct *tty)
1272 {
1273   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1274   unsigned long flags;
1275                                 
1276 #ifdef SERIAL_DEBUG_IO
1277     printk("cy_flush_buffer %s\n", tty->name); /* */
1278 #endif
1279
1280     if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
1281         return;
1282     local_irq_save(flags);
1283         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1284     local_irq_restore(flags);
1285     tty_wakeup(tty);
1286 } /* cy_flush_buffer */
1287
1288
1289 /* This routine is called by the upper-layer tty layer to signal
1290    that incoming characters should be throttled or that the
1291    throttle should be released.
1292  */
1293 static void
1294 cy_throttle(struct tty_struct * tty)
1295 {
1296   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1297   unsigned long flags;
1298   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1299   int channel;
1300
1301 #ifdef SERIAL_DEBUG_THROTTLE
1302   char buf[64];
1303         
1304     printk("throttle %s: %d....\n", tty_name(tty, buf),
1305            tty->ldisc.chars_in_buffer(tty));
1306     printk("cy_throttle %s\n", tty->name);
1307 #endif
1308
1309     if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){
1310             return;
1311     }
1312
1313     if (I_IXOFF(tty)) {
1314         info->x_char = STOP_CHAR(tty);
1315             /* Should use the "Send Special Character" feature!!! */
1316     }
1317
1318     channel = info->line;
1319
1320     local_irq_save(flags);
1321         base_addr[CyCAR] = (u_char)channel;
1322         base_addr[CyMSVR1] = 0;
1323     local_irq_restore(flags);
1324
1325     return;
1326 } /* cy_throttle */
1327
1328
1329 static void
1330 cy_unthrottle(struct tty_struct * tty)
1331 {
1332   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1333   unsigned long flags;
1334   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1335   int channel;
1336
1337 #ifdef SERIAL_DEBUG_THROTTLE
1338   char buf[64];
1339         
1340     printk("throttle %s: %d....\n", tty_name(tty, buf),
1341            tty->ldisc.chars_in_buffer(tty));
1342     printk("cy_unthrottle %s\n", tty->name);
1343 #endif
1344
1345     if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){
1346             return;
1347     }
1348
1349     if (I_IXOFF(tty)) {
1350         info->x_char = START_CHAR(tty);
1351         /* Should use the "Send Special Character" feature!!! */
1352     }
1353
1354     channel = info->line;
1355
1356     local_irq_save(flags);
1357         base_addr[CyCAR] = (u_char)channel;
1358         base_addr[CyMSVR1] = CyRTS;
1359     local_irq_restore(flags);
1360
1361     return;
1362 } /* cy_unthrottle */
1363
1364 static int
1365 get_serial_info(struct cyclades_port * info,
1366                            struct serial_struct * retinfo)
1367 {
1368   struct serial_struct tmp;
1369
1370 /* CP('g'); */
1371     if (!retinfo)
1372             return -EFAULT;
1373     memset(&tmp, 0, sizeof(tmp));
1374     tmp.type = info->type;
1375     tmp.line = info->line;
1376     tmp.port = info->line;
1377     tmp.irq = 0;
1378     tmp.flags = info->flags;
1379     tmp.baud_base = 0;          /*!!!*/
1380     tmp.close_delay = info->close_delay;
1381     tmp.custom_divisor = 0;     /*!!!*/
1382     tmp.hub6 = 0;               /*!!!*/
1383     return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0;
1384 } /* get_serial_info */
1385
1386 static int
1387 set_serial_info(struct cyclades_port * info,
1388                            struct serial_struct * new_info)
1389 {
1390   struct serial_struct new_serial;
1391   struct cyclades_port old_info;
1392
1393 /* CP('s'); */
1394     if (!new_info)
1395             return -EFAULT;
1396     if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
1397             return -EFAULT;
1398     old_info = *info;
1399
1400     if (!capable(CAP_SYS_ADMIN)) {
1401             if ((new_serial.close_delay != info->close_delay) ||
1402                 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
1403                  (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
1404                     return -EPERM;
1405             info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1406                            (new_serial.flags & ASYNC_USR_MASK));
1407             goto check_and_exit;
1408     }
1409
1410
1411     /*
1412      * OK, past this point, all the error checking has been done.
1413      * At this point, we start making changes.....
1414      */
1415
1416     info->flags = ((info->flags & ~ASYNC_FLAGS) |
1417                     (new_serial.flags & ASYNC_FLAGS));
1418     info->close_delay = new_serial.close_delay;
1419
1420
1421 check_and_exit:
1422     if (info->flags & ASYNC_INITIALIZED){
1423         config_setup(info);
1424         return 0;
1425     }else{
1426         return startup(info);
1427     }
1428 } /* set_serial_info */
1429
1430 static int
1431 cy_tiocmget(struct tty_struct *tty, struct file *file)
1432 {
1433   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1434   int channel;
1435   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1436   unsigned long flags;
1437   unsigned char status;
1438   unsigned int result;
1439
1440     channel = info->line;
1441
1442     local_irq_save(flags);
1443         base_addr[CyCAR] = (u_char)channel;
1444         status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
1445     local_irq_restore(flags);
1446
1447     return    ((status  & CyRTS) ? TIOCM_RTS : 0)
1448             | ((status  & CyDTR) ? TIOCM_DTR : 0)
1449             | ((status  & CyDCD) ? TIOCM_CAR : 0)
1450             | ((status  & CyDSR) ? TIOCM_DSR : 0)
1451             | ((status  & CyCTS) ? TIOCM_CTS : 0);
1452 } /* cy_tiocmget */
1453
1454 static int
1455 cy_tiocmset(struct tty_struct *tty, struct file *file,
1456             unsigned int set, unsigned int clear)
1457 {
1458   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1459   int channel;
1460   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1461   unsigned long flags;
1462   unsigned int arg;
1463           
1464     channel = info->line;
1465
1466         if (set & TIOCM_RTS){
1467             local_irq_save(flags);
1468                 base_addr[CyCAR] = (u_char)channel;
1469                 base_addr[CyMSVR1] = CyRTS;
1470             local_irq_restore(flags);
1471         }
1472         if (set & TIOCM_DTR){
1473             local_irq_save(flags);
1474             base_addr[CyCAR] = (u_char)channel;
1475 /* CP('S');CP('2'); */
1476             base_addr[CyMSVR2] = CyDTR;
1477 #ifdef SERIAL_DEBUG_DTR
1478             printk("cyc: %d: raising DTR\n", __LINE__);
1479             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1480 #endif
1481             local_irq_restore(flags);
1482         }
1483
1484         if (clear & TIOCM_RTS){
1485             local_irq_save(flags);
1486                 base_addr[CyCAR] = (u_char)channel;
1487                 base_addr[CyMSVR1] = 0;
1488             local_irq_restore(flags);
1489         }
1490         if (clear & TIOCM_DTR){
1491             local_irq_save(flags);
1492             base_addr[CyCAR] = (u_char)channel;
1493 /* CP('C');CP('2'); */
1494             base_addr[CyMSVR2] = 0;
1495 #ifdef SERIAL_DEBUG_DTR
1496             printk("cyc: %d: dropping DTR\n", __LINE__);
1497             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1498 #endif
1499             local_irq_restore(flags);
1500         }
1501
1502     return 0;
1503 } /* set_modem_info */
1504
1505 static void
1506 send_break( struct cyclades_port * info, int duration)
1507 { /* Let the transmit ISR take care of this (since it
1508      requires stuffing characters into the output stream).
1509    */
1510     info->x_break = duration;
1511     if (!info->xmit_cnt ) {
1512         start_xmit(info);
1513     }
1514 } /* send_break */
1515
1516 static int
1517 get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
1518 {
1519
1520    if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
1521            return -EFAULT;
1522    info->mon.int_count  = 0;
1523    info->mon.char_count = 0;
1524    info->mon.char_max   = 0;
1525    info->mon.char_last  = 0;
1526    return 0;
1527 }
1528
1529 static int
1530 set_threshold(struct cyclades_port * info, unsigned long *arg)
1531 {
1532    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1533    unsigned long value;
1534    int channel;
1535    
1536    if (get_user(value, arg))
1537            return -EFAULT;
1538
1539    channel = info->line;
1540    info->cor4 &= ~CyREC_FIFO;
1541    info->cor4 |= value & CyREC_FIFO;
1542    base_addr[CyCOR4] = info->cor4;
1543    return 0;
1544 }
1545
1546 static int
1547 get_threshold(struct cyclades_port * info, unsigned long *value)
1548 {
1549    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1550    int channel;
1551    unsigned long tmp;
1552    
1553    channel = info->line;
1554
1555    tmp = base_addr[CyCOR4] & CyREC_FIFO;
1556    return put_user(tmp,value);
1557 }
1558
1559 static int
1560 set_default_threshold(struct cyclades_port * info, unsigned long *arg)
1561 {
1562    unsigned long value;
1563
1564    if (get_user(value, arg))
1565         return -EFAULT;
1566
1567    info->default_threshold = value & 0x0f;
1568    return 0;
1569 }
1570
1571 static int
1572 get_default_threshold(struct cyclades_port * info, unsigned long *value)
1573 {
1574    return put_user(info->default_threshold,value);
1575 }
1576
1577 static int
1578 set_timeout(struct cyclades_port * info, unsigned long *arg)
1579 {
1580    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1581    int channel;
1582    unsigned long value;
1583
1584    if (get_user(value, arg))
1585            return -EFAULT;
1586    
1587    channel = info->line;
1588
1589    base_addr[CyRTPRL] = value & 0xff;
1590    base_addr[CyRTPRH] = (value >> 8) & 0xff;
1591    return 0;
1592 }
1593
1594 static int
1595 get_timeout(struct cyclades_port * info, unsigned long *value)
1596 {
1597    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1598    int channel;
1599    unsigned long tmp;
1600    
1601    channel = info->line;
1602
1603    tmp = base_addr[CyRTPRL];
1604    return put_user(tmp,value);
1605 }
1606
1607 static int
1608 set_default_timeout(struct cyclades_port * info, unsigned long value)
1609 {
1610    info->default_timeout = value & 0xff;
1611    return 0;
1612 }
1613
1614 static int
1615 get_default_timeout(struct cyclades_port * info, unsigned long *value)
1616 {
1617    return put_user(info->default_timeout,value);
1618 }
1619
1620 static int
1621 cy_ioctl(struct tty_struct *tty, struct file * file,
1622             unsigned int cmd, unsigned long arg)
1623 {
1624   unsigned long val;
1625   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1626   int ret_val = 0;
1627
1628 #ifdef SERIAL_DEBUG_OTHER
1629     printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
1630 #endif
1631
1632     switch (cmd) {
1633         case CYGETMON:
1634             ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
1635             break;
1636         case CYGETTHRESH:
1637             ret_val = get_threshold(info, (unsigned long *)arg);
1638             break;
1639         case CYSETTHRESH:
1640             ret_val = set_threshold(info, (unsigned long *)arg);
1641             break;
1642         case CYGETDEFTHRESH:
1643             ret_val = get_default_threshold(info, (unsigned long *)arg);
1644             break;
1645         case CYSETDEFTHRESH:
1646             ret_val = set_default_threshold(info, (unsigned long *)arg);
1647             break;
1648         case CYGETTIMEOUT:
1649             ret_val = get_timeout(info, (unsigned long *)arg);
1650             break;
1651         case CYSETTIMEOUT:
1652             ret_val = set_timeout(info, (unsigned long *)arg);
1653             break;
1654         case CYGETDEFTIMEOUT:
1655             ret_val = get_default_timeout(info, (unsigned long *)arg);
1656             break;
1657         case CYSETDEFTIMEOUT:
1658             ret_val = set_default_timeout(info, (unsigned long)arg);
1659             break;
1660         case TCSBRK:    /* SVID version: non-zero arg --> no break */
1661             ret_val = tty_check_change(tty);
1662             if (ret_val)
1663                     break;
1664             tty_wait_until_sent(tty,0);
1665             if (!arg)
1666                 send_break(info, HZ/4); /* 1/4 second */
1667             break;
1668         case TCSBRKP:   /* support for POSIX tcsendbreak() */
1669             ret_val = tty_check_change(tty);
1670             if (ret_val)
1671                 break;
1672             tty_wait_until_sent(tty,0);
1673             send_break(info, arg ? arg*(HZ/10) : HZ/4);
1674             break;
1675
1676 /* The following commands are incompletely implemented!!! */
1677         case TIOCGSOFTCAR:
1678             ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
1679             break;
1680         case TIOCSSOFTCAR:
1681             ret_val = get_user(val, (unsigned long *) arg);
1682             if (ret_val)
1683                     break;
1684             tty->termios->c_cflag =
1685                     ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
1686             break;
1687         case TIOCGSERIAL:
1688             ret_val = get_serial_info(info, (struct serial_struct *) arg);
1689             break;
1690         case TIOCSSERIAL:
1691             ret_val = set_serial_info(info,
1692                                    (struct serial_struct *) arg);
1693             break;
1694         default:
1695             ret_val = -ENOIOCTLCMD;
1696     }
1697
1698 #ifdef SERIAL_DEBUG_OTHER
1699     printk("cy_ioctl done\n");
1700 #endif
1701
1702     return ret_val;
1703 } /* cy_ioctl */
1704
1705
1706
1707
1708 static void
1709 cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
1710 {
1711   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1712
1713 #ifdef SERIAL_DEBUG_OTHER
1714     printk("cy_set_termios %s\n", tty->name);
1715 #endif
1716
1717     if (tty->termios->c_cflag == old_termios->c_cflag)
1718         return;
1719     config_setup(info);
1720
1721     if ((old_termios->c_cflag & CRTSCTS) &&
1722         !(tty->termios->c_cflag & CRTSCTS)) {
1723             tty->stopped = 0;
1724             cy_start(tty);
1725     }
1726 #ifdef tytso_patch_94Nov25_1726
1727     if (!(old_termios->c_cflag & CLOCAL) &&
1728         (tty->termios->c_cflag & CLOCAL))
1729             wake_up_interruptible(&info->open_wait);
1730 #endif
1731
1732     return;
1733 } /* cy_set_termios */
1734
1735
1736 static void
1737 cy_close(struct tty_struct * tty, struct file * filp)
1738 {
1739   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1740
1741 /* CP('C'); */
1742 #ifdef SERIAL_DEBUG_OTHER
1743     printk("cy_close %s\n", tty->name);
1744 #endif
1745
1746     if (!info
1747     || serial_paranoia_check(info, tty->name, "cy_close")){
1748         return;
1749     }
1750 #ifdef SERIAL_DEBUG_OPEN
1751     printk("cy_close %s, count = %d\n", tty->name, info->count);
1752 #endif
1753
1754     if ((tty->count == 1) && (info->count != 1)) {
1755         /*
1756          * Uh, oh.  tty->count is 1, which means that the tty
1757          * structure will be freed.  Info->count should always
1758          * be one in these conditions.  If it's greater than
1759          * one, we've got real problems, since it means the
1760          * serial port won't be shutdown.
1761          */
1762         printk("cy_close: bad serial port count; tty->count is 1, "
1763            "info->count is %d\n", info->count);
1764         info->count = 1;
1765     }
1766 #ifdef SERIAL_DEBUG_COUNT
1767     printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count - 1);
1768 #endif
1769     if (--info->count < 0) {
1770         printk("cy_close: bad serial port count for ttys%d: %d\n",
1771                info->line, info->count);
1772 #ifdef SERIAL_DEBUG_COUNT
1773     printk("cyc: %d: setting count to 0\n", __LINE__);
1774 #endif
1775         info->count = 0;
1776     }
1777     if (info->count)
1778         return;
1779     info->flags |= ASYNC_CLOSING;
1780     if (info->flags & ASYNC_INITIALIZED)
1781         tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
1782     shutdown(info);
1783     if (tty->driver->flush_buffer)
1784         tty->driver->flush_buffer(tty);
1785     tty_ldisc_flush(tty);
1786     info->event = 0;
1787     info->tty = 0;
1788     if (info->blocked_open) {
1789         if (info->close_delay) {
1790             msleep_interruptible(jiffies_to_msecs(info->close_delay));
1791         }
1792         wake_up_interruptible(&info->open_wait);
1793     }
1794     info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1795     wake_up_interruptible(&info->close_wait);
1796
1797 #ifdef SERIAL_DEBUG_OTHER
1798     printk("cy_close done\n");
1799 #endif
1800
1801     return;
1802 } /* cy_close */
1803
1804 /*
1805  * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
1806  */
1807 void
1808 cy_hangup(struct tty_struct *tty)
1809 {
1810   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1811         
1812 #ifdef SERIAL_DEBUG_OTHER
1813     printk("cy_hangup %s\n", tty->name); /* */
1814 #endif
1815
1816     if (serial_paranoia_check(info, tty->name, "cy_hangup"))
1817         return;
1818     
1819     shutdown(info);
1820 #if 0
1821     info->event = 0;
1822     info->count = 0;
1823 #ifdef SERIAL_DEBUG_COUNT
1824     printk("cyc: %d: setting count to 0\n", __LINE__);
1825 #endif
1826     info->tty = 0;
1827 #endif
1828     info->flags &= ~ASYNC_NORMAL_ACTIVE;
1829     wake_up_interruptible(&info->open_wait);
1830 } /* cy_hangup */
1831
1832
1833
1834 /*
1835  * ------------------------------------------------------------
1836  * cy_open() and friends
1837  * ------------------------------------------------------------
1838  */
1839
1840 static int
1841 block_til_ready(struct tty_struct *tty, struct file * filp,
1842                            struct cyclades_port *info)
1843 {
1844   DECLARE_WAITQUEUE(wait, current);
1845   unsigned long flags;
1846   int channel;
1847   int retval;
1848   volatile u_char *base_addr = (u_char *)BASE_ADDR;
1849
1850     /*
1851      * If the device is in the middle of being closed, then block
1852      * until it's done, and then try again.
1853      */
1854     if (info->flags & ASYNC_CLOSING) {
1855         interruptible_sleep_on(&info->close_wait);
1856         if (info->flags & ASYNC_HUP_NOTIFY){
1857             return -EAGAIN;
1858         }else{
1859             return -ERESTARTSYS;
1860         }
1861     }
1862
1863     /*
1864      * If non-blocking mode is set, then make the check up front
1865      * and then exit.
1866      */
1867     if (filp->f_flags & O_NONBLOCK) {
1868         info->flags |= ASYNC_NORMAL_ACTIVE;
1869         return 0;
1870     }
1871
1872     /*
1873      * Block waiting for the carrier detect and the line to become
1874      * free (i.e., not in use by the callout).  While we are in
1875      * this loop, info->count is dropped by one, so that
1876      * cy_close() knows when to free things.  We restore it upon
1877      * exit, either normal or abnormal.
1878      */
1879     retval = 0;
1880     add_wait_queue(&info->open_wait, &wait);
1881 #ifdef SERIAL_DEBUG_OPEN
1882     printk("block_til_ready before block: %s, count = %d\n",
1883            tty->name, info->count);/**/
1884 #endif
1885     info->count--;
1886 #ifdef SERIAL_DEBUG_COUNT
1887     printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
1888 #endif
1889     info->blocked_open++;
1890
1891     channel = info->line;
1892
1893     while (1) {
1894         local_irq_save(flags);
1895         base_addr[CyCAR] = (u_char)channel;
1896         base_addr[CyMSVR1] = CyRTS;
1897 /* CP('S');CP('4'); */
1898         base_addr[CyMSVR2] = CyDTR;
1899 #ifdef SERIAL_DEBUG_DTR
1900         printk("cyc: %d: raising DTR\n", __LINE__);
1901         printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1902 #endif
1903         local_irq_restore(flags);
1904         set_current_state(TASK_INTERRUPTIBLE);
1905         if (tty_hung_up_p(filp)
1906         || !(info->flags & ASYNC_INITIALIZED) ){
1907             if (info->flags & ASYNC_HUP_NOTIFY) {
1908                 retval = -EAGAIN;
1909             }else{
1910                 retval = -ERESTARTSYS;
1911             }
1912             break;
1913         }
1914         local_irq_save(flags);
1915             base_addr[CyCAR] = (u_char)channel;
1916 /* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */
1917             if (!(info->flags & ASYNC_CLOSING)
1918             && (C_CLOCAL(tty)
1919                 || (base_addr[CyMSVR1] & CyDCD))) {
1920                     local_irq_restore(flags);
1921                     break;
1922             }
1923         local_irq_restore(flags);
1924         if (signal_pending(current)) {
1925             retval = -ERESTARTSYS;
1926             break;
1927         }
1928 #ifdef SERIAL_DEBUG_OPEN
1929         printk("block_til_ready blocking: %s, count = %d\n",
1930                tty->name, info->count);/**/
1931 #endif
1932         schedule();
1933     }
1934     current->state = TASK_RUNNING;
1935     remove_wait_queue(&info->open_wait, &wait);
1936     if (!tty_hung_up_p(filp)){
1937         info->count++;
1938 #ifdef SERIAL_DEBUG_COUNT
1939     printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
1940 #endif
1941     }
1942     info->blocked_open--;
1943 #ifdef SERIAL_DEBUG_OPEN
1944     printk("block_til_ready after blocking: %s, count = %d\n",
1945            tty->name, info->count);/**/
1946 #endif
1947     if (retval)
1948             return retval;
1949     info->flags |= ASYNC_NORMAL_ACTIVE;
1950     return 0;
1951 } /* block_til_ready */
1952
1953 /*
1954  * This routine is called whenever a serial port is opened.  It
1955  * performs the serial-specific initialization for the tty structure.
1956  */
1957 int
1958 cy_open(struct tty_struct *tty, struct file * filp)
1959 {
1960   struct cyclades_port  *info;
1961   int retval, line;
1962
1963 /* CP('O'); */
1964     line = tty->index;
1965     if ((line < 0) || (NR_PORTS <= line)){
1966         return -ENODEV;
1967     }
1968     info = &cy_port[line];
1969     if (info->line < 0){
1970         return -ENODEV;
1971     }
1972 #ifdef SERIAL_DEBUG_OTHER
1973     printk("cy_open %s\n", tty->name); /* */
1974 #endif
1975     if (serial_paranoia_check(info, tty->name, "cy_open")){
1976         return -ENODEV;
1977     }
1978 #ifdef SERIAL_DEBUG_OPEN
1979     printk("cy_open %s, count = %d\n", tty->name, info->count);/**/
1980 #endif
1981     info->count++;
1982 #ifdef SERIAL_DEBUG_COUNT
1983     printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
1984 #endif
1985     tty->driver_data = info;
1986     info->tty = tty;
1987
1988     if (!tmp_buf) {
1989         tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
1990         if (!tmp_buf){
1991             return -ENOMEM;
1992         }
1993     }
1994
1995     /*
1996      * Start up serial port
1997      */
1998     retval = startup(info);
1999     if (retval){
2000         return retval;
2001     }
2002
2003     retval = block_til_ready(tty, filp, info);
2004     if (retval) {
2005 #ifdef SERIAL_DEBUG_OPEN
2006         printk("cy_open returning after block_til_ready with %d\n",
2007                retval);
2008 #endif
2009         return retval;
2010     }
2011
2012 #ifdef SERIAL_DEBUG_OPEN
2013     printk("cy_open done\n");/**/
2014 #endif
2015     return 0;
2016 } /* cy_open */
2017
2018
2019
2020 /*
2021  * ---------------------------------------------------------------------
2022  * serial167_init() and friends
2023  *
2024  * serial167_init() is called at boot-time to initialize the serial driver.
2025  * ---------------------------------------------------------------------
2026  */
2027
2028 /*
2029  * This routine prints out the appropriate serial driver version
2030  * number, and identifies which options were configured into this
2031  * driver.
2032  */
2033 static void
2034 show_version(void)
2035 {
2036     printk("MVME166/167 cd2401 driver\n");
2037 } /* show_version */
2038
2039 /* initialize chips on card -- return number of valid
2040    chips (which is number of ports/4) */
2041
2042 /*
2043  * This initialises the hardware to a reasonable state.  It should
2044  * probe the chip first so as to copy 166-Bug setup as a default for
2045  * port 0.  It initialises CMR to CyASYNC; that is never done again, so
2046  * as to limit the number of CyINIT_CHAN commands in normal running.
2047  *
2048  * ... I wonder what I should do if this fails ...
2049  */
2050
2051 void
2052 mvme167_serial_console_setup(int cflag)
2053 {
2054         volatile unsigned char* base_addr = (u_char *)BASE_ADDR;
2055         int ch;
2056         u_char spd;
2057         u_char rcor, rbpr, badspeed = 0;
2058         unsigned long flags;
2059
2060         local_irq_save(flags);
2061
2062         /*
2063          * First probe channel zero of the chip, to see what speed has
2064          * been selected.
2065          */
2066
2067         base_addr[CyCAR] = 0;
2068
2069         rcor = base_addr[CyRCOR] << 5;
2070         rbpr = base_addr[CyRBPR];
2071
2072         for (spd = 0; spd < sizeof(baud_bpr); spd++)
2073                 if (rbpr == baud_bpr[spd] && rcor == baud_co[spd])
2074                         break;
2075         if (spd >= sizeof(baud_bpr)) {
2076                 spd = 14;       /* 19200 */
2077                 badspeed = 1;   /* Failed to identify speed */
2078         }
2079         initial_console_speed = spd;
2080
2081         /* OK, we have chosen a speed, now reset and reinitialise */
2082
2083         my_udelay(20000L);      /* Allow time for any active o/p to complete */
2084         if(base_addr[CyCCR] != 0x00){
2085             local_irq_restore(flags);
2086             /* printk(" chip is never idle (CCR != 0)\n"); */
2087             return;
2088         }
2089
2090         base_addr[CyCCR] = CyCHIP_RESET;        /* Reset the chip */
2091         my_udelay(1000L);
2092
2093         if(base_addr[CyGFRCR] == 0x00){
2094             local_irq_restore(flags);
2095             /* printk(" chip is not responding (GFRCR stayed 0)\n"); */
2096             return;
2097         }
2098
2099         /*
2100          * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms
2101          * tick
2102          */
2103
2104         base_addr[CyTPR] = 10;
2105
2106         base_addr[CyPILR1] = 0x01;    /* Interrupt level for modem change */
2107         base_addr[CyPILR2] = 0x02;    /* Interrupt level for tx ints */
2108         base_addr[CyPILR3] = 0x03;    /* Interrupt level for rx ints */
2109
2110         /*
2111          * Attempt to set up all channels to something reasonable, and
2112          * bang out a INIT_CHAN command.  We should then be able to limit
2113          * the ammount of fiddling we have to do in normal running.
2114          */
2115
2116         for (ch = 3; ch >= 0 ; ch--) {
2117                 base_addr[CyCAR] = (u_char)ch;
2118                 base_addr[CyIER] = 0;
2119                 base_addr[CyCMR] = CyASYNC;
2120                 base_addr[CyLICR] = (u_char)ch << 2;
2121                 base_addr[CyLIVR] = 0x5c;
2122                 base_addr[CyTCOR] = baud_co[spd];
2123                 base_addr[CyTBPR] = baud_bpr[spd];
2124                 base_addr[CyRCOR] = baud_co[spd] >> 5;
2125                 base_addr[CyRBPR] = baud_bpr[spd];
2126                 base_addr[CySCHR1] = 'Q' & 0x1f;
2127                 base_addr[CySCHR2] = 'X' & 0x1f;
2128                 base_addr[CySCRL] = 0;
2129                 base_addr[CySCRH] = 0;
2130                 base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
2131                 base_addr[CyCOR2] = 0;
2132                 base_addr[CyCOR3] = Cy_1_STOP;
2133                 base_addr[CyCOR4] = baud_cor4[spd];
2134                 base_addr[CyCOR5] = 0;
2135                 base_addr[CyCOR6] = 0;
2136                 base_addr[CyCOR7] = 0;
2137                 base_addr[CyRTPRL] = 2;
2138                 base_addr[CyRTPRH] = 0;
2139                 base_addr[CyMSVR1] = 0;
2140                 base_addr[CyMSVR2] = 0;
2141                 write_cy_cmd(base_addr,CyINIT_CHAN|CyDIS_RCVR|CyDIS_XMTR);
2142         }
2143
2144         /*
2145          * Now do specials for channel zero....
2146          */
2147
2148         base_addr[CyMSVR1] = CyRTS;
2149         base_addr[CyMSVR2] = CyDTR;
2150         base_addr[CyIER] = CyRxData;
2151         write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR);
2152
2153         local_irq_restore(flags);
2154
2155         my_udelay(20000L);      /* Let it all settle down */
2156
2157         printk("CD2401 initialised,  chip is rev 0x%02x\n", base_addr[CyGFRCR]);
2158         if (badspeed)
2159                 printk("  WARNING:  Failed to identify line speed, rcor=%02x,rbpr=%02x\n",
2160                                         rcor >> 5, rbpr);
2161 } /* serial_console_init */
2162
2163 static struct tty_operations cy_ops = {
2164         .open = cy_open,
2165         .close = cy_close,
2166         .write = cy_write,
2167         .put_char = cy_put_char,
2168         .flush_chars = cy_flush_chars,
2169         .write_room = cy_write_room,
2170         .chars_in_buffer = cy_chars_in_buffer,
2171         .flush_buffer = cy_flush_buffer,
2172         .ioctl = cy_ioctl,
2173         .throttle = cy_throttle,
2174         .unthrottle = cy_unthrottle,
2175         .set_termios = cy_set_termios,
2176         .stop = cy_stop,
2177         .start = cy_start,
2178         .hangup = cy_hangup,
2179         .tiocmget = cy_tiocmget,
2180         .tiocmset = cy_tiocmset,
2181 };
2182 /* The serial driver boot-time initialization code!
2183     Hardware I/O ports are mapped to character special devices on a
2184     first found, first allocated manner.  That is, this code searches
2185     for Cyclom cards in the system.  As each is found, it is probed
2186     to discover how many chips (and thus how many ports) are present.
2187     These ports are mapped to the tty ports 64 and upward in monotonic
2188     fashion.  If an 8-port card is replaced with a 16-port card, the
2189     port mapping on a following card will shift.
2190
2191     This approach is different from what is used in the other serial
2192     device driver because the Cyclom is more properly a multiplexer,
2193     not just an aggregation of serial ports on one card.
2194
2195     If there are more cards with more ports than have been statically
2196     allocated above, a warning is printed and the extra ports are ignored.
2197  */
2198 static int __init
2199 serial167_init(void)
2200 {
2201   struct cyclades_port *info;
2202   int ret = 0;
2203   int good_ports = 0;
2204   int port_num = 0;
2205   int index;
2206   int DefSpeed;
2207 #ifdef notyet
2208   struct sigaction sa;
2209 #endif
2210
2211     if (!(mvme16x_config &MVME16x_CONFIG_GOT_CD2401))
2212         return 0;
2213
2214     cy_serial_driver = alloc_tty_driver(NR_PORTS);
2215     if (!cy_serial_driver)
2216         return -ENOMEM;
2217
2218 #if 0
2219 scrn[1] = '\0';
2220 #endif
2221
2222     show_version();
2223
2224     /* Has "console=0,9600n8" been used in bootinfo to change speed? */
2225     if (serial_console_cflag)
2226         DefSpeed = serial_console_cflag & 0017;
2227     else {
2228         DefSpeed = initial_console_speed;
2229         serial_console_info = &cy_port[0];
2230         serial_console_cflag = DefSpeed | CS8;
2231 #if 0
2232         serial_console = 64; /*callout_driver.minor_start*/
2233 #endif
2234     }
2235
2236     /* Initialize the tty_driver structure */
2237     
2238     cy_serial_driver->owner = THIS_MODULE;
2239     cy_serial_driver->devfs_name = "tts/";
2240     cy_serial_driver->name = "ttyS";
2241     cy_serial_driver->major = TTY_MAJOR;
2242     cy_serial_driver->minor_start = 64;
2243     cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
2244     cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
2245     cy_serial_driver->init_termios = tty_std_termios;
2246     cy_serial_driver->init_termios.c_cflag =
2247             B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2248     cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
2249     tty_set_operations(cy_serial_driver, &cy_ops);
2250
2251     ret = tty_register_driver(cy_serial_driver);
2252     if (ret) {
2253             printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
2254             put_tty_driver(cy_serial_driver);
2255             return ret;
2256     }
2257
2258     port_num = 0;
2259     info = cy_port;
2260     for (index = 0; index < 1; index++) {
2261
2262         good_ports = 4;
2263
2264         if(port_num < NR_PORTS){
2265             while( good_ports-- && port_num < NR_PORTS){
2266                 /*** initialize port ***/
2267                 info->magic = CYCLADES_MAGIC;
2268                 info->type = PORT_CIRRUS;
2269                 info->card = index;
2270                 info->line = port_num;
2271                 info->flags = STD_COM_FLAGS;
2272                 info->tty = 0;
2273                 info->xmit_fifo_size = 12;
2274                 info->cor1 = CyPARITY_NONE|Cy_8_BITS;
2275                 info->cor2 = CyETC;
2276                 info->cor3 = Cy_1_STOP;
2277                 info->cor4 = 0x08; /* _very_ small receive threshold */
2278                 info->cor5 = 0;
2279                 info->cor6 = 0;
2280                 info->cor7 = 0;
2281                 info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */
2282                 info->tco = baud_co[DefSpeed]; /* Tx CO */
2283                 info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */
2284                 info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */
2285                 info->close_delay = 0;
2286                 info->x_char = 0;
2287                 info->event = 0;
2288                 info->count = 0;
2289 #ifdef SERIAL_DEBUG_COUNT
2290     printk("cyc: %d: setting count to 0\n", __LINE__);
2291 #endif
2292                 info->blocked_open = 0;
2293                 info->default_threshold = 0;
2294                 info->default_timeout = 0;
2295                 INIT_WORK(&info->tqueue, do_softint, info);
2296                 init_waitqueue_head(&info->open_wait);
2297                 init_waitqueue_head(&info->close_wait);
2298                 /* info->session */
2299                 /* info->pgrp */
2300 /*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/
2301                 info->read_status_mask = CyTIMEOUT| CySPECHAR| CyBREAK
2302                                        | CyPARITY| CyFRAME| CyOVERRUN;
2303                 /* info->timeout */
2304
2305                 printk("ttyS%d ", info->line);
2306                 port_num++;info++;
2307                 if(!(port_num & 7)){
2308                     printk("\n               ");
2309                 }
2310             }
2311         }
2312         printk("\n");
2313     }
2314     while( port_num < NR_PORTS){
2315         info->line = -1;
2316         port_num++;info++;
2317     }
2318 #ifdef CONFIG_REMOTE_DEBUG
2319     debug_setup();
2320 #endif
2321     ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
2322                                 "cd2401_errors", cd2401_rxerr_interrupt);
2323     if (ret) {
2324             printk(KERN_ERR "Could't get cd2401_errors IRQ");
2325             goto cleanup_serial_driver;
2326     }
2327
2328     ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
2329                                 "cd2401_modem", cd2401_modem_interrupt);
2330     if (ret) {
2331             printk(KERN_ERR "Could't get cd2401_modem IRQ");
2332             goto cleanup_irq_cd2401_errors;
2333     }
2334
2335     ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
2336                                 "cd2401_txints", cd2401_tx_interrupt);
2337     if (ret) {
2338             printk(KERN_ERR "Could't get cd2401_txints IRQ");
2339             goto cleanup_irq_cd2401_modem;
2340     }
2341
2342     ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
2343                                 "cd2401_rxints", cd2401_rx_interrupt);
2344     if (ret) {
2345             printk(KERN_ERR "Could't get cd2401_rxints IRQ");
2346             goto cleanup_irq_cd2401_txints;
2347     }
2348
2349     /* Now we have registered the interrupt handlers, allow the interrupts */
2350
2351     pcc2chip[PccSCCMICR] = 0x15;                /* Serial ints are level 5 */
2352     pcc2chip[PccSCCTICR] = 0x15;
2353     pcc2chip[PccSCCRICR] = 0x15;
2354
2355     pcc2chip[PccIMLR] = 3;                      /* Allow PCC2 ints above 3!? */
2356
2357     return 0;
2358 cleanup_irq_cd2401_txints:
2359     free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt);
2360 cleanup_irq_cd2401_modem:
2361     free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
2362 cleanup_irq_cd2401_errors:
2363     free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
2364 cleanup_serial_driver:
2365     if (tty_unregister_driver(cy_serial_driver))
2366             printk(KERN_ERR "Couldn't unregister MVME166/7 serial driver\n");
2367     put_tty_driver(cy_serial_driver);
2368     return ret;
2369 } /* serial167_init */
2370
2371 module_init(serial167_init);
2372
2373
2374 #ifdef CYCLOM_SHOW_STATUS
2375 static void
2376 show_status(int line_num)
2377 {
2378   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2379   int channel;
2380   struct cyclades_port * info;
2381   unsigned long flags;
2382
2383     info = &cy_port[line_num];
2384     channel = info->line;
2385     printk("  channel %d\n", channel);/**/
2386
2387     printk(" cy_port\n");
2388     printk("  card line flags = %d %d %x\n",
2389                  info->card, info->line, info->flags);
2390     printk("  *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
2391                  (long)info->tty, info->read_status_mask,
2392                  info->timeout, info->xmit_fifo_size);
2393     printk("  cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n",
2394              info->cor1, info->cor2, info->cor3, info->cor4, info->cor5,
2395                         info->cor6, info->cor7);
2396     printk("  tbpr,tco,rbpr,rco = %d %d %d %d\n",
2397              info->tbpr, info->tco, info->rbpr, info->rco);
2398     printk("  close_delay event count = %d %d %d\n",
2399              info->close_delay, info->event, info->count);
2400     printk("  x_char blocked_open = %x %x\n",
2401              info->x_char, info->blocked_open);
2402     printk("  open_wait = %lx %lx %lx\n",
2403              (long)info->open_wait);
2404
2405
2406     local_irq_save(flags);
2407
2408 /* Global Registers */
2409
2410         printk(" CyGFRCR %x\n", base_addr[CyGFRCR]);
2411         printk(" CyCAR %x\n", base_addr[CyCAR]);
2412         printk(" CyRISR %x\n", base_addr[CyRISR]);
2413         printk(" CyTISR %x\n", base_addr[CyTISR]);
2414         printk(" CyMISR %x\n", base_addr[CyMISR]);
2415         printk(" CyRIR %x\n", base_addr[CyRIR]);
2416         printk(" CyTIR %x\n", base_addr[CyTIR]);
2417         printk(" CyMIR %x\n", base_addr[CyMIR]);
2418         printk(" CyTPR %x\n", base_addr[CyTPR]);
2419
2420         base_addr[CyCAR] = (u_char)channel;
2421
2422 /* Virtual Registers */
2423
2424 #if 0
2425         printk(" CyRIVR %x\n", base_addr[CyRIVR]);
2426         printk(" CyTIVR %x\n", base_addr[CyTIVR]);
2427         printk(" CyMIVR %x\n", base_addr[CyMIVR]);
2428         printk(" CyMISR %x\n", base_addr[CyMISR]);
2429 #endif
2430
2431 /* Channel Registers */
2432
2433         printk(" CyCCR %x\n", base_addr[CyCCR]);
2434         printk(" CyIER %x\n", base_addr[CyIER]);
2435         printk(" CyCOR1 %x\n", base_addr[CyCOR1]);
2436         printk(" CyCOR2 %x\n", base_addr[CyCOR2]);
2437         printk(" CyCOR3 %x\n", base_addr[CyCOR3]);
2438         printk(" CyCOR4 %x\n", base_addr[CyCOR4]);
2439         printk(" CyCOR5 %x\n", base_addr[CyCOR5]);
2440 #if 0
2441         printk(" CyCCSR %x\n", base_addr[CyCCSR]);
2442         printk(" CyRDCR %x\n", base_addr[CyRDCR]);
2443 #endif
2444         printk(" CySCHR1 %x\n", base_addr[CySCHR1]);
2445         printk(" CySCHR2 %x\n", base_addr[CySCHR2]);
2446 #if 0
2447         printk(" CySCHR3 %x\n", base_addr[CySCHR3]);
2448         printk(" CySCHR4 %x\n", base_addr[CySCHR4]);
2449         printk(" CySCRL %x\n", base_addr[CySCRL]);
2450         printk(" CySCRH %x\n", base_addr[CySCRH]);
2451         printk(" CyLNC %x\n", base_addr[CyLNC]);
2452         printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]);
2453         printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]);
2454 #endif
2455         printk(" CyRTPRL %x\n", base_addr[CyRTPRL]);
2456         printk(" CyRTPRH %x\n", base_addr[CyRTPRH]);
2457         printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]);
2458         printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]);
2459         printk(" CyRBPR %x\n", base_addr[CyRBPR]);
2460         printk(" CyRCOR %x\n", base_addr[CyRCOR]);
2461         printk(" CyTBPR %x\n", base_addr[CyTBPR]);
2462         printk(" CyTCOR %x\n", base_addr[CyTCOR]);
2463
2464     local_irq_restore(flags);
2465 } /* show_status */
2466 #endif
2467
2468
2469 #if 0
2470 /* Dummy routine in mvme16x/config.c for now */
2471
2472 /* Serial console setup. Called from linux/init/main.c */
2473
2474 void console_setup(char *str, int *ints)
2475 {
2476         char *s;
2477         int baud, bits, parity;
2478         int cflag = 0;
2479
2480         /* Sanity check. */
2481         if (ints[0] > 3 || ints[1] > 3) return;
2482
2483         /* Get baud, bits and parity */
2484         baud = 2400;
2485         bits = 8;
2486         parity = 'n';
2487         if (ints[2]) baud = ints[2];
2488         if ((s = strchr(str, ','))) {
2489                 do {
2490                         s++;
2491                 } while(*s >= '0' && *s <= '9');
2492                 if (*s) parity = *s++;
2493                 if (*s) bits   = *s - '0';
2494         }
2495
2496         /* Now construct a cflag setting. */
2497         switch(baud) {
2498                 case 1200:
2499                         cflag |= B1200;
2500                         break;
2501                 case 9600:
2502                         cflag |= B9600;
2503                         break;
2504                 case 19200:
2505                         cflag |= B19200;
2506                         break;
2507                 case 38400:
2508                         cflag |= B38400;
2509                         break;
2510                 case 2400:
2511                 default:
2512                         cflag |= B2400;
2513                         break;
2514         }
2515         switch(bits) {
2516                 case 7:
2517                         cflag |= CS7;
2518                         break;
2519                 default:
2520                 case 8:
2521                         cflag |= CS8;
2522                         break;
2523         }
2524         switch(parity) {
2525                 case 'o': case 'O':
2526                         cflag |= PARODD;
2527                         break;
2528                 case 'e': case 'E':
2529                         cflag |= PARENB;
2530                         break;
2531         }
2532
2533         serial_console_info = &cy_port[ints[1]];
2534         serial_console_cflag = cflag;
2535         serial_console = ints[1] + 64; /*callout_driver.minor_start*/
2536 }
2537 #endif
2538
2539 /*
2540  * The following is probably out of date for 2.1.x serial console stuff.
2541  *
2542  * The console is registered early on from arch/m68k/kernel/setup.c, and
2543  * it therefore relies on the chip being setup correctly by 166-Bug.  This
2544  * seems reasonable, as the serial port has been used to invoke the system
2545  * boot.  It also means that this function must not rely on any data
2546  * initialisation performed by serial167_init() etc.
2547  *
2548  * Of course, once the console has been registered, we had better ensure
2549  * that serial167_init() doesn't leave the chip non-functional.
2550  *
2551  * The console must be locked when we get here.
2552  */
2553
2554 void serial167_console_write(struct console *co, const char *str, unsigned count)
2555 {
2556         volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2557         unsigned long flags;
2558         volatile u_char sink;
2559         u_char ier;
2560         int port;
2561         u_char do_lf = 0;
2562         int i = 0;
2563
2564         local_irq_save(flags);
2565
2566         /* Ensure transmitter is enabled! */
2567
2568         port = 0;
2569         base_addr[CyCAR] = (u_char)port;
2570         while (base_addr[CyCCR])
2571                 ;
2572         base_addr[CyCCR] = CyENB_XMTR;
2573
2574         ier = base_addr[CyIER];
2575         base_addr[CyIER] = CyTxMpty;
2576
2577         while (1) {
2578                 if (pcc2chip[PccSCCTICR] & 0x20)
2579                 {
2580                         /* We have a Tx int. Acknowledge it */
2581                         sink = pcc2chip[PccTPIACKR];
2582                         if ((base_addr[CyLICR] >> 2) == port) {
2583                                 if (i == count) {
2584                                         /* Last char of string is now output */
2585                                         base_addr[CyTEOIR] = CyNOTRANS;
2586                                         break;
2587                                 }
2588                                 if (do_lf) {
2589                                         base_addr[CyTDR] = '\n';
2590                                         str++;
2591                                         i++;
2592                                         do_lf = 0;
2593                                 }
2594                                 else if (*str == '\n') {
2595                                         base_addr[CyTDR] = '\r';
2596                                         do_lf = 1;
2597                                 }
2598                                 else {
2599                                         base_addr[CyTDR] = *str++;
2600                                         i++;
2601                                 }
2602                                 base_addr[CyTEOIR] = 0;
2603                         }
2604                         else
2605                                 base_addr[CyTEOIR] = CyNOTRANS;
2606                 }
2607         }
2608
2609         base_addr[CyIER] = ier;
2610
2611         local_irq_restore(flags);
2612 }
2613
2614 static struct tty_driver *serial167_console_device(struct console *c, int *index)
2615 {
2616         *index = c->index;
2617         return cy_serial_driver;
2618 }
2619
2620
2621 static int __init serial167_console_setup(struct console *co, char *options)
2622 {
2623         return 0;
2624 }
2625
2626
2627 static struct console sercons = {
2628         .name           = "ttyS",
2629         .write          = serial167_console_write,
2630         .device         = serial167_console_device,
2631         .setup          = serial167_console_setup,
2632         .flags          = CON_PRINTBUFFER,
2633         .index          = -1,
2634 };
2635
2636
2637 static int __init serial167_console_init(void)
2638 {
2639         if (vme_brdtype == VME_TYPE_MVME166 ||
2640                         vme_brdtype == VME_TYPE_MVME167 ||
2641                         vme_brdtype == VME_TYPE_MVME177) {
2642                 mvme167_serial_console_setup(0);
2643                 register_console(&sercons);
2644         }
2645         return 0;
2646 }
2647 console_initcall(serial167_console_init);
2648
2649 #ifdef CONFIG_REMOTE_DEBUG
2650 void putDebugChar (int c)
2651 {
2652         volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2653         unsigned long flags;
2654         volatile u_char sink;
2655         u_char ier;
2656         int port;
2657
2658         local_irq_save(flags);
2659
2660         /* Ensure transmitter is enabled! */
2661
2662         port = DEBUG_PORT;
2663         base_addr[CyCAR] = (u_char)port;
2664         while (base_addr[CyCCR])
2665                 ;
2666         base_addr[CyCCR] = CyENB_XMTR;
2667
2668         ier = base_addr[CyIER];
2669         base_addr[CyIER] = CyTxMpty;
2670
2671         while (1) {
2672                 if (pcc2chip[PccSCCTICR] & 0x20)
2673                 {
2674                         /* We have a Tx int. Acknowledge it */
2675                         sink = pcc2chip[PccTPIACKR];
2676                         if ((base_addr[CyLICR] >> 2) == port) {
2677                                 base_addr[CyTDR] = c;
2678                                 base_addr[CyTEOIR] = 0;
2679                                 break;
2680                         }
2681                         else
2682                                 base_addr[CyTEOIR] = CyNOTRANS;
2683                 }
2684         }
2685
2686         base_addr[CyIER] = ier;
2687
2688         local_irq_restore(flags);
2689 }
2690
2691 int getDebugChar()
2692 {
2693         volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2694         unsigned long flags;
2695         volatile u_char sink;
2696         u_char ier;
2697         int port;
2698         int i, c;
2699
2700         i = debugiq.out;
2701         if (i != debugiq.in) {
2702                 c = debugiq.buf[i];
2703                 if (++i == DEBUG_LEN)
2704                         i = 0;
2705                 debugiq.out = i;
2706                 return c;
2707         }
2708         /* OK, nothing in queue, wait in poll loop */
2709
2710         local_irq_save(flags);
2711
2712         /* Ensure receiver is enabled! */
2713
2714         port = DEBUG_PORT;
2715         base_addr[CyCAR] = (u_char)port;
2716 #if 0
2717         while (base_addr[CyCCR])
2718                 ;
2719         base_addr[CyCCR] = CyENB_RCVR;
2720 #endif
2721         ier = base_addr[CyIER];
2722         base_addr[CyIER] = CyRxData;
2723
2724         while (1) {
2725                 if (pcc2chip[PccSCCRICR] & 0x20)
2726                 {
2727                         /* We have a Rx int. Acknowledge it */
2728                         sink = pcc2chip[PccRPIACKR];
2729                         if ((base_addr[CyLICR] >> 2) == port) {
2730                                 int cnt = base_addr[CyRFOC];
2731                                 while (cnt-- > 0)
2732                                 {
2733                                         c = base_addr[CyRDR];
2734                                         if (c == 0)
2735                                                 printk ("!! debug char is null (cnt=%d) !!", cnt);
2736                                         else
2737                                                 queueDebugChar (c);
2738                                 }
2739                                 base_addr[CyREOIR] = 0;
2740                                 i = debugiq.out;
2741                                 if (i == debugiq.in)
2742                                         panic ("Debug input queue empty!");
2743                                 c = debugiq.buf[i];
2744                                 if (++i == DEBUG_LEN)
2745                                         i = 0;
2746                                 debugiq.out = i;
2747                                 break;
2748                         }
2749                         else
2750                                 base_addr[CyREOIR] = CyNOTRANS;
2751                 }
2752         }
2753
2754         base_addr[CyIER] = ier;
2755
2756         local_irq_restore(flags);
2757
2758         return (c);
2759 }
2760
2761 void queueDebugChar (int c)
2762 {
2763         int i;
2764
2765         i = debugiq.in;
2766         debugiq.buf[i] = c;
2767         if (++i == DEBUG_LEN)
2768                 i = 0;
2769         if (i != debugiq.out)
2770                 debugiq.in = i;
2771 }
2772
2773 static void
2774 debug_setup()
2775 {
2776   unsigned long flags;
2777   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2778   int   i, cflag;
2779
2780     cflag = B19200;
2781
2782     local_irq_save(flags);
2783
2784     for (i = 0; i < 4; i++)
2785     {
2786         base_addr[CyCAR] = i;
2787         base_addr[CyLICR] = i << 2;
2788     }
2789
2790     debugiq.in = debugiq.out = 0;
2791
2792     base_addr[CyCAR] = DEBUG_PORT;
2793
2794     /* baud rate */
2795     i = cflag & CBAUD;
2796
2797     base_addr[CyIER] = 0;
2798
2799     base_addr[CyCMR] = CyASYNC;
2800     base_addr[CyLICR] = DEBUG_PORT << 2;
2801     base_addr[CyLIVR] = 0x5c;
2802
2803     /* tx and rx baud rate */
2804
2805     base_addr[CyTCOR] = baud_co[i];
2806     base_addr[CyTBPR] = baud_bpr[i];
2807     base_addr[CyRCOR] = baud_co[i] >> 5;
2808     base_addr[CyRBPR] = baud_bpr[i];
2809
2810     /* set line characteristics  according configuration */
2811
2812     base_addr[CySCHR1] = 0;
2813     base_addr[CySCHR2] = 0;
2814     base_addr[CySCRL] = 0;
2815     base_addr[CySCRH] = 0;
2816     base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
2817     base_addr[CyCOR2] = 0;
2818     base_addr[CyCOR3] = Cy_1_STOP;
2819     base_addr[CyCOR4] = baud_cor4[i];
2820     base_addr[CyCOR5] = 0;
2821     base_addr[CyCOR6] = 0;
2822     base_addr[CyCOR7] = 0;
2823
2824     write_cy_cmd(base_addr,CyINIT_CHAN);
2825     write_cy_cmd(base_addr,CyENB_RCVR);
2826
2827     base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */
2828
2829     base_addr[CyRTPRL] = 2;
2830     base_addr[CyRTPRH] = 0;
2831
2832     base_addr[CyMSVR1] = CyRTS;
2833     base_addr[CyMSVR2] = CyDTR;
2834
2835     base_addr[CyIER] = CyRxData;
2836
2837     local_irq_restore(flags);
2838
2839 } /* debug_setup */
2840
2841 #endif
2842
2843 MODULE_LICENSE("GPL");