Coarsly sort out 32-bit-only, 64-bit-only and ``portable'' MIPS lib/
[linux-2.6/linux-mips.git] / drivers / char / serial167.c
blob82b815099f1baaeebdd5de60ab60c8b52c9cd1fe
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 * Changes:
36 * 200 lines of changes record removed - RGH 11-10-95, starting work on
37 * converting this to drive serial ports on mvme166 (cd2401).
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
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 #include <linux/module.h>
67 #include <asm/system.h>
68 #include <asm/io.h>
69 #include <asm/bitops.h>
70 #include <asm/mvme16xhw.h>
71 #include <asm/bootinfo.h>
72 #include <asm/setup.h>
74 #include <linux/types.h>
75 #include <linux/kernel.h>
77 #include <linux/version.h>
78 #include <asm/uaccess.h>
79 #include <linux/init.h>
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
91 #ifndef MIN
92 #define MIN(a,b) ((a) < (b) ? (a) : (b))
93 #endif
95 #define WAKEUP_CHARS 256
97 #define STD_COM_FLAGS (0)
99 #define SERIAL_TYPE_NORMAL 1
101 DECLARE_TASK_QUEUE(tq_cyclades);
103 static struct tty_driver *cy_serial_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))
131 * tmp_buf is used as a temporary buffer by serial_write. We need to
132 * lock it in case the copy_from_user blocks while swapping in a page,
133 * and some other program tries to do a serial write at the same time.
134 * Since the lock will only come under contention when the system is
135 * swapping and available memory is low, it makes sense to share one
136 * buffer across all the serial ports, since it significantly saves
137 * memory if large numbers of serial ports are open.
139 static unsigned char *tmp_buf = 0;
140 DECLARE_MUTEX(tmp_buf_sem);
143 * This is used to look up the divisor speeds and the timeouts
144 * We're normally limited to 15 distinct baud rates. The extra
145 * are accessed via settings in info->flags.
146 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
147 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
148 * HI VHI
150 static int baud_table[] = {
151 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
152 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,115200,150000,
155 #if 0
156 static char baud_co[] = { /* 25 MHz clock option table */
157 /* value => 00 01 02 03 04 */
158 /* divide by 8 32 128 512 2048 */
159 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
160 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
162 static char baud_bpr[] = { /* 25 MHz baud rate period table */
163 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
164 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15};
165 #endif
167 /* I think 166 brd clocks 2401 at 20MHz.... */
169 /* These values are written directly to tcor, and >> 5 for writing to rcor */
170 static u_char baud_co[] = { /* 20 MHz clock option table */
171 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40,
172 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
174 /* These values written directly to tbpr/rbpr */
175 static u_char baud_bpr[] = { /* 20 MHz baud rate period table */
176 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81,
177 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10};
179 static u_char baud_cor4[] = { /* receive threshold */
180 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
181 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07};
185 static void shutdown(struct cyclades_port *);
186 static int startup (struct cyclades_port *);
187 static void cy_throttle(struct tty_struct *);
188 static void cy_unthrottle(struct tty_struct *);
189 static void config_setup(struct cyclades_port *);
190 extern void console_print(const char *);
191 #ifdef CYCLOM_SHOW_STATUS
192 static void show_status(int);
193 #endif
195 #ifdef CONFIG_REMOTE_DEBUG
196 static void debug_setup(void);
197 void queueDebugChar (int c);
198 int getDebugChar(void);
200 #define DEBUG_PORT 1
201 #define DEBUG_LEN 256
203 typedef struct {
204 int in;
205 int out;
206 unsigned char buf[DEBUG_LEN];
207 } debugq;
209 debugq debugiq;
210 #endif
213 * I have my own version of udelay(), as it is needed when initialising
214 * the chip, before the delay loop has been calibrated. Should probably
215 * reference one of the vmechip2 or pccchip2 counter for an accurate
216 * delay, but this wild guess will do for now.
219 void my_udelay (long us)
221 u_char x;
222 volatile u_char *p = &x;
223 int i;
225 while (us--)
226 for (i = 100; i; i--)
227 x |= *p;
230 static inline int
231 serial_paranoia_check(struct cyclades_port *info, char *name,
232 const char *routine)
234 #ifdef SERIAL_PARANOIA_CHECK
235 static const char *badmagic =
236 "Warning: bad magic number for serial struct (%s) in %s\n";
237 static const char *badinfo =
238 "Warning: null cyclades_port for (%s) in %s\n";
239 static const char *badrange =
240 "Warning: cyclades_port out of range for (%s) in %s\n";
242 if (!info) {
243 printk(badinfo, name, routine);
244 return 1;
247 if( (long)info < (long)(&cy_port[0])
248 || (long)(&cy_port[NR_PORTS]) < (long)info ){
249 printk(badrange, name, routine);
250 return 1;
253 if (info->magic != CYCLADES_MAGIC) {
254 printk(badmagic, name, routine);
255 return 1;
257 #endif
258 return 0;
259 } /* serial_paranoia_check */
261 #if 0
262 /* The following diagnostic routines allow the driver to spew
263 information on the screen, even (especially!) during interrupts.
265 void
266 SP(char *data){
267 unsigned long flags;
268 local_irq_save(flags);
269 console_print(data);
270 local_irq_restore(flags);
272 char scrn[2];
273 void
274 CP(char data){
275 unsigned long flags;
276 local_irq_save(flags);
277 scrn[0] = data;
278 console_print(scrn);
279 local_irq_restore(flags);
280 }/* CP */
282 void CP1(int data) { (data<10)? CP(data+'0'): CP(data+'A'-10); }/* CP1 */
283 void CP2(int data) { CP1((data>>4) & 0x0f); CP1( data & 0x0f); }/* CP2 */
284 void CP4(int data) { CP2((data>>8) & 0xff); CP2(data & 0xff); }/* CP4 */
285 void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }/* CP8 */
286 #endif
288 /* This routine waits up to 1000 micro-seconds for the previous
289 command to the Cirrus chip to complete and then issues the
290 new command. An error is returned if the previous command
291 didn't finish within the time limit.
293 u_short
294 write_cy_cmd(volatile u_char *base_addr, u_char cmd)
296 unsigned long flags;
297 volatile int i;
299 local_irq_save(flags);
300 /* Check to see that the previous command has completed */
301 for(i = 0 ; i < 100 ; i++){
302 if (base_addr[CyCCR] == 0){
303 break;
305 my_udelay(10L);
307 /* if the CCR never cleared, the previous command
308 didn't finish within the "reasonable time" */
309 if ( i == 10 ) {
310 local_irq_restore(flags);
311 return (-1);
314 /* Issue the new command */
315 base_addr[CyCCR] = cmd;
316 local_irq_restore(flags);
317 return(0);
318 } /* write_cy_cmd */
321 /* cy_start and cy_stop provide software output flow control as a
322 function of XON/XOFF, software CTS, and other such stuff. */
324 static void
325 cy_stop(struct tty_struct *tty)
327 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
328 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
329 int channel;
330 unsigned long flags;
332 #ifdef SERIAL_DEBUG_OTHER
333 printk("cy_stop %s\n", tty->name); /* */
334 #endif
336 if (serial_paranoia_check(info, tty->name, "cy_stop"))
337 return;
339 channel = info->line;
341 local_irq_save(flags);
342 base_addr[CyCAR] = (u_char)(channel); /* index channel */
343 base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
344 local_irq_restore(flags);
346 return;
347 } /* cy_stop */
349 static void
350 cy_start(struct tty_struct *tty)
352 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
353 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
354 int channel;
355 unsigned long flags;
357 #ifdef SERIAL_DEBUG_OTHER
358 printk("cy_start %s\n", tty->name); /* */
359 #endif
361 if (serial_paranoia_check(info, tty->name, "cy_start"))
362 return;
364 channel = info->line;
366 local_irq_save(flags);
367 base_addr[CyCAR] = (u_char)(channel);
368 base_addr[CyIER] |= CyTxMpty;
369 local_irq_restore(flags);
371 return;
372 } /* cy_start */
376 * This routine is used by the interrupt handler to schedule
377 * processing in the software interrupt portion of the driver
378 * (also known as the "bottom half"). This can be called any
379 * number of times for any channel without harm.
381 static inline void
382 cy_sched_event(struct cyclades_port *info, int event)
384 info->event |= 1 << event; /* remember what kind of event and who */
385 queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */
386 mark_bh(CYCLADES_BH); /* then trigger event */
387 } /* cy_sched_event */
390 /* The real interrupt service routines are called
391 whenever the card wants its hand held--chars
392 received, out buffer empty, modem change, etc.
394 static irqreturn_t
395 cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
397 struct tty_struct *tty;
398 struct cyclades_port *info;
399 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
400 unsigned char err, rfoc;
401 int channel;
402 char data;
404 /* determine the channel and change to that context */
405 channel = (u_short ) (base_addr[CyLICR] >> 2);
406 info = &cy_port[channel];
407 info->last_active = jiffies;
409 if ((err = base_addr[CyRISR]) & CyTIMEOUT) {
410 /* This is a receive timeout interrupt, ignore it */
411 base_addr[CyREOIR] = CyNOTRANS;
412 return IRQ_HANDLED;
415 /* Read a byte of data if there is any - assume the error
416 * is associated with this character */
418 if ((rfoc = base_addr[CyRFOC]) != 0)
419 data = base_addr[CyRDR];
420 else
421 data = 0;
423 /* if there is nowhere to put the data, discard it */
424 if(info->tty == 0) {
425 base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
426 return IRQ_HANDLED;
428 else { /* there is an open port for this data */
429 tty = info->tty;
430 if(err & info->ignore_status_mask){
431 base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
432 return IRQ_HANDLED;
434 if (tty->flip.count < TTY_FLIPBUF_SIZE){
435 tty->flip.count++;
436 if (err & info->read_status_mask){
437 if(err & CyBREAK){
438 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
439 *tty->flip.char_buf_ptr++ = data;
440 if (info->flags & ASYNC_SAK){
441 do_SAK(tty);
443 }else if(err & CyFRAME){
444 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
445 *tty->flip.char_buf_ptr++ = data;
446 }else if(err & CyPARITY){
447 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
448 *tty->flip.char_buf_ptr++ = data;
449 }else if(err & CyOVERRUN){
450 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
451 *tty->flip.char_buf_ptr++ = 0;
453 If the flip buffer itself is
454 overflowing, we still loose
455 the next incoming character.
457 if(tty->flip.count < TTY_FLIPBUF_SIZE){
458 tty->flip.count++;
459 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
460 *tty->flip.char_buf_ptr++ = data;
462 /* These two conditions may imply */
463 /* a normal read should be done. */
464 /* else if(data & CyTIMEOUT) */
465 /* else if(data & CySPECHAR) */
466 }else{
467 *tty->flip.flag_buf_ptr++ = 0;
468 *tty->flip.char_buf_ptr++ = 0;
470 }else{
471 *tty->flip.flag_buf_ptr++ = 0;
472 *tty->flip.char_buf_ptr++ = 0;
474 }else{
475 /* there was a software buffer overrun
476 and nothing could be done about it!!! */
479 queue_task(&tty->flip.tqueue, &tq_timer);
480 /* end of service */
481 base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
482 return IRQ_HANDLED;
483 } /* cy_rxerr_interrupt */
485 static irqreturn_t
486 cd2401_modem_interrupt(int irq, void *dev_id, struct pt_regs *fp)
488 struct cyclades_port *info;
489 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
490 int channel;
491 int mdm_change;
492 int mdm_status;
495 /* determine the channel and change to that context */
496 channel = (u_short ) (base_addr[CyLICR] >> 2);
497 info = &cy_port[channel];
498 info->last_active = jiffies;
500 mdm_change = base_addr[CyMISR];
501 mdm_status = base_addr[CyMSVR1];
503 if(info->tty == 0){ /* nowhere to put the data, ignore it */
505 }else{
506 if((mdm_change & CyDCD)
507 && (info->flags & ASYNC_CHECK_CD)){
508 if(mdm_status & CyDCD){
509 /* CP('!'); */
510 cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
511 } else {
512 /* CP('@'); */
513 cy_sched_event(info, Cy_EVENT_HANGUP);
516 if((mdm_change & CyCTS)
517 && (info->flags & ASYNC_CTS_FLOW)){
518 if(info->tty->stopped){
519 if(mdm_status & CyCTS){
520 /* !!! cy_start isn't used because... */
521 info->tty->stopped = 0;
522 base_addr[CyIER] |= CyTxMpty;
523 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
525 }else{
526 if(!(mdm_status & CyCTS)){
527 /* !!! cy_stop isn't used because... */
528 info->tty->stopped = 1;
529 base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
533 if(mdm_status & CyDSR){
536 base_addr[CyMEOIR] = 0;
537 return IRQ_HANDLED;
538 } /* cy_modem_interrupt */
540 static irqreturn_t
541 cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
543 struct cyclades_port *info;
544 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
545 int channel;
546 int char_count, saved_cnt;
547 int outch;
549 /* determine the channel and change to that context */
550 channel = (u_short ) (base_addr[CyLICR] >> 2);
552 #ifdef CONFIG_REMOTE_DEBUG
553 if (channel == DEBUG_PORT) {
554 panic ("TxInt on debug port!!!");
556 #endif
558 info = &cy_port[channel];
560 /* validate the port number (as configured and open) */
561 if( (channel < 0) || (NR_PORTS <= channel) ){
562 base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
563 base_addr[CyTEOIR] = CyNOTRANS;
564 return IRQ_HANDLED;
566 info->last_active = jiffies;
567 if(info->tty == 0){
568 base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
569 if (info->xmit_cnt < WAKEUP_CHARS) {
570 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
572 base_addr[CyTEOIR] = CyNOTRANS;
573 return IRQ_HANDLED;
576 /* load the on-chip space available for outbound data */
577 saved_cnt = char_count = base_addr[CyTFTC];
579 if(info->x_char) { /* send special char */
580 outch = info->x_char;
581 base_addr[CyTDR] = outch;
582 char_count--;
583 info->x_char = 0;
586 if (info->x_break){
587 /* The Cirrus chip requires the "Embedded Transmit
588 Commands" of start break, delay, and end break
589 sequences to be sent. The duration of the
590 break is given in TICs, which runs at HZ
591 (typically 100) and the PPR runs at 200 Hz,
592 so the delay is duration * 200/HZ, and thus a
593 break can run from 1/100 sec to about 5/4 sec.
594 Need to check these values - RGH 141095.
596 base_addr[CyTDR] = 0; /* start break */
597 base_addr[CyTDR] = 0x81;
598 base_addr[CyTDR] = 0; /* delay a bit */
599 base_addr[CyTDR] = 0x82;
600 base_addr[CyTDR] = info->x_break*200/HZ;
601 base_addr[CyTDR] = 0; /* terminate break */
602 base_addr[CyTDR] = 0x83;
603 char_count -= 7;
604 info->x_break = 0;
607 while (char_count > 0){
608 if (!info->xmit_cnt){
609 base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
610 break;
612 if (info->xmit_buf == 0){
613 base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
614 break;
616 if (info->tty->stopped || info->tty->hw_stopped){
617 base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
618 break;
620 /* Because the Embedded Transmit Commands have been
621 enabled, we must check to see if the escape
622 character, NULL, is being sent. If it is, we
623 must ensure that there is room for it to be
624 doubled in the output stream. Therefore we
625 no longer advance the pointer when the character
626 is fetched, but rather wait until after the check
627 for a NULL output character. (This is necessary
628 because there may not be room for the two chars
629 needed to send a NULL.
631 outch = info->xmit_buf[info->xmit_tail];
632 if( outch ){
633 info->xmit_cnt--;
634 info->xmit_tail = (info->xmit_tail + 1)
635 & (PAGE_SIZE - 1);
636 base_addr[CyTDR] = outch;
637 char_count--;
638 }else{
639 if(char_count > 1){
640 info->xmit_cnt--;
641 info->xmit_tail = (info->xmit_tail + 1)
642 & (PAGE_SIZE - 1);
643 base_addr[CyTDR] = outch;
644 base_addr[CyTDR] = 0;
645 char_count--;
646 char_count--;
647 }else{
648 break;
653 if (info->xmit_cnt < WAKEUP_CHARS) {
654 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
656 base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS;
657 return IRQ_HANDLED;
658 } /* cy_tx_interrupt */
660 static irqreturn_t
661 cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
663 struct tty_struct *tty;
664 struct cyclades_port *info;
665 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
666 int channel;
667 char data;
668 int char_count;
669 int save_cnt;
671 /* determine the channel and change to that context */
672 channel = (u_short ) (base_addr[CyLICR] >> 2);
673 info = &cy_port[channel];
674 info->last_active = jiffies;
675 save_cnt = char_count = base_addr[CyRFOC];
677 #ifdef CONFIG_REMOTE_DEBUG
678 if (channel == DEBUG_PORT) {
679 while (char_count--) {
680 data = base_addr[CyRDR];
681 queueDebugChar(data);
684 else
685 #endif
686 /* if there is nowhere to put the data, discard it */
687 if(info->tty == 0){
688 while(char_count--){
689 data = base_addr[CyRDR];
691 }else{ /* there is an open port for this data */
692 tty = info->tty;
693 /* load # characters available from the chip */
695 #ifdef CYCLOM_ENABLE_MONITORING
696 ++info->mon.int_count;
697 info->mon.char_count += char_count;
698 if (char_count > info->mon.char_max)
699 info->mon.char_max = char_count;
700 info->mon.char_last = char_count;
701 #endif
702 while(char_count--){
703 data = base_addr[CyRDR];
704 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
705 continue;
707 tty->flip.count++;
708 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
709 *tty->flip.char_buf_ptr++ = data;
710 #ifdef CYCLOM_16Y_HACK
711 udelay(10L);
712 #endif
714 queue_task(&tty->flip.tqueue, &tq_timer);
716 /* end of service */
717 base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
718 return IRQ_HANDLED;
719 } /* cy_rx_interrupt */
722 * This routine is used to handle the "bottom half" processing for the
723 * serial driver, known also the "software interrupt" processing.
724 * This processing is done at the kernel interrupt level, after the
725 * cy_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
726 * is where time-consuming activities which can not be done in the
727 * interrupt driver proper are done; the interrupt driver schedules
728 * them using cy_sched_event(), and they get done here.
730 * This is done through one level of indirection--the task queue.
731 * When a hardware interrupt service routine wants service by the
732 * driver's bottom half, it enqueues the appropriate tq_struct (one
733 * per port) to the tq_cyclades work queue and sets a request flag
734 * via mark_bh for processing that queue. When the time is right,
735 * do_cyclades_bh is called (because of the mark_bh) and it requests
736 * that the work queue be processed.
738 * Although this may seem unwieldy, it gives the system a way to
739 * pass an argument (in this case the pointer to the cyclades_port
740 * structure) to the bottom half of the driver. Previous kernels
741 * had to poll every port to see if that port needed servicing.
743 static void
744 do_cyclades_bh(void)
746 run_task_queue(&tq_cyclades);
747 } /* do_cyclades_bh */
749 static void
750 do_softint(void *private_)
752 struct cyclades_port *info = (struct cyclades_port *) private_;
753 struct tty_struct *tty;
755 tty = info->tty;
756 if (!tty)
757 return;
759 if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
760 tty_hangup(info->tty);
761 wake_up_interruptible(&info->open_wait);
762 info->flags &= ~ASYNC_NORMAL_ACTIVE;
764 if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
765 wake_up_interruptible(&info->open_wait);
767 if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
768 if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
769 && tty->ldisc.write_wakeup){
770 (tty->ldisc.write_wakeup)(tty);
772 wake_up_interruptible(&tty->write_wait);
774 } /* do_softint */
777 /* This is called whenever a port becomes active;
778 interrupts are enabled and DTR & RTS are turned on.
780 static int
781 startup(struct cyclades_port * info)
783 unsigned long flags;
784 volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
785 int channel;
787 if (info->flags & ASYNC_INITIALIZED){
788 return 0;
791 if (!info->type){
792 if (info->tty){
793 set_bit(TTY_IO_ERROR, &info->tty->flags);
795 return 0;
797 if (!info->xmit_buf){
798 info->xmit_buf = (unsigned char *) get_zeroed_page (GFP_KERNEL);
799 if (!info->xmit_buf){
800 return -ENOMEM;
804 config_setup(info);
806 channel = info->line;
808 #ifdef SERIAL_DEBUG_OPEN
809 printk("startup channel %d\n", channel);
810 #endif
812 local_irq_save(flags);
813 base_addr[CyCAR] = (u_char)channel;
814 write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR);
816 base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
817 base_addr[CyMSVR1] = CyRTS;
818 /* CP('S');CP('1'); */
819 base_addr[CyMSVR2] = CyDTR;
821 #ifdef SERIAL_DEBUG_DTR
822 printk("cyc: %d: raising DTR\n", __LINE__);
823 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
824 #endif
826 base_addr[CyIER] |= CyRxData;
827 info->flags |= ASYNC_INITIALIZED;
829 if (info->tty){
830 clear_bit(TTY_IO_ERROR, &info->tty->flags);
832 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
834 local_irq_restore(flags);
836 #ifdef SERIAL_DEBUG_OPEN
837 printk(" done\n");
838 #endif
839 return 0;
840 } /* startup */
842 void
843 start_xmit( struct cyclades_port *info )
845 unsigned long flags;
846 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
847 int channel;
849 channel = info->line;
850 local_irq_save(flags);
851 base_addr[CyCAR] = channel;
852 base_addr[CyIER] |= CyTxMpty;
853 local_irq_restore(flags);
854 } /* start_xmit */
857 * This routine shuts down a serial port; interrupts are disabled,
858 * and DTR is dropped if the hangup on close termio flag is on.
860 static void
861 shutdown(struct cyclades_port * info)
863 unsigned long flags;
864 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
865 int channel;
867 if (!(info->flags & ASYNC_INITIALIZED)){
868 /* CP('$'); */
869 return;
872 channel = info->line;
874 #ifdef SERIAL_DEBUG_OPEN
875 printk("shutdown channel %d\n", channel);
876 #endif
878 /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE
879 SENT BEFORE DROPPING THE LINE !!! (Perhaps
880 set some flag that is read when XMTY happens.)
881 Other choices are to delay some fixed interval
882 or schedule some later processing.
884 local_irq_save(flags);
885 if (info->xmit_buf){
886 free_page((unsigned long) info->xmit_buf);
887 info->xmit_buf = 0;
890 base_addr[CyCAR] = (u_char)channel;
891 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
892 base_addr[CyMSVR1] = 0;
893 /* CP('C');CP('1'); */
894 base_addr[CyMSVR2] = 0;
895 #ifdef SERIAL_DEBUG_DTR
896 printk("cyc: %d: dropping DTR\n", __LINE__);
897 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
898 #endif
900 write_cy_cmd(base_addr,CyDIS_RCVR);
901 /* it may be appropriate to clear _XMIT at
902 some later date (after testing)!!! */
904 if (info->tty){
905 set_bit(TTY_IO_ERROR, &info->tty->flags);
907 info->flags &= ~ASYNC_INITIALIZED;
908 local_irq_restore(flags);
910 #ifdef SERIAL_DEBUG_OPEN
911 printk(" done\n");
912 #endif
913 return;
914 } /* shutdown */
917 * This routine finds or computes the various line characteristics.
919 static void
920 config_setup(struct cyclades_port * info)
922 unsigned long flags;
923 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
924 int channel;
925 unsigned cflag;
926 int i;
927 unsigned char ti, need_init_chan = 0;
929 if (!info->tty || !info->tty->termios){
930 return;
932 if (info->line == -1){
933 return;
935 cflag = info->tty->termios->c_cflag;
937 /* baud rate */
938 i = cflag & CBAUD;
939 #ifdef CBAUDEX
940 /* Starting with kernel 1.1.65, there is direct support for
941 higher baud rates. The following code supports those
942 changes. The conditional aspect allows this driver to be
943 used for earlier as well as later kernel versions. (The
944 mapping is slightly different from serial.c because there
945 is still the possibility of supporting 75 kbit/sec with
946 the Cyclades board.)
948 if (i & CBAUDEX) {
949 if (i == B57600)
950 i = 16;
951 else if(i == B115200)
952 i = 18;
953 #ifdef B78600
954 else if(i == B78600)
955 i = 17;
956 #endif
957 else
958 info->tty->termios->c_cflag &= ~CBAUDEX;
960 #endif
961 if (i == 15) {
962 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
963 i += 1;
964 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
965 i += 3;
967 /* Don't ever change the speed of the console port. It will
968 * run at the speed specified in bootinfo, or at 19.2K */
969 /* Actually, it should run at whatever speed 166Bug was using */
970 /* Note info->timeout isn't used at present */
971 if (info != serial_console_info) {
972 info->tbpr = baud_bpr[i]; /* Tx BPR */
973 info->tco = baud_co[i]; /* Tx CO */
974 info->rbpr = baud_bpr[i]; /* Rx BPR */
975 info->rco = baud_co[i] >> 5; /* Rx CO */
976 if (baud_table[i] == 134) {
977 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
978 /* get it right for 134.5 baud */
979 } else if (baud_table[i]) {
980 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
981 /* this needs to be propagated into the card info */
982 } else {
983 info->timeout = 0;
986 /* By tradition (is it a standard?) a baud rate of zero
987 implies the line should be/has been closed. A bit
988 later in this routine such a test is performed. */
990 /* byte size and parity */
991 info->cor7 = 0;
992 info->cor6 = 0;
993 info->cor5 = 0;
994 info->cor4 = (info->default_threshold
995 ? info->default_threshold
996 : baud_cor4[i]); /* receive threshold */
997 /* Following two lines added 101295, RGH. */
998 /* It is obviously wrong to access CyCORx, and not info->corx here,
999 * try and remember to fix it later! */
1000 channel = info->line;
1001 base_addr[CyCAR] = (u_char)channel;
1002 if (C_CLOCAL(info->tty)) {
1003 if (base_addr[CyIER] & CyMdmCh)
1004 base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */
1005 /* ignore 1->0 modem transitions */
1006 if (base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD))
1007 base_addr[CyCOR4] &= ~(CyDSR|CyCTS|CyDCD);
1008 /* ignore 0->1 modem transitions */
1009 if (base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD))
1010 base_addr[CyCOR5] &= ~(CyDSR|CyCTS|CyDCD);
1011 } else {
1012 if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh)
1013 base_addr[CyIER] |= CyMdmCh; /* with modem intr */
1014 /* act on 1->0 modem transitions */
1015 if ((base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD))
1016 base_addr[CyCOR4] |= CyDSR|CyCTS|CyDCD;
1017 /* act on 0->1 modem transitions */
1018 if ((base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD))
1019 base_addr[CyCOR5] |= CyDSR|CyCTS|CyDCD;
1021 info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP;
1022 info->cor2 = CyETC;
1023 switch(cflag & CSIZE){
1024 case CS5:
1025 info->cor1 = Cy_5_BITS;
1026 break;
1027 case CS6:
1028 info->cor1 = Cy_6_BITS;
1029 break;
1030 case CS7:
1031 info->cor1 = Cy_7_BITS;
1032 break;
1033 case CS8:
1034 info->cor1 = Cy_8_BITS;
1035 break;
1037 if (cflag & PARENB){
1038 if (cflag & PARODD){
1039 info->cor1 |= CyPARITY_O;
1040 }else{
1041 info->cor1 |= CyPARITY_E;
1043 }else{
1044 info->cor1 |= CyPARITY_NONE;
1047 /* CTS flow control flag */
1048 #if 0
1049 /* Don't complcate matters for now! RGH 141095 */
1050 if (cflag & CRTSCTS){
1051 info->flags |= ASYNC_CTS_FLOW;
1052 info->cor2 |= CyCtsAE;
1053 }else{
1054 info->flags &= ~ASYNC_CTS_FLOW;
1055 info->cor2 &= ~CyCtsAE;
1057 #endif
1058 if (cflag & CLOCAL)
1059 info->flags &= ~ASYNC_CHECK_CD;
1060 else
1061 info->flags |= ASYNC_CHECK_CD;
1063 /***********************************************
1064 The hardware option, CyRtsAO, presents RTS when
1065 the chip has characters to send. Since most modems
1066 use RTS as reverse (inbound) flow control, this
1067 option is not used. If inbound flow control is
1068 necessary, DTR can be programmed to provide the
1069 appropriate signals for use with a non-standard
1070 cable. Contact Marcio Saito for details.
1071 ***********************************************/
1073 channel = info->line;
1075 local_irq_save(flags);
1076 base_addr[CyCAR] = (u_char)channel;
1078 /* CyCMR set once only in mvme167_init_serial() */
1079 if (base_addr[CyLICR] != channel << 2)
1080 base_addr[CyLICR] = channel << 2;
1081 if (base_addr[CyLIVR] != 0x5c)
1082 base_addr[CyLIVR] = 0x5c;
1084 /* tx and rx baud rate */
1086 if (base_addr[CyCOR1] != info->cor1)
1087 need_init_chan = 1;
1088 if (base_addr[CyTCOR] != info->tco)
1089 base_addr[CyTCOR] = info->tco;
1090 if (base_addr[CyTBPR] != info->tbpr)
1091 base_addr[CyTBPR] = info->tbpr;
1092 if (base_addr[CyRCOR] != info->rco)
1093 base_addr[CyRCOR] = info->rco;
1094 if (base_addr[CyRBPR] != info->rbpr)
1095 base_addr[CyRBPR] = info->rbpr;
1097 /* set line characteristics according configuration */
1099 if (base_addr[CySCHR1] != START_CHAR(info->tty))
1100 base_addr[CySCHR1] = START_CHAR(info->tty);
1101 if (base_addr[CySCHR2] != STOP_CHAR(info->tty))
1102 base_addr[CySCHR2] = STOP_CHAR(info->tty);
1103 if (base_addr[CySCRL] != START_CHAR(info->tty))
1104 base_addr[CySCRL] = START_CHAR(info->tty);
1105 if (base_addr[CySCRH] != START_CHAR(info->tty))
1106 base_addr[CySCRH] = START_CHAR(info->tty);
1107 if (base_addr[CyCOR1] != info->cor1)
1108 base_addr[CyCOR1] = info->cor1;
1109 if (base_addr[CyCOR2] != info->cor2)
1110 base_addr[CyCOR2] = info->cor2;
1111 if (base_addr[CyCOR3] != info->cor3)
1112 base_addr[CyCOR3] = info->cor3;
1113 if (base_addr[CyCOR4] != info->cor4)
1114 base_addr[CyCOR4] = info->cor4;
1115 if (base_addr[CyCOR5] != info->cor5)
1116 base_addr[CyCOR5] = info->cor5;
1117 if (base_addr[CyCOR6] != info->cor6)
1118 base_addr[CyCOR6] = info->cor6;
1119 if (base_addr[CyCOR7] != info->cor7)
1120 base_addr[CyCOR7] = info->cor7;
1122 if (need_init_chan)
1123 write_cy_cmd(base_addr,CyINIT_CHAN);
1125 base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
1127 /* 2ms default rx timeout */
1128 ti = info->default_timeout ? info->default_timeout : 0x02;
1129 if (base_addr[CyRTPRL] != ti)
1130 base_addr[CyRTPRL] = ti;
1131 if (base_addr[CyRTPRH] != 0)
1132 base_addr[CyRTPRH] = 0;
1134 /* Set up RTS here also ????? RGH 141095 */
1135 if(i == 0){ /* baud rate is zero, turn off line */
1136 if ((base_addr[CyMSVR2] & CyDTR) == CyDTR)
1137 base_addr[CyMSVR2] = 0;
1138 #ifdef SERIAL_DEBUG_DTR
1139 printk("cyc: %d: dropping DTR\n", __LINE__);
1140 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1141 #endif
1142 }else{
1143 if ((base_addr[CyMSVR2] & CyDTR) != CyDTR)
1144 base_addr[CyMSVR2] = CyDTR;
1145 #ifdef SERIAL_DEBUG_DTR
1146 printk("cyc: %d: raising DTR\n", __LINE__);
1147 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1148 #endif
1151 if (info->tty){
1152 clear_bit(TTY_IO_ERROR, &info->tty->flags);
1155 local_irq_restore(flags);
1157 } /* config_setup */
1160 static void
1161 cy_put_char(struct tty_struct *tty, unsigned char ch)
1163 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1164 unsigned long flags;
1166 #ifdef SERIAL_DEBUG_IO
1167 printk("cy_put_char %s(0x%02x)\n", tty->name, ch);
1168 #endif
1170 if (serial_paranoia_check(info, tty->name, "cy_put_char"))
1171 return;
1173 if (!tty || !info->xmit_buf)
1174 return;
1176 local_irq_save(flags);
1177 if (info->xmit_cnt >= PAGE_SIZE - 1) {
1178 local_irq_restore(flags);
1179 return;
1182 info->xmit_buf[info->xmit_head++] = ch;
1183 info->xmit_head &= PAGE_SIZE - 1;
1184 info->xmit_cnt++;
1185 local_irq_restore(flags);
1186 } /* cy_put_char */
1189 static void
1190 cy_flush_chars(struct tty_struct *tty)
1192 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1193 unsigned long flags;
1194 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1195 int channel;
1197 #ifdef SERIAL_DEBUG_IO
1198 printk("cy_flush_chars %s\n", tty->name); /* */
1199 #endif
1201 if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
1202 return;
1204 if (info->xmit_cnt <= 0 || tty->stopped
1205 || tty->hw_stopped || !info->xmit_buf)
1206 return;
1208 channel = info->line;
1210 local_irq_save(flags);
1211 base_addr[CyCAR] = channel;
1212 base_addr[CyIER] |= CyTxMpty;
1213 local_irq_restore(flags);
1214 } /* cy_flush_chars */
1217 /* This routine gets called when tty_write has put something into
1218 the write_queue. If the port is not already transmitting stuff,
1219 start it off by enabling interrupts. The interrupt service
1220 routine will then ensure that the characters are sent. If the
1221 port is already active, there is no need to kick it.
1223 static int
1224 cy_write(struct tty_struct * tty, int from_user,
1225 const unsigned char *buf, int count)
1227 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1228 unsigned long flags;
1229 int c, total = 0;
1231 #ifdef SERIAL_DEBUG_IO
1232 printk("cy_write %s\n", tty->name); /* */
1233 #endif
1235 if (serial_paranoia_check(info, tty->name, "cy_write")){
1236 return 0;
1239 if (!tty || !info->xmit_buf || !tmp_buf){
1240 return 0;
1243 if (from_user) {
1244 down(&tmp_buf_sem);
1245 while (1) {
1246 c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1247 SERIAL_XMIT_SIZE - info->xmit_head));
1248 if (c <= 0)
1249 break;
1251 c -= copy_from_user(tmp_buf, buf, c);
1252 if (!c) {
1253 if (!total)
1254 total = -EFAULT;
1255 break;
1258 local_irq_save(flags);
1259 c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1260 SERIAL_XMIT_SIZE - info->xmit_head));
1261 memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
1262 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1263 info->xmit_cnt += c;
1264 local_irq_restore(flags);
1266 buf += c;
1267 count -= c;
1268 total += c;
1270 up(&tmp_buf_sem);
1271 } else {
1272 while (1) {
1273 local_irq_save(flags);
1274 c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1275 SERIAL_XMIT_SIZE - info->xmit_head));
1276 if (c <= 0) {
1277 local_irq_restore(flags);
1278 break;
1281 memcpy(info->xmit_buf + info->xmit_head, buf, c);
1282 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1283 info->xmit_cnt += c;
1284 local_irq_restore(flags);
1286 buf += c;
1287 count -= c;
1288 total += c;
1292 if (info->xmit_cnt
1293 && !tty->stopped
1294 && !tty->hw_stopped ) {
1295 start_xmit(info);
1297 return total;
1298 } /* cy_write */
1301 static int
1302 cy_write_room(struct tty_struct *tty)
1304 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1305 int ret;
1307 #ifdef SERIAL_DEBUG_IO
1308 printk("cy_write_room %s\n", tty->name); /* */
1309 #endif
1311 if (serial_paranoia_check(info, tty->name, "cy_write_room"))
1312 return 0;
1313 ret = PAGE_SIZE - info->xmit_cnt - 1;
1314 if (ret < 0)
1315 ret = 0;
1316 return ret;
1317 } /* cy_write_room */
1320 static int
1321 cy_chars_in_buffer(struct tty_struct *tty)
1323 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1325 #ifdef SERIAL_DEBUG_IO
1326 printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */
1327 #endif
1329 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
1330 return 0;
1332 return info->xmit_cnt;
1333 } /* cy_chars_in_buffer */
1336 static void
1337 cy_flush_buffer(struct tty_struct *tty)
1339 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1340 unsigned long flags;
1342 #ifdef SERIAL_DEBUG_IO
1343 printk("cy_flush_buffer %s\n", tty->name); /* */
1344 #endif
1346 if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
1347 return;
1348 local_irq_save(flags);
1349 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1350 local_irq_restore(flags);
1351 wake_up_interruptible(&tty->write_wait);
1352 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
1353 && tty->ldisc.write_wakeup)
1354 (tty->ldisc.write_wakeup)(tty);
1355 } /* cy_flush_buffer */
1358 /* This routine is called by the upper-layer tty layer to signal
1359 that incoming characters should be throttled or that the
1360 throttle should be released.
1362 static void
1363 cy_throttle(struct tty_struct * tty)
1365 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1366 unsigned long flags;
1367 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1368 int channel;
1370 #ifdef SERIAL_DEBUG_THROTTLE
1371 char buf[64];
1373 printk("throttle %s: %d....\n", tty_name(tty, buf),
1374 tty->ldisc.chars_in_buffer(tty));
1375 printk("cy_throttle %s\n", tty->name);
1376 #endif
1378 if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){
1379 return;
1382 if (I_IXOFF(tty)) {
1383 info->x_char = STOP_CHAR(tty);
1384 /* Should use the "Send Special Character" feature!!! */
1387 channel = info->line;
1389 local_irq_save(flags);
1390 base_addr[CyCAR] = (u_char)channel;
1391 base_addr[CyMSVR1] = 0;
1392 local_irq_restore(flags);
1394 return;
1395 } /* cy_throttle */
1398 static void
1399 cy_unthrottle(struct tty_struct * tty)
1401 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1402 unsigned long flags;
1403 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1404 int channel;
1406 #ifdef SERIAL_DEBUG_THROTTLE
1407 char buf[64];
1409 printk("throttle %s: %d....\n", tty_name(tty, buf),
1410 tty->ldisc.chars_in_buffer(tty));
1411 printk("cy_unthrottle %s\n", tty->name);
1412 #endif
1414 if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){
1415 return;
1418 if (I_IXOFF(tty)) {
1419 info->x_char = START_CHAR(tty);
1420 /* Should use the "Send Special Character" feature!!! */
1423 channel = info->line;
1425 local_irq_save(flags);
1426 base_addr[CyCAR] = (u_char)channel;
1427 base_addr[CyMSVR1] = CyRTS;
1428 local_irq_restore(flags);
1430 return;
1431 } /* cy_unthrottle */
1433 static int
1434 get_serial_info(struct cyclades_port * info,
1435 struct serial_struct * retinfo)
1437 struct serial_struct tmp;
1439 /* CP('g'); */
1440 if (!retinfo)
1441 return -EFAULT;
1442 memset(&tmp, 0, sizeof(tmp));
1443 tmp.type = info->type;
1444 tmp.line = info->line;
1445 tmp.port = info->line;
1446 tmp.irq = 0;
1447 tmp.flags = info->flags;
1448 tmp.baud_base = 0; /*!!!*/
1449 tmp.close_delay = info->close_delay;
1450 tmp.custom_divisor = 0; /*!!!*/
1451 tmp.hub6 = 0; /*!!!*/
1452 return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0;
1453 } /* get_serial_info */
1455 static int
1456 set_serial_info(struct cyclades_port * info,
1457 struct serial_struct * new_info)
1459 struct serial_struct new_serial;
1460 struct cyclades_port old_info;
1462 /* CP('s'); */
1463 if (!new_info)
1464 return -EFAULT;
1465 if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
1466 return -EFAULT;
1467 old_info = *info;
1469 if (!capable(CAP_SYS_ADMIN)) {
1470 if ((new_serial.close_delay != info->close_delay) ||
1471 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
1472 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
1473 return -EPERM;
1474 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1475 (new_serial.flags & ASYNC_USR_MASK));
1476 goto check_and_exit;
1481 * OK, past this point, all the error checking has been done.
1482 * At this point, we start making changes.....
1485 info->flags = ((info->flags & ~ASYNC_FLAGS) |
1486 (new_serial.flags & ASYNC_FLAGS));
1487 info->close_delay = new_serial.close_delay;
1490 check_and_exit:
1491 if (info->flags & ASYNC_INITIALIZED){
1492 config_setup(info);
1493 return 0;
1494 }else{
1495 return startup(info);
1497 } /* set_serial_info */
1499 static int
1500 get_modem_info(struct cyclades_port * info, unsigned int *value)
1502 int channel;
1503 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1504 unsigned long flags;
1505 unsigned char status;
1506 unsigned int result;
1508 channel = info->line;
1510 local_irq_save(flags);
1511 base_addr[CyCAR] = (u_char)channel;
1512 status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
1513 local_irq_restore(flags);
1515 result = ((status & CyRTS) ? TIOCM_RTS : 0)
1516 | ((status & CyDTR) ? TIOCM_DTR : 0)
1517 | ((status & CyDCD) ? TIOCM_CAR : 0)
1518 | ((status & CyDSR) ? TIOCM_DSR : 0)
1519 | ((status & CyCTS) ? TIOCM_CTS : 0);
1520 return put_user(result,(unsigned int *) value);
1521 } /* get_modem_info */
1523 static int
1524 set_modem_info(struct cyclades_port * info, unsigned int cmd,
1525 unsigned int *value)
1527 int channel;
1528 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1529 unsigned long flags;
1530 unsigned int arg;
1532 if (get_user(arg, (unsigned long *) value))
1533 return -EFAULT;
1534 channel = info->line;
1536 switch (cmd) {
1537 case TIOCMBIS:
1538 if (arg & TIOCM_RTS){
1539 local_irq_save(flags);
1540 base_addr[CyCAR] = (u_char)channel;
1541 base_addr[CyMSVR1] = CyRTS;
1542 local_irq_restore(flags);
1544 if (arg & TIOCM_DTR){
1545 local_irq_save(flags);
1546 base_addr[CyCAR] = (u_char)channel;
1547 /* CP('S');CP('2'); */
1548 base_addr[CyMSVR2] = CyDTR;
1549 #ifdef SERIAL_DEBUG_DTR
1550 printk("cyc: %d: raising DTR\n", __LINE__);
1551 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1552 #endif
1553 local_irq_restore(flags);
1555 break;
1556 case TIOCMBIC:
1557 if (arg & TIOCM_RTS){
1558 local_irq_save(flags);
1559 base_addr[CyCAR] = (u_char)channel;
1560 base_addr[CyMSVR1] = 0;
1561 local_irq_restore(flags);
1563 if (arg & TIOCM_DTR){
1564 local_irq_save(flags);
1565 base_addr[CyCAR] = (u_char)channel;
1566 /* CP('C');CP('2'); */
1567 base_addr[CyMSVR2] = 0;
1568 #ifdef SERIAL_DEBUG_DTR
1569 printk("cyc: %d: dropping DTR\n", __LINE__);
1570 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1571 #endif
1572 local_irq_restore(flags);
1574 break;
1575 case TIOCMSET:
1576 if (arg & TIOCM_RTS){
1577 local_irq_save(flags);
1578 base_addr[CyCAR] = (u_char)channel;
1579 base_addr[CyMSVR1] = CyRTS;
1580 local_irq_restore(flags);
1581 }else{
1582 local_irq_save(flags);
1583 base_addr[CyCAR] = (u_char)channel;
1584 base_addr[CyMSVR1] = 0;
1585 local_irq_restore(flags);
1587 if (arg & TIOCM_DTR){
1588 local_irq_save(flags);
1589 base_addr[CyCAR] = (u_char)channel;
1590 /* CP('S');CP('3'); */
1591 base_addr[CyMSVR2] = CyDTR;
1592 #ifdef SERIAL_DEBUG_DTR
1593 printk("cyc: %d: raising DTR\n", __LINE__);
1594 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1595 #endif
1596 local_irq_restore(flags);
1597 }else{
1598 local_irq_save(flags);
1599 base_addr[CyCAR] = (u_char)channel;
1600 /* CP('C');CP('3'); */
1601 base_addr[CyMSVR2] = 0;
1602 #ifdef SERIAL_DEBUG_DTR
1603 printk("cyc: %d: dropping DTR\n", __LINE__);
1604 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1605 #endif
1606 local_irq_restore(flags);
1608 break;
1609 default:
1610 return -EINVAL;
1612 return 0;
1613 } /* set_modem_info */
1615 static void
1616 send_break( struct cyclades_port * info, int duration)
1617 { /* Let the transmit ISR take care of this (since it
1618 requires stuffing characters into the output stream).
1620 info->x_break = duration;
1621 if (!info->xmit_cnt ) {
1622 start_xmit(info);
1624 } /* send_break */
1626 static int
1627 get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
1630 if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
1631 return -EFAULT;
1632 info->mon.int_count = 0;
1633 info->mon.char_count = 0;
1634 info->mon.char_max = 0;
1635 info->mon.char_last = 0;
1636 return 0;
1639 static int
1640 set_threshold(struct cyclades_port * info, unsigned long *arg)
1642 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1643 unsigned long value;
1644 int channel;
1646 if (get_user(value, arg))
1647 return -EFAULT;
1649 channel = info->line;
1650 info->cor4 &= ~CyREC_FIFO;
1651 info->cor4 |= value & CyREC_FIFO;
1652 base_addr[CyCOR4] = info->cor4;
1653 return 0;
1656 static int
1657 get_threshold(struct cyclades_port * info, unsigned long *value)
1659 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1660 int channel;
1661 unsigned long tmp;
1663 channel = info->line;
1665 tmp = base_addr[CyCOR4] & CyREC_FIFO;
1666 return put_user(tmp,value);
1669 static int
1670 set_default_threshold(struct cyclades_port * info, unsigned long *arg)
1672 unsigned long value;
1674 if (get_user(value, arg))
1675 return -EFAULT;
1677 info->default_threshold = value & 0x0f;
1678 return 0;
1681 static int
1682 get_default_threshold(struct cyclades_port * info, unsigned long *value)
1684 return put_user(info->default_threshold,value);
1687 static int
1688 set_timeout(struct cyclades_port * info, unsigned long *arg)
1690 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1691 int channel;
1692 unsigned long value;
1694 if (get_user(value, arg))
1695 return -EFAULT;
1697 channel = info->line;
1699 base_addr[CyRTPRL] = value & 0xff;
1700 base_addr[CyRTPRH] = (value >> 8) & 0xff;
1701 return 0;
1704 static int
1705 get_timeout(struct cyclades_port * info, unsigned long *value)
1707 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
1708 int channel;
1709 unsigned long tmp;
1711 channel = info->line;
1713 tmp = base_addr[CyRTPRL];
1714 return put_user(tmp,value);
1717 static int
1718 set_default_timeout(struct cyclades_port * info, unsigned long value)
1720 info->default_timeout = value & 0xff;
1721 return 0;
1724 static int
1725 get_default_timeout(struct cyclades_port * info, unsigned long *value)
1727 return put_user(info->default_timeout,value);
1730 static int
1731 cy_ioctl(struct tty_struct *tty, struct file * file,
1732 unsigned int cmd, unsigned long arg)
1734 unsigned long val;
1735 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1736 int ret_val = 0;
1738 #ifdef SERIAL_DEBUG_OTHER
1739 printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
1740 #endif
1742 switch (cmd) {
1743 case CYGETMON:
1744 ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
1745 break;
1746 case CYGETTHRESH:
1747 ret_val = get_threshold(info, (unsigned long *)arg);
1748 break;
1749 case CYSETTHRESH:
1750 ret_val = set_threshold(info, (unsigned long *)arg);
1751 break;
1752 case CYGETDEFTHRESH:
1753 ret_val = get_default_threshold(info, (unsigned long *)arg);
1754 break;
1755 case CYSETDEFTHRESH:
1756 ret_val = set_default_threshold(info, (unsigned long *)arg);
1757 break;
1758 case CYGETTIMEOUT:
1759 ret_val = get_timeout(info, (unsigned long *)arg);
1760 break;
1761 case CYSETTIMEOUT:
1762 ret_val = set_timeout(info, (unsigned long *)arg);
1763 break;
1764 case CYGETDEFTIMEOUT:
1765 ret_val = get_default_timeout(info, (unsigned long *)arg);
1766 break;
1767 case CYSETDEFTIMEOUT:
1768 ret_val = set_default_timeout(info, (unsigned long)arg);
1769 break;
1770 case TCSBRK: /* SVID version: non-zero arg --> no break */
1771 ret_val = tty_check_change(tty);
1772 if (ret_val)
1773 break;
1774 tty_wait_until_sent(tty,0);
1775 if (!arg)
1776 send_break(info, HZ/4); /* 1/4 second */
1777 break;
1778 case TCSBRKP: /* support for POSIX tcsendbreak() */
1779 ret_val = tty_check_change(tty);
1780 if (ret_val)
1781 break;
1782 tty_wait_until_sent(tty,0);
1783 send_break(info, arg ? arg*(HZ/10) : HZ/4);
1784 break;
1785 case TIOCMBIS:
1786 case TIOCMBIC:
1787 case TIOCMSET:
1788 ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
1789 break;
1791 /* The following commands are incompletely implemented!!! */
1792 case TIOCGSOFTCAR:
1793 ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
1794 break;
1795 case TIOCSSOFTCAR:
1796 ret_val = get_user(val, (unsigned long *) arg);
1797 if (ret_val)
1798 break;
1799 tty->termios->c_cflag =
1800 ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
1801 break;
1802 case TIOCMGET:
1803 ret_val = get_modem_info(info, (unsigned int *) arg);
1804 break;
1805 case TIOCGSERIAL:
1806 ret_val = get_serial_info(info, (struct serial_struct *) arg);
1807 break;
1808 case TIOCSSERIAL:
1809 ret_val = set_serial_info(info,
1810 (struct serial_struct *) arg);
1811 break;
1812 default:
1813 ret_val = -ENOIOCTLCMD;
1816 #ifdef SERIAL_DEBUG_OTHER
1817 printk("cy_ioctl done\n");
1818 #endif
1820 return ret_val;
1821 } /* cy_ioctl */
1826 static void
1827 cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
1829 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1831 #ifdef SERIAL_DEBUG_OTHER
1832 printk("cy_set_termios %s\n", tty->name);
1833 #endif
1835 if (tty->termios->c_cflag == old_termios->c_cflag)
1836 return;
1837 config_setup(info);
1839 if ((old_termios->c_cflag & CRTSCTS) &&
1840 !(tty->termios->c_cflag & CRTSCTS)) {
1841 tty->stopped = 0;
1842 cy_start(tty);
1844 #ifdef tytso_patch_94Nov25_1726
1845 if (!(old_termios->c_cflag & CLOCAL) &&
1846 (tty->termios->c_cflag & CLOCAL))
1847 wake_up_interruptible(&info->open_wait);
1848 #endif
1850 return;
1851 } /* cy_set_termios */
1854 static void
1855 cy_close(struct tty_struct * tty, struct file * filp)
1857 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1859 /* CP('C'); */
1860 #ifdef SERIAL_DEBUG_OTHER
1861 printk("cy_close %s\n", tty->name);
1862 #endif
1864 if (!info
1865 || serial_paranoia_check(info, tty->name, "cy_close")){
1866 return;
1868 #ifdef SERIAL_DEBUG_OPEN
1869 printk("cy_close %s, count = %d\n", tty->name, info->count);
1870 #endif
1872 if ((tty->count == 1) && (info->count != 1)) {
1874 * Uh, oh. tty->count is 1, which means that the tty
1875 * structure will be freed. Info->count should always
1876 * be one in these conditions. If it's greater than
1877 * one, we've got real problems, since it means the
1878 * serial port won't be shutdown.
1880 printk("cy_close: bad serial port count; tty->count is 1, "
1881 "info->count is %d\n", info->count);
1882 info->count = 1;
1884 #ifdef SERIAL_DEBUG_COUNT
1885 printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count - 1);
1886 #endif
1887 if (--info->count < 0) {
1888 printk("cy_close: bad serial port count for ttys%d: %d\n",
1889 info->line, info->count);
1890 #ifdef SERIAL_DEBUG_COUNT
1891 printk("cyc: %d: setting count to 0\n", __LINE__);
1892 #endif
1893 info->count = 0;
1895 if (info->count)
1896 return;
1897 info->flags |= ASYNC_CLOSING;
1898 if (info->flags & ASYNC_INITIALIZED)
1899 tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
1900 shutdown(info);
1901 if (tty->driver->flush_buffer)
1902 tty->driver->flush_buffer(tty);
1903 if (tty->ldisc.flush_buffer)
1904 tty->ldisc.flush_buffer(tty);
1905 info->event = 0;
1906 info->tty = 0;
1907 if (tty->ldisc.num != ldiscs[N_TTY].num) {
1908 if (tty->ldisc.close)
1909 (tty->ldisc.close)(tty);
1910 tty->ldisc = ldiscs[N_TTY];
1911 tty->termios->c_line = N_TTY;
1912 if (tty->ldisc.open)
1913 (tty->ldisc.open)(tty);
1915 if (info->blocked_open) {
1916 if (info->close_delay) {
1917 current->state = TASK_INTERRUPTIBLE;
1918 schedule_timeout(info->close_delay);
1920 wake_up_interruptible(&info->open_wait);
1922 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1923 wake_up_interruptible(&info->close_wait);
1925 #ifdef SERIAL_DEBUG_OTHER
1926 printk("cy_close done\n");
1927 #endif
1929 return;
1930 } /* cy_close */
1933 * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
1935 void
1936 cy_hangup(struct tty_struct *tty)
1938 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1940 #ifdef SERIAL_DEBUG_OTHER
1941 printk("cy_hangup %s\n", tty->name); /* */
1942 #endif
1944 if (serial_paranoia_check(info, tty->name, "cy_hangup"))
1945 return;
1947 shutdown(info);
1948 #if 0
1949 info->event = 0;
1950 info->count = 0;
1951 #ifdef SERIAL_DEBUG_COUNT
1952 printk("cyc: %d: setting count to 0\n", __LINE__);
1953 #endif
1954 info->tty = 0;
1955 #endif
1956 info->flags &= ~ASYNC_NORMAL_ACTIVE;
1957 wake_up_interruptible(&info->open_wait);
1958 } /* cy_hangup */
1963 * ------------------------------------------------------------
1964 * cy_open() and friends
1965 * ------------------------------------------------------------
1968 static int
1969 block_til_ready(struct tty_struct *tty, struct file * filp,
1970 struct cyclades_port *info)
1972 DECLARE_WAITQUEUE(wait, current);
1973 unsigned long flags;
1974 int channel;
1975 int retval;
1976 volatile u_char *base_addr = (u_char *)BASE_ADDR;
1979 * If the device is in the middle of being closed, then block
1980 * until it's done, and then try again.
1982 if (info->flags & ASYNC_CLOSING) {
1983 interruptible_sleep_on(&info->close_wait);
1984 if (info->flags & ASYNC_HUP_NOTIFY){
1985 return -EAGAIN;
1986 }else{
1987 return -ERESTARTSYS;
1992 * If non-blocking mode is set, then make the check up front
1993 * and then exit.
1995 if (filp->f_flags & O_NONBLOCK) {
1996 info->flags |= ASYNC_NORMAL_ACTIVE;
1997 return 0;
2001 * Block waiting for the carrier detect and the line to become
2002 * free (i.e., not in use by the callout). While we are in
2003 * this loop, info->count is dropped by one, so that
2004 * cy_close() knows when to free things. We restore it upon
2005 * exit, either normal or abnormal.
2007 retval = 0;
2008 add_wait_queue(&info->open_wait, &wait);
2009 #ifdef SERIAL_DEBUG_OPEN
2010 printk("block_til_ready before block: %s, count = %d\n",
2011 tty->name, info->count);/**/
2012 #endif
2013 info->count--;
2014 #ifdef SERIAL_DEBUG_COUNT
2015 printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
2016 #endif
2017 info->blocked_open++;
2019 channel = info->line;
2021 while (1) {
2022 local_irq_save(flags);
2023 base_addr[CyCAR] = (u_char)channel;
2024 base_addr[CyMSVR1] = CyRTS;
2025 /* CP('S');CP('4'); */
2026 base_addr[CyMSVR2] = CyDTR;
2027 #ifdef SERIAL_DEBUG_DTR
2028 printk("cyc: %d: raising DTR\n", __LINE__);
2029 printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
2030 #endif
2031 local_irq_restore(flags);
2032 set_current_state(TASK_INTERRUPTIBLE);
2033 if (tty_hung_up_p(filp)
2034 || !(info->flags & ASYNC_INITIALIZED) ){
2035 if (info->flags & ASYNC_HUP_NOTIFY) {
2036 retval = -EAGAIN;
2037 }else{
2038 retval = -ERESTARTSYS;
2040 break;
2042 local_irq_save(flags);
2043 base_addr[CyCAR] = (u_char)channel;
2044 /* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */
2045 if (!(info->flags & ASYNC_CLOSING)
2046 && (C_CLOCAL(tty)
2047 || (base_addr[CyMSVR1] & CyDCD))) {
2048 local_irq_restore(flags);
2049 break;
2051 local_irq_restore(flags);
2052 if (signal_pending(current)) {
2053 retval = -ERESTARTSYS;
2054 break;
2056 #ifdef SERIAL_DEBUG_OPEN
2057 printk("block_til_ready blocking: %s, count = %d\n",
2058 tty->name, info->count);/**/
2059 #endif
2060 schedule();
2062 current->state = TASK_RUNNING;
2063 remove_wait_queue(&info->open_wait, &wait);
2064 if (!tty_hung_up_p(filp)){
2065 info->count++;
2066 #ifdef SERIAL_DEBUG_COUNT
2067 printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
2068 #endif
2070 info->blocked_open--;
2071 #ifdef SERIAL_DEBUG_OPEN
2072 printk("block_til_ready after blocking: %s, count = %d\n",
2073 tty->name, info->count);/**/
2074 #endif
2075 if (retval)
2076 return retval;
2077 info->flags |= ASYNC_NORMAL_ACTIVE;
2078 return 0;
2079 } /* block_til_ready */
2082 * This routine is called whenever a serial port is opened. It
2083 * performs the serial-specific initialization for the tty structure.
2086 cy_open(struct tty_struct *tty, struct file * filp)
2088 struct cyclades_port *info;
2089 int retval, line;
2091 /* CP('O'); */
2092 line = tty->index;
2093 if ((line < 0) || (NR_PORTS <= line)){
2094 return -ENODEV;
2096 info = &cy_port[line];
2097 if (info->line < 0){
2098 return -ENODEV;
2100 #ifdef SERIAL_DEBUG_OTHER
2101 printk("cy_open %s\n", tty->name); /* */
2102 #endif
2103 if (serial_paranoia_check(info, tty->name, "cy_open")){
2104 return -ENODEV;
2106 #ifdef SERIAL_DEBUG_OPEN
2107 printk("cy_open %s, count = %d\n", tty->name, info->count);/**/
2108 #endif
2109 info->count++;
2110 #ifdef SERIAL_DEBUG_COUNT
2111 printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
2112 #endif
2113 tty->driver_data = info;
2114 info->tty = tty;
2116 if (!tmp_buf) {
2117 tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
2118 if (!tmp_buf){
2119 return -ENOMEM;
2124 * Start up serial port
2126 retval = startup(info);
2127 if (retval){
2128 return retval;
2131 retval = block_til_ready(tty, filp, info);
2132 if (retval) {
2133 #ifdef SERIAL_DEBUG_OPEN
2134 printk("cy_open returning after block_til_ready with %d\n",
2135 retval);
2136 #endif
2137 return retval;
2140 #ifdef SERIAL_DEBUG_OPEN
2141 printk("cy_open done\n");/**/
2142 #endif
2143 return 0;
2144 } /* cy_open */
2149 * ---------------------------------------------------------------------
2150 * serial167_init() and friends
2152 * serial167_init() is called at boot-time to initialize the serial driver.
2153 * ---------------------------------------------------------------------
2157 * This routine prints out the appropriate serial driver version
2158 * number, and identifies which options were configured into this
2159 * driver.
2161 static void
2162 show_version(void)
2164 printk("MVME166/167 cd2401 driver\n");
2165 } /* show_version */
2167 /* initialize chips on card -- return number of valid
2168 chips (which is number of ports/4) */
2171 * This initialises the hardware to a reasonable state. It should
2172 * probe the chip first so as to copy 166-Bug setup as a default for
2173 * port 0. It initialises CMR to CyASYNC; that is never done again, so
2174 * as to limit the number of CyINIT_CHAN commands in normal running.
2176 * ... I wonder what I should do if this fails ...
2179 void
2180 mvme167_serial_console_setup(int cflag)
2182 volatile unsigned char* base_addr = (u_char *)BASE_ADDR;
2183 int ch;
2184 u_char spd;
2185 u_char rcor, rbpr, badspeed = 0;
2186 unsigned long flags;
2188 local_irq_save(flags);
2191 * First probe channel zero of the chip, to see what speed has
2192 * been selected.
2195 base_addr[CyCAR] = 0;
2197 rcor = base_addr[CyRCOR] << 5;
2198 rbpr = base_addr[CyRBPR];
2200 for (spd = 0; spd < sizeof(baud_bpr); spd++)
2201 if (rbpr == baud_bpr[spd] && rcor == baud_co[spd])
2202 break;
2203 if (spd >= sizeof(baud_bpr)) {
2204 spd = 14; /* 19200 */
2205 badspeed = 1; /* Failed to identify speed */
2207 initial_console_speed = spd;
2209 /* OK, we have chosen a speed, now reset and reinitialise */
2211 my_udelay(20000L); /* Allow time for any active o/p to complete */
2212 if(base_addr[CyCCR] != 0x00){
2213 local_irq_restore(flags);
2214 /* printk(" chip is never idle (CCR != 0)\n"); */
2215 return;
2218 base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */
2219 my_udelay(1000L);
2221 if(base_addr[CyGFRCR] == 0x00){
2222 local_irq_restore(flags);
2223 /* printk(" chip is not responding (GFRCR stayed 0)\n"); */
2224 return;
2228 * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms
2229 * tick
2232 base_addr[CyTPR] = 10;
2234 base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */
2235 base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */
2236 base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */
2239 * Attempt to set up all channels to something reasonable, and
2240 * bang out a INIT_CHAN command. We should then be able to limit
2241 * the ammount of fiddling we have to do in normal running.
2244 for (ch = 3; ch >= 0 ; ch--) {
2245 base_addr[CyCAR] = (u_char)ch;
2246 base_addr[CyIER] = 0;
2247 base_addr[CyCMR] = CyASYNC;
2248 base_addr[CyLICR] = (u_char)ch << 2;
2249 base_addr[CyLIVR] = 0x5c;
2250 base_addr[CyTCOR] = baud_co[spd];
2251 base_addr[CyTBPR] = baud_bpr[spd];
2252 base_addr[CyRCOR] = baud_co[spd] >> 5;
2253 base_addr[CyRBPR] = baud_bpr[spd];
2254 base_addr[CySCHR1] = 'Q' & 0x1f;
2255 base_addr[CySCHR2] = 'X' & 0x1f;
2256 base_addr[CySCRL] = 0;
2257 base_addr[CySCRH] = 0;
2258 base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
2259 base_addr[CyCOR2] = 0;
2260 base_addr[CyCOR3] = Cy_1_STOP;
2261 base_addr[CyCOR4] = baud_cor4[spd];
2262 base_addr[CyCOR5] = 0;
2263 base_addr[CyCOR6] = 0;
2264 base_addr[CyCOR7] = 0;
2265 base_addr[CyRTPRL] = 2;
2266 base_addr[CyRTPRH] = 0;
2267 base_addr[CyMSVR1] = 0;
2268 base_addr[CyMSVR2] = 0;
2269 write_cy_cmd(base_addr,CyINIT_CHAN|CyDIS_RCVR|CyDIS_XMTR);
2273 * Now do specials for channel zero....
2276 base_addr[CyMSVR1] = CyRTS;
2277 base_addr[CyMSVR2] = CyDTR;
2278 base_addr[CyIER] = CyRxData;
2279 write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR);
2281 local_irq_restore(flags);
2283 my_udelay(20000L); /* Let it all settle down */
2285 printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]);
2286 if (badspeed)
2287 printk(" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n",
2288 rcor >> 5, rbpr);
2289 } /* serial_console_init */
2291 static struct tty_operations cy_ops = {
2292 .open = cy_open,
2293 .close = cy_close,
2294 .write = cy_write,
2295 .put_char = cy_put_char,
2296 .flush_chars = cy_flush_chars,
2297 .write_room = cy_write_room,
2298 .chars_in_buffer = cy_chars_in_buffer,
2299 .flush_buffer = cy_flush_buffer,
2300 .ioctl = cy_ioctl,
2301 .throttle = cy_throttle,
2302 .unthrottle = cy_unthrottle,
2303 .set_termios = cy_set_termios,
2304 .stop = cy_stop,
2305 .start = cy_start,
2306 .hangup = cy_hangup,
2308 /* The serial driver boot-time initialization code!
2309 Hardware I/O ports are mapped to character special devices on a
2310 first found, first allocated manner. That is, this code searches
2311 for Cyclom cards in the system. As each is found, it is probed
2312 to discover how many chips (and thus how many ports) are present.
2313 These ports are mapped to the tty ports 64 and upward in monotonic
2314 fashion. If an 8-port card is replaced with a 16-port card, the
2315 port mapping on a following card will shift.
2317 This approach is different from what is used in the other serial
2318 device driver because the Cyclom is more properly a multiplexer,
2319 not just an aggregation of serial ports on one card.
2321 If there are more cards with more ports than have been statically
2322 allocated above, a warning is printed and the extra ports are ignored.
2325 serial167_init(void)
2327 struct cyclades_port *info;
2328 int ret = 0;
2329 int good_ports = 0;
2330 int port_num = 0;
2331 int index;
2332 int DefSpeed;
2333 #ifdef notyet
2334 struct sigaction sa;
2335 #endif
2337 if (!(mvme16x_config &MVME16x_CONFIG_GOT_CD2401))
2338 return 0;
2340 cy_serial_driver = alloc_tty_driver(NR_PORTS);
2341 if (!cy_serial_driver)
2342 return -ENOMEM;
2344 #if 0
2345 scrn[1] = '\0';
2346 #endif
2348 show_version();
2350 /* Has "console=0,9600n8" been used in bootinfo to change speed? */
2351 if (serial_console_cflag)
2352 DefSpeed = serial_console_cflag & 0017;
2353 else {
2354 DefSpeed = initial_console_speed;
2355 serial_console_info = &cy_port[0];
2356 serial_console_cflag = DefSpeed | CS8;
2357 #if 0
2358 serial_console = 64; /*callout_driver.minor_start*/
2359 #endif
2362 /* Initialize the tty_driver structure */
2364 cy_serial_driver->owner = THIS_MODULE;
2365 cy_serial_driver->devfs_name = "tts/";
2366 cy_serial_driver->name = "ttyS";
2367 cy_serial_driver->major = TTY_MAJOR;
2368 cy_serial_driver->minor_start = 64;
2369 cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
2370 cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
2371 cy_serial_driver->init_termios = tty_std_termios;
2372 cy_serial_driver->init_termios.c_cflag =
2373 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2374 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
2375 tty_set_operations(cy_serial_driver, &cy_ops);
2377 ret = tty_register_driver(cy_serial_driver);
2378 if (ret) {
2379 printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
2380 put_tty_driver(cy_serial_driver);
2381 return ret;
2384 init_bh(CYCLADES_BH, do_cyclades_bh);
2386 port_num = 0;
2387 info = cy_port;
2388 for (index = 0; index < 1; index++) {
2390 good_ports = 4;
2392 if(port_num < NR_PORTS){
2393 while( good_ports-- && port_num < NR_PORTS){
2394 /*** initialize port ***/
2395 info->magic = CYCLADES_MAGIC;
2396 info->type = PORT_CIRRUS;
2397 info->card = index;
2398 info->line = port_num;
2399 info->flags = STD_COM_FLAGS;
2400 info->tty = 0;
2401 info->xmit_fifo_size = 12;
2402 info->cor1 = CyPARITY_NONE|Cy_8_BITS;
2403 info->cor2 = CyETC;
2404 info->cor3 = Cy_1_STOP;
2405 info->cor4 = 0x08; /* _very_ small receive threshold */
2406 info->cor5 = 0;
2407 info->cor6 = 0;
2408 info->cor7 = 0;
2409 info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */
2410 info->tco = baud_co[DefSpeed]; /* Tx CO */
2411 info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */
2412 info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */
2413 info->close_delay = 0;
2414 info->x_char = 0;
2415 info->event = 0;
2416 info->count = 0;
2417 #ifdef SERIAL_DEBUG_COUNT
2418 printk("cyc: %d: setting count to 0\n", __LINE__);
2419 #endif
2420 info->blocked_open = 0;
2421 info->default_threshold = 0;
2422 info->default_timeout = 0;
2423 info->tqueue.routine = do_softint;
2424 info->tqueue.data = info;
2425 init_waitqueue_head(&info->open_wait);
2426 init_waitqueue_head(&info->close_wait);
2427 /* info->session */
2428 /* info->pgrp */
2429 /*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/
2430 info->read_status_mask = CyTIMEOUT| CySPECHAR| CyBREAK
2431 | CyPARITY| CyFRAME| CyOVERRUN;
2432 /* info->timeout */
2434 printk("ttyS%1d ", info->line);
2435 port_num++;info++;
2436 if(!(port_num & 7)){
2437 printk("\n ");
2441 printk("\n");
2443 while( port_num < NR_PORTS){
2444 info->line = -1;
2445 port_num++;info++;
2447 #ifdef CONFIG_REMOTE_DEBUG
2448 debug_setup();
2449 #endif
2450 ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
2451 "cd2401_errors", cd2401_rxerr_interrupt);
2452 if (ret) {
2453 printk(KERN_ERR "Could't get cd2401_errors IRQ");
2454 goto cleanup_serial_driver;
2457 ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
2458 "cd2401_modem", cd2401_modem_interrupt);
2459 if (ret) {
2460 printk(KERN_ERR "Could't get cd2401_modem IRQ");
2461 goto cleanup_irq_cd2401_errors;
2464 ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
2465 "cd2401_txints", cd2401_tx_interrupt);
2466 if (ret) {
2467 printk(KERN_ERR "Could't get cd2401_txints IRQ");
2468 goto cleanup_irq_cd2401_modem;
2471 ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
2472 "cd2401_rxints", cd2401_rx_interrupt);
2473 if (ret) {
2474 printk(KERN_ERR "Could't get cd2401_rxints IRQ");
2475 goto cleanup_irq_cd2401_txints;
2478 /* Now we have registered the interrupt handlers, allow the interrupts */
2480 pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */
2481 pcc2chip[PccSCCTICR] = 0x15;
2482 pcc2chip[PccSCCRICR] = 0x15;
2484 pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */
2486 return 0;
2487 cleanup_irq_cd2401_txints:
2488 free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt);
2489 cleanup_irq_cd2401_modem:
2490 free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
2491 cleanup_irq_cd2401_errors:
2492 free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
2493 cleanup_serial_driver:
2494 if (tty_unregister_driver(cy_serial_driver))
2495 printk(KERN_ERR "Couldn't unregister MVME166/7 serial driver\n");
2496 put_tty_driver(cy_serial_driver);
2497 return ret;
2498 } /* serial167_init */
2501 #ifdef CYCLOM_SHOW_STATUS
2502 static void
2503 show_status(int line_num)
2505 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2506 int channel;
2507 struct cyclades_port * info;
2508 unsigned long flags;
2510 info = &cy_port[line_num];
2511 channel = info->line;
2512 printk(" channel %d\n", channel);/**/
2514 printk(" cy_port\n");
2515 printk(" card line flags = %d %d %x\n",
2516 info->card, info->line, info->flags);
2517 printk(" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
2518 (long)info->tty, info->read_status_mask,
2519 info->timeout, info->xmit_fifo_size);
2520 printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n",
2521 info->cor1, info->cor2, info->cor3, info->cor4, info->cor5,
2522 info->cor6, info->cor7);
2523 printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n",
2524 info->tbpr, info->tco, info->rbpr, info->rco);
2525 printk(" close_delay event count = %d %d %d\n",
2526 info->close_delay, info->event, info->count);
2527 printk(" x_char blocked_open = %x %x\n",
2528 info->x_char, info->blocked_open);
2529 printk(" open_wait = %lx %lx %lx\n",
2530 (long)info->open_wait);
2533 local_irq_save(flags);
2535 /* Global Registers */
2537 printk(" CyGFRCR %x\n", base_addr[CyGFRCR]);
2538 printk(" CyCAR %x\n", base_addr[CyCAR]);
2539 printk(" CyRISR %x\n", base_addr[CyRISR]);
2540 printk(" CyTISR %x\n", base_addr[CyTISR]);
2541 printk(" CyMISR %x\n", base_addr[CyMISR]);
2542 printk(" CyRIR %x\n", base_addr[CyRIR]);
2543 printk(" CyTIR %x\n", base_addr[CyTIR]);
2544 printk(" CyMIR %x\n", base_addr[CyMIR]);
2545 printk(" CyTPR %x\n", base_addr[CyTPR]);
2547 base_addr[CyCAR] = (u_char)channel;
2549 /* Virtual Registers */
2551 #if 0
2552 printk(" CyRIVR %x\n", base_addr[CyRIVR]);
2553 printk(" CyTIVR %x\n", base_addr[CyTIVR]);
2554 printk(" CyMIVR %x\n", base_addr[CyMIVR]);
2555 printk(" CyMISR %x\n", base_addr[CyMISR]);
2556 #endif
2558 /* Channel Registers */
2560 printk(" CyCCR %x\n", base_addr[CyCCR]);
2561 printk(" CyIER %x\n", base_addr[CyIER]);
2562 printk(" CyCOR1 %x\n", base_addr[CyCOR1]);
2563 printk(" CyCOR2 %x\n", base_addr[CyCOR2]);
2564 printk(" CyCOR3 %x\n", base_addr[CyCOR3]);
2565 printk(" CyCOR4 %x\n", base_addr[CyCOR4]);
2566 printk(" CyCOR5 %x\n", base_addr[CyCOR5]);
2567 #if 0
2568 printk(" CyCCSR %x\n", base_addr[CyCCSR]);
2569 printk(" CyRDCR %x\n", base_addr[CyRDCR]);
2570 #endif
2571 printk(" CySCHR1 %x\n", base_addr[CySCHR1]);
2572 printk(" CySCHR2 %x\n", base_addr[CySCHR2]);
2573 #if 0
2574 printk(" CySCHR3 %x\n", base_addr[CySCHR3]);
2575 printk(" CySCHR4 %x\n", base_addr[CySCHR4]);
2576 printk(" CySCRL %x\n", base_addr[CySCRL]);
2577 printk(" CySCRH %x\n", base_addr[CySCRH]);
2578 printk(" CyLNC %x\n", base_addr[CyLNC]);
2579 printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]);
2580 printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]);
2581 #endif
2582 printk(" CyRTPRL %x\n", base_addr[CyRTPRL]);
2583 printk(" CyRTPRH %x\n", base_addr[CyRTPRH]);
2584 printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]);
2585 printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]);
2586 printk(" CyRBPR %x\n", base_addr[CyRBPR]);
2587 printk(" CyRCOR %x\n", base_addr[CyRCOR]);
2588 printk(" CyTBPR %x\n", base_addr[CyTBPR]);
2589 printk(" CyTCOR %x\n", base_addr[CyTCOR]);
2591 local_irq_restore(flags);
2592 } /* show_status */
2593 #endif
2596 #if 0
2597 /* Dummy routine in mvme16x/config.c for now */
2599 /* Serial console setup. Called from linux/init/main.c */
2601 void console_setup(char *str, int *ints)
2603 char *s;
2604 int baud, bits, parity;
2605 int cflag = 0;
2607 /* Sanity check. */
2608 if (ints[0] > 3 || ints[1] > 3) return;
2610 /* Get baud, bits and parity */
2611 baud = 2400;
2612 bits = 8;
2613 parity = 'n';
2614 if (ints[2]) baud = ints[2];
2615 if ((s = strchr(str, ','))) {
2616 do {
2617 s++;
2618 } while(*s >= '0' && *s <= '9');
2619 if (*s) parity = *s++;
2620 if (*s) bits = *s - '0';
2623 /* Now construct a cflag setting. */
2624 switch(baud) {
2625 case 1200:
2626 cflag |= B1200;
2627 break;
2628 case 9600:
2629 cflag |= B9600;
2630 break;
2631 case 19200:
2632 cflag |= B19200;
2633 break;
2634 case 38400:
2635 cflag |= B38400;
2636 break;
2637 case 2400:
2638 default:
2639 cflag |= B2400;
2640 break;
2642 switch(bits) {
2643 case 7:
2644 cflag |= CS7;
2645 break;
2646 default:
2647 case 8:
2648 cflag |= CS8;
2649 break;
2651 switch(parity) {
2652 case 'o': case 'O':
2653 cflag |= PARODD;
2654 break;
2655 case 'e': case 'E':
2656 cflag |= PARENB;
2657 break;
2660 serial_console_info = &cy_port[ints[1]];
2661 serial_console_cflag = cflag;
2662 serial_console = ints[1] + 64; /*callout_driver.minor_start*/
2664 #endif
2667 * The following is probably out of date for 2.1.x serial console stuff.
2669 * The console is registered early on from arch/m68k/kernel/setup.c, and
2670 * it therefore relies on the chip being setup correctly by 166-Bug. This
2671 * seems reasonable, as the serial port has been used to invoke the system
2672 * boot. It also means that this function must not rely on any data
2673 * initialisation performed by serial167_init() etc.
2675 * Of course, once the console has been registered, we had better ensure
2676 * that serial167_init() doesn't leave the chip non-functional.
2678 * The console must be locked when we get here.
2681 void serial167_console_write(struct console *co, const char *str, unsigned count)
2683 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2684 unsigned long flags;
2685 volatile u_char sink;
2686 u_char ier;
2687 int port;
2688 u_char do_lf = 0;
2689 int i = 0;
2691 local_irq_save(flags);
2693 /* Ensure transmitter is enabled! */
2695 port = 0;
2696 base_addr[CyCAR] = (u_char)port;
2697 while (base_addr[CyCCR])
2699 base_addr[CyCCR] = CyENB_XMTR;
2701 ier = base_addr[CyIER];
2702 base_addr[CyIER] = CyTxMpty;
2704 while (1) {
2705 if (pcc2chip[PccSCCTICR] & 0x20)
2707 /* We have a Tx int. Acknowledge it */
2708 sink = pcc2chip[PccTPIACKR];
2709 if ((base_addr[CyLICR] >> 2) == port) {
2710 if (i == count) {
2711 /* Last char of string is now output */
2712 base_addr[CyTEOIR] = CyNOTRANS;
2713 break;
2715 if (do_lf) {
2716 base_addr[CyTDR] = '\n';
2717 str++;
2718 i++;
2719 do_lf = 0;
2721 else if (*str == '\n') {
2722 base_addr[CyTDR] = '\r';
2723 do_lf = 1;
2725 else {
2726 base_addr[CyTDR] = *str++;
2727 i++;
2729 base_addr[CyTEOIR] = 0;
2731 else
2732 base_addr[CyTEOIR] = CyNOTRANS;
2736 base_addr[CyIER] = ier;
2738 local_irq_restore(flags);
2741 static struct tty_driver *serial167_console_device(struct console *c, int *index)
2743 *index = c->index;
2744 return cy_serial_driver;
2748 static int __init serial167_console_setup(struct console *co, char *options)
2750 return 0;
2754 static struct console sercons = {
2755 .name = "ttyS",
2756 .write = serial167_console_write,
2757 .device = serial167_console_device,
2758 .setup = serial167_console_setup,
2759 .flags = CON_PRINTBUFFER,
2760 .index = -1,
2764 static int __init serial167_console_init(void)
2766 if (vme_brdtype == VME_TYPE_MVME166 ||
2767 vme_brdtype == VME_TYPE_MVME167 ||
2768 vme_brdtype == VME_TYPE_MVME177) {
2769 mvme167_serial_console_setup(0);
2770 register_console(&sercons);
2772 return 0;
2774 console_initcall(serial167_console_init);
2776 #ifdef CONFIG_REMOTE_DEBUG
2777 void putDebugChar (int c)
2779 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2780 unsigned long flags;
2781 volatile u_char sink;
2782 u_char ier;
2783 int port;
2785 local_irq_save(flags);
2787 /* Ensure transmitter is enabled! */
2789 port = DEBUG_PORT;
2790 base_addr[CyCAR] = (u_char)port;
2791 while (base_addr[CyCCR])
2793 base_addr[CyCCR] = CyENB_XMTR;
2795 ier = base_addr[CyIER];
2796 base_addr[CyIER] = CyTxMpty;
2798 while (1) {
2799 if (pcc2chip[PccSCCTICR] & 0x20)
2801 /* We have a Tx int. Acknowledge it */
2802 sink = pcc2chip[PccTPIACKR];
2803 if ((base_addr[CyLICR] >> 2) == port) {
2804 base_addr[CyTDR] = c;
2805 base_addr[CyTEOIR] = 0;
2806 break;
2808 else
2809 base_addr[CyTEOIR] = CyNOTRANS;
2813 base_addr[CyIER] = ier;
2815 local_irq_restore(flags);
2818 int getDebugChar()
2820 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2821 unsigned long flags;
2822 volatile u_char sink;
2823 u_char ier;
2824 int port;
2825 int i, c;
2827 i = debugiq.out;
2828 if (i != debugiq.in) {
2829 c = debugiq.buf[i];
2830 if (++i == DEBUG_LEN)
2831 i = 0;
2832 debugiq.out = i;
2833 return c;
2835 /* OK, nothing in queue, wait in poll loop */
2837 local_irq_save(flags);
2839 /* Ensure receiver is enabled! */
2841 port = DEBUG_PORT;
2842 base_addr[CyCAR] = (u_char)port;
2843 #if 0
2844 while (base_addr[CyCCR])
2846 base_addr[CyCCR] = CyENB_RCVR;
2847 #endif
2848 ier = base_addr[CyIER];
2849 base_addr[CyIER] = CyRxData;
2851 while (1) {
2852 if (pcc2chip[PccSCCRICR] & 0x20)
2854 /* We have a Rx int. Acknowledge it */
2855 sink = pcc2chip[PccRPIACKR];
2856 if ((base_addr[CyLICR] >> 2) == port) {
2857 int cnt = base_addr[CyRFOC];
2858 while (cnt-- > 0)
2860 c = base_addr[CyRDR];
2861 if (c == 0)
2862 printk ("!! debug char is null (cnt=%d) !!", cnt);
2863 else
2864 queueDebugChar (c);
2866 base_addr[CyREOIR] = 0;
2867 i = debugiq.out;
2868 if (i == debugiq.in)
2869 panic ("Debug input queue empty!");
2870 c = debugiq.buf[i];
2871 if (++i == DEBUG_LEN)
2872 i = 0;
2873 debugiq.out = i;
2874 break;
2876 else
2877 base_addr[CyREOIR] = CyNOTRANS;
2881 base_addr[CyIER] = ier;
2883 local_irq_restore(flags);
2885 return (c);
2888 void queueDebugChar (int c)
2890 int i;
2892 i = debugiq.in;
2893 debugiq.buf[i] = c;
2894 if (++i == DEBUG_LEN)
2895 i = 0;
2896 if (i != debugiq.out)
2897 debugiq.in = i;
2900 static void
2901 debug_setup()
2903 unsigned long flags;
2904 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2905 int i, cflag;
2907 cflag = B19200;
2909 local_irq_save(flags);
2911 for (i = 0; i < 4; i++)
2913 base_addr[CyCAR] = i;
2914 base_addr[CyLICR] = i << 2;
2917 debugiq.in = debugiq.out = 0;
2919 base_addr[CyCAR] = DEBUG_PORT;
2921 /* baud rate */
2922 i = cflag & CBAUD;
2924 base_addr[CyIER] = 0;
2926 base_addr[CyCMR] = CyASYNC;
2927 base_addr[CyLICR] = DEBUG_PORT << 2;
2928 base_addr[CyLIVR] = 0x5c;
2930 /* tx and rx baud rate */
2932 base_addr[CyTCOR] = baud_co[i];
2933 base_addr[CyTBPR] = baud_bpr[i];
2934 base_addr[CyRCOR] = baud_co[i] >> 5;
2935 base_addr[CyRBPR] = baud_bpr[i];
2937 /* set line characteristics according configuration */
2939 base_addr[CySCHR1] = 0;
2940 base_addr[CySCHR2] = 0;
2941 base_addr[CySCRL] = 0;
2942 base_addr[CySCRH] = 0;
2943 base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
2944 base_addr[CyCOR2] = 0;
2945 base_addr[CyCOR3] = Cy_1_STOP;
2946 base_addr[CyCOR4] = baud_cor4[i];
2947 base_addr[CyCOR5] = 0;
2948 base_addr[CyCOR6] = 0;
2949 base_addr[CyCOR7] = 0;
2951 write_cy_cmd(base_addr,CyINIT_CHAN);
2952 write_cy_cmd(base_addr,CyENB_RCVR);
2954 base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */
2956 base_addr[CyRTPRL] = 2;
2957 base_addr[CyRTPRH] = 0;
2959 base_addr[CyMSVR1] = CyRTS;
2960 base_addr[CyMSVR2] = CyDTR;
2962 base_addr[CyIER] = CyRxData;
2964 local_irq_restore(flags);
2966 } /* debug_setup */
2968 #endif
2970 MODULE_LICENSE("GPL");