This source file includes following definitions.
- modem_status_intr
- send_intr
- receive_intr
- line_status_intr
- check_tty
- do_IRQ3
- do_IRQ4
- com1_timer
- com2_timer
- com3_timer
- com4_timer
- do_rs_write
- com1_timeout
- com2_timeout
- com3_timeout
- com4_timeout
- init
- serial_open
- rs_init
- rs_write
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <signal.h>
17
18 #include <linux/sched.h>
19 #include <linux/timer.h>
20 #include <linux/tty.h>
21
22 #include <asm/system.h>
23 #include <asm/io.h>
24
25 #define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
26
27 extern void IRQ3_interrupt(void);
28 extern void IRQ4_interrupt(void);
29
30 static void modem_status_intr(unsigned line, unsigned port, struct tty_struct * tty)
31 {
32 unsigned char status = inb(port+6);
33
34 if ((status & 0x88) == 0x08 && tty->pgrp > 0)
35 kill_pg(tty->pgrp,SIGHUP,1);
36 }
37
38
39
40
41
42
43
44
45
46
47 static void send_intr(unsigned line, unsigned port, struct tty_struct * tty)
48 {
49 int c;
50
51 #define TIMER ((SER1_TIMEOUT-1)+line)
52 timer_active &= ~(1 << TIMER);
53 if ((c = GETCH(tty->write_q)) < 0)
54 return;
55 outb(c,port);
56 timer_table[TIMER].expires = jiffies + 10;
57 timer_active |= 1 << TIMER;
58 if (LEFT(tty->write_q) > WAKEUP_CHARS)
59 wake_up(&tty->write_q->proc_list);
60 #undef TIMER
61 }
62
63 static void receive_intr(unsigned line, unsigned port, struct tty_struct * tty)
64 {
65 if (FULL(tty->read_q))
66 return;
67 PUTCH(inb(port),tty->read_q);
68 timer_active |= (1<<(SER1_TIMER-1))<<line;
69 }
70
71 static void line_status_intr(unsigned line, unsigned port, struct tty_struct * tty)
72 {
73 unsigned char status = inb(port+5);
74
75
76 }
77
78 static void (*jmp_table[4])(unsigned,unsigned,struct tty_struct *) = {
79 modem_status_intr,
80 send_intr,
81 receive_intr,
82 line_status_intr
83 };
84
85 static void check_tty(unsigned line,struct tty_struct * tty)
86 {
87 unsigned short port;
88 unsigned char ident;
89
90 if (!(port = tty->read_q->data))
91 return;
92 while (1) {
93 ident = inb(port+2);
94 if (ident & 1)
95 return;
96 ident >>= 1;
97 if (ident > 3)
98 return;
99 jmp_table[ident](line,port,tty);
100 }
101 }
102
103
104
105
106 void do_IRQ3(void)
107 {
108 check_tty(2,tty_table+65);
109 check_tty(4,tty_table+67);
110 }
111
112
113
114
115 void do_IRQ4(void)
116 {
117 check_tty(1,tty_table+64);
118 check_tty(3,tty_table+66);
119 }
120
121 static void com1_timer(void)
122 {
123 TTY_READ_FLUSH(tty_table+64);
124 }
125
126 static void com2_timer(void)
127 {
128 TTY_READ_FLUSH(tty_table+65);
129 }
130
131 static void com3_timer(void)
132 {
133 TTY_READ_FLUSH(tty_table+66);
134 }
135
136 static void com4_timer(void)
137 {
138 TTY_READ_FLUSH(tty_table+67);
139 }
140
141
142
143
144
145 static inline void do_rs_write(unsigned line, struct tty_struct * tty)
146 {
147 int port;
148
149 #define TIMER ((SER1_TIMEOUT-1)+line)
150 if (!tty || !tty->write_q || EMPTY(tty->write_q))
151 return;
152 if (!(port = tty->write_q->data))
153 return;
154 cli();
155 if (inb_p(port+5) & 0x20)
156 send_intr(line,port,tty);
157 else {
158 timer_table[TIMER].expires = jiffies + 10;
159 timer_active |= 1 << TIMER;
160 }
161 sti();
162 #undef TIMER
163 }
164
165 static void com1_timeout(void)
166 {
167 do_rs_write(1,tty_table+64);
168 }
169
170 static void com2_timeout(void)
171 {
172 do_rs_write(2,tty_table+65);
173 }
174
175 static void com3_timeout(void)
176 {
177 do_rs_write(3,tty_table+66);
178 }
179
180 static void com4_timeout(void)
181 {
182 do_rs_write(4,tty_table+67);
183 }
184
185 static void init(int port)
186 {
187 outb_p(0x80,port+3);
188 outb_p(0x30,port);
189 outb_p(0x00,port+1);
190 outb_p(0x03,port+3);
191 outb_p(0x00,port+4);
192 outb_p(0x0f,port+1);
193 (void)inb(port);
194 }
195
196
197
198
199
200 void serial_open(unsigned line)
201 {
202 unsigned short port;
203 unsigned short port2;
204
205 if (line>3)
206 return;
207 port = tty_table[64+line].read_q->data;
208 if (!port)
209 return;
210 port2 = tty_table[64+(line ^ 2)].read_q->data;
211 cli();
212 if (port2)
213 outb_p(0x00,port2+4);
214 outb_p(0x03,port+3);
215 outb_p(0x0f,port+4);
216 outb_p(0x0f,port+1);
217 inb_p(port+5);
218 inb_p(port+0);
219 inb_p(port+6);
220 inb(port+2);
221 sti();
222 }
223
224 void rs_init(void)
225 {
226
227 timer_table[SER1_TIMER].fn = com1_timer;
228 timer_table[SER1_TIMER].expires = 0;
229 timer_table[SER2_TIMER].fn = com2_timer;
230 timer_table[SER2_TIMER].expires = 0;
231 timer_table[SER3_TIMER].fn = com3_timer;
232 timer_table[SER3_TIMER].expires = 0;
233 timer_table[SER4_TIMER].fn = com4_timer;
234 timer_table[SER4_TIMER].expires = 0;
235
236 timer_table[SER1_TIMEOUT].fn = com1_timeout;
237 timer_table[SER1_TIMEOUT].expires = 0;
238 timer_table[SER2_TIMEOUT].fn = com2_timeout;
239 timer_table[SER2_TIMEOUT].expires = 0;
240 timer_table[SER3_TIMEOUT].fn = com3_timeout;
241 timer_table[SER3_TIMEOUT].expires = 0;
242 timer_table[SER4_TIMEOUT].fn = com4_timeout;
243 timer_table[SER4_TIMEOUT].expires = 0;
244 set_intr_gate(0x23,IRQ3_interrupt);
245 set_intr_gate(0x24,IRQ4_interrupt);
246 init(tty_table[64].read_q->data);
247 init(tty_table[65].read_q->data);
248 init(tty_table[66].read_q->data);
249 init(tty_table[67].read_q->data);
250 outb(inb_p(0x21)&0xE7,0x21);
251 }
252
253
254
255
256
257
258
259
260 void rs_write(struct tty_struct * tty)
261 {
262 int line = tty - tty_table - 63;
263
264 do_rs_write(line,tty);
265 }