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