This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / char / dz.c
1 /*
2  * dz.c: Serial port driver for DECStations equiped 
3  *       with the DZ chipset.
4  *
5  * Copyright (C) 1998 Olivier A. D. Lebaillif 
6  *             
7  * Email: olivier.lebaillif@ifrsys.com
8  *
9  * [31-AUG-98] triemer
10  * Changed IRQ to use Harald's dec internals interrupts.h
11  * removed base_addr code - moving address assignment to setup.c
12  * Changed name of dz_init to rs_init to be consistent with tc code
13  * [13-NOV-98] triemer fixed code to receive characters
14  *    after patches by harald to irq code.  
15  * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
16  *            field from "current" - somewhere between 2.1.121 and 2.1.131
17 Qua Jun 27 15:02:26 BRT 2001
18  * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
19  *  
20  * Parts (C) 1999 David Airlie, airlied@linux.ie 
21  * [07-SEP-99] Bugfixes 
22  */
23
24 /* #define DEBUG_DZ 1 */
25
26 #include <linux/module.h>
27
28 #include <linux/config.h>
29 #include <linux/kernel.h>
30 #include <linux/sched.h>
31 #include <linux/init.h> 
32 #include <linux/slab.h>
33 #include <linux/mm.h>
34 #include <linux/major.h>
35 #include <linux/param.h>
36 #include <linux/interrupt.h>
37 #include <linux/serial.h>
38 #include <linux/serialP.h>
39 #include <asm-mips/wbflush.h>
40 #include <asm/dec/interrupts.h>                 /* for definition of SERIAL */
41
42 /* for definition of struct console */
43 #ifdef CONFIG_SERIAL_CONSOLE
44 #define CONSOLE_LINE (3)
45 #endif /* ifdef CONFIG_SERIAL_CONSOLE */
46 #if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_DZ)
47 #include <linux/console.h>
48 #endif /* if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_DZ) */
49
50 #include <linux/tty.h>
51 #include <linux/tty_flip.h>
52
53 #include <asm/uaccess.h>
54 #include <asm/irq.h>
55 #include <asm/dec/machtype.h>
56 #include <asm/dec/kn01.h>
57 #include <asm/dec/kn02.h>
58
59 #ifdef DEBUG_DZ
60 #include <linux/ptrace.h>
61 #include <linux/fs.h>
62 #include <asm/bootinfo.h>
63
64 extern int (*prom_printf) (char *,...);
65 #endif
66
67
68
69 #include "dz.h"
70
71 #define DZ_INTR_DEBUG 1
72
73 DECLARE_TASK_QUEUE(tq_serial);
74
75 static struct dz_serial *lines[4];
76 static unsigned char tmp_buffer[256];
77
78
79
80 #ifdef DEBUG_DZ
81 /*
82  * debugging code to send out chars via prom 
83  */
84 static void debug_console( const char *s,int count)
85 {
86         unsigned i;
87
88         for (i = 0; i < count; i++) {
89                 if (*s == 10)
90                         prom_printf("%c", 13);
91                 prom_printf("%c", *s++);
92         }
93 }
94 #endif
95
96 /*
97  * ------------------------------------------------------------
98  * dz_in () and dz_out ()
99  *
100  * These routines are used to access the registers of the DZ 
101  * chip, hiding relocation differences between implementation.
102  * ------------------------------------------------------------
103  */
104
105 static inline unsigned short dz_in (struct dz_serial *info, unsigned offset)
106 {
107         volatile u16 *addr = (volatile u16 *)(info->port + offset);
108
109         return *addr;
110 }
111
112 static inline void dz_out (struct dz_serial *info, unsigned offset,
113                            unsigned short value)
114 {
115         volatile u16 *addr = (volatile u16 *)(info->port + offset);
116         *addr = value;
117 }
118
119 /*
120  * ------------------------------------------------------------
121  * rs_stop () and rs_start ()
122  *
123  * These routines are called before setting or resetting 
124  * tty->stopped. They enable or disable transmitter interrupts, 
125  * as necessary.
126  * ------------------------------------------------------------
127  */
128
129 static void dz_stop (struct tty_struct *tty)
130 {
131         struct dz_serial *info; 
132         unsigned short mask, tmp;
133
134         if (!tty) 
135                 return; 
136  
137         info = (struct dz_serial *)tty->driver_data; 
138
139         mask = 1 << info->line;
140         tmp = dz_in (info, DZ_TCR);       /* read the TX flag */
141
142         tmp &= ~mask;                   /* clear the TX flag */
143         dz_out (info, DZ_TCR, tmp);
144 }
145
146 static void dz_start (struct tty_struct *tty)
147 {
148         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
149         unsigned short mask, tmp;
150
151         mask = 1 << info->line;
152         tmp = dz_in (info, DZ_TCR);      /* read the TX flag */
153
154         tmp |= mask;                   /* set the TX flag */
155         dz_out (info, DZ_TCR, tmp);
156 }
157
158 /*
159  * ------------------------------------------------------------
160  * Here starts the interrupt handling routines.  All of the 
161  * following subroutines are declared as inline and are folded 
162  * into dz_interrupt.  They were separated out for readability's 
163  * sake. 
164  *
165  * Note: rs_interrupt() is a "fast" interrupt, which means that it
166  * runs with interrupts turned off.  People who may want to modify
167  * rs_interrupt() should try to keep the interrupt handler as fast as
168  * possible.  After you are done making modifications, it is not a bad
169  * idea to do:
170  * 
171  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer dz.c
172  *
173  * and look at the resulting assemble code in serial.s.
174  *
175  * ------------------------------------------------------------
176  */
177
178 /*
179  * ------------------------------------------------------------
180  * dz_sched_event ()
181  *
182  * This routine is used by the interrupt handler to schedule
183  * processing in the software interrupt portion of the driver.
184  * ------------------------------------------------------------
185  */
186 static inline void dz_sched_event (struct dz_serial *info, int event)
187 {
188         info->event |= 1 << event;
189         queue_task(&info->tqueue, &tq_serial);
190         mark_bh(SERIAL_BH);
191 }
192
193 /*
194  * ------------------------------------------------------------
195  * receive_char ()
196  *
197  * This routine deals with inputs from any lines.
198  * ------------------------------------------------------------
199  */
200 static inline void receive_chars (struct dz_serial *info_in)
201 {
202         struct dz_serial *info;
203         struct tty_struct *tty = 0;
204         struct async_icount *icount;
205         int ignore = 0;
206         unsigned short status, tmp;
207         unsigned char ch;
208
209         /*
210          * This code is going to be a problem...  the call to tty_flip_buffer
211          * is going to need to be rethought...
212          */
213         do {
214                 status = dz_in (info_in, DZ_RBUF);
215                 info = lines[LINE(status)];
216
217                 /* punt so we don't get duplicate characters */
218                 if (!(status & DZ_DVAL))
219                         goto ignore_char;
220
221                 ch = UCHAR(status);                     /* grab the char */
222
223 #if 0
224                 if (info->is_console) {
225                         if (ch == 0)
226                                 return;                 /* it's a break ... */
227                 }
228 #endif
229
230                 tty = info->tty;        /* now tty points to the proper dev */
231                 icount = &info->icount;
232
233                 if (!tty)
234                         break;
235                 if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
236
237                 *tty->flip.char_buf_ptr = ch;
238                 *tty->flip.flag_buf_ptr = 0;
239                 icount->rx++;
240
241                 /* keep track of the statistics */
242                 if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
243                         if (status & DZ_PERR)           /* parity error */
244                                 icount->parity++;
245                         else if (status & DZ_FERR)      /* frame error */
246                                 icount->frame++;
247                         if (status & DZ_OERR)           /* overrun error */
248                                 icount->overrun++;
249
250                         /*
251                          * Check to see if we should ignore the character and
252                          * mask off conditions that should be ignored
253                          */
254
255                         if (status & info->ignore_status_mask) {
256                                 if (++ignore > 100)
257                                         break;
258                                 goto ignore_char;
259                         }
260
261                         /* mask off the error conditions we want to ignore */
262                         tmp = status & info->read_status_mask;
263
264                         if (tmp & DZ_PERR) {
265                                 *tty->flip.flag_buf_ptr = TTY_PARITY;
266 #ifdef DEBUG_DZ
267                                 debug_console("PERR\n",5);
268 #endif /* DEBUG_DZ */
269                         } else if (tmp & DZ_FERR) {
270                                 *tty->flip.flag_buf_ptr = TTY_FRAME;
271 #ifdef DEBUG_DZ
272                                 debug_console("FERR\n",5);
273 #endif /* DEBUG_DZ */
274                         } if (tmp & DZ_OERR) { 
275 #ifdef DEBUG_DZ
276                                 debug_console("OERR\n",5);
277 #endif /* DEBUG_DZ */
278                                 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
279                                         tty->flip.count++;
280                                         tty->flip.flag_buf_ptr++;
281                                         tty->flip.char_buf_ptr++;
282                                         *tty->flip.flag_buf_ptr = TTY_OVERRUN;
283                                 }
284                         }
285                 }
286         tty->flip.flag_buf_ptr++;
287         tty->flip.char_buf_ptr++;
288         tty->flip.count++;
289 ignore_char:
290         ;
291         } while (status & DZ_DVAL);
292
293         if (tty)
294                 tty_flip_buffer_push(tty);
295 }
296
297 /*
298  * ------------------------------------------------------------
299  * transmit_char ()
300  *
301  * This routine deals with outputs to any lines.
302  * ------------------------------------------------------------
303  */
304 static inline void transmit_chars (struct dz_serial *info)
305 {
306         unsigned char tmp;
307
308         if (info->x_char) {           /* XON/XOFF chars */
309                 dz_out(info, DZ_TDR, info->x_char);
310                 info->icount.tx++;
311                 info->x_char = 0;
312                 return;
313         }
314
315         /* if nothing to do or stopped or hardware stopped */
316         if ((info->xmit_cnt <= 0) || info->tty->stopped ||
317             info->tty->hw_stopped) {
318                 dz_stop(info->tty);
319                 return;
320         }
321
322         /*
323          * If something to do ... (rember the dz has no output fifo so we go
324          * one char at a time :-<
325          */
326         tmp = (unsigned short) info->xmit_buf[info->xmit_tail++];
327         dz_out(info, DZ_TDR, tmp);
328         info->xmit_tail = info->xmit_tail & (DZ_XMIT_SIZE - 1);
329         info->icount.tx++;
330
331         if (--info->xmit_cnt < WAKEUP_CHARS)
332         dz_sched_event(info, DZ_EVENT_WRITE_WAKEUP);
333
334         /* Are we done */
335         if (info->xmit_cnt <= 0)
336                 dz_stop(info->tty);
337 }
338
339 /*
340  * ------------------------------------------------------------
341  * check_modem_status ()
342  *
343  * Only valid for the MODEM line duh !
344  * ------------------------------------------------------------
345  */
346 static inline void check_modem_status (struct dz_serial *info)
347 {
348         unsigned short status;
349
350         /* if not ne modem line just return */
351         if (info->line != DZ_MODEM)
352                 return;
353
354         status = dz_in(info, DZ_MSR);
355   
356         /* it's easy, since DSR2 is the only bit in the register */
357         if (status)
358                 info->icount.dsr++;
359 }
360
361 /*
362  * ------------------------------------------------------------
363  * dz_interrupt ()
364  *
365  * this is the main interrupt routine for the DZ chip.
366  * It deals with the multiple ports.
367  * ------------------------------------------------------------
368  */
369 static void dz_interrupt (int irq, void *dev, struct pt_regs *regs)
370 {
371         struct dz_serial *info;
372         unsigned short status;
373
374          /* get the reason why we just got an irq */
375         status = dz_in((struct dz_serial *)dev, DZ_CSR);
376         info = lines[LINE(status)];     /* re-arrange info the proper port */
377
378         if (status & DZ_RDONE) 
379                 receive_chars(info);    /* the receive function */
380
381         if (status & DZ_TRDY) 
382                 transmit_chars (info);
383 }
384
385 /*
386  * -------------------------------------------------------------------
387  * Here ends the DZ interrupt routines.
388  * -------------------------------------------------------------------
389  */
390
391 /*
392  * This routine is used to handle the "bottom half" processing for the
393  * serial driver, known also the "software interrupt" processing.
394  * This processing is done at the kernel interrupt level, after the
395  * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
396  * is where time-consuming activities which can not be done in the
397  * interrupt driver proper are done; the interrupt driver schedules
398  * them using rs_sched_event(), and they get done here.
399  */
400 static void do_serial_bh (void)
401 {
402         run_task_queue (&tq_serial);
403 }
404
405 static void do_softint (void *private_data)
406 {
407         struct dz_serial *info = (struct dz_serial *) private_data;
408         struct tty_struct *tty = info->tty;
409
410         if (!tty)
411                 return;
412
413         if (test_and_clear_bit(DZ_EVENT_WRITE_WAKEUP, &info->event)) {
414                 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
415                     tty->ldisc.write_wakeup)
416                         (tty->ldisc.write_wakeup) (tty);
417                 wake_up_interruptible (&tty->write_wait);
418         }
419 }
420
421 /*
422  * -------------------------------------------------------------------
423  * This routine is called from the scheduler tqueue when the interrupt
424  * routine has signalled that a hangup has occurred.  The path of
425  * hangup processing is:
426  *
427  *      serial interrupt routine -> (scheduler tqueue) ->
428  *      do_serial_hangup() -> tty->hangup() -> rs_hangup()
429  * ------------------------------------------------------------------- 
430  */
431 static void do_serial_hangup (void *private_data)
432 {
433         struct dz_serial *info = (struct dz_serial *) private_data;
434         struct tty_struct *tty = info->tty;
435         
436         if (!tty)
437                 return;
438
439         tty_hangup(tty);
440 }
441
442 /*
443  * -------------------------------------------------------------------
444  * startup ()
445  *
446  * various initialization tasks
447  * ------------------------------------------------------------------- 
448  */
449 static int startup (struct dz_serial *info)
450 {
451         unsigned long page, flags;
452         unsigned short tmp;
453
454         if (info->is_initialized)
455                 return 0;
456   
457         save_and_cli(flags);
458
459         if (!info->port) {
460                 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
461                 restore_flags(flags);
462                 return -ENODEV;
463         }
464
465         if (!info->xmit_buf) {
466                 page = get_zeroed_page(GFP_KERNEL);
467                 if (!page) {
468                         restore_flags (flags);
469                 return -ENOMEM;
470                 }
471                 info->xmit_buf = (unsigned char *)page;
472         }
473
474         if (info->tty)
475                 clear_bit(TTY_IO_ERROR, &info->tty->flags);
476
477         /* enable the interrupt and the scanning */
478         tmp = dz_in(info, DZ_CSR);
479         tmp |= (DZ_RIE | DZ_TIE | DZ_MSE);
480         dz_out(info, DZ_CSR, tmp);
481
482         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
483
484         change_speed(info);                     /* set up the speed */
485
486         /*
487          * Clear the line transmitter buffer I can't figure out why I need to
488          * do this - but its necessary - in order for the console portion and
489          * the interrupt portion to live happily side by side.
490          */
491
492         info->is_initialized = 1;
493
494         restore_flags(flags);
495
496         return 0;
497 }
498
499 /* 
500  * -------------------------------------------------------------------
501  * shutdown ()
502  *
503  * This routine will shutdown a serial port; interrupts are disabled, and
504  * DTR is dropped if the hangup on close termio flag is on.
505  * ------------------------------------------------------------------- 
506  */
507 static void shutdown (struct dz_serial *info)
508 {
509         unsigned long flags;
510         unsigned short tmp;
511
512         if (!info->is_initialized)
513                 return;
514
515         save_and_cli(flags);
516
517         dz_stop (info->tty);
518
519         info->cflags &= ~DZ_CREAD;      /* turn off receive enable flag */
520         dz_out(info, DZ_LPR, info->cflags);
521
522         if (info->xmit_buf) {               /* free Tx buffer */
523                 free_page((unsigned long)info->xmit_buf);
524                 info->xmit_buf = 0;
525         }
526
527         if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
528                 tmp = dz_in(info, DZ_TCR);
529                 if (tmp & DZ_MODEM_DTR) {
530                         tmp &= ~DZ_MODEM_DTR;
531                         dz_out(info, DZ_TCR, tmp);
532                 }
533         }
534
535         if (info->tty)
536                 set_bit (TTY_IO_ERROR, &info->tty->flags);
537
538         info->is_initialized = 0;
539
540         restore_flags (flags);
541 }
542
543 /* 
544  * -------------------------------------------------------------------
545  * change_speed ()
546  *
547  * set the baud rate.
548  * ------------------------------------------------------------------- 
549  */
550 static void change_speed (struct dz_serial *info)
551 {
552         unsigned long flags;
553         unsigned cflag;
554         int baud;
555
556         if (!info->tty || !info->tty->termios)
557                 return;
558   
559         save_and_cli(flags);
560   
561         info->cflags = info->line;
562
563         cflag = info->tty->termios->c_cflag;
564
565         switch (cflag & CSIZE) {
566                 case CS5:
567                         info->cflags |= DZ_CS5;
568                         break;
569                 case CS6:
570                         info->cflags |= DZ_CS6;
571                         break;
572                 case CS7:
573                         info->cflags |= DZ_CS7;
574                         break;
575                 case CS8: 
576                 default:
577                         info->cflags |= DZ_CS8;
578         }
579
580         if (cflag & CSTOPB)
581                 info->cflags |= DZ_CSTOPB;
582         if (cflag & PARENB)
583                 info->cflags |= DZ_PARENB;
584         if (cflag & PARODD)
585                 info->cflags |= DZ_PARODD;
586   
587         baud = tty_get_baud_rate(info->tty);
588         switch (baud) {
589         case 50:
590                 info->cflags |= DZ_B50;
591                 break;
592         case 75:
593                 info->cflags |= DZ_B75;
594                 break;
595         case 110:
596                 info->cflags |= DZ_B110;
597                 break;
598         case 134:
599                 info->cflags |= DZ_B134;
600                 break; 
601         case 150:
602                 info->cflags |= DZ_B150;
603                 break;
604         case 300:
605                 info->cflags |= DZ_B300;
606                 break; 
607         case 600:
608                 info->cflags |= DZ_B600;
609                 break;
610         case 1200:
611                 info->cflags |= DZ_B1200;
612                 break; 
613         case 1800:
614                 info->cflags |= DZ_B1800;
615                 break;
616         case 2000:
617                 info->cflags |= DZ_B2000;
618                 break;
619         case 2400:
620                 info->cflags |= DZ_B2400;
621                 break;
622         case 3600:
623                 info->cflags |= DZ_B3600;
624                 break; 
625         case 4800:
626                 info->cflags |= DZ_B4800;
627                 break;
628         case 7200:
629                 info->cflags |= DZ_B7200;
630                 break; 
631         case 9600: 
632         default:
633                 info->cflags |= DZ_B9600; 
634         }
635
636         info->cflags |= DZ_RXENAB;
637         dz_out(info, DZ_LPR, info->cflags);
638
639         /* setup accept flag */
640         info->read_status_mask = DZ_OERR;
641         if (I_INPCK(info->tty))
642                 info->read_status_mask |= (DZ_FERR | DZ_PERR); 
643   
644         /* characters to ignore */
645         info->ignore_status_mask = 0;
646         if (I_IGNPAR(info->tty))
647                 info->ignore_status_mask |= (DZ_FERR | DZ_PERR);
648
649         restore_flags(flags);
650 }
651
652 /* 
653  * -------------------------------------------------------------------
654  * dz_flush_char ()
655  *
656  * Flush the buffer.
657  * ------------------------------------------------------------------- 
658  */
659 static void dz_flush_chars (struct tty_struct *tty)
660 {
661         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
662         unsigned long flags;
663
664         if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
665             !info->xmit_buf)
666                 return;
667
668         save_and_cli(flags);
669         dz_start (info->tty);
670         restore_flags(flags);
671 }
672
673
674 /* 
675  * -------------------------------------------------------------------
676  * dz_write ()
677  *
678  * main output routine.
679  * ------------------------------------------------------------------- 
680  */
681 static int dz_write (struct tty_struct *tty, int from_user,
682                      const unsigned char *buf, int count)
683 {
684         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
685         unsigned long flags;
686         int c, ret = 0;
687
688         if (!tty )
689                 return ret;
690         if (!info->xmit_buf)
691                 return ret;
692         if (!tmp_buf)
693                 tmp_buf = tmp_buffer;
694
695         if (from_user) {
696                 down (&tmp_buf_sem);
697                 while (1) {
698                         c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
699                                            DZ_XMIT_SIZE - info->xmit_head));
700                         if (c <= 0)
701                                 break;
702
703                         c -= copy_from_user (tmp_buf, buf, c);
704                         if (!c) {
705                                 if (!ret)
706                                         ret = -EFAULT;
707                                 break;
708                         }
709
710                         save_and_cli(flags);
711
712                         c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
713                                        DZ_XMIT_SIZE - info->xmit_head));
714                         memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
715                         info->xmit_head = ((info->xmit_head + c) &
716                                            (DZ_XMIT_SIZE - 1));
717                         info->xmit_cnt += c;
718                         restore_flags(flags);
719
720                         buf += c;
721                         count -= c;
722                         ret += c;
723                 }
724                 up(&tmp_buf_sem);
725         } else {
726                 while (1) {
727                         save_and_cli(flags);
728
729                         c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1,
730                                            DZ_XMIT_SIZE - info->xmit_head));
731                         if (c <= 0) {
732                                 restore_flags (flags);
733                                 break;
734                         }
735                         memcpy(info->xmit_buf + info->xmit_head, buf, c);
736                         info->xmit_head = ((info->xmit_head + c) &
737                                            (DZ_XMIT_SIZE-1));
738                         info->xmit_cnt += c;
739                         restore_flags(flags);
740
741                         buf += c;
742                         count -= c;
743                         ret += c;
744                 }
745         }
746
747         if (info->xmit_cnt) {
748                 if (!tty->stopped) {
749                         if (!tty->hw_stopped) {
750                                 dz_start (info->tty);
751                         }
752                 }
753         }
754
755         return ret;
756 }
757
758 /* 
759  * -------------------------------------------------------------------
760  * dz_write_room ()
761  *
762  * compute the amount of space available for writing.
763  * ------------------------------------------------------------------- 
764  */
765 static int dz_write_room (struct tty_struct *tty)
766 {
767         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
768         int ret;
769
770         ret = DZ_XMIT_SIZE - info->xmit_cnt - 1;
771         if (ret < 0)
772                 ret = 0;
773
774         return ret;
775 }
776
777 /* 
778  * -------------------------------------------------------------------
779  * dz_chars_in_buffer ()
780  *
781  * compute the amount of char left to be transmitted
782  * ------------------------------------------------------------------- 
783  */
784 static int dz_chars_in_buffer (struct tty_struct *tty)
785 {
786         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
787   
788         return info->xmit_cnt;
789 }
790
791 /* 
792  * -------------------------------------------------------------------
793  * dz_flush_buffer ()
794  *
795  * Empty the output buffer
796  * ------------------------------------------------------------------- 
797  */
798 static void dz_flush_buffer (struct tty_struct *tty)
799 {
800         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
801                                 
802         cli();
803         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
804         sti();
805
806         wake_up_interruptible (&tty->write_wait);
807
808         if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
809              tty->ldisc.write_wakeup)
810                 tty->ldisc.write_wakeup(tty);
811 }
812
813 /*
814  * ------------------------------------------------------------
815  * dz_throttle () and dz_unthrottle ()
816  * 
817  * This routine is called by the upper-layer tty layer to signal that
818  * incoming characters should be throttled (or not).
819  * ------------------------------------------------------------
820  */
821 static void dz_throttle (struct tty_struct *tty)
822 {
823         struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
824
825         if (I_IXOFF(tty))
826                 info->x_char = STOP_CHAR(tty);
827 }
828
829 static void dz_unthrottle (struct tty_struct *tty)
830 {
831         struct dz_serial *info = (struct dz_serial *)tty->driver_data;  
832
833         if (I_IXOFF(tty)) {
834                 if (info->x_char)
835                         info->x_char = 0;
836                 else
837                         info->x_char = START_CHAR(tty);
838         }
839 }
840
841 static void dz_send_xchar (struct tty_struct *tty, char ch)
842 {
843         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
844
845         info->x_char = ch;
846
847         if (ch)
848                 dz_start(info->tty);
849 }
850
851 /*
852  * ------------------------------------------------------------
853  * rs_ioctl () and friends
854  * ------------------------------------------------------------
855  */
856 static int get_serial_info(struct dz_serial *info,
857                            struct serial_struct *retinfo)
858 {
859         struct serial_struct tmp;
860   
861         if (!retinfo)
862                 return -EFAULT;
863
864         memset (&tmp, 0, sizeof(tmp));
865
866         tmp.type = info->type;
867         tmp.line = info->line;
868         tmp.port = info->port;
869         tmp.irq = SERIAL;
870         tmp.flags = info->flags;
871         tmp.baud_base = info->baud_base;
872         tmp.close_delay = info->close_delay;
873         tmp.closing_wait = info->closing_wait;
874
875         return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
876 }
877
878 static int set_serial_info (struct dz_serial *info,
879                             struct serial_struct *new_info)
880 {
881         struct serial_struct new_serial;
882         struct dz_serial old_info;
883         int retval = 0;
884
885         if (!new_info)
886                 return -EFAULT;
887
888         if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
889                 return -EFAULT;
890
891         old_info = *info;
892
893         if (!capable(CAP_SYS_ADMIN))
894                 return -EPERM;
895
896         if (info->count > 1)
897                 return -EBUSY;
898
899         /*
900          * OK, past this point, all the error checking has been done.
901          * At this point, we start making changes.....
902          */
903
904         info->baud_base = new_serial.baud_base;
905         info->type = new_serial.type;
906         info->close_delay = new_serial.close_delay;
907         info->closing_wait = new_serial.closing_wait;
908
909         retval = startup(info);
910
911         return retval;
912 }
913
914 /*
915  * get_lsr_info - get line status register info
916  *
917  * Purpose: Let user call ioctl() to get info when the UART physically
918  *          is emptied.  On bus types like RS485, the transmitter must
919  *          release the bus after transmitting. This must be done when
920  *          the transmit shift register is empty, not be done when the
921  *          transmit holding register is empty.  This functionality
922  *          allows an RS485 driver to be written in user space. 
923  */
924 static int get_lsr_info (struct dz_serial *info, unsigned int *value)
925 {
926         unsigned short status = dz_in (info, DZ_LPR);
927
928         return put_user (status, value);
929 }
930
931 /*
932  * This routine sends a break character out the serial port.
933  */
934 static void send_break (struct dz_serial *info, int duration)
935 {
936         unsigned long flags;
937         unsigned short tmp, mask;
938
939         if (!info->port)
940                 return;
941
942         mask = 1 << info->line;
943         tmp = dz_in (info, DZ_TCR);
944         tmp |= mask;
945
946         current->state = TASK_INTERRUPTIBLE;
947
948         save_and_cli(flags);
949         dz_out(info, DZ_TCR, tmp);
950         schedule_timeout(duration);
951         tmp &= ~mask;
952         dz_out(info, DZ_TCR, tmp);
953         restore_flags(flags);
954 }
955
956 static int dz_ioctl(struct tty_struct *tty, struct file *file,
957                     unsigned int cmd, unsigned long arg)
958 {
959         int error;
960         struct dz_serial * info = (struct dz_serial *)tty->driver_data;
961         int retval;
962
963         if (cmd != TIOCGSERIAL && cmd != TIOCSSERIAL &&
964             cmd != TIOCSERCONFIG && cmd != TIOCSERGWILD  &&
965             cmd != TIOCSERSWILD && cmd != TIOCSERGSTRUCT) {
966                 if (tty->flags & (1 << TTY_IO_ERROR))
967                         return -EIO;
968         }
969
970         switch (cmd) {
971         case TCSBRK:            /* SVID version: non-zero arg --> no break */
972                 retval = tty_check_change(tty);
973                 if (retval)
974                         return retval;
975                 tty_wait_until_sent(tty, 0);
976                 if (!arg)
977                         send_break(info, HZ/4); /* 1/4 second */
978                 return 0;
979
980         case TCSBRKP:           /* support for POSIX tcsendbreak() */
981                 retval = tty_check_change(tty);
982                 if (retval)
983                         return retval;
984                 tty_wait_until_sent(tty, 0);
985                 send_break(info, arg ? arg*(HZ/10) : HZ/4);
986                 return 0;
987
988         case TIOCGSOFTCAR:
989                 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
990
991         case TIOCSSOFTCAR:
992                 if (get_user (arg, (unsigned long *)arg))
993                         return -EFAULT;
994
995                 tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) |
996                                         (arg ? CLOCAL : 0);
997                 return 0;
998
999         case TIOCGSERIAL:
1000                 return get_serial_info(info, (struct serial_struct *)arg);
1001
1002         case TIOCSSERIAL:
1003                 return set_serial_info(info, (struct serial_struct *) arg);
1004
1005         case TIOCSERGETLSR:             /* Get line status register */
1006                 return get_lsr_info (info, (unsigned int *)arg);
1007
1008         case TIOCSERGSTRUCT:
1009                 return copy_to_user((struct dz_serial *)arg, info,
1010                                     sizeof(struct dz_serial)) ? -EFAULT : 0;
1011  
1012         default:
1013                 return -ENOIOCTLCMD;
1014         }
1015
1016         return 0;
1017 }
1018
1019 static void dz_set_termios (struct tty_struct *tty,
1020                             struct termios *old_termios)
1021 {
1022         struct dz_serial *info = (struct dz_serial *)tty->driver_data;
1023
1024         if (tty->termios->c_cflag == old_termios->c_cflag)
1025                 return;
1026
1027         change_speed (info);
1028
1029         if ((old_termios->c_cflag & CRTSCTS) &&
1030             !(tty->termios->c_cflag & CRTSCTS)) {
1031                 tty->hw_stopped = 0;
1032                 dz_start(tty);
1033         }
1034 }
1035
1036 /*
1037  * ------------------------------------------------------------
1038  * dz_close()
1039  * 
1040  * This routine is called when the serial port gets closed.  First, we
1041  * wait for the last remaining data to be sent.  Then, we turn off
1042  * the transmit enable and receive enable flags.
1043  * ------------------------------------------------------------
1044  */
1045 static void dz_close(struct tty_struct *tty, struct file *filp)
1046 {
1047         struct dz_serial * info = (struct dz_serial *)tty->driver_data;
1048         unsigned long flags;
1049
1050         if (!info)
1051                 return;
1052  
1053         save_and_cli(flags); 
1054
1055         if (tty_hung_up_p(filp)) {
1056                 restore_flags(flags);
1057                 return;
1058         }
1059
1060         if ((tty->count == 1) && (info->count != 1)) {
1061                 /*
1062                  * Uh, oh.  tty->count is 1, which means that the tty structure
1063                  * will be freed.  Info->count should always be one in these
1064                  * conditions.  If it's greater than one, we've got real
1065                  * problems, since it means the serial port won't be shutdown.
1066                  */
1067                 printk("dz_close: bad serial port count; tty->count is 1, "
1068                        "info->count is %d\n", info->count);
1069                 info->count = 1;
1070         }
1071
1072         if (--info->count < 0) {
1073                 printk("ds_close: bad serial port count for ttyS%02d: %d\n",
1074                        info->line, info->count);
1075                 info->count = 0;
1076         }
1077
1078         if (info->count) {
1079                 restore_flags(flags);
1080                 return;
1081         }
1082         info->flags |= DZ_CLOSING;
1083         /*
1084          * Now we wait for the transmit buffer to clear; and we notify the line
1085          * discipline to only process XON/XOFF characters.
1086          */
1087         tty->closing = 1;
1088
1089         if (info->closing_wait != DZ_CLOSING_WAIT_NONE)
1090                 tty_wait_until_sent(tty, info->closing_wait);
1091
1092         /*
1093          * At this point we stop accepting input.  To do this, we disable the
1094          * receive line status interrupts.
1095          */
1096         shutdown(info);
1097
1098         if (tty->driver->flush_buffer)
1099                 tty->driver->flush_buffer (tty);
1100         if (tty->ldisc.flush_buffer)
1101                 tty->ldisc.flush_buffer (tty);
1102         tty->closing = 0;
1103         info->event = 0;
1104         info->tty = 0;
1105
1106         if (tty->ldisc.num != ldiscs[N_TTY].num) {
1107                 if (tty->ldisc.close)
1108                         tty->ldisc.close(tty);
1109                 tty->ldisc = ldiscs[N_TTY];
1110                 tty->termios->c_line = N_TTY;
1111                 if (tty->ldisc.open)
1112                         tty->ldisc.open(tty);
1113         }
1114         if (info->blocked_open) {
1115                 if (info->close_delay) {
1116                         current->state = TASK_INTERRUPTIBLE;
1117                         schedule_timeout(info->close_delay);
1118                 }
1119                 wake_up_interruptible(&info->open_wait);
1120         }
1121
1122         info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CLOSING);
1123         wake_up_interruptible(&info->close_wait);
1124
1125         restore_flags(flags);
1126 }
1127
1128 /*
1129  * dz_hangup () --- called by tty_hangup() when a hangup is signaled.
1130  */
1131 static void dz_hangup (struct tty_struct *tty)
1132 {
1133         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
1134   
1135         dz_flush_buffer(tty);
1136         shutdown(info);
1137         info->event = 0;
1138         info->count = 0;
1139         info->flags &= ~DZ_NORMAL_ACTIVE;
1140         info->tty = 0;
1141         wake_up_interruptible(&info->open_wait);
1142 }
1143
1144 /*
1145  * ------------------------------------------------------------
1146  * rs_open() and friends
1147  * ------------------------------------------------------------
1148  */
1149 static int block_til_ready(struct tty_struct *tty, struct file *filp,
1150                            struct dz_serial *info)
1151 {
1152         DECLARE_WAITQUEUE(wait, current); 
1153         int retval;
1154         int do_clocal = 0;
1155
1156         /*
1157          * If the device is in the middle of being closed, then block
1158          * until it's done, and then try again.
1159          */
1160         if (info->flags & DZ_CLOSING) {
1161                 interruptible_sleep_on(&info->close_wait);
1162                 return -EAGAIN;
1163         }
1164
1165         /*
1166          * If non-blocking mode is set, or the port is not enabled, then make
1167          * the check up front and then exit.
1168          */
1169         if ((filp->f_flags & O_NONBLOCK) ||
1170             (tty->flags & (1 << TTY_IO_ERROR))) {
1171                 info->flags |= DZ_NORMAL_ACTIVE;
1172
1173                 return 0;
1174         }
1175
1176         if (tty->termios->c_cflag & CLOCAL)
1177                 do_clocal = 1;
1178
1179         /*
1180          * Block waiting for the carrier detect and the line to become free
1181          * (i.e., not in use by the callout).  While we are in this loop,
1182          * info->count is dropped by one, so that dz_close() knows when to free
1183          * things.  We restore it upon exit, either normal or abnormal.
1184          */
1185         retval = 0;
1186         add_wait_queue(&info->open_wait, &wait);
1187
1188         info->count--;
1189         info->blocked_open++;
1190         while (1) {
1191                 set_current_state(TASK_INTERRUPTIBLE);
1192                 if (tty_hung_up_p (filp) || !(info->is_initialized)) {
1193                         retval = -EAGAIN;
1194                         break;
1195                 }
1196                 if (!(info->flags & DZ_CLOSING) && do_clocal)
1197                         break;
1198                 if (signal_pending(current)) {
1199                         retval = -ERESTARTSYS;
1200                         break;
1201                 }
1202                 schedule();
1203         }
1204                 
1205         current->state = TASK_RUNNING;
1206         remove_wait_queue (&info->open_wait, &wait);
1207         if (!tty_hung_up_p(filp))
1208                 info->count++;
1209         info->blocked_open--;
1210
1211         if (retval)
1212                 return retval;
1213         info->flags |= DZ_NORMAL_ACTIVE;
1214         return 0;
1215 }
1216
1217 /*
1218  * This routine is called whenever a serial port is opened.  It
1219  * enables interrupts for a serial port. It also performs the 
1220  * serial-specific initialization for the tty structure.
1221  */
1222 static int dz_open (struct tty_struct *tty, struct file *filp)
1223 {
1224         struct dz_serial *info;
1225         int retval, line;
1226
1227         line = tty->index;
1228
1229         /*
1230          * The dz lines for the mouse/keyboard must be opened using their
1231          * respective drivers.
1232          */
1233         if ((line < 0) || (line >= DZ_NB_PORT))
1234                 return -ENODEV;
1235
1236         if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE))
1237                 return -ENODEV;
1238
1239         info = lines[line];
1240         info->count++;
1241
1242         tty->driver_data = info;
1243         info->tty = tty;
1244
1245         /*
1246          * Start up serial port
1247          */
1248         retval = startup (info);
1249         if (retval)
1250                 return retval;
1251
1252         retval = block_til_ready (tty, filp, info);
1253         if (retval)
1254                 return retval;
1255
1256         return 0;
1257 }
1258
1259 static void show_serial_version (void)
1260 {
1261         printk("%s%s\n", dz_name, dz_version);
1262 }
1263
1264 static struct tty_driver *serial_driver;
1265
1266 static struct tty_operations serial_ops = {
1267         .open = dz_open,
1268         .close = dz_close,
1269         .write = dz_write,
1270         .flush_chars = dz_flush_chars,
1271         .write_room = dz_write_room,
1272         .chars_in_buffer = dz_chars_in_buffer,
1273         .flush_buffer = dz_flush_buffer,
1274         .ioctl = dz_ioctl,
1275         .throttle = dz_throttle,
1276         .unthrottle = dz_unthrottle,
1277         .send_xchar = dz_send_xchar,
1278         .set_termios = dz_set_termios,
1279         .stop = dz_stop,
1280         .start = dz_start,
1281         .hangup = dz_hangup,
1282 };
1283
1284 int __init dz_init(void)
1285 {
1286         int i, flags;
1287         struct dz_serial *info;
1288
1289         serial_driver = alloc_tty_driver(DZ_NB_PORT);
1290         if (!serial_driver)
1291                 return -ENOMEM;
1292
1293         /* Setup base handler, and timer table. */
1294         init_bh(SERIAL_BH, do_serial_bh);
1295
1296         show_serial_version();
1297
1298         serial_driver->owner = THIS_MODULE;
1299         serial_driver->devfs_name = "tts/";
1300         serial_driver->name = "ttyS";
1301         serial_driver->major = TTY_MAJOR;
1302         serial_driver->minor_start = 64;
1303         serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
1304         serial_driver->subtype = SERIAL_TYPE_NORMAL;
1305         serial_driver->init_termios = tty_std_termios;
1306         serial_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
1307                                              CLOCAL;
1308         serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
1309         tty_set_operations(serial_driver, &serial_ops);
1310
1311         if (tty_register_driver(serial_driver))
1312                 panic("Couldn't register serial driver\n");
1313
1314         save_flags(flags); cli();
1315         for (i=0; i < DZ_NB_PORT;  i++) {
1316                 info = &multi[i]; 
1317                 lines[i] = info;
1318                 info->magic = SERIAL_MAGIC;
1319
1320                 if ((mips_machtype == MACH_DS23100) ||
1321                     (mips_machtype == MACH_DS5100)) 
1322                         info->port = (unsigned long) KN01_DZ11_BASE;
1323                 else 
1324                         info->port = (unsigned long) KN02_DZ11_BASE;
1325
1326                 info->line = i;
1327                 info->tty = 0;
1328                 info->close_delay = 50;
1329                 info->closing_wait = 3000;
1330                 info->x_char = 0;
1331                 info->event = 0;
1332                 info->count = 0;
1333                 info->blocked_open = 0;
1334                 info->tqueue.routine = do_softint;
1335                 info->tqueue.data = info;
1336                 info->tqueue_hangup.routine = do_serial_hangup;
1337                 info->tqueue_hangup.data = info;
1338                 init_waitqueue_head(&info->open_wait); 
1339                 init_waitqueue_head(&info->close_wait); 
1340
1341                 /*
1342                  * If we are pointing to address zero then punt - not correctly
1343                  * set up in setup.c to handle this.
1344                  */
1345                 if (! info->port)
1346                         return 0;
1347
1348                 printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line,
1349                        info->port, SERIAL);
1350
1351                 tty_register_device(serial_driver, info->line, NULL);
1352         }
1353
1354         /* Reset the chip */
1355 #ifndef CONFIG_SERIAL_CONSOLE
1356         {
1357                 int tmp;
1358                 dz_out(info, DZ_CSR, DZ_CLR);
1359                 while ((tmp = dz_in(info,DZ_CSR)) & DZ_CLR);
1360                 wbflush();
1361   
1362                 /* Enable scanning */
1363                 dz_out(info, DZ_CSR, DZ_MSE); 
1364         }
1365 #endif
1366   
1367         /*
1368          * Order matters here... the trick is that flags is updated... in
1369          * request_irq - to immediatedly obliterate it is unwise.
1370          */
1371         restore_flags(flags);
1372
1373         if (request_irq(SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))
1374                 panic("Unable to register DZ interrupt\n");
1375  
1376         return 0;
1377 }
1378
1379 #ifdef CONFIG_SERIAL_CONSOLE
1380 static void dz_console_put_char (unsigned char ch)
1381 {
1382         unsigned long flags;
1383         int  loops = 2500;
1384         unsigned short tmp = ch;
1385         /*
1386          * this code sends stuff out to serial device - spinning its wheels and
1387          * waiting.
1388          */
1389
1390         /* force the issue - point it at lines[3]*/
1391         dz_console = &multi[CONSOLE_LINE];
1392
1393         save_and_cli(flags);
1394
1395         /* spin our wheels */
1396         while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) &&  loops--)
1397                 ;
1398   
1399         /* Actually transmit the character. */
1400         dz_out(dz_console, DZ_TDR, tmp);
1401
1402         restore_flags(flags); 
1403 }
1404
1405 /* 
1406  * -------------------------------------------------------------------
1407  * dz_console_print ()
1408  *
1409  * dz_console_print is registered for printk.
1410  * The console must be locked when we get here.
1411  * ------------------------------------------------------------------- 
1412  */
1413 static void dz_console_print (struct console *cons, 
1414                               const char *str, 
1415                               unsigned int count)
1416 {
1417 #ifdef DEBUG_DZ
1418         prom_printf((char *)str);
1419 #endif
1420         while (count--) {
1421                 if (*str == '\n')
1422                         dz_console_put_char('\r');
1423                 dz_console_put_char(*str++);
1424         }
1425 }
1426
1427 static struct tty_driver *dz_console_device(struct console *c, int *index)
1428 {
1429         *index = c->index;
1430         return serial_driver;
1431 }
1432
1433 static int __init dz_console_setup(struct console *co, char *options)
1434 {
1435         int baud = 9600;
1436         int bits = 8;
1437         int parity = 'n';
1438         int cflag = CREAD | HUPCL | CLOCAL;
1439         char *s;
1440         unsigned short mask,tmp;
1441
1442         if (options) {
1443                 baud = simple_strtoul(options, NULL, 10);
1444                 s = options;
1445                 while (*s >= '0' && *s <= '9')
1446                         s++;
1447                 if (*s)
1448                         parity = *s++;
1449                 if (*s)
1450                         bits   = *s - '0';
1451         }
1452
1453         /*
1454          * Now construct a cflag setting.
1455          */
1456         switch (baud) {
1457         case 1200:
1458                 cflag |= DZ_B1200;
1459                 break;
1460         case 2400:
1461                 cflag |= DZ_B2400;
1462                 break;
1463         case 4800:
1464                 cflag |= DZ_B4800;
1465                 break;
1466         case 9600:
1467         default:
1468                 cflag |= DZ_B9600;
1469                 break;
1470         }
1471         switch (bits) {
1472         case 7:
1473                 cflag |= DZ_CS7;
1474                 break;
1475         default:
1476         case 8:
1477                 cflag |= DZ_CS8;
1478                 break;
1479         }
1480         switch (parity) {
1481         case 'o':
1482         case 'O':
1483                 cflag |= DZ_PARODD;
1484                 break;
1485         case 'e':
1486         case 'E':
1487                 cflag |= DZ_PARENB;
1488                 break;
1489         }
1490         co->cflag = cflag;
1491
1492         /* TOFIX: force to console line */
1493         dz_console = &multi[CONSOLE_LINE];
1494         if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) 
1495                 dz_console->port = KN01_DZ11_BASE;
1496         else 
1497                 dz_console->port = KN02_DZ11_BASE; 
1498         dz_console->line = CONSOLE_LINE;
1499
1500         dz_out(dz_console, DZ_CSR, DZ_CLR);
1501         while ((tmp = dz_in(dz_console,DZ_CSR)) & DZ_CLR)
1502                 ;
1503
1504         /* enable scanning */
1505         dz_out(dz_console, DZ_CSR, DZ_MSE); 
1506
1507         /*  Set up flags... */
1508         dz_console->cflags = 0;
1509         dz_console->cflags |= DZ_B9600;
1510         dz_console->cflags |= DZ_CS8;
1511         dz_console->cflags |= DZ_PARENB;
1512         dz_out(dz_console, DZ_LPR, dz_console->cflags);
1513
1514         mask = 1 << dz_console->line;
1515         tmp = dz_in (dz_console, DZ_TCR);               /* read the TX flag */
1516         if (!(tmp & mask)) {
1517                 tmp |= mask;                            /* set the TX flag */
1518                 dz_out (dz_console, DZ_TCR, tmp); 
1519         }
1520
1521         return 0;
1522 }
1523
1524 static struct console dz_sercons = {
1525     .name       = "ttyS",
1526     .write      = dz_console_print,
1527     .device     = dz_console_device,
1528     .setup      = dz_console_setup,
1529     .flags      = CON_CONSDEV | CON_PRINTBUFFER,
1530     .index      = CONSOLE_LINE,
1531 };
1532
1533 void __init dz_serial_console_init(void)
1534 {
1535         register_console(&dz_sercons);
1536 }
1537
1538 #endif /* ifdef CONFIG_SERIAL_CONSOLE */
1539
1540 MODULE_LICENSE("GPL");