2 * drivers/s390/char/hwc_tty.c
3 * HWC line mode terminal driver.
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
9 * Thanks to Martin Schwidefsky.
12 #include <linux/config.h>
13 #include <linux/major.h>
14 #include <linux/termios.h>
15 #include <linux/tty.h>
16 #include <linux/tty_driver.h>
17 #include <linux/sched.h>
19 #include <linux/devfs_fs_kernel.h>
20 #include <linux/init.h>
22 #include <asm/uaccess.h>
27 #define HWC_TTY_PRINT_HEADER "hwc tty driver: "
29 #define HWC_TTY_BUF_SIZE 512
33 struct tty_struct *tty;
35 unsigned char buf[HWC_TTY_BUF_SIZE];
37 unsigned short int buf_count;
41 hwc_high_level_calls_t calls;
42 } hwc_tty_data_struct;
44 static hwc_tty_data_struct hwc_tty_data =
46 static struct tty_driver hwc_tty_driver;
47 static struct tty_struct *hwc_tty_table[1];
48 static struct termios *hwc_tty_termios[1];
49 static struct termios *hwc_tty_termios_locked[1];
50 static int hwc_tty_refcount = 0;
52 extern struct termios tty_std_termios;
54 void hwc_tty_wake_up (void);
55 void hwc_tty_input (unsigned char *, unsigned int);
58 hwc_tty_open (struct tty_struct *tty,
62 if (MINOR (tty->device) - tty->driver.minor_start)
65 tty->driver_data = &hwc_tty_data;
66 hwc_tty_data.buf_count = 0;
67 hwc_tty_data.tty = tty;
70 hwc_tty_data.calls.wake_up = hwc_tty_wake_up;
71 hwc_tty_data.calls.move_input = hwc_tty_input;
72 hwc_register_calls (&(hwc_tty_data.calls));
78 hwc_tty_close (struct tty_struct *tty,
81 if (MINOR (tty->device) != tty->driver.minor_start) {
82 printk (KERN_WARNING HWC_TTY_PRINT_HEADER
83 "do not close hwc tty because of wrong device number");
89 hwc_tty_data.tty = NULL;
91 hwc_unregister_calls (&(hwc_tty_data.calls));
95 hwc_tty_write_room (struct tty_struct *tty)
99 retval = hwc_write_room (IN_BUFS_TOTAL);
104 hwc_tty_write (struct tty_struct *tty,
106 const unsigned char *buf,
111 if (hwc_tty_data.buf_count > 0) {
112 hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
113 hwc_tty_data.buf_count = 0;
115 retval = hwc_write (from_user, buf, count);
120 hwc_tty_put_char (struct tty_struct *tty,
125 spin_lock_irqsave (&hwc_tty_data.lock, flags);
126 if (hwc_tty_data.buf_count >= HWC_TTY_BUF_SIZE) {
127 hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
128 hwc_tty_data.buf_count = 0;
130 hwc_tty_data.buf[hwc_tty_data.buf_count] = ch;
131 hwc_tty_data.buf_count++;
132 spin_unlock_irqrestore (&hwc_tty_data.lock, flags);
136 hwc_tty_flush_chars (struct tty_struct *tty)
140 spin_lock_irqsave (&hwc_tty_data.lock, flags);
141 hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
142 hwc_tty_data.buf_count = 0;
143 spin_unlock_irqrestore (&hwc_tty_data.lock, flags);
147 hwc_tty_chars_in_buffer (struct tty_struct *tty)
151 retval = hwc_chars_in_buffer (IN_BUFS_TOTAL);
156 hwc_tty_flush_buffer (struct tty_struct *tty)
163 struct tty_struct *tty,
168 if (tty->flags & (1 << TTY_IO_ERROR))
171 return hwc_ioctl (cmd, arg);
175 hwc_tty_wake_up (void)
177 if (hwc_tty_data.tty == NULL)
179 if ((hwc_tty_data.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
180 hwc_tty_data.tty->ldisc.write_wakeup)
181 (hwc_tty_data.tty->ldisc.write_wakeup) (hwc_tty_data.tty);
182 wake_up_interruptible (&hwc_tty_data.tty->write_wait);
186 hwc_tty_input (unsigned char *buf, unsigned int count)
188 struct tty_struct *tty = hwc_tty_data.tty;
192 if ((cchar = ctrlchar_handle (buf, count, tty))) {
193 if (cchar == (char *) -1)
196 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
197 *tty->flip.char_buf_ptr++ = *cchar;
200 memcpy (tty->flip.char_buf_ptr, buf, count);
202 strncmp (buf + count - 2, "^n", 2) ||
203 strncmp (buf + count - 2, "\0252n", 2))) {
204 tty->flip.char_buf_ptr[count] = '\n';
208 memset (tty->flip.flag_buf_ptr, TTY_NORMAL, count);
209 tty->flip.char_buf_ptr += count;
210 tty->flip.flag_buf_ptr += count;
211 tty->flip.count += count;
213 tty_flip_buffer_push (tty);
226 memset (&hwc_tty_driver, 0, sizeof (struct tty_driver));
227 memset (&hwc_tty_data, 0, sizeof (hwc_tty_data_struct));
228 hwc_tty_driver.magic = TTY_DRIVER_MAGIC;
229 hwc_tty_driver.driver_name = "tty_hwc";
230 hwc_tty_driver.name = "ttyS";
231 hwc_tty_driver.name_base = 0;
232 hwc_tty_driver.major = TTY_MAJOR;
233 hwc_tty_driver.minor_start = 64;
234 hwc_tty_driver.num = 1;
235 hwc_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM;
236 hwc_tty_driver.subtype = SYSTEM_TYPE_TTY;
237 hwc_tty_driver.init_termios = tty_std_termios;
238 hwc_tty_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
239 hwc_tty_driver.init_termios.c_oflag = ONLCR;
240 hwc_tty_driver.init_termios.c_lflag = ISIG | ECHO;
241 hwc_tty_driver.flags = TTY_DRIVER_REAL_RAW;
242 hwc_tty_driver.refcount = &hwc_tty_refcount;
244 hwc_tty_driver.table = hwc_tty_table;
245 hwc_tty_driver.termios = hwc_tty_termios;
246 hwc_tty_driver.termios_locked = hwc_tty_termios_locked;
248 hwc_tty_driver.open = hwc_tty_open;
249 hwc_tty_driver.close = hwc_tty_close;
250 hwc_tty_driver.write = hwc_tty_write;
251 hwc_tty_driver.put_char = hwc_tty_put_char;
252 hwc_tty_driver.flush_chars = hwc_tty_flush_chars;
253 hwc_tty_driver.write_room = hwc_tty_write_room;
254 hwc_tty_driver.chars_in_buffer = hwc_tty_chars_in_buffer;
255 hwc_tty_driver.flush_buffer = hwc_tty_flush_buffer;
256 hwc_tty_driver.ioctl = hwc_tty_ioctl;
258 hwc_tty_driver.throttle = NULL;
259 hwc_tty_driver.unthrottle = NULL;
260 hwc_tty_driver.send_xchar = NULL;
261 hwc_tty_driver.set_termios = NULL;
262 hwc_tty_driver.set_ldisc = NULL;
263 hwc_tty_driver.stop = NULL;
264 hwc_tty_driver.start = NULL;
265 hwc_tty_driver.hangup = NULL;
266 hwc_tty_driver.break_ctl = NULL;
267 hwc_tty_driver.wait_until_sent = NULL;
268 hwc_tty_driver.read_proc = NULL;
269 hwc_tty_driver.write_proc = NULL;
271 if (tty_register_driver (&hwc_tty_driver))
272 panic ("Couldn't register hwc_tty driver\n");