blob: 037c940ac71b8bb10b4dd2788aff141980ddba63 [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;
2238 cy_serial_driver->devfs_name = "tts/";
2239 cy_serial_driver->name = "ttyS";
2240 cy_serial_driver->major = TTY_MAJOR;
2241 cy_serial_driver->minor_start = 64;
2242 cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
2243 cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
2244 cy_serial_driver->init_termios = tty_std_termios;
2245 cy_serial_driver->init_termios.c_cflag =
2246 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2247 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
2248 tty_set_operations(cy_serial_driver, &cy_ops);
2249
2250 ret = tty_register_driver(cy_serial_driver);
2251 if (ret) {
2252 printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
2253 put_tty_driver(cy_serial_driver);
2254 return ret;
2255 }
2256
2257 port_num = 0;
2258 info = cy_port;
2259 for (index = 0; index < 1; index++) {
2260
2261 good_ports = 4;
2262
2263 if(port_num < NR_PORTS){
2264 while( good_ports-- && port_num < NR_PORTS){
2265 /*** initialize port ***/
2266 info->magic = CYCLADES_MAGIC;
2267 info->type = PORT_CIRRUS;
2268 info->card = index;
2269 info->line = port_num;
2270 info->flags = STD_COM_FLAGS;
2271 info->tty = 0;
2272 info->xmit_fifo_size = 12;
2273 info->cor1 = CyPARITY_NONE|Cy_8_BITS;
2274 info->cor2 = CyETC;
2275 info->cor3 = Cy_1_STOP;
2276 info->cor4 = 0x08; /* _very_ small receive threshold */
2277 info->cor5 = 0;
2278 info->cor6 = 0;
2279 info->cor7 = 0;
2280 info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */
2281 info->tco = baud_co[DefSpeed]; /* Tx CO */
2282 info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */
2283 info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */
2284 info->close_delay = 0;
2285 info->x_char = 0;
2286 info->event = 0;
2287 info->count = 0;
2288#ifdef SERIAL_DEBUG_COUNT
2289 printk("cyc: %d: setting count to 0\n", __LINE__);
2290#endif
2291 info->blocked_open = 0;
2292 info->default_threshold = 0;
2293 info->default_timeout = 0;
2294 INIT_WORK(&info->tqueue, do_softint, info);
2295 init_waitqueue_head(&info->open_wait);
2296 init_waitqueue_head(&info->close_wait);
2297 /* info->session */
2298 /* info->pgrp */
2299/*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/
2300 info->read_status_mask = CyTIMEOUT| CySPECHAR| CyBREAK
2301 | CyPARITY| CyFRAME| CyOVERRUN;
2302 /* info->timeout */
2303
2304 printk("ttyS%d ", info->line);
2305 port_num++;info++;
2306 if(!(port_num & 7)){
2307 printk("\n ");
2308 }
2309 }
2310 }
2311 printk("\n");
2312 }
2313 while( port_num < NR_PORTS){
2314 info->line = -1;
2315 port_num++;info++;
2316 }
2317#ifdef CONFIG_REMOTE_DEBUG
2318 debug_setup();
2319#endif
2320 ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
2321 "cd2401_errors", cd2401_rxerr_interrupt);
2322 if (ret) {
2323 printk(KERN_ERR "Could't get cd2401_errors IRQ");
2324 goto cleanup_serial_driver;
2325 }
2326
2327 ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
2328 "cd2401_modem", cd2401_modem_interrupt);
2329 if (ret) {
2330 printk(KERN_ERR "Could't get cd2401_modem IRQ");
2331 goto cleanup_irq_cd2401_errors;
2332 }
2333
2334 ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
2335 "cd2401_txints", cd2401_tx_interrupt);
2336 if (ret) {
2337 printk(KERN_ERR "Could't get cd2401_txints IRQ");
2338 goto cleanup_irq_cd2401_modem;
2339 }
2340
2341 ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
2342 "cd2401_rxints", cd2401_rx_interrupt);
2343 if (ret) {
2344 printk(KERN_ERR "Could't get cd2401_rxints IRQ");
2345 goto cleanup_irq_cd2401_txints;
2346 }
2347
2348 /* Now we have registered the interrupt handlers, allow the interrupts */
2349
2350 pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */
2351 pcc2chip[PccSCCTICR] = 0x15;
2352 pcc2chip[PccSCCRICR] = 0x15;
2353
2354 pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */
2355
2356 return 0;
2357cleanup_irq_cd2401_txints:
2358 free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt);
2359cleanup_irq_cd2401_modem:
2360 free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
2361cleanup_irq_cd2401_errors:
2362 free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
2363cleanup_serial_driver:
2364 if (tty_unregister_driver(cy_serial_driver))
2365 printk(KERN_ERR "Couldn't unregister MVME166/7 serial driver\n");
2366 put_tty_driver(cy_serial_driver);
2367 return ret;
2368} /* serial167_init */
2369
2370module_init(serial167_init);
2371
2372
2373#ifdef CYCLOM_SHOW_STATUS
2374static void
2375show_status(int line_num)
2376{
2377 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2378 int channel;
2379 struct cyclades_port * info;
2380 unsigned long flags;
2381
2382 info = &cy_port[line_num];
2383 channel = info->line;
2384 printk(" channel %d\n", channel);/**/
2385
2386 printk(" cy_port\n");
2387 printk(" card line flags = %d %d %x\n",
2388 info->card, info->line, info->flags);
2389 printk(" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
2390 (long)info->tty, info->read_status_mask,
2391 info->timeout, info->xmit_fifo_size);
2392 printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n",
2393 info->cor1, info->cor2, info->cor3, info->cor4, info->cor5,
2394 info->cor6, info->cor7);
2395 printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n",
2396 info->tbpr, info->tco, info->rbpr, info->rco);
2397 printk(" close_delay event count = %d %d %d\n",
2398 info->close_delay, info->event, info->count);
2399 printk(" x_char blocked_open = %x %x\n",
2400 info->x_char, info->blocked_open);
2401 printk(" open_wait = %lx %lx %lx\n",
2402 (long)info->open_wait);
2403
2404
2405 local_irq_save(flags);
2406
2407/* Global Registers */
2408
2409 printk(" CyGFRCR %x\n", base_addr[CyGFRCR]);
2410 printk(" CyCAR %x\n", base_addr[CyCAR]);
2411 printk(" CyRISR %x\n", base_addr[CyRISR]);
2412 printk(" CyTISR %x\n", base_addr[CyTISR]);
2413 printk(" CyMISR %x\n", base_addr[CyMISR]);
2414 printk(" CyRIR %x\n", base_addr[CyRIR]);
2415 printk(" CyTIR %x\n", base_addr[CyTIR]);
2416 printk(" CyMIR %x\n", base_addr[CyMIR]);
2417 printk(" CyTPR %x\n", base_addr[CyTPR]);
2418
2419 base_addr[CyCAR] = (u_char)channel;
2420
2421/* Virtual Registers */
2422
2423#if 0
2424 printk(" CyRIVR %x\n", base_addr[CyRIVR]);
2425 printk(" CyTIVR %x\n", base_addr[CyTIVR]);
2426 printk(" CyMIVR %x\n", base_addr[CyMIVR]);
2427 printk(" CyMISR %x\n", base_addr[CyMISR]);
2428#endif
2429
2430/* Channel Registers */
2431
2432 printk(" CyCCR %x\n", base_addr[CyCCR]);
2433 printk(" CyIER %x\n", base_addr[CyIER]);
2434 printk(" CyCOR1 %x\n", base_addr[CyCOR1]);
2435 printk(" CyCOR2 %x\n", base_addr[CyCOR2]);
2436 printk(" CyCOR3 %x\n", base_addr[CyCOR3]);
2437 printk(" CyCOR4 %x\n", base_addr[CyCOR4]);
2438 printk(" CyCOR5 %x\n", base_addr[CyCOR5]);
2439#if 0
2440 printk(" CyCCSR %x\n", base_addr[CyCCSR]);
2441 printk(" CyRDCR %x\n", base_addr[CyRDCR]);
2442#endif
2443 printk(" CySCHR1 %x\n", base_addr[CySCHR1]);
2444 printk(" CySCHR2 %x\n", base_addr[CySCHR2]);
2445#if 0
2446 printk(" CySCHR3 %x\n", base_addr[CySCHR3]);
2447 printk(" CySCHR4 %x\n", base_addr[CySCHR4]);
2448 printk(" CySCRL %x\n", base_addr[CySCRL]);
2449 printk(" CySCRH %x\n", base_addr[CySCRH]);
2450 printk(" CyLNC %x\n", base_addr[CyLNC]);
2451 printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]);
2452 printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]);
2453#endif
2454 printk(" CyRTPRL %x\n", base_addr[CyRTPRL]);
2455 printk(" CyRTPRH %x\n", base_addr[CyRTPRH]);
2456 printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]);
2457 printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]);
2458 printk(" CyRBPR %x\n", base_addr[CyRBPR]);
2459 printk(" CyRCOR %x\n", base_addr[CyRCOR]);
2460 printk(" CyTBPR %x\n", base_addr[CyTBPR]);
2461 printk(" CyTCOR %x\n", base_addr[CyTCOR]);
2462
2463 local_irq_restore(flags);
2464} /* show_status */
2465#endif
2466
2467
2468#if 0
2469/* Dummy routine in mvme16x/config.c for now */
2470
2471/* Serial console setup. Called from linux/init/main.c */
2472
2473void console_setup(char *str, int *ints)
2474{
2475 char *s;
2476 int baud, bits, parity;
2477 int cflag = 0;
2478
2479 /* Sanity check. */
2480 if (ints[0] > 3 || ints[1] > 3) return;
2481
2482 /* Get baud, bits and parity */
2483 baud = 2400;
2484 bits = 8;
2485 parity = 'n';
2486 if (ints[2]) baud = ints[2];
2487 if ((s = strchr(str, ','))) {
2488 do {
2489 s++;
2490 } while(*s >= '0' && *s <= '9');
2491 if (*s) parity = *s++;
2492 if (*s) bits = *s - '0';
2493 }
2494
2495 /* Now construct a cflag setting. */
2496 switch(baud) {
2497 case 1200:
2498 cflag |= B1200;
2499 break;
2500 case 9600:
2501 cflag |= B9600;
2502 break;
2503 case 19200:
2504 cflag |= B19200;
2505 break;
2506 case 38400:
2507 cflag |= B38400;
2508 break;
2509 case 2400:
2510 default:
2511 cflag |= B2400;
2512 break;
2513 }
2514 switch(bits) {
2515 case 7:
2516 cflag |= CS7;
2517 break;
2518 default:
2519 case 8:
2520 cflag |= CS8;
2521 break;
2522 }
2523 switch(parity) {
2524 case 'o': case 'O':
2525 cflag |= PARODD;
2526 break;
2527 case 'e': case 'E':
2528 cflag |= PARENB;
2529 break;
2530 }
2531
2532 serial_console_info = &cy_port[ints[1]];
2533 serial_console_cflag = cflag;
2534 serial_console = ints[1] + 64; /*callout_driver.minor_start*/
2535}
2536#endif
2537
2538/*
2539 * The following is probably out of date for 2.1.x serial console stuff.
2540 *
2541 * The console is registered early on from arch/m68k/kernel/setup.c, and
2542 * it therefore relies on the chip being setup correctly by 166-Bug. This
2543 * seems reasonable, as the serial port has been used to invoke the system
2544 * boot. It also means that this function must not rely on any data
2545 * initialisation performed by serial167_init() etc.
2546 *
2547 * Of course, once the console has been registered, we had better ensure
2548 * that serial167_init() doesn't leave the chip non-functional.
2549 *
2550 * The console must be locked when we get here.
2551 */
2552
2553void serial167_console_write(struct console *co, const char *str, unsigned count)
2554{
2555 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2556 unsigned long flags;
2557 volatile u_char sink;
2558 u_char ier;
2559 int port;
2560 u_char do_lf = 0;
2561 int i = 0;
2562
2563 local_irq_save(flags);
2564
2565 /* Ensure transmitter is enabled! */
2566
2567 port = 0;
2568 base_addr[CyCAR] = (u_char)port;
2569 while (base_addr[CyCCR])
2570 ;
2571 base_addr[CyCCR] = CyENB_XMTR;
2572
2573 ier = base_addr[CyIER];
2574 base_addr[CyIER] = CyTxMpty;
2575
2576 while (1) {
2577 if (pcc2chip[PccSCCTICR] & 0x20)
2578 {
2579 /* We have a Tx int. Acknowledge it */
2580 sink = pcc2chip[PccTPIACKR];
2581 if ((base_addr[CyLICR] >> 2) == port) {
2582 if (i == count) {
2583 /* Last char of string is now output */
2584 base_addr[CyTEOIR] = CyNOTRANS;
2585 break;
2586 }
2587 if (do_lf) {
2588 base_addr[CyTDR] = '\n';
2589 str++;
2590 i++;
2591 do_lf = 0;
2592 }
2593 else if (*str == '\n') {
2594 base_addr[CyTDR] = '\r';
2595 do_lf = 1;
2596 }
2597 else {
2598 base_addr[CyTDR] = *str++;
2599 i++;
2600 }
2601 base_addr[CyTEOIR] = 0;
2602 }
2603 else
2604 base_addr[CyTEOIR] = CyNOTRANS;
2605 }
2606 }
2607
2608 base_addr[CyIER] = ier;
2609
2610 local_irq_restore(flags);
2611}
2612
2613static struct tty_driver *serial167_console_device(struct console *c, int *index)
2614{
2615 *index = c->index;
2616 return cy_serial_driver;
2617}
2618
2619
2620static int __init serial167_console_setup(struct console *co, char *options)
2621{
2622 return 0;
2623}
2624
2625
2626static struct console sercons = {
2627 .name = "ttyS",
2628 .write = serial167_console_write,
2629 .device = serial167_console_device,
2630 .setup = serial167_console_setup,
2631 .flags = CON_PRINTBUFFER,
2632 .index = -1,
2633};
2634
2635
2636static int __init serial167_console_init(void)
2637{
2638 if (vme_brdtype == VME_TYPE_MVME166 ||
2639 vme_brdtype == VME_TYPE_MVME167 ||
2640 vme_brdtype == VME_TYPE_MVME177) {
2641 mvme167_serial_console_setup(0);
2642 register_console(&sercons);
2643 }
2644 return 0;
2645}
2646console_initcall(serial167_console_init);
2647
2648#ifdef CONFIG_REMOTE_DEBUG
2649void putDebugChar (int c)
2650{
2651 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2652 unsigned long flags;
2653 volatile u_char sink;
2654 u_char ier;
2655 int port;
2656
2657 local_irq_save(flags);
2658
2659 /* Ensure transmitter is enabled! */
2660
2661 port = DEBUG_PORT;
2662 base_addr[CyCAR] = (u_char)port;
2663 while (base_addr[CyCCR])
2664 ;
2665 base_addr[CyCCR] = CyENB_XMTR;
2666
2667 ier = base_addr[CyIER];
2668 base_addr[CyIER] = CyTxMpty;
2669
2670 while (1) {
2671 if (pcc2chip[PccSCCTICR] & 0x20)
2672 {
2673 /* We have a Tx int. Acknowledge it */
2674 sink = pcc2chip[PccTPIACKR];
2675 if ((base_addr[CyLICR] >> 2) == port) {
2676 base_addr[CyTDR] = c;
2677 base_addr[CyTEOIR] = 0;
2678 break;
2679 }
2680 else
2681 base_addr[CyTEOIR] = CyNOTRANS;
2682 }
2683 }
2684
2685 base_addr[CyIER] = ier;
2686
2687 local_irq_restore(flags);
2688}
2689
2690int getDebugChar()
2691{
2692 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2693 unsigned long flags;
2694 volatile u_char sink;
2695 u_char ier;
2696 int port;
2697 int i, c;
2698
2699 i = debugiq.out;
2700 if (i != debugiq.in) {
2701 c = debugiq.buf[i];
2702 if (++i == DEBUG_LEN)
2703 i = 0;
2704 debugiq.out = i;
2705 return c;
2706 }
2707 /* OK, nothing in queue, wait in poll loop */
2708
2709 local_irq_save(flags);
2710
2711 /* Ensure receiver is enabled! */
2712
2713 port = DEBUG_PORT;
2714 base_addr[CyCAR] = (u_char)port;
2715#if 0
2716 while (base_addr[CyCCR])
2717 ;
2718 base_addr[CyCCR] = CyENB_RCVR;
2719#endif
2720 ier = base_addr[CyIER];
2721 base_addr[CyIER] = CyRxData;
2722
2723 while (1) {
2724 if (pcc2chip[PccSCCRICR] & 0x20)
2725 {
2726 /* We have a Rx int. Acknowledge it */
2727 sink = pcc2chip[PccRPIACKR];
2728 if ((base_addr[CyLICR] >> 2) == port) {
2729 int cnt = base_addr[CyRFOC];
2730 while (cnt-- > 0)
2731 {
2732 c = base_addr[CyRDR];
2733 if (c == 0)
2734 printk ("!! debug char is null (cnt=%d) !!", cnt);
2735 else
2736 queueDebugChar (c);
2737 }
2738 base_addr[CyREOIR] = 0;
2739 i = debugiq.out;
2740 if (i == debugiq.in)
2741 panic ("Debug input queue empty!");
2742 c = debugiq.buf[i];
2743 if (++i == DEBUG_LEN)
2744 i = 0;
2745 debugiq.out = i;
2746 break;
2747 }
2748 else
2749 base_addr[CyREOIR] = CyNOTRANS;
2750 }
2751 }
2752
2753 base_addr[CyIER] = ier;
2754
2755 local_irq_restore(flags);
2756
2757 return (c);
2758}
2759
2760void queueDebugChar (int c)
2761{
2762 int i;
2763
2764 i = debugiq.in;
2765 debugiq.buf[i] = c;
2766 if (++i == DEBUG_LEN)
2767 i = 0;
2768 if (i != debugiq.out)
2769 debugiq.in = i;
2770}
2771
2772static void
2773debug_setup()
2774{
2775 unsigned long flags;
2776 volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
2777 int i, cflag;
2778
2779 cflag = B19200;
2780
2781 local_irq_save(flags);
2782
2783 for (i = 0; i < 4; i++)
2784 {
2785 base_addr[CyCAR] = i;
2786 base_addr[CyLICR] = i << 2;
2787 }
2788
2789 debugiq.in = debugiq.out = 0;
2790
2791 base_addr[CyCAR] = DEBUG_PORT;
2792
2793 /* baud rate */
2794 i = cflag & CBAUD;
2795
2796 base_addr[CyIER] = 0;
2797
2798 base_addr[CyCMR] = CyASYNC;
2799 base_addr[CyLICR] = DEBUG_PORT << 2;
2800 base_addr[CyLIVR] = 0x5c;
2801
2802 /* tx and rx baud rate */
2803
2804 base_addr[CyTCOR] = baud_co[i];
2805 base_addr[CyTBPR] = baud_bpr[i];
2806 base_addr[CyRCOR] = baud_co[i] >> 5;
2807 base_addr[CyRBPR] = baud_bpr[i];
2808
2809 /* set line characteristics according configuration */
2810
2811 base_addr[CySCHR1] = 0;
2812 base_addr[CySCHR2] = 0;
2813 base_addr[CySCRL] = 0;
2814 base_addr[CySCRH] = 0;
2815 base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
2816 base_addr[CyCOR2] = 0;
2817 base_addr[CyCOR3] = Cy_1_STOP;
2818 base_addr[CyCOR4] = baud_cor4[i];
2819 base_addr[CyCOR5] = 0;
2820 base_addr[CyCOR6] = 0;
2821 base_addr[CyCOR7] = 0;
2822
2823 write_cy_cmd(base_addr,CyINIT_CHAN);
2824 write_cy_cmd(base_addr,CyENB_RCVR);
2825
2826 base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */
2827
2828 base_addr[CyRTPRL] = 2;
2829 base_addr[CyRTPRH] = 0;
2830
2831 base_addr[CyMSVR1] = CyRTS;
2832 base_addr[CyMSVR2] = CyDTR;
2833
2834 base_addr[CyIER] = CyRxData;
2835
2836 local_irq_restore(flags);
2837
2838} /* debug_setup */
2839
2840#endif
2841
2842MODULE_LICENSE("GPL");