~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/char/serial167.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.