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