Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / char / dz.c
blobdd2b50d8cc8b9403a6209090195487fcd7a4b49f
1 /*
2 * dz.c: Serial port driver for DECStations equiped
3 * with the DZ chipset.
5 * Copyright (C) 1998 Olivier A. D. Lebaillif
6 *
7 * Email: olivier.lebaillif@ifrsys.com
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
18 * Parts (C) 1999 David Airlie, airlied@linux.ie
19 * [07-SEP-99] Bugfixes
22 #define DEBUG_DZ 1
24 #ifdef MODULE
25 #include <linux/module.h>
26 #include <linux/version.h>
27 #else
28 #define MOD_INC_USE_COUNT
29 #define MOD_DEC_USE_COUNT
30 #endif
32 #include <linux/config.h>
33 #include <linux/kernel.h>
34 #include <linux/sched.h>
35 #include <linux/init.h>
36 #include <linux/malloc.h>
37 #include <linux/mm.h>
38 #include <linux/major.h>
39 #include <linux/param.h>
40 #include <linux/tqueue.h>
41 #include <linux/interrupt.h>
42 #include <asm-mips/wbflush.h>
43 /* for definition of SERIAL */
44 #include <asm/dec/interrupts.h>
46 /* for definition of struct console */
47 #ifdef CONFIG_SERIAL_CONSOLE
48 #define CONSOLE_LINE (3)
49 #endif /* ifdef CONFIG_SERIAL_CONSOLE */
50 #if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_DZ)
51 #include <linux/console.h>
52 #endif /* if defined(CONFIG_SERIAL_CONSOLE) || defined(DEBUG_DZ) */
54 #include <linux/tty.h>
55 #include <linux/tty_flip.h>
56 #include <linux/serial.h>
58 #include <asm/uaccess.h>
59 #include <asm/irq.h>
60 #include <asm/dec/machtype.h>
61 #include <asm/dec/kn01.h>
62 #include <asm/dec/kn02.h>
64 #ifdef DEBUG_DZ
65 #include <linux/ptrace.h>
66 #include <linux/fs.h>
67 #include <asm/bootinfo.h>
69 extern int (*prom_printf) (char *,...);
70 #endif
74 #include "dz.h"
76 #define DZ_INTR_DEBUG 1
78 DECLARE_TASK_QUEUE(tq_serial);
80 extern wait_queue_head_t keypress_wait;
81 static struct dz_serial *lines[4];
82 static unsigned char tmp_buffer[256];
86 #ifdef DEBUG_DZ
88 * debugging code to send out chars via prom
90 static void debug_console( const char *s,int count)
92 unsigned i;
94 for (i = 0; i < count; i++) {
95 if (*s == 10)
96 prom_printf("%c", 13);
97 prom_printf("%c", *s++);
100 #endif
103 * ------------------------------------------------------------
104 * dz_in () and dz_out ()
106 * These routines are used to access the registers of the DZ
107 * chip, hiding relocation differences between implementation.
108 * ------------------------------------------------------------
111 static inline unsigned short dz_in (struct dz_serial *info, unsigned offset)
113 volatile unsigned short *addr = (volatile unsigned short *)(info->port + offset);
114 return *addr;
117 static inline void dz_out (struct dz_serial *info, unsigned offset, unsigned short value)
120 volatile unsigned short *addr = (volatile unsigned short *)(info->port + offset);
121 *addr = value;
126 * ------------------------------------------------------------
127 * rs_stop () and rs_start ()
129 * These routines are called before setting or resetting
130 * tty->stopped. They enable or disable transmitter interrupts,
131 * as necessary.
132 * ------------------------------------------------------------
135 static void dz_stop (struct tty_struct *tty)
137 struct dz_serial *info;
138 unsigned short mask, tmp;
140 if (tty==0)
141 return;
143 info = (struct dz_serial *)tty->driver_data;
145 mask = 1 << info->line;
146 tmp = dz_in (info, DZ_TCR); /* read the TX flag */
148 tmp &= ~mask; /* clear the TX flag */
149 dz_out (info, DZ_TCR, tmp);
152 static void dz_start (struct tty_struct *tty)
154 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
155 unsigned short mask, tmp;
157 mask = 1 << info->line;
158 tmp = dz_in (info, DZ_TCR); /* read the TX flag */
160 tmp |= mask; /* set the TX flag */
161 dz_out (info, DZ_TCR, tmp);
166 * ------------------------------------------------------------
167 * Here starts the interrupt handling routines. All of the
168 * following subroutines are declared as inline and are folded
169 * into dz_interrupt. They were separated out for readability's
170 * sake.
172 * Note: rs_interrupt() is a "fast" interrupt, which means that it
173 * runs with interrupts turned off. People who may want to modify
174 * rs_interrupt() should try to keep the interrupt handler as fast as
175 * possible. After you are done making modifications, it is not a bad
176 * idea to do:
178 * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer dz.c
180 * and look at the resulting assemble code in serial.s.
182 * ------------------------------------------------------------
186 * ------------------------------------------------------------
187 * dz_sched_event ()
189 * This routine is used by the interrupt handler to schedule
190 * processing in the software interrupt portion of the driver.
191 * ------------------------------------------------------------
193 static inline void dz_sched_event (struct dz_serial *info, int event)
195 info->event |= 1 << event;
196 queue_task (&info->tqueue, &tq_serial);
197 mark_bh (SERIAL_BH);
201 * ------------------------------------------------------------
202 * receive_char ()
204 * This routine deals with inputs from any lines.
205 * ------------------------------------------------------------
207 static inline void receive_chars (struct dz_serial *info_in)
210 struct dz_serial *info;
211 struct tty_struct *tty = 0;
212 struct async_icount *icount;
213 int ignore = 0;
214 unsigned short status, tmp;
215 unsigned char ch;
217 /* this code is going to be a problem...
218 the call to tty_flip_buffer is going to need
219 to be rethought...
223 status = dz_in (info_in, DZ_RBUF);
224 info = lines[LINE(status)];
226 /* punt so we don't get duplicate characters */
227 if (!(status & DZ_DVAL))
228 goto ignore_char;
231 ch = UCHAR(status); /* grab the char */
233 #ifdef 0
234 if (info->is_console) {
235 if (ch == 0) return; /* it's a break ... */
237 wake_up (&keypress_wait); /* It is a 'keyboard interrupt' ;-) */
239 #endif
241 tty = info->tty; /* now tty points to the proper dev */
242 icount = &info->icount;
244 if (!tty) break;
245 if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
247 *tty->flip.char_buf_ptr = ch;
248 *tty->flip.flag_buf_ptr = 0;
249 icount->rx++;
251 /* keep track of the statistics */
252 if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
253 if (status & DZ_PERR) /* parity error */
254 icount->parity++;
255 else if (status & DZ_FERR) /* frame error */
256 icount->frame++;
257 if (status & DZ_OERR) /* overrun error */
258 icount->overrun++;
260 /* check to see if we should ignore the character
261 and mask off conditions that should be ignored
264 if (status & info->ignore_status_mask) {
265 if (++ignore > 100 ) break;
266 goto ignore_char;
269 /* mask off the error conditions we want to ignore */
270 tmp = status & info->read_status_mask;
272 if (tmp & DZ_PERR)
274 *tty->flip.flag_buf_ptr = TTY_PARITY;
275 debug_console("PERR\n",5);
277 else if (tmp & DZ_FERR)
279 *tty->flip.flag_buf_ptr = TTY_FRAME;
280 debug_console("FERR\n",5);
282 if (tmp & DZ_OERR)
284 debug_console("OERR\n",5);
285 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
286 tty->flip.count++;
287 tty->flip.flag_buf_ptr++;
288 tty->flip.char_buf_ptr++;
289 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
293 tty->flip.flag_buf_ptr++;
294 tty->flip.char_buf_ptr++;
295 tty->flip.count++;
296 ignore_char:
297 } while (status & DZ_DVAL);
299 if (tty)
300 tty_flip_buffer_push(tty);
304 * ------------------------------------------------------------
305 * transmit_char ()
307 * This routine deals with outputs to any lines.
308 * ------------------------------------------------------------
310 static inline void transmit_chars (struct dz_serial *info)
312 unsigned char tmp;
316 if (info->x_char) { /* XON/XOFF chars */
317 dz_out (info, DZ_TDR, info->x_char);
318 info->icount.tx++;
319 info->x_char = 0;
320 return;
323 /* if nothing to do or stopped or hardware stopped */
324 if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped) {
325 dz_stop (info->tty);
326 return;
329 /* if something to do ... (rember the dz has no output fifo so we go one char at a time :-< */
330 tmp = (unsigned short)info->xmit_buf[info->xmit_tail++];
331 dz_out (info, DZ_TDR, tmp);
332 info->xmit_tail = info->xmit_tail & (DZ_XMIT_SIZE - 1);
333 info->icount.tx++;
335 if (--info->xmit_cnt < WAKEUP_CHARS)
336 dz_sched_event (info, DZ_EVENT_WRITE_WAKEUP);
339 /* Are we done */
340 if (info->xmit_cnt <= 0) dz_stop (info->tty);
344 * ------------------------------------------------------------
345 * check_modem_status ()
347 * Only valid for the MODEM line duh !
348 * ------------------------------------------------------------
350 static inline void check_modem_status (struct dz_serial *info)
352 unsigned short status;
354 /* if not ne modem line just return */
355 if (info->line != DZ_MODEM) return;
357 status = dz_in (info, DZ_MSR);
359 /* it's easy, since DSR2 is the only bit in the register */
360 if (status) info->icount.dsr++;
364 * ------------------------------------------------------------
365 * dz_interrupt ()
367 * this is the main interrupt routine for the DZ chip.
368 * It deals with the multiple ports.
369 * ------------------------------------------------------------
371 static void dz_interrupt (int irq, void *dev, struct pt_regs *regs)
373 struct dz_serial *info;
374 unsigned short status;
376 status = dz_in ((struct dz_serial *)dev, DZ_CSR); /* get the reason why we just got an irq */
377 info = lines[LINE(status)]; /* re-arrange info the proper port */
379 if (status & DZ_RDONE)
380 receive_chars (info); /* the receive function */
382 if (status & DZ_TRDY)
383 transmit_chars (info);
387 * -------------------------------------------------------------------
388 * Here ends the DZ interrupt routines.
389 * -------------------------------------------------------------------
393 * This routine is used to handle the "bottom half" processing for the
394 * serial driver, known also the "software interrupt" processing.
395 * This processing is done at the kernel interrupt level, after the
396 * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
397 * is where time-consuming activities which can not be done in the
398 * interrupt driver proper are done; the interrupt driver schedules
399 * them using rs_sched_event(), and they get done here.
401 static void do_serial_bh (void)
403 run_task_queue (&tq_serial);
406 static void do_softint (void *private_data)
408 struct dz_serial *info = (struct dz_serial *)private_data;
409 struct tty_struct *tty = info->tty;
411 if (!tty) return;
413 if (test_and_clear_bit (DZ_EVENT_WRITE_WAKEUP, &info->event)) {
414 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
415 (tty->ldisc.write_wakeup) (tty);
416 wake_up_interruptible (&tty->write_wait);
421 * -------------------------------------------------------------------
422 * This routine is called from the scheduler tqueue when the interrupt
423 * routine has signalled that a hangup has occurred. The path of
424 * hangup processing is:
426 * serial interrupt routine -> (scheduler tqueue) ->
427 * do_serial_hangup() -> tty->hangup() -> rs_hangup()
428 * -------------------------------------------------------------------
430 static void do_serial_hangup (void *private_data)
432 struct dz_serial *info = (struct dz_serial *)private_data;
433 struct tty_struct *tty = info->tty;;
435 if (!tty) return;
437 tty_hangup (tty);
441 * -------------------------------------------------------------------
442 * startup ()
444 * various initialization tasks
445 * -------------------------------------------------------------------
447 static int startup (struct dz_serial *info)
449 unsigned long page, flags;
450 unsigned short tmp;
452 if (info->is_initialized) return 0;
454 save_flags (flags);
455 cli ();
457 if (!info->port) {
458 if (info->tty) set_bit (TTY_IO_ERROR, &info->tty->flags);
459 restore_flags (flags);
460 return -ENODEV;
463 if (!info->xmit_buf) {
464 page = get_free_page (GFP_KERNEL);
465 if (!page) {
466 restore_flags (flags);
467 return -ENOMEM;
469 info->xmit_buf = (unsigned char *)page;
472 if (info->tty) clear_bit (TTY_IO_ERROR, &info->tty->flags);
474 /* enable the interrupt and the scanning */
475 tmp = dz_in (info, DZ_CSR);
476 tmp |= (DZ_RIE | DZ_TIE | DZ_MSE);
477 dz_out (info, DZ_CSR, tmp);
479 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
481 /* set up the speed */
482 change_speed (info);
484 /* clear the line transmitter buffer
485 I can't figure out why I need to do this - but
486 its necessary - in order for the console portion
487 and the interrupt portion to live happily side by side.
490 /* clear the line transmitter buffer
491 I can't figure out why I need to do this - but
492 its necessary - in order for the console portion
493 and the interrupt portion to live happily side by side.
496 info->is_initialized = 1;
498 restore_flags (flags);
499 return 0;
503 * -------------------------------------------------------------------
504 * shutdown ()
506 * This routine will shutdown a serial port; interrupts are disabled, and
507 * DTR is dropped if the hangup on close termio flag is on.
508 * -------------------------------------------------------------------
510 static void shutdown (struct dz_serial *info)
512 unsigned long flags;
513 unsigned short tmp;
515 if (!info->is_initialized) return;
517 save_flags (flags);
518 cli ();
520 dz_stop (info->tty);
524 info->cflags &= ~DZ_CREAD; /* turn off receive enable flag */
525 dz_out (info, DZ_LPR, info->cflags);
527 if (info->xmit_buf) { /* free Tx buffer */
528 free_page ((unsigned long)info->xmit_buf);
529 info->xmit_buf = 0;
532 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
533 tmp = dz_in (info, DZ_TCR);
534 if (tmp & DZ_MODEM_DTR) {
535 tmp &= ~DZ_MODEM_DTR;
536 dz_out (info, DZ_TCR, tmp);
540 if (info->tty) set_bit (TTY_IO_ERROR, &info->tty->flags);
542 info->is_initialized = 0;
543 restore_flags (flags);
547 * -------------------------------------------------------------------
548 * change_speed ()
550 * set the baud rate.
551 * -------------------------------------------------------------------
553 static void change_speed (struct dz_serial *info)
555 unsigned long flags;
556 unsigned cflag;
557 int baud;
559 if (!info->tty || !info->tty->termios) return;
561 save_flags (flags);
562 cli ();
564 info->cflags = info->line;
566 cflag = info->tty->termios->c_cflag;
568 switch (cflag & CSIZE) {
569 case CS5: info->cflags |= DZ_CS5; break;
570 case CS6: info->cflags |= DZ_CS6; break;
571 case CS7: info->cflags |= DZ_CS7; break;
572 case CS8:
573 default: info->cflags |= DZ_CS8;
576 if (cflag & CSTOPB) info->cflags |= DZ_CSTOPB;
577 if (cflag & PARENB) info->cflags |= DZ_PARENB;
578 if (cflag & PARODD) info->cflags |= DZ_PARODD;
580 baud = tty_get_baud_rate (info->tty);
581 switch (baud) {
582 case 50 : info->cflags |= DZ_B50; break;
583 case 75 : info->cflags |= DZ_B75; break;
584 case 110 : info->cflags |= DZ_B110; break;
585 case 134 : info->cflags |= DZ_B134; break;
586 case 150 : info->cflags |= DZ_B150; break;
587 case 300 : info->cflags |= DZ_B300; break;
588 case 600 : info->cflags |= DZ_B600; break;
589 case 1200: info->cflags |= DZ_B1200; break;
590 case 1800: info->cflags |= DZ_B1800; break;
591 case 2000: info->cflags |= DZ_B2000; break;
592 case 2400: info->cflags |= DZ_B2400; break;
593 case 3600: info->cflags |= DZ_B3600; break;
594 case 4800: info->cflags |= DZ_B4800; break;
595 case 7200: info->cflags |= DZ_B7200; break;
596 case 9600:
597 default : info->cflags |= DZ_B9600;
600 info->cflags |= DZ_RXENAB;
601 dz_out (info, DZ_LPR, info->cflags);
603 /* setup accept flag */
604 info->read_status_mask = DZ_OERR;
605 if (I_INPCK(info->tty))
606 info->read_status_mask |= (DZ_FERR | DZ_PERR);
608 /* characters to ignore */
609 info->ignore_status_mask = 0;
610 if (I_IGNPAR(info->tty))
611 info->ignore_status_mask |= (DZ_FERR | DZ_PERR);
613 restore_flags (flags);
617 * -------------------------------------------------------------------
618 * dz_flush_char ()
620 * Flush the buffer.
621 * -------------------------------------------------------------------
623 static void dz_flush_chars (struct tty_struct *tty)
625 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
626 unsigned long flags;
628 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf)
629 return;
631 save_flags (flags);
632 cli ();
634 dz_start (info->tty);
636 restore_flags (flags);
641 * -------------------------------------------------------------------
642 * dz_write ()
644 * main output routine.
645 * -------------------------------------------------------------------
647 static int dz_write (struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
649 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
650 unsigned long flags;
651 int c, ret = 0;
653 if (!tty ) return ret;
654 if (!info->xmit_buf) return ret;
655 if (!tmp_buf) tmp_buf = tmp_buffer;
659 if (from_user) {
661 down (&tmp_buf_sem);
662 while (1) {
663 c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
664 if (c <= 0) break;
666 c -= copy_from_user (tmp_buf, buf, c);
667 if (!c) {
668 if (!ret) ret = -EFAULT;
669 break;
672 save_flags (flags);
673 cli ();
675 c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
676 memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
677 info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE-1));
678 info->xmit_cnt += c;
680 restore_flags(flags);
682 buf += c;
683 count -= c;
684 ret += c;
687 up (&tmp_buf_sem);
688 } else {
691 while (1) {
692 save_flags (flags);
693 cli ();
695 c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
696 if (c <= 0) {
697 restore_flags (flags);
698 break;
700 memcpy (info->xmit_buf + info->xmit_head, buf, c);
701 info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE-1));
702 info->xmit_cnt += c;
704 restore_flags (flags);
706 buf += c;
707 count -= c;
708 ret += c;
713 if (info->xmit_cnt)
715 if (!tty->stopped)
717 if (!tty->hw_stopped)
719 dz_start (info->tty);
723 return ret;
727 * -------------------------------------------------------------------
728 * dz_write_room ()
730 * compute the amount of space available for writing.
731 * -------------------------------------------------------------------
733 static int dz_write_room (struct tty_struct *tty)
735 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
736 int ret;
738 ret = DZ_XMIT_SIZE - info->xmit_cnt - 1;
739 if (ret < 0) ret = 0;
740 return ret;
744 * -------------------------------------------------------------------
745 * dz_chars_in_buffer ()
747 * compute the amount of char left to be transmitted
748 * -------------------------------------------------------------------
750 static int dz_chars_in_buffer (struct tty_struct *tty)
752 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
754 return info->xmit_cnt;
758 * -------------------------------------------------------------------
759 * dz_flush_buffer ()
761 * Empty the output buffer
762 * -------------------------------------------------------------------
764 static void dz_flush_buffer (struct tty_struct *tty)
766 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
768 cli ();
769 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
770 sti ();
772 wake_up_interruptible (&tty->write_wait);
774 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
775 (tty->ldisc.write_wakeup)(tty);
779 * ------------------------------------------------------------
780 * dz_throttle () and dz_unthrottle ()
782 * This routine is called by the upper-layer tty layer to signal that
783 * incoming characters should be throttled (or not).
784 * ------------------------------------------------------------
786 static void dz_throttle (struct tty_struct *tty)
788 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
790 if (I_IXOFF(tty))
791 info->x_char = STOP_CHAR(tty);
794 static void dz_unthrottle (struct tty_struct *tty)
796 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
798 if (I_IXOFF(tty)) {
799 if (info->x_char)
800 info->x_char = 0;
801 else
802 info->x_char = START_CHAR(tty);
806 static void dz_send_xchar (struct tty_struct *tty, char ch)
808 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
810 info->x_char = ch;
812 if (ch) dz_start (info->tty);
816 * ------------------------------------------------------------
817 * rs_ioctl () and friends
818 * ------------------------------------------------------------
820 static int get_serial_info (struct dz_serial *info, struct serial_struct *retinfo)
822 struct serial_struct tmp;
824 if (!retinfo)
825 return -EFAULT;
827 memset (&tmp, 0, sizeof(tmp));
829 tmp.type = info->type;
830 tmp.line = info->line;
831 tmp.port = info->port;
832 tmp.irq = SERIAL;
833 tmp.flags = info->flags;
834 tmp.baud_base = info->baud_base;
835 tmp.close_delay = info->close_delay;
836 tmp.closing_wait = info->closing_wait;
838 return copy_to_user (retinfo, &tmp, sizeof(*retinfo));
841 static int set_serial_info (struct dz_serial *info, struct serial_struct *new_info)
843 struct serial_struct new_serial;
844 struct dz_serial old_info;
845 int retval = 0;
847 if (!new_info)
848 return -EFAULT;
850 copy_from_user (&new_serial, new_info, sizeof(new_serial));
851 old_info = *info;
853 if (!suser())
854 return -EPERM;
856 if (info->count > 1)
857 return -EBUSY;
860 * OK, past this point, all the error checking has been done.
861 * At this point, we start making changes.....
864 info->baud_base = new_serial.baud_base;
865 info->type = new_serial.type;
866 info->close_delay = new_serial.close_delay;
867 info->closing_wait = new_serial.closing_wait;
869 retval = startup (info);
870 return retval;
874 * get_lsr_info - get line status register info
876 * Purpose: Let user call ioctl() to get info when the UART physically
877 * is emptied. On bus types like RS485, the transmitter must
878 * release the bus after transmitting. This must be done when
879 * the transmit shift register is empty, not be done when the
880 * transmit holding register is empty. This functionality
881 * allows an RS485 driver to be written in user space.
883 static int get_lsr_info (struct dz_serial *info, unsigned int *value)
885 unsigned short status = dz_in (info, DZ_LPR);
887 return put_user (status, value);
891 * This routine sends a break character out the serial port.
893 static void send_break (struct dz_serial *info, int duration)
895 unsigned long flags;
896 unsigned short tmp, mask;
898 if (!info->port)
899 return;
901 mask = 1 << info->line;
902 tmp = dz_in (info, DZ_TCR);
903 tmp |= mask;
905 current->state = TASK_INTERRUPTIBLE;
907 save_flags (flags);
908 cli();
910 dz_out (info, DZ_TCR, tmp);
912 schedule_timeout(duration);
914 tmp &= ~mask;
915 dz_out (info, DZ_TCR, tmp);
917 restore_flags (flags);
920 static int dz_ioctl (struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
922 int error;
923 struct dz_serial * info = (struct dz_serial *)tty->driver_data;
924 int retval;
926 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
927 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
928 (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
929 if (tty->flags & (1 << TTY_IO_ERROR))
930 return -EIO;
933 switch (cmd) {
934 case TCSBRK: /* SVID version: non-zero arg --> no break */
935 retval = tty_check_change (tty);
936 if (retval)
937 return retval;
938 tty_wait_until_sent (tty, 0);
939 if (!arg)
940 send_break (info, HZ/4); /* 1/4 second */
941 return 0;
943 case TCSBRKP: /* support for POSIX tcsendbreak() */
944 retval = tty_check_change (tty);
945 if (retval)
946 return retval;
947 tty_wait_until_sent (tty, 0);
948 send_break (info, arg ? arg*(HZ/10) : HZ/4);
949 return 0;
951 case TIOCGSOFTCAR:
952 error = verify_area (VERIFY_WRITE, (void *)arg, sizeof(long));
953 if (error)
954 return error;
955 put_user (C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
956 return 0;
958 case TIOCSSOFTCAR:
959 error = get_user (arg, (unsigned long *)arg);
960 if (error)
961 return error;
962 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
963 return 0;
965 case TIOCGSERIAL:
966 error = verify_area (VERIFY_WRITE, (void *)arg, sizeof(struct serial_struct));
967 if (error)
968 return error;
969 return get_serial_info (info, (struct serial_struct *)arg);
971 case TIOCSSERIAL:
972 return set_serial_info (info, (struct serial_struct *) arg);
974 case TIOCSERGETLSR: /* Get line status register */
975 error = verify_area (VERIFY_WRITE, (void *)arg, sizeof(unsigned int));
976 if (error)
977 return error;
978 else
979 return get_lsr_info (info, (unsigned int *)arg);
981 case TIOCSERGSTRUCT:
982 error = verify_area (VERIFY_WRITE, (void *)arg, sizeof(struct dz_serial));
983 if (error)
984 return error;
985 copy_to_user((struct dz_serial *)arg, info, sizeof(struct dz_serial));
986 return 0;
988 default:
989 return -ENOIOCTLCMD;
992 return 0;
995 static void dz_set_termios (struct tty_struct *tty,
996 struct termios *old_termios)
998 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
1000 if (tty->termios->c_cflag == old_termios->c_cflag)
1001 return;
1003 change_speed (info);
1005 if ((old_termios->c_cflag & CRTSCTS) &&
1006 !(tty->termios->c_cflag & CRTSCTS)) {
1007 tty->hw_stopped = 0;
1008 dz_start (tty);
1013 * ------------------------------------------------------------
1014 * dz_close()
1016 * This routine is called when the serial port gets closed. First, we
1017 * wait for the last remaining data to be sent. Then, we turn off
1018 * the transmit enable and receive enable flags.
1019 * ------------------------------------------------------------
1021 static void dz_close (struct tty_struct *tty, struct file *filp)
1023 struct dz_serial * info = (struct dz_serial *)tty->driver_data;
1024 unsigned long flags;
1026 if (!info) return;
1028 save_flags (flags);
1029 cli();
1031 if (tty_hung_up_p (filp)) {
1032 restore_flags (flags);
1033 return;
1036 if ((tty->count == 1) && (info->count != 1)) {
1038 * Uh, oh. tty->count is 1, which means that the tty
1039 * structure will be freed. Info->count should always
1040 * be one in these conditions. If it's greater than
1041 * one, we've got real problems, since it means the
1042 * serial port won't be shutdown.
1044 printk("dz_close: bad serial port count; tty->count is 1, "
1045 "info->count is %d\n", info->count);
1046 info->count = 1;
1049 if (--info->count < 0) {
1050 printk("ds_close: bad serial port count for ttys%d: %d\n",
1051 info->line, info->count);
1052 info->count = 0;
1055 if (info->count) {
1056 restore_flags (flags);
1057 return;
1059 info->flags |= DZ_CLOSING;
1061 * Save the termios structure, since this port may have
1062 * separate termios for callout and dialin.
1064 if (info->flags & DZ_NORMAL_ACTIVE)
1065 info->normal_termios = *tty->termios;
1066 if (info->flags & DZ_CALLOUT_ACTIVE)
1067 info->callout_termios = *tty->termios;
1069 * Now we wait for the transmit buffer to clear; and we notify
1070 * the line discipline to only process XON/XOFF characters.
1072 tty->closing = 1;
1074 if (info->closing_wait != DZ_CLOSING_WAIT_NONE)
1075 tty_wait_until_sent (tty, info->closing_wait);
1078 * At this point we stop accepting input. To do this, we
1079 * disable the receive line status interrupts.
1082 shutdown (info);
1084 if (tty->driver.flush_buffer)
1085 tty->driver.flush_buffer (tty);
1086 if (tty->ldisc.flush_buffer)
1087 tty->ldisc.flush_buffer (tty);
1088 tty->closing = 0;
1089 info->event = 0;
1090 info->tty = 0;
1092 if (tty->ldisc.num != ldiscs[N_TTY].num) {
1093 if (tty->ldisc.close)
1094 (tty->ldisc.close)(tty);
1095 tty->ldisc = ldiscs[N_TTY];
1096 tty->termios->c_line = N_TTY;
1097 if (tty->ldisc.open)
1098 (tty->ldisc.open)(tty);
1100 if (info->blocked_open) {
1101 if (info->close_delay) {
1102 current->state = TASK_INTERRUPTIBLE;
1103 schedule_timeout(info->close_delay);
1105 wake_up_interruptible (&info->open_wait);
1108 info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING);
1109 wake_up_interruptible (&info->close_wait);
1111 restore_flags (flags);
1115 * dz_hangup () --- called by tty_hangup() when a hangup is signaled.
1117 static void dz_hangup (struct tty_struct *tty)
1119 struct dz_serial *info = (struct dz_serial *)tty->driver_data;
1121 dz_flush_buffer (tty);
1122 shutdown (info);
1123 info->event = 0;
1124 info->count = 0;
1125 info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE);
1126 info->tty = 0;
1127 wake_up_interruptible (&info->open_wait);
1131 * ------------------------------------------------------------
1132 * rs_open() and friends
1133 * ------------------------------------------------------------
1135 static int block_til_ready (struct tty_struct *tty, struct file *filp, struct dz_serial *info)
1137 DECLARE_WAITQUEUE(wait, current);
1138 int retval;
1139 int do_clocal = 0;
1142 * If the device is in the middle of being closed, then block
1143 * until it's done, and then try again.
1145 if (info->flags & DZ_CLOSING) {
1146 interruptible_sleep_on (&info->close_wait);
1147 return -EAGAIN;
1151 * If this is a callout device, then just make sure the normal
1152 * device isn't being used.
1154 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
1155 if (info->flags & DZ_NORMAL_ACTIVE)
1156 return -EBUSY;
1158 if ((info->flags & DZ_CALLOUT_ACTIVE) &&
1159 (info->flags & DZ_SESSION_LOCKOUT) &&
1160 (info->session != current->session))
1161 return -EBUSY;
1163 if ((info->flags & DZ_CALLOUT_ACTIVE) &&
1164 (info->flags & DZ_PGRP_LOCKOUT) &&
1165 (info->pgrp != current->pgrp))
1166 return -EBUSY;
1167 info->flags |= DZ_CALLOUT_ACTIVE;
1168 return 0;
1172 * If non-blocking mode is set, or the port is not enabled,
1173 * then make the check up front and then exit.
1175 if ((filp->f_flags & O_NONBLOCK) ||
1176 (tty->flags & (1 << TTY_IO_ERROR))) {
1177 if (info->flags & DZ_CALLOUT_ACTIVE)
1178 return -EBUSY;
1179 info->flags |= DZ_NORMAL_ACTIVE;
1180 return 0;
1183 if (info->flags & DZ_CALLOUT_ACTIVE) {
1184 if (info->normal_termios.c_cflag & CLOCAL)
1185 do_clocal = 1;
1186 } else {
1187 if (tty->termios->c_cflag & CLOCAL)
1188 do_clocal = 1;
1192 * Block waiting for the carrier detect and the line to become
1193 * free (i.e., not in use by the callout). While we are in
1194 * this loop, info->count is dropped by one, so that
1195 * dz_close() knows when to free things. We restore it upon
1196 * exit, either normal or abnormal.
1198 retval = 0;
1199 add_wait_queue (&info->open_wait, &wait);
1201 info->count--;
1202 info->blocked_open++;
1203 while (1) {
1204 set_current_state(TASK_INTERRUPTIBLE);
1205 if (tty_hung_up_p (filp) || !(info->is_initialized)) {
1206 retval = -EAGAIN;
1207 break;
1209 if (!(info->flags & DZ_CALLOUT_ACTIVE) &&
1210 !(info->flags & DZ_CLOSING) && do_clocal)
1211 break;
1212 if (signal_pending (current)) {
1213 retval = -ERESTARTSYS;
1214 break;
1216 schedule();
1219 current->state = TASK_RUNNING;
1220 remove_wait_queue (&info->open_wait, &wait);
1221 if (!tty_hung_up_p(filp))
1222 info->count++;
1223 info->blocked_open--;
1225 if (retval)
1226 return retval;
1227 info->flags |= DZ_NORMAL_ACTIVE;
1228 return 0;
1232 * This routine is called whenever a serial port is opened. It
1233 * enables interrupts for a serial port. It also performs the
1234 * serial-specific initialization for the tty structure.
1236 static int dz_open (struct tty_struct *tty, struct file *filp)
1238 struct dz_serial *info;
1239 int retval, line;
1241 line = MINOR(tty->device) - tty->driver.minor_start;
1243 /* The dz lines for the mouse/keyboard must be
1244 * opened using their respective drivers.
1246 if ((line < 0) || (line >= DZ_NB_PORT))
1247 return -ENODEV;
1249 if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE))
1250 return -ENODEV;
1252 info = lines[line];
1253 info->count++;
1255 tty->driver_data = info;
1256 info->tty = tty;
1259 * Start up serial port
1261 retval = startup (info);
1262 if (retval)
1263 return retval;
1267 retval = block_til_ready (tty, filp, info);
1268 if (retval)
1269 return retval;
1271 if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) {
1272 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
1273 *tty->termios = info->normal_termios;
1274 else
1275 *tty->termios = info->callout_termios;
1276 change_speed (info);
1280 info->session = current->session;
1281 info->pgrp = current->pgrp;
1282 return 0;
1285 static void show_serial_version (void)
1287 printk("%s%s\n", dz_name, dz_version);
1291 int __init dz_init(void)
1293 int i, flags;
1294 struct dz_serial *info;
1296 /* Setup base handler, and timer table. */
1297 init_bh (SERIAL_BH, do_serial_bh);
1299 show_serial_version ();
1301 memset(&serial_driver, 0, sizeof(struct tty_driver));
1302 serial_driver.magic = TTY_DRIVER_MAGIC;
1303 serial_driver.name = "ttyS";
1304 serial_driver.major = TTY_MAJOR;
1305 serial_driver.minor_start = 64;
1306 serial_driver.num = DZ_NB_PORT;
1307 serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
1308 serial_driver.subtype = SERIAL_TYPE_NORMAL;
1309 serial_driver.init_termios = tty_std_termios;
1311 serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1312 serial_driver.flags = TTY_DRIVER_REAL_RAW;
1313 serial_driver.refcount = &serial_refcount;
1314 serial_driver.table = serial_table;
1315 serial_driver.termios = serial_termios;
1316 serial_driver.termios_locked = serial_termios_locked;
1318 serial_driver.open = dz_open;
1319 serial_driver.close = dz_close;
1320 serial_driver.write = dz_write;
1321 serial_driver.flush_chars = dz_flush_chars;
1322 serial_driver.write_room = dz_write_room;
1323 serial_driver.chars_in_buffer = dz_chars_in_buffer;
1324 serial_driver.flush_buffer = dz_flush_buffer;
1325 serial_driver.ioctl = dz_ioctl;
1326 serial_driver.throttle = dz_throttle;
1327 serial_driver.unthrottle = dz_unthrottle;
1328 serial_driver.send_xchar = dz_send_xchar;
1329 serial_driver.set_termios = dz_set_termios;
1330 serial_driver.stop = dz_stop;
1331 serial_driver.start = dz_start;
1332 serial_driver.hangup = dz_hangup;
1335 * The callout device is just like normal device except for
1336 * major number and the subtype code.
1338 callout_driver = serial_driver;
1339 callout_driver.name = "cua";
1340 callout_driver.major = TTYAUX_MAJOR;
1341 callout_driver.subtype = SERIAL_TYPE_CALLOUT;
1343 if (tty_register_driver (&serial_driver))
1344 panic("Couldn't register serial driver\n");
1345 if (tty_register_driver (&callout_driver))
1346 panic("Couldn't register callout driver\n");
1347 save_flags(flags); cli();
1349 for (i=0; i < DZ_NB_PORT; i++)
1351 info = &multi[i];
1352 lines[i] = info;
1353 info->magic = SERIAL_MAGIC;
1355 if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100))
1356 info->port = (unsigned long) KN01_DZ11_BASE;
1357 else
1358 info->port = (unsigned long) KN02_DZ11_BASE;
1360 info->line = i;
1361 info->tty = 0;
1362 info->close_delay = 50;
1363 info->closing_wait = 3000;
1364 info->x_char = 0;
1365 info->event = 0;
1366 info->count = 0;
1367 info->blocked_open = 0;
1368 info->tqueue.routine = do_softint;
1369 info->tqueue.data = info;
1370 info->tqueue_hangup.routine = do_serial_hangup;
1371 info->tqueue_hangup.data = info;
1372 info->callout_termios = callout_driver.init_termios;
1373 info->normal_termios = serial_driver.init_termios;
1374 init_waitqueue_head(&info->open_wait);
1375 init_waitqueue_head(&info->close_wait);
1377 /* If we are pointing to address zero then punt - not correctly
1378 set up in setup.c to handle this. */
1379 if (! info->port)
1380 return 0;
1382 printk("ttyS%02d at 0x%04x (irq = %d)\n", info->line, info->port, SERIAL);
1385 /* reset the chip */
1386 #ifndef CONFIG_SERIAL_CONSOLE
1387 dz_out(info, DZ_CSR, DZ_CLR);
1388 while ((tmp = dz_in(info,DZ_CSR)) & DZ_CLR) ;
1389 wbflush();
1391 /* enable scanning */
1392 dz_out(info, DZ_CSR, DZ_MSE);
1393 #endif
1395 /* order matters here... the trick is that flags
1396 is updated... in request_irq - to immediatedly obliterate
1397 it is unwise. */
1398 restore_flags(flags);
1401 if (request_irq (SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))
1402 panic ("Unable to register DZ interrupt\n");
1404 return 0;
1407 #ifdef CONFIG_SERIAL_CONSOLE
1408 static void dz_console_put_char (unsigned char ch)
1410 unsigned long flags;
1411 int loops = 2500;
1412 unsigned short tmp = ch;
1413 /* this code sends stuff out to serial device - spinning its
1414 wheels and waiting. */
1416 /* force the issue - point it at lines[3]*/
1417 dz_console=&multi[CONSOLE_LINE];
1419 save_flags(flags);
1420 cli();
1423 /* spin our wheels */
1424 while (((dz_in(dz_console,DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--)
1427 /* Actually transmit the character. */
1428 dz_out (dz_console, DZ_TDR, tmp);
1430 restore_flags(flags);
1433 * -------------------------------------------------------------------
1434 * dz_console_print ()
1436 * dz_console_print is registered for printk.
1437 * The console_lock must be held when we get here.
1438 * -------------------------------------------------------------------
1440 static void dz_console_print (struct console *cons,
1441 const char *str,
1442 unsigned int count)
1444 #ifdef DEBUG_DZ
1445 prom_printf((char *)str);
1446 #endif
1447 while (count--)
1449 if (*str == '\n')
1450 dz_console_put_char ('\r');
1451 dz_console_put_char (*str++);
1455 static int dz_console_wait_key(struct console *co)
1457 return 0;
1460 static kdev_t dz_console_device(struct console *c)
1462 return MKDEV(TTY_MAJOR, 64 + c->index);
1465 static int __init dz_console_setup(struct console *co, char *options)
1467 int baud = 9600;
1468 int bits = 8;
1469 int parity = 'n';
1470 int cflag = CREAD | HUPCL | CLOCAL;
1471 char *s;
1472 unsigned short mask,tmp;
1474 if (options) {
1475 baud = simple_strtoul(options, NULL, 10);
1476 s = options;
1477 while(*s >= '0' && *s <= '9')
1478 s++;
1479 if (*s)
1480 parity = *s++;
1481 if (*s)
1482 bits = *s - '0';
1486 * Now construct a cflag setting.
1488 switch(baud) {
1489 case 1200:
1490 cflag |= DZ_B1200;
1491 break;
1492 case 2400:
1493 cflag |= DZ_B2400;
1494 break;
1495 case 4800:
1496 cflag |= DZ_B4800;
1497 break;
1498 case 9600:
1499 default:
1500 cflag |= DZ_B9600;
1501 break;
1503 switch(bits) {
1504 case 7:
1505 cflag |= DZ_CS7;
1506 break;
1507 default:
1508 case 8:
1509 cflag |= DZ_CS8;
1510 break;
1512 switch(parity) {
1513 case 'o': case 'O':
1514 cflag |= DZ_PARODD;
1515 break;
1516 case 'e': case 'E':
1517 cflag |= DZ_PARENB;
1518 break;
1520 co->cflag = cflag;
1522 /* TOFIX: force to console line */
1523 dz_console = &multi[CONSOLE_LINE];
1524 if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100))
1525 dz_console->port = KN01_DZ11_BASE;
1526 else
1527 dz_console->port = KN02_DZ11_BASE;
1528 dz_console->line = CONSOLE_LINE;
1530 dz_out(dz_console, DZ_CSR, DZ_CLR);
1531 while ((tmp = dz_in(dz_console,DZ_CSR)) & DZ_CLR)
1534 /* enable scanning */
1535 dz_out(dz_console, DZ_CSR, DZ_MSE);
1537 /* Set up flags... */
1538 dz_console->cflags = 0;
1539 dz_console->cflags |= DZ_B9600;
1540 dz_console->cflags |= DZ_CS8;
1541 dz_console->cflags |= DZ_PARENB;
1542 dz_out (dz_console, DZ_LPR, dz_console->cflags);
1544 mask = 1 << dz_console->line;
1545 tmp = dz_in (dz_console, DZ_TCR); /* read the TX flag */
1546 if (!(tmp & mask)) {
1547 tmp |= mask; /* set the TX flag */
1548 dz_out (dz_console, DZ_TCR, tmp);
1552 return 0;
1555 static struct console dz_sercons = {
1556 name: "ttyS",
1557 write: dz_console_print,
1558 device: dz_console_device,
1559 wait_key: dz_console_wait_key,
1560 setup: dz_console_setup,
1561 flags: CON_CONSDEV | CON_PRINTBUFFER,
1562 index: CONSOLE_LINE,
1565 void __init dz_serial_console_init(void)
1567 register_console(&dz_sercons);
1570 #endif /* ifdef CONFIG_SERIAL_CONSOLE */