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