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