OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [s390/] [char/] [hwc_tty.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  drivers/s390/char/hwc_tty.c
3
 *    HWC line mode terminal driver.
4
 *
5
 *  S390 version
6
 *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7
 *    Author(s): Martin Peschke <mpeschke@de.ibm.com>
8
 *
9
 *  Thanks to Martin Schwidefsky.
10
 */
11
 
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>
18
#include <linux/mm.h>
19
#include <linux/devfs_fs_kernel.h>
20
#include <linux/init.h>
21
 
22
#include <asm/uaccess.h>
23
 
24
#include "hwc_rw.h"
25
#include "ctrlchar.h"
26
 
27
#define HWC_TTY_PRINT_HEADER "hwc tty driver: "
28
 
29
#define HWC_TTY_BUF_SIZE 512
30
 
31
typedef struct {
32
 
33
        struct tty_struct *tty;
34
 
35
        unsigned char buf[HWC_TTY_BUF_SIZE];
36
 
37
        unsigned short int buf_count;
38
 
39
        spinlock_t lock;
40
 
41
        hwc_high_level_calls_t calls;
42
} hwc_tty_data_struct;
43
 
44
static hwc_tty_data_struct hwc_tty_data =
45
{ /* NULL/0 */ };
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;
51
 
52
extern struct termios tty_std_termios;
53
 
54
void hwc_tty_wake_up (void);
55
void hwc_tty_input (unsigned char *, unsigned int);
56
 
57
static int
58
hwc_tty_open (struct tty_struct *tty,
59
              struct file *filp)
60
{
61
 
62
        if (MINOR (tty->device) - tty->driver.minor_start)
63
                return -ENODEV;
64
 
65
        tty->driver_data = &hwc_tty_data;
66
        hwc_tty_data.buf_count = 0;
67
        hwc_tty_data.tty = tty;
68
        tty->low_latency = 0;
69
 
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));
73
 
74
        return 0;
75
}
76
 
77
static void
78
hwc_tty_close (struct tty_struct *tty,
79
               struct file *filp)
80
{
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");
84
                return;
85
        }
86
        if (tty->count > 1)
87
                return;
88
 
89
        hwc_tty_data.tty = NULL;
90
 
91
        hwc_unregister_calls (&(hwc_tty_data.calls));
92
}
93
 
94
static int
95
hwc_tty_write_room (struct tty_struct *tty)
96
{
97
        int retval;
98
 
99
        retval = hwc_write_room (IN_BUFS_TOTAL);
100
        return retval;
101
}
102
 
103
static int
104
hwc_tty_write (struct tty_struct *tty,
105
               int from_user,
106
               const unsigned char *buf,
107
               int count)
108
{
109
        int retval;
110
 
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;
114
        }
115
        retval = hwc_write (from_user, buf, count);
116
        return retval;
117
}
118
 
119
static void
120
hwc_tty_put_char (struct tty_struct *tty,
121
                  unsigned char ch)
122
{
123
        unsigned long flags;
124
 
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;
129
        }
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);
133
}
134
 
135
static void
136
hwc_tty_flush_chars (struct tty_struct *tty)
137
{
138
        unsigned long flags;
139
 
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);
144
}
145
 
146
static int
147
hwc_tty_chars_in_buffer (struct tty_struct *tty)
148
{
149
        int retval;
150
 
151
        retval = hwc_chars_in_buffer (IN_BUFS_TOTAL);
152
        return retval;
153
}
154
 
155
static void
156
hwc_tty_flush_buffer (struct tty_struct *tty)
157
{
158
        hwc_tty_wake_up ();
159
}
160
 
161
static int
162
hwc_tty_ioctl (
163
                      struct tty_struct *tty,
164
                      struct file *file,
165
                      unsigned int cmd,
166
                      unsigned long arg)
167
{
168
        if (tty->flags & (1 << TTY_IO_ERROR))
169
                return -EIO;
170
 
171
        return hwc_ioctl (cmd, arg);
172
}
173
 
174
void
175
hwc_tty_wake_up (void)
176
{
177
        if (hwc_tty_data.tty == NULL)
178
                return;
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);
183
}
184
 
185
void
186
hwc_tty_input (unsigned char *buf, unsigned int count)
187
{
188
        struct tty_struct *tty = hwc_tty_data.tty;
189
 
190
        if (tty != NULL) {
191
                char *cchar;
192
                if ((cchar = ctrlchar_handle (buf, count, tty))) {
193
                        if (cchar == (char *) -1)
194
                                return;
195
                        tty->flip.count++;
196
                        *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
197
                        *tty->flip.char_buf_ptr++ = *cchar;
198
                } else {
199
 
200
                        memcpy (tty->flip.char_buf_ptr, buf, count);
201
                        if (count < 2 || (
202
                                         strncmp (buf + count - 2, "^n", 2) ||
203
                                    strncmp (buf + count - 2, "\0252n", 2))) {
204
                                tty->flip.char_buf_ptr[count] = '\n';
205
                                count++;
206
                        } else
207
                                count -= 2;
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;
212
                }
213
                tty_flip_buffer_push (tty);
214
                hwc_tty_wake_up ();
215
        }
216
}
217
 
218
void
219
hwc_tty_init (void)
220
{
221
        if (!CONSOLE_IS_HWC)
222
                return;
223
 
224
        ctrlchar_init ();
225
 
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;
243
 
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;
247
 
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;
257
 
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;
270
 
271
        if (tty_register_driver (&hwc_tty_driver))
272
                panic ("Couldn't register hwc_tty driver\n");
273
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.