diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-22 20:09:33 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-22 20:09:33 -0500 |
commit | 4c37705877e74c02c968735c2eee0f84914cf557 (patch) | |
tree | 87af608b211f1b6920927ab101a192ee4529946b /drivers/char | |
parent | 4a6514e6d096716fb7bedf238efaaca877e2a7e8 (diff) |
tty: move obsolete and broken generic_serial drivers to drivers/staging/generic_serial/
As planned by Arnd Bergmann, this moves the following drivers to the
drivers/staging/generic_serial directory where they will be removed
after 2.6.41 if no one steps up to claim them.
generic_serial
rio
ser_a2232
sx
vme_scc
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char')
51 files changed, 0 insertions, 20308 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 7b8cf0295f6c..04f8b2d083c6 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -15,34 +15,6 @@ config DEVKMEM | |||
15 | kind of kernel debugging operations. | 15 | kind of kernel debugging operations. |
16 | When in doubt, say "N". | 16 | When in doubt, say "N". |
17 | 17 | ||
18 | config SX | ||
19 | tristate "Specialix SX (and SI) card support" | ||
20 | depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN | ||
21 | help | ||
22 | This is a driver for the SX and SI multiport serial cards. | ||
23 | Please read the file <file:Documentation/serial/sx.txt> for details. | ||
24 | |||
25 | This driver can only be built as a module ( = code which can be | ||
26 | inserted in and removed from the running kernel whenever you want). | ||
27 | The module will be called sx. If you want to do that, say M here. | ||
28 | |||
29 | config RIO | ||
30 | tristate "Specialix RIO system support" | ||
31 | depends on SERIAL_NONSTANDARD && BROKEN | ||
32 | help | ||
33 | This is a driver for the Specialix RIO, a smart serial card which | ||
34 | drives an outboard box that can support up to 128 ports. Product | ||
35 | information is at <http://www.perle.com/support/documentation.html#multiport>. | ||
36 | There are both ISA and PCI versions. | ||
37 | |||
38 | config RIO_OLDPCI | ||
39 | bool "Support really old RIO/PCI cards" | ||
40 | depends on RIO | ||
41 | help | ||
42 | Older RIO PCI cards need some initialization-time configuration to | ||
43 | determine the IRQ and some control addresses. If you have a RIO and | ||
44 | this doesn't seem to work, try setting this to Y. | ||
45 | |||
46 | config STALDRV | 18 | config STALDRV |
47 | bool "Stallion multiport serial support" | 19 | bool "Stallion multiport serial support" |
48 | depends on SERIAL_NONSTANDARD | 20 | depends on SERIAL_NONSTANDARD |
@@ -55,22 +27,6 @@ config STALDRV | |||
55 | in this case. If you have never heard about all this, it's safe to | 27 | in this case. If you have never heard about all this, it's safe to |
56 | say N. | 28 | say N. |
57 | 29 | ||
58 | config A2232 | ||
59 | tristate "Commodore A2232 serial support (EXPERIMENTAL)" | ||
60 | depends on EXPERIMENTAL && ZORRO && BROKEN | ||
61 | ---help--- | ||
62 | This option supports the 2232 7-port serial card shipped with the | ||
63 | Amiga 2000 and other Zorro-bus machines, dating from 1989. At | ||
64 | a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip | ||
65 | each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The | ||
66 | ports were connected with 8 pin DIN connectors on the card bracket, | ||
67 | for which 8 pin to DB25 adapters were supplied. The card also had | ||
68 | jumpers internally to toggle various pinning configurations. | ||
69 | |||
70 | This driver can be built as a module; but then "generic_serial" | ||
71 | will also be built as a module. This has to be loaded before | ||
72 | "ser_a2232". If you want to do this, answer M here. | ||
73 | |||
74 | config SGI_SNSC | 30 | config SGI_SNSC |
75 | bool "SGI Altix system controller communication support" | 31 | bool "SGI Altix system controller communication support" |
76 | depends on (IA64_SGI_SN2 || IA64_GENERIC) | 32 | depends on (IA64_SGI_SN2 || IA64_GENERIC) |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 48bb8acbea49..3ca1f627be8a 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -5,13 +5,7 @@ | |||
5 | obj-y += mem.o random.o | 5 | obj-y += mem.o random.o |
6 | obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o | 6 | obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o |
7 | obj-y += misc.o | 7 | obj-y += misc.o |
8 | obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o | ||
9 | obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o | ||
10 | obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o | ||
11 | obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o | ||
12 | obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o | 8 | obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o |
13 | obj-$(CONFIG_SX) += sx.o generic_serial.o | ||
14 | obj-$(CONFIG_RIO) += rio/ generic_serial.o | ||
15 | obj-$(CONFIG_RAW_DRIVER) += raw.o | 9 | obj-$(CONFIG_RAW_DRIVER) += raw.o |
16 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o | 10 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o |
17 | obj-$(CONFIG_MSPEC) += mspec.o | 11 | obj-$(CONFIG_MSPEC) += mspec.o |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c deleted file mode 100644 index 5954ee1dc953..000000000000 --- a/drivers/char/generic_serial.c +++ /dev/null | |||
@@ -1,844 +0,0 @@ | |||
1 | /* | ||
2 | * generic_serial.c | ||
3 | * | ||
4 | * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl | ||
5 | * | ||
6 | * written for the SX serial driver. | ||
7 | * Contains the code that should be shared over all the serial drivers. | ||
8 | * | ||
9 | * Credit for the idea to do it this way might go to Alan Cox. | ||
10 | * | ||
11 | * | ||
12 | * Version 0.1 -- December, 1998. Initial version. | ||
13 | * Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc. | ||
14 | * Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus. | ||
15 | * | ||
16 | * BitWizard is actively maintaining this file. We sometimes find | ||
17 | * that someone submitted changes to this file. We really appreciate | ||
18 | * your help, but please submit changes through us. We're doing our | ||
19 | * best to be responsive. -- REW | ||
20 | * */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/tty.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/serial.h> | ||
27 | #include <linux/mm.h> | ||
28 | #include <linux/generic_serial.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/tty_flip.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/gfp.h> | ||
33 | #include <asm/uaccess.h> | ||
34 | |||
35 | #define DEBUG | ||
36 | |||
37 | static int gs_debug; | ||
38 | |||
39 | #ifdef DEBUG | ||
40 | #define gs_dprintk(f, str...) if (gs_debug & f) printk (str) | ||
41 | #else | ||
42 | #define gs_dprintk(f, str...) /* nothing */ | ||
43 | #endif | ||
44 | |||
45 | #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__) | ||
46 | #define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__) | ||
47 | |||
48 | #define RS_EVENT_WRITE_WAKEUP 1 | ||
49 | |||
50 | module_param(gs_debug, int, 0644); | ||
51 | |||
52 | |||
53 | int gs_put_char(struct tty_struct * tty, unsigned char ch) | ||
54 | { | ||
55 | struct gs_port *port; | ||
56 | |||
57 | func_enter (); | ||
58 | |||
59 | port = tty->driver_data; | ||
60 | |||
61 | if (!port) return 0; | ||
62 | |||
63 | if (! (port->port.flags & ASYNC_INITIALIZED)) return 0; | ||
64 | |||
65 | /* Take a lock on the serial tranmit buffer! */ | ||
66 | mutex_lock(& port->port_write_mutex); | ||
67 | |||
68 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { | ||
69 | /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ | ||
70 | mutex_unlock(&port->port_write_mutex); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | port->xmit_buf[port->xmit_head++] = ch; | ||
75 | port->xmit_head &= SERIAL_XMIT_SIZE - 1; | ||
76 | port->xmit_cnt++; /* Characters in buffer */ | ||
77 | |||
78 | mutex_unlock(&port->port_write_mutex); | ||
79 | func_exit (); | ||
80 | return 1; | ||
81 | } | ||
82 | |||
83 | |||
84 | /* | ||
85 | > Problems to take into account are: | ||
86 | > -1- Interrupts that empty part of the buffer. | ||
87 | > -2- page faults on the access to userspace. | ||
88 | > -3- Other processes that are also trying to do a "write". | ||
89 | */ | ||
90 | |||
91 | int gs_write(struct tty_struct * tty, | ||
92 | const unsigned char *buf, int count) | ||
93 | { | ||
94 | struct gs_port *port; | ||
95 | int c, total = 0; | ||
96 | int t; | ||
97 | |||
98 | func_enter (); | ||
99 | |||
100 | port = tty->driver_data; | ||
101 | |||
102 | if (!port) return 0; | ||
103 | |||
104 | if (! (port->port.flags & ASYNC_INITIALIZED)) | ||
105 | return 0; | ||
106 | |||
107 | /* get exclusive "write" access to this port (problem 3) */ | ||
108 | /* This is not a spinlock because we can have a disk access (page | ||
109 | fault) in copy_from_user */ | ||
110 | mutex_lock(& port->port_write_mutex); | ||
111 | |||
112 | while (1) { | ||
113 | |||
114 | c = count; | ||
115 | |||
116 | /* This is safe because we "OWN" the "head". Noone else can | ||
117 | change the "head": we own the port_write_mutex. */ | ||
118 | /* Don't overrun the end of the buffer */ | ||
119 | t = SERIAL_XMIT_SIZE - port->xmit_head; | ||
120 | if (t < c) c = t; | ||
121 | |||
122 | /* This is safe because the xmit_cnt can only decrease. This | ||
123 | would increase "t", so we might copy too little chars. */ | ||
124 | /* Don't copy past the "head" of the buffer */ | ||
125 | t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt; | ||
126 | if (t < c) c = t; | ||
127 | |||
128 | /* Can't copy more? break out! */ | ||
129 | if (c <= 0) break; | ||
130 | |||
131 | memcpy (port->xmit_buf + port->xmit_head, buf, c); | ||
132 | |||
133 | port -> xmit_cnt += c; | ||
134 | port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1); | ||
135 | buf += c; | ||
136 | count -= c; | ||
137 | total += c; | ||
138 | } | ||
139 | mutex_unlock(& port->port_write_mutex); | ||
140 | |||
141 | gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n", | ||
142 | (port->port.flags & GS_TX_INTEN)?"enabled": "disabled"); | ||
143 | |||
144 | if (port->xmit_cnt && | ||
145 | !tty->stopped && | ||
146 | !tty->hw_stopped && | ||
147 | !(port->port.flags & GS_TX_INTEN)) { | ||
148 | port->port.flags |= GS_TX_INTEN; | ||
149 | port->rd->enable_tx_interrupts (port); | ||
150 | } | ||
151 | func_exit (); | ||
152 | return total; | ||
153 | } | ||
154 | |||
155 | |||
156 | |||
157 | int gs_write_room(struct tty_struct * tty) | ||
158 | { | ||
159 | struct gs_port *port = tty->driver_data; | ||
160 | int ret; | ||
161 | |||
162 | func_enter (); | ||
163 | ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; | ||
164 | if (ret < 0) | ||
165 | ret = 0; | ||
166 | func_exit (); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | |||
171 | int gs_chars_in_buffer(struct tty_struct *tty) | ||
172 | { | ||
173 | struct gs_port *port = tty->driver_data; | ||
174 | func_enter (); | ||
175 | |||
176 | func_exit (); | ||
177 | return port->xmit_cnt; | ||
178 | } | ||
179 | |||
180 | |||
181 | static int gs_real_chars_in_buffer(struct tty_struct *tty) | ||
182 | { | ||
183 | struct gs_port *port; | ||
184 | func_enter (); | ||
185 | |||
186 | port = tty->driver_data; | ||
187 | |||
188 | if (!port->rd) return 0; | ||
189 | if (!port->rd->chars_in_buffer) return 0; | ||
190 | |||
191 | func_exit (); | ||
192 | return port->xmit_cnt + port->rd->chars_in_buffer (port); | ||
193 | } | ||
194 | |||
195 | |||
196 | static int gs_wait_tx_flushed (void * ptr, unsigned long timeout) | ||
197 | { | ||
198 | struct gs_port *port = ptr; | ||
199 | unsigned long end_jiffies; | ||
200 | int jiffies_to_transmit, charsleft = 0, rv = 0; | ||
201 | int rcib; | ||
202 | |||
203 | func_enter(); | ||
204 | |||
205 | gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port); | ||
206 | if (port) { | ||
207 | gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n", | ||
208 | port->xmit_cnt, port->xmit_buf, port->port.tty); | ||
209 | } | ||
210 | |||
211 | if (!port || port->xmit_cnt < 0 || !port->xmit_buf) { | ||
212 | gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n"); | ||
213 | func_exit(); | ||
214 | return -EINVAL; /* This is an error which we don't know how to handle. */ | ||
215 | } | ||
216 | |||
217 | rcib = gs_real_chars_in_buffer(port->port.tty); | ||
218 | |||
219 | if(rcib <= 0) { | ||
220 | gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n"); | ||
221 | func_exit(); | ||
222 | return rv; | ||
223 | } | ||
224 | /* stop trying: now + twice the time it would normally take + seconds */ | ||
225 | if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT; | ||
226 | end_jiffies = jiffies; | ||
227 | if (timeout != MAX_SCHEDULE_TIMEOUT) | ||
228 | end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0; | ||
229 | end_jiffies += timeout; | ||
230 | |||
231 | gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n", | ||
232 | jiffies, end_jiffies, end_jiffies-jiffies); | ||
233 | |||
234 | /* the expression is actually jiffies < end_jiffies, but that won't | ||
235 | work around the wraparound. Tricky eh? */ | ||
236 | while ((charsleft = gs_real_chars_in_buffer (port->port.tty)) && | ||
237 | time_after (end_jiffies, jiffies)) { | ||
238 | /* Units check: | ||
239 | chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies! | ||
240 | check! */ | ||
241 | |||
242 | charsleft += 16; /* Allow 16 chars more to be transmitted ... */ | ||
243 | jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0; | ||
244 | /* ^^^ Round up.... */ | ||
245 | if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1; | ||
246 | |||
247 | gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies " | ||
248 | "(%d chars).\n", jiffies_to_transmit, charsleft); | ||
249 | |||
250 | msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit)); | ||
251 | if (signal_pending (current)) { | ||
252 | gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: "); | ||
253 | rv = -EINTR; | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft); | ||
259 | set_current_state (TASK_RUNNING); | ||
260 | |||
261 | func_exit(); | ||
262 | return rv; | ||
263 | } | ||
264 | |||
265 | |||
266 | |||
267 | void gs_flush_buffer(struct tty_struct *tty) | ||
268 | { | ||
269 | struct gs_port *port; | ||
270 | unsigned long flags; | ||
271 | |||
272 | func_enter (); | ||
273 | |||
274 | port = tty->driver_data; | ||
275 | |||
276 | if (!port) return; | ||
277 | |||
278 | /* XXX Would the write semaphore do? */ | ||
279 | spin_lock_irqsave (&port->driver_lock, flags); | ||
280 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
281 | spin_unlock_irqrestore (&port->driver_lock, flags); | ||
282 | |||
283 | tty_wakeup(tty); | ||
284 | func_exit (); | ||
285 | } | ||
286 | |||
287 | |||
288 | void gs_flush_chars(struct tty_struct * tty) | ||
289 | { | ||
290 | struct gs_port *port; | ||
291 | |||
292 | func_enter (); | ||
293 | |||
294 | port = tty->driver_data; | ||
295 | |||
296 | if (!port) return; | ||
297 | |||
298 | if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || | ||
299 | !port->xmit_buf) { | ||
300 | func_exit (); | ||
301 | return; | ||
302 | } | ||
303 | |||
304 | /* Beats me -- REW */ | ||
305 | port->port.flags |= GS_TX_INTEN; | ||
306 | port->rd->enable_tx_interrupts (port); | ||
307 | func_exit (); | ||
308 | } | ||
309 | |||
310 | |||
311 | void gs_stop(struct tty_struct * tty) | ||
312 | { | ||
313 | struct gs_port *port; | ||
314 | |||
315 | func_enter (); | ||
316 | |||
317 | port = tty->driver_data; | ||
318 | |||
319 | if (!port) return; | ||
320 | |||
321 | if (port->xmit_cnt && | ||
322 | port->xmit_buf && | ||
323 | (port->port.flags & GS_TX_INTEN) ) { | ||
324 | port->port.flags &= ~GS_TX_INTEN; | ||
325 | port->rd->disable_tx_interrupts (port); | ||
326 | } | ||
327 | func_exit (); | ||
328 | } | ||
329 | |||
330 | |||
331 | void gs_start(struct tty_struct * tty) | ||
332 | { | ||
333 | struct gs_port *port; | ||
334 | |||
335 | port = tty->driver_data; | ||
336 | |||
337 | if (!port) return; | ||
338 | |||
339 | if (port->xmit_cnt && | ||
340 | port->xmit_buf && | ||
341 | !(port->port.flags & GS_TX_INTEN) ) { | ||
342 | port->port.flags |= GS_TX_INTEN; | ||
343 | port->rd->enable_tx_interrupts (port); | ||
344 | } | ||
345 | func_exit (); | ||
346 | } | ||
347 | |||
348 | |||
349 | static void gs_shutdown_port (struct gs_port *port) | ||
350 | { | ||
351 | unsigned long flags; | ||
352 | |||
353 | func_enter(); | ||
354 | |||
355 | if (!port) return; | ||
356 | |||
357 | if (!(port->port.flags & ASYNC_INITIALIZED)) | ||
358 | return; | ||
359 | |||
360 | spin_lock_irqsave(&port->driver_lock, flags); | ||
361 | |||
362 | if (port->xmit_buf) { | ||
363 | free_page((unsigned long) port->xmit_buf); | ||
364 | port->xmit_buf = NULL; | ||
365 | } | ||
366 | |||
367 | if (port->port.tty) | ||
368 | set_bit(TTY_IO_ERROR, &port->port.tty->flags); | ||
369 | |||
370 | port->rd->shutdown_port (port); | ||
371 | |||
372 | port->port.flags &= ~ASYNC_INITIALIZED; | ||
373 | spin_unlock_irqrestore(&port->driver_lock, flags); | ||
374 | |||
375 | func_exit(); | ||
376 | } | ||
377 | |||
378 | |||
379 | void gs_hangup(struct tty_struct *tty) | ||
380 | { | ||
381 | struct gs_port *port; | ||
382 | unsigned long flags; | ||
383 | |||
384 | func_enter (); | ||
385 | |||
386 | port = tty->driver_data; | ||
387 | tty = port->port.tty; | ||
388 | if (!tty) | ||
389 | return; | ||
390 | |||
391 | gs_shutdown_port (port); | ||
392 | spin_lock_irqsave(&port->port.lock, flags); | ||
393 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE); | ||
394 | port->port.tty = NULL; | ||
395 | port->port.count = 0; | ||
396 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
397 | |||
398 | wake_up_interruptible(&port->port.open_wait); | ||
399 | func_exit (); | ||
400 | } | ||
401 | |||
402 | |||
403 | int gs_block_til_ready(void *port_, struct file * filp) | ||
404 | { | ||
405 | struct gs_port *gp = port_; | ||
406 | struct tty_port *port = &gp->port; | ||
407 | DECLARE_WAITQUEUE(wait, current); | ||
408 | int retval; | ||
409 | int do_clocal = 0; | ||
410 | int CD; | ||
411 | struct tty_struct *tty; | ||
412 | unsigned long flags; | ||
413 | |||
414 | func_enter (); | ||
415 | |||
416 | if (!port) return 0; | ||
417 | |||
418 | tty = port->tty; | ||
419 | |||
420 | gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); | ||
421 | /* | ||
422 | * If the device is in the middle of being closed, then block | ||
423 | * until it's done, and then try again. | ||
424 | */ | ||
425 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { | ||
426 | interruptible_sleep_on(&port->close_wait); | ||
427 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
428 | return -EAGAIN; | ||
429 | else | ||
430 | return -ERESTARTSYS; | ||
431 | } | ||
432 | |||
433 | gs_dprintk (GS_DEBUG_BTR, "after hung up\n"); | ||
434 | |||
435 | /* | ||
436 | * If non-blocking mode is set, or the port is not enabled, | ||
437 | * then make the check up front and then exit. | ||
438 | */ | ||
439 | if ((filp->f_flags & O_NONBLOCK) || | ||
440 | (tty->flags & (1 << TTY_IO_ERROR))) { | ||
441 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | gs_dprintk (GS_DEBUG_BTR, "after nonblock\n"); | ||
446 | |||
447 | if (C_CLOCAL(tty)) | ||
448 | do_clocal = 1; | ||
449 | |||
450 | /* | ||
451 | * Block waiting for the carrier detect and the line to become | ||
452 | * free (i.e., not in use by the callout). While we are in | ||
453 | * this loop, port->count is dropped by one, so that | ||
454 | * rs_close() knows when to free things. We restore it upon | ||
455 | * exit, either normal or abnormal. | ||
456 | */ | ||
457 | retval = 0; | ||
458 | |||
459 | add_wait_queue(&port->open_wait, &wait); | ||
460 | |||
461 | gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); | ||
462 | spin_lock_irqsave(&port->lock, flags); | ||
463 | if (!tty_hung_up_p(filp)) { | ||
464 | port->count--; | ||
465 | } | ||
466 | port->blocked_open++; | ||
467 | spin_unlock_irqrestore(&port->lock, flags); | ||
468 | while (1) { | ||
469 | CD = tty_port_carrier_raised(port); | ||
470 | gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); | ||
471 | set_current_state (TASK_INTERRUPTIBLE); | ||
472 | if (tty_hung_up_p(filp) || | ||
473 | !(port->flags & ASYNC_INITIALIZED)) { | ||
474 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
475 | retval = -EAGAIN; | ||
476 | else | ||
477 | retval = -ERESTARTSYS; | ||
478 | break; | ||
479 | } | ||
480 | if (!(port->flags & ASYNC_CLOSING) && | ||
481 | (do_clocal || CD)) | ||
482 | break; | ||
483 | gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", | ||
484 | (int)signal_pending (current), *(long*)(¤t->blocked)); | ||
485 | if (signal_pending(current)) { | ||
486 | retval = -ERESTARTSYS; | ||
487 | break; | ||
488 | } | ||
489 | schedule(); | ||
490 | } | ||
491 | gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", | ||
492 | port->blocked_open); | ||
493 | set_current_state (TASK_RUNNING); | ||
494 | remove_wait_queue(&port->open_wait, &wait); | ||
495 | |||
496 | spin_lock_irqsave(&port->lock, flags); | ||
497 | if (!tty_hung_up_p(filp)) { | ||
498 | port->count++; | ||
499 | } | ||
500 | port->blocked_open--; | ||
501 | if (retval == 0) | ||
502 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
503 | spin_unlock_irqrestore(&port->lock, flags); | ||
504 | func_exit (); | ||
505 | return retval; | ||
506 | } | ||
507 | |||
508 | |||
509 | void gs_close(struct tty_struct * tty, struct file * filp) | ||
510 | { | ||
511 | unsigned long flags; | ||
512 | struct gs_port *port; | ||
513 | |||
514 | func_enter (); | ||
515 | |||
516 | port = tty->driver_data; | ||
517 | |||
518 | if (!port) return; | ||
519 | |||
520 | if (!port->port.tty) { | ||
521 | /* This seems to happen when this is called from vhangup. */ | ||
522 | gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->port.tty is NULL\n"); | ||
523 | port->port.tty = tty; | ||
524 | } | ||
525 | |||
526 | spin_lock_irqsave(&port->port.lock, flags); | ||
527 | |||
528 | if (tty_hung_up_p(filp)) { | ||
529 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
530 | if (port->rd->hungup) | ||
531 | port->rd->hungup (port); | ||
532 | func_exit (); | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | if ((tty->count == 1) && (port->port.count != 1)) { | ||
537 | printk(KERN_ERR "gs: gs_close port %p: bad port count;" | ||
538 | " tty->count is 1, port count is %d\n", port, port->port.count); | ||
539 | port->port.count = 1; | ||
540 | } | ||
541 | if (--port->port.count < 0) { | ||
542 | printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->port.count); | ||
543 | port->port.count = 0; | ||
544 | } | ||
545 | |||
546 | if (port->port.count) { | ||
547 | gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count); | ||
548 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
549 | func_exit (); | ||
550 | return; | ||
551 | } | ||
552 | port->port.flags |= ASYNC_CLOSING; | ||
553 | |||
554 | /* | ||
555 | * Now we wait for the transmit buffer to clear; and we notify | ||
556 | * the line discipline to only process XON/XOFF characters. | ||
557 | */ | ||
558 | tty->closing = 1; | ||
559 | /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
560 | tty_wait_until_sent(tty, port->closing_wait); */ | ||
561 | |||
562 | /* | ||
563 | * At this point we stop accepting input. To do this, we | ||
564 | * disable the receive line status interrupts, and tell the | ||
565 | * interrupt driver to stop checking the data ready bit in the | ||
566 | * line status register. | ||
567 | */ | ||
568 | |||
569 | spin_lock_irqsave(&port->driver_lock, flags); | ||
570 | port->rd->disable_rx_interrupts (port); | ||
571 | spin_unlock_irqrestore(&port->driver_lock, flags); | ||
572 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
573 | |||
574 | /* close has no way of returning "EINTR", so discard return value */ | ||
575 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
576 | gs_wait_tx_flushed (port, port->closing_wait); | ||
577 | |||
578 | port->port.flags &= ~GS_ACTIVE; | ||
579 | |||
580 | gs_flush_buffer(tty); | ||
581 | |||
582 | tty_ldisc_flush(tty); | ||
583 | tty->closing = 0; | ||
584 | |||
585 | spin_lock_irqsave(&port->driver_lock, flags); | ||
586 | port->event = 0; | ||
587 | port->rd->close (port); | ||
588 | port->rd->shutdown_port (port); | ||
589 | spin_unlock_irqrestore(&port->driver_lock, flags); | ||
590 | |||
591 | spin_lock_irqsave(&port->port.lock, flags); | ||
592 | port->port.tty = NULL; | ||
593 | |||
594 | if (port->port.blocked_open) { | ||
595 | if (port->close_delay) { | ||
596 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
597 | msleep_interruptible(jiffies_to_msecs(port->close_delay)); | ||
598 | spin_lock_irqsave(&port->port.lock, flags); | ||
599 | } | ||
600 | wake_up_interruptible(&port->port.open_wait); | ||
601 | } | ||
602 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); | ||
603 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
604 | wake_up_interruptible(&port->port.close_wait); | ||
605 | |||
606 | func_exit (); | ||
607 | } | ||
608 | |||
609 | |||
610 | void gs_set_termios (struct tty_struct * tty, | ||
611 | struct ktermios * old_termios) | ||
612 | { | ||
613 | struct gs_port *port; | ||
614 | int baudrate, tmp, rv; | ||
615 | struct ktermios *tiosp; | ||
616 | |||
617 | func_enter(); | ||
618 | |||
619 | port = tty->driver_data; | ||
620 | |||
621 | if (!port) return; | ||
622 | if (!port->port.tty) { | ||
623 | /* This seems to happen when this is called after gs_close. */ | ||
624 | gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->port.tty is NULL\n"); | ||
625 | port->port.tty = tty; | ||
626 | } | ||
627 | |||
628 | |||
629 | tiosp = tty->termios; | ||
630 | |||
631 | if (gs_debug & GS_DEBUG_TERMIOS) { | ||
632 | gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); | ||
633 | } | ||
634 | |||
635 | if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) { | ||
636 | if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n"); | ||
637 | if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n"); | ||
638 | if(tiosp->c_cflag != old_termios->c_cflag) printk("c_cflag changed\n"); | ||
639 | if(tiosp->c_lflag != old_termios->c_lflag) printk("c_lflag changed\n"); | ||
640 | if(tiosp->c_line != old_termios->c_line) printk("c_line changed\n"); | ||
641 | if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n"); | ||
642 | } | ||
643 | |||
644 | baudrate = tty_get_baud_rate(tty); | ||
645 | |||
646 | if ((tiosp->c_cflag & CBAUD) == B38400) { | ||
647 | if ( (port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | ||
648 | baudrate = 57600; | ||
649 | else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | ||
650 | baudrate = 115200; | ||
651 | else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | ||
652 | baudrate = 230400; | ||
653 | else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | ||
654 | baudrate = 460800; | ||
655 | else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) | ||
656 | baudrate = (port->baud_base / port->custom_divisor); | ||
657 | } | ||
658 | |||
659 | /* I recommend using THIS instead of the mess in termios (and | ||
660 | duplicating the above code). Next we should create a clean | ||
661 | interface towards this variable. If your card supports arbitrary | ||
662 | baud rates, (e.g. CD1400 or 16550 based cards) then everything | ||
663 | will be very easy..... */ | ||
664 | port->baud = baudrate; | ||
665 | |||
666 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ | ||
667 | /* Baudrate/10 is cps. Divide by HZ to get chars per tick. */ | ||
668 | tmp = (baudrate / 10 / HZ) * 2; | ||
669 | |||
670 | if (tmp < 0) tmp = 0; | ||
671 | if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1; | ||
672 | |||
673 | port->wakeup_chars = tmp; | ||
674 | |||
675 | /* We should really wait for the characters to be all sent before | ||
676 | changing the settings. -- CAL */ | ||
677 | rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT); | ||
678 | if (rv < 0) return /* rv */; | ||
679 | |||
680 | rv = port->rd->set_real_termios(port); | ||
681 | if (rv < 0) return /* rv */; | ||
682 | |||
683 | if ((!old_termios || | ||
684 | (old_termios->c_cflag & CRTSCTS)) && | ||
685 | !( tiosp->c_cflag & CRTSCTS)) { | ||
686 | tty->stopped = 0; | ||
687 | gs_start(tty); | ||
688 | } | ||
689 | |||
690 | #ifdef tytso_patch_94Nov25_1726 | ||
691 | /* This "makes sense", Why is it commented out? */ | ||
692 | |||
693 | if (!(old_termios->c_cflag & CLOCAL) && | ||
694 | (tty->termios->c_cflag & CLOCAL)) | ||
695 | wake_up_interruptible(&port->gs.open_wait); | ||
696 | #endif | ||
697 | |||
698 | func_exit(); | ||
699 | return /* 0 */; | ||
700 | } | ||
701 | |||
702 | |||
703 | |||
704 | /* Must be called with interrupts enabled */ | ||
705 | int gs_init_port(struct gs_port *port) | ||
706 | { | ||
707 | unsigned long flags; | ||
708 | |||
709 | func_enter (); | ||
710 | |||
711 | if (port->port.flags & ASYNC_INITIALIZED) { | ||
712 | func_exit (); | ||
713 | return 0; | ||
714 | } | ||
715 | if (!port->xmit_buf) { | ||
716 | /* We may sleep in get_zeroed_page() */ | ||
717 | unsigned long tmp; | ||
718 | |||
719 | tmp = get_zeroed_page(GFP_KERNEL); | ||
720 | spin_lock_irqsave (&port->driver_lock, flags); | ||
721 | if (port->xmit_buf) | ||
722 | free_page (tmp); | ||
723 | else | ||
724 | port->xmit_buf = (unsigned char *) tmp; | ||
725 | spin_unlock_irqrestore(&port->driver_lock, flags); | ||
726 | if (!port->xmit_buf) { | ||
727 | func_exit (); | ||
728 | return -ENOMEM; | ||
729 | } | ||
730 | } | ||
731 | |||
732 | spin_lock_irqsave (&port->driver_lock, flags); | ||
733 | if (port->port.tty) | ||
734 | clear_bit(TTY_IO_ERROR, &port->port.tty->flags); | ||
735 | mutex_init(&port->port_write_mutex); | ||
736 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
737 | spin_unlock_irqrestore(&port->driver_lock, flags); | ||
738 | gs_set_termios(port->port.tty, NULL); | ||
739 | spin_lock_irqsave (&port->driver_lock, flags); | ||
740 | port->port.flags |= ASYNC_INITIALIZED; | ||
741 | port->port.flags &= ~GS_TX_INTEN; | ||
742 | |||
743 | spin_unlock_irqrestore(&port->driver_lock, flags); | ||
744 | func_exit (); | ||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | |||
749 | int gs_setserial(struct gs_port *port, struct serial_struct __user *sp) | ||
750 | { | ||
751 | struct serial_struct sio; | ||
752 | |||
753 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) | ||
754 | return(-EFAULT); | ||
755 | |||
756 | if (!capable(CAP_SYS_ADMIN)) { | ||
757 | if ((sio.baud_base != port->baud_base) || | ||
758 | (sio.close_delay != port->close_delay) || | ||
759 | ((sio.flags & ~ASYNC_USR_MASK) != | ||
760 | (port->port.flags & ~ASYNC_USR_MASK))) | ||
761 | return(-EPERM); | ||
762 | } | ||
763 | |||
764 | port->port.flags = (port->port.flags & ~ASYNC_USR_MASK) | | ||
765 | (sio.flags & ASYNC_USR_MASK); | ||
766 | |||
767 | port->baud_base = sio.baud_base; | ||
768 | port->close_delay = sio.close_delay; | ||
769 | port->closing_wait = sio.closing_wait; | ||
770 | port->custom_divisor = sio.custom_divisor; | ||
771 | |||
772 | gs_set_termios (port->port.tty, NULL); | ||
773 | |||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | |||
778 | /*****************************************************************************/ | ||
779 | |||
780 | /* | ||
781 | * Generate the serial struct info. | ||
782 | */ | ||
783 | |||
784 | int gs_getserial(struct gs_port *port, struct serial_struct __user *sp) | ||
785 | { | ||
786 | struct serial_struct sio; | ||
787 | |||
788 | memset(&sio, 0, sizeof(struct serial_struct)); | ||
789 | sio.flags = port->port.flags; | ||
790 | sio.baud_base = port->baud_base; | ||
791 | sio.close_delay = port->close_delay; | ||
792 | sio.closing_wait = port->closing_wait; | ||
793 | sio.custom_divisor = port->custom_divisor; | ||
794 | sio.hub6 = 0; | ||
795 | |||
796 | /* If you want you can override these. */ | ||
797 | sio.type = PORT_UNKNOWN; | ||
798 | sio.xmit_fifo_size = -1; | ||
799 | sio.line = -1; | ||
800 | sio.port = -1; | ||
801 | sio.irq = -1; | ||
802 | |||
803 | if (port->rd->getserial) | ||
804 | port->rd->getserial (port, &sio); | ||
805 | |||
806 | if (copy_to_user(sp, &sio, sizeof(struct serial_struct))) | ||
807 | return -EFAULT; | ||
808 | return 0; | ||
809 | |||
810 | } | ||
811 | |||
812 | |||
813 | void gs_got_break(struct gs_port *port) | ||
814 | { | ||
815 | func_enter (); | ||
816 | |||
817 | tty_insert_flip_char(port->port.tty, 0, TTY_BREAK); | ||
818 | tty_schedule_flip(port->port.tty); | ||
819 | if (port->port.flags & ASYNC_SAK) { | ||
820 | do_SAK (port->port.tty); | ||
821 | } | ||
822 | |||
823 | func_exit (); | ||
824 | } | ||
825 | |||
826 | |||
827 | EXPORT_SYMBOL(gs_put_char); | ||
828 | EXPORT_SYMBOL(gs_write); | ||
829 | EXPORT_SYMBOL(gs_write_room); | ||
830 | EXPORT_SYMBOL(gs_chars_in_buffer); | ||
831 | EXPORT_SYMBOL(gs_flush_buffer); | ||
832 | EXPORT_SYMBOL(gs_flush_chars); | ||
833 | EXPORT_SYMBOL(gs_stop); | ||
834 | EXPORT_SYMBOL(gs_start); | ||
835 | EXPORT_SYMBOL(gs_hangup); | ||
836 | EXPORT_SYMBOL(gs_block_til_ready); | ||
837 | EXPORT_SYMBOL(gs_close); | ||
838 | EXPORT_SYMBOL(gs_set_termios); | ||
839 | EXPORT_SYMBOL(gs_init_port); | ||
840 | EXPORT_SYMBOL(gs_setserial); | ||
841 | EXPORT_SYMBOL(gs_getserial); | ||
842 | EXPORT_SYMBOL(gs_got_break); | ||
843 | |||
844 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/rio/Makefile b/drivers/char/rio/Makefile deleted file mode 100644 index 1661875883fb..000000000000 --- a/drivers/char/rio/Makefile +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the linux rio-subsystem. | ||
3 | # | ||
4 | # (C) R.E.Wolff@BitWizard.nl | ||
5 | # | ||
6 | # This file is GPL. See other files for the full Blurb. I'm lazy today. | ||
7 | # | ||
8 | |||
9 | obj-$(CONFIG_RIO) += rio.o | ||
10 | |||
11 | rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ | ||
12 | rioparam.o rioroute.o riotable.o riotty.o | ||
diff --git a/drivers/char/rio/board.h b/drivers/char/rio/board.h deleted file mode 100644 index bdea633a9076..000000000000 --- a/drivers/char/rio/board.h +++ /dev/null | |||
@@ -1,132 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : board.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:07 | ||
26 | ** Retrieved : 11/6/98 11:34:20 | ||
27 | ** | ||
28 | ** ident @(#)board.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_board_h__ | ||
34 | #define __rio_board_h__ | ||
35 | |||
36 | /* | ||
37 | ** board.h contains the definitions for the *hardware* of the host cards. | ||
38 | ** It describes the memory overlay for the dual port RAM area. | ||
39 | */ | ||
40 | |||
41 | #define DP_SRAM1_SIZE 0x7C00 | ||
42 | #define DP_SRAM2_SIZE 0x0200 | ||
43 | #define DP_SRAM3_SIZE 0x7000 | ||
44 | #define DP_SCRATCH_SIZE 0x1000 | ||
45 | #define DP_PARMMAP_ADDR 0x01FE /* offset into SRAM2 */ | ||
46 | #define DP_STARTUP_ADDR 0x01F8 /* offset into SRAM2 */ | ||
47 | |||
48 | /* | ||
49 | ** The shape of the Host Control area, at offset 0x7C00, Write Only | ||
50 | */ | ||
51 | struct s_Ctrl { | ||
52 | u8 DpCtl; /* 7C00 */ | ||
53 | u8 Dp_Unused2_[127]; | ||
54 | u8 DpIntSet; /* 7C80 */ | ||
55 | u8 Dp_Unused3_[127]; | ||
56 | u8 DpTpuReset; /* 7D00 */ | ||
57 | u8 Dp_Unused4_[127]; | ||
58 | u8 DpIntReset; /* 7D80 */ | ||
59 | u8 Dp_Unused5_[127]; | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | ** The PROM data area on the host (0x7C00), Read Only | ||
64 | */ | ||
65 | struct s_Prom { | ||
66 | u16 DpSlxCode[2]; | ||
67 | u16 DpRev; | ||
68 | u16 Dp_Unused6_; | ||
69 | u16 DpUniq[4]; | ||
70 | u16 DpJahre; | ||
71 | u16 DpWoche; | ||
72 | u16 DpHwFeature[5]; | ||
73 | u16 DpOemId; | ||
74 | u16 DpSiggy[16]; | ||
75 | }; | ||
76 | |||
77 | /* | ||
78 | ** Union of the Ctrl and Prom areas | ||
79 | */ | ||
80 | union u_CtrlProm { /* This is the control/PROM area (0x7C00) */ | ||
81 | struct s_Ctrl DpCtrl; | ||
82 | struct s_Prom DpProm; | ||
83 | }; | ||
84 | |||
85 | /* | ||
86 | ** The top end of memory! | ||
87 | */ | ||
88 | struct s_ParmMapS { /* Area containing Parm Map Pointer */ | ||
89 | u8 Dp_Unused8_[DP_PARMMAP_ADDR]; | ||
90 | u16 DpParmMapAd; | ||
91 | }; | ||
92 | |||
93 | struct s_StartUpS { | ||
94 | u8 Dp_Unused9_[DP_STARTUP_ADDR]; | ||
95 | u8 Dp_LongJump[0x4]; | ||
96 | u8 Dp_Unused10_[2]; | ||
97 | u8 Dp_ShortJump[0x2]; | ||
98 | }; | ||
99 | |||
100 | union u_Sram2ParmMap { /* This is the top of memory (0x7E00-0x7FFF) */ | ||
101 | u8 DpSramMem[DP_SRAM2_SIZE]; | ||
102 | struct s_ParmMapS DpParmMapS; | ||
103 | struct s_StartUpS DpStartUpS; | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | ** This is the DP RAM overlay. | ||
108 | */ | ||
109 | struct DpRam { | ||
110 | u8 DpSram1[DP_SRAM1_SIZE]; /* 0000 - 7BFF */ | ||
111 | union u_CtrlProm DpCtrlProm; /* 7C00 - 7DFF */ | ||
112 | union u_Sram2ParmMap DpSram2ParmMap; /* 7E00 - 7FFF */ | ||
113 | u8 DpScratch[DP_SCRATCH_SIZE]; /* 8000 - 8FFF */ | ||
114 | u8 DpSram3[DP_SRAM3_SIZE]; /* 9000 - FFFF */ | ||
115 | }; | ||
116 | |||
117 | #define DpControl DpCtrlProm.DpCtrl.DpCtl | ||
118 | #define DpSetInt DpCtrlProm.DpCtrl.DpIntSet | ||
119 | #define DpResetTpu DpCtrlProm.DpCtrl.DpTpuReset | ||
120 | #define DpResetInt DpCtrlProm.DpCtrl.DpIntReset | ||
121 | |||
122 | #define DpSlx DpCtrlProm.DpProm.DpSlxCode | ||
123 | #define DpRevision DpCtrlProm.DpProm.DpRev | ||
124 | #define DpUnique DpCtrlProm.DpProm.DpUniq | ||
125 | #define DpYear DpCtrlProm.DpProm.DpJahre | ||
126 | #define DpWeek DpCtrlProm.DpProm.DpWoche | ||
127 | #define DpSignature DpCtrlProm.DpProm.DpSiggy | ||
128 | |||
129 | #define DpParmMapR DpSram2ParmMap.DpParmMapS.DpParmMapAd | ||
130 | #define DpSram2 DpSram2ParmMap.DpSramMem | ||
131 | |||
132 | #endif | ||
diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h deleted file mode 100644 index 5ab51679caa2..000000000000 --- a/drivers/char/rio/cirrus.h +++ /dev/null | |||
@@ -1,210 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* CIRRUS.H ******* | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Jeremy Rolls | ||
8 | Date : 3 Aug 1990 | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | |||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _cirrus_h | ||
38 | #define _cirrus_h 1 | ||
39 | |||
40 | /* Bit fields for particular registers shared with driver */ | ||
41 | |||
42 | /* COR1 - driver and RTA */ | ||
43 | #define RIOC_COR1_ODD 0x80 /* Odd parity */ | ||
44 | #define RIOC_COR1_EVEN 0x00 /* Even parity */ | ||
45 | #define RIOC_COR1_NOP 0x00 /* No parity */ | ||
46 | #define RIOC_COR1_FORCE 0x20 /* Force parity */ | ||
47 | #define RIOC_COR1_NORMAL 0x40 /* With parity */ | ||
48 | #define RIOC_COR1_1STOP 0x00 /* 1 stop bit */ | ||
49 | #define RIOC_COR1_15STOP 0x04 /* 1.5 stop bits */ | ||
50 | #define RIOC_COR1_2STOP 0x08 /* 2 stop bits */ | ||
51 | #define RIOC_COR1_5BITS 0x00 /* 5 data bits */ | ||
52 | #define RIOC_COR1_6BITS 0x01 /* 6 data bits */ | ||
53 | #define RIOC_COR1_7BITS 0x02 /* 7 data bits */ | ||
54 | #define RIOC_COR1_8BITS 0x03 /* 8 data bits */ | ||
55 | |||
56 | #define RIOC_COR1_HOST 0xef /* Safe host bits */ | ||
57 | |||
58 | /* RTA only */ | ||
59 | #define RIOC_COR1_CINPCK 0x00 /* Check parity of received characters */ | ||
60 | #define RIOC_COR1_CNINPCK 0x10 /* Don't check parity */ | ||
61 | |||
62 | /* COR2 bits for both RTA and driver use */ | ||
63 | #define RIOC_COR2_IXANY 0x80 /* IXANY - any character is XON */ | ||
64 | #define RIOC_COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */ | ||
65 | #define RIOC_COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */ | ||
66 | |||
67 | /* Additional driver bits */ | ||
68 | #define RIOC_COR2_HUPCL 0x20 /* Hang up on close */ | ||
69 | #define RIOC_COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */ | ||
70 | #define RIOC_COR2_IXOFF 0x01 /* Enable rx software flow control */ | ||
71 | #define RIOC_COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */ | ||
72 | |||
73 | /* RTA use only */ | ||
74 | #define RIOC_COR2_ETC 0x20 /* Embedded transmit options */ | ||
75 | #define RIOC_COR2_LOCAL 0x10 /* Local loopback mode */ | ||
76 | #define RIOC_COR2_REMOTE 0x08 /* Remote loopback mode */ | ||
77 | #define RIOC_COR2_HOST 0xc2 /* Safe host bits */ | ||
78 | |||
79 | /* COR3 - RTA use only */ | ||
80 | #define RIOC_COR3_SCDRNG 0x80 /* Enable special char detect for range */ | ||
81 | #define RIOC_COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */ | ||
82 | #define RIOC_COR3_FCT 0x20 /* Flow control transparency */ | ||
83 | #define RIOC_COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */ | ||
84 | #define RIOC_COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */ | ||
85 | #define RIOC_COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */ | ||
86 | #define RIOC_COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */ | ||
87 | #define RIOC_COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */ | ||
88 | |||
89 | #define RIOC_COR3_THRESHOLD RIOC_COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */ | ||
90 | |||
91 | #define RIOC_COR3_DEFAULT (RIOC_COR3_FCT | RIOC_COR3_THRESHOLD) | ||
92 | /* Default bits for COR3 */ | ||
93 | |||
94 | /* COR4 driver and RTA use */ | ||
95 | #define RIOC_COR4_IGNCR 0x80 /* Throw away CR's on input */ | ||
96 | #define RIOC_COR4_ICRNL 0x40 /* Map CR -> NL on input */ | ||
97 | #define RIOC_COR4_INLCR 0x20 /* Map NL -> CR on input */ | ||
98 | #define RIOC_COR4_IGNBRK 0x10 /* Ignore Break */ | ||
99 | #define RIOC_COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */ | ||
100 | #define RIOC_COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */ | ||
101 | |||
102 | |||
103 | /* COR4 driver only */ | ||
104 | #define RIOC_COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */ | ||
105 | #define RIOC_COR4_PARMRK 0x02 /* PARMRK */ | ||
106 | |||
107 | #define RIOC_COR4_HOST 0xf8 /* Safe host bits */ | ||
108 | |||
109 | /* COR4 RTA only */ | ||
110 | #define RIOC_COR4_CIGNPAR 0x02 /* Thrown away bad characters */ | ||
111 | #define RIOC_COR4_CPARMRK 0x04 /* PARMRK characters */ | ||
112 | #define RIOC_COR4_CNPARMRK 0x03 /* Don't PARMRK */ | ||
113 | |||
114 | /* COR5 driver and RTA use */ | ||
115 | #define RIOC_COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */ | ||
116 | #define RIOC_COR5_LNE 0x40 /* Enable LNEXT processing */ | ||
117 | #define RIOC_COR5_CMOE 0x20 /* Match good and errored characters */ | ||
118 | #define RIOC_COR5_ONLCR 0x02 /* NL -> CR NL on output */ | ||
119 | #define RIOC_COR5_OCRNL 0x01 /* CR -> NL on output */ | ||
120 | |||
121 | /* | ||
122 | ** Spare bits - these are not used in the CIRRUS registers, so we use | ||
123 | ** them to set various other features. | ||
124 | */ | ||
125 | /* | ||
126 | ** tstop and tbusy indication | ||
127 | */ | ||
128 | #define RIOC_COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */ | ||
129 | #define RIOC_COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */ | ||
130 | /* | ||
131 | ** TAB3 | ||
132 | */ | ||
133 | #define RIOC_COR5_TAB3 0x10 /* TAB3 mode */ | ||
134 | |||
135 | #define RIOC_COR5_HOST 0xc3 /* Safe host bits */ | ||
136 | |||
137 | /* CCSR */ | ||
138 | #define RIOC_CCSR_TXFLOFF 0x04 /* Tx is xoffed */ | ||
139 | |||
140 | /* MSVR1 */ | ||
141 | /* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the | ||
142 | RTA. This is because otherwise DCD would get lost on the 1 parallel / 3 | ||
143 | serial option. | ||
144 | */ | ||
145 | #define RIOC_MSVR1_CD 0x80 /* CD (DSR on Cirrus) */ | ||
146 | #define RIOC_MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */ | ||
147 | #define RIOC_MSVR1_RI 0x20 /* RI */ | ||
148 | #define RIOC_MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */ | ||
149 | #define RIOC_MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */ | ||
150 | /* Next two used to indicate state of tbusy and tstop to driver */ | ||
151 | #define RIOC_MSVR1_TSTOP 0x08 /* Set if port flow controlled */ | ||
152 | #define RIOC_MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */ | ||
153 | |||
154 | #define RIOC_MSVR1_HOST 0xf3 /* The bits the host wants */ | ||
155 | |||
156 | /* Defines for the subscripts of a CONFIG packet */ | ||
157 | #define RIOC_CONFIG_COR1 1 /* Option register 1 */ | ||
158 | #define RIOC_CONFIG_COR2 2 /* Option register 2 */ | ||
159 | #define RIOC_CONFIG_COR4 3 /* Option register 4 */ | ||
160 | #define RIOC_CONFIG_COR5 4 /* Option register 5 */ | ||
161 | #define RIOC_CONFIG_TXXON 5 /* Tx XON character */ | ||
162 | #define RIOC_CONFIG_TXXOFF 6 /* Tx XOFF character */ | ||
163 | #define RIOC_CONFIG_RXXON 7 /* Rx XON character */ | ||
164 | #define RIOC_CONFIG_RXXOFF 8 /* Rx XOFF character */ | ||
165 | #define RIOC_CONFIG_LNEXT 9 /* LNEXT character */ | ||
166 | #define RIOC_CONFIG_TXBAUD 10 /* Tx baud rate */ | ||
167 | #define RIOC_CONFIG_RXBAUD 11 /* Rx baud rate */ | ||
168 | |||
169 | #define RIOC_PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */ | ||
170 | |||
171 | /* Packet types going from Host to remote - with the exception of OPEN, MOPEN, | ||
172 | CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not | ||
173 | be used | ||
174 | */ | ||
175 | #define RIOC_OPEN 0x00 /* Open a port */ | ||
176 | #define RIOC_CONFIG 0x01 /* Configure a port */ | ||
177 | #define RIOC_MOPEN 0x02 /* Modem open (block for DCD) */ | ||
178 | #define RIOC_CLOSE 0x03 /* Close a port */ | ||
179 | #define RIOC_WFLUSH (0x04 | RIOC_PRE_EMPTIVE) /* Write flush */ | ||
180 | #define RIOC_RFLUSH (0x05 | RIOC_PRE_EMPTIVE) /* Read flush */ | ||
181 | #define RIOC_RESUME (0x06 | RIOC_PRE_EMPTIVE) /* Resume if xoffed */ | ||
182 | #define RIOC_SBREAK 0x07 /* Start break */ | ||
183 | #define RIOC_EBREAK 0x08 /* End break */ | ||
184 | #define RIOC_SUSPEND (0x09 | RIOC_PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */ | ||
185 | #define RIOC_FCLOSE (0x0a | RIOC_PRE_EMPTIVE) /* Force close */ | ||
186 | #define RIOC_XPRINT 0x0b /* Xprint packet */ | ||
187 | #define RIOC_MBIS (0x0c | RIOC_PRE_EMPTIVE) /* Set modem lines */ | ||
188 | #define RIOC_MBIC (0x0d | RIOC_PRE_EMPTIVE) /* Clear modem lines */ | ||
189 | #define RIOC_MSET (0x0e | RIOC_PRE_EMPTIVE) /* Set modem lines */ | ||
190 | #define RIOC_PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */ | ||
191 | #define RIOC_MGET (0x10 | RIOC_PRE_EMPTIVE) /* Force update of modem status */ | ||
192 | #define RIOC_MEMDUMP (0x11 | RIOC_PRE_EMPTIVE) /* Send back mem from addr supplied */ | ||
193 | #define RIOC_READ_REGISTER (0x12 | RIOC_PRE_EMPTIVE) /* Read CD1400 register (debug) */ | ||
194 | |||
195 | /* "Command" packets going from remote to host COMPLETE and MODEM_STATUS | ||
196 | use data[4] / data[3] to indicate current state and modem status respectively | ||
197 | */ | ||
198 | |||
199 | #define RIOC_COMPLETE (0x20 | RIOC_PRE_EMPTIVE) | ||
200 | /* Command complete */ | ||
201 | #define RIOC_BREAK_RECEIVED (0x21 | RIOC_PRE_EMPTIVE) | ||
202 | /* Break received */ | ||
203 | #define RIOC_MODEM_STATUS (0x22 | RIOC_PRE_EMPTIVE) | ||
204 | /* Change in modem status */ | ||
205 | |||
206 | /* "Command" packet that could go either way - handshake wake-up */ | ||
207 | #define RIOC_HANDSHAKE (0x23 | RIOC_PRE_EMPTIVE) | ||
208 | /* Wake-up to HOST / RTA */ | ||
209 | |||
210 | #endif | ||
diff --git a/drivers/char/rio/cmdblk.h b/drivers/char/rio/cmdblk.h deleted file mode 100644 index 9ed4f861675a..000000000000 --- a/drivers/char/rio/cmdblk.h +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : cmdblk.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:09 | ||
26 | ** Retrieved : 11/6/98 11:34:20 | ||
27 | ** | ||
28 | ** ident @(#)cmdblk.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_cmdblk_h__ | ||
34 | #define __rio_cmdblk_h__ | ||
35 | |||
36 | /* | ||
37 | ** the structure of a command block, used to queue commands destined for | ||
38 | ** a rup. | ||
39 | */ | ||
40 | |||
41 | struct CmdBlk { | ||
42 | struct CmdBlk *NextP; /* Pointer to next command block */ | ||
43 | struct PKT Packet; /* A packet, to copy to the rup */ | ||
44 | /* The func to call to check if OK */ | ||
45 | int (*PreFuncP) (unsigned long, struct CmdBlk *); | ||
46 | int PreArg; /* The arg for the func */ | ||
47 | /* The func to call when completed */ | ||
48 | int (*PostFuncP) (unsigned long, struct CmdBlk *); | ||
49 | int PostArg; /* The arg for the func */ | ||
50 | }; | ||
51 | |||
52 | #define NUM_RIO_CMD_BLKS (3 * (MAX_RUP * 4 + LINKS_PER_UNIT * 4)) | ||
53 | #endif | ||
diff --git a/drivers/char/rio/cmdpkt.h b/drivers/char/rio/cmdpkt.h deleted file mode 100644 index c1e7a2798070..000000000000 --- a/drivers/char/rio/cmdpkt.h +++ /dev/null | |||
@@ -1,177 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : cmdpkt.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:09 | ||
26 | ** Retrieved : 11/6/98 11:34:20 | ||
27 | ** | ||
28 | ** ident @(#)cmdpkt.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | #ifndef __rio_cmdpkt_h__ | ||
33 | #define __rio_cmdpkt_h__ | ||
34 | |||
35 | /* | ||
36 | ** overlays for the data area of a packet. Used in both directions | ||
37 | ** (to build a packet to send, and to interpret a packet that arrives) | ||
38 | ** and is very inconvenient for MIPS, so they appear as two separate | ||
39 | ** structures - those used for modifying/reading packets on the card | ||
40 | ** and those for modifying/reading packets in real memory, which have an _M | ||
41 | ** suffix. | ||
42 | */ | ||
43 | |||
44 | #define RTA_BOOT_DATA_SIZE (PKT_MAX_DATA_LEN-2) | ||
45 | |||
46 | /* | ||
47 | ** The boot information packet looks like this: | ||
48 | ** This structure overlays a PktCmd->CmdData structure, and so starts | ||
49 | ** at Data[2] in the actual pkt! | ||
50 | */ | ||
51 | struct BootSequence { | ||
52 | u16 NumPackets; | ||
53 | u16 LoadBase; | ||
54 | u16 CodeSize; | ||
55 | }; | ||
56 | |||
57 | #define BOOT_SEQUENCE_LEN 8 | ||
58 | |||
59 | struct SamTop { | ||
60 | u8 Unit; | ||
61 | u8 Link; | ||
62 | }; | ||
63 | |||
64 | struct CmdHdr { | ||
65 | u8 PcCommand; | ||
66 | union { | ||
67 | u8 PcPhbNum; | ||
68 | u8 PcLinkNum; | ||
69 | u8 PcIDNum; | ||
70 | } U0; | ||
71 | }; | ||
72 | |||
73 | |||
74 | struct PktCmd { | ||
75 | union { | ||
76 | struct { | ||
77 | struct CmdHdr CmdHdr; | ||
78 | struct BootSequence PcBootSequence; | ||
79 | } S1; | ||
80 | struct { | ||
81 | u16 PcSequence; | ||
82 | u8 PcBootData[RTA_BOOT_DATA_SIZE]; | ||
83 | } S2; | ||
84 | struct { | ||
85 | u16 __crud__; | ||
86 | u8 PcUniqNum[4]; /* this is really a uint. */ | ||
87 | u8 PcModuleTypes; /* what modules are fitted */ | ||
88 | } S3; | ||
89 | struct { | ||
90 | struct CmdHdr CmdHdr; | ||
91 | u8 __undefined__; | ||
92 | u8 PcModemStatus; | ||
93 | u8 PcPortStatus; | ||
94 | u8 PcSubCommand; /* commands like mem or register dump */ | ||
95 | u16 PcSubAddr; /* Address for command */ | ||
96 | u8 PcSubData[64]; /* Date area for command */ | ||
97 | } S4; | ||
98 | struct { | ||
99 | struct CmdHdr CmdHdr; | ||
100 | u8 PcCommandText[1]; | ||
101 | u8 __crud__[20]; | ||
102 | u8 PcIDNum2; /* It had to go somewhere! */ | ||
103 | } S5; | ||
104 | struct { | ||
105 | struct CmdHdr CmdHdr; | ||
106 | struct SamTop Topology[LINKS_PER_UNIT]; | ||
107 | } S6; | ||
108 | } U1; | ||
109 | }; | ||
110 | |||
111 | struct PktCmd_M { | ||
112 | union { | ||
113 | struct { | ||
114 | struct { | ||
115 | u8 PcCommand; | ||
116 | union { | ||
117 | u8 PcPhbNum; | ||
118 | u8 PcLinkNum; | ||
119 | u8 PcIDNum; | ||
120 | } U0; | ||
121 | } CmdHdr; | ||
122 | struct { | ||
123 | u16 NumPackets; | ||
124 | u16 LoadBase; | ||
125 | u16 CodeSize; | ||
126 | } PcBootSequence; | ||
127 | } S1; | ||
128 | struct { | ||
129 | u16 PcSequence; | ||
130 | u8 PcBootData[RTA_BOOT_DATA_SIZE]; | ||
131 | } S2; | ||
132 | struct { | ||
133 | u16 __crud__; | ||
134 | u8 PcUniqNum[4]; /* this is really a uint. */ | ||
135 | u8 PcModuleTypes; /* what modules are fitted */ | ||
136 | } S3; | ||
137 | struct { | ||
138 | u16 __cmd_hdr__; | ||
139 | u8 __undefined__; | ||
140 | u8 PcModemStatus; | ||
141 | u8 PcPortStatus; | ||
142 | u8 PcSubCommand; | ||
143 | u16 PcSubAddr; | ||
144 | u8 PcSubData[64]; | ||
145 | } S4; | ||
146 | struct { | ||
147 | u16 __cmd_hdr__; | ||
148 | u8 PcCommandText[1]; | ||
149 | u8 __crud__[20]; | ||
150 | u8 PcIDNum2; /* Tacked on end */ | ||
151 | } S5; | ||
152 | struct { | ||
153 | u16 __cmd_hdr__; | ||
154 | struct Top Topology[LINKS_PER_UNIT]; | ||
155 | } S6; | ||
156 | } U1; | ||
157 | }; | ||
158 | |||
159 | #define Command U1.S1.CmdHdr.PcCommand | ||
160 | #define PhbNum U1.S1.CmdHdr.U0.PcPhbNum | ||
161 | #define IDNum U1.S1.CmdHdr.U0.PcIDNum | ||
162 | #define IDNum2 U1.S5.PcIDNum2 | ||
163 | #define LinkNum U1.S1.CmdHdr.U0.PcLinkNum | ||
164 | #define Sequence U1.S2.PcSequence | ||
165 | #define BootData U1.S2.PcBootData | ||
166 | #define BootSequence U1.S1.PcBootSequence | ||
167 | #define UniqNum U1.S3.PcUniqNum | ||
168 | #define ModemStatus U1.S4.PcModemStatus | ||
169 | #define PortStatus U1.S4.PcPortStatus | ||
170 | #define SubCommand U1.S4.PcSubCommand | ||
171 | #define SubAddr U1.S4.PcSubAddr | ||
172 | #define SubData U1.S4.PcSubData | ||
173 | #define CommandText U1.S5.PcCommandText | ||
174 | #define RouteTopology U1.S6.Topology | ||
175 | #define ModuleTypes U1.S3.PcModuleTypes | ||
176 | |||
177 | #endif | ||
diff --git a/drivers/char/rio/daemon.h b/drivers/char/rio/daemon.h deleted file mode 100644 index 4af90323fd00..000000000000 --- a/drivers/char/rio/daemon.h +++ /dev/null | |||
@@ -1,307 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : daemon.h | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 11:34:09 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)daemon.h 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_daemon_h__ | ||
34 | #define __rio_daemon_h__ | ||
35 | |||
36 | |||
37 | /* | ||
38 | ** structures used on /dev/rio | ||
39 | */ | ||
40 | |||
41 | struct Error { | ||
42 | unsigned int Error; | ||
43 | unsigned int Entry; | ||
44 | unsigned int Other; | ||
45 | }; | ||
46 | |||
47 | struct DownLoad { | ||
48 | char __user *DataP; | ||
49 | unsigned int Count; | ||
50 | unsigned int ProductCode; | ||
51 | }; | ||
52 | |||
53 | /* | ||
54 | ** A few constants.... | ||
55 | */ | ||
56 | #ifndef MAX_VERSION_LEN | ||
57 | #define MAX_VERSION_LEN 256 | ||
58 | #endif | ||
59 | |||
60 | #ifndef MAX_XP_CTRL_LEN | ||
61 | #define MAX_XP_CTRL_LEN 16 /* ALSO IN PORT.H */ | ||
62 | #endif | ||
63 | |||
64 | struct PortSetup { | ||
65 | unsigned int From; /* Set/Clear XP & IXANY Control from this port.... */ | ||
66 | unsigned int To; /* .... to this port */ | ||
67 | unsigned int XpCps; /* at this speed */ | ||
68 | char XpOn[MAX_XP_CTRL_LEN]; /* this is the start string */ | ||
69 | char XpOff[MAX_XP_CTRL_LEN]; /* this is the stop string */ | ||
70 | u8 IxAny; /* enable/disable IXANY */ | ||
71 | u8 IxOn; /* enable/disable IXON */ | ||
72 | u8 Lock; /* lock port params */ | ||
73 | u8 Store; /* store params across closes */ | ||
74 | u8 Drain; /* close only when drained */ | ||
75 | }; | ||
76 | |||
77 | struct LpbReq { | ||
78 | unsigned int Host; | ||
79 | unsigned int Link; | ||
80 | struct LPB __user *LpbP; | ||
81 | }; | ||
82 | |||
83 | struct RupReq { | ||
84 | unsigned int HostNum; | ||
85 | unsigned int RupNum; | ||
86 | struct RUP __user *RupP; | ||
87 | }; | ||
88 | |||
89 | struct PortReq { | ||
90 | unsigned int SysPort; | ||
91 | struct Port __user *PortP; | ||
92 | }; | ||
93 | |||
94 | struct StreamInfo { | ||
95 | unsigned int SysPort; | ||
96 | int RQueue; | ||
97 | int WQueue; | ||
98 | }; | ||
99 | |||
100 | struct HostReq { | ||
101 | unsigned int HostNum; | ||
102 | struct Host __user *HostP; | ||
103 | }; | ||
104 | |||
105 | struct HostDpRam { | ||
106 | unsigned int HostNum; | ||
107 | struct DpRam __user *DpRamP; | ||
108 | }; | ||
109 | |||
110 | struct DebugCtrl { | ||
111 | unsigned int SysPort; | ||
112 | unsigned int Debug; | ||
113 | unsigned int Wait; | ||
114 | }; | ||
115 | |||
116 | struct MapInfo { | ||
117 | unsigned int FirstPort; /* 8 ports, starting from this (tty) number */ | ||
118 | unsigned int RtaUnique; /* reside on this RTA (unique number) */ | ||
119 | }; | ||
120 | |||
121 | struct MapIn { | ||
122 | unsigned int NumEntries; /* How many port sets are we mapping? */ | ||
123 | struct MapInfo *MapInfoP; /* Pointer to (user space) info */ | ||
124 | }; | ||
125 | |||
126 | struct SendPack { | ||
127 | unsigned int PortNum; | ||
128 | unsigned char Len; | ||
129 | unsigned char Data[PKT_MAX_DATA_LEN]; | ||
130 | }; | ||
131 | |||
132 | struct SpecialRupCmd { | ||
133 | struct PKT Packet; | ||
134 | unsigned short Host; | ||
135 | unsigned short RupNum; | ||
136 | }; | ||
137 | |||
138 | struct IdentifyRta { | ||
139 | unsigned long RtaUnique; | ||
140 | u8 ID; | ||
141 | }; | ||
142 | |||
143 | struct KillNeighbour { | ||
144 | unsigned long UniqueNum; | ||
145 | u8 Link; | ||
146 | }; | ||
147 | |||
148 | struct rioVersion { | ||
149 | char version[MAX_VERSION_LEN]; | ||
150 | char relid[MAX_VERSION_LEN]; | ||
151 | int buildLevel; | ||
152 | char buildDate[MAX_VERSION_LEN]; | ||
153 | }; | ||
154 | |||
155 | |||
156 | /* | ||
157 | ** RIOC commands are for the daemon type operations | ||
158 | ** | ||
159 | ** 09.12.1998 ARG - ESIL 0776 part fix | ||
160 | ** Definition for 'RIOC' also appears in rioioctl.h, so we'd better do a | ||
161 | ** #ifndef here first. | ||
162 | ** rioioctl.h also now has #define 'RIO_QUICK_CHECK' as this ioctl is now | ||
163 | ** allowed to be used by customers. | ||
164 | */ | ||
165 | #ifndef RIOC | ||
166 | #define RIOC ('R'<<8)|('i'<<16)|('o'<<24) | ||
167 | #endif | ||
168 | |||
169 | /* | ||
170 | ** Boot stuff | ||
171 | */ | ||
172 | #define RIO_GET_TABLE (RIOC | 100) | ||
173 | #define RIO_PUT_TABLE (RIOC | 101) | ||
174 | #define RIO_ASSIGN_RTA (RIOC | 102) | ||
175 | #define RIO_DELETE_RTA (RIOC | 103) | ||
176 | #define RIO_HOST_FOAD (RIOC | 104) | ||
177 | #define RIO_QUICK_CHECK (RIOC | 105) | ||
178 | #define RIO_SIGNALS_ON (RIOC | 106) | ||
179 | #define RIO_SIGNALS_OFF (RIOC | 107) | ||
180 | #define RIO_CHANGE_NAME (RIOC | 108) | ||
181 | #define RIO_DOWNLOAD (RIOC | 109) | ||
182 | #define RIO_GET_LOG (RIOC | 110) | ||
183 | #define RIO_SETUP_PORTS (RIOC | 111) | ||
184 | #define RIO_ALL_MODEM (RIOC | 112) | ||
185 | |||
186 | /* | ||
187 | ** card state, debug stuff | ||
188 | */ | ||
189 | #define RIO_NUM_HOSTS (RIOC | 120) | ||
190 | #define RIO_HOST_LPB (RIOC | 121) | ||
191 | #define RIO_HOST_RUP (RIOC | 122) | ||
192 | #define RIO_HOST_PORT (RIOC | 123) | ||
193 | #define RIO_PARMS (RIOC | 124) | ||
194 | #define RIO_HOST_REQ (RIOC | 125) | ||
195 | #define RIO_READ_CONFIG (RIOC | 126) | ||
196 | #define RIO_SET_CONFIG (RIOC | 127) | ||
197 | #define RIO_VERSID (RIOC | 128) | ||
198 | #define RIO_FLAGS (RIOC | 129) | ||
199 | #define RIO_SETDEBUG (RIOC | 130) | ||
200 | #define RIO_GETDEBUG (RIOC | 131) | ||
201 | #define RIO_READ_LEVELS (RIOC | 132) | ||
202 | #define RIO_SET_FAST_BUS (RIOC | 133) | ||
203 | #define RIO_SET_SLOW_BUS (RIOC | 134) | ||
204 | #define RIO_SET_BYTE_MODE (RIOC | 135) | ||
205 | #define RIO_SET_WORD_MODE (RIOC | 136) | ||
206 | #define RIO_STREAM_INFO (RIOC | 137) | ||
207 | #define RIO_START_POLLER (RIOC | 138) | ||
208 | #define RIO_STOP_POLLER (RIOC | 139) | ||
209 | #define RIO_LAST_ERROR (RIOC | 140) | ||
210 | #define RIO_TICK (RIOC | 141) | ||
211 | #define RIO_TOCK (RIOC | 241) /* I did this on purpose, you know. */ | ||
212 | #define RIO_SEND_PACKET (RIOC | 142) | ||
213 | #define RIO_SET_BUSY (RIOC | 143) | ||
214 | #define SPECIAL_RUP_CMD (RIOC | 144) | ||
215 | #define RIO_FOAD_RTA (RIOC | 145) | ||
216 | #define RIO_ZOMBIE_RTA (RIOC | 146) | ||
217 | #define RIO_IDENTIFY_RTA (RIOC | 147) | ||
218 | #define RIO_KILL_NEIGHBOUR (RIOC | 148) | ||
219 | #define RIO_DEBUG_MEM (RIOC | 149) | ||
220 | /* | ||
221 | ** 150 - 167 used..... See below | ||
222 | */ | ||
223 | #define RIO_GET_PORT_SETUP (RIOC | 168) | ||
224 | #define RIO_RESUME (RIOC | 169) | ||
225 | #define RIO_MESG (RIOC | 170) | ||
226 | #define RIO_NO_MESG (RIOC | 171) | ||
227 | #define RIO_WHAT_MESG (RIOC | 172) | ||
228 | #define RIO_HOST_DPRAM (RIOC | 173) | ||
229 | #define RIO_MAP_B50_TO_50 (RIOC | 174) | ||
230 | #define RIO_MAP_B50_TO_57600 (RIOC | 175) | ||
231 | #define RIO_MAP_B110_TO_110 (RIOC | 176) | ||
232 | #define RIO_MAP_B110_TO_115200 (RIOC | 177) | ||
233 | #define RIO_GET_PORT_PARAMS (RIOC | 178) | ||
234 | #define RIO_SET_PORT_PARAMS (RIOC | 179) | ||
235 | #define RIO_GET_PORT_TTY (RIOC | 180) | ||
236 | #define RIO_SET_PORT_TTY (RIOC | 181) | ||
237 | #define RIO_SYSLOG_ONLY (RIOC | 182) | ||
238 | #define RIO_SYSLOG_CONS (RIOC | 183) | ||
239 | #define RIO_CONS_ONLY (RIOC | 184) | ||
240 | #define RIO_BLOCK_OPENS (RIOC | 185) | ||
241 | |||
242 | /* | ||
243 | ** 02.03.1999 ARG - ESIL 0820 fix : | ||
244 | ** RIOBootMode is no longer use by the driver, so these ioctls | ||
245 | ** are now obsolete : | ||
246 | ** | ||
247 | #define RIO_GET_BOOT_MODE (RIOC | 186) | ||
248 | #define RIO_SET_BOOT_MODE (RIOC | 187) | ||
249 | ** | ||
250 | */ | ||
251 | |||
252 | #define RIO_MEM_DUMP (RIOC | 189) | ||
253 | #define RIO_READ_REGISTER (RIOC | 190) | ||
254 | #define RIO_GET_MODTYPE (RIOC | 191) | ||
255 | #define RIO_SET_TIMER (RIOC | 192) | ||
256 | #define RIO_READ_CHECK (RIOC | 196) | ||
257 | #define RIO_WAITING_FOR_RESTART (RIOC | 197) | ||
258 | #define RIO_BIND_RTA (RIOC | 198) | ||
259 | #define RIO_GET_BINDINGS (RIOC | 199) | ||
260 | #define RIO_PUT_BINDINGS (RIOC | 200) | ||
261 | |||
262 | #define RIO_MAKE_DEV (RIOC | 201) | ||
263 | #define RIO_MINOR (RIOC | 202) | ||
264 | |||
265 | #define RIO_IDENTIFY_DRIVER (RIOC | 203) | ||
266 | #define RIO_DISPLAY_HOST_CFG (RIOC | 204) | ||
267 | |||
268 | |||
269 | /* | ||
270 | ** MAKE_DEV / MINOR stuff | ||
271 | */ | ||
272 | #define RIO_DEV_DIRECT 0x0000 | ||
273 | #define RIO_DEV_MODEM 0x0200 | ||
274 | #define RIO_DEV_XPRINT 0x0400 | ||
275 | #define RIO_DEV_MASK 0x0600 | ||
276 | |||
277 | /* | ||
278 | ** port management, xprint stuff | ||
279 | */ | ||
280 | #define rIOCN(N) (RIOC|(N)) | ||
281 | #define rIOCR(N,T) (RIOC|(N)) | ||
282 | #define rIOCW(N,T) (RIOC|(N)) | ||
283 | |||
284 | #define RIO_GET_XP_ON rIOCR(150,char[16]) /* start xprint string */ | ||
285 | #define RIO_SET_XP_ON rIOCW(151,char[16]) | ||
286 | #define RIO_GET_XP_OFF rIOCR(152,char[16]) /* finish xprint string */ | ||
287 | #define RIO_SET_XP_OFF rIOCW(153,char[16]) | ||
288 | #define RIO_GET_XP_CPS rIOCR(154,int) /* xprint CPS */ | ||
289 | #define RIO_SET_XP_CPS rIOCW(155,int) | ||
290 | #define RIO_GET_IXANY rIOCR(156,int) /* ixany allowed? */ | ||
291 | #define RIO_SET_IXANY rIOCW(157,int) | ||
292 | #define RIO_SET_IXANY_ON rIOCN(158) /* allow ixany */ | ||
293 | #define RIO_SET_IXANY_OFF rIOCN(159) /* disallow ixany */ | ||
294 | #define RIO_GET_MODEM rIOCR(160,int) /* port is modem/direct line? */ | ||
295 | #define RIO_SET_MODEM rIOCW(161,int) | ||
296 | #define RIO_SET_MODEM_ON rIOCN(162) /* port is a modem */ | ||
297 | #define RIO_SET_MODEM_OFF rIOCN(163) /* port is direct */ | ||
298 | #define RIO_GET_IXON rIOCR(164,int) /* ixon allowed? */ | ||
299 | #define RIO_SET_IXON rIOCW(165,int) | ||
300 | #define RIO_SET_IXON_ON rIOCN(166) /* allow ixon */ | ||
301 | #define RIO_SET_IXON_OFF rIOCN(167) /* disallow ixon */ | ||
302 | |||
303 | #define RIO_GET_SIVIEW ((('s')<<8) | 106) /* backwards compatible with SI */ | ||
304 | |||
305 | #define RIO_IOCTL_UNKNOWN -2 | ||
306 | |||
307 | #endif | ||
diff --git a/drivers/char/rio/errors.h b/drivers/char/rio/errors.h deleted file mode 100644 index bdb05234090a..000000000000 --- a/drivers/char/rio/errors.h +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : errors.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:10 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)errors.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_errors_h__ | ||
34 | #define __rio_errors_h__ | ||
35 | |||
36 | /* | ||
37 | ** error codes | ||
38 | */ | ||
39 | |||
40 | #define NOTHING_WRONG_AT_ALL 0 | ||
41 | #define BAD_CHARACTER_IN_NAME 1 | ||
42 | #define TABLE_ENTRY_ISNT_PROPERLY_NULL 2 | ||
43 | #define UNKNOWN_HOST_NUMBER 3 | ||
44 | #define ZERO_RTA_ID 4 | ||
45 | #define BAD_RTA_ID 5 | ||
46 | #define DUPLICATED_RTA_ID 6 | ||
47 | #define DUPLICATE_UNIQUE_NUMBER 7 | ||
48 | #define BAD_TTY_NUMBER 8 | ||
49 | #define TTY_NUMBER_IN_USE 9 | ||
50 | #define NAME_USED_TWICE 10 | ||
51 | #define HOST_ID_NOT_ZERO 11 | ||
52 | #define BOOT_IN_PROGRESS 12 | ||
53 | #define COPYIN_FAILED 13 | ||
54 | #define HOST_FILE_TOO_LARGE 14 | ||
55 | #define COPYOUT_FAILED 15 | ||
56 | #define NOT_SUPER_USER 16 | ||
57 | #define RIO_ALREADY_POLLING 17 | ||
58 | |||
59 | #define ID_NUMBER_OUT_OF_RANGE 18 | ||
60 | #define PORT_NUMBER_OUT_OF_RANGE 19 | ||
61 | #define HOST_NUMBER_OUT_OF_RANGE 20 | ||
62 | #define RUP_NUMBER_OUT_OF_RANGE 21 | ||
63 | #define TTY_NUMBER_OUT_OF_RANGE 22 | ||
64 | #define LINK_NUMBER_OUT_OF_RANGE 23 | ||
65 | |||
66 | #define HOST_NOT_RUNNING 24 | ||
67 | #define IOCTL_COMMAND_UNKNOWN 25 | ||
68 | #define RIO_SYSTEM_HALTED 26 | ||
69 | #define WAIT_FOR_DRAIN_BROKEN 27 | ||
70 | #define PORT_NOT_MAPPED_INTO_SYSTEM 28 | ||
71 | #define EXCLUSIVE_USE_SET 29 | ||
72 | #define WAIT_FOR_NOT_CLOSING_BROKEN 30 | ||
73 | #define WAIT_FOR_PORT_TO_OPEN_BROKEN 31 | ||
74 | #define WAIT_FOR_CARRIER_BROKEN 32 | ||
75 | #define WAIT_FOR_NOT_IN_USE_BROKEN 33 | ||
76 | #define WAIT_FOR_CAN_ADD_COMMAND_BROKEN 34 | ||
77 | #define WAIT_FOR_ADD_COMMAND_BROKEN 35 | ||
78 | #define WAIT_FOR_NOT_PARAM_BROKEN 36 | ||
79 | #define WAIT_FOR_RETRY_BROKEN 37 | ||
80 | #define HOST_HAS_ALREADY_BEEN_BOOTED 38 | ||
81 | #define UNIT_IS_IN_USE 39 | ||
82 | #define COULDNT_FIND_ENTRY 40 | ||
83 | #define RTA_UNIQUE_NUMBER_ZERO 41 | ||
84 | #define CLOSE_COMMAND_FAILED 42 | ||
85 | #define WAIT_FOR_CLOSE_BROKEN 43 | ||
86 | #define CPS_VALUE_OUT_OF_RANGE 44 | ||
87 | #define ID_ALREADY_IN_USE 45 | ||
88 | #define SIGNALS_ALREADY_SET 46 | ||
89 | #define NOT_RECEIVING_PROCESS 47 | ||
90 | #define RTA_NUMBER_WRONG 48 | ||
91 | #define NO_SUCH_PRODUCT 49 | ||
92 | #define HOST_SYSPORT_BAD 50 | ||
93 | #define ID_NOT_TENTATIVE 51 | ||
94 | #define XPRINT_CPS_OUT_OF_RANGE 52 | ||
95 | #define NOT_ENOUGH_CORE_FOR_PCI_COPY 53 | ||
96 | |||
97 | |||
98 | #endif /* __rio_errors_h__ */ | ||
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h deleted file mode 100644 index 078d44f85e45..000000000000 --- a/drivers/char/rio/func.h +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : func.h | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 11:34:10 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)func.h 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __func_h_def | ||
34 | #define __func_h_def | ||
35 | |||
36 | #include <linux/kdev_t.h> | ||
37 | |||
38 | /* rioboot.c */ | ||
39 | int RIOBootCodeRTA(struct rio_info *, struct DownLoad *); | ||
40 | int RIOBootCodeHOST(struct rio_info *, struct DownLoad *); | ||
41 | int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *); | ||
42 | void msec_timeout(struct Host *); | ||
43 | int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); | ||
44 | int RIOBootOk(struct rio_info *, struct Host *, unsigned long); | ||
45 | int RIORtaBound(struct rio_info *, unsigned int); | ||
46 | void rio_fill_host_slot(int, int, unsigned int, struct Host *); | ||
47 | |||
48 | /* riocmd.c */ | ||
49 | int RIOFoadRta(struct Host *, struct Map *); | ||
50 | int RIOZombieRta(struct Host *, struct Map *); | ||
51 | int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *)); | ||
52 | int RIOIdentifyRta(struct rio_info *, void __user *); | ||
53 | int RIOKillNeighbour(struct rio_info *, void __user *); | ||
54 | int RIOSuspendBootRta(struct Host *, int, int); | ||
55 | int RIOFoadWakeup(struct rio_info *); | ||
56 | struct CmdBlk *RIOGetCmdBlk(void); | ||
57 | void RIOFreeCmdBlk(struct CmdBlk *); | ||
58 | int RIOQueueCmdBlk(struct Host *, unsigned int, struct CmdBlk *); | ||
59 | void RIOPollHostCommands(struct rio_info *, struct Host *); | ||
60 | int RIOWFlushMark(unsigned long, struct CmdBlk *); | ||
61 | int RIORFlushEnable(unsigned long, struct CmdBlk *); | ||
62 | int RIOUnUse(unsigned long, struct CmdBlk *); | ||
63 | |||
64 | /* rioctrl.c */ | ||
65 | int riocontrol(struct rio_info *, dev_t, int, unsigned long, int); | ||
66 | |||
67 | int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char); | ||
68 | |||
69 | /* rioinit.c */ | ||
70 | void rioinit(struct rio_info *, struct RioHostInfo *); | ||
71 | void RIOInitHosts(struct rio_info *, struct RioHostInfo *); | ||
72 | void RIOISAinit(struct rio_info *, int); | ||
73 | int RIODoAT(struct rio_info *, int, int); | ||
74 | caddr_t RIOCheckForATCard(int); | ||
75 | int RIOAssignAT(struct rio_info *, int, void __iomem *, int); | ||
76 | int RIOBoardTest(unsigned long, void __iomem *, unsigned char, int); | ||
77 | void RIOAllocDataStructs(struct rio_info *); | ||
78 | void RIOSetupDataStructs(struct rio_info *); | ||
79 | int RIODefaultName(struct rio_info *, struct Host *, unsigned int); | ||
80 | struct rioVersion *RIOVersid(void); | ||
81 | void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int); | ||
82 | |||
83 | /* riointr.c */ | ||
84 | void RIOTxEnable(char *); | ||
85 | void RIOServiceHost(struct rio_info *, struct Host *); | ||
86 | int riotproc(struct rio_info *, struct ttystatics *, int, int); | ||
87 | |||
88 | /* rioparam.c */ | ||
89 | int RIOParam(struct Port *, int, int, int); | ||
90 | int RIODelay(struct Port *PortP, int); | ||
91 | int RIODelay_ni(struct Port *PortP, int); | ||
92 | void ms_timeout(struct Port *); | ||
93 | int can_add_transmit(struct PKT __iomem **, struct Port *); | ||
94 | void add_transmit(struct Port *); | ||
95 | void put_free_end(struct Host *, struct PKT __iomem *); | ||
96 | int can_remove_receive(struct PKT __iomem **, struct Port *); | ||
97 | void remove_receive(struct Port *); | ||
98 | |||
99 | /* rioroute.c */ | ||
100 | int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); | ||
101 | void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int); | ||
102 | unsigned int GetUnitType(unsigned int); | ||
103 | int RIOSetChange(struct rio_info *); | ||
104 | int RIOFindFreeID(struct rio_info *, struct Host *, unsigned int *, unsigned int *); | ||
105 | |||
106 | |||
107 | /* riotty.c */ | ||
108 | |||
109 | int riotopen(struct tty_struct *tty, struct file *filp); | ||
110 | int riotclose(void *ptr); | ||
111 | int riotioctl(struct rio_info *, struct tty_struct *, int, caddr_t); | ||
112 | void ttyseth(struct Port *, struct ttystatics *, struct old_sgttyb *sg); | ||
113 | |||
114 | /* riotable.c */ | ||
115 | int RIONewTable(struct rio_info *); | ||
116 | int RIOApel(struct rio_info *); | ||
117 | int RIODeleteRta(struct rio_info *, struct Map *); | ||
118 | int RIOAssignRta(struct rio_info *, struct Map *); | ||
119 | int RIOReMapPorts(struct rio_info *, struct Host *, struct Map *); | ||
120 | int RIOChangeName(struct rio_info *, struct Map *); | ||
121 | |||
122 | #if 0 | ||
123 | /* riodrvr.c */ | ||
124 | struct rio_info *rio_install(struct RioHostInfo *); | ||
125 | int rio_uninstall(struct rio_info *); | ||
126 | int rio_open(struct rio_info *, int, struct file *); | ||
127 | int rio_close(struct rio_info *, struct file *); | ||
128 | int rio_read(struct rio_info *, struct file *, char *, int); | ||
129 | int rio_write(struct rio_info *, struct file *f, char *, int); | ||
130 | int rio_ioctl(struct rio_info *, struct file *, int, char *); | ||
131 | int rio_select(struct rio_info *, struct file *f, int, struct sel *); | ||
132 | int rio_intr(char *); | ||
133 | int rio_isr_thread(char *); | ||
134 | struct rio_info *rio_info_store(int cmd, struct rio_info *p); | ||
135 | #endif | ||
136 | |||
137 | extern void rio_copy_to_card(void *from, void __iomem *to, int len); | ||
138 | extern int rio_minor(struct tty_struct *tty); | ||
139 | extern int rio_ismodem(struct tty_struct *tty); | ||
140 | |||
141 | extern void rio_start_card_running(struct Host *HostP); | ||
142 | |||
143 | #endif /* __func_h_def */ | ||
diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h deleted file mode 100644 index 78f24540c224..000000000000 --- a/drivers/char/rio/host.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : host.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:10 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)host.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_host_h__ | ||
34 | #define __rio_host_h__ | ||
35 | |||
36 | /* | ||
37 | ** the host structure - one per host card in the system. | ||
38 | */ | ||
39 | |||
40 | #define MAX_EXTRA_UNITS 64 | ||
41 | |||
42 | /* | ||
43 | ** Host data structure. This is used for the software equiv. of | ||
44 | ** the host. | ||
45 | */ | ||
46 | struct Host { | ||
47 | struct pci_dev *pdev; | ||
48 | unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ | ||
49 | unsigned char Ivec; /* POLLED or ivec number */ | ||
50 | unsigned char Mode; /* Control stuff */ | ||
51 | unsigned char Slot; /* Slot */ | ||
52 | void __iomem *Caddr; /* KV address of DPRAM */ | ||
53 | struct DpRam __iomem *CardP; /* KV address of DPRAM, with overlay */ | ||
54 | unsigned long PaddrP; /* Phys. address of DPRAM */ | ||
55 | char Name[MAX_NAME_LEN]; /* The name of the host */ | ||
56 | unsigned int UniqueNum; /* host unique number */ | ||
57 | spinlock_t HostLock; /* Lock structure for MPX */ | ||
58 | unsigned int WorkToBeDone; /* set to true each interrupt */ | ||
59 | unsigned int InIntr; /* Being serviced? */ | ||
60 | unsigned int IntSrvDone; /* host's interrupt has been serviced */ | ||
61 | void (*Copy) (void *, void __iomem *, int); /* copy func */ | ||
62 | struct timer_list timer; | ||
63 | /* | ||
64 | ** I M P O R T A N T ! | ||
65 | ** | ||
66 | ** The rest of this data structure is cleared to zero after | ||
67 | ** a RIO_HOST_FOAD command. | ||
68 | */ | ||
69 | |||
70 | unsigned long Flags; /* Whats going down */ | ||
71 | #define RC_WAITING 0 | ||
72 | #define RC_STARTUP 1 | ||
73 | #define RC_RUNNING 2 | ||
74 | #define RC_STUFFED 3 | ||
75 | #define RC_READY 7 | ||
76 | #define RUN_STATE 7 | ||
77 | /* | ||
78 | ** Boot mode applies to the way in which hosts in this system will | ||
79 | ** boot RTAs | ||
80 | */ | ||
81 | #define RC_BOOT_ALL 0x8 /* Boot all RTAs attached */ | ||
82 | #define RC_BOOT_OWN 0x10 /* Only boot RTAs bound to this system */ | ||
83 | #define RC_BOOT_NONE 0x20 /* Don't boot any RTAs (slave mode) */ | ||
84 | |||
85 | struct Top Topology[LINKS_PER_UNIT]; /* one per link */ | ||
86 | struct Map Mapping[MAX_RUP]; /* Mappings for host */ | ||
87 | struct PHB __iomem *PhbP; /* Pointer to the PHB array */ | ||
88 | unsigned short __iomem *PhbNumP; /* Ptr to Number of PHB's */ | ||
89 | struct LPB __iomem *LinkStrP; /* Link Structure Array */ | ||
90 | struct RUP __iomem *RupP; /* Sixteen real rups here */ | ||
91 | struct PARM_MAP __iomem *ParmMapP; /* points to the parmmap */ | ||
92 | unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */ | ||
93 | unsigned int NumExtraBooted; /* how many of the above */ | ||
94 | /* | ||
95 | ** Twenty logical rups. | ||
96 | ** The first sixteen are the real Rup entries (above), the last four | ||
97 | ** are the link RUPs. | ||
98 | */ | ||
99 | struct UnixRup UnixRups[MAX_RUP + LINKS_PER_UNIT]; | ||
100 | int timeout_id; /* For calling 100 ms delays */ | ||
101 | int timeout_sem; /* For calling 100 ms delays */ | ||
102 | unsigned long locks; /* long req'd for set_bit --RR */ | ||
103 | char ____end_marker____; | ||
104 | }; | ||
105 | #define Control CardP->DpControl | ||
106 | #define SetInt CardP->DpSetInt | ||
107 | #define ResetTpu CardP->DpResetTpu | ||
108 | #define ResetInt CardP->DpResetInt | ||
109 | #define Signature CardP->DpSignature | ||
110 | #define Sram1 CardP->DpSram1 | ||
111 | #define Sram2 CardP->DpSram2 | ||
112 | #define Sram3 CardP->DpSram3 | ||
113 | #define Scratch CardP->DpScratch | ||
114 | #define __ParmMapR CardP->DpParmMapR | ||
115 | #define SLX CardP->DpSlx | ||
116 | #define Revision CardP->DpRevision | ||
117 | #define Unique CardP->DpUnique | ||
118 | #define Year CardP->DpYear | ||
119 | #define Week CardP->DpWeek | ||
120 | |||
121 | #define RIO_DUMBPARM 0x0860 /* what not to expect */ | ||
122 | |||
123 | #endif | ||
diff --git a/drivers/char/rio/link.h b/drivers/char/rio/link.h deleted file mode 100644 index f3bf11a04d41..000000000000 --- a/drivers/char/rio/link.h +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* L I N K | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Ian Nandhra / Jeremy Rolls | ||
8 | Date : | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | |||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _link_h | ||
38 | #define _link_h 1 | ||
39 | |||
40 | /************************************************* | ||
41 | * Define the Link Status stuff | ||
42 | ************************************************/ | ||
43 | /* Boot request stuff */ | ||
44 | #define BOOT_REQUEST ((ushort) 0) /* Request for a boot */ | ||
45 | #define BOOT_ABORT ((ushort) 1) /* Abort a boot */ | ||
46 | #define BOOT_SEQUENCE ((ushort) 2) /* Packet with the number of packets | ||
47 | and load address */ | ||
48 | #define BOOT_COMPLETED ((ushort) 3) /* Boot completed */ | ||
49 | |||
50 | |||
51 | struct LPB { | ||
52 | u16 link_number; /* Link Number */ | ||
53 | u16 in_ch; /* Link In Channel */ | ||
54 | u16 out_ch; /* Link Out Channel */ | ||
55 | u8 attached_serial[4]; /* Attached serial number */ | ||
56 | u8 attached_host_serial[4]; | ||
57 | /* Serial number of Host who | ||
58 | booted the other end */ | ||
59 | u16 descheduled; /* Currently Descheduled */ | ||
60 | u16 state; /* Current state */ | ||
61 | u16 send_poll; /* Send a Poll Packet */ | ||
62 | u16 ltt_p; /* Process Descriptor */ | ||
63 | u16 lrt_p; /* Process Descriptor */ | ||
64 | u16 lrt_status; /* Current lrt status */ | ||
65 | u16 ltt_status; /* Current ltt status */ | ||
66 | u16 timeout; /* Timeout value */ | ||
67 | u16 topology; /* Topology bits */ | ||
68 | u16 mon_ltt; | ||
69 | u16 mon_lrt; | ||
70 | u16 WaitNoBoot; /* Secs to hold off booting */ | ||
71 | u16 add_packet_list; /* Add packets to here */ | ||
72 | u16 remove_packet_list; /* Send packets from here */ | ||
73 | |||
74 | u16 lrt_fail_chan; /* Lrt's failure channel */ | ||
75 | u16 ltt_fail_chan; /* Ltt's failure channel */ | ||
76 | |||
77 | /* RUP structure for HOST to driver communications */ | ||
78 | struct RUP rup; | ||
79 | struct RUP link_rup; /* RUP for the link (POLL, | ||
80 | topology etc.) */ | ||
81 | u16 attached_link; /* Number of attached link */ | ||
82 | u16 csum_errors; /* csum errors */ | ||
83 | u16 num_disconnects; /* number of disconnects */ | ||
84 | u16 num_sync_rcvd; /* # sync's received */ | ||
85 | u16 num_sync_rqst; /* # sync requests */ | ||
86 | u16 num_tx; /* Num pkts sent */ | ||
87 | u16 num_rx; /* Num pkts received */ | ||
88 | u16 module_attached; /* Module tpyes of attached */ | ||
89 | u16 led_timeout; /* LED timeout */ | ||
90 | u16 first_port; /* First port to service */ | ||
91 | u16 last_port; /* Last port to service */ | ||
92 | }; | ||
93 | |||
94 | #endif | ||
95 | |||
96 | /*********** end of file ***********/ | ||
diff --git a/drivers/char/rio/linux_compat.h b/drivers/char/rio/linux_compat.h deleted file mode 100644 index 34c0d2899ef1..000000000000 --- a/drivers/char/rio/linux_compat.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* | ||
2 | * (C) 2000 R.E.Wolff@BitWizard.nl | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/interrupt.h> | ||
20 | |||
21 | |||
22 | #define DEBUG_ALL | ||
23 | |||
24 | struct ttystatics { | ||
25 | struct termios tm; | ||
26 | }; | ||
27 | |||
28 | extern int rio_debug; | ||
29 | |||
30 | #define RIO_DEBUG_INIT 0x000001 | ||
31 | #define RIO_DEBUG_BOOT 0x000002 | ||
32 | #define RIO_DEBUG_CMD 0x000004 | ||
33 | #define RIO_DEBUG_CTRL 0x000008 | ||
34 | #define RIO_DEBUG_INTR 0x000010 | ||
35 | #define RIO_DEBUG_PARAM 0x000020 | ||
36 | #define RIO_DEBUG_ROUTE 0x000040 | ||
37 | #define RIO_DEBUG_TABLE 0x000080 | ||
38 | #define RIO_DEBUG_TTY 0x000100 | ||
39 | #define RIO_DEBUG_FLOW 0x000200 | ||
40 | #define RIO_DEBUG_MODEMSIGNALS 0x000400 | ||
41 | #define RIO_DEBUG_PROBE 0x000800 | ||
42 | #define RIO_DEBUG_CLEANUP 0x001000 | ||
43 | #define RIO_DEBUG_IFLOW 0x002000 | ||
44 | #define RIO_DEBUG_PFE 0x004000 | ||
45 | #define RIO_DEBUG_REC 0x008000 | ||
46 | #define RIO_DEBUG_SPINLOCK 0x010000 | ||
47 | #define RIO_DEBUG_DELAY 0x020000 | ||
48 | #define RIO_DEBUG_MOD_COUNT 0x040000 | ||
49 | |||
50 | |||
51 | /* Copied over from riowinif.h . This is ugly. The winif file declares | ||
52 | also much other stuff which is incompatible with the headers from | ||
53 | the older driver. The older driver includes "brates.h" which shadows | ||
54 | the definitions from Linux, and is incompatible... */ | ||
55 | |||
56 | /* RxBaud and TxBaud definitions... */ | ||
57 | #define RIO_B0 0x00 /* RTS / DTR signals dropped */ | ||
58 | #define RIO_B50 0x01 /* 50 baud */ | ||
59 | #define RIO_B75 0x02 /* 75 baud */ | ||
60 | #define RIO_B110 0x03 /* 110 baud */ | ||
61 | #define RIO_B134 0x04 /* 134.5 baud */ | ||
62 | #define RIO_B150 0x05 /* 150 baud */ | ||
63 | #define RIO_B200 0x06 /* 200 baud */ | ||
64 | #define RIO_B300 0x07 /* 300 baud */ | ||
65 | #define RIO_B600 0x08 /* 600 baud */ | ||
66 | #define RIO_B1200 0x09 /* 1200 baud */ | ||
67 | #define RIO_B1800 0x0A /* 1800 baud */ | ||
68 | #define RIO_B2400 0x0B /* 2400 baud */ | ||
69 | #define RIO_B4800 0x0C /* 4800 baud */ | ||
70 | #define RIO_B9600 0x0D /* 9600 baud */ | ||
71 | #define RIO_B19200 0x0E /* 19200 baud */ | ||
72 | #define RIO_B38400 0x0F /* 38400 baud */ | ||
73 | #define RIO_B56000 0x10 /* 56000 baud */ | ||
74 | #define RIO_B57600 0x11 /* 57600 baud */ | ||
75 | #define RIO_B64000 0x12 /* 64000 baud */ | ||
76 | #define RIO_B115200 0x13 /* 115200 baud */ | ||
77 | #define RIO_B2000 0x14 /* 2000 baud */ | ||
diff --git a/drivers/char/rio/map.h b/drivers/char/rio/map.h deleted file mode 100644 index 8366978578c1..000000000000 --- a/drivers/char/rio/map.h +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : map.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:11 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)map.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_map_h__ | ||
34 | #define __rio_map_h__ | ||
35 | |||
36 | /* | ||
37 | ** mapping structure passed to and from the config.rio program to | ||
38 | ** determine the current topology of the world | ||
39 | */ | ||
40 | |||
41 | #define MAX_MAP_ENTRY 17 | ||
42 | #define TOTAL_MAP_ENTRIES (MAX_MAP_ENTRY*RIO_SLOTS) | ||
43 | #define MAX_NAME_LEN 32 | ||
44 | |||
45 | struct Map { | ||
46 | unsigned int HostUniqueNum; /* Supporting hosts unique number */ | ||
47 | unsigned int RtaUniqueNum; /* Unique number */ | ||
48 | /* | ||
49 | ** The next two IDs must be swapped on big-endian architectures | ||
50 | ** when using a v2.04 /etc/rio/config with a v3.00 driver (when | ||
51 | ** upgrading for example). | ||
52 | */ | ||
53 | unsigned short ID; /* ID used in the subnet */ | ||
54 | unsigned short ID2; /* ID of 2nd block of 8 for 16 port */ | ||
55 | unsigned long Flags; /* Booted, ID Given, Disconnected */ | ||
56 | unsigned long SysPort; /* First tty mapped to this port */ | ||
57 | struct Top Topology[LINKS_PER_UNIT]; /* ID connected to each link */ | ||
58 | char Name[MAX_NAME_LEN]; /* Cute name by which RTA is known */ | ||
59 | }; | ||
60 | |||
61 | /* | ||
62 | ** Flag values: | ||
63 | */ | ||
64 | #define RTA_BOOTED 0x00000001 | ||
65 | #define RTA_NEWBOOT 0x00000010 | ||
66 | #define MSG_DONE 0x00000020 | ||
67 | #define RTA_INTERCONNECT 0x00000040 | ||
68 | #define RTA16_SECOND_SLOT 0x00000080 | ||
69 | #define BEEN_HERE 0x00000100 | ||
70 | #define SLOT_TENTATIVE 0x40000000 | ||
71 | #define SLOT_IN_USE 0x80000000 | ||
72 | |||
73 | /* | ||
74 | ** HostUniqueNum is the unique number from the host card that this RTA | ||
75 | ** is to be connected to. | ||
76 | ** RtaUniqueNum is the unique number of the RTA concerned. It will be ZERO | ||
77 | ** if the slot in the table is unused. If it is the same as the HostUniqueNum | ||
78 | ** then this slot represents a host card. | ||
79 | ** Flags contains current boot/route state info | ||
80 | ** SysPort is a value in the range 0-504, being the number of the first tty | ||
81 | ** on this RTA. Each RTA supports 8 ports. The SysPort value must be modulo 8. | ||
82 | ** SysPort 0-127 correspond to /dev/ttyr001 to /dev/ttyr128, with minor | ||
83 | ** numbers 0-127. SysPort 128-255 correspond to /dev/ttyr129 to /dev/ttyr256, | ||
84 | ** again with minor numbers 0-127, and so on for SysPorts 256-383 and 384-511 | ||
85 | ** ID will be in the range 0-16 for a `known' RTA. ID will be 0xFFFF for an | ||
86 | ** unused slot/unknown ID etc. | ||
87 | ** The Topology array contains the ID of the unit connected to each of the | ||
88 | ** four links on this unit. The entry will be 0xFFFF if NOTHING is connected | ||
89 | ** to the link, or will be 0xFF00 if an UNKNOWN unit is connected to the link. | ||
90 | ** The Name field is a null-terminated string, upto 31 characters, containing | ||
91 | ** the 'cute' name that the sysadmin/users know the RTA by. It is permissible | ||
92 | ** for this string to contain any character in the range \040 to \176 inclusive. | ||
93 | ** In particular, ctrl sequences and DEL (0x7F, \177) are not allowed. The | ||
94 | ** special character '%' IS allowable, and needs no special action. | ||
95 | ** | ||
96 | */ | ||
97 | |||
98 | #endif | ||
diff --git a/drivers/char/rio/param.h b/drivers/char/rio/param.h deleted file mode 100644 index 7e9b6283e8aa..000000000000 --- a/drivers/char/rio/param.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : param.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:12 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)param.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_param_h__ | ||
34 | #define __rio_param_h__ | ||
35 | |||
36 | /* | ||
37 | ** the param command block, as used in OPEN and PARAM calls. | ||
38 | */ | ||
39 | |||
40 | struct phb_param { | ||
41 | u8 Cmd; /* It is very important that these line up */ | ||
42 | u8 Cor1; /* with what is expected at the other end. */ | ||
43 | u8 Cor2; /* to confirm that you've got it right, */ | ||
44 | u8 Cor4; /* check with cirrus/cirrus.h */ | ||
45 | u8 Cor5; | ||
46 | u8 TxXon; /* Transmit X-On character */ | ||
47 | u8 TxXoff; /* Transmit X-Off character */ | ||
48 | u8 RxXon; /* Receive X-On character */ | ||
49 | u8 RxXoff; /* Receive X-Off character */ | ||
50 | u8 LNext; /* Literal-next character */ | ||
51 | u8 TxBaud; /* Transmit baudrate */ | ||
52 | u8 RxBaud; /* Receive baudrate */ | ||
53 | }; | ||
54 | |||
55 | #endif | ||
diff --git a/drivers/char/rio/parmmap.h b/drivers/char/rio/parmmap.h deleted file mode 100644 index acc8fa439df5..000000000000 --- a/drivers/char/rio/parmmap.h +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* H O S T M E M O R Y M A P | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Ian Nandhra / Jeremy Rolls | ||
8 | Date : | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | 6/4/1991 jonb Made changes to accommodate Mips R3230 bus | ||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _parmap_h | ||
38 | #define _parmap_h | ||
39 | |||
40 | typedef struct PARM_MAP PARM_MAP; | ||
41 | |||
42 | struct PARM_MAP { | ||
43 | u16 phb_ptr; /* Pointer to the PHB array */ | ||
44 | u16 phb_num_ptr; /* Ptr to Number of PHB's */ | ||
45 | u16 free_list; /* Free List pointer */ | ||
46 | u16 free_list_end; /* Free List End pointer */ | ||
47 | u16 q_free_list_ptr; /* Ptr to Q_BUF variable */ | ||
48 | u16 unit_id_ptr; /* Unit Id */ | ||
49 | u16 link_str_ptr; /* Link Structure Array */ | ||
50 | u16 bootloader_1; /* 1st Stage Boot Loader */ | ||
51 | u16 bootloader_2; /* 2nd Stage Boot Loader */ | ||
52 | u16 port_route_map_ptr; /* Port Route Map */ | ||
53 | u16 route_ptr; /* Unit Route Map */ | ||
54 | u16 map_present; /* Route Map present */ | ||
55 | s16 pkt_num; /* Total number of packets */ | ||
56 | s16 q_num; /* Total number of Q packets */ | ||
57 | u16 buffers_per_port; /* Number of buffers per port */ | ||
58 | u16 heap_size; /* Initial size of heap */ | ||
59 | u16 heap_left; /* Current Heap left */ | ||
60 | u16 error; /* Error code */ | ||
61 | u16 tx_max; /* Max number of tx pkts per phb */ | ||
62 | u16 rx_max; /* Max number of rx pkts per phb */ | ||
63 | u16 rx_limit; /* For high / low watermarks */ | ||
64 | s16 links; /* Links to use */ | ||
65 | s16 timer; /* Interrupts per second */ | ||
66 | u16 rups; /* Pointer to the RUPs */ | ||
67 | u16 max_phb; /* Mostly for debugging */ | ||
68 | u16 living; /* Just increments!! */ | ||
69 | u16 init_done; /* Initialisation over */ | ||
70 | u16 booting_link; | ||
71 | u16 idle_count; /* Idle time counter */ | ||
72 | u16 busy_count; /* Busy counter */ | ||
73 | u16 idle_control; /* Control Idle Process */ | ||
74 | u16 tx_intr; /* TX interrupt pending */ | ||
75 | u16 rx_intr; /* RX interrupt pending */ | ||
76 | u16 rup_intr; /* RUP interrupt pending */ | ||
77 | }; | ||
78 | |||
79 | #endif | ||
80 | |||
81 | /*********** end of file ***********/ | ||
diff --git a/drivers/char/rio/pci.h b/drivers/char/rio/pci.h deleted file mode 100644 index 6032f9135956..000000000000 --- a/drivers/char/rio/pci.h +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : pci.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:12 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)pci.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_pci_h__ | ||
34 | #define __rio_pci_h__ | ||
35 | |||
36 | /* | ||
37 | ** PCI stuff | ||
38 | */ | ||
39 | |||
40 | #define PCITpFastClock 0x80 | ||
41 | #define PCITpSlowClock 0x00 | ||
42 | #define PCITpFastLinks 0x40 | ||
43 | #define PCITpSlowLinks 0x00 | ||
44 | #define PCITpIntEnable 0x04 | ||
45 | #define PCITpIntDisable 0x00 | ||
46 | #define PCITpBusEnable 0x02 | ||
47 | #define PCITpBusDisable 0x00 | ||
48 | #define PCITpBootFromRam 0x01 | ||
49 | #define PCITpBootFromLink 0x00 | ||
50 | |||
51 | #define RIO_PCI_VENDOR 0x11CB | ||
52 | #define RIO_PCI_DEVICE 0x8000 | ||
53 | #define RIO_PCI_BASE_CLASS 0x02 | ||
54 | #define RIO_PCI_SUB_CLASS 0x80 | ||
55 | #define RIO_PCI_PROG_IFACE 0x00 | ||
56 | |||
57 | #define RIO_PCI_RID 0x0008 | ||
58 | #define RIO_PCI_BADR0 0x0010 | ||
59 | #define RIO_PCI_INTLN 0x003C | ||
60 | #define RIO_PCI_INTPIN 0x003D | ||
61 | |||
62 | #define RIO_PCI_MEM_SIZE 65536 | ||
63 | |||
64 | #define RIO_PCI_TURBO_TP 0x80 | ||
65 | #define RIO_PCI_FAST_LINKS 0x40 | ||
66 | #define RIO_PCI_INT_ENABLE 0x04 | ||
67 | #define RIO_PCI_TP_BUS_ENABLE 0x02 | ||
68 | #define RIO_PCI_BOOT_FROM_RAM 0x01 | ||
69 | |||
70 | #define RIO_PCI_DEFAULT_MODE 0x05 | ||
71 | |||
72 | #endif /* __rio_pci_h__ */ | ||
diff --git a/drivers/char/rio/phb.h b/drivers/char/rio/phb.h deleted file mode 100644 index a4c48ae4e365..000000000000 --- a/drivers/char/rio/phb.h +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* P H B H E A D E R ******* | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Ian Nandhra, Jeremy Rolls | ||
8 | Date : | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | |||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _phb_h | ||
38 | #define _phb_h 1 | ||
39 | |||
40 | /************************************************* | ||
41 | * Handshake asserted. Deasserted by the LTT(s) | ||
42 | ************************************************/ | ||
43 | #define PHB_HANDSHAKE_SET ((ushort) 0x001) /* Set by LRT */ | ||
44 | |||
45 | #define PHB_HANDSHAKE_RESET ((ushort) 0x002) /* Set by ISR / driver */ | ||
46 | |||
47 | #define PHB_HANDSHAKE_FLAGS (PHB_HANDSHAKE_RESET | PHB_HANDSHAKE_SET) | ||
48 | /* Reset by ltt */ | ||
49 | |||
50 | |||
51 | /************************************************* | ||
52 | * Maximum number of PHB's | ||
53 | ************************************************/ | ||
54 | #define MAX_PHB ((ushort) 128) /* range 0-127 */ | ||
55 | |||
56 | /************************************************* | ||
57 | * Defines for the mode fields | ||
58 | ************************************************/ | ||
59 | #define TXPKT_INCOMPLETE 0x0001 /* Previous tx packet not completed */ | ||
60 | #define TXINTR_ENABLED 0x0002 /* Tx interrupt is enabled */ | ||
61 | #define TX_TAB3 0x0004 /* TAB3 mode */ | ||
62 | #define TX_OCRNL 0x0008 /* OCRNL mode */ | ||
63 | #define TX_ONLCR 0x0010 /* ONLCR mode */ | ||
64 | #define TX_SENDSPACES 0x0020 /* Send n spaces command needs | ||
65 | completing */ | ||
66 | #define TX_SENDNULL 0x0040 /* Escaping NULL needs completing */ | ||
67 | #define TX_SENDLF 0x0080 /* LF -> CR LF needs completing */ | ||
68 | #define TX_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel | ||
69 | port */ | ||
70 | #define TX_HANGOVER (TX_SENDSPACES | TX_SENDLF | TX_SENDNULL) | ||
71 | #define TX_DTRFLOW 0x0200 /* DTR tx flow control */ | ||
72 | #define TX_DTRFLOWED 0x0400 /* DTR is low - don't allow more data | ||
73 | into the FIFO */ | ||
74 | #define TX_DATAINFIFO 0x0800 /* There is data in the FIFO */ | ||
75 | #define TX_BUSY 0x1000 /* Data in FIFO, shift or holding regs */ | ||
76 | |||
77 | #define RX_SPARE 0x0001 /* SPARE */ | ||
78 | #define RXINTR_ENABLED 0x0002 /* Rx interrupt enabled */ | ||
79 | #define RX_ICRNL 0x0008 /* ICRNL mode */ | ||
80 | #define RX_INLCR 0x0010 /* INLCR mode */ | ||
81 | #define RX_IGNCR 0x0020 /* IGNCR mode */ | ||
82 | #define RX_CTSFLOW 0x0040 /* CTSFLOW enabled */ | ||
83 | #define RX_IXOFF 0x0080 /* IXOFF enabled */ | ||
84 | #define RX_CTSFLOWED 0x0100 /* CTSFLOW and CTS dropped */ | ||
85 | #define RX_IXOFFED 0x0200 /* IXOFF and xoff sent */ | ||
86 | #define RX_BUFFERED 0x0400 /* Try and pass on complete packets */ | ||
87 | |||
88 | #define PORT_ISOPEN 0x0001 /* Port open? */ | ||
89 | #define PORT_HUPCL 0x0002 /* Hangup on close? */ | ||
90 | #define PORT_MOPENPEND 0x0004 /* Modem open pending */ | ||
91 | #define PORT_ISPARALLEL 0x0008 /* Parallel port */ | ||
92 | #define PORT_BREAK 0x0010 /* Port on break */ | ||
93 | #define PORT_STATUSPEND 0x0020 /* Status packet pending */ | ||
94 | #define PORT_BREAKPEND 0x0040 /* Break packet pending */ | ||
95 | #define PORT_MODEMPEND 0x0080 /* Modem status packet pending */ | ||
96 | #define PORT_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel | ||
97 | port */ | ||
98 | #define PORT_FULLMODEM 0x0200 /* Full modem signals */ | ||
99 | #define PORT_RJ45 0x0400 /* RJ45 connector - no RI signal */ | ||
100 | #define PORT_RESTRICTED 0x0600 /* Restricted connector - no RI / DTR */ | ||
101 | |||
102 | #define PORT_MODEMBITS 0x0600 /* Mask for modem fields */ | ||
103 | |||
104 | #define PORT_WCLOSE 0x0800 /* Waiting for close */ | ||
105 | #define PORT_HANDSHAKEFIX 0x1000 /* Port has H/W flow control fix */ | ||
106 | #define PORT_WASPCLOSED 0x2000 /* Port closed with PCLOSE */ | ||
107 | #define DUMPMODE 0x4000 /* Dump RTA mem */ | ||
108 | #define READ_REG 0x8000 /* Read CD1400 register */ | ||
109 | |||
110 | |||
111 | |||
112 | /************************************************************************** | ||
113 | * PHB Structure | ||
114 | * A few words. | ||
115 | * | ||
116 | * Normally Packets are added to the end of the list and removed from | ||
117 | * the start. The pointer tx_add points to a SPACE to put a Packet. | ||
118 | * The pointer tx_remove points to the next Packet to remove | ||
119 | *************************************************************************/ | ||
120 | |||
121 | struct PHB { | ||
122 | u8 source; | ||
123 | u8 handshake; | ||
124 | u8 status; | ||
125 | u16 timeout; /* Maximum of 1.9 seconds */ | ||
126 | u8 link; /* Send down this link */ | ||
127 | u8 destination; | ||
128 | u16 tx_start; | ||
129 | u16 tx_end; | ||
130 | u16 tx_add; | ||
131 | u16 tx_remove; | ||
132 | |||
133 | u16 rx_start; | ||
134 | u16 rx_end; | ||
135 | u16 rx_add; | ||
136 | u16 rx_remove; | ||
137 | |||
138 | }; | ||
139 | |||
140 | #endif | ||
141 | |||
142 | /*********** end of file ***********/ | ||
diff --git a/drivers/char/rio/pkt.h b/drivers/char/rio/pkt.h deleted file mode 100644 index a9458164f02f..000000000000 --- a/drivers/char/rio/pkt.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* P A C K E T H E A D E R F I L E | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Ian Nandhra / Jeremy Rolls | ||
8 | Date : | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | |||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _pkt_h | ||
38 | #define _pkt_h 1 | ||
39 | |||
40 | #define PKT_CMD_BIT ((ushort) 0x080) | ||
41 | #define PKT_CMD_DATA ((ushort) 0x080) | ||
42 | |||
43 | #define PKT_ACK ((ushort) 0x040) | ||
44 | |||
45 | #define PKT_TGL ((ushort) 0x020) | ||
46 | |||
47 | #define PKT_LEN_MASK ((ushort) 0x07f) | ||
48 | |||
49 | #define DATA_WNDW ((ushort) 0x10) | ||
50 | #define PKT_TTL_MASK ((ushort) 0x0f) | ||
51 | |||
52 | #define PKT_MAX_DATA_LEN 72 | ||
53 | |||
54 | #define PKT_LENGTH sizeof(struct PKT) | ||
55 | #define SYNC_PKT_LENGTH (PKT_LENGTH + 4) | ||
56 | |||
57 | #define CONTROL_PKT_LEN_MASK PKT_LEN_MASK | ||
58 | #define CONTROL_PKT_CMD_BIT PKT_CMD_BIT | ||
59 | #define CONTROL_PKT_ACK (PKT_ACK << 8) | ||
60 | #define CONTROL_PKT_TGL (PKT_TGL << 8) | ||
61 | #define CONTROL_PKT_TTL_MASK (PKT_TTL_MASK << 8) | ||
62 | #define CONTROL_DATA_WNDW (DATA_WNDW << 8) | ||
63 | |||
64 | struct PKT { | ||
65 | u8 dest_unit; /* Destination Unit Id */ | ||
66 | u8 dest_port; /* Destination POrt */ | ||
67 | u8 src_unit; /* Source Unit Id */ | ||
68 | u8 src_port; /* Source POrt */ | ||
69 | u8 len; | ||
70 | u8 control; | ||
71 | u8 data[PKT_MAX_DATA_LEN]; | ||
72 | /* Actual data :-) */ | ||
73 | u16 csum; /* C-SUM */ | ||
74 | }; | ||
75 | #endif | ||
76 | |||
77 | /*********** end of file ***********/ | ||
diff --git a/drivers/char/rio/port.h b/drivers/char/rio/port.h deleted file mode 100644 index 49cf6d15ee54..000000000000 --- a/drivers/char/rio/port.h +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : port.h | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 11:34:12 | ||
26 | ** Retrieved : 11/6/98 11:34:21 | ||
27 | ** | ||
28 | ** ident @(#)port.h 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_port_h__ | ||
34 | #define __rio_port_h__ | ||
35 | |||
36 | /* | ||
37 | ** Port data structure | ||
38 | */ | ||
39 | struct Port { | ||
40 | struct gs_port gs; | ||
41 | int PortNum; /* RIO port no., 0-511 */ | ||
42 | struct Host *HostP; | ||
43 | void __iomem *Caddr; | ||
44 | unsigned short HostPort; /* Port number on host card */ | ||
45 | unsigned char RupNum; /* Number of RUP for port */ | ||
46 | unsigned char ID2; /* Second ID of RTA for port */ | ||
47 | unsigned long State; /* FLAGS for open & xopen */ | ||
48 | #define RIO_LOPEN 0x00001 /* Local open */ | ||
49 | #define RIO_MOPEN 0x00002 /* Modem open */ | ||
50 | #define RIO_WOPEN 0x00004 /* Waiting for open */ | ||
51 | #define RIO_CLOSING 0x00008 /* The port is being close */ | ||
52 | #define RIO_XPBUSY 0x00010 /* Transparent printer busy */ | ||
53 | #define RIO_BREAKING 0x00020 /* Break in progress */ | ||
54 | #define RIO_DIRECT 0x00040 /* Doing Direct output */ | ||
55 | #define RIO_EXCLUSIVE 0x00080 /* Stream open for exclusive use */ | ||
56 | #define RIO_NDELAY 0x00100 /* Stream is open FNDELAY */ | ||
57 | #define RIO_CARR_ON 0x00200 /* Stream has carrier present */ | ||
58 | #define RIO_XPWANTR 0x00400 /* Stream wanted by Xprint */ | ||
59 | #define RIO_RBLK 0x00800 /* Stream is read-blocked */ | ||
60 | #define RIO_BUSY 0x01000 /* Stream is BUSY for write */ | ||
61 | #define RIO_TIMEOUT 0x02000 /* Stream timeout in progress */ | ||
62 | #define RIO_TXSTOP 0x04000 /* Stream output is stopped */ | ||
63 | #define RIO_WAITFLUSH 0x08000 /* Stream waiting for flush */ | ||
64 | #define RIO_DYNOROD 0x10000 /* Drain failed */ | ||
65 | #define RIO_DELETED 0x20000 /* RTA has been deleted */ | ||
66 | #define RIO_ISSCANCODE 0x40000 /* This line is in scancode mode */ | ||
67 | #define RIO_USING_EUC 0x100000 /* Using extended Unix chars */ | ||
68 | #define RIO_CAN_COOK 0x200000 /* This line can do cooking */ | ||
69 | #define RIO_TRIAD_MODE 0x400000 /* Enable TRIAD special ops. */ | ||
70 | #define RIO_TRIAD_BLOCK 0x800000 /* Next read will block */ | ||
71 | #define RIO_TRIAD_FUNC 0x1000000 /* Seen a function key coming in */ | ||
72 | #define RIO_THROTTLE_RX 0x2000000 /* RX needs to be throttled. */ | ||
73 | |||
74 | unsigned long Config; /* FLAGS for NOREAD.... */ | ||
75 | #define RIO_NOREAD 0x0001 /* Are not allowed to read port */ | ||
76 | #define RIO_NOWRITE 0x0002 /* Are not allowed to write port */ | ||
77 | #define RIO_NOXPRINT 0x0004 /* Are not allowed to xprint port */ | ||
78 | #define RIO_NOMASK 0x0007 /* All not allowed things */ | ||
79 | #define RIO_IXANY 0x0008 /* Port is allowed ixany */ | ||
80 | #define RIO_MODEM 0x0010 /* Stream is a modem device */ | ||
81 | #define RIO_IXON 0x0020 /* Port is allowed ixon */ | ||
82 | #define RIO_WAITDRAIN 0x0040 /* Wait for port to completely drain */ | ||
83 | #define RIO_MAP_50_TO_50 0x0080 /* Map 50 baud to 50 baud */ | ||
84 | #define RIO_MAP_110_TO_110 0x0100 /* Map 110 baud to 110 baud */ | ||
85 | |||
86 | /* | ||
87 | ** 15.10.1998 ARG - ESIL 0761 prt fix | ||
88 | ** As LynxOS does not appear to support Hardware Flow Control ..... | ||
89 | ** Define our own flow control flags in 'Config'. | ||
90 | */ | ||
91 | #define RIO_CTSFLOW 0x0200 /* RIO's own CTSFLOW flag */ | ||
92 | #define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */ | ||
93 | |||
94 | |||
95 | struct PHB __iomem *PhbP; /* pointer to PHB for port */ | ||
96 | u16 __iomem *TxAdd; /* Add packets here */ | ||
97 | u16 __iomem *TxStart; /* Start of add array */ | ||
98 | u16 __iomem *TxEnd; /* End of add array */ | ||
99 | u16 __iomem *RxRemove; /* Remove packets here */ | ||
100 | u16 __iomem *RxStart; /* Start of remove array */ | ||
101 | u16 __iomem *RxEnd; /* End of remove array */ | ||
102 | unsigned int RtaUniqueNum; /* Unique number of RTA */ | ||
103 | unsigned short PortState; /* status of port */ | ||
104 | unsigned short ModemState; /* status of modem lines */ | ||
105 | unsigned long ModemLines; /* Modem bits sent to RTA */ | ||
106 | unsigned char CookMode; /* who expands CR/LF? */ | ||
107 | unsigned char ParamSem; /* Prevent write during param */ | ||
108 | unsigned char Mapped; /* if port mapped onto host */ | ||
109 | unsigned char SecondBlock; /* if port belongs to 2nd block | ||
110 | of 16 port RTA */ | ||
111 | unsigned char InUse; /* how many pre-emptive cmds */ | ||
112 | unsigned char Lock; /* if params locked */ | ||
113 | unsigned char Store; /* if params stored across closes */ | ||
114 | unsigned char FirstOpen; /* TRUE if first time port opened */ | ||
115 | unsigned char FlushCmdBodge; /* if doing a (non)flush */ | ||
116 | unsigned char MagicFlags; /* require intr processing */ | ||
117 | #define MAGIC_FLUSH 0x01 /* mirror of WflushFlag */ | ||
118 | #define MAGIC_REBOOT 0x02 /* RTA re-booted, re-open ports */ | ||
119 | #define MORE_OUTPUT_EYGOR 0x04 /* riotproc failed to empty clists */ | ||
120 | unsigned char WflushFlag; /* 1 How many WFLUSHs active */ | ||
121 | /* | ||
122 | ** Transparent print stuff | ||
123 | */ | ||
124 | struct Xprint { | ||
125 | #ifndef MAX_XP_CTRL_LEN | ||
126 | #define MAX_XP_CTRL_LEN 16 /* ALSO IN DAEMON.H */ | ||
127 | #endif | ||
128 | unsigned int XpCps; | ||
129 | char XpOn[MAX_XP_CTRL_LEN]; | ||
130 | char XpOff[MAX_XP_CTRL_LEN]; | ||
131 | unsigned short XpLen; /* strlen(XpOn)+strlen(XpOff) */ | ||
132 | unsigned char XpActive; | ||
133 | unsigned char XpLastTickOk; /* TRUE if we can process */ | ||
134 | #define XP_OPEN 00001 | ||
135 | #define XP_RUNABLE 00002 | ||
136 | struct ttystatics *XttyP; | ||
137 | } Xprint; | ||
138 | unsigned char RxDataStart; | ||
139 | unsigned char Cor2Copy; /* copy of COR2 */ | ||
140 | char *Name; /* points to the Rta's name */ | ||
141 | char *TxRingBuffer; | ||
142 | unsigned short TxBufferIn; /* New data arrives here */ | ||
143 | unsigned short TxBufferOut; /* Intr removes data here */ | ||
144 | unsigned short OldTxBufferOut; /* Indicates if draining */ | ||
145 | int TimeoutId; /* Timeout ID */ | ||
146 | unsigned int Debug; | ||
147 | unsigned char WaitUntilBooted; /* True if open should block */ | ||
148 | unsigned int statsGather; /* True if gathering stats */ | ||
149 | unsigned long txchars; /* Chars transmitted */ | ||
150 | unsigned long rxchars; /* Chars received */ | ||
151 | unsigned long opens; /* port open count */ | ||
152 | unsigned long closes; /* port close count */ | ||
153 | unsigned long ioctls; /* ioctl count */ | ||
154 | unsigned char LastRxTgl; /* Last state of rx toggle bit */ | ||
155 | spinlock_t portSem; /* Lock using this sem */ | ||
156 | int MonitorTstate; /* Monitoring ? */ | ||
157 | int timeout_id; /* For calling 100 ms delays */ | ||
158 | int timeout_sem; /* For calling 100 ms delays */ | ||
159 | int firstOpen; /* First time open ? */ | ||
160 | char *p; /* save the global struc here .. */ | ||
161 | }; | ||
162 | |||
163 | struct ModuleInfo { | ||
164 | char *Name; | ||
165 | unsigned int Flags[4]; /* one per port on a module */ | ||
166 | }; | ||
167 | |||
168 | /* | ||
169 | ** This struct is required because trying to grab an entire Port structure | ||
170 | ** runs into problems with differing struct sizes between driver and config. | ||
171 | */ | ||
172 | struct PortParams { | ||
173 | unsigned int Port; | ||
174 | unsigned long Config; | ||
175 | unsigned long State; | ||
176 | struct ttystatics *TtyP; | ||
177 | }; | ||
178 | |||
179 | #endif | ||
diff --git a/drivers/char/rio/protsts.h b/drivers/char/rio/protsts.h deleted file mode 100644 index 8ab79401d3ee..000000000000 --- a/drivers/char/rio/protsts.h +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* P R O T O C O L S T A T U S S T R U C T U R E ******* | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Ian Nandhra / Jeremy Rolls | ||
8 | Date : | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | |||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _protsts_h | ||
38 | #define _protsts_h 1 | ||
39 | |||
40 | /************************************************* | ||
41 | * ACK bit. Last Packet received OK. Set by | ||
42 | * rxpkt to indicate that the Packet has been | ||
43 | * received OK and that the LTT must set the ACK | ||
44 | * bit in the next outward bound Packet | ||
45 | * and re-set by LTT's after xmit. | ||
46 | * | ||
47 | * Gets shoved into rx_status | ||
48 | ************************************************/ | ||
49 | #define PHB_RX_LAST_PKT_ACKED ((ushort) 0x080) | ||
50 | |||
51 | /******************************************************* | ||
52 | * The Rx TOGGLE bit. | ||
53 | * Stuffed into rx_status by RXPKT | ||
54 | ******************************************************/ | ||
55 | #define PHB_RX_DATA_WNDW ((ushort) 0x040) | ||
56 | |||
57 | /******************************************************* | ||
58 | * The Rx TOGGLE bit. Matches the setting in PKT.H | ||
59 | * Stuffed into rx_status | ||
60 | ******************************************************/ | ||
61 | #define PHB_RX_TGL ((ushort) 0x2000) | ||
62 | |||
63 | |||
64 | /************************************************* | ||
65 | * This bit is set by the LRT to indicate that | ||
66 | * an ACK (packet) must be returned. | ||
67 | * | ||
68 | * Gets shoved into tx_status | ||
69 | ************************************************/ | ||
70 | #define PHB_TX_SEND_PKT_ACK ((ushort) 0x08) | ||
71 | |||
72 | /************************************************* | ||
73 | * Set by LTT to indicate that an ACK is required | ||
74 | *************************************************/ | ||
75 | #define PHB_TX_ACK_RQRD ((ushort) 0x01) | ||
76 | |||
77 | |||
78 | /******************************************************* | ||
79 | * The Tx TOGGLE bit. | ||
80 | * Stuffed into tx_status by RXPKT from the PKT WndW | ||
81 | * field. Looked by the LTT when the NEXT Packet | ||
82 | * is going to be sent. | ||
83 | ******************************************************/ | ||
84 | #define PHB_TX_DATA_WNDW ((ushort) 0x04) | ||
85 | |||
86 | |||
87 | /******************************************************* | ||
88 | * The Tx TOGGLE bit. Matches the setting in PKT.H | ||
89 | * Stuffed into tx_status | ||
90 | ******************************************************/ | ||
91 | #define PHB_TX_TGL ((ushort) 0x02) | ||
92 | |||
93 | /******************************************************* | ||
94 | * Request intr bit. Set when the queue has gone quiet | ||
95 | * and the PHB has requested an interrupt. | ||
96 | ******************************************************/ | ||
97 | #define PHB_TX_INTR ((ushort) 0x100) | ||
98 | |||
99 | /******************************************************* | ||
100 | * SET if the PHB cannot send any more data down the | ||
101 | * Link | ||
102 | ******************************************************/ | ||
103 | #define PHB_TX_HANDSHAKE ((ushort) 0x010) | ||
104 | |||
105 | |||
106 | #define RUP_SEND_WNDW ((ushort) 0x08) ; | ||
107 | |||
108 | #endif | ||
109 | |||
110 | /*********** end of file ***********/ | ||
diff --git a/drivers/char/rio/rio.h b/drivers/char/rio/rio.h deleted file mode 100644 index 1bf36223a4e8..000000000000 --- a/drivers/char/rio/rio.h +++ /dev/null | |||
@@ -1,208 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 1998 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rio.h | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 11:34:13 | ||
26 | ** Retrieved : 11/6/98 11:34:22 | ||
27 | ** | ||
28 | ** ident @(#)rio.h 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_rio_h__ | ||
34 | #define __rio_rio_h__ | ||
35 | |||
36 | /* | ||
37 | ** Maximum numbers of things | ||
38 | */ | ||
39 | #define RIO_SLOTS 4 /* number of configuration slots */ | ||
40 | #define RIO_HOSTS 4 /* number of hosts that can be found */ | ||
41 | #define PORTS_PER_HOST 128 /* number of ports per host */ | ||
42 | #define LINKS_PER_UNIT 4 /* number of links from a host */ | ||
43 | #define RIO_PORTS (PORTS_PER_HOST * RIO_HOSTS) /* max. no. of ports */ | ||
44 | #define RTAS_PER_HOST (MAX_RUP) /* number of RTAs per host */ | ||
45 | #define PORTS_PER_RTA (PORTS_PER_HOST/RTAS_PER_HOST) /* ports on a rta */ | ||
46 | #define PORTS_PER_MODULE 4 /* number of ports on a plug-in module */ | ||
47 | /* number of modules on an RTA */ | ||
48 | #define MODULES_PER_RTA (PORTS_PER_RTA/PORTS_PER_MODULE) | ||
49 | #define MAX_PRODUCT 16 /* numbr of different product codes */ | ||
50 | #define MAX_MODULE_TYPES 16 /* number of different types of module */ | ||
51 | |||
52 | #define RIO_CONTROL_DEV 128 /* minor number of host/control device */ | ||
53 | #define RIO_INVALID_MAJOR 0 /* test first host card's major no for validity */ | ||
54 | |||
55 | /* | ||
56 | ** number of RTAs that can be bound to a master | ||
57 | */ | ||
58 | #define MAX_RTA_BINDINGS (MAX_RUP * RIO_HOSTS) | ||
59 | |||
60 | /* | ||
61 | ** Unit types | ||
62 | */ | ||
63 | #define PC_RTA16 0x90000000 | ||
64 | #define PC_RTA8 0xe0000000 | ||
65 | #define TYPE_HOST 0 | ||
66 | #define TYPE_RTA8 1 | ||
67 | #define TYPE_RTA16 2 | ||
68 | |||
69 | /* | ||
70 | ** Flag values returned by functions | ||
71 | */ | ||
72 | |||
73 | #define RIO_FAIL -1 | ||
74 | |||
75 | /* | ||
76 | ** SysPort value for something that hasn't any ports | ||
77 | */ | ||
78 | #define NO_PORT 0xFFFFFFFF | ||
79 | |||
80 | /* | ||
81 | ** Unit ID Of all hosts | ||
82 | */ | ||
83 | #define HOST_ID 0 | ||
84 | |||
85 | /* | ||
86 | ** Break bytes into nybles | ||
87 | */ | ||
88 | #define LONYBLE(X) ((X) & 0xF) | ||
89 | #define HINYBLE(X) (((X)>>4) & 0xF) | ||
90 | |||
91 | /* | ||
92 | ** Flag values passed into some functions | ||
93 | */ | ||
94 | #define DONT_SLEEP 0 | ||
95 | #define OK_TO_SLEEP 1 | ||
96 | |||
97 | #define DONT_PRINT 1 | ||
98 | #define DO_PRINT 0 | ||
99 | |||
100 | #define PRINT_TO_LOG_CONS 0 | ||
101 | #define PRINT_TO_CONS 1 | ||
102 | #define PRINT_TO_LOG 2 | ||
103 | |||
104 | /* | ||
105 | ** Timeout has trouble with times of less than 3 ticks... | ||
106 | */ | ||
107 | #define MIN_TIMEOUT 3 | ||
108 | |||
109 | /* | ||
110 | ** Generally useful constants | ||
111 | */ | ||
112 | |||
113 | #define HUNDRED_MS ((HZ/10)?(HZ/10):1) | ||
114 | #define ONE_MEG 0x100000 | ||
115 | #define SIXTY_FOUR_K 0x10000 | ||
116 | |||
117 | #define RIO_AT_MEM_SIZE SIXTY_FOUR_K | ||
118 | #define RIO_EISA_MEM_SIZE SIXTY_FOUR_K | ||
119 | #define RIO_MCA_MEM_SIZE SIXTY_FOUR_K | ||
120 | |||
121 | #define COOK_WELL 0 | ||
122 | #define COOK_MEDIUM 1 | ||
123 | #define COOK_RAW 2 | ||
124 | |||
125 | /* | ||
126 | ** Pointer manipulation stuff | ||
127 | ** RIO_PTR takes hostp->Caddr and the offset into the DP RAM area | ||
128 | ** and produces a UNIX caddr_t (pointer) to the object | ||
129 | ** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and | ||
130 | ** returns the offset into the DP RAM area. | ||
131 | */ | ||
132 | #define RIO_PTR(C,O) (((unsigned char __iomem *)(C))+(0xFFFF&(O))) | ||
133 | #define RIO_OFF(C,O) ((unsigned char __iomem *)(O)-(unsigned char __iomem *)(C)) | ||
134 | |||
135 | /* | ||
136 | ** How to convert from various different device number formats: | ||
137 | ** DEV is a dev number, as passed to open, close etc - NOT a minor | ||
138 | ** number! | ||
139 | **/ | ||
140 | |||
141 | #define RIO_MODEM_MASK 0x1FF | ||
142 | #define RIO_MODEM_BIT 0x200 | ||
143 | #define RIO_UNMODEM(DEV) (MINOR(DEV) & RIO_MODEM_MASK) | ||
144 | #define RIO_ISMODEM(DEV) (MINOR(DEV) & RIO_MODEM_BIT) | ||
145 | #define RIO_PORT(DEV,FIRST_MAJ) ( (MAJOR(DEV) - FIRST_MAJ) * PORTS_PER_HOST) \ | ||
146 | + MINOR(DEV) | ||
147 | #define CSUM(pkt_ptr) (((u16 *)(pkt_ptr))[0] + ((u16 *)(pkt_ptr))[1] + \ | ||
148 | ((u16 *)(pkt_ptr))[2] + ((u16 *)(pkt_ptr))[3] + \ | ||
149 | ((u16 *)(pkt_ptr))[4] + ((u16 *)(pkt_ptr))[5] + \ | ||
150 | ((u16 *)(pkt_ptr))[6] + ((u16 *)(pkt_ptr))[7] + \ | ||
151 | ((u16 *)(pkt_ptr))[8] + ((u16 *)(pkt_ptr))[9] ) | ||
152 | |||
153 | #define RIO_LINK_ENABLE 0x80FF /* FF is a hack, mainly for Mips, to */ | ||
154 | /* prevent a really stupid race condition. */ | ||
155 | |||
156 | #define NOT_INITIALISED 0 | ||
157 | #define INITIALISED 1 | ||
158 | |||
159 | #define NOT_POLLING 0 | ||
160 | #define POLLING 1 | ||
161 | |||
162 | #define NOT_CHANGED 0 | ||
163 | #define CHANGED 1 | ||
164 | |||
165 | #define NOT_INUSE 0 | ||
166 | |||
167 | #define DISCONNECT 0 | ||
168 | #define CONNECT 1 | ||
169 | |||
170 | /* ------ Control Codes ------ */ | ||
171 | |||
172 | #define CONTROL '^' | ||
173 | #define IFOAD ( CONTROL + 1 ) | ||
174 | #define IDENTIFY ( CONTROL + 2 ) | ||
175 | #define ZOMBIE ( CONTROL + 3 ) | ||
176 | #define UFOAD ( CONTROL + 4 ) | ||
177 | #define IWAIT ( CONTROL + 5 ) | ||
178 | |||
179 | #define IFOAD_MAGIC 0xF0AD /* of course */ | ||
180 | #define ZOMBIE_MAGIC (~0xDEAD) /* not dead -> zombie */ | ||
181 | #define UFOAD_MAGIC 0xD1E /* kill-your-neighbour */ | ||
182 | #define IWAIT_MAGIC 0xB1DE /* Bide your time */ | ||
183 | |||
184 | /* ------ Error Codes ------ */ | ||
185 | |||
186 | #define E_NO_ERROR ((ushort) 0) | ||
187 | |||
188 | /* ------ Free Lists ------ */ | ||
189 | |||
190 | struct rio_free_list { | ||
191 | u16 next; | ||
192 | u16 prev; | ||
193 | }; | ||
194 | |||
195 | /* NULL for card side linked lists */ | ||
196 | #define TPNULL ((ushort)(0x8000)) | ||
197 | /* We can add another packet to a transmit queue if the packet pointer pointed | ||
198 | * to by the TxAdd pointer has PKT_IN_USE clear in its address. */ | ||
199 | #define PKT_IN_USE 0x1 | ||
200 | |||
201 | /* ------ Topology ------ */ | ||
202 | |||
203 | struct Top { | ||
204 | u8 Unit; | ||
205 | u8 Link; | ||
206 | }; | ||
207 | |||
208 | #endif /* __rio_h__ */ | ||
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c deleted file mode 100644 index 5e33293d24e3..000000000000 --- a/drivers/char/rio/rio_linux.c +++ /dev/null | |||
@@ -1,1204 +0,0 @@ | |||
1 | |||
2 | /* rio_linux.c -- Linux driver for the Specialix RIO series cards. | ||
3 | * | ||
4 | * | ||
5 | * (C) 1999 R.E.Wolff@BitWizard.nl | ||
6 | * | ||
7 | * Specialix pays for the development and support of this driver. | ||
8 | * Please DO contact support@specialix.co.uk if you require | ||
9 | * support. But please read the documentation (rio.txt) first. | ||
10 | * | ||
11 | * | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License as | ||
15 | * published by the Free Software Foundation; either version 2 of | ||
16 | * the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be | ||
19 | * useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
21 | * PURPOSE. See the GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public | ||
24 | * License along with this program; if not, write to the Free | ||
25 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, | ||
26 | * USA. | ||
27 | * | ||
28 | * */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/kdev_t.h> | ||
32 | #include <asm/io.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/sched.h> | ||
35 | #include <linux/ioport.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/errno.h> | ||
38 | #include <linux/tty.h> | ||
39 | #include <linux/tty_flip.h> | ||
40 | #include <linux/mm.h> | ||
41 | #include <linux/serial.h> | ||
42 | #include <linux/fcntl.h> | ||
43 | #include <linux/major.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/mutex.h> | ||
48 | #include <linux/miscdevice.h> | ||
49 | #include <linux/init.h> | ||
50 | |||
51 | #include <linux/generic_serial.h> | ||
52 | #include <asm/uaccess.h> | ||
53 | |||
54 | #include "linux_compat.h" | ||
55 | #include "pkt.h" | ||
56 | #include "daemon.h" | ||
57 | #include "rio.h" | ||
58 | #include "riospace.h" | ||
59 | #include "cmdpkt.h" | ||
60 | #include "map.h" | ||
61 | #include "rup.h" | ||
62 | #include "port.h" | ||
63 | #include "riodrvr.h" | ||
64 | #include "rioinfo.h" | ||
65 | #include "func.h" | ||
66 | #include "errors.h" | ||
67 | #include "pci.h" | ||
68 | |||
69 | #include "parmmap.h" | ||
70 | #include "unixrup.h" | ||
71 | #include "board.h" | ||
72 | #include "host.h" | ||
73 | #include "phb.h" | ||
74 | #include "link.h" | ||
75 | #include "cmdblk.h" | ||
76 | #include "route.h" | ||
77 | #include "cirrus.h" | ||
78 | #include "rioioctl.h" | ||
79 | #include "param.h" | ||
80 | #include "protsts.h" | ||
81 | #include "rioboard.h" | ||
82 | |||
83 | |||
84 | #include "rio_linux.h" | ||
85 | |||
86 | /* I don't think that this driver can handle more than 512 ports on | ||
87 | one machine. Specialix specifies max 4 boards in one machine. I don't | ||
88 | know why. If you want to try anyway you'll have to increase the number | ||
89 | of boards in rio.h. You'll have to allocate more majors if you need | ||
90 | more than 512 ports.... */ | ||
91 | |||
92 | #ifndef RIO_NORMAL_MAJOR0 | ||
93 | /* This allows overriding on the compiler commandline, or in a "major.h" | ||
94 | include or something like that */ | ||
95 | #define RIO_NORMAL_MAJOR0 154 | ||
96 | #define RIO_NORMAL_MAJOR1 156 | ||
97 | #endif | ||
98 | |||
99 | #ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 | ||
100 | #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 | ||
101 | #endif | ||
102 | |||
103 | #ifndef RIO_WINDOW_LEN | ||
104 | #define RIO_WINDOW_LEN 0x10000 | ||
105 | #endif | ||
106 | |||
107 | |||
108 | /* Configurable options: | ||
109 | (Don't be too sure that it'll work if you toggle them) */ | ||
110 | |||
111 | /* Am I paranoid or not ? ;-) */ | ||
112 | #undef RIO_PARANOIA_CHECK | ||
113 | |||
114 | |||
115 | /* 20 -> 2000 per second. The card should rate-limit interrupts at 1000 | ||
116 | Hz, but it is user configurable. I don't recommend going above 1000 | ||
117 | Hz. The interrupt ratelimit might trigger if the interrupt is | ||
118 | shared with a very active other device. | ||
119 | undef this if you want to disable the check.... | ||
120 | */ | ||
121 | #define IRQ_RATE_LIMIT 200 | ||
122 | |||
123 | |||
124 | /* These constants are derived from SCO Source */ | ||
125 | static DEFINE_MUTEX(rio_fw_mutex); | ||
126 | static struct Conf | ||
127 | RIOConf = { | ||
128 | /* locator */ "RIO Config here", | ||
129 | /* startuptime */ HZ * 2, | ||
130 | /* how long to wait for card to run */ | ||
131 | /* slowcook */ 0, | ||
132 | /* TRUE -> always use line disc. */ | ||
133 | /* intrpolltime */ 1, | ||
134 | /* The frequency of OUR polls */ | ||
135 | /* breakinterval */ 25, | ||
136 | /* x10 mS XXX: units seem to be 1ms not 10! -- REW */ | ||
137 | /* timer */ 10, | ||
138 | /* mS */ | ||
139 | /* RtaLoadBase */ 0x7000, | ||
140 | /* HostLoadBase */ 0x7C00, | ||
141 | /* XpHz */ 5, | ||
142 | /* number of Xprint hits per second */ | ||
143 | /* XpCps */ 120, | ||
144 | /* Xprint characters per second */ | ||
145 | /* XpOn */ "\033d#", | ||
146 | /* start Xprint for a wyse 60 */ | ||
147 | /* XpOff */ "\024", | ||
148 | /* end Xprint for a wyse 60 */ | ||
149 | /* MaxXpCps */ 2000, | ||
150 | /* highest Xprint speed */ | ||
151 | /* MinXpCps */ 10, | ||
152 | /* slowest Xprint speed */ | ||
153 | /* SpinCmds */ 1, | ||
154 | /* non-zero for mega fast boots */ | ||
155 | /* First Addr */ 0x0A0000, | ||
156 | /* First address to look at */ | ||
157 | /* Last Addr */ 0xFF0000, | ||
158 | /* Last address looked at */ | ||
159 | /* BufferSize */ 1024, | ||
160 | /* Bytes per port of buffering */ | ||
161 | /* LowWater */ 256, | ||
162 | /* how much data left before wakeup */ | ||
163 | /* LineLength */ 80, | ||
164 | /* how wide is the console? */ | ||
165 | /* CmdTimeout */ HZ, | ||
166 | /* how long a close command may take */ | ||
167 | }; | ||
168 | |||
169 | |||
170 | |||
171 | |||
172 | /* Function prototypes */ | ||
173 | |||
174 | static void rio_disable_tx_interrupts(void *ptr); | ||
175 | static void rio_enable_tx_interrupts(void *ptr); | ||
176 | static void rio_disable_rx_interrupts(void *ptr); | ||
177 | static void rio_enable_rx_interrupts(void *ptr); | ||
178 | static int rio_carrier_raised(struct tty_port *port); | ||
179 | static void rio_shutdown_port(void *ptr); | ||
180 | static int rio_set_real_termios(void *ptr); | ||
181 | static void rio_hungup(void *ptr); | ||
182 | static void rio_close(void *ptr); | ||
183 | static int rio_chars_in_buffer(void *ptr); | ||
184 | static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); | ||
185 | static int rio_init_drivers(void); | ||
186 | |||
187 | static void my_hd(void *addr, int len); | ||
188 | |||
189 | static struct tty_driver *rio_driver, *rio_driver2; | ||
190 | |||
191 | /* The name "p" is a bit non-descript. But that's what the rio-lynxos | ||
192 | sources use all over the place. */ | ||
193 | struct rio_info *p; | ||
194 | |||
195 | int rio_debug; | ||
196 | |||
197 | |||
198 | /* You can have the driver poll your card. | ||
199 | - Set rio_poll to 1 to poll every timer tick (10ms on Intel). | ||
200 | This is used when the card cannot use an interrupt for some reason. | ||
201 | */ | ||
202 | static int rio_poll = 1; | ||
203 | |||
204 | |||
205 | /* These are the only open spaces in my computer. Yours may have more | ||
206 | or less.... */ | ||
207 | static int rio_probe_addrs[] = { 0xc0000, 0xd0000, 0xe0000 }; | ||
208 | |||
209 | #define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs) | ||
210 | |||
211 | |||
212 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. | ||
213 | Some architectures may need more. -- Changed to LONG to | ||
214 | support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ | ||
215 | static long rio_irqmask = -1; | ||
216 | |||
217 | MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>"); | ||
218 | MODULE_DESCRIPTION("RIO driver"); | ||
219 | MODULE_LICENSE("GPL"); | ||
220 | module_param(rio_poll, int, 0); | ||
221 | module_param(rio_debug, int, 0644); | ||
222 | module_param(rio_irqmask, long, 0); | ||
223 | |||
224 | static struct real_driver rio_real_driver = { | ||
225 | rio_disable_tx_interrupts, | ||
226 | rio_enable_tx_interrupts, | ||
227 | rio_disable_rx_interrupts, | ||
228 | rio_enable_rx_interrupts, | ||
229 | rio_shutdown_port, | ||
230 | rio_set_real_termios, | ||
231 | rio_chars_in_buffer, | ||
232 | rio_close, | ||
233 | rio_hungup, | ||
234 | NULL | ||
235 | }; | ||
236 | |||
237 | /* | ||
238 | * Firmware loader driver specific routines | ||
239 | * | ||
240 | */ | ||
241 | |||
242 | static const struct file_operations rio_fw_fops = { | ||
243 | .owner = THIS_MODULE, | ||
244 | .unlocked_ioctl = rio_fw_ioctl, | ||
245 | .llseek = noop_llseek, | ||
246 | }; | ||
247 | |||
248 | static struct miscdevice rio_fw_device = { | ||
249 | RIOCTL_MISC_MINOR, "rioctl", &rio_fw_fops | ||
250 | }; | ||
251 | |||
252 | |||
253 | |||
254 | |||
255 | |||
256 | #ifdef RIO_PARANOIA_CHECK | ||
257 | |||
258 | /* This doesn't work. Who's paranoid around here? Not me! */ | ||
259 | |||
260 | static inline int rio_paranoia_check(struct rio_port const *port, char *name, const char *routine) | ||
261 | { | ||
262 | |||
263 | static const char *badmagic = KERN_ERR "rio: Warning: bad rio port magic number for device %s in %s\n"; | ||
264 | static const char *badinfo = KERN_ERR "rio: Warning: null rio port for device %s in %s\n"; | ||
265 | |||
266 | if (!port) { | ||
267 | printk(badinfo, name, routine); | ||
268 | return 1; | ||
269 | } | ||
270 | if (port->magic != RIO_MAGIC) { | ||
271 | printk(badmagic, name, routine); | ||
272 | return 1; | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | #else | ||
278 | #define rio_paranoia_check(a,b,c) 0 | ||
279 | #endif | ||
280 | |||
281 | |||
282 | #ifdef DEBUG | ||
283 | static void my_hd(void *ad, int len) | ||
284 | { | ||
285 | int i, j, ch; | ||
286 | unsigned char *addr = ad; | ||
287 | |||
288 | for (i = 0; i < len; i += 16) { | ||
289 | rio_dprintk(RIO_DEBUG_PARAM, "%08lx ", (unsigned long) addr + i); | ||
290 | for (j = 0; j < 16; j++) { | ||
291 | rio_dprintk(RIO_DEBUG_PARAM, "%02x %s", addr[j + i], (j == 7) ? " " : ""); | ||
292 | } | ||
293 | for (j = 0; j < 16; j++) { | ||
294 | ch = addr[j + i]; | ||
295 | rio_dprintk(RIO_DEBUG_PARAM, "%c", (ch < 0x20) ? '.' : ((ch > 0x7f) ? '.' : ch)); | ||
296 | } | ||
297 | rio_dprintk(RIO_DEBUG_PARAM, "\n"); | ||
298 | } | ||
299 | } | ||
300 | #else | ||
301 | #define my_hd(ad,len) do{/* nothing*/ } while (0) | ||
302 | #endif | ||
303 | |||
304 | |||
305 | /* Delay a number of jiffies, allowing a signal to interrupt */ | ||
306 | int RIODelay(struct Port *PortP, int njiffies) | ||
307 | { | ||
308 | func_enter(); | ||
309 | |||
310 | rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies\n", njiffies); | ||
311 | msleep_interruptible(jiffies_to_msecs(njiffies)); | ||
312 | func_exit(); | ||
313 | |||
314 | if (signal_pending(current)) | ||
315 | return RIO_FAIL; | ||
316 | else | ||
317 | return !RIO_FAIL; | ||
318 | } | ||
319 | |||
320 | |||
321 | /* Delay a number of jiffies, disallowing a signal to interrupt */ | ||
322 | int RIODelay_ni(struct Port *PortP, int njiffies) | ||
323 | { | ||
324 | func_enter(); | ||
325 | |||
326 | rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies (ni)\n", njiffies); | ||
327 | msleep(jiffies_to_msecs(njiffies)); | ||
328 | func_exit(); | ||
329 | return !RIO_FAIL; | ||
330 | } | ||
331 | |||
332 | void rio_copy_to_card(void *from, void __iomem *to, int len) | ||
333 | { | ||
334 | rio_copy_toio(to, from, len); | ||
335 | } | ||
336 | |||
337 | int rio_minor(struct tty_struct *tty) | ||
338 | { | ||
339 | return tty->index + ((tty->driver == rio_driver) ? 0 : 256); | ||
340 | } | ||
341 | |||
342 | static int rio_set_real_termios(void *ptr) | ||
343 | { | ||
344 | return RIOParam((struct Port *) ptr, RIOC_CONFIG, 1, 1); | ||
345 | } | ||
346 | |||
347 | |||
348 | static void rio_reset_interrupt(struct Host *HostP) | ||
349 | { | ||
350 | func_enter(); | ||
351 | |||
352 | switch (HostP->Type) { | ||
353 | case RIO_AT: | ||
354 | case RIO_MCA: | ||
355 | case RIO_PCI: | ||
356 | writeb(0xFF, &HostP->ResetInt); | ||
357 | } | ||
358 | |||
359 | func_exit(); | ||
360 | } | ||
361 | |||
362 | |||
363 | static irqreturn_t rio_interrupt(int irq, void *ptr) | ||
364 | { | ||
365 | struct Host *HostP; | ||
366 | func_enter(); | ||
367 | |||
368 | HostP = ptr; /* &p->RIOHosts[(long)ptr]; */ | ||
369 | rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); | ||
370 | |||
371 | /* AAargh! The order in which to do these things is essential and | ||
372 | not trivial. | ||
373 | |||
374 | - hardware twiddling goes before "recursive". Otherwise when we | ||
375 | poll the card, and a recursive interrupt happens, we won't | ||
376 | ack the card, so it might keep on interrupting us. (especially | ||
377 | level sensitive interrupt systems like PCI). | ||
378 | |||
379 | - Rate limit goes before hardware twiddling. Otherwise we won't | ||
380 | catch a card that has gone bonkers. | ||
381 | |||
382 | - The "initialized" test goes after the hardware twiddling. Otherwise | ||
383 | the card will stick us in the interrupt routine again. | ||
384 | |||
385 | - The initialized test goes before recursive. | ||
386 | */ | ||
387 | |||
388 | rio_dprintk(RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); | ||
389 | if (HostP->Ivec == irq) { | ||
390 | /* Tell the card we've noticed the interrupt. */ | ||
391 | rio_reset_interrupt(HostP); | ||
392 | } | ||
393 | |||
394 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) | ||
395 | return IRQ_HANDLED; | ||
396 | |||
397 | if (test_and_set_bit(RIO_BOARD_INTR_LOCK, &HostP->locks)) { | ||
398 | printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n", ptr, HostP->Ivec); | ||
399 | return IRQ_HANDLED; | ||
400 | } | ||
401 | |||
402 | RIOServiceHost(p, HostP); | ||
403 | |||
404 | rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type); | ||
405 | |||
406 | clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks); | ||
407 | rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec); | ||
408 | func_exit(); | ||
409 | return IRQ_HANDLED; | ||
410 | } | ||
411 | |||
412 | |||
413 | static void rio_pollfunc(unsigned long data) | ||
414 | { | ||
415 | func_enter(); | ||
416 | |||
417 | rio_interrupt(0, &p->RIOHosts[data]); | ||
418 | mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll); | ||
419 | |||
420 | func_exit(); | ||
421 | } | ||
422 | |||
423 | |||
424 | /* ********************************************************************** * | ||
425 | * Here are the routines that actually * | ||
426 | * interface with the generic_serial driver * | ||
427 | * ********************************************************************** */ | ||
428 | |||
429 | /* Ehhm. I don't know how to fiddle with interrupts on the Specialix | ||
430 | cards. .... Hmm. Ok I figured it out. You don't. -- REW */ | ||
431 | |||
432 | static void rio_disable_tx_interrupts(void *ptr) | ||
433 | { | ||
434 | func_enter(); | ||
435 | |||
436 | /* port->gs.port.flags &= ~GS_TX_INTEN; */ | ||
437 | |||
438 | func_exit(); | ||
439 | } | ||
440 | |||
441 | |||
442 | static void rio_enable_tx_interrupts(void *ptr) | ||
443 | { | ||
444 | struct Port *PortP = ptr; | ||
445 | /* int hn; */ | ||
446 | |||
447 | func_enter(); | ||
448 | |||
449 | /* hn = PortP->HostP - p->RIOHosts; | ||
450 | |||
451 | rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn); | ||
452 | rio_interrupt (-1,(void *) hn, NULL); */ | ||
453 | |||
454 | RIOTxEnable((char *) PortP); | ||
455 | |||
456 | /* | ||
457 | * In general we cannot count on "tx empty" interrupts, although | ||
458 | * the interrupt routine seems to be able to tell the difference. | ||
459 | */ | ||
460 | PortP->gs.port.flags &= ~GS_TX_INTEN; | ||
461 | |||
462 | func_exit(); | ||
463 | } | ||
464 | |||
465 | |||
466 | static void rio_disable_rx_interrupts(void *ptr) | ||
467 | { | ||
468 | func_enter(); | ||
469 | func_exit(); | ||
470 | } | ||
471 | |||
472 | static void rio_enable_rx_interrupts(void *ptr) | ||
473 | { | ||
474 | /* struct rio_port *port = ptr; */ | ||
475 | func_enter(); | ||
476 | func_exit(); | ||
477 | } | ||
478 | |||
479 | |||
480 | /* Jeez. Isn't this simple? */ | ||
481 | static int rio_carrier_raised(struct tty_port *port) | ||
482 | { | ||
483 | struct Port *PortP = container_of(port, struct Port, gs.port); | ||
484 | int rv; | ||
485 | |||
486 | func_enter(); | ||
487 | rv = (PortP->ModemState & RIOC_MSVR1_CD) != 0; | ||
488 | |||
489 | rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); | ||
490 | |||
491 | func_exit(); | ||
492 | return rv; | ||
493 | } | ||
494 | |||
495 | |||
496 | /* Jeez. Isn't this simple? Actually, we can sync with the actual port | ||
497 | by just pushing stuff into the queue going to the port... */ | ||
498 | static int rio_chars_in_buffer(void *ptr) | ||
499 | { | ||
500 | func_enter(); | ||
501 | |||
502 | func_exit(); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | |||
507 | /* Nothing special here... */ | ||
508 | static void rio_shutdown_port(void *ptr) | ||
509 | { | ||
510 | struct Port *PortP; | ||
511 | |||
512 | func_enter(); | ||
513 | |||
514 | PortP = (struct Port *) ptr; | ||
515 | PortP->gs.port.tty = NULL; | ||
516 | func_exit(); | ||
517 | } | ||
518 | |||
519 | |||
520 | /* I haven't the foggiest why the decrement use count has to happen | ||
521 | here. The whole linux serial drivers stuff needs to be redesigned. | ||
522 | My guess is that this is a hack to minimize the impact of a bug | ||
523 | elsewhere. Thinking about it some more. (try it sometime) Try | ||
524 | running minicom on a serial port that is driven by a modularized | ||
525 | driver. Have the modem hangup. Then remove the driver module. Then | ||
526 | exit minicom. I expect an "oops". -- REW */ | ||
527 | static void rio_hungup(void *ptr) | ||
528 | { | ||
529 | struct Port *PortP; | ||
530 | |||
531 | func_enter(); | ||
532 | |||
533 | PortP = (struct Port *) ptr; | ||
534 | PortP->gs.port.tty = NULL; | ||
535 | |||
536 | func_exit(); | ||
537 | } | ||
538 | |||
539 | |||
540 | /* The standard serial_close would become shorter if you'd wrap it like | ||
541 | this. | ||
542 | rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;} | ||
543 | */ | ||
544 | static void rio_close(void *ptr) | ||
545 | { | ||
546 | struct Port *PortP; | ||
547 | |||
548 | func_enter(); | ||
549 | |||
550 | PortP = (struct Port *) ptr; | ||
551 | |||
552 | riotclose(ptr); | ||
553 | |||
554 | if (PortP->gs.port.count) { | ||
555 | printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.port.count); | ||
556 | PortP->gs.port.count = 0; | ||
557 | } | ||
558 | |||
559 | PortP->gs.port.tty = NULL; | ||
560 | func_exit(); | ||
561 | } | ||
562 | |||
563 | |||
564 | |||
565 | static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
566 | { | ||
567 | int rc = 0; | ||
568 | func_enter(); | ||
569 | |||
570 | /* The "dev" argument isn't used. */ | ||
571 | mutex_lock(&rio_fw_mutex); | ||
572 | rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN)); | ||
573 | mutex_unlock(&rio_fw_mutex); | ||
574 | |||
575 | func_exit(); | ||
576 | return rc; | ||
577 | } | ||
578 | |||
579 | extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); | ||
580 | |||
581 | static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg) | ||
582 | { | ||
583 | void __user *argp = (void __user *)arg; | ||
584 | int rc; | ||
585 | struct Port *PortP; | ||
586 | int ival; | ||
587 | |||
588 | func_enter(); | ||
589 | |||
590 | PortP = (struct Port *) tty->driver_data; | ||
591 | |||
592 | rc = 0; | ||
593 | switch (cmd) { | ||
594 | case TIOCSSOFTCAR: | ||
595 | if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) { | ||
596 | tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0); | ||
597 | } | ||
598 | break; | ||
599 | case TIOCGSERIAL: | ||
600 | rc = -EFAULT; | ||
601 | if (access_ok(VERIFY_WRITE, argp, sizeof(struct serial_struct))) | ||
602 | rc = gs_getserial(&PortP->gs, argp); | ||
603 | break; | ||
604 | case TCSBRK: | ||
605 | if (PortP->State & RIO_DELETED) { | ||
606 | rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); | ||
607 | rc = -EIO; | ||
608 | } else { | ||
609 | if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, 250) == | ||
610 | RIO_FAIL) { | ||
611 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | ||
612 | rc = -EIO; | ||
613 | } | ||
614 | } | ||
615 | break; | ||
616 | case TCSBRKP: | ||
617 | if (PortP->State & RIO_DELETED) { | ||
618 | rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); | ||
619 | rc = -EIO; | ||
620 | } else { | ||
621 | int l; | ||
622 | l = arg ? arg * 100 : 250; | ||
623 | if (l > 255) | ||
624 | l = 255; | ||
625 | if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, | ||
626 | arg ? arg * 100 : 250) == RIO_FAIL) { | ||
627 | rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); | ||
628 | rc = -EIO; | ||
629 | } | ||
630 | } | ||
631 | break; | ||
632 | case TIOCSSERIAL: | ||
633 | rc = -EFAULT; | ||
634 | if (access_ok(VERIFY_READ, argp, sizeof(struct serial_struct))) | ||
635 | rc = gs_setserial(&PortP->gs, argp); | ||
636 | break; | ||
637 | default: | ||
638 | rc = -ENOIOCTLCMD; | ||
639 | break; | ||
640 | } | ||
641 | func_exit(); | ||
642 | return rc; | ||
643 | } | ||
644 | |||
645 | |||
646 | /* The throttle/unthrottle scheme for the Specialix card is different | ||
647 | * from other drivers and deserves some explanation. | ||
648 | * The Specialix hardware takes care of XON/XOFF | ||
649 | * and CTS/RTS flow control itself. This means that all we have to | ||
650 | * do when signalled by the upper tty layer to throttle/unthrottle is | ||
651 | * to make a note of it here. When we come to read characters from the | ||
652 | * rx buffers on the card (rio_receive_chars()) we look to see if the | ||
653 | * upper layer can accept more (as noted here in rio_rx_throt[]). | ||
654 | * If it can't we simply don't remove chars from the cards buffer. | ||
655 | * When the tty layer can accept chars, we again note that here and when | ||
656 | * rio_receive_chars() is called it will remove them from the cards buffer. | ||
657 | * The card will notice that a ports buffer has drained below some low | ||
658 | * water mark and will unflow control the line itself, using whatever | ||
659 | * flow control scheme is in use for that port. -- Simon Allen | ||
660 | */ | ||
661 | |||
662 | static void rio_throttle(struct tty_struct *tty) | ||
663 | { | ||
664 | struct Port *port = (struct Port *) tty->driver_data; | ||
665 | |||
666 | func_enter(); | ||
667 | /* If the port is using any type of input flow | ||
668 | * control then throttle the port. | ||
669 | */ | ||
670 | |||
671 | if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { | ||
672 | port->State |= RIO_THROTTLE_RX; | ||
673 | } | ||
674 | |||
675 | func_exit(); | ||
676 | } | ||
677 | |||
678 | |||
679 | static void rio_unthrottle(struct tty_struct *tty) | ||
680 | { | ||
681 | struct Port *port = (struct Port *) tty->driver_data; | ||
682 | |||
683 | func_enter(); | ||
684 | /* Always unthrottle even if flow control is not enabled on | ||
685 | * this port in case we disabled flow control while the port | ||
686 | * was throttled | ||
687 | */ | ||
688 | |||
689 | port->State &= ~RIO_THROTTLE_RX; | ||
690 | |||
691 | func_exit(); | ||
692 | return; | ||
693 | } | ||
694 | |||
695 | |||
696 | |||
697 | |||
698 | |||
699 | /* ********************************************************************** * | ||
700 | * Here are the initialization routines. * | ||
701 | * ********************************************************************** */ | ||
702 | |||
703 | |||
704 | static struct vpd_prom *get_VPD_PROM(struct Host *hp) | ||
705 | { | ||
706 | static struct vpd_prom vpdp; | ||
707 | char *p; | ||
708 | int i; | ||
709 | |||
710 | func_enter(); | ||
711 | rio_dprintk(RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", hp->Caddr + RIO_VPD_ROM); | ||
712 | |||
713 | p = (char *) &vpdp; | ||
714 | for (i = 0; i < sizeof(struct vpd_prom); i++) | ||
715 | *p++ = readb(hp->Caddr + RIO_VPD_ROM + i * 2); | ||
716 | /* read_rio_byte (hp, RIO_VPD_ROM + i*2); */ | ||
717 | |||
718 | /* Terminate the identifier string. | ||
719 | *** requires one extra byte in struct vpd_prom *** */ | ||
720 | *p++ = 0; | ||
721 | |||
722 | if (rio_debug & RIO_DEBUG_PROBE) | ||
723 | my_hd((char *) &vpdp, 0x20); | ||
724 | |||
725 | func_exit(); | ||
726 | |||
727 | return &vpdp; | ||
728 | } | ||
729 | |||
730 | static const struct tty_operations rio_ops = { | ||
731 | .open = riotopen, | ||
732 | .close = gs_close, | ||
733 | .write = gs_write, | ||
734 | .put_char = gs_put_char, | ||
735 | .flush_chars = gs_flush_chars, | ||
736 | .write_room = gs_write_room, | ||
737 | .chars_in_buffer = gs_chars_in_buffer, | ||
738 | .flush_buffer = gs_flush_buffer, | ||
739 | .ioctl = rio_ioctl, | ||
740 | .throttle = rio_throttle, | ||
741 | .unthrottle = rio_unthrottle, | ||
742 | .set_termios = gs_set_termios, | ||
743 | .stop = gs_stop, | ||
744 | .start = gs_start, | ||
745 | .hangup = gs_hangup, | ||
746 | }; | ||
747 | |||
748 | static int rio_init_drivers(void) | ||
749 | { | ||
750 | int error = -ENOMEM; | ||
751 | |||
752 | rio_driver = alloc_tty_driver(256); | ||
753 | if (!rio_driver) | ||
754 | goto out; | ||
755 | rio_driver2 = alloc_tty_driver(256); | ||
756 | if (!rio_driver2) | ||
757 | goto out1; | ||
758 | |||
759 | func_enter(); | ||
760 | |||
761 | rio_driver->owner = THIS_MODULE; | ||
762 | rio_driver->driver_name = "specialix_rio"; | ||
763 | rio_driver->name = "ttySR"; | ||
764 | rio_driver->major = RIO_NORMAL_MAJOR0; | ||
765 | rio_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
766 | rio_driver->subtype = SERIAL_TYPE_NORMAL; | ||
767 | rio_driver->init_termios = tty_std_termios; | ||
768 | rio_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
769 | rio_driver->flags = TTY_DRIVER_REAL_RAW; | ||
770 | tty_set_operations(rio_driver, &rio_ops); | ||
771 | |||
772 | rio_driver2->owner = THIS_MODULE; | ||
773 | rio_driver2->driver_name = "specialix_rio"; | ||
774 | rio_driver2->name = "ttySR"; | ||
775 | rio_driver2->major = RIO_NORMAL_MAJOR1; | ||
776 | rio_driver2->type = TTY_DRIVER_TYPE_SERIAL; | ||
777 | rio_driver2->subtype = SERIAL_TYPE_NORMAL; | ||
778 | rio_driver2->init_termios = tty_std_termios; | ||
779 | rio_driver2->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
780 | rio_driver2->flags = TTY_DRIVER_REAL_RAW; | ||
781 | tty_set_operations(rio_driver2, &rio_ops); | ||
782 | |||
783 | rio_dprintk(RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios); | ||
784 | |||
785 | if ((error = tty_register_driver(rio_driver))) | ||
786 | goto out2; | ||
787 | if ((error = tty_register_driver(rio_driver2))) | ||
788 | goto out3; | ||
789 | func_exit(); | ||
790 | return 0; | ||
791 | out3: | ||
792 | tty_unregister_driver(rio_driver); | ||
793 | out2: | ||
794 | put_tty_driver(rio_driver2); | ||
795 | out1: | ||
796 | put_tty_driver(rio_driver); | ||
797 | out: | ||
798 | printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n", error); | ||
799 | return 1; | ||
800 | } | ||
801 | |||
802 | static const struct tty_port_operations rio_port_ops = { | ||
803 | .carrier_raised = rio_carrier_raised, | ||
804 | }; | ||
805 | |||
806 | static int rio_init_datastructures(void) | ||
807 | { | ||
808 | int i; | ||
809 | struct Port *port; | ||
810 | func_enter(); | ||
811 | |||
812 | /* Many drivers statically allocate the maximum number of ports | ||
813 | There is no reason not to allocate them dynamically. Is there? -- REW */ | ||
814 | /* However, the RIO driver allows users to configure their first | ||
815 | RTA as the ports numbered 504-511. We therefore need to allocate | ||
816 | the whole range. :-( -- REW */ | ||
817 | |||
818 | #define RI_SZ sizeof(struct rio_info) | ||
819 | #define HOST_SZ sizeof(struct Host) | ||
820 | #define PORT_SZ sizeof(struct Port *) | ||
821 | #define TMIO_SZ sizeof(struct termios *) | ||
822 | rio_dprintk(RIO_DEBUG_INIT, "getting : %Zd %Zd %Zd %Zd %Zd bytes\n", RI_SZ, RIO_HOSTS * HOST_SZ, RIO_PORTS * PORT_SZ, RIO_PORTS * TMIO_SZ, RIO_PORTS * TMIO_SZ); | ||
823 | |||
824 | if (!(p = kzalloc(RI_SZ, GFP_KERNEL))) | ||
825 | goto free0; | ||
826 | if (!(p->RIOHosts = kzalloc(RIO_HOSTS * HOST_SZ, GFP_KERNEL))) | ||
827 | goto free1; | ||
828 | if (!(p->RIOPortp = kzalloc(RIO_PORTS * PORT_SZ, GFP_KERNEL))) | ||
829 | goto free2; | ||
830 | p->RIOConf = RIOConf; | ||
831 | rio_dprintk(RIO_DEBUG_INIT, "Got : %p %p %p\n", p, p->RIOHosts, p->RIOPortp); | ||
832 | |||
833 | #if 1 | ||
834 | for (i = 0; i < RIO_PORTS; i++) { | ||
835 | port = p->RIOPortp[i] = kzalloc(sizeof(struct Port), GFP_KERNEL); | ||
836 | if (!port) { | ||
837 | goto free6; | ||
838 | } | ||
839 | rio_dprintk(RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); | ||
840 | tty_port_init(&port->gs.port); | ||
841 | port->gs.port.ops = &rio_port_ops; | ||
842 | port->PortNum = i; | ||
843 | port->gs.magic = RIO_MAGIC; | ||
844 | port->gs.close_delay = HZ / 2; | ||
845 | port->gs.closing_wait = 30 * HZ; | ||
846 | port->gs.rd = &rio_real_driver; | ||
847 | spin_lock_init(&port->portSem); | ||
848 | } | ||
849 | #else | ||
850 | /* We could postpone initializing them to when they are configured. */ | ||
851 | #endif | ||
852 | |||
853 | |||
854 | |||
855 | if (rio_debug & RIO_DEBUG_INIT) { | ||
856 | my_hd(&rio_real_driver, sizeof(rio_real_driver)); | ||
857 | } | ||
858 | |||
859 | |||
860 | func_exit(); | ||
861 | return 0; | ||
862 | |||
863 | free6:for (i--; i >= 0; i--) | ||
864 | kfree(p->RIOPortp[i]); | ||
865 | /*free5: | ||
866 | free4: | ||
867 | free3:*/ kfree(p->RIOPortp); | ||
868 | free2:kfree(p->RIOHosts); | ||
869 | free1: | ||
870 | rio_dprintk(RIO_DEBUG_INIT, "Not enough memory! %p %p %p\n", p, p->RIOHosts, p->RIOPortp); | ||
871 | kfree(p); | ||
872 | free0: | ||
873 | return -ENOMEM; | ||
874 | } | ||
875 | |||
876 | static void __exit rio_release_drivers(void) | ||
877 | { | ||
878 | func_enter(); | ||
879 | tty_unregister_driver(rio_driver2); | ||
880 | tty_unregister_driver(rio_driver); | ||
881 | put_tty_driver(rio_driver2); | ||
882 | put_tty_driver(rio_driver); | ||
883 | func_exit(); | ||
884 | } | ||
885 | |||
886 | |||
887 | #ifdef CONFIG_PCI | ||
888 | /* This was written for SX, but applies to RIO too... | ||
889 | (including bugs....) | ||
890 | |||
891 | There is another bit besides Bit 17. Turning that bit off | ||
892 | (on boards shipped with the fix in the eeprom) results in a | ||
893 | hang on the next access to the card. | ||
894 | */ | ||
895 | |||
896 | /******************************************************** | ||
897 | * Setting bit 17 in the CNTRL register of the PLX 9050 * | ||
898 | * chip forces a retry on writes while a read is pending.* | ||
899 | * This is to prevent the card locking up on Intel Xeon * | ||
900 | * multiprocessor systems with the NX chipset. -- NV * | ||
901 | ********************************************************/ | ||
902 | |||
903 | /* Newer cards are produced with this bit set from the configuration | ||
904 | EEprom. As the bit is read/write for the CPU, we can fix it here, | ||
905 | if we detect that it isn't set correctly. -- REW */ | ||
906 | |||
907 | static void fix_rio_pci(struct pci_dev *pdev) | ||
908 | { | ||
909 | unsigned long hwbase; | ||
910 | unsigned char __iomem *rebase; | ||
911 | unsigned int t; | ||
912 | |||
913 | #define CNTRL_REG_OFFSET 0x50 | ||
914 | #define CNTRL_REG_GOODVALUE 0x18260000 | ||
915 | |||
916 | hwbase = pci_resource_start(pdev, 0); | ||
917 | rebase = ioremap(hwbase, 0x80); | ||
918 | t = readl(rebase + CNTRL_REG_OFFSET); | ||
919 | if (t != CNTRL_REG_GOODVALUE) { | ||
920 | printk(KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); | ||
921 | writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); | ||
922 | } | ||
923 | iounmap(rebase); | ||
924 | } | ||
925 | #endif | ||
926 | |||
927 | |||
928 | static int __init rio_init(void) | ||
929 | { | ||
930 | int found = 0; | ||
931 | int i; | ||
932 | struct Host *hp; | ||
933 | int retval; | ||
934 | struct vpd_prom *vpdp; | ||
935 | int okboard; | ||
936 | |||
937 | #ifdef CONFIG_PCI | ||
938 | struct pci_dev *pdev = NULL; | ||
939 | unsigned short tshort; | ||
940 | #endif | ||
941 | |||
942 | func_enter(); | ||
943 | rio_dprintk(RIO_DEBUG_INIT, "Initing rio module... (rio_debug=%d)\n", rio_debug); | ||
944 | |||
945 | if (abs((long) (&rio_debug) - rio_debug) < 0x10000) { | ||
946 | printk(KERN_WARNING "rio: rio_debug is an address, instead of a value. " "Assuming -1. Was %x/%p.\n", rio_debug, &rio_debug); | ||
947 | rio_debug = -1; | ||
948 | } | ||
949 | |||
950 | if (misc_register(&rio_fw_device) < 0) { | ||
951 | printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n"); | ||
952 | return -EIO; | ||
953 | } | ||
954 | |||
955 | retval = rio_init_datastructures(); | ||
956 | if (retval < 0) { | ||
957 | misc_deregister(&rio_fw_device); | ||
958 | return retval; | ||
959 | } | ||
960 | #ifdef CONFIG_PCI | ||
961 | /* First look for the JET devices: */ | ||
962 | while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { | ||
963 | u32 tint; | ||
964 | |||
965 | if (pci_enable_device(pdev)) | ||
966 | continue; | ||
967 | |||
968 | /* Specialix has a whole bunch of cards with | ||
969 | 0x2000 as the device ID. They say its because | ||
970 | the standard requires it. Stupid standard. */ | ||
971 | /* It seems that reading a word doesn't work reliably on 2.0. | ||
972 | Also, reading a non-aligned dword doesn't work. So we read the | ||
973 | whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID) | ||
974 | ourselves */ | ||
975 | pci_read_config_dword(pdev, 0x2c, &tint); | ||
976 | tshort = (tint >> 16) & 0xffff; | ||
977 | rio_dprintk(RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); | ||
978 | if (tshort != 0x0100) { | ||
979 | rio_dprintk(RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", tshort); | ||
980 | continue; | ||
981 | } | ||
982 | rio_dprintk(RIO_DEBUG_PROBE, "cp1\n"); | ||
983 | |||
984 | hp = &p->RIOHosts[p->RIONumHosts]; | ||
985 | hp->PaddrP = pci_resource_start(pdev, 2); | ||
986 | hp->Ivec = pdev->irq; | ||
987 | if (((1 << hp->Ivec) & rio_irqmask) == 0) | ||
988 | hp->Ivec = 0; | ||
989 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); | ||
990 | hp->CardP = (struct DpRam __iomem *) hp->Caddr; | ||
991 | hp->Type = RIO_PCI; | ||
992 | hp->Copy = rio_copy_to_card; | ||
993 | hp->Mode = RIO_PCI_BOOT_FROM_RAM; | ||
994 | spin_lock_init(&hp->HostLock); | ||
995 | rio_reset_interrupt(hp); | ||
996 | rio_start_card_running(hp); | ||
997 | |||
998 | rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); | ||
999 | if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { | ||
1000 | rio_dprintk(RIO_DEBUG_INIT, "Done RIOBoardTest\n"); | ||
1001 | writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); | ||
1002 | p->RIOHosts[p->RIONumHosts].UniqueNum = | ||
1003 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | | ||
1004 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); | ||
1005 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); | ||
1006 | |||
1007 | fix_rio_pci(pdev); | ||
1008 | |||
1009 | p->RIOHosts[p->RIONumHosts].pdev = pdev; | ||
1010 | pci_dev_get(pdev); | ||
1011 | |||
1012 | p->RIOLastPCISearch = 0; | ||
1013 | p->RIONumHosts++; | ||
1014 | found++; | ||
1015 | } else { | ||
1016 | iounmap(p->RIOHosts[p->RIONumHosts].Caddr); | ||
1017 | p->RIOHosts[p->RIONumHosts].Caddr = NULL; | ||
1018 | } | ||
1019 | } | ||
1020 | |||
1021 | /* Then look for the older PCI card.... : */ | ||
1022 | |||
1023 | /* These older PCI cards have problems (only byte-mode access is | ||
1024 | supported), which makes them a bit awkward to support. | ||
1025 | They also have problems sharing interrupts. Be careful. | ||
1026 | (The driver now refuses to share interrupts for these | ||
1027 | cards. This should be sufficient). | ||
1028 | */ | ||
1029 | |||
1030 | /* Then look for the older RIO/PCI devices: */ | ||
1031 | while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { | ||
1032 | if (pci_enable_device(pdev)) | ||
1033 | continue; | ||
1034 | |||
1035 | #ifdef CONFIG_RIO_OLDPCI | ||
1036 | hp = &p->RIOHosts[p->RIONumHosts]; | ||
1037 | hp->PaddrP = pci_resource_start(pdev, 0); | ||
1038 | hp->Ivec = pdev->irq; | ||
1039 | if (((1 << hp->Ivec) & rio_irqmask) == 0) | ||
1040 | hp->Ivec = 0; | ||
1041 | hp->Ivec |= 0x8000; /* Mark as non-sharable */ | ||
1042 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); | ||
1043 | hp->CardP = (struct DpRam __iomem *) hp->Caddr; | ||
1044 | hp->Type = RIO_PCI; | ||
1045 | hp->Copy = rio_copy_to_card; | ||
1046 | hp->Mode = RIO_PCI_BOOT_FROM_RAM; | ||
1047 | spin_lock_init(&hp->HostLock); | ||
1048 | |||
1049 | rio_dprintk(RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec); | ||
1050 | rio_dprintk(RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode); | ||
1051 | |||
1052 | rio_reset_interrupt(hp); | ||
1053 | rio_start_card_running(hp); | ||
1054 | rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); | ||
1055 | if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { | ||
1056 | writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); | ||
1057 | p->RIOHosts[p->RIONumHosts].UniqueNum = | ||
1058 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | | ||
1059 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); | ||
1060 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); | ||
1061 | |||
1062 | p->RIOHosts[p->RIONumHosts].pdev = pdev; | ||
1063 | pci_dev_get(pdev); | ||
1064 | |||
1065 | p->RIOLastPCISearch = 0; | ||
1066 | p->RIONumHosts++; | ||
1067 | found++; | ||
1068 | } else { | ||
1069 | iounmap(p->RIOHosts[p->RIONumHosts].Caddr); | ||
1070 | p->RIOHosts[p->RIONumHosts].Caddr = NULL; | ||
1071 | } | ||
1072 | #else | ||
1073 | printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); | ||
1074 | #endif | ||
1075 | } | ||
1076 | #endif /* PCI */ | ||
1077 | |||
1078 | /* Now probe for ISA cards... */ | ||
1079 | for (i = 0; i < NR_RIO_ADDRS; i++) { | ||
1080 | hp = &p->RIOHosts[p->RIONumHosts]; | ||
1081 | hp->PaddrP = rio_probe_addrs[i]; | ||
1082 | /* There was something about the IRQs of these cards. 'Forget what.--REW */ | ||
1083 | hp->Ivec = 0; | ||
1084 | hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); | ||
1085 | hp->CardP = (struct DpRam __iomem *) hp->Caddr; | ||
1086 | hp->Type = RIO_AT; | ||
1087 | hp->Copy = rio_copy_to_card; /* AT card PCI???? - PVDL | ||
1088 | * -- YES! this is now a normal copy. Only the | ||
1089 | * old PCI card uses the special PCI copy. | ||
1090 | * Moreover, the ISA card will work with the | ||
1091 | * special PCI copy anyway. -- REW */ | ||
1092 | hp->Mode = 0; | ||
1093 | spin_lock_init(&hp->HostLock); | ||
1094 | |||
1095 | vpdp = get_VPD_PROM(hp); | ||
1096 | rio_dprintk(RIO_DEBUG_PROBE, "Got VPD ROM\n"); | ||
1097 | okboard = 0; | ||
1098 | if ((strncmp(vpdp->identifier, RIO_ISA_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA3_IDENT, 16) == 0)) { | ||
1099 | /* Board is present... */ | ||
1100 | if (RIOBoardTest(hp->PaddrP, hp->Caddr, RIO_AT, 0) == 0) { | ||
1101 | /* ... and feeling fine!!!! */ | ||
1102 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); | ||
1103 | if (RIOAssignAT(p, hp->PaddrP, hp->Caddr, 0)) { | ||
1104 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, host%d uniqid = %x.\n", p->RIONumHosts, p->RIOHosts[p->RIONumHosts - 1].UniqueNum); | ||
1105 | okboard++; | ||
1106 | found++; | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | if (!okboard) { | ||
1111 | iounmap(hp->Caddr); | ||
1112 | hp->Caddr = NULL; | ||
1113 | } | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1117 | |||
1118 | for (i = 0; i < p->RIONumHosts; i++) { | ||
1119 | hp = &p->RIOHosts[i]; | ||
1120 | if (hp->Ivec) { | ||
1121 | int mode = IRQF_SHARED; | ||
1122 | if (hp->Ivec & 0x8000) { | ||
1123 | mode = 0; | ||
1124 | hp->Ivec &= 0x7fff; | ||
1125 | } | ||
1126 | rio_dprintk(RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp, hp->Ivec, hp->Mode); | ||
1127 | retval = request_irq(hp->Ivec, rio_interrupt, mode, "rio", hp); | ||
1128 | rio_dprintk(RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval); | ||
1129 | if (retval) { | ||
1130 | printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); | ||
1131 | hp->Ivec = 0; | ||
1132 | } | ||
1133 | rio_dprintk(RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec); | ||
1134 | if (hp->Ivec != 0) { | ||
1135 | rio_dprintk(RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); | ||
1136 | hp->Mode |= RIO_PCI_INT_ENABLE; | ||
1137 | } else | ||
1138 | hp->Mode &= ~RIO_PCI_INT_ENABLE; | ||
1139 | rio_dprintk(RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode); | ||
1140 | rio_start_card_running(hp); | ||
1141 | } | ||
1142 | /* Init the timer "always" to make sure that it can safely be | ||
1143 | deleted when we unload... */ | ||
1144 | |||
1145 | setup_timer(&hp->timer, rio_pollfunc, i); | ||
1146 | if (!hp->Ivec) { | ||
1147 | rio_dprintk(RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n", rio_poll); | ||
1148 | mod_timer(&hp->timer, jiffies + rio_poll); | ||
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | if (found) { | ||
1153 | rio_dprintk(RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found); | ||
1154 | rio_init_drivers(); | ||
1155 | } else { | ||
1156 | /* deregister the misc device we created earlier */ | ||
1157 | misc_deregister(&rio_fw_device); | ||
1158 | } | ||
1159 | |||
1160 | func_exit(); | ||
1161 | return found ? 0 : -EIO; | ||
1162 | } | ||
1163 | |||
1164 | |||
1165 | static void __exit rio_exit(void) | ||
1166 | { | ||
1167 | int i; | ||
1168 | struct Host *hp; | ||
1169 | |||
1170 | func_enter(); | ||
1171 | |||
1172 | for (i = 0, hp = p->RIOHosts; i < p->RIONumHosts; i++, hp++) { | ||
1173 | RIOHostReset(hp->Type, hp->CardP, hp->Slot); | ||
1174 | if (hp->Ivec) { | ||
1175 | free_irq(hp->Ivec, hp); | ||
1176 | rio_dprintk(RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec); | ||
1177 | } | ||
1178 | /* It is safe/allowed to del_timer a non-active timer */ | ||
1179 | del_timer_sync(&hp->timer); | ||
1180 | if (hp->Caddr) | ||
1181 | iounmap(hp->Caddr); | ||
1182 | if (hp->Type == RIO_PCI) | ||
1183 | pci_dev_put(hp->pdev); | ||
1184 | } | ||
1185 | |||
1186 | if (misc_deregister(&rio_fw_device) < 0) { | ||
1187 | printk(KERN_INFO "rio: couldn't deregister control-device\n"); | ||
1188 | } | ||
1189 | |||
1190 | |||
1191 | rio_dprintk(RIO_DEBUG_CLEANUP, "Cleaning up drivers\n"); | ||
1192 | |||
1193 | rio_release_drivers(); | ||
1194 | |||
1195 | /* Release dynamically allocated memory */ | ||
1196 | kfree(p->RIOPortp); | ||
1197 | kfree(p->RIOHosts); | ||
1198 | kfree(p); | ||
1199 | |||
1200 | func_exit(); | ||
1201 | } | ||
1202 | |||
1203 | module_init(rio_init); | ||
1204 | module_exit(rio_exit); | ||
diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h deleted file mode 100644 index 7f26cd7c815e..000000000000 --- a/drivers/char/rio/rio_linux.h +++ /dev/null | |||
@@ -1,197 +0,0 @@ | |||
1 | |||
2 | /* | ||
3 | * rio_linux.h | ||
4 | * | ||
5 | * Copyright (C) 1998,1999,2000 R.E.Wolff@BitWizard.nl | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | * RIO serial driver. | ||
22 | * | ||
23 | * Version 1.0 -- July, 1999. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #define RIO_NBOARDS 4 | ||
28 | #define RIO_PORTSPERBOARD 128 | ||
29 | #define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD) | ||
30 | |||
31 | #define MODEM_SUPPORT | ||
32 | |||
33 | #ifdef __KERNEL__ | ||
34 | |||
35 | #define RIO_MAGIC 0x12345678 | ||
36 | |||
37 | |||
38 | struct vpd_prom { | ||
39 | unsigned short id; | ||
40 | char hwrev; | ||
41 | char hwass; | ||
42 | int uniqid; | ||
43 | char myear; | ||
44 | char mweek; | ||
45 | char hw_feature[5]; | ||
46 | char oem_id; | ||
47 | char identifier[16]; | ||
48 | }; | ||
49 | |||
50 | |||
51 | #define RIO_DEBUG_ALL 0xffffffff | ||
52 | |||
53 | #define O_OTHER(tty) \ | ||
54 | ((O_OLCUC(tty)) ||\ | ||
55 | (O_ONLCR(tty)) ||\ | ||
56 | (O_OCRNL(tty)) ||\ | ||
57 | (O_ONOCR(tty)) ||\ | ||
58 | (O_ONLRET(tty)) ||\ | ||
59 | (O_OFILL(tty)) ||\ | ||
60 | (O_OFDEL(tty)) ||\ | ||
61 | (O_NLDLY(tty)) ||\ | ||
62 | (O_CRDLY(tty)) ||\ | ||
63 | (O_TABDLY(tty)) ||\ | ||
64 | (O_BSDLY(tty)) ||\ | ||
65 | (O_VTDLY(tty)) ||\ | ||
66 | (O_FFDLY(tty))) | ||
67 | |||
68 | /* Same for input. */ | ||
69 | #define I_OTHER(tty) \ | ||
70 | ((I_INLCR(tty)) ||\ | ||
71 | (I_IGNCR(tty)) ||\ | ||
72 | (I_ICRNL(tty)) ||\ | ||
73 | (I_IUCLC(tty)) ||\ | ||
74 | (L_ISIG(tty))) | ||
75 | |||
76 | |||
77 | #endif /* __KERNEL__ */ | ||
78 | |||
79 | |||
80 | #define RIO_BOARD_INTR_LOCK 1 | ||
81 | |||
82 | |||
83 | #ifndef RIOCTL_MISC_MINOR | ||
84 | /* Allow others to gather this into "major.h" or something like that */ | ||
85 | #define RIOCTL_MISC_MINOR 169 | ||
86 | #endif | ||
87 | |||
88 | |||
89 | /* Allow us to debug "in the field" without requiring clients to | ||
90 | recompile.... */ | ||
91 | #if 1 | ||
92 | #define rio_spin_lock_irqsave(sem, flags) do { \ | ||
93 | rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \ | ||
94 | sem, __FILE__, __LINE__);\ | ||
95 | spin_lock_irqsave(sem, flags);\ | ||
96 | } while (0) | ||
97 | |||
98 | #define rio_spin_unlock_irqrestore(sem, flags) do { \ | ||
99 | rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\ | ||
100 | sem, __FILE__, __LINE__);\ | ||
101 | spin_unlock_irqrestore(sem, flags);\ | ||
102 | } while (0) | ||
103 | |||
104 | #define rio_spin_lock(sem) do { \ | ||
105 | rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\ | ||
106 | sem, __FILE__, __LINE__);\ | ||
107 | spin_lock(sem);\ | ||
108 | } while (0) | ||
109 | |||
110 | #define rio_spin_unlock(sem) do { \ | ||
111 | rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\ | ||
112 | sem, __FILE__, __LINE__);\ | ||
113 | spin_unlock(sem);\ | ||
114 | } while (0) | ||
115 | #else | ||
116 | #define rio_spin_lock_irqsave(sem, flags) \ | ||
117 | spin_lock_irqsave(sem, flags) | ||
118 | |||
119 | #define rio_spin_unlock_irqrestore(sem, flags) \ | ||
120 | spin_unlock_irqrestore(sem, flags) | ||
121 | |||
122 | #define rio_spin_lock(sem) \ | ||
123 | spin_lock(sem) | ||
124 | |||
125 | #define rio_spin_unlock(sem) \ | ||
126 | spin_unlock(sem) | ||
127 | |||
128 | #endif | ||
129 | |||
130 | |||
131 | |||
132 | #ifdef CONFIG_RIO_OLDPCI | ||
133 | static inline void __iomem *rio_memcpy_toio(void __iomem *dummy, void __iomem *dest, void *source, int n) | ||
134 | { | ||
135 | char __iomem *dst = dest; | ||
136 | char *src = source; | ||
137 | |||
138 | while (n--) { | ||
139 | writeb(*src++, dst++); | ||
140 | (void) readb(dummy); | ||
141 | } | ||
142 | |||
143 | return dest; | ||
144 | } | ||
145 | |||
146 | static inline void __iomem *rio_copy_toio(void __iomem *dest, void *source, int n) | ||
147 | { | ||
148 | char __iomem *dst = dest; | ||
149 | char *src = source; | ||
150 | |||
151 | while (n--) | ||
152 | writeb(*src++, dst++); | ||
153 | |||
154 | return dest; | ||
155 | } | ||
156 | |||
157 | |||
158 | static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n) | ||
159 | { | ||
160 | char *dst = dest; | ||
161 | char __iomem *src = source; | ||
162 | |||
163 | while (n--) | ||
164 | *dst++ = readb(src++); | ||
165 | |||
166 | return dest; | ||
167 | } | ||
168 | |||
169 | #else | ||
170 | #define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n) | ||
171 | #define rio_copy_toio memcpy_toio | ||
172 | #define rio_memcpy_fromio memcpy_fromio | ||
173 | #endif | ||
174 | |||
175 | #define DEBUG 1 | ||
176 | |||
177 | |||
178 | /* | ||
179 | This driver can spew a whole lot of debugging output at you. If you | ||
180 | need maximum performance, you should disable the DEBUG define. To | ||
181 | aid in debugging in the field, I'm leaving the compile-time debug | ||
182 | features enabled, and disable them "runtime". That allows me to | ||
183 | instruct people with problems to enable debugging without requiring | ||
184 | them to recompile... | ||
185 | */ | ||
186 | |||
187 | #ifdef DEBUG | ||
188 | #define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0) | ||
189 | #define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __func__) | ||
190 | #define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __func__) | ||
191 | #define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__func__, port->line) | ||
192 | #else | ||
193 | #define rio_dprintk(f, str...) /* nothing */ | ||
194 | #define func_enter() | ||
195 | #define func_exit() | ||
196 | #define func_enter2() | ||
197 | #endif | ||
diff --git a/drivers/char/rio/rioboard.h b/drivers/char/rio/rioboard.h deleted file mode 100644 index 252230043c82..000000000000 --- a/drivers/char/rio/rioboard.h +++ /dev/null | |||
@@ -1,275 +0,0 @@ | |||
1 | /************************************************************************/ | ||
2 | /* */ | ||
3 | /* Title : RIO Host Card Hardware Definitions */ | ||
4 | /* */ | ||
5 | /* Author : N.P.Vassallo */ | ||
6 | /* */ | ||
7 | /* Creation : 26th April 1999 */ | ||
8 | /* */ | ||
9 | /* Version : 1.0.0 */ | ||
10 | /* */ | ||
11 | /* Copyright : (c) Specialix International Ltd. 1999 * | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * */ | ||
27 | /* Description : Prototypes, structures and definitions */ | ||
28 | /* describing the RIO board hardware */ | ||
29 | /* */ | ||
30 | /************************************************************************/ | ||
31 | |||
32 | #ifndef _rioboard_h /* If RIOBOARD.H not already defined */ | ||
33 | #define _rioboard_h 1 | ||
34 | |||
35 | /***************************************************************************** | ||
36 | *********************** *********************** | ||
37 | *********************** Hardware Control Registers *********************** | ||
38 | *********************** *********************** | ||
39 | *****************************************************************************/ | ||
40 | |||
41 | /* Hardware Registers... */ | ||
42 | |||
43 | #define RIO_REG_BASE 0x7C00 /* Base of control registers */ | ||
44 | |||
45 | #define RIO_CONFIG RIO_REG_BASE + 0x0000 /* WRITE: Configuration Register */ | ||
46 | #define RIO_INTSET RIO_REG_BASE + 0x0080 /* WRITE: Interrupt Set */ | ||
47 | #define RIO_RESET RIO_REG_BASE + 0x0100 /* WRITE: Host Reset */ | ||
48 | #define RIO_INTRESET RIO_REG_BASE + 0x0180 /* WRITE: Interrupt Reset */ | ||
49 | |||
50 | #define RIO_VPD_ROM RIO_REG_BASE + 0x0000 /* READ: Vital Product Data ROM */ | ||
51 | #define RIO_INTSTAT RIO_REG_BASE + 0x0080 /* READ: Interrupt Status (Jet boards only) */ | ||
52 | #define RIO_RESETSTAT RIO_REG_BASE + 0x0100 /* READ: Reset Status (Jet boards only) */ | ||
53 | |||
54 | /* RIO_VPD_ROM definitions... */ | ||
55 | #define VPD_SLX_ID1 0x00 /* READ: Specialix Identifier #1 */ | ||
56 | #define VPD_SLX_ID2 0x01 /* READ: Specialix Identifier #2 */ | ||
57 | #define VPD_HW_REV 0x02 /* READ: Hardware Revision */ | ||
58 | #define VPD_HW_ASSEM 0x03 /* READ: Hardware Assembly Level */ | ||
59 | #define VPD_UNIQUEID4 0x04 /* READ: Unique Identifier #4 */ | ||
60 | #define VPD_UNIQUEID3 0x05 /* READ: Unique Identifier #3 */ | ||
61 | #define VPD_UNIQUEID2 0x06 /* READ: Unique Identifier #2 */ | ||
62 | #define VPD_UNIQUEID1 0x07 /* READ: Unique Identifier #1 */ | ||
63 | #define VPD_MANU_YEAR 0x08 /* READ: Year Of Manufacture (0 = 1970) */ | ||
64 | #define VPD_MANU_WEEK 0x09 /* READ: Week Of Manufacture (0 = week 1 Jan) */ | ||
65 | #define VPD_HWFEATURE1 0x0A /* READ: Hardware Feature Byte 1 */ | ||
66 | #define VPD_HWFEATURE2 0x0B /* READ: Hardware Feature Byte 2 */ | ||
67 | #define VPD_HWFEATURE3 0x0C /* READ: Hardware Feature Byte 3 */ | ||
68 | #define VPD_HWFEATURE4 0x0D /* READ: Hardware Feature Byte 4 */ | ||
69 | #define VPD_HWFEATURE5 0x0E /* READ: Hardware Feature Byte 5 */ | ||
70 | #define VPD_OEMID 0x0F /* READ: OEM Identifier */ | ||
71 | #define VPD_IDENT 0x10 /* READ: Identifier string (16 bytes) */ | ||
72 | #define VPD_IDENT_LEN 0x10 | ||
73 | |||
74 | /* VPD ROM Definitions... */ | ||
75 | #define SLX_ID1 0x4D | ||
76 | #define SLX_ID2 0x98 | ||
77 | |||
78 | #define PRODUCT_ID(a) ((a>>4)&0xF) /* Use to obtain Product ID from VPD_UNIQUEID1 */ | ||
79 | |||
80 | #define ID_SX_ISA 0x2 | ||
81 | #define ID_RIO_EISA 0x3 | ||
82 | #define ID_SX_PCI 0x5 | ||
83 | #define ID_SX_EISA 0x7 | ||
84 | #define ID_RIO_RTA16 0x9 | ||
85 | #define ID_RIO_ISA 0xA | ||
86 | #define ID_RIO_MCA 0xB | ||
87 | #define ID_RIO_SBUS 0xC | ||
88 | #define ID_RIO_PCI 0xD | ||
89 | #define ID_RIO_RTA8 0xE | ||
90 | |||
91 | /* Transputer bootstrap definitions... */ | ||
92 | |||
93 | #define BOOTLOADADDR (0x8000 - 6) | ||
94 | #define BOOTINDICATE (0x8000 - 2) | ||
95 | |||
96 | /* Firmware load position... */ | ||
97 | |||
98 | #define FIRMWARELOADADDR 0x7C00 /* Firmware is loaded _before_ this address */ | ||
99 | |||
100 | /***************************************************************************** | ||
101 | ***************************** ***************************** | ||
102 | ***************************** RIO (Rev1) ISA ***************************** | ||
103 | ***************************** ***************************** | ||
104 | *****************************************************************************/ | ||
105 | |||
106 | /* Control Register Definitions... */ | ||
107 | #define RIO_ISA_IDENT "JBJGPGGHINSMJPJR" | ||
108 | |||
109 | #define RIO_ISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ | ||
110 | #define RIO_ISA_CFG_BUSENABLE 0x02 /* Enable processor bus */ | ||
111 | #define RIO_ISA_CFG_IRQMASK 0x30 /* Interrupt mask */ | ||
112 | #define RIO_ISA_CFG_IRQ12 0x10 /* Interrupt Level 12 */ | ||
113 | #define RIO_ISA_CFG_IRQ11 0x20 /* Interrupt Level 11 */ | ||
114 | #define RIO_ISA_CFG_IRQ9 0x30 /* Interrupt Level 9 */ | ||
115 | #define RIO_ISA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ | ||
116 | #define RIO_ISA_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ | ||
117 | |||
118 | /***************************************************************************** | ||
119 | ***************************** ***************************** | ||
120 | ***************************** RIO (Rev2) ISA ***************************** | ||
121 | ***************************** ***************************** | ||
122 | *****************************************************************************/ | ||
123 | |||
124 | /* Control Register Definitions... */ | ||
125 | #define RIO_ISA2_IDENT "JBJGPGGHINSMJPJR" | ||
126 | |||
127 | #define RIO_ISA2_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ | ||
128 | #define RIO_ISA2_CFG_BUSENABLE 0x02 /* Enable processor bus */ | ||
129 | #define RIO_ISA2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ | ||
130 | #define RIO_ISA2_CFG_16BIT 0x08 /* 16bit mode, else 8bit */ | ||
131 | #define RIO_ISA2_CFG_IRQMASK 0x30 /* Interrupt mask */ | ||
132 | #define RIO_ISA2_CFG_IRQ15 0x00 /* Interrupt Level 15 */ | ||
133 | #define RIO_ISA2_CFG_IRQ12 0x10 /* Interrupt Level 12 */ | ||
134 | #define RIO_ISA2_CFG_IRQ11 0x20 /* Interrupt Level 11 */ | ||
135 | #define RIO_ISA2_CFG_IRQ9 0x30 /* Interrupt Level 9 */ | ||
136 | #define RIO_ISA2_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ | ||
137 | #define RIO_ISA2_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ | ||
138 | |||
139 | /***************************************************************************** | ||
140 | ***************************** ****************************** | ||
141 | ***************************** RIO (Jet) ISA ****************************** | ||
142 | ***************************** ****************************** | ||
143 | *****************************************************************************/ | ||
144 | |||
145 | /* Control Register Definitions... */ | ||
146 | #define RIO_ISA3_IDENT "JET HOST BY KEV#" | ||
147 | |||
148 | #define RIO_ISA3_CFG_BUSENABLE 0x02 /* Enable processor bus */ | ||
149 | #define RIO_ISA3_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ | ||
150 | #define RIO_ISA32_CFG_IRQMASK 0xF30 /* Interrupt mask */ | ||
151 | #define RIO_ISA3_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ | ||
152 | #define RIO_ISA3_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ | ||
153 | #define RIO_ISA3_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ | ||
154 | #define RIO_ISA3_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ | ||
155 | #define RIO_ISA3_CFG_IRQ9 0x90 /* Interrupt Level 9 */ | ||
156 | |||
157 | /***************************************************************************** | ||
158 | ********************************* ******************************** | ||
159 | ********************************* RIO MCA ******************************** | ||
160 | ********************************* ******************************** | ||
161 | *****************************************************************************/ | ||
162 | |||
163 | /* Control Register Definitions... */ | ||
164 | #define RIO_MCA_IDENT "JBJGPGGHINSMJPJR" | ||
165 | |||
166 | #define RIO_MCA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ | ||
167 | #define RIO_MCA_CFG_BUSENABLE 0x02 /* Enable processor bus */ | ||
168 | #define RIO_MCA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ | ||
169 | |||
170 | /***************************************************************************** | ||
171 | ******************************** ******************************** | ||
172 | ******************************** RIO EISA ******************************** | ||
173 | ******************************** ******************************** | ||
174 | *****************************************************************************/ | ||
175 | |||
176 | /* EISA Configuration Space Definitions... */ | ||
177 | #define EISA_PRODUCT_ID1 0xC80 | ||
178 | #define EISA_PRODUCT_ID2 0xC81 | ||
179 | #define EISA_PRODUCT_NUMBER 0xC82 | ||
180 | #define EISA_REVISION_NUMBER 0xC83 | ||
181 | #define EISA_CARD_ENABLE 0xC84 | ||
182 | #define EISA_VPD_UNIQUEID4 0xC88 /* READ: Unique Identifier #4 */ | ||
183 | #define EISA_VPD_UNIQUEID3 0xC8A /* READ: Unique Identifier #3 */ | ||
184 | #define EISA_VPD_UNIQUEID2 0xC90 /* READ: Unique Identifier #2 */ | ||
185 | #define EISA_VPD_UNIQUEID1 0xC92 /* READ: Unique Identifier #1 */ | ||
186 | #define EISA_VPD_MANU_YEAR 0xC98 /* READ: Year Of Manufacture (0 = 1970) */ | ||
187 | #define EISA_VPD_MANU_WEEK 0xC9A /* READ: Week Of Manufacture (0 = week 1 Jan) */ | ||
188 | #define EISA_MEM_ADDR_23_16 0xC00 | ||
189 | #define EISA_MEM_ADDR_31_24 0xC01 | ||
190 | #define EISA_RIO_CONFIG 0xC02 /* WRITE: Configuration Register */ | ||
191 | #define EISA_RIO_INTSET 0xC03 /* WRITE: Interrupt Set */ | ||
192 | #define EISA_RIO_INTRESET 0xC03 /* READ: Interrupt Reset */ | ||
193 | |||
194 | /* Control Register Definitions... */ | ||
195 | #define RIO_EISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ | ||
196 | #define RIO_EISA_CFG_LINK20 0x02 /* 20Mbps link, else 10Mbps */ | ||
197 | #define RIO_EISA_CFG_BUSENABLE 0x04 /* Enable processor bus */ | ||
198 | #define RIO_EISA_CFG_PROCRUN 0x08 /* Processor running, else reset */ | ||
199 | #define RIO_EISA_CFG_IRQMASK 0xF0 /* Interrupt mask */ | ||
200 | #define RIO_EISA_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ | ||
201 | #define RIO_EISA_CFG_IRQ14 0xE0 /* Interrupt Level 14 */ | ||
202 | #define RIO_EISA_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ | ||
203 | #define RIO_EISA_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ | ||
204 | #define RIO_EISA_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ | ||
205 | #define RIO_EISA_CFG_IRQ9 0x90 /* Interrupt Level 9 */ | ||
206 | #define RIO_EISA_CFG_IRQ7 0x70 /* Interrupt Level 7 */ | ||
207 | #define RIO_EISA_CFG_IRQ6 0x60 /* Interrupt Level 6 */ | ||
208 | #define RIO_EISA_CFG_IRQ5 0x50 /* Interrupt Level 5 */ | ||
209 | #define RIO_EISA_CFG_IRQ4 0x40 /* Interrupt Level 4 */ | ||
210 | #define RIO_EISA_CFG_IRQ3 0x30 /* Interrupt Level 3 */ | ||
211 | |||
212 | /***************************************************************************** | ||
213 | ******************************** ******************************** | ||
214 | ******************************** RIO SBus ******************************** | ||
215 | ******************************** ******************************** | ||
216 | *****************************************************************************/ | ||
217 | |||
218 | /* Control Register Definitions... */ | ||
219 | #define RIO_SBUS_IDENT "JBPGK#\0\0\0\0\0\0\0\0\0\0" | ||
220 | |||
221 | #define RIO_SBUS_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ | ||
222 | #define RIO_SBUS_CFG_BUSENABLE 0x02 /* Enable processor bus */ | ||
223 | #define RIO_SBUS_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ | ||
224 | #define RIO_SBUS_CFG_IRQMASK 0x38 /* Interrupt mask */ | ||
225 | #define RIO_SBUS_CFG_IRQNONE 0x00 /* No Interrupt */ | ||
226 | #define RIO_SBUS_CFG_IRQ7 0x38 /* Interrupt Level 7 */ | ||
227 | #define RIO_SBUS_CFG_IRQ6 0x30 /* Interrupt Level 6 */ | ||
228 | #define RIO_SBUS_CFG_IRQ5 0x28 /* Interrupt Level 5 */ | ||
229 | #define RIO_SBUS_CFG_IRQ4 0x20 /* Interrupt Level 4 */ | ||
230 | #define RIO_SBUS_CFG_IRQ3 0x18 /* Interrupt Level 3 */ | ||
231 | #define RIO_SBUS_CFG_IRQ2 0x10 /* Interrupt Level 2 */ | ||
232 | #define RIO_SBUS_CFG_IRQ1 0x08 /* Interrupt Level 1 */ | ||
233 | #define RIO_SBUS_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ | ||
234 | #define RIO_SBUS_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ | ||
235 | |||
236 | /***************************************************************************** | ||
237 | ********************************* ******************************** | ||
238 | ********************************* RIO PCI ******************************** | ||
239 | ********************************* ******************************** | ||
240 | *****************************************************************************/ | ||
241 | |||
242 | /* Control Register Definitions... */ | ||
243 | #define RIO_PCI_IDENT "ECDDPGJGJHJRGSK#" | ||
244 | |||
245 | #define RIO_PCI_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ | ||
246 | #define RIO_PCI_CFG_BUSENABLE 0x02 /* Enable processor bus */ | ||
247 | #define RIO_PCI_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ | ||
248 | #define RIO_PCI_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ | ||
249 | #define RIO_PCI_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ | ||
250 | |||
251 | /* PCI Definitions... */ | ||
252 | #define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ | ||
253 | #define SPX_DEVICE_ID 0x8000 /* RIO bridge boards */ | ||
254 | #define SPX_PLXDEVICE_ID 0x2000 /* PLX bridge boards */ | ||
255 | #define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ | ||
256 | #define RIO_SUB_SYS_ID 0x0800 /* RIO PCI board */ | ||
257 | |||
258 | /***************************************************************************** | ||
259 | ***************************** ****************************** | ||
260 | ***************************** RIO (Jet) PCI ****************************** | ||
261 | ***************************** ****************************** | ||
262 | *****************************************************************************/ | ||
263 | |||
264 | /* Control Register Definitions... */ | ||
265 | #define RIO_PCI2_IDENT "JET HOST BY KEV#" | ||
266 | |||
267 | #define RIO_PCI2_CFG_BUSENABLE 0x02 /* Enable processor bus */ | ||
268 | #define RIO_PCI2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ | ||
269 | |||
270 | /* PCI Definitions... */ | ||
271 | #define RIO2_SUB_SYS_ID 0x0100 /* RIO (Jet) PCI board */ | ||
272 | |||
273 | #endif /*_rioboard_h */ | ||
274 | |||
275 | /* End of RIOBOARD.H */ | ||
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c deleted file mode 100644 index d956dd316005..000000000000 --- a/drivers/char/rio/rioboot.c +++ /dev/null | |||
@@ -1,1113 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rioboot.c | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 10:33:36 | ||
26 | ** Retrieved : 11/6/98 10:33:48 | ||
27 | ** | ||
28 | ** ident @(#)rioboot.c 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/termios.h> | ||
36 | #include <linux/serial.h> | ||
37 | #include <linux/vmalloc.h> | ||
38 | #include <linux/generic_serial.h> | ||
39 | #include <linux/errno.h> | ||
40 | #include <linux/interrupt.h> | ||
41 | #include <linux/delay.h> | ||
42 | #include <asm/io.h> | ||
43 | #include <asm/system.h> | ||
44 | #include <asm/string.h> | ||
45 | #include <asm/uaccess.h> | ||
46 | |||
47 | |||
48 | #include "linux_compat.h" | ||
49 | #include "rio_linux.h" | ||
50 | #include "pkt.h" | ||
51 | #include "daemon.h" | ||
52 | #include "rio.h" | ||
53 | #include "riospace.h" | ||
54 | #include "cmdpkt.h" | ||
55 | #include "map.h" | ||
56 | #include "rup.h" | ||
57 | #include "port.h" | ||
58 | #include "riodrvr.h" | ||
59 | #include "rioinfo.h" | ||
60 | #include "func.h" | ||
61 | #include "errors.h" | ||
62 | #include "pci.h" | ||
63 | |||
64 | #include "parmmap.h" | ||
65 | #include "unixrup.h" | ||
66 | #include "board.h" | ||
67 | #include "host.h" | ||
68 | #include "phb.h" | ||
69 | #include "link.h" | ||
70 | #include "cmdblk.h" | ||
71 | #include "route.h" | ||
72 | |||
73 | static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP); | ||
74 | |||
75 | static const unsigned char RIOAtVec2Ctrl[] = { | ||
76 | /* 0 */ INTERRUPT_DISABLE, | ||
77 | /* 1 */ INTERRUPT_DISABLE, | ||
78 | /* 2 */ INTERRUPT_DISABLE, | ||
79 | /* 3 */ INTERRUPT_DISABLE, | ||
80 | /* 4 */ INTERRUPT_DISABLE, | ||
81 | /* 5 */ INTERRUPT_DISABLE, | ||
82 | /* 6 */ INTERRUPT_DISABLE, | ||
83 | /* 7 */ INTERRUPT_DISABLE, | ||
84 | /* 8 */ INTERRUPT_DISABLE, | ||
85 | /* 9 */ IRQ_9 | INTERRUPT_ENABLE, | ||
86 | /* 10 */ INTERRUPT_DISABLE, | ||
87 | /* 11 */ IRQ_11 | INTERRUPT_ENABLE, | ||
88 | /* 12 */ IRQ_12 | INTERRUPT_ENABLE, | ||
89 | /* 13 */ INTERRUPT_DISABLE, | ||
90 | /* 14 */ INTERRUPT_DISABLE, | ||
91 | /* 15 */ IRQ_15 | INTERRUPT_ENABLE | ||
92 | }; | ||
93 | |||
94 | /** | ||
95 | * RIOBootCodeRTA - Load RTA boot code | ||
96 | * @p: RIO to load | ||
97 | * @rbp: Download descriptor | ||
98 | * | ||
99 | * Called when the user process initiates booting of the card firmware. | ||
100 | * Lads the firmware | ||
101 | */ | ||
102 | |||
103 | int RIOBootCodeRTA(struct rio_info *p, struct DownLoad * rbp) | ||
104 | { | ||
105 | int offset; | ||
106 | |||
107 | func_enter(); | ||
108 | |||
109 | rio_dprintk(RIO_DEBUG_BOOT, "Data at user address %p\n", rbp->DataP); | ||
110 | |||
111 | /* | ||
112 | ** Check that we have set asside enough memory for this | ||
113 | */ | ||
114 | if (rbp->Count > SIXTY_FOUR_K) { | ||
115 | rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); | ||
116 | p->RIOError.Error = HOST_FILE_TOO_LARGE; | ||
117 | func_exit(); | ||
118 | return -ENOMEM; | ||
119 | } | ||
120 | |||
121 | if (p->RIOBooting) { | ||
122 | rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n"); | ||
123 | p->RIOError.Error = BOOT_IN_PROGRESS; | ||
124 | func_exit(); | ||
125 | return -EBUSY; | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary, | ||
130 | ** so calculate how far we have to move the data up the buffer | ||
131 | ** to achieve this. | ||
132 | */ | ||
133 | offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % RTA_BOOT_DATA_SIZE; | ||
134 | |||
135 | /* | ||
136 | ** Be clean, and clear the 'unused' portion of the boot buffer, | ||
137 | ** because it will (eventually) be part of the Rta run time environment | ||
138 | ** and so should be zeroed. | ||
139 | */ | ||
140 | memset(p->RIOBootPackets, 0, offset); | ||
141 | |||
142 | /* | ||
143 | ** Copy the data from user space into the array | ||
144 | */ | ||
145 | |||
146 | if (copy_from_user(((u8 *)p->RIOBootPackets) + offset, rbp->DataP, rbp->Count)) { | ||
147 | rio_dprintk(RIO_DEBUG_BOOT, "Bad data copy from user space\n"); | ||
148 | p->RIOError.Error = COPYIN_FAILED; | ||
149 | func_exit(); | ||
150 | return -EFAULT; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | ** Make sure that our copy of the size includes that offset we discussed | ||
155 | ** earlier. | ||
156 | */ | ||
157 | p->RIONumBootPkts = (rbp->Count + offset) / RTA_BOOT_DATA_SIZE; | ||
158 | p->RIOBootCount = rbp->Count; | ||
159 | |||
160 | func_exit(); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * rio_start_card_running - host card start | ||
166 | * @HostP: The RIO to kick off | ||
167 | * | ||
168 | * Start a RIO processor unit running. Encapsulates the knowledge | ||
169 | * of the card type. | ||
170 | */ | ||
171 | |||
172 | void rio_start_card_running(struct Host *HostP) | ||
173 | { | ||
174 | switch (HostP->Type) { | ||
175 | case RIO_AT: | ||
176 | rio_dprintk(RIO_DEBUG_BOOT, "Start ISA card running\n"); | ||
177 | writeb(BOOT_FROM_RAM | EXTERNAL_BUS_ON | HostP->Mode | RIOAtVec2Ctrl[HostP->Ivec & 0xF], &HostP->Control); | ||
178 | break; | ||
179 | case RIO_PCI: | ||
180 | /* | ||
181 | ** PCI is much the same as MCA. Everything is once again memory | ||
182 | ** mapped, so we are writing to memory registers instead of io | ||
183 | ** ports. | ||
184 | */ | ||
185 | rio_dprintk(RIO_DEBUG_BOOT, "Start PCI card running\n"); | ||
186 | writeb(PCITpBootFromRam | PCITpBusEnable | HostP->Mode, &HostP->Control); | ||
187 | break; | ||
188 | default: | ||
189 | rio_dprintk(RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type); | ||
190 | break; | ||
191 | } | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | ** Load in the host boot code - load it directly onto all halted hosts | ||
197 | ** of the correct type. | ||
198 | ** | ||
199 | ** Put your rubber pants on before messing with this code - even the magic | ||
200 | ** numbers have trouble understanding what they are doing here. | ||
201 | */ | ||
202 | |||
203 | int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) | ||
204 | { | ||
205 | struct Host *HostP; | ||
206 | u8 __iomem *Cad; | ||
207 | PARM_MAP __iomem *ParmMapP; | ||
208 | int RupN; | ||
209 | int PortN; | ||
210 | unsigned int host; | ||
211 | u8 __iomem *StartP; | ||
212 | u8 __iomem *DestP; | ||
213 | int wait_count; | ||
214 | u16 OldParmMap; | ||
215 | u16 offset; /* It is very important that this is a u16 */ | ||
216 | u8 *DownCode = NULL; | ||
217 | unsigned long flags; | ||
218 | |||
219 | HostP = NULL; /* Assure the compiler we've initialized it */ | ||
220 | |||
221 | |||
222 | /* Walk the hosts */ | ||
223 | for (host = 0; host < p->RIONumHosts; host++) { | ||
224 | rio_dprintk(RIO_DEBUG_BOOT, "Attempt to boot host %d\n", host); | ||
225 | HostP = &p->RIOHosts[host]; | ||
226 | |||
227 | rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); | ||
228 | |||
229 | /* Don't boot hosts already running */ | ||
230 | if ((HostP->Flags & RUN_STATE) != RC_WAITING) { | ||
231 | rio_dprintk(RIO_DEBUG_BOOT, "%s %d already running\n", "Host", host); | ||
232 | continue; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | ** Grab a pointer to the card (ioremapped) | ||
237 | */ | ||
238 | Cad = HostP->Caddr; | ||
239 | |||
240 | /* | ||
241 | ** We are going to (try) and load in rbp->Count bytes. | ||
242 | ** The last byte will reside at p->RIOConf.HostLoadBase-1; | ||
243 | ** Therefore, we need to start copying at address | ||
244 | ** (caddr+p->RIOConf.HostLoadBase-rbp->Count) | ||
245 | */ | ||
246 | StartP = &Cad[p->RIOConf.HostLoadBase - rbp->Count]; | ||
247 | |||
248 | rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for host is %p\n", Cad); | ||
249 | rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for download is %p\n", StartP); | ||
250 | rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); | ||
251 | rio_dprintk(RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count); | ||
252 | |||
253 | /* Make sure it fits */ | ||
254 | if (p->RIOConf.HostLoadBase < rbp->Count) { | ||
255 | rio_dprintk(RIO_DEBUG_BOOT, "Bin too large\n"); | ||
256 | p->RIOError.Error = HOST_FILE_TOO_LARGE; | ||
257 | func_exit(); | ||
258 | return -EFBIG; | ||
259 | } | ||
260 | /* | ||
261 | ** Ensure that the host really is stopped. | ||
262 | ** Disable it's external bus & twang its reset line. | ||
263 | */ | ||
264 | RIOHostReset(HostP->Type, HostP->CardP, HostP->Slot); | ||
265 | |||
266 | /* | ||
267 | ** Copy the data directly from user space to the SRAM. | ||
268 | ** This ain't going to be none too clever if the download | ||
269 | ** code is bigger than this segment. | ||
270 | */ | ||
271 | rio_dprintk(RIO_DEBUG_BOOT, "Copy in code\n"); | ||
272 | |||
273 | /* Buffer to local memory as we want to use I/O space and | ||
274 | some cards only do 8 or 16 bit I/O */ | ||
275 | |||
276 | DownCode = vmalloc(rbp->Count); | ||
277 | if (!DownCode) { | ||
278 | p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; | ||
279 | func_exit(); | ||
280 | return -ENOMEM; | ||
281 | } | ||
282 | if (copy_from_user(DownCode, rbp->DataP, rbp->Count)) { | ||
283 | kfree(DownCode); | ||
284 | p->RIOError.Error = COPYIN_FAILED; | ||
285 | func_exit(); | ||
286 | return -EFAULT; | ||
287 | } | ||
288 | HostP->Copy(DownCode, StartP, rbp->Count); | ||
289 | vfree(DownCode); | ||
290 | |||
291 | rio_dprintk(RIO_DEBUG_BOOT, "Copy completed\n"); | ||
292 | |||
293 | /* | ||
294 | ** S T O P ! | ||
295 | ** | ||
296 | ** Upto this point the code has been fairly rational, and possibly | ||
297 | ** even straight forward. What follows is a pile of crud that will | ||
298 | ** magically turn into six bytes of transputer assembler. Normally | ||
299 | ** you would expect an array or something, but, being me, I have | ||
300 | ** chosen [been told] to use a technique whereby the startup code | ||
301 | ** will be correct if we change the loadbase for the code. Which | ||
302 | ** brings us onto another issue - the loadbase is the *end* of the | ||
303 | ** code, not the start. | ||
304 | ** | ||
305 | ** If I were you I wouldn't start from here. | ||
306 | */ | ||
307 | |||
308 | /* | ||
309 | ** We now need to insert a short boot section into | ||
310 | ** the memory at the end of Sram2. This is normally (de)composed | ||
311 | ** of the last eight bytes of the download code. The | ||
312 | ** download has been assembled/compiled to expect to be | ||
313 | ** loaded from 0x7FFF downwards. We have loaded it | ||
314 | ** at some other address. The startup code goes into the small | ||
315 | ** ram window at Sram2, in the last 8 bytes, which are really | ||
316 | ** at addresses 0x7FF8-0x7FFF. | ||
317 | ** | ||
318 | ** If the loadbase is, say, 0x7C00, then we need to branch to | ||
319 | ** address 0x7BFE to run the host.bin startup code. We assemble | ||
320 | ** this jump manually. | ||
321 | ** | ||
322 | ** The two byte sequence 60 08 is loaded into memory at address | ||
323 | ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0, | ||
324 | ** which adds '0' to the .O register, complements .O, and then shifts | ||
325 | ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will | ||
326 | ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new | ||
327 | ** location. Now, the branch starts from the value of .PC (or .IP or | ||
328 | ** whatever the bloody register is called on this chip), and the .PC | ||
329 | ** will be pointing to the location AFTER the branch, in this case | ||
330 | ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8. | ||
331 | ** | ||
332 | ** A long branch is coded at 0x7FF8. This consists of loading a four | ||
333 | ** byte offset into .O using nfix (as above) and pfix operators. The | ||
334 | ** pfix operates in exactly the same way as the nfix operator, but | ||
335 | ** without the complement operation. The offset, of course, must be | ||
336 | ** relative to the address of the byte AFTER the branch instruction, | ||
337 | ** which will be (urm) 0x7FFC, so, our final destination of the branch | ||
338 | ** (loadbase-2), has to be reached from here. Imagine that the loadbase | ||
339 | ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which | ||
340 | ** is the first byte of the initial two byte short local branch of the | ||
341 | ** download code). | ||
342 | ** | ||
343 | ** To code a jump from 0x7FFC (which is where the branch will start | ||
344 | ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)= | ||
345 | ** 0x7BFE. | ||
346 | ** This will be coded as four bytes: | ||
347 | ** 60 2C 20 02 | ||
348 | ** being nfix .O+0 | ||
349 | ** pfix .O+C | ||
350 | ** pfix .O+0 | ||
351 | ** jump .O+2 | ||
352 | ** | ||
353 | ** The nfix operator is used, so that the startup code will be | ||
354 | ** compatible with the whole Tp family. (lies, damn lies, it'll never | ||
355 | ** work in a month of Sundays). | ||
356 | ** | ||
357 | ** The nfix nyble is the 1s complement of the nyble value you | ||
358 | ** want to load - in this case we wanted 'F' so we nfix loaded '0'. | ||
359 | */ | ||
360 | |||
361 | |||
362 | /* | ||
363 | ** Dest points to the top 8 bytes of Sram2. The Tp jumps | ||
364 | ** to 0x7FFE at reset time, and starts executing. This is | ||
365 | ** a short branch to 0x7FF8, where a long branch is coded. | ||
366 | */ | ||
367 | |||
368 | DestP = &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ | ||
369 | |||
370 | #define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ | ||
371 | #define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ | ||
372 | #define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */ | ||
373 | |||
374 | /* | ||
375 | ** 0x7FFC is the address of the location following the last byte of | ||
376 | ** the four byte jump instruction. | ||
377 | ** READ THE ABOVE COMMENTS | ||
378 | ** | ||
379 | ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about. | ||
380 | ** Memsize is 64K for this range of Tp, so offset is a short (unsigned, | ||
381 | ** cos I don't understand 2's complement). | ||
382 | */ | ||
383 | offset = (p->RIOConf.HostLoadBase - 2) - 0x7FFC; | ||
384 | |||
385 | writeb(NFIX(((unsigned short) (~offset) >> (unsigned short) 12) & 0xF), DestP); | ||
386 | writeb(PFIX((offset >> 8) & 0xF), DestP + 1); | ||
387 | writeb(PFIX((offset >> 4) & 0xF), DestP + 2); | ||
388 | writeb(JUMP(offset & 0xF), DestP + 3); | ||
389 | |||
390 | writeb(NFIX(0), DestP + 6); | ||
391 | writeb(JUMP(8), DestP + 7); | ||
392 | |||
393 | rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); | ||
394 | rio_dprintk(RIO_DEBUG_BOOT, "startup offset is 0x%x\n", offset); | ||
395 | |||
396 | /* | ||
397 | ** Flag what is going on | ||
398 | */ | ||
399 | HostP->Flags &= ~RUN_STATE; | ||
400 | HostP->Flags |= RC_STARTUP; | ||
401 | |||
402 | /* | ||
403 | ** Grab a copy of the current ParmMap pointer, so we | ||
404 | ** can tell when it has changed. | ||
405 | */ | ||
406 | OldParmMap = readw(&HostP->__ParmMapR); | ||
407 | |||
408 | rio_dprintk(RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n", OldParmMap); | ||
409 | |||
410 | /* | ||
411 | ** And start it running (I hope). | ||
412 | ** As there is nothing dodgy or obscure about the | ||
413 | ** above code, this is guaranteed to work every time. | ||
414 | */ | ||
415 | rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); | ||
416 | |||
417 | rio_start_card_running(HostP); | ||
418 | |||
419 | rio_dprintk(RIO_DEBUG_BOOT, "Set control port\n"); | ||
420 | |||
421 | /* | ||
422 | ** Now, wait for upto five seconds for the Tp to setup the parmmap | ||
423 | ** pointer: | ||
424 | */ | ||
425 | for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && (readw(&HostP->__ParmMapR) == OldParmMap); wait_count++) { | ||
426 | rio_dprintk(RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n", wait_count, readw(&HostP->__ParmMapR)); | ||
427 | mdelay(100); | ||
428 | |||
429 | } | ||
430 | |||
431 | /* | ||
432 | ** If the parmmap pointer is unchanged, then the host code | ||
433 | ** has crashed & burned in a really spectacular way | ||
434 | */ | ||
435 | if (readw(&HostP->__ParmMapR) == OldParmMap) { | ||
436 | rio_dprintk(RIO_DEBUG_BOOT, "parmmap 0x%x\n", readw(&HostP->__ParmMapR)); | ||
437 | rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); | ||
438 | HostP->Flags &= ~RUN_STATE; | ||
439 | HostP->Flags |= RC_STUFFED; | ||
440 | RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); | ||
441 | continue; | ||
442 | } | ||
443 | |||
444 | rio_dprintk(RIO_DEBUG_BOOT, "Running 0x%x\n", readw(&HostP->__ParmMapR)); | ||
445 | |||
446 | /* | ||
447 | ** Well, the board thought it was OK, and setup its parmmap | ||
448 | ** pointer. For the time being, we will pretend that this | ||
449 | ** board is running, and check out what the error flag says. | ||
450 | */ | ||
451 | |||
452 | /* | ||
453 | ** Grab a 32 bit pointer to the parmmap structure | ||
454 | */ | ||
455 | ParmMapP = (PARM_MAP __iomem *) RIO_PTR(Cad, readw(&HostP->__ParmMapR)); | ||
456 | rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); | ||
457 | ParmMapP = (PARM_MAP __iomem *)(Cad + readw(&HostP->__ParmMapR)); | ||
458 | rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); | ||
459 | |||
460 | /* | ||
461 | ** The links entry should be 0xFFFF; we set it up | ||
462 | ** with a mask to say how many PHBs to use, and | ||
463 | ** which links to use. | ||
464 | */ | ||
465 | if (readw(&ParmMapP->links) != 0xFFFF) { | ||
466 | rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); | ||
467 | rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", readw(&ParmMapP->links)); | ||
468 | HostP->Flags &= ~RUN_STATE; | ||
469 | HostP->Flags |= RC_STUFFED; | ||
470 | RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); | ||
471 | continue; | ||
472 | } | ||
473 | |||
474 | writew(RIO_LINK_ENABLE, &ParmMapP->links); | ||
475 | |||
476 | /* | ||
477 | ** now wait for the card to set all the parmmap->XXX stuff | ||
478 | ** this is a wait of upto two seconds.... | ||
479 | */ | ||
480 | rio_dprintk(RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n", p->RIOConf.StartupTime); | ||
481 | HostP->timeout_id = 0; | ||
482 | for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && !readw(&ParmMapP->init_done); wait_count++) { | ||
483 | rio_dprintk(RIO_DEBUG_BOOT, "Waiting for init_done\n"); | ||
484 | mdelay(100); | ||
485 | } | ||
486 | rio_dprintk(RIO_DEBUG_BOOT, "OK! init_done!\n"); | ||
487 | |||
488 | if (readw(&ParmMapP->error) != E_NO_ERROR || !readw(&ParmMapP->init_done)) { | ||
489 | rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); | ||
490 | rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); | ||
491 | HostP->Flags &= ~RUN_STATE; | ||
492 | HostP->Flags |= RC_STUFFED; | ||
493 | RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); | ||
494 | continue; | ||
495 | } | ||
496 | |||
497 | rio_dprintk(RIO_DEBUG_BOOT, "Got init_done\n"); | ||
498 | |||
499 | /* | ||
500 | ** It runs! It runs! | ||
501 | */ | ||
502 | rio_dprintk(RIO_DEBUG_BOOT, "Host ID %x Running\n", HostP->UniqueNum); | ||
503 | |||
504 | /* | ||
505 | ** set the time period between interrupts. | ||
506 | */ | ||
507 | writew(p->RIOConf.Timer, &ParmMapP->timer); | ||
508 | |||
509 | /* | ||
510 | ** Translate all the 16 bit pointers in the __ParmMapR into | ||
511 | ** 32 bit pointers for the driver in ioremap space. | ||
512 | */ | ||
513 | HostP->ParmMapP = ParmMapP; | ||
514 | HostP->PhbP = (struct PHB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr)); | ||
515 | HostP->RupP = (struct RUP __iomem *) RIO_PTR(Cad, readw(&ParmMapP->rups)); | ||
516 | HostP->PhbNumP = (unsigned short __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr)); | ||
517 | HostP->LinkStrP = (struct LPB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr)); | ||
518 | |||
519 | /* | ||
520 | ** point the UnixRups at the real Rups | ||
521 | */ | ||
522 | for (RupN = 0; RupN < MAX_RUP; RupN++) { | ||
523 | HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN]; | ||
524 | HostP->UnixRups[RupN].Id = RupN + 1; | ||
525 | HostP->UnixRups[RupN].BaseSysPort = NO_PORT; | ||
526 | spin_lock_init(&HostP->UnixRups[RupN].RupLock); | ||
527 | } | ||
528 | |||
529 | for (RupN = 0; RupN < LINKS_PER_UNIT; RupN++) { | ||
530 | HostP->UnixRups[RupN + MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup; | ||
531 | HostP->UnixRups[RupN + MAX_RUP].Id = 0; | ||
532 | HostP->UnixRups[RupN + MAX_RUP].BaseSysPort = NO_PORT; | ||
533 | spin_lock_init(&HostP->UnixRups[RupN + MAX_RUP].RupLock); | ||
534 | } | ||
535 | |||
536 | /* | ||
537 | ** point the PortP->Phbs at the real Phbs | ||
538 | */ | ||
539 | for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) { | ||
540 | if (p->RIOPortp[PortN]->HostP == HostP) { | ||
541 | struct Port *PortP = p->RIOPortp[PortN]; | ||
542 | struct PHB __iomem *PhbP; | ||
543 | /* int oldspl; */ | ||
544 | |||
545 | if (!PortP->Mapped) | ||
546 | continue; | ||
547 | |||
548 | PhbP = &HostP->PhbP[PortP->HostPort]; | ||
549 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
550 | |||
551 | PortP->PhbP = PhbP; | ||
552 | |||
553 | PortP->TxAdd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_add)); | ||
554 | PortP->TxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_start)); | ||
555 | PortP->TxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_end)); | ||
556 | PortP->RxRemove = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_remove)); | ||
557 | PortP->RxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_start)); | ||
558 | PortP->RxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_end)); | ||
559 | |||
560 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
561 | /* | ||
562 | ** point the UnixRup at the base SysPort | ||
563 | */ | ||
564 | if (!(PortN % PORTS_PER_RTA)) | ||
565 | HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | rio_dprintk(RIO_DEBUG_BOOT, "Set the card running... \n"); | ||
570 | /* | ||
571 | ** last thing - show the world that everything is in place | ||
572 | */ | ||
573 | HostP->Flags &= ~RUN_STATE; | ||
574 | HostP->Flags |= RC_RUNNING; | ||
575 | } | ||
576 | /* | ||
577 | ** MPX always uses a poller. This is actually patched into the system | ||
578 | ** configuration and called directly from each clock tick. | ||
579 | ** | ||
580 | */ | ||
581 | p->RIOPolling = 1; | ||
582 | |||
583 | p->RIOSystemUp++; | ||
584 | |||
585 | rio_dprintk(RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec); | ||
586 | func_exit(); | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | |||
591 | |||
592 | /** | ||
593 | * RIOBootRup - Boot an RTA | ||
594 | * @p: rio we are working with | ||
595 | * @Rup: Rup number | ||
596 | * @HostP: host object | ||
597 | * @PacketP: packet to use | ||
598 | * | ||
599 | * If we have successfully processed this boot, then | ||
600 | * return 1. If we havent, then return 0. | ||
601 | */ | ||
602 | |||
603 | int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem *PacketP) | ||
604 | { | ||
605 | struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; | ||
606 | struct PktCmd_M *PktReplyP; | ||
607 | struct CmdBlk *CmdBlkP; | ||
608 | unsigned int sequence; | ||
609 | |||
610 | /* | ||
611 | ** If we haven't been told what to boot, we can't boot it. | ||
612 | */ | ||
613 | if (p->RIONumBootPkts == 0) { | ||
614 | rio_dprintk(RIO_DEBUG_BOOT, "No RTA code to download yet\n"); | ||
615 | return 0; | ||
616 | } | ||
617 | |||
618 | /* | ||
619 | ** Special case of boot completed - if we get one of these then we | ||
620 | ** don't need a command block. For all other cases we do, so handle | ||
621 | ** this first and then get a command block, then handle every other | ||
622 | ** case, relinquishing the command block if disaster strikes! | ||
623 | */ | ||
624 | if ((readb(&PacketP->len) & PKT_CMD_BIT) && (readb(&PktCmdP->Command) == BOOT_COMPLETED)) | ||
625 | return RIOBootComplete(p, HostP, Rup, PktCmdP); | ||
626 | |||
627 | /* | ||
628 | ** Try to allocate a command block. This is in kernel space | ||
629 | */ | ||
630 | if (!(CmdBlkP = RIOGetCmdBlk())) { | ||
631 | rio_dprintk(RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n"); | ||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | /* | ||
636 | ** Fill in the default info on the command block | ||
637 | */ | ||
638 | CmdBlkP->Packet.dest_unit = Rup < (unsigned short) MAX_RUP ? Rup : 0; | ||
639 | CmdBlkP->Packet.dest_port = BOOT_RUP; | ||
640 | CmdBlkP->Packet.src_unit = 0; | ||
641 | CmdBlkP->Packet.src_port = BOOT_RUP; | ||
642 | |||
643 | CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; | ||
644 | PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; | ||
645 | |||
646 | /* | ||
647 | ** process COMMANDS on the boot rup! | ||
648 | */ | ||
649 | if (readb(&PacketP->len) & PKT_CMD_BIT) { | ||
650 | /* | ||
651 | ** We only expect one type of command - a BOOT_REQUEST! | ||
652 | */ | ||
653 | if (readb(&PktCmdP->Command) != BOOT_REQUEST) { | ||
654 | rio_dprintk(RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %Zd\n", readb(&PktCmdP->Command), Rup, HostP - p->RIOHosts); | ||
655 | RIOFreeCmdBlk(CmdBlkP); | ||
656 | return 1; | ||
657 | } | ||
658 | |||
659 | /* | ||
660 | ** Build a Boot Sequence command block | ||
661 | ** | ||
662 | ** We no longer need to use "Boot Mode", we'll always allow | ||
663 | ** boot requests - the boot will not complete if the device | ||
664 | ** appears in the bindings table. | ||
665 | ** | ||
666 | ** We'll just (always) set the command field in packet reply | ||
667 | ** to allow an attempted boot sequence : | ||
668 | */ | ||
669 | PktReplyP->Command = BOOT_SEQUENCE; | ||
670 | |||
671 | PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts; | ||
672 | PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase; | ||
673 | PktReplyP->BootSequence.CodeSize = p->RIOBootCount; | ||
674 | |||
675 | CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT; | ||
676 | |||
677 | memcpy((void *) &CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN], "BOOT", 4); | ||
678 | |||
679 | rio_dprintk(RIO_DEBUG_BOOT, "Boot RTA on Host %Zd Rup %d - %d (0x%x) packets to 0x%x\n", HostP - p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, p->RIOConf.RtaLoadBase); | ||
680 | |||
681 | /* | ||
682 | ** If this host is in slave mode, send the RTA an invalid boot | ||
683 | ** sequence command block to force it to kill the boot. We wait | ||
684 | ** for half a second before sending this packet to prevent the RTA | ||
685 | ** attempting to boot too often. The master host should then grab | ||
686 | ** the RTA and make it its own. | ||
687 | */ | ||
688 | p->RIOBooting++; | ||
689 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); | ||
690 | return 1; | ||
691 | } | ||
692 | |||
693 | /* | ||
694 | ** It is a request for boot data. | ||
695 | */ | ||
696 | sequence = readw(&PktCmdP->Sequence); | ||
697 | |||
698 | rio_dprintk(RIO_DEBUG_BOOT, "Boot block %d on Host %Zd Rup%d\n", sequence, HostP - p->RIOHosts, Rup); | ||
699 | |||
700 | if (sequence >= p->RIONumBootPkts) { | ||
701 | rio_dprintk(RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, p->RIONumBootPkts); | ||
702 | } | ||
703 | |||
704 | PktReplyP->Sequence = sequence; | ||
705 | memcpy(PktReplyP->BootData, p->RIOBootPackets[p->RIONumBootPkts - sequence - 1], RTA_BOOT_DATA_SIZE); | ||
706 | CmdBlkP->Packet.len = PKT_MAX_DATA_LEN; | ||
707 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); | ||
708 | return 1; | ||
709 | } | ||
710 | |||
711 | /** | ||
712 | * RIOBootComplete - RTA boot is done | ||
713 | * @p: RIO we are working with | ||
714 | * @HostP: Host structure | ||
715 | * @Rup: RUP being used | ||
716 | * @PktCmdP: Packet command that was used | ||
717 | * | ||
718 | * This function is called when an RTA been booted. | ||
719 | * If booted by a host, HostP->HostUniqueNum is the booting host. | ||
720 | * If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA. | ||
721 | * RtaUniq is the booted RTA. | ||
722 | */ | ||
723 | |||
724 | static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP) | ||
725 | { | ||
726 | struct Map *MapP = NULL; | ||
727 | struct Map *MapP2 = NULL; | ||
728 | int Flag; | ||
729 | int found; | ||
730 | int host, rta; | ||
731 | int EmptySlot = -1; | ||
732 | int entry, entry2; | ||
733 | char *MyType, *MyName; | ||
734 | unsigned int MyLink; | ||
735 | unsigned short RtaType; | ||
736 | u32 RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); | ||
737 | |||
738 | p->RIOBooting = 0; | ||
739 | |||
740 | rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting); | ||
741 | |||
742 | /* | ||
743 | ** Determine type of unit (16/8 port RTA). | ||
744 | */ | ||
745 | |||
746 | RtaType = GetUnitType(RtaUniq); | ||
747 | if (Rup >= (unsigned short) MAX_RUP) | ||
748 | rio_dprintk(RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n", HostP->Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); | ||
749 | else | ||
750 | rio_dprintk(RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n", HostP->Mapping[Rup].Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); | ||
751 | |||
752 | rio_dprintk(RIO_DEBUG_BOOT, "UniqNum is 0x%x\n", RtaUniq); | ||
753 | |||
754 | if (RtaUniq == 0x00000000 || RtaUniq == 0xffffffff) { | ||
755 | rio_dprintk(RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n"); | ||
756 | return 1; | ||
757 | } | ||
758 | |||
759 | /* | ||
760 | ** If this RTA has just booted an RTA which doesn't belong to this | ||
761 | ** system, or the system is in slave mode, do not attempt to create | ||
762 | ** a new table entry for it. | ||
763 | */ | ||
764 | |||
765 | if (!RIOBootOk(p, HostP, RtaUniq)) { | ||
766 | MyLink = readb(&PktCmdP->LinkNum); | ||
767 | if (Rup < (unsigned short) MAX_RUP) { | ||
768 | /* | ||
769 | ** RtaUniq was clone booted (by this RTA). Instruct this RTA | ||
770 | ** to hold off further attempts to boot on this link for 30 | ||
771 | ** seconds. | ||
772 | */ | ||
773 | if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink)) { | ||
774 | rio_dprintk(RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n", 'A' + MyLink); | ||
775 | } | ||
776 | } else | ||
777 | /* | ||
778 | ** RtaUniq was booted by this host. Set the booting link | ||
779 | ** to hold off for 30 seconds to give another unit a | ||
780 | ** chance to boot it. | ||
781 | */ | ||
782 | writew(30, &HostP->LinkStrP[MyLink].WaitNoBoot); | ||
783 | rio_dprintk(RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n", RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum); | ||
784 | return 1; | ||
785 | } | ||
786 | |||
787 | /* | ||
788 | ** Check for a SLOT_IN_USE entry for this RTA attached to the | ||
789 | ** current host card in the driver table. | ||
790 | ** | ||
791 | ** If it exists, make a note that we have booted it. Other parts of | ||
792 | ** the driver are interested in this information at a later date, | ||
793 | ** in particular when the booting RTA asks for an ID for this unit, | ||
794 | ** we must have set the BOOTED flag, and the NEWBOOT flag is used | ||
795 | ** to force an open on any ports that where previously open on this | ||
796 | ** unit. | ||
797 | */ | ||
798 | for (entry = 0; entry < MAX_RUP; entry++) { | ||
799 | unsigned int sysport; | ||
800 | |||
801 | if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { | ||
802 | HostP->Mapping[entry].Flags |= RTA_BOOTED | RTA_NEWBOOT; | ||
803 | if ((sysport = HostP->Mapping[entry].SysPort) != NO_PORT) { | ||
804 | if (sysport < p->RIOFirstPortsBooted) | ||
805 | p->RIOFirstPortsBooted = sysport; | ||
806 | if (sysport > p->RIOLastPortsBooted) | ||
807 | p->RIOLastPortsBooted = sysport; | ||
808 | /* | ||
809 | ** For a 16 port RTA, check the second bank of 8 ports | ||
810 | */ | ||
811 | if (RtaType == TYPE_RTA16) { | ||
812 | entry2 = HostP->Mapping[entry].ID2 - 1; | ||
813 | HostP->Mapping[entry2].Flags |= RTA_BOOTED | RTA_NEWBOOT; | ||
814 | sysport = HostP->Mapping[entry2].SysPort; | ||
815 | if (sysport < p->RIOFirstPortsBooted) | ||
816 | p->RIOFirstPortsBooted = sysport; | ||
817 | if (sysport > p->RIOLastPortsBooted) | ||
818 | p->RIOLastPortsBooted = sysport; | ||
819 | } | ||
820 | } | ||
821 | if (RtaType == TYPE_RTA16) | ||
822 | rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n", entry + 1, entry2 + 1); | ||
823 | else | ||
824 | rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given ID %d\n", entry + 1); | ||
825 | return 1; | ||
826 | } | ||
827 | } | ||
828 | |||
829 | rio_dprintk(RIO_DEBUG_BOOT, "RTA not configured for this host\n"); | ||
830 | |||
831 | if (Rup >= (unsigned short) MAX_RUP) { | ||
832 | /* | ||
833 | ** It was a host that did the booting | ||
834 | */ | ||
835 | MyType = "Host"; | ||
836 | MyName = HostP->Name; | ||
837 | } else { | ||
838 | /* | ||
839 | ** It was an RTA that did the booting | ||
840 | */ | ||
841 | MyType = "RTA"; | ||
842 | MyName = HostP->Mapping[Rup].Name; | ||
843 | } | ||
844 | MyLink = readb(&PktCmdP->LinkNum); | ||
845 | |||
846 | /* | ||
847 | ** There is no SLOT_IN_USE entry for this RTA attached to the current | ||
848 | ** host card in the driver table. | ||
849 | ** | ||
850 | ** Check for a SLOT_TENTATIVE entry for this RTA attached to the | ||
851 | ** current host card in the driver table. | ||
852 | ** | ||
853 | ** If we find one, then we re-use that slot. | ||
854 | */ | ||
855 | for (entry = 0; entry < MAX_RUP; entry++) { | ||
856 | if ((HostP->Mapping[entry].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { | ||
857 | if (RtaType == TYPE_RTA16) { | ||
858 | entry2 = HostP->Mapping[entry].ID2 - 1; | ||
859 | if ((HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq)) | ||
860 | rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n", entry, entry2); | ||
861 | else | ||
862 | continue; | ||
863 | } else | ||
864 | rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n", entry); | ||
865 | if (!p->RIONoMessage) | ||
866 | printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); | ||
867 | return 1; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | /* | ||
872 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | ||
873 | ** attached to the current host card in the driver table. | ||
874 | ** | ||
875 | ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another | ||
876 | ** host for this RTA in the driver table. | ||
877 | ** | ||
878 | ** For a SLOT_IN_USE entry on another host, we need to delete the RTA | ||
879 | ** entry from the other host and add it to this host (using some of | ||
880 | ** the functions from table.c which do this). | ||
881 | ** For a SLOT_TENTATIVE entry on another host, we must cope with the | ||
882 | ** following scenario: | ||
883 | ** | ||
884 | ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry | ||
885 | ** in table) | ||
886 | ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE | ||
887 | ** entries) | ||
888 | ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE) | ||
889 | ** + Unplug RTA and plug back into host A. | ||
890 | ** + Configure RTA on host A. We now have the same RTA configured | ||
891 | ** with different ports on two different hosts. | ||
892 | */ | ||
893 | rio_dprintk(RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq); | ||
894 | found = 0; | ||
895 | Flag = 0; /* Convince the compiler this variable is initialized */ | ||
896 | for (host = 0; !found && (host < p->RIONumHosts); host++) { | ||
897 | for (rta = 0; rta < MAX_RUP; rta++) { | ||
898 | if ((p->RIOHosts[host].Mapping[rta].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (p->RIOHosts[host].Mapping[rta].RtaUniqueNum == RtaUniq)) { | ||
899 | Flag = p->RIOHosts[host].Mapping[rta].Flags; | ||
900 | MapP = &p->RIOHosts[host].Mapping[rta]; | ||
901 | if (RtaType == TYPE_RTA16) { | ||
902 | MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1]; | ||
903 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n", rta + 1, MapP->ID2, p->RIOHosts[host].Name); | ||
904 | } else | ||
905 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n", rta + 1, p->RIOHosts[host].Name); | ||
906 | found = 1; | ||
907 | break; | ||
908 | } | ||
909 | } | ||
910 | } | ||
911 | |||
912 | /* | ||
913 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | ||
914 | ** attached to the current host card in the driver table. | ||
915 | ** | ||
916 | ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on | ||
917 | ** another host for this RTA in the driver table... | ||
918 | ** | ||
919 | ** Check for a SLOT_IN_USE entry for this RTA in the config table. | ||
920 | */ | ||
921 | if (!MapP) { | ||
922 | rio_dprintk(RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n", RtaUniq); | ||
923 | for (rta = 0; rta < TOTAL_MAP_ENTRIES; rta++) { | ||
924 | rio_dprintk(RIO_DEBUG_BOOT, "Check table entry %d (%x)", rta, p->RIOSavedTable[rta].RtaUniqueNum); | ||
925 | |||
926 | if ((p->RIOSavedTable[rta].Flags & SLOT_IN_USE) && (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq)) { | ||
927 | MapP = &p->RIOSavedTable[rta]; | ||
928 | Flag = p->RIOSavedTable[rta].Flags; | ||
929 | if (RtaType == TYPE_RTA16) { | ||
930 | for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES; entry2++) { | ||
931 | if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq) | ||
932 | break; | ||
933 | } | ||
934 | MapP2 = &p->RIOSavedTable[entry2]; | ||
935 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n", rta, entry2); | ||
936 | } else | ||
937 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta); | ||
938 | break; | ||
939 | } | ||
940 | } | ||
941 | } | ||
942 | |||
943 | /* | ||
944 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | ||
945 | ** attached to the current host card in the driver table. | ||
946 | ** | ||
947 | ** We may have found a SLOT_IN_USE entry on another host for this | ||
948 | ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry | ||
949 | ** on another host for this RTA in the driver table. | ||
950 | ** | ||
951 | ** Check the driver table for room to fit this newly discovered RTA. | ||
952 | ** RIOFindFreeID() first looks for free slots and if it does not | ||
953 | ** find any free slots it will then attempt to oust any | ||
954 | ** tentative entry in the table. | ||
955 | */ | ||
956 | EmptySlot = 1; | ||
957 | if (RtaType == TYPE_RTA16) { | ||
958 | if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0) { | ||
959 | RIODefaultName(p, HostP, entry); | ||
960 | rio_fill_host_slot(entry, entry2, RtaUniq, HostP); | ||
961 | EmptySlot = 0; | ||
962 | } | ||
963 | } else { | ||
964 | if (RIOFindFreeID(p, HostP, &entry, NULL) == 0) { | ||
965 | RIODefaultName(p, HostP, entry); | ||
966 | rio_fill_host_slot(entry, 0, RtaUniq, HostP); | ||
967 | EmptySlot = 0; | ||
968 | } | ||
969 | } | ||
970 | |||
971 | /* | ||
972 | ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA | ||
973 | ** attached to the current host card in the driver table. | ||
974 | ** | ||
975 | ** If we found a SLOT_IN_USE entry on another host for this | ||
976 | ** RTA in the config or driver table, and there are enough free | ||
977 | ** slots in the driver table, then we need to move it over and | ||
978 | ** delete it from the other host. | ||
979 | ** If we found a SLOT_TENTATIVE entry on another host for this | ||
980 | ** RTA in the driver table, just delete the other host entry. | ||
981 | */ | ||
982 | if (EmptySlot == 0) { | ||
983 | if (MapP) { | ||
984 | if (Flag & SLOT_IN_USE) { | ||
985 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA configured on another host - move entry to current host (1)\n"); | ||
986 | HostP->Mapping[entry].SysPort = MapP->SysPort; | ||
987 | memcpy(HostP->Mapping[entry].Name, MapP->Name, MAX_NAME_LEN); | ||
988 | HostP->Mapping[entry].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; | ||
989 | RIOReMapPorts(p, HostP, &HostP->Mapping[entry]); | ||
990 | if (HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted) | ||
991 | p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort; | ||
992 | if (HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted) | ||
993 | p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort; | ||
994 | rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) MapP->SysPort, MapP->Name); | ||
995 | } else { | ||
996 | rio_dprintk(RIO_DEBUG_BOOT, "This RTA has a tentative entry on another host - delete that entry (1)\n"); | ||
997 | HostP->Mapping[entry].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; | ||
998 | } | ||
999 | if (RtaType == TYPE_RTA16) { | ||
1000 | if (Flag & SLOT_IN_USE) { | ||
1001 | HostP->Mapping[entry2].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; | ||
1002 | HostP->Mapping[entry2].SysPort = MapP2->SysPort; | ||
1003 | /* | ||
1004 | ** Map second block of ttys for 16 port RTA | ||
1005 | */ | ||
1006 | RIOReMapPorts(p, HostP, &HostP->Mapping[entry2]); | ||
1007 | if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted) | ||
1008 | p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort; | ||
1009 | if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted) | ||
1010 | p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort; | ||
1011 | rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) HostP->Mapping[entry2].SysPort, HostP->Mapping[entry].Name); | ||
1012 | } else | ||
1013 | HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; | ||
1014 | memset(MapP2, 0, sizeof(struct Map)); | ||
1015 | } | ||
1016 | memset(MapP, 0, sizeof(struct Map)); | ||
1017 | if (!p->RIONoMessage) | ||
1018 | printk("An orphaned RTA has been adopted by %s '%s' (%c).\n", MyType, MyName, MyLink + 'A'); | ||
1019 | } else if (!p->RIONoMessage) | ||
1020 | printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); | ||
1021 | RIOSetChange(p); | ||
1022 | return 1; | ||
1023 | } | ||
1024 | |||
1025 | /* | ||
1026 | ** There is no room in the driver table to make an entry for the | ||
1027 | ** booted RTA. Keep a note of its Uniq Num in the overflow table, | ||
1028 | ** so we can ignore it's ID requests. | ||
1029 | */ | ||
1030 | if (!p->RIONoMessage) | ||
1031 | printk("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n", MyType, MyName, MyLink + 'A'); | ||
1032 | for (entry = 0; entry < HostP->NumExtraBooted; entry++) { | ||
1033 | if (HostP->ExtraUnits[entry] == RtaUniq) { | ||
1034 | /* | ||
1035 | ** already got it! | ||
1036 | */ | ||
1037 | return 1; | ||
1038 | } | ||
1039 | } | ||
1040 | /* | ||
1041 | ** If there is room, add the unit to the list of extras | ||
1042 | */ | ||
1043 | if (HostP->NumExtraBooted < MAX_EXTRA_UNITS) | ||
1044 | HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq; | ||
1045 | return 1; | ||
1046 | } | ||
1047 | |||
1048 | |||
1049 | /* | ||
1050 | ** If the RTA or its host appears in the RIOBindTab[] structure then | ||
1051 | ** we mustn't boot the RTA and should return 0. | ||
1052 | ** This operation is slightly different from the other drivers for RIO | ||
1053 | ** in that this is designed to work with the new utilities | ||
1054 | ** not config.rio and is FAR SIMPLER. | ||
1055 | ** We no longer support the RIOBootMode variable. It is all done from the | ||
1056 | ** "boot/noboot" field in the rio.cf file. | ||
1057 | */ | ||
1058 | int RIOBootOk(struct rio_info *p, struct Host *HostP, unsigned long RtaUniq) | ||
1059 | { | ||
1060 | int Entry; | ||
1061 | unsigned int HostUniq = HostP->UniqueNum; | ||
1062 | |||
1063 | /* | ||
1064 | ** Search bindings table for RTA or its parent. | ||
1065 | ** If it exists, return 0, else 1. | ||
1066 | */ | ||
1067 | for (Entry = 0; (Entry < MAX_RTA_BINDINGS) && (p->RIOBindTab[Entry] != 0); Entry++) { | ||
1068 | if ((p->RIOBindTab[Entry] == HostUniq) || (p->RIOBindTab[Entry] == RtaUniq)) | ||
1069 | return 0; | ||
1070 | } | ||
1071 | return 1; | ||
1072 | } | ||
1073 | |||
1074 | /* | ||
1075 | ** Make an empty slot tentative. If this is a 16 port RTA, make both | ||
1076 | ** slots tentative, and the second one RTA_SECOND_SLOT as well. | ||
1077 | */ | ||
1078 | |||
1079 | void rio_fill_host_slot(int entry, int entry2, unsigned int rta_uniq, struct Host *host) | ||
1080 | { | ||
1081 | int link; | ||
1082 | |||
1083 | rio_dprintk(RIO_DEBUG_BOOT, "rio_fill_host_slot(%d, %d, 0x%x...)\n", entry, entry2, rta_uniq); | ||
1084 | |||
1085 | host->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE); | ||
1086 | host->Mapping[entry].SysPort = NO_PORT; | ||
1087 | host->Mapping[entry].RtaUniqueNum = rta_uniq; | ||
1088 | host->Mapping[entry].HostUniqueNum = host->UniqueNum; | ||
1089 | host->Mapping[entry].ID = entry + 1; | ||
1090 | host->Mapping[entry].ID2 = 0; | ||
1091 | if (entry2) { | ||
1092 | host->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE | RTA16_SECOND_SLOT); | ||
1093 | host->Mapping[entry2].SysPort = NO_PORT; | ||
1094 | host->Mapping[entry2].RtaUniqueNum = rta_uniq; | ||
1095 | host->Mapping[entry2].HostUniqueNum = host->UniqueNum; | ||
1096 | host->Mapping[entry2].Name[0] = '\0'; | ||
1097 | host->Mapping[entry2].ID = entry2 + 1; | ||
1098 | host->Mapping[entry2].ID2 = entry + 1; | ||
1099 | host->Mapping[entry].ID2 = entry2 + 1; | ||
1100 | } | ||
1101 | /* | ||
1102 | ** Must set these up, so that utilities show | ||
1103 | ** topology of 16 port RTAs correctly | ||
1104 | */ | ||
1105 | for (link = 0; link < LINKS_PER_UNIT; link++) { | ||
1106 | host->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT; | ||
1107 | host->Mapping[entry].Topology[link].Link = NO_LINK; | ||
1108 | if (entry2) { | ||
1109 | host->Mapping[entry2].Topology[link].Unit = ROUTE_DISCONNECT; | ||
1110 | host->Mapping[entry2].Topology[link].Link = NO_LINK; | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c deleted file mode 100644 index f121357e5af0..000000000000 --- a/drivers/char/rio/riocmd.c +++ /dev/null | |||
@@ -1,939 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** ported from the existing SCO driver source | ||
6 | ** | ||
7 | * | ||
8 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | ** | ||
24 | ** Module : riocmd.c | ||
25 | ** SID : 1.2 | ||
26 | ** Last Modified : 11/6/98 10:33:41 | ||
27 | ** Retrieved : 11/6/98 10:33:49 | ||
28 | ** | ||
29 | ** ident @(#)riocmd.c 1.2 | ||
30 | ** | ||
31 | ** ----------------------------------------------------------------------------- | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/errno.h> | ||
38 | #include <linux/tty.h> | ||
39 | #include <asm/io.h> | ||
40 | #include <asm/system.h> | ||
41 | #include <asm/string.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | |||
44 | #include <linux/termios.h> | ||
45 | #include <linux/serial.h> | ||
46 | |||
47 | #include <linux/generic_serial.h> | ||
48 | |||
49 | #include "linux_compat.h" | ||
50 | #include "rio_linux.h" | ||
51 | #include "pkt.h" | ||
52 | #include "daemon.h" | ||
53 | #include "rio.h" | ||
54 | #include "riospace.h" | ||
55 | #include "cmdpkt.h" | ||
56 | #include "map.h" | ||
57 | #include "rup.h" | ||
58 | #include "port.h" | ||
59 | #include "riodrvr.h" | ||
60 | #include "rioinfo.h" | ||
61 | #include "func.h" | ||
62 | #include "errors.h" | ||
63 | #include "pci.h" | ||
64 | |||
65 | #include "parmmap.h" | ||
66 | #include "unixrup.h" | ||
67 | #include "board.h" | ||
68 | #include "host.h" | ||
69 | #include "phb.h" | ||
70 | #include "link.h" | ||
71 | #include "cmdblk.h" | ||
72 | #include "route.h" | ||
73 | #include "cirrus.h" | ||
74 | |||
75 | |||
76 | static struct IdentifyRta IdRta; | ||
77 | static struct KillNeighbour KillUnit; | ||
78 | |||
79 | int RIOFoadRta(struct Host *HostP, struct Map *MapP) | ||
80 | { | ||
81 | struct CmdBlk *CmdBlkP; | ||
82 | |||
83 | rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA\n"); | ||
84 | |||
85 | CmdBlkP = RIOGetCmdBlk(); | ||
86 | |||
87 | if (!CmdBlkP) { | ||
88 | rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n"); | ||
89 | return -ENXIO; | ||
90 | } | ||
91 | |||
92 | CmdBlkP->Packet.dest_unit = MapP->ID; | ||
93 | CmdBlkP->Packet.dest_port = BOOT_RUP; | ||
94 | CmdBlkP->Packet.src_unit = 0; | ||
95 | CmdBlkP->Packet.src_port = BOOT_RUP; | ||
96 | CmdBlkP->Packet.len = 0x84; | ||
97 | CmdBlkP->Packet.data[0] = IFOAD; | ||
98 | CmdBlkP->Packet.data[1] = 0; | ||
99 | CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF; | ||
100 | CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF; | ||
101 | |||
102 | if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { | ||
103 | rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n"); | ||
104 | return -EIO; | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int RIOZombieRta(struct Host *HostP, struct Map *MapP) | ||
110 | { | ||
111 | struct CmdBlk *CmdBlkP; | ||
112 | |||
113 | rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA\n"); | ||
114 | |||
115 | CmdBlkP = RIOGetCmdBlk(); | ||
116 | |||
117 | if (!CmdBlkP) { | ||
118 | rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n"); | ||
119 | return -ENXIO; | ||
120 | } | ||
121 | |||
122 | CmdBlkP->Packet.dest_unit = MapP->ID; | ||
123 | CmdBlkP->Packet.dest_port = BOOT_RUP; | ||
124 | CmdBlkP->Packet.src_unit = 0; | ||
125 | CmdBlkP->Packet.src_port = BOOT_RUP; | ||
126 | CmdBlkP->Packet.len = 0x84; | ||
127 | CmdBlkP->Packet.data[0] = ZOMBIE; | ||
128 | CmdBlkP->Packet.data[1] = 0; | ||
129 | CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF; | ||
130 | CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF; | ||
131 | |||
132 | if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { | ||
133 | rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n"); | ||
134 | return -EIO; | ||
135 | } | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | int RIOCommandRta(struct rio_info *p, unsigned long RtaUnique, int (*func) (struct Host * HostP, struct Map * MapP)) | ||
140 | { | ||
141 | unsigned int Host; | ||
142 | |||
143 | rio_dprintk(RIO_DEBUG_CMD, "Command RTA 0x%lx func %p\n", RtaUnique, func); | ||
144 | |||
145 | if (!RtaUnique) | ||
146 | return (0); | ||
147 | |||
148 | for (Host = 0; Host < p->RIONumHosts; Host++) { | ||
149 | unsigned int Rta; | ||
150 | struct Host *HostP = &p->RIOHosts[Host]; | ||
151 | |||
152 | for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { | ||
153 | struct Map *MapP = &HostP->Mapping[Rta]; | ||
154 | |||
155 | if (MapP->RtaUniqueNum == RtaUnique) { | ||
156 | uint Link; | ||
157 | |||
158 | /* | ||
159 | ** now, lets just check we have a route to it... | ||
160 | ** IF the routing stuff is working, then one of the | ||
161 | ** topology entries for this unit will have a legit | ||
162 | ** route *somewhere*. We care not where - if its got | ||
163 | ** any connections, we can get to it. | ||
164 | */ | ||
165 | for (Link = 0; Link < LINKS_PER_UNIT; Link++) { | ||
166 | if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { | ||
167 | /* | ||
168 | ** Its worth trying the operation... | ||
169 | */ | ||
170 | return (*func) (HostP, MapP); | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | return -ENXIO; | ||
177 | } | ||
178 | |||
179 | |||
180 | int RIOIdentifyRta(struct rio_info *p, void __user * arg) | ||
181 | { | ||
182 | unsigned int Host; | ||
183 | |||
184 | if (copy_from_user(&IdRta, arg, sizeof(IdRta))) { | ||
185 | rio_dprintk(RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n"); | ||
186 | p->RIOError.Error = COPYIN_FAILED; | ||
187 | return -EFAULT; | ||
188 | } | ||
189 | |||
190 | for (Host = 0; Host < p->RIONumHosts; Host++) { | ||
191 | unsigned int Rta; | ||
192 | struct Host *HostP = &p->RIOHosts[Host]; | ||
193 | |||
194 | for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { | ||
195 | struct Map *MapP = &HostP->Mapping[Rta]; | ||
196 | |||
197 | if (MapP->RtaUniqueNum == IdRta.RtaUnique) { | ||
198 | uint Link; | ||
199 | /* | ||
200 | ** now, lets just check we have a route to it... | ||
201 | ** IF the routing stuff is working, then one of the | ||
202 | ** topology entries for this unit will have a legit | ||
203 | ** route *somewhere*. We care not where - if its got | ||
204 | ** any connections, we can get to it. | ||
205 | */ | ||
206 | for (Link = 0; Link < LINKS_PER_UNIT; Link++) { | ||
207 | if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { | ||
208 | /* | ||
209 | ** Its worth trying the operation... | ||
210 | */ | ||
211 | struct CmdBlk *CmdBlkP; | ||
212 | |||
213 | rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA\n"); | ||
214 | |||
215 | CmdBlkP = RIOGetCmdBlk(); | ||
216 | |||
217 | if (!CmdBlkP) { | ||
218 | rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n"); | ||
219 | return -ENXIO; | ||
220 | } | ||
221 | |||
222 | CmdBlkP->Packet.dest_unit = MapP->ID; | ||
223 | CmdBlkP->Packet.dest_port = BOOT_RUP; | ||
224 | CmdBlkP->Packet.src_unit = 0; | ||
225 | CmdBlkP->Packet.src_port = BOOT_RUP; | ||
226 | CmdBlkP->Packet.len = 0x84; | ||
227 | CmdBlkP->Packet.data[0] = IDENTIFY; | ||
228 | CmdBlkP->Packet.data[1] = 0; | ||
229 | CmdBlkP->Packet.data[2] = IdRta.ID; | ||
230 | |||
231 | if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { | ||
232 | rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n"); | ||
233 | return -EIO; | ||
234 | } | ||
235 | return 0; | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | return -ENOENT; | ||
242 | } | ||
243 | |||
244 | |||
245 | int RIOKillNeighbour(struct rio_info *p, void __user * arg) | ||
246 | { | ||
247 | uint Host; | ||
248 | uint ID; | ||
249 | struct Host *HostP; | ||
250 | struct CmdBlk *CmdBlkP; | ||
251 | |||
252 | rio_dprintk(RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n"); | ||
253 | |||
254 | if (copy_from_user(&KillUnit, arg, sizeof(KillUnit))) { | ||
255 | rio_dprintk(RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n"); | ||
256 | p->RIOError.Error = COPYIN_FAILED; | ||
257 | return -EFAULT; | ||
258 | } | ||
259 | |||
260 | if (KillUnit.Link > 3) | ||
261 | return -ENXIO; | ||
262 | |||
263 | CmdBlkP = RIOGetCmdBlk(); | ||
264 | |||
265 | if (!CmdBlkP) { | ||
266 | rio_dprintk(RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n"); | ||
267 | return -ENXIO; | ||
268 | } | ||
269 | |||
270 | CmdBlkP->Packet.dest_unit = 0; | ||
271 | CmdBlkP->Packet.src_unit = 0; | ||
272 | CmdBlkP->Packet.dest_port = BOOT_RUP; | ||
273 | CmdBlkP->Packet.src_port = BOOT_RUP; | ||
274 | CmdBlkP->Packet.len = 0x84; | ||
275 | CmdBlkP->Packet.data[0] = UFOAD; | ||
276 | CmdBlkP->Packet.data[1] = KillUnit.Link; | ||
277 | CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF; | ||
278 | CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF; | ||
279 | |||
280 | for (Host = 0; Host < p->RIONumHosts; Host++) { | ||
281 | ID = 0; | ||
282 | HostP = &p->RIOHosts[Host]; | ||
283 | |||
284 | if (HostP->UniqueNum == KillUnit.UniqueNum) { | ||
285 | if (RIOQueueCmdBlk(HostP, RTAS_PER_HOST + KillUnit.Link, CmdBlkP) == RIO_FAIL) { | ||
286 | rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); | ||
287 | return -EIO; | ||
288 | } | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | for (ID = 0; ID < RTAS_PER_HOST; ID++) { | ||
293 | if (HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum) { | ||
294 | CmdBlkP->Packet.dest_unit = ID + 1; | ||
295 | if (RIOQueueCmdBlk(HostP, ID, CmdBlkP) == RIO_FAIL) { | ||
296 | rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); | ||
297 | return -EIO; | ||
298 | } | ||
299 | return 0; | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | RIOFreeCmdBlk(CmdBlkP); | ||
304 | return -ENXIO; | ||
305 | } | ||
306 | |||
307 | int RIOSuspendBootRta(struct Host *HostP, int ID, int Link) | ||
308 | { | ||
309 | struct CmdBlk *CmdBlkP; | ||
310 | |||
311 | rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link); | ||
312 | |||
313 | CmdBlkP = RIOGetCmdBlk(); | ||
314 | |||
315 | if (!CmdBlkP) { | ||
316 | rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n"); | ||
317 | return -ENXIO; | ||
318 | } | ||
319 | |||
320 | CmdBlkP->Packet.dest_unit = ID; | ||
321 | CmdBlkP->Packet.dest_port = BOOT_RUP; | ||
322 | CmdBlkP->Packet.src_unit = 0; | ||
323 | CmdBlkP->Packet.src_port = BOOT_RUP; | ||
324 | CmdBlkP->Packet.len = 0x84; | ||
325 | CmdBlkP->Packet.data[0] = IWAIT; | ||
326 | CmdBlkP->Packet.data[1] = Link; | ||
327 | CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF; | ||
328 | CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF; | ||
329 | |||
330 | if (RIOQueueCmdBlk(HostP, ID - 1, CmdBlkP) == RIO_FAIL) { | ||
331 | rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n"); | ||
332 | return -EIO; | ||
333 | } | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | int RIOFoadWakeup(struct rio_info *p) | ||
338 | { | ||
339 | int port; | ||
340 | struct Port *PortP; | ||
341 | unsigned long flags; | ||
342 | |||
343 | for (port = 0; port < RIO_PORTS; port++) { | ||
344 | PortP = p->RIOPortp[port]; | ||
345 | |||
346 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
347 | PortP->Config = 0; | ||
348 | PortP->State = 0; | ||
349 | PortP->InUse = NOT_INUSE; | ||
350 | PortP->PortState = 0; | ||
351 | PortP->FlushCmdBodge = 0; | ||
352 | PortP->ModemLines = 0; | ||
353 | PortP->ModemState = 0; | ||
354 | PortP->CookMode = 0; | ||
355 | PortP->ParamSem = 0; | ||
356 | PortP->Mapped = 0; | ||
357 | PortP->WflushFlag = 0; | ||
358 | PortP->MagicFlags = 0; | ||
359 | PortP->RxDataStart = 0; | ||
360 | PortP->TxBufferIn = 0; | ||
361 | PortP->TxBufferOut = 0; | ||
362 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
363 | } | ||
364 | return (0); | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | ** Incoming command on the COMMAND_RUP to be processed. | ||
369 | */ | ||
370 | static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP) | ||
371 | { | ||
372 | struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data; | ||
373 | struct Port *PortP; | ||
374 | struct UnixRup *UnixRupP; | ||
375 | unsigned short SysPort; | ||
376 | unsigned short ReportedModemStatus; | ||
377 | unsigned short rup; | ||
378 | unsigned short subCommand; | ||
379 | unsigned long flags; | ||
380 | |||
381 | func_enter(); | ||
382 | |||
383 | /* | ||
384 | ** 16 port RTA note: | ||
385 | ** Command rup packets coming from the RTA will have pkt->data[1] (which | ||
386 | ** translates to PktCmdP->PhbNum) set to the host port number for the | ||
387 | ** particular unit. To access the correct BaseSysPort for a 16 port RTA, | ||
388 | ** we can use PhbNum to get the rup number for the appropriate 8 port | ||
389 | ** block (for the first block, this should be equal to 'Rup'). | ||
390 | */ | ||
391 | rup = readb(&PktCmdP->PhbNum) / (unsigned short) PORTS_PER_RTA; | ||
392 | UnixRupP = &HostP->UnixRups[rup]; | ||
393 | SysPort = UnixRupP->BaseSysPort + (readb(&PktCmdP->PhbNum) % (unsigned short) PORTS_PER_RTA); | ||
394 | rio_dprintk(RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort); | ||
395 | |||
396 | if (UnixRupP->BaseSysPort == NO_PORT) { | ||
397 | rio_dprintk(RIO_DEBUG_CMD, "OBSCURE ERROR!\n"); | ||
398 | rio_dprintk(RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"); | ||
399 | rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Host number %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name); | ||
400 | rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup); | ||
401 | |||
402 | if (Rup < (unsigned short) MAX_RUP) { | ||
403 | rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", HostP->Mapping[Rup].Name); | ||
404 | } else | ||
405 | rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name); | ||
406 | |||
407 | rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port)); | ||
408 | rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port)); | ||
409 | rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len)); | ||
410 | rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control)); | ||
411 | rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum)); | ||
412 | rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command)); | ||
413 | return 1; | ||
414 | } | ||
415 | PortP = p->RIOPortp[SysPort]; | ||
416 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
417 | switch (readb(&PktCmdP->Command)) { | ||
418 | case RIOC_BREAK_RECEIVED: | ||
419 | rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n"); | ||
420 | /* If the current line disc. is not multi-threading and | ||
421 | the current processor is not the default, reset rup_intr | ||
422 | and return 0 to ensure that the command packet is | ||
423 | not freed. */ | ||
424 | /* Call tmgr HANGUP HERE */ | ||
425 | /* Fix this later when every thing works !!!! RAMRAJ */ | ||
426 | gs_got_break(&PortP->gs); | ||
427 | break; | ||
428 | |||
429 | case RIOC_COMPLETE: | ||
430 | rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts); | ||
431 | subCommand = 1; | ||
432 | switch (readb(&PktCmdP->SubCommand)) { | ||
433 | case RIOC_MEMDUMP: | ||
434 | rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr)); | ||
435 | break; | ||
436 | case RIOC_READ_REGISTER: | ||
437 | rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr)); | ||
438 | p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST); | ||
439 | break; | ||
440 | default: | ||
441 | subCommand = 0; | ||
442 | break; | ||
443 | } | ||
444 | if (subCommand) | ||
445 | break; | ||
446 | rio_dprintk(RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", readb(&PktCmdP->PortStatus), PortP->PortState); | ||
447 | if (PortP->PortState != readb(&PktCmdP->PortStatus)) { | ||
448 | rio_dprintk(RIO_DEBUG_CMD, "Mark status & wakeup\n"); | ||
449 | PortP->PortState = readb(&PktCmdP->PortStatus); | ||
450 | /* What should we do here ... | ||
451 | wakeup( &PortP->PortState ); | ||
452 | */ | ||
453 | } else | ||
454 | rio_dprintk(RIO_DEBUG_CMD, "No change\n"); | ||
455 | |||
456 | /* FALLTHROUGH */ | ||
457 | case RIOC_MODEM_STATUS: | ||
458 | /* | ||
459 | ** Knock out the tbusy and tstop bits, as these are not relevant | ||
460 | ** to the check for modem status change (they're just there because | ||
461 | ** it's a convenient place to put them!). | ||
462 | */ | ||
463 | ReportedModemStatus = readb(&PktCmdP->ModemStatus); | ||
464 | if ((PortP->ModemState & RIOC_MSVR1_HOST) == | ||
465 | (ReportedModemStatus & RIOC_MSVR1_HOST)) { | ||
466 | rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState); | ||
467 | /* | ||
468 | ** Update ModemState just in case tbusy or tstop states have | ||
469 | ** changed. | ||
470 | */ | ||
471 | PortP->ModemState = ReportedModemStatus; | ||
472 | } else { | ||
473 | rio_dprintk(RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n", PortP->ModemState, ReportedModemStatus); | ||
474 | PortP->ModemState = ReportedModemStatus; | ||
475 | #ifdef MODEM_SUPPORT | ||
476 | if (PortP->Mapped) { | ||
477 | /***********************************************************\ | ||
478 | ************************************************************* | ||
479 | *** *** | ||
480 | *** M O D E M S T A T E C H A N G E *** | ||
481 | *** *** | ||
482 | ************************************************************* | ||
483 | \***********************************************************/ | ||
484 | /* | ||
485 | ** If the device is a modem, then check the modem | ||
486 | ** carrier. | ||
487 | */ | ||
488 | if (PortP->gs.port.tty == NULL) | ||
489 | break; | ||
490 | if (PortP->gs.port.tty->termios == NULL) | ||
491 | break; | ||
492 | |||
493 | if (!(PortP->gs.port.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) { | ||
494 | |||
495 | rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n"); | ||
496 | /* | ||
497 | ** Is there a carrier? | ||
498 | */ | ||
499 | if (PortP->ModemState & RIOC_MSVR1_CD) { | ||
500 | /* | ||
501 | ** Has carrier just appeared? | ||
502 | */ | ||
503 | if (!(PortP->State & RIO_CARR_ON)) { | ||
504 | rio_dprintk(RIO_DEBUG_CMD, "Carrier just came up.\n"); | ||
505 | PortP->State |= RIO_CARR_ON; | ||
506 | /* | ||
507 | ** wakeup anyone in WOPEN | ||
508 | */ | ||
509 | if (PortP->State & (PORT_ISOPEN | RIO_WOPEN)) | ||
510 | wake_up_interruptible(&PortP->gs.port.open_wait); | ||
511 | } | ||
512 | } else { | ||
513 | /* | ||
514 | ** Has carrier just dropped? | ||
515 | */ | ||
516 | if (PortP->State & RIO_CARR_ON) { | ||
517 | if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN)) | ||
518 | tty_hangup(PortP->gs.port.tty); | ||
519 | PortP->State &= ~RIO_CARR_ON; | ||
520 | rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n"); | ||
521 | } | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | #endif | ||
526 | } | ||
527 | break; | ||
528 | |||
529 | default: | ||
530 | rio_dprintk(RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %Zd\n", readb(&PktCmdP->Command), HostP - p->RIOHosts); | ||
531 | break; | ||
532 | } | ||
533 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
534 | |||
535 | func_exit(); | ||
536 | |||
537 | return 1; | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | ** The command mechanism: | ||
542 | ** Each rup has a chain of commands associated with it. | ||
543 | ** This chain is maintained by routines in this file. | ||
544 | ** Periodically we are called and we run a quick check of all the | ||
545 | ** active chains to determine if there is a command to be executed, | ||
546 | ** and if the rup is ready to accept it. | ||
547 | ** | ||
548 | */ | ||
549 | |||
550 | /* | ||
551 | ** Allocate an empty command block. | ||
552 | */ | ||
553 | struct CmdBlk *RIOGetCmdBlk(void) | ||
554 | { | ||
555 | struct CmdBlk *CmdBlkP; | ||
556 | |||
557 | CmdBlkP = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC); | ||
558 | return CmdBlkP; | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | ** Return a block to the head of the free list. | ||
563 | */ | ||
564 | void RIOFreeCmdBlk(struct CmdBlk *CmdBlkP) | ||
565 | { | ||
566 | kfree(CmdBlkP); | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | ** attach a command block to the list of commands to be performed for | ||
571 | ** a given rup. | ||
572 | */ | ||
573 | int RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP) | ||
574 | { | ||
575 | struct CmdBlk **Base; | ||
576 | struct UnixRup *UnixRupP; | ||
577 | unsigned long flags; | ||
578 | |||
579 | if (Rup >= (unsigned short) (MAX_RUP + LINKS_PER_UNIT)) { | ||
580 | rio_dprintk(RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n", Rup); | ||
581 | RIOFreeCmdBlk(CmdBlkP); | ||
582 | return RIO_FAIL; | ||
583 | } | ||
584 | |||
585 | UnixRupP = &HostP->UnixRups[Rup]; | ||
586 | |||
587 | rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); | ||
588 | |||
589 | /* | ||
590 | ** If the RUP is currently inactive, then put the request | ||
591 | ** straight on the RUP.... | ||
592 | */ | ||
593 | if ((UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) && (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) | ||
594 | : 1)) { | ||
595 | rio_dprintk(RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n", CmdBlkP->Packet.data[0]); | ||
596 | |||
597 | /* | ||
598 | ** Whammy! blat that pack! | ||
599 | */ | ||
600 | HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); | ||
601 | |||
602 | /* | ||
603 | ** place command packet on the pending position. | ||
604 | */ | ||
605 | UnixRupP->CmdPendingP = CmdBlkP; | ||
606 | |||
607 | /* | ||
608 | ** set the command register | ||
609 | */ | ||
610 | writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); | ||
611 | |||
612 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | ||
613 | |||
614 | return 0; | ||
615 | } | ||
616 | rio_dprintk(RIO_DEBUG_CMD, "RUP active - en-queing\n"); | ||
617 | |||
618 | if (UnixRupP->CmdsWaitingP != NULL) | ||
619 | rio_dprintk(RIO_DEBUG_CMD, "Rup active - command waiting\n"); | ||
620 | if (UnixRupP->CmdPendingP != NULL) | ||
621 | rio_dprintk(RIO_DEBUG_CMD, "Rup active - command pending\n"); | ||
622 | if (readw(&UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE) | ||
623 | rio_dprintk(RIO_DEBUG_CMD, "Rup active - command rup not ready\n"); | ||
624 | |||
625 | Base = &UnixRupP->CmdsWaitingP; | ||
626 | |||
627 | rio_dprintk(RIO_DEBUG_CMD, "First try to queue cmdblk %p at %p\n", CmdBlkP, Base); | ||
628 | |||
629 | while (*Base) { | ||
630 | rio_dprintk(RIO_DEBUG_CMD, "Command cmdblk %p here\n", *Base); | ||
631 | Base = &((*Base)->NextP); | ||
632 | rio_dprintk(RIO_DEBUG_CMD, "Now try to queue cmd cmdblk %p at %p\n", CmdBlkP, Base); | ||
633 | } | ||
634 | |||
635 | rio_dprintk(RIO_DEBUG_CMD, "Will queue cmdblk %p at %p\n", CmdBlkP, Base); | ||
636 | |||
637 | *Base = CmdBlkP; | ||
638 | |||
639 | CmdBlkP->NextP = NULL; | ||
640 | |||
641 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | ||
642 | |||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | /* | ||
647 | ** Here we go - if there is an empty rup, fill it! | ||
648 | ** must be called at splrio() or higher. | ||
649 | */ | ||
650 | void RIOPollHostCommands(struct rio_info *p, struct Host *HostP) | ||
651 | { | ||
652 | struct CmdBlk *CmdBlkP; | ||
653 | struct UnixRup *UnixRupP; | ||
654 | struct PKT __iomem *PacketP; | ||
655 | unsigned short Rup; | ||
656 | unsigned long flags; | ||
657 | |||
658 | |||
659 | Rup = MAX_RUP + LINKS_PER_UNIT; | ||
660 | |||
661 | do { /* do this loop for each RUP */ | ||
662 | /* | ||
663 | ** locate the rup we are processing & lock it | ||
664 | */ | ||
665 | UnixRupP = &HostP->UnixRups[--Rup]; | ||
666 | |||
667 | spin_lock_irqsave(&UnixRupP->RupLock, flags); | ||
668 | |||
669 | /* | ||
670 | ** First check for incoming commands: | ||
671 | */ | ||
672 | if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) { | ||
673 | int FreeMe; | ||
674 | |||
675 | PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt)); | ||
676 | |||
677 | switch (readb(&PacketP->dest_port)) { | ||
678 | case BOOT_RUP: | ||
679 | rio_dprintk(RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", readb(&PacketP->len) & 0x80 ? "Command" : "Data", readb(&PacketP->data[0])); | ||
680 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | ||
681 | FreeMe = RIOBootRup(p, Rup, HostP, PacketP); | ||
682 | rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); | ||
683 | break; | ||
684 | |||
685 | case COMMAND_RUP: | ||
686 | /* | ||
687 | ** Free the RUP lock as loss of carrier causes a | ||
688 | ** ttyflush which will (eventually) call another | ||
689 | ** routine that uses the RUP lock. | ||
690 | */ | ||
691 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | ||
692 | FreeMe = RIOCommandRup(p, Rup, HostP, PacketP); | ||
693 | if (readb(&PacketP->data[5]) == RIOC_MEMDUMP) { | ||
694 | rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6]))); | ||
695 | rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32); | ||
696 | } | ||
697 | rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); | ||
698 | break; | ||
699 | |||
700 | case ROUTE_RUP: | ||
701 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | ||
702 | FreeMe = RIORouteRup(p, Rup, HostP, PacketP); | ||
703 | rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); | ||
704 | break; | ||
705 | |||
706 | default: | ||
707 | rio_dprintk(RIO_DEBUG_CMD, "Unknown RUP %d\n", readb(&PacketP->dest_port)); | ||
708 | FreeMe = 1; | ||
709 | break; | ||
710 | } | ||
711 | |||
712 | if (FreeMe) { | ||
713 | rio_dprintk(RIO_DEBUG_CMD, "Free processed incoming command packet\n"); | ||
714 | put_free_end(HostP, PacketP); | ||
715 | |||
716 | writew(RX_RUP_INACTIVE, &UnixRupP->RupP->rxcontrol); | ||
717 | |||
718 | if (readw(&UnixRupP->RupP->handshake) == PHB_HANDSHAKE_SET) { | ||
719 | rio_dprintk(RIO_DEBUG_CMD, "Handshake rup %d\n", Rup); | ||
720 | writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &UnixRupP->RupP->handshake); | ||
721 | } | ||
722 | } | ||
723 | } | ||
724 | |||
725 | /* | ||
726 | ** IF a command was running on the port, | ||
727 | ** and it has completed, then tidy it up. | ||
728 | */ | ||
729 | if ((CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */ | ||
730 | (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { | ||
731 | /* | ||
732 | ** we are idle. | ||
733 | ** there is a command in pending. | ||
734 | ** Therefore, this command has finished. | ||
735 | ** So, wakeup whoever is waiting for it (and tell them | ||
736 | ** what happened). | ||
737 | */ | ||
738 | if (CmdBlkP->Packet.dest_port == BOOT_RUP) | ||
739 | rio_dprintk(RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", CmdBlkP->Packet.len & 0x80 ? "Command" : "Data", CmdBlkP->Packet.data[0]); | ||
740 | |||
741 | rio_dprintk(RIO_DEBUG_CMD, "Command %p completed\n", CmdBlkP); | ||
742 | |||
743 | /* | ||
744 | ** Clear the Rup lock to prevent mutual exclusion. | ||
745 | */ | ||
746 | if (CmdBlkP->PostFuncP) { | ||
747 | rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | ||
748 | (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg, CmdBlkP); | ||
749 | rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); | ||
750 | } | ||
751 | |||
752 | /* | ||
753 | ** ....clear the pending flag.... | ||
754 | */ | ||
755 | UnixRupP->CmdPendingP = NULL; | ||
756 | |||
757 | /* | ||
758 | ** ....and return the command block to the freelist. | ||
759 | */ | ||
760 | RIOFreeCmdBlk(CmdBlkP); | ||
761 | } | ||
762 | |||
763 | /* | ||
764 | ** If there is a command for this rup, and the rup | ||
765 | ** is idle, then process the command | ||
766 | */ | ||
767 | if ((CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */ | ||
768 | (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { | ||
769 | /* | ||
770 | ** if the pre-function is non-zero, call it. | ||
771 | ** If it returns RIO_FAIL then don't | ||
772 | ** send this command yet! | ||
773 | */ | ||
774 | if (!(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) : 1)) { | ||
775 | rio_dprintk(RIO_DEBUG_CMD, "Not ready to start command %p\n", CmdBlkP); | ||
776 | } else { | ||
777 | rio_dprintk(RIO_DEBUG_CMD, "Start new command %p Cmd byte is 0x%x\n", CmdBlkP, CmdBlkP->Packet.data[0]); | ||
778 | /* | ||
779 | ** Whammy! blat that pack! | ||
780 | */ | ||
781 | HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); | ||
782 | |||
783 | /* | ||
784 | ** remove the command from the rup command queue... | ||
785 | */ | ||
786 | UnixRupP->CmdsWaitingP = CmdBlkP->NextP; | ||
787 | |||
788 | /* | ||
789 | ** ...and place it on the pending position. | ||
790 | */ | ||
791 | UnixRupP->CmdPendingP = CmdBlkP; | ||
792 | |||
793 | /* | ||
794 | ** set the command register | ||
795 | */ | ||
796 | writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); | ||
797 | |||
798 | /* | ||
799 | ** the command block will be freed | ||
800 | ** when the command has been processed. | ||
801 | */ | ||
802 | } | ||
803 | } | ||
804 | spin_unlock_irqrestore(&UnixRupP->RupLock, flags); | ||
805 | } while (Rup); | ||
806 | } | ||
807 | |||
808 | int RIOWFlushMark(unsigned long iPortP, struct CmdBlk *CmdBlkP) | ||
809 | { | ||
810 | struct Port *PortP = (struct Port *) iPortP; | ||
811 | unsigned long flags; | ||
812 | |||
813 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
814 | PortP->WflushFlag++; | ||
815 | PortP->MagicFlags |= MAGIC_FLUSH; | ||
816 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
817 | return RIOUnUse(iPortP, CmdBlkP); | ||
818 | } | ||
819 | |||
820 | int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP) | ||
821 | { | ||
822 | struct Port *PortP = (struct Port *) iPortP; | ||
823 | struct PKT __iomem *PacketP; | ||
824 | unsigned long flags; | ||
825 | |||
826 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
827 | |||
828 | while (can_remove_receive(&PacketP, PortP)) { | ||
829 | remove_receive(PortP); | ||
830 | put_free_end(PortP->HostP, PacketP); | ||
831 | } | ||
832 | |||
833 | if (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET) { | ||
834 | /* | ||
835 | ** MAGIC! (Basically, handshake the RX buffer, so that | ||
836 | ** the RTAs upstream can be re-enabled.) | ||
837 | */ | ||
838 | rio_dprintk(RIO_DEBUG_CMD, "Util: Set RX handshake bit\n"); | ||
839 | writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); | ||
840 | } | ||
841 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
842 | return RIOUnUse(iPortP, CmdBlkP); | ||
843 | } | ||
844 | |||
845 | int RIOUnUse(unsigned long iPortP, struct CmdBlk *CmdBlkP) | ||
846 | { | ||
847 | struct Port *PortP = (struct Port *) iPortP; | ||
848 | unsigned long flags; | ||
849 | |||
850 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
851 | |||
852 | rio_dprintk(RIO_DEBUG_CMD, "Decrement in use count for port\n"); | ||
853 | |||
854 | if (PortP->InUse) { | ||
855 | if (--PortP->InUse != NOT_INUSE) { | ||
856 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
857 | return 0; | ||
858 | } | ||
859 | } | ||
860 | /* | ||
861 | ** While PortP->InUse is set (i.e. a preemptive command has been sent to | ||
862 | ** the RTA and is awaiting completion), any transmit data is prevented from | ||
863 | ** being transferred from the write queue into the transmit packets | ||
864 | ** (add_transmit) and no furthur transmit interrupt will be sent for that | ||
865 | ** data. The next interrupt will occur up to 500ms later (RIOIntr is called | ||
866 | ** twice a second as a saftey measure). This was the case when kermit was | ||
867 | ** used to send data into a RIO port. After each packet was sent, TCFLSH | ||
868 | ** was called to flush the read queue preemptively. PortP->InUse was | ||
869 | ** incremented, thereby blocking the 6 byte acknowledgement packet | ||
870 | ** transmitted back. This acknowledgment hung around for 500ms before | ||
871 | ** being sent, thus reducing input performance substantially!. | ||
872 | ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data | ||
873 | ** hanging around in the transmit buffer is sent immediately. | ||
874 | */ | ||
875 | writew(1, &PortP->HostP->ParmMapP->tx_intr); | ||
876 | /* What to do here .. | ||
877 | wakeup( (caddr_t)&(PortP->InUse) ); | ||
878 | */ | ||
879 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
880 | return 0; | ||
881 | } | ||
882 | |||
883 | /* | ||
884 | ** | ||
885 | ** How to use this file: | ||
886 | ** | ||
887 | ** To send a command down a rup, you need to allocate a command block, fill | ||
888 | ** in the packet information, fill in the command number, fill in the pre- | ||
889 | ** and post- functions and arguments, and then add the command block to the | ||
890 | ** queue of command blocks for the port in question. When the port is idle, | ||
891 | ** then the pre-function will be called. If this returns RIO_FAIL then the | ||
892 | ** command will be re-queued and tried again at a later date (probably in one | ||
893 | ** clock tick). If the pre-function returns NOT RIO_FAIL, then the command | ||
894 | ** packet will be queued on the RUP, and the txcontrol field set to the | ||
895 | ** command number. When the txcontrol field has changed from being the | ||
896 | ** command number, then the post-function will be called, with the argument | ||
897 | ** specified earlier, a pointer to the command block, and the value of | ||
898 | ** txcontrol. | ||
899 | ** | ||
900 | ** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer | ||
901 | ** to the command block structure allocated, or NULL if there aren't any. | ||
902 | ** The block will have been zeroed for you. | ||
903 | ** | ||
904 | ** The structure has the following fields: | ||
905 | ** | ||
906 | ** struct CmdBlk | ||
907 | ** { | ||
908 | ** struct CmdBlk *NextP; ** Pointer to next command block ** | ||
909 | ** struct PKT Packet; ** A packet, to copy to the rup ** | ||
910 | ** int (*PreFuncP)(); ** The func to call to check if OK ** | ||
911 | ** int PreArg; ** The arg for the func ** | ||
912 | ** int (*PostFuncP)(); ** The func to call when completed ** | ||
913 | ** int PostArg; ** The arg for the func ** | ||
914 | ** }; | ||
915 | ** | ||
916 | ** You need to fill in ALL fields EXCEPT NextP, which is used to link the | ||
917 | ** blocks together either on the free list or on the Rup list. | ||
918 | ** | ||
919 | ** Packet is an actual packet structure to be filled in with the packet | ||
920 | ** information associated with the command. You need to fill in everything, | ||
921 | ** as the command processor doesn't process the command packet in any way. | ||
922 | ** | ||
923 | ** The PreFuncP is called before the packet is enqueued on the host rup. | ||
924 | ** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must | ||
925 | ** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL | ||
926 | ** if the packet is NOT to be queued. | ||
927 | ** | ||
928 | ** The PostFuncP is called when the command has completed. It is called | ||
929 | ** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected | ||
930 | ** to return a value. PostFuncP does NOT need to free the command block, | ||
931 | ** as this happens automatically after PostFuncP returns. | ||
932 | ** | ||
933 | ** Once the command block has been filled in, it is attached to the correct | ||
934 | ** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is | ||
935 | ** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer | ||
936 | ** to it!), and CmdBlkP is the pointer to the command block allocated using | ||
937 | ** RIOGetCmdBlk(). | ||
938 | ** | ||
939 | */ | ||
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c deleted file mode 100644 index 780506326a73..000000000000 --- a/drivers/char/rio/rioctrl.c +++ /dev/null | |||
@@ -1,1504 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rioctrl.c | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 10:33:42 | ||
26 | ** Retrieved : 11/6/98 10:33:49 | ||
27 | ** | ||
28 | ** ident @(#)rioctrl.c 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/sched.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/errno.h> | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/system.h> | ||
39 | #include <asm/string.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | |||
42 | #include <linux/termios.h> | ||
43 | #include <linux/serial.h> | ||
44 | |||
45 | #include <linux/generic_serial.h> | ||
46 | |||
47 | |||
48 | #include "linux_compat.h" | ||
49 | #include "rio_linux.h" | ||
50 | #include "pkt.h" | ||
51 | #include "daemon.h" | ||
52 | #include "rio.h" | ||
53 | #include "riospace.h" | ||
54 | #include "cmdpkt.h" | ||
55 | #include "map.h" | ||
56 | #include "rup.h" | ||
57 | #include "port.h" | ||
58 | #include "riodrvr.h" | ||
59 | #include "rioinfo.h" | ||
60 | #include "func.h" | ||
61 | #include "errors.h" | ||
62 | #include "pci.h" | ||
63 | |||
64 | #include "parmmap.h" | ||
65 | #include "unixrup.h" | ||
66 | #include "board.h" | ||
67 | #include "host.h" | ||
68 | #include "phb.h" | ||
69 | #include "link.h" | ||
70 | #include "cmdblk.h" | ||
71 | #include "route.h" | ||
72 | #include "cirrus.h" | ||
73 | #include "rioioctl.h" | ||
74 | |||
75 | |||
76 | static struct LpbReq LpbReq; | ||
77 | static struct RupReq RupReq; | ||
78 | static struct PortReq PortReq; | ||
79 | static struct HostReq HostReq; /* oh really? global? and no locking? */ | ||
80 | static struct HostDpRam HostDpRam; | ||
81 | static struct DebugCtrl DebugCtrl; | ||
82 | static struct Map MapEnt; | ||
83 | static struct PortSetup PortSetup; | ||
84 | static struct DownLoad DownLoad; | ||
85 | static struct SendPack SendPack; | ||
86 | /* static struct StreamInfo StreamInfo; */ | ||
87 | /* static char modemtable[RIO_PORTS]; */ | ||
88 | static struct SpecialRupCmd SpecialRupCmd; | ||
89 | static struct PortParams PortParams; | ||
90 | static struct portStats portStats; | ||
91 | |||
92 | static struct SubCmdStruct { | ||
93 | ushort Host; | ||
94 | ushort Rup; | ||
95 | ushort Port; | ||
96 | ushort Addr; | ||
97 | } SubCmd; | ||
98 | |||
99 | struct PortTty { | ||
100 | uint port; | ||
101 | struct ttystatics Tty; | ||
102 | }; | ||
103 | |||
104 | static struct PortTty PortTty; | ||
105 | typedef struct ttystatics TERMIO; | ||
106 | |||
107 | /* | ||
108 | ** This table is used when the config.rio downloads bin code to the | ||
109 | ** driver. We index the table using the product code, 0-F, and call | ||
110 | ** the function pointed to by the entry, passing the information | ||
111 | ** about the boot. | ||
112 | ** The RIOBootCodeUNKNOWN entry is there to politely tell the calling | ||
113 | ** process to bog off. | ||
114 | */ | ||
115 | static int | ||
116 | (*RIOBootTable[MAX_PRODUCT]) (struct rio_info *, struct DownLoad *) = { | ||
117 | /* 0 */ RIOBootCodeHOST, | ||
118 | /* Host Card */ | ||
119 | /* 1 */ RIOBootCodeRTA, | ||
120 | /* RTA */ | ||
121 | }; | ||
122 | |||
123 | #define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff)) | ||
124 | |||
125 | static int copy_from_io(void __user *to, void __iomem *from, size_t size) | ||
126 | { | ||
127 | void *buf = kmalloc(size, GFP_KERNEL); | ||
128 | int res = -ENOMEM; | ||
129 | if (buf) { | ||
130 | rio_memcpy_fromio(buf, from, size); | ||
131 | res = copy_to_user(to, buf, size); | ||
132 | kfree(buf); | ||
133 | } | ||
134 | return res; | ||
135 | } | ||
136 | |||
137 | int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su) | ||
138 | { | ||
139 | uint Host; /* leave me unsigned! */ | ||
140 | uint port; /* and me! */ | ||
141 | struct Host *HostP; | ||
142 | ushort loop; | ||
143 | int Entry; | ||
144 | struct Port *PortP; | ||
145 | struct PKT __iomem *PacketP; | ||
146 | int retval = 0; | ||
147 | unsigned long flags; | ||
148 | void __user *argp = (void __user *)arg; | ||
149 | |||
150 | func_enter(); | ||
151 | |||
152 | /* Confuse the compiler to think that we've initialized these */ | ||
153 | Host = 0; | ||
154 | PortP = NULL; | ||
155 | |||
156 | rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, argp); | ||
157 | |||
158 | switch (cmd) { | ||
159 | /* | ||
160 | ** RIO_SET_TIMER | ||
161 | ** | ||
162 | ** Change the value of the host card interrupt timer. | ||
163 | ** If the host card number is -1 then all host cards are changed | ||
164 | ** otherwise just the specified host card will be changed. | ||
165 | */ | ||
166 | case RIO_SET_TIMER: | ||
167 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", arg); | ||
168 | { | ||
169 | int host, value; | ||
170 | host = (arg >> 16) & 0x0000FFFF; | ||
171 | value = arg & 0x0000ffff; | ||
172 | if (host == -1) { | ||
173 | for (host = 0; host < p->RIONumHosts; host++) { | ||
174 | if (p->RIOHosts[host].Flags == RC_RUNNING) { | ||
175 | writew(value, &p->RIOHosts[host].ParmMapP->timer); | ||
176 | } | ||
177 | } | ||
178 | } else if (host >= p->RIONumHosts) { | ||
179 | return -EINVAL; | ||
180 | } else { | ||
181 | if (p->RIOHosts[host].Flags == RC_RUNNING) { | ||
182 | writew(value, &p->RIOHosts[host].ParmMapP->timer); | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | return 0; | ||
187 | |||
188 | case RIO_FOAD_RTA: | ||
189 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n"); | ||
190 | return RIOCommandRta(p, arg, RIOFoadRta); | ||
191 | |||
192 | case RIO_ZOMBIE_RTA: | ||
193 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n"); | ||
194 | return RIOCommandRta(p, arg, RIOZombieRta); | ||
195 | |||
196 | case RIO_IDENTIFY_RTA: | ||
197 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n"); | ||
198 | return RIOIdentifyRta(p, argp); | ||
199 | |||
200 | case RIO_KILL_NEIGHBOUR: | ||
201 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n"); | ||
202 | return RIOKillNeighbour(p, argp); | ||
203 | |||
204 | case SPECIAL_RUP_CMD: | ||
205 | { | ||
206 | struct CmdBlk *CmdBlkP; | ||
207 | |||
208 | rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n"); | ||
209 | if (copy_from_user(&SpecialRupCmd, argp, sizeof(SpecialRupCmd))) { | ||
210 | rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n"); | ||
211 | p->RIOError.Error = COPYIN_FAILED; | ||
212 | return -EFAULT; | ||
213 | } | ||
214 | CmdBlkP = RIOGetCmdBlk(); | ||
215 | if (!CmdBlkP) { | ||
216 | rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n"); | ||
217 | return -ENXIO; | ||
218 | } | ||
219 | CmdBlkP->Packet = SpecialRupCmd.Packet; | ||
220 | if (SpecialRupCmd.Host >= p->RIONumHosts) | ||
221 | SpecialRupCmd.Host = 0; | ||
222 | rio_dprintk(RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n", SpecialRupCmd.Host, SpecialRupCmd.RupNum); | ||
223 | if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) { | ||
224 | printk(KERN_WARNING "rio: FAILED TO QUEUE SPECIAL RUP COMMAND\n"); | ||
225 | } | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | case RIO_DEBUG_MEM: | ||
230 | return -EPERM; | ||
231 | |||
232 | case RIO_ALL_MODEM: | ||
233 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n"); | ||
234 | p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; | ||
235 | return -EINVAL; | ||
236 | |||
237 | case RIO_GET_TABLE: | ||
238 | /* | ||
239 | ** Read the routing table from the device driver to user space | ||
240 | */ | ||
241 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE\n"); | ||
242 | |||
243 | if ((retval = RIOApel(p)) != 0) | ||
244 | return retval; | ||
245 | |||
246 | if (copy_to_user(argp, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { | ||
247 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n"); | ||
248 | p->RIOError.Error = COPYOUT_FAILED; | ||
249 | return -EFAULT; | ||
250 | } | ||
251 | |||
252 | { | ||
253 | int entry; | ||
254 | rio_dprintk(RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n"); | ||
255 | for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { | ||
256 | if ((p->RIOConnectTable[entry].ID == 0) && (p->RIOConnectTable[entry].HostUniqueNum == 0) && (p->RIOConnectTable[entry].RtaUniqueNum == 0)) | ||
257 | continue; | ||
258 | |||
259 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum); | ||
260 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum); | ||
261 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID); | ||
262 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2); | ||
263 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int) p->RIOConnectTable[entry].Flags); | ||
264 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int) p->RIOConnectTable[entry].SysPort); | ||
265 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit); | ||
266 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link); | ||
267 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit); | ||
268 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link); | ||
269 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit); | ||
270 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link); | ||
271 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit); | ||
272 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link); | ||
273 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name); | ||
274 | } | ||
275 | rio_dprintk(RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n"); | ||
276 | } | ||
277 | p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */ | ||
278 | return 0; | ||
279 | |||
280 | case RIO_PUT_TABLE: | ||
281 | /* | ||
282 | ** Write the routing table to the device driver from user space | ||
283 | */ | ||
284 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n"); | ||
285 | |||
286 | if (!su) { | ||
287 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n"); | ||
288 | p->RIOError.Error = NOT_SUPER_USER; | ||
289 | return -EPERM; | ||
290 | } | ||
291 | if (copy_from_user(&p->RIOConnectTable[0], argp, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { | ||
292 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n"); | ||
293 | p->RIOError.Error = COPYIN_FAILED; | ||
294 | return -EFAULT; | ||
295 | } | ||
296 | /* | ||
297 | *********************************** | ||
298 | { | ||
299 | int entry; | ||
300 | rio_dprint(RIO_DEBUG_CTRL, ("*****\nMAP ENTRIES\n") ); | ||
301 | for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ ) | ||
302 | { | ||
303 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ) ); | ||
304 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) ); | ||
305 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) ); | ||
306 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) ); | ||
307 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Flags = 0x%x\n", entry, p->RIOConnectTable[entry].Flags ) ); | ||
308 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.SysPort = 0x%x\n", entry, p->RIOConnectTable[entry].SysPort ) ); | ||
309 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) ); | ||
310 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) ); | ||
311 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) ); | ||
312 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) ); | ||
313 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) ); | ||
314 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) ); | ||
315 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[3].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) ); | ||
316 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[4].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) ); | ||
317 | rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) ); | ||
318 | } | ||
319 | rio_dprint(RIO_DEBUG_CTRL, ("*****\nEND MAP ENTRIES\n") ); | ||
320 | } | ||
321 | *********************************** | ||
322 | */ | ||
323 | return RIONewTable(p); | ||
324 | |||
325 | case RIO_GET_BINDINGS: | ||
326 | /* | ||
327 | ** Send bindings table, containing unique numbers of RTAs owned | ||
328 | ** by this system to user space | ||
329 | */ | ||
330 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n"); | ||
331 | |||
332 | if (!su) { | ||
333 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n"); | ||
334 | p->RIOError.Error = NOT_SUPER_USER; | ||
335 | return -EPERM; | ||
336 | } | ||
337 | if (copy_to_user(argp, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) { | ||
338 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n"); | ||
339 | p->RIOError.Error = COPYOUT_FAILED; | ||
340 | return -EFAULT; | ||
341 | } | ||
342 | return 0; | ||
343 | |||
344 | case RIO_PUT_BINDINGS: | ||
345 | /* | ||
346 | ** Receive a bindings table, containing unique numbers of RTAs owned | ||
347 | ** by this system | ||
348 | */ | ||
349 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n"); | ||
350 | |||
351 | if (!su) { | ||
352 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n"); | ||
353 | p->RIOError.Error = NOT_SUPER_USER; | ||
354 | return -EPERM; | ||
355 | } | ||
356 | if (copy_from_user(&p->RIOBindTab[0], argp, (sizeof(ulong) * MAX_RTA_BINDINGS))) { | ||
357 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n"); | ||
358 | p->RIOError.Error = COPYIN_FAILED; | ||
359 | return -EFAULT; | ||
360 | } | ||
361 | return 0; | ||
362 | |||
363 | case RIO_BIND_RTA: | ||
364 | { | ||
365 | int EmptySlot = -1; | ||
366 | /* | ||
367 | ** Bind this RTA to host, so that it will be booted by | ||
368 | ** host in 'boot owned RTAs' mode. | ||
369 | */ | ||
370 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n"); | ||
371 | |||
372 | if (!su) { | ||
373 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n"); | ||
374 | p->RIOError.Error = NOT_SUPER_USER; | ||
375 | return -EPERM; | ||
376 | } | ||
377 | for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) { | ||
378 | if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L)) | ||
379 | EmptySlot = Entry; | ||
380 | else if (p->RIOBindTab[Entry] == arg) { | ||
381 | /* | ||
382 | ** Already exists - delete | ||
383 | */ | ||
384 | p->RIOBindTab[Entry] = 0L; | ||
385 | rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", arg); | ||
386 | return 0; | ||
387 | } | ||
388 | } | ||
389 | /* | ||
390 | ** Dosen't exist - add | ||
391 | */ | ||
392 | if (EmptySlot != -1) { | ||
393 | p->RIOBindTab[EmptySlot] = arg; | ||
394 | rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", arg); | ||
395 | } else { | ||
396 | rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", arg); | ||
397 | return -ENOMEM; | ||
398 | } | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | case RIO_RESUME: | ||
403 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n"); | ||
404 | port = arg; | ||
405 | if ((port < 0) || (port > 511)) { | ||
406 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port); | ||
407 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
408 | return -EINVAL; | ||
409 | } | ||
410 | PortP = p->RIOPortp[port]; | ||
411 | if (!PortP->Mapped) { | ||
412 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port); | ||
413 | p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; | ||
414 | return -EINVAL; | ||
415 | } | ||
416 | if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { | ||
417 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port); | ||
418 | return -EINVAL; | ||
419 | } | ||
420 | |||
421 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
422 | if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RIOC_RESUME) == | ||
423 | RIO_FAIL) { | ||
424 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); | ||
425 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
426 | return -EBUSY; | ||
427 | } else { | ||
428 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port); | ||
429 | PortP->State |= RIO_BUSY; | ||
430 | } | ||
431 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
432 | return retval; | ||
433 | |||
434 | case RIO_ASSIGN_RTA: | ||
435 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n"); | ||
436 | if (!su) { | ||
437 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n"); | ||
438 | p->RIOError.Error = NOT_SUPER_USER; | ||
439 | return -EPERM; | ||
440 | } | ||
441 | if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { | ||
442 | rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); | ||
443 | p->RIOError.Error = COPYIN_FAILED; | ||
444 | return -EFAULT; | ||
445 | } | ||
446 | return RIOAssignRta(p, &MapEnt); | ||
447 | |||
448 | case RIO_CHANGE_NAME: | ||
449 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n"); | ||
450 | if (!su) { | ||
451 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n"); | ||
452 | p->RIOError.Error = NOT_SUPER_USER; | ||
453 | return -EPERM; | ||
454 | } | ||
455 | if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { | ||
456 | rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); | ||
457 | p->RIOError.Error = COPYIN_FAILED; | ||
458 | return -EFAULT; | ||
459 | } | ||
460 | return RIOChangeName(p, &MapEnt); | ||
461 | |||
462 | case RIO_DELETE_RTA: | ||
463 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n"); | ||
464 | if (!su) { | ||
465 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n"); | ||
466 | p->RIOError.Error = NOT_SUPER_USER; | ||
467 | return -EPERM; | ||
468 | } | ||
469 | if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { | ||
470 | rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n"); | ||
471 | p->RIOError.Error = COPYIN_FAILED; | ||
472 | return -EFAULT; | ||
473 | } | ||
474 | return RIODeleteRta(p, &MapEnt); | ||
475 | |||
476 | case RIO_QUICK_CHECK: | ||
477 | if (copy_to_user(argp, &p->RIORtaDisCons, sizeof(unsigned int))) { | ||
478 | p->RIOError.Error = COPYOUT_FAILED; | ||
479 | return -EFAULT; | ||
480 | } | ||
481 | return 0; | ||
482 | |||
483 | case RIO_LAST_ERROR: | ||
484 | if (copy_to_user(argp, &p->RIOError, sizeof(struct Error))) | ||
485 | return -EFAULT; | ||
486 | return 0; | ||
487 | |||
488 | case RIO_GET_LOG: | ||
489 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n"); | ||
490 | return -EINVAL; | ||
491 | |||
492 | case RIO_GET_MODTYPE: | ||
493 | if (copy_from_user(&port, argp, sizeof(unsigned int))) { | ||
494 | p->RIOError.Error = COPYIN_FAILED; | ||
495 | return -EFAULT; | ||
496 | } | ||
497 | rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port); | ||
498 | if (port < 0 || port > 511) { | ||
499 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port); | ||
500 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
501 | return -EINVAL; | ||
502 | } | ||
503 | PortP = (p->RIOPortp[port]); | ||
504 | if (!PortP->Mapped) { | ||
505 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port); | ||
506 | p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; | ||
507 | return -EINVAL; | ||
508 | } | ||
509 | /* | ||
510 | ** Return module type of port | ||
511 | */ | ||
512 | port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes; | ||
513 | if (copy_to_user(argp, &port, sizeof(unsigned int))) { | ||
514 | p->RIOError.Error = COPYOUT_FAILED; | ||
515 | return -EFAULT; | ||
516 | } | ||
517 | return (0); | ||
518 | case RIO_BLOCK_OPENS: | ||
519 | rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n"); | ||
520 | for (Entry = 0; Entry < RIO_PORTS; Entry++) { | ||
521 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
522 | p->RIOPortp[Entry]->WaitUntilBooted = 1; | ||
523 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
524 | } | ||
525 | return 0; | ||
526 | |||
527 | case RIO_SETUP_PORTS: | ||
528 | rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n"); | ||
529 | if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { | ||
530 | p->RIOError.Error = COPYIN_FAILED; | ||
531 | rio_dprintk(RIO_DEBUG_CTRL, "EFAULT"); | ||
532 | return -EFAULT; | ||
533 | } | ||
534 | if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) { | ||
535 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
536 | rio_dprintk(RIO_DEBUG_CTRL, "ENXIO"); | ||
537 | return -ENXIO; | ||
538 | } | ||
539 | if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) { | ||
540 | p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE; | ||
541 | rio_dprintk(RIO_DEBUG_CTRL, "EINVAL"); | ||
542 | return -EINVAL; | ||
543 | } | ||
544 | if (!p->RIOPortp) { | ||
545 | printk(KERN_ERR "rio: No p->RIOPortp array!\n"); | ||
546 | rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n"); | ||
547 | return -EIO; | ||
548 | } | ||
549 | rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To); | ||
550 | for (loop = PortSetup.From; loop <= PortSetup.To; loop++) { | ||
551 | rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop); | ||
552 | } | ||
553 | rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop); | ||
554 | rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval); | ||
555 | return retval; | ||
556 | |||
557 | case RIO_GET_PORT_SETUP: | ||
558 | rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n"); | ||
559 | if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { | ||
560 | p->RIOError.Error = COPYIN_FAILED; | ||
561 | return -EFAULT; | ||
562 | } | ||
563 | if (PortSetup.From >= RIO_PORTS) { | ||
564 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
565 | return -ENXIO; | ||
566 | } | ||
567 | |||
568 | port = PortSetup.To = PortSetup.From; | ||
569 | PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0; | ||
570 | PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0; | ||
571 | PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0; | ||
572 | PortSetup.Store = p->RIOPortp[port]->Store; | ||
573 | PortSetup.Lock = p->RIOPortp[port]->Lock; | ||
574 | PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps; | ||
575 | memcpy(PortSetup.XpOn, p->RIOPortp[port]->Xprint.XpOn, MAX_XP_CTRL_LEN); | ||
576 | memcpy(PortSetup.XpOff, p->RIOPortp[port]->Xprint.XpOff, MAX_XP_CTRL_LEN); | ||
577 | PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0'; | ||
578 | PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0'; | ||
579 | |||
580 | if (copy_to_user(argp, &PortSetup, sizeof(PortSetup))) { | ||
581 | p->RIOError.Error = COPYOUT_FAILED; | ||
582 | return -EFAULT; | ||
583 | } | ||
584 | return retval; | ||
585 | |||
586 | case RIO_GET_PORT_PARAMS: | ||
587 | rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n"); | ||
588 | if (copy_from_user(&PortParams, argp, sizeof(struct PortParams))) { | ||
589 | p->RIOError.Error = COPYIN_FAILED; | ||
590 | return -EFAULT; | ||
591 | } | ||
592 | if (PortParams.Port >= RIO_PORTS) { | ||
593 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
594 | return -ENXIO; | ||
595 | } | ||
596 | PortP = (p->RIOPortp[PortParams.Port]); | ||
597 | PortParams.Config = PortP->Config; | ||
598 | PortParams.State = PortP->State; | ||
599 | rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port); | ||
600 | |||
601 | if (copy_to_user(argp, &PortParams, sizeof(struct PortParams))) { | ||
602 | p->RIOError.Error = COPYOUT_FAILED; | ||
603 | return -EFAULT; | ||
604 | } | ||
605 | return retval; | ||
606 | |||
607 | case RIO_GET_PORT_TTY: | ||
608 | rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n"); | ||
609 | if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { | ||
610 | p->RIOError.Error = COPYIN_FAILED; | ||
611 | return -EFAULT; | ||
612 | } | ||
613 | if (PortTty.port >= RIO_PORTS) { | ||
614 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
615 | return -ENXIO; | ||
616 | } | ||
617 | |||
618 | rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port); | ||
619 | PortP = (p->RIOPortp[PortTty.port]); | ||
620 | if (copy_to_user(argp, &PortTty, sizeof(struct PortTty))) { | ||
621 | p->RIOError.Error = COPYOUT_FAILED; | ||
622 | return -EFAULT; | ||
623 | } | ||
624 | return retval; | ||
625 | |||
626 | case RIO_SET_PORT_TTY: | ||
627 | if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { | ||
628 | p->RIOError.Error = COPYIN_FAILED; | ||
629 | return -EFAULT; | ||
630 | } | ||
631 | rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port); | ||
632 | if (PortTty.port >= (ushort) RIO_PORTS) { | ||
633 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
634 | return -ENXIO; | ||
635 | } | ||
636 | PortP = (p->RIOPortp[PortTty.port]); | ||
637 | RIOParam(PortP, RIOC_CONFIG, PortP->State & RIO_MODEM, | ||
638 | OK_TO_SLEEP); | ||
639 | return retval; | ||
640 | |||
641 | case RIO_SET_PORT_PARAMS: | ||
642 | rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n"); | ||
643 | if (copy_from_user(&PortParams, argp, sizeof(PortParams))) { | ||
644 | p->RIOError.Error = COPYIN_FAILED; | ||
645 | return -EFAULT; | ||
646 | } | ||
647 | if (PortParams.Port >= (ushort) RIO_PORTS) { | ||
648 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
649 | return -ENXIO; | ||
650 | } | ||
651 | PortP = (p->RIOPortp[PortParams.Port]); | ||
652 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
653 | PortP->Config = PortParams.Config; | ||
654 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
655 | return retval; | ||
656 | |||
657 | case RIO_GET_PORT_STATS: | ||
658 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n"); | ||
659 | if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { | ||
660 | p->RIOError.Error = COPYIN_FAILED; | ||
661 | return -EFAULT; | ||
662 | } | ||
663 | if (portStats.port < 0 || portStats.port >= RIO_PORTS) { | ||
664 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
665 | return -ENXIO; | ||
666 | } | ||
667 | PortP = (p->RIOPortp[portStats.port]); | ||
668 | portStats.gather = PortP->statsGather; | ||
669 | portStats.txchars = PortP->txchars; | ||
670 | portStats.rxchars = PortP->rxchars; | ||
671 | portStats.opens = PortP->opens; | ||
672 | portStats.closes = PortP->closes; | ||
673 | portStats.ioctls = PortP->ioctls; | ||
674 | if (copy_to_user(argp, &portStats, sizeof(struct portStats))) { | ||
675 | p->RIOError.Error = COPYOUT_FAILED; | ||
676 | return -EFAULT; | ||
677 | } | ||
678 | return retval; | ||
679 | |||
680 | case RIO_RESET_PORT_STATS: | ||
681 | port = arg; | ||
682 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n"); | ||
683 | if (port >= RIO_PORTS) { | ||
684 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
685 | return -ENXIO; | ||
686 | } | ||
687 | PortP = (p->RIOPortp[port]); | ||
688 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
689 | PortP->txchars = 0; | ||
690 | PortP->rxchars = 0; | ||
691 | PortP->opens = 0; | ||
692 | PortP->closes = 0; | ||
693 | PortP->ioctls = 0; | ||
694 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
695 | return retval; | ||
696 | |||
697 | case RIO_GATHER_PORT_STATS: | ||
698 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n"); | ||
699 | if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { | ||
700 | p->RIOError.Error = COPYIN_FAILED; | ||
701 | return -EFAULT; | ||
702 | } | ||
703 | if (portStats.port < 0 || portStats.port >= RIO_PORTS) { | ||
704 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
705 | return -ENXIO; | ||
706 | } | ||
707 | PortP = (p->RIOPortp[portStats.port]); | ||
708 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
709 | PortP->statsGather = portStats.gather; | ||
710 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
711 | return retval; | ||
712 | |||
713 | case RIO_READ_CONFIG: | ||
714 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n"); | ||
715 | if (copy_to_user(argp, &p->RIOConf, sizeof(struct Conf))) { | ||
716 | p->RIOError.Error = COPYOUT_FAILED; | ||
717 | return -EFAULT; | ||
718 | } | ||
719 | return retval; | ||
720 | |||
721 | case RIO_SET_CONFIG: | ||
722 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n"); | ||
723 | if (!su) { | ||
724 | p->RIOError.Error = NOT_SUPER_USER; | ||
725 | return -EPERM; | ||
726 | } | ||
727 | if (copy_from_user(&p->RIOConf, argp, sizeof(struct Conf))) { | ||
728 | p->RIOError.Error = COPYIN_FAILED; | ||
729 | return -EFAULT; | ||
730 | } | ||
731 | /* | ||
732 | ** move a few value around | ||
733 | */ | ||
734 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
735 | if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING) | ||
736 | writew(p->RIOConf.Timer, &p->RIOHosts[Host].ParmMapP->timer); | ||
737 | return retval; | ||
738 | |||
739 | case RIO_START_POLLER: | ||
740 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n"); | ||
741 | return -EINVAL; | ||
742 | |||
743 | case RIO_STOP_POLLER: | ||
744 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n"); | ||
745 | if (!su) { | ||
746 | p->RIOError.Error = NOT_SUPER_USER; | ||
747 | return -EPERM; | ||
748 | } | ||
749 | p->RIOPolling = NOT_POLLING; | ||
750 | return retval; | ||
751 | |||
752 | case RIO_SETDEBUG: | ||
753 | case RIO_GETDEBUG: | ||
754 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n"); | ||
755 | if (copy_from_user(&DebugCtrl, argp, sizeof(DebugCtrl))) { | ||
756 | p->RIOError.Error = COPYIN_FAILED; | ||
757 | return -EFAULT; | ||
758 | } | ||
759 | if (DebugCtrl.SysPort == NO_PORT) { | ||
760 | if (cmd == RIO_SETDEBUG) { | ||
761 | if (!su) { | ||
762 | p->RIOError.Error = NOT_SUPER_USER; | ||
763 | return -EPERM; | ||
764 | } | ||
765 | p->rio_debug = DebugCtrl.Debug; | ||
766 | p->RIODebugWait = DebugCtrl.Wait; | ||
767 | rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait); | ||
768 | } else { | ||
769 | rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait); | ||
770 | DebugCtrl.Debug = p->rio_debug; | ||
771 | DebugCtrl.Wait = p->RIODebugWait; | ||
772 | if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { | ||
773 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); | ||
774 | p->RIOError.Error = COPYOUT_FAILED; | ||
775 | return -EFAULT; | ||
776 | } | ||
777 | } | ||
778 | } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) { | ||
779 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); | ||
780 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
781 | return -ENXIO; | ||
782 | } else if (cmd == RIO_SETDEBUG) { | ||
783 | if (!su) { | ||
784 | p->RIOError.Error = NOT_SUPER_USER; | ||
785 | return -EPERM; | ||
786 | } | ||
787 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
788 | p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug; | ||
789 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
790 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); | ||
791 | } else { | ||
792 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); | ||
793 | DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; | ||
794 | if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { | ||
795 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); | ||
796 | p->RIOError.Error = COPYOUT_FAILED; | ||
797 | return -EFAULT; | ||
798 | } | ||
799 | } | ||
800 | return retval; | ||
801 | |||
802 | case RIO_VERSID: | ||
803 | /* | ||
804 | ** Enquire about the release and version. | ||
805 | ** We return MAX_VERSION_LEN bytes, being a | ||
806 | ** textual null terminated string. | ||
807 | */ | ||
808 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n"); | ||
809 | if (copy_to_user(argp, RIOVersid(), sizeof(struct rioVersion))) { | ||
810 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); | ||
811 | p->RIOError.Error = COPYOUT_FAILED; | ||
812 | return -EFAULT; | ||
813 | } | ||
814 | return retval; | ||
815 | |||
816 | case RIO_NUM_HOSTS: | ||
817 | /* | ||
818 | ** Enquire as to the number of hosts located | ||
819 | ** at init time. | ||
820 | */ | ||
821 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); | ||
822 | if (copy_to_user(argp, &p->RIONumHosts, sizeof(p->RIONumHosts))) { | ||
823 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); | ||
824 | p->RIOError.Error = COPYOUT_FAILED; | ||
825 | return -EFAULT; | ||
826 | } | ||
827 | return retval; | ||
828 | |||
829 | case RIO_HOST_FOAD: | ||
830 | /* | ||
831 | ** Kill host. This may not be in the final version... | ||
832 | */ | ||
833 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", arg); | ||
834 | if (!su) { | ||
835 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); | ||
836 | p->RIOError.Error = NOT_SUPER_USER; | ||
837 | return -EPERM; | ||
838 | } | ||
839 | p->RIOHalted = 1; | ||
840 | p->RIOSystemUp = 0; | ||
841 | |||
842 | for (Host = 0; Host < p->RIONumHosts; Host++) { | ||
843 | (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot); | ||
844 | memset(&p->RIOHosts[Host].Flags, 0, ((char *) &p->RIOHosts[Host].____end_marker____) - ((char *) &p->RIOHosts[Host].Flags)); | ||
845 | p->RIOHosts[Host].Flags = RC_WAITING; | ||
846 | } | ||
847 | RIOFoadWakeup(p); | ||
848 | p->RIONumBootPkts = 0; | ||
849 | p->RIOBooting = 0; | ||
850 | printk("HEEEEELP!\n"); | ||
851 | |||
852 | for (loop = 0; loop < RIO_PORTS; loop++) { | ||
853 | spin_lock_init(&p->RIOPortp[loop]->portSem); | ||
854 | p->RIOPortp[loop]->InUse = NOT_INUSE; | ||
855 | } | ||
856 | |||
857 | p->RIOSystemUp = 0; | ||
858 | return retval; | ||
859 | |||
860 | case RIO_DOWNLOAD: | ||
861 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n"); | ||
862 | if (!su) { | ||
863 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n"); | ||
864 | p->RIOError.Error = NOT_SUPER_USER; | ||
865 | return -EPERM; | ||
866 | } | ||
867 | if (copy_from_user(&DownLoad, argp, sizeof(DownLoad))) { | ||
868 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); | ||
869 | p->RIOError.Error = COPYIN_FAILED; | ||
870 | return -EFAULT; | ||
871 | } | ||
872 | rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode); | ||
873 | |||
874 | /* | ||
875 | ** It is important that the product code is an unsigned object! | ||
876 | */ | ||
877 | if (DownLoad.ProductCode >= MAX_PRODUCT) { | ||
878 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode); | ||
879 | p->RIOError.Error = NO_SUCH_PRODUCT; | ||
880 | return -ENXIO; | ||
881 | } | ||
882 | /* | ||
883 | ** do something! | ||
884 | */ | ||
885 | retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad); | ||
886 | /* <-- Panic */ | ||
887 | p->RIOHalted = 0; | ||
888 | /* | ||
889 | ** and go back, content with a job well completed. | ||
890 | */ | ||
891 | return retval; | ||
892 | |||
893 | case RIO_PARMS: | ||
894 | { | ||
895 | unsigned int host; | ||
896 | |||
897 | if (copy_from_user(&host, argp, sizeof(host))) { | ||
898 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); | ||
899 | p->RIOError.Error = COPYIN_FAILED; | ||
900 | return -EFAULT; | ||
901 | } | ||
902 | /* | ||
903 | ** Fetch the parmmap | ||
904 | */ | ||
905 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n"); | ||
906 | if (copy_from_io(argp, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) { | ||
907 | p->RIOError.Error = COPYOUT_FAILED; | ||
908 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); | ||
909 | return -EFAULT; | ||
910 | } | ||
911 | } | ||
912 | return retval; | ||
913 | |||
914 | case RIO_HOST_REQ: | ||
915 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); | ||
916 | if (copy_from_user(&HostReq, argp, sizeof(HostReq))) { | ||
917 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); | ||
918 | p->RIOError.Error = COPYIN_FAILED; | ||
919 | return -EFAULT; | ||
920 | } | ||
921 | if (HostReq.HostNum >= p->RIONumHosts) { | ||
922 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
923 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum); | ||
924 | return -ENXIO; | ||
925 | } | ||
926 | rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum); | ||
927 | |||
928 | if (copy_to_user(HostReq.HostP, &p->RIOHosts[HostReq.HostNum], sizeof(struct Host))) { | ||
929 | p->RIOError.Error = COPYOUT_FAILED; | ||
930 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n"); | ||
931 | return -EFAULT; | ||
932 | } | ||
933 | return retval; | ||
934 | |||
935 | case RIO_HOST_DPRAM: | ||
936 | rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n"); | ||
937 | if (copy_from_user(&HostDpRam, argp, sizeof(HostDpRam))) { | ||
938 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); | ||
939 | p->RIOError.Error = COPYIN_FAILED; | ||
940 | return -EFAULT; | ||
941 | } | ||
942 | if (HostDpRam.HostNum >= p->RIONumHosts) { | ||
943 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
944 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum); | ||
945 | return -ENXIO; | ||
946 | } | ||
947 | rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum); | ||
948 | |||
949 | if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) { | ||
950 | int off; | ||
951 | /* It's hardware like this that really gets on my tits. */ | ||
952 | static unsigned char copy[sizeof(struct DpRam)]; | ||
953 | for (off = 0; off < sizeof(struct DpRam); off++) | ||
954 | copy[off] = readb(p->RIOHosts[HostDpRam.HostNum].Caddr + off); | ||
955 | if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) { | ||
956 | p->RIOError.Error = COPYOUT_FAILED; | ||
957 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); | ||
958 | return -EFAULT; | ||
959 | } | ||
960 | } else if (copy_from_io(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) { | ||
961 | p->RIOError.Error = COPYOUT_FAILED; | ||
962 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); | ||
963 | return -EFAULT; | ||
964 | } | ||
965 | return retval; | ||
966 | |||
967 | case RIO_SET_BUSY: | ||
968 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); | ||
969 | if (arg > 511) { | ||
970 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", arg); | ||
971 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
972 | return -EINVAL; | ||
973 | } | ||
974 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
975 | p->RIOPortp[arg]->State |= RIO_BUSY; | ||
976 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
977 | return retval; | ||
978 | |||
979 | case RIO_HOST_PORT: | ||
980 | /* | ||
981 | ** The daemon want port information | ||
982 | ** (probably for debug reasons) | ||
983 | */ | ||
984 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); | ||
985 | if (copy_from_user(&PortReq, argp, sizeof(PortReq))) { | ||
986 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); | ||
987 | p->RIOError.Error = COPYIN_FAILED; | ||
988 | return -EFAULT; | ||
989 | } | ||
990 | |||
991 | if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */ | ||
992 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort); | ||
993 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
994 | return -ENXIO; | ||
995 | } | ||
996 | rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort); | ||
997 | if (copy_to_user(PortReq.PortP, p->RIOPortp[PortReq.SysPort], sizeof(struct Port))) { | ||
998 | p->RIOError.Error = COPYOUT_FAILED; | ||
999 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n"); | ||
1000 | return -EFAULT; | ||
1001 | } | ||
1002 | return retval; | ||
1003 | |||
1004 | case RIO_HOST_RUP: | ||
1005 | /* | ||
1006 | ** The daemon want rup information | ||
1007 | ** (probably for debug reasons) | ||
1008 | */ | ||
1009 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); | ||
1010 | if (copy_from_user(&RupReq, argp, sizeof(RupReq))) { | ||
1011 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); | ||
1012 | p->RIOError.Error = COPYIN_FAILED; | ||
1013 | return -EFAULT; | ||
1014 | } | ||
1015 | if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */ | ||
1016 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum); | ||
1017 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1018 | return -ENXIO; | ||
1019 | } | ||
1020 | if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) { /* eek! */ | ||
1021 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum); | ||
1022 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | ||
1023 | return -EINVAL; | ||
1024 | } | ||
1025 | HostP = &p->RIOHosts[RupReq.HostNum]; | ||
1026 | |||
1027 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { | ||
1028 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum); | ||
1029 | p->RIOError.Error = HOST_NOT_RUNNING; | ||
1030 | return -EIO; | ||
1031 | } | ||
1032 | rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum); | ||
1033 | |||
1034 | if (copy_from_io(RupReq.RupP, HostP->UnixRups[RupReq.RupNum].RupP, sizeof(struct RUP))) { | ||
1035 | p->RIOError.Error = COPYOUT_FAILED; | ||
1036 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); | ||
1037 | return -EFAULT; | ||
1038 | } | ||
1039 | return retval; | ||
1040 | |||
1041 | case RIO_HOST_LPB: | ||
1042 | /* | ||
1043 | ** The daemon want lpb information | ||
1044 | ** (probably for debug reasons) | ||
1045 | */ | ||
1046 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); | ||
1047 | if (copy_from_user(&LpbReq, argp, sizeof(LpbReq))) { | ||
1048 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); | ||
1049 | p->RIOError.Error = COPYIN_FAILED; | ||
1050 | return -EFAULT; | ||
1051 | } | ||
1052 | if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */ | ||
1053 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host); | ||
1054 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1055 | return -ENXIO; | ||
1056 | } | ||
1057 | if (LpbReq.Link >= LINKS_PER_UNIT) { /* eek! */ | ||
1058 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link); | ||
1059 | p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; | ||
1060 | return -EINVAL; | ||
1061 | } | ||
1062 | HostP = &p->RIOHosts[LpbReq.Host]; | ||
1063 | |||
1064 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { | ||
1065 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host); | ||
1066 | p->RIOError.Error = HOST_NOT_RUNNING; | ||
1067 | return -EIO; | ||
1068 | } | ||
1069 | rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); | ||
1070 | |||
1071 | if (copy_from_io(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) { | ||
1072 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); | ||
1073 | p->RIOError.Error = COPYOUT_FAILED; | ||
1074 | return -EFAULT; | ||
1075 | } | ||
1076 | return retval; | ||
1077 | |||
1078 | /* | ||
1079 | ** Here 3 IOCTL's that allow us to change the way in which | ||
1080 | ** rio logs errors. send them just to syslog or send them | ||
1081 | ** to both syslog and console or send them to just the console. | ||
1082 | ** | ||
1083 | ** See RioStrBuf() in util.c for the other half. | ||
1084 | */ | ||
1085 | case RIO_SYSLOG_ONLY: | ||
1086 | p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ | ||
1087 | return 0; | ||
1088 | |||
1089 | case RIO_SYSLOG_CONS: | ||
1090 | p->RIOPrintLogState = PRINT_TO_LOG_CONS; /* syslog and console */ | ||
1091 | return 0; | ||
1092 | |||
1093 | case RIO_CONS_ONLY: | ||
1094 | p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ | ||
1095 | return 0; | ||
1096 | |||
1097 | case RIO_SIGNALS_ON: | ||
1098 | if (p->RIOSignalProcess) { | ||
1099 | p->RIOError.Error = SIGNALS_ALREADY_SET; | ||
1100 | return -EBUSY; | ||
1101 | } | ||
1102 | /* FIXME: PID tracking */ | ||
1103 | p->RIOSignalProcess = current->pid; | ||
1104 | p->RIOPrintDisabled = DONT_PRINT; | ||
1105 | return retval; | ||
1106 | |||
1107 | case RIO_SIGNALS_OFF: | ||
1108 | if (p->RIOSignalProcess != current->pid) { | ||
1109 | p->RIOError.Error = NOT_RECEIVING_PROCESS; | ||
1110 | return -EPERM; | ||
1111 | } | ||
1112 | rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n"); | ||
1113 | p->RIOSignalProcess = 0; | ||
1114 | return retval; | ||
1115 | |||
1116 | case RIO_SET_BYTE_MODE: | ||
1117 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1118 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1119 | p->RIOHosts[Host].Mode &= ~WORD_OPERATION; | ||
1120 | return retval; | ||
1121 | |||
1122 | case RIO_SET_WORD_MODE: | ||
1123 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1124 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1125 | p->RIOHosts[Host].Mode |= WORD_OPERATION; | ||
1126 | return retval; | ||
1127 | |||
1128 | case RIO_SET_FAST_BUS: | ||
1129 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1130 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1131 | p->RIOHosts[Host].Mode |= FAST_AT_BUS; | ||
1132 | return retval; | ||
1133 | |||
1134 | case RIO_SET_SLOW_BUS: | ||
1135 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1136 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1137 | p->RIOHosts[Host].Mode &= ~FAST_AT_BUS; | ||
1138 | return retval; | ||
1139 | |||
1140 | case RIO_MAP_B50_TO_50: | ||
1141 | case RIO_MAP_B50_TO_57600: | ||
1142 | case RIO_MAP_B110_TO_110: | ||
1143 | case RIO_MAP_B110_TO_115200: | ||
1144 | rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n"); | ||
1145 | port = arg; | ||
1146 | if (port < 0 || port > 511) { | ||
1147 | rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); | ||
1148 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1149 | return -EINVAL; | ||
1150 | } | ||
1151 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1152 | switch (cmd) { | ||
1153 | case RIO_MAP_B50_TO_50: | ||
1154 | p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50; | ||
1155 | break; | ||
1156 | case RIO_MAP_B50_TO_57600: | ||
1157 | p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50; | ||
1158 | break; | ||
1159 | case RIO_MAP_B110_TO_110: | ||
1160 | p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110; | ||
1161 | break; | ||
1162 | case RIO_MAP_B110_TO_115200: | ||
1163 | p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110; | ||
1164 | break; | ||
1165 | } | ||
1166 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1167 | return retval; | ||
1168 | |||
1169 | case RIO_STREAM_INFO: | ||
1170 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n"); | ||
1171 | return -EINVAL; | ||
1172 | |||
1173 | case RIO_SEND_PACKET: | ||
1174 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); | ||
1175 | if (copy_from_user(&SendPack, argp, sizeof(SendPack))) { | ||
1176 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); | ||
1177 | p->RIOError.Error = COPYIN_FAILED; | ||
1178 | return -EFAULT; | ||
1179 | } | ||
1180 | if (SendPack.PortNum >= 128) { | ||
1181 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1182 | return -ENXIO; | ||
1183 | } | ||
1184 | |||
1185 | PortP = p->RIOPortp[SendPack.PortNum]; | ||
1186 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1187 | |||
1188 | if (!can_add_transmit(&PacketP, PortP)) { | ||
1189 | p->RIOError.Error = UNIT_IS_IN_USE; | ||
1190 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1191 | return -ENOSPC; | ||
1192 | } | ||
1193 | |||
1194 | for (loop = 0; loop < (ushort) (SendPack.Len & 127); loop++) | ||
1195 | writeb(SendPack.Data[loop], &PacketP->data[loop]); | ||
1196 | |||
1197 | writeb(SendPack.Len, &PacketP->len); | ||
1198 | |||
1199 | add_transmit(PortP); | ||
1200 | /* | ||
1201 | ** Count characters transmitted for port statistics reporting | ||
1202 | */ | ||
1203 | if (PortP->statsGather) | ||
1204 | PortP->txchars += (SendPack.Len & 127); | ||
1205 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1206 | return retval; | ||
1207 | |||
1208 | case RIO_NO_MESG: | ||
1209 | if (su) | ||
1210 | p->RIONoMessage = 1; | ||
1211 | return su ? 0 : -EPERM; | ||
1212 | |||
1213 | case RIO_MESG: | ||
1214 | if (su) | ||
1215 | p->RIONoMessage = 0; | ||
1216 | return su ? 0 : -EPERM; | ||
1217 | |||
1218 | case RIO_WHAT_MESG: | ||
1219 | if (copy_to_user(argp, &p->RIONoMessage, sizeof(p->RIONoMessage))) { | ||
1220 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); | ||
1221 | p->RIOError.Error = COPYOUT_FAILED; | ||
1222 | return -EFAULT; | ||
1223 | } | ||
1224 | return 0; | ||
1225 | |||
1226 | case RIO_MEM_DUMP: | ||
1227 | if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { | ||
1228 | p->RIOError.Error = COPYIN_FAILED; | ||
1229 | return -EFAULT; | ||
1230 | } | ||
1231 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr); | ||
1232 | |||
1233 | if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { | ||
1234 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | ||
1235 | return -EINVAL; | ||
1236 | } | ||
1237 | |||
1238 | if (SubCmd.Host >= p->RIONumHosts) { | ||
1239 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1240 | return -EINVAL; | ||
1241 | } | ||
1242 | |||
1243 | port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort; | ||
1244 | |||
1245 | PortP = p->RIOPortp[port]; | ||
1246 | |||
1247 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1248 | |||
1249 | if (RIOPreemptiveCmd(p, PortP, RIOC_MEMDUMP) == RIO_FAIL) { | ||
1250 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); | ||
1251 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1252 | return -EBUSY; | ||
1253 | } else | ||
1254 | PortP->State |= RIO_BUSY; | ||
1255 | |||
1256 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1257 | if (copy_to_user(argp, p->RIOMemDump, MEMDUMP_SIZE)) { | ||
1258 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); | ||
1259 | p->RIOError.Error = COPYOUT_FAILED; | ||
1260 | return -EFAULT; | ||
1261 | } | ||
1262 | return 0; | ||
1263 | |||
1264 | case RIO_TICK: | ||
1265 | if (arg >= p->RIONumHosts) | ||
1266 | return -EINVAL; | ||
1267 | rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", arg); | ||
1268 | writeb(0xFF, &p->RIOHosts[arg].SetInt); | ||
1269 | return 0; | ||
1270 | |||
1271 | case RIO_TOCK: | ||
1272 | if (arg >= p->RIONumHosts) | ||
1273 | return -EINVAL; | ||
1274 | rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", arg); | ||
1275 | writeb(0xFF, &p->RIOHosts[arg].ResetInt); | ||
1276 | return 0; | ||
1277 | |||
1278 | case RIO_READ_CHECK: | ||
1279 | /* Check reads for pkts with data[0] the same */ | ||
1280 | p->RIOReadCheck = !p->RIOReadCheck; | ||
1281 | if (copy_to_user(argp, &p->RIOReadCheck, sizeof(unsigned int))) { | ||
1282 | p->RIOError.Error = COPYOUT_FAILED; | ||
1283 | return -EFAULT; | ||
1284 | } | ||
1285 | return 0; | ||
1286 | |||
1287 | case RIO_READ_REGISTER: | ||
1288 | if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { | ||
1289 | p->RIOError.Error = COPYIN_FAILED; | ||
1290 | return -EFAULT; | ||
1291 | } | ||
1292 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr); | ||
1293 | |||
1294 | if (SubCmd.Port > 511) { | ||
1295 | rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port); | ||
1296 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1297 | return -EINVAL; | ||
1298 | } | ||
1299 | |||
1300 | if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { | ||
1301 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | ||
1302 | return -EINVAL; | ||
1303 | } | ||
1304 | |||
1305 | if (SubCmd.Host >= p->RIONumHosts) { | ||
1306 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1307 | return -EINVAL; | ||
1308 | } | ||
1309 | |||
1310 | port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port; | ||
1311 | PortP = p->RIOPortp[port]; | ||
1312 | |||
1313 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1314 | |||
1315 | if (RIOPreemptiveCmd(p, PortP, RIOC_READ_REGISTER) == | ||
1316 | RIO_FAIL) { | ||
1317 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); | ||
1318 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1319 | return -EBUSY; | ||
1320 | } else | ||
1321 | PortP->State |= RIO_BUSY; | ||
1322 | |||
1323 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1324 | if (copy_to_user(argp, &p->CdRegister, sizeof(unsigned int))) { | ||
1325 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); | ||
1326 | p->RIOError.Error = COPYOUT_FAILED; | ||
1327 | return -EFAULT; | ||
1328 | } | ||
1329 | return 0; | ||
1330 | /* | ||
1331 | ** rio_make_dev: given port number (0-511) ORed with port type | ||
1332 | ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t | ||
1333 | ** value to pass to mknod to create the correct device node. | ||
1334 | */ | ||
1335 | case RIO_MAKE_DEV: | ||
1336 | { | ||
1337 | unsigned int port = arg & RIO_MODEM_MASK; | ||
1338 | unsigned int ret; | ||
1339 | |||
1340 | switch (arg & RIO_DEV_MASK) { | ||
1341 | case RIO_DEV_DIRECT: | ||
1342 | ret = drv_makedev(MAJOR(dev), port); | ||
1343 | rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret); | ||
1344 | return ret; | ||
1345 | case RIO_DEV_MODEM: | ||
1346 | ret = drv_makedev(MAJOR(dev), (port | RIO_MODEM_BIT)); | ||
1347 | rio_dprintk(RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n", port, ret); | ||
1348 | return ret; | ||
1349 | case RIO_DEV_XPRINT: | ||
1350 | ret = drv_makedev(MAJOR(dev), port); | ||
1351 | rio_dprintk(RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n", port, ret); | ||
1352 | return ret; | ||
1353 | } | ||
1354 | rio_dprintk(RIO_DEBUG_CTRL, "MAKE Device is called\n"); | ||
1355 | return -EINVAL; | ||
1356 | } | ||
1357 | /* | ||
1358 | ** rio_minor: given a dev_t from a stat() call, return | ||
1359 | ** the port number (0-511) ORed with the port type | ||
1360 | ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT ) | ||
1361 | */ | ||
1362 | case RIO_MINOR: | ||
1363 | { | ||
1364 | dev_t dv; | ||
1365 | int mino; | ||
1366 | unsigned long ret; | ||
1367 | |||
1368 | dv = (dev_t) (arg); | ||
1369 | mino = RIO_UNMODEM(dv); | ||
1370 | |||
1371 | if (RIO_ISMODEM(dv)) { | ||
1372 | rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino); | ||
1373 | ret = mino | RIO_DEV_MODEM; | ||
1374 | } else { | ||
1375 | rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino); | ||
1376 | ret = mino | RIO_DEV_DIRECT; | ||
1377 | } | ||
1378 | return ret; | ||
1379 | } | ||
1380 | } | ||
1381 | rio_dprintk(RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n", cmd); | ||
1382 | p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; | ||
1383 | |||
1384 | func_exit(); | ||
1385 | return -EINVAL; | ||
1386 | } | ||
1387 | |||
1388 | /* | ||
1389 | ** Pre-emptive commands go on RUPs and are only one byte long. | ||
1390 | */ | ||
1391 | int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) | ||
1392 | { | ||
1393 | struct CmdBlk *CmdBlkP; | ||
1394 | struct PktCmd_M *PktCmdP; | ||
1395 | int Ret; | ||
1396 | ushort rup; | ||
1397 | int port; | ||
1398 | |||
1399 | if (PortP->State & RIO_DELETED) { | ||
1400 | rio_dprintk(RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n"); | ||
1401 | return RIO_FAIL; | ||
1402 | } | ||
1403 | |||
1404 | if ((PortP->InUse == (typeof(PortP->InUse))-1) || | ||
1405 | !(CmdBlkP = RIOGetCmdBlk())) { | ||
1406 | rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block " | ||
1407 | "for command %d on port %d\n", Cmd, PortP->PortNum); | ||
1408 | return RIO_FAIL; | ||
1409 | } | ||
1410 | |||
1411 | rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n", | ||
1412 | CmdBlkP, PortP->InUse); | ||
1413 | |||
1414 | PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0]; | ||
1415 | |||
1416 | CmdBlkP->Packet.src_unit = 0; | ||
1417 | if (PortP->SecondBlock) | ||
1418 | rup = PortP->ID2; | ||
1419 | else | ||
1420 | rup = PortP->RupNum; | ||
1421 | CmdBlkP->Packet.dest_unit = rup; | ||
1422 | CmdBlkP->Packet.src_port = COMMAND_RUP; | ||
1423 | CmdBlkP->Packet.dest_port = COMMAND_RUP; | ||
1424 | CmdBlkP->Packet.len = PKT_CMD_BIT | 2; | ||
1425 | CmdBlkP->PostFuncP = RIOUnUse; | ||
1426 | CmdBlkP->PostArg = (unsigned long) PortP; | ||
1427 | PktCmdP->Command = Cmd; | ||
1428 | port = PortP->HostPort % (ushort) PORTS_PER_RTA; | ||
1429 | /* | ||
1430 | ** Index ports 8-15 for 2nd block of 16 port RTA. | ||
1431 | */ | ||
1432 | if (PortP->SecondBlock) | ||
1433 | port += (ushort) PORTS_PER_RTA; | ||
1434 | PktCmdP->PhbNum = port; | ||
1435 | |||
1436 | switch (Cmd) { | ||
1437 | case RIOC_MEMDUMP: | ||
1438 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p " | ||
1439 | "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); | ||
1440 | PktCmdP->SubCommand = RIOC_MEMDUMP; | ||
1441 | PktCmdP->SubAddr = SubCmd.Addr; | ||
1442 | break; | ||
1443 | case RIOC_FCLOSE: | ||
1444 | rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", | ||
1445 | CmdBlkP); | ||
1446 | break; | ||
1447 | case RIOC_READ_REGISTER: | ||
1448 | rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) " | ||
1449 | "command blk %p\n", (int) SubCmd.Addr, CmdBlkP); | ||
1450 | PktCmdP->SubCommand = RIOC_READ_REGISTER; | ||
1451 | PktCmdP->SubAddr = SubCmd.Addr; | ||
1452 | break; | ||
1453 | case RIOC_RESUME: | ||
1454 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", | ||
1455 | CmdBlkP); | ||
1456 | break; | ||
1457 | case RIOC_RFLUSH: | ||
1458 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", | ||
1459 | CmdBlkP); | ||
1460 | CmdBlkP->PostFuncP = RIORFlushEnable; | ||
1461 | break; | ||
1462 | case RIOC_SUSPEND: | ||
1463 | rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", | ||
1464 | CmdBlkP); | ||
1465 | break; | ||
1466 | |||
1467 | case RIOC_MGET: | ||
1468 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", | ||
1469 | CmdBlkP); | ||
1470 | break; | ||
1471 | |||
1472 | case RIOC_MSET: | ||
1473 | case RIOC_MBIC: | ||
1474 | case RIOC_MBIS: | ||
1475 | CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; | ||
1476 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command " | ||
1477 | "blk %p\n", CmdBlkP); | ||
1478 | break; | ||
1479 | |||
1480 | case RIOC_WFLUSH: | ||
1481 | /* | ||
1482 | ** If we have queued up the maximum number of Write flushes | ||
1483 | ** allowed then we should not bother sending any more to the | ||
1484 | ** RTA. | ||
1485 | */ | ||
1486 | if (PortP->WflushFlag == (typeof(PortP->WflushFlag))-1) { | ||
1487 | rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, " | ||
1488 | "WflushFlag about to wrap!"); | ||
1489 | RIOFreeCmdBlk(CmdBlkP); | ||
1490 | return (RIO_FAIL); | ||
1491 | } else { | ||
1492 | rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command " | ||
1493 | "blk %p\n", CmdBlkP); | ||
1494 | CmdBlkP->PostFuncP = RIOWFlushMark; | ||
1495 | } | ||
1496 | break; | ||
1497 | } | ||
1498 | |||
1499 | PortP->InUse++; | ||
1500 | |||
1501 | Ret = RIOQueueCmdBlk(PortP->HostP, rup, CmdBlkP); | ||
1502 | |||
1503 | return Ret; | ||
1504 | } | ||
diff --git a/drivers/char/rio/riodrvr.h b/drivers/char/rio/riodrvr.h deleted file mode 100644 index 0907e711b355..000000000000 --- a/drivers/char/rio/riodrvr.h +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : riodrvr.h | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 09:22:46 | ||
26 | ** Retrieved : 11/6/98 09:22:46 | ||
27 | ** | ||
28 | ** ident @(#)riodrvr.h 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __riodrvr_h | ||
34 | #define __riodrvr_h | ||
35 | |||
36 | #include <asm/param.h> /* for HZ */ | ||
37 | |||
38 | #define MEMDUMP_SIZE 32 | ||
39 | #define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT) | ||
40 | |||
41 | |||
42 | struct rio_info { | ||
43 | int mode; /* Intr or polled, word/byte */ | ||
44 | spinlock_t RIOIntrSem; /* Interrupt thread sem */ | ||
45 | int current_chan; /* current channel */ | ||
46 | int RIOFailed; /* Not initialised ? */ | ||
47 | int RIOInstallAttempts; /* no. of rio-install() calls */ | ||
48 | int RIOLastPCISearch; /* status of last search */ | ||
49 | int RIONumHosts; /* Number of RIO Hosts */ | ||
50 | struct Host *RIOHosts; /* RIO Host values */ | ||
51 | struct Port **RIOPortp; /* RIO port values */ | ||
52 | /* | ||
53 | ** 02.03.1999 ARG - ESIL 0820 fix | ||
54 | ** We no longer use RIOBootMode | ||
55 | ** | ||
56 | int RIOBootMode; * RIO boot mode * | ||
57 | ** | ||
58 | */ | ||
59 | int RIOPrintDisabled; /* RIO printing disabled ? */ | ||
60 | int RIOPrintLogState; /* RIO printing state ? */ | ||
61 | int RIOPolling; /* Polling ? */ | ||
62 | /* | ||
63 | ** 09.12.1998 ARG - ESIL 0776 part fix | ||
64 | ** The 'RIO_QUICK_CHECK' ioctl was using RIOHalted. | ||
65 | ** The fix for this ESIL introduces another member (RIORtaDisCons) here to be | ||
66 | ** updated in RIOConCon() - to keep track of RTA connections/disconnections. | ||
67 | ** 'RIO_QUICK_CHECK' now returns the value of RIORtaDisCons. | ||
68 | */ | ||
69 | int RIOHalted; /* halted ? */ | ||
70 | int RIORtaDisCons; /* RTA connections/disconnections */ | ||
71 | unsigned int RIOReadCheck; /* Rio read check */ | ||
72 | unsigned int RIONoMessage; /* To display message or not */ | ||
73 | unsigned int RIONumBootPkts; /* how many packets for an RTA */ | ||
74 | unsigned int RIOBootCount; /* size of RTA code */ | ||
75 | unsigned int RIOBooting; /* count of outstanding boots */ | ||
76 | unsigned int RIOSystemUp; /* Booted ?? */ | ||
77 | unsigned int RIOCounting; /* for counting interrupts */ | ||
78 | unsigned int RIOIntCount; /* # of intr since last check */ | ||
79 | unsigned int RIOTxCount; /* number of xmit intrs */ | ||
80 | unsigned int RIORxCount; /* number of rx intrs */ | ||
81 | unsigned int RIORupCount; /* number of rup intrs */ | ||
82 | int RIXTimer; | ||
83 | int RIOBufferSize; /* Buffersize */ | ||
84 | int RIOBufferMask; /* Buffersize */ | ||
85 | |||
86 | int RIOFirstMajor; /* First host card's major no */ | ||
87 | |||
88 | unsigned int RIOLastPortsMapped; /* highest port number known */ | ||
89 | unsigned int RIOFirstPortsMapped; /* lowest port number known */ | ||
90 | |||
91 | unsigned int RIOLastPortsBooted; /* highest port number running */ | ||
92 | unsigned int RIOFirstPortsBooted; /* lowest port number running */ | ||
93 | |||
94 | unsigned int RIOLastPortsOpened; /* highest port number running */ | ||
95 | unsigned int RIOFirstPortsOpened; /* lowest port number running */ | ||
96 | |||
97 | /* Flag to say that the topology information has been changed. */ | ||
98 | unsigned int RIOQuickCheck; | ||
99 | unsigned int CdRegister; /* ??? */ | ||
100 | int RIOSignalProcess; /* Signalling process */ | ||
101 | int rio_debug; /* To debug ... */ | ||
102 | int RIODebugWait; /* For what ??? */ | ||
103 | int tpri; /* Thread prio */ | ||
104 | int tid; /* Thread id */ | ||
105 | unsigned int _RIO_Polled; /* Counter for polling */ | ||
106 | unsigned int _RIO_Interrupted; /* Counter for interrupt */ | ||
107 | int intr_tid; /* iointset return value */ | ||
108 | int TxEnSem; /* TxEnable Semaphore */ | ||
109 | |||
110 | |||
111 | struct Error RIOError; /* to Identify what went wrong */ | ||
112 | struct Conf RIOConf; /* Configuration ??? */ | ||
113 | struct ttystatics channel[RIO_PORTS]; /* channel information */ | ||
114 | char RIOBootPackets[1 + (SIXTY_FOUR_K / RTA_BOOT_DATA_SIZE)] | ||
115 | [RTA_BOOT_DATA_SIZE]; | ||
116 | struct Map RIOConnectTable[TOTAL_MAP_ENTRIES]; | ||
117 | struct Map RIOSavedTable[TOTAL_MAP_ENTRIES]; | ||
118 | |||
119 | /* RTA to host binding table for master/slave operation */ | ||
120 | unsigned long RIOBindTab[MAX_RTA_BINDINGS]; | ||
121 | /* RTA memory dump variable */ | ||
122 | unsigned char RIOMemDump[MEMDUMP_SIZE]; | ||
123 | struct ModuleInfo RIOModuleTypes[MAX_MODULE_TYPES]; | ||
124 | |||
125 | }; | ||
126 | |||
127 | |||
128 | #ifdef linux | ||
129 | #define debug(x) printk x | ||
130 | #else | ||
131 | #define debug(x) kkprintf x | ||
132 | #endif | ||
133 | |||
134 | |||
135 | |||
136 | #define RIO_RESET_INT 0x7d80 | ||
137 | |||
138 | #endif /* __riodrvr.h */ | ||
diff --git a/drivers/char/rio/rioinfo.h b/drivers/char/rio/rioinfo.h deleted file mode 100644 index 42ff1e79d96f..000000000000 --- a/drivers/char/rio/rioinfo.h +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rioinfo.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 14:07:49 | ||
26 | ** Retrieved : 11/6/98 14:07:50 | ||
27 | ** | ||
28 | ** ident @(#)rioinfo.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rioinfo_h | ||
34 | #define __rioinfo_h | ||
35 | |||
36 | /* | ||
37 | ** Host card data structure | ||
38 | */ | ||
39 | struct RioHostInfo { | ||
40 | long location; /* RIO Card Base I/O address */ | ||
41 | long vector; /* RIO Card IRQ vector */ | ||
42 | int bus; /* ISA/EISA/MCA/PCI */ | ||
43 | int mode; /* pointer to host mode - INTERRUPT / POLLED */ | ||
44 | struct old_sgttyb | ||
45 | *Sg; /* pointer to default term characteristics */ | ||
46 | }; | ||
47 | |||
48 | |||
49 | /* Mode in rio device info */ | ||
50 | #define INTERRUPTED_MODE 0x01 /* Interrupt is generated */ | ||
51 | #define POLLED_MODE 0x02 /* No interrupt */ | ||
52 | #define AUTO_MODE 0x03 /* Auto mode */ | ||
53 | |||
54 | #define WORD_ACCESS_MODE 0x10 /* Word Access Mode */ | ||
55 | #define BYTE_ACCESS_MODE 0x20 /* Byte Access Mode */ | ||
56 | |||
57 | |||
58 | /* Bus type that RIO supports */ | ||
59 | #define ISA_BUS 0x01 /* The card is ISA */ | ||
60 | #define EISA_BUS 0x02 /* The card is EISA */ | ||
61 | #define MCA_BUS 0x04 /* The card is MCA */ | ||
62 | #define PCI_BUS 0x08 /* The card is PCI */ | ||
63 | |||
64 | /* | ||
65 | ** 11.11.1998 ARG - ESIL ???? part fix | ||
66 | ** Moved definition for 'CHAN' here from rioinfo.c (it is now | ||
67 | ** called 'DEF_TERM_CHARACTERISTICS'). | ||
68 | */ | ||
69 | |||
70 | #define DEF_TERM_CHARACTERISTICS \ | ||
71 | { \ | ||
72 | B19200, B19200, /* input and output speed */ \ | ||
73 | 'H' - '@', /* erase char */ \ | ||
74 | -1, /* 2nd erase char */ \ | ||
75 | 'U' - '@', /* kill char */ \ | ||
76 | ECHO | CRMOD, /* mode */ \ | ||
77 | 'C' - '@', /* interrupt character */ \ | ||
78 | '\\' - '@', /* quit char */ \ | ||
79 | 'Q' - '@', /* start char */ \ | ||
80 | 'S' - '@', /* stop char */ \ | ||
81 | 'D' - '@', /* EOF */ \ | ||
82 | -1, /* brk */ \ | ||
83 | (LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */ \ | ||
84 | 'Z' - '@', /* process stop */ \ | ||
85 | 'Y' - '@', /* delayed stop */ \ | ||
86 | 'R' - '@', /* reprint line */ \ | ||
87 | 'O' - '@', /* flush output */ \ | ||
88 | 'W' - '@', /* word erase */ \ | ||
89 | 'V' - '@' /* literal next char */ \ | ||
90 | } | ||
91 | |||
92 | #endif /* __rioinfo_h */ | ||
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c deleted file mode 100644 index 24a282bb89d4..000000000000 --- a/drivers/char/rio/rioinit.c +++ /dev/null | |||
@@ -1,421 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rioinit.c | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 10:33:43 | ||
26 | ** Retrieved : 11/6/98 10:33:49 | ||
27 | ** | ||
28 | ** ident @(#)rioinit.c 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <asm/io.h> | ||
37 | #include <asm/system.h> | ||
38 | #include <asm/string.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | #include <linux/termios.h> | ||
42 | #include <linux/serial.h> | ||
43 | |||
44 | #include <linux/generic_serial.h> | ||
45 | |||
46 | |||
47 | #include "linux_compat.h" | ||
48 | #include "pkt.h" | ||
49 | #include "daemon.h" | ||
50 | #include "rio.h" | ||
51 | #include "riospace.h" | ||
52 | #include "cmdpkt.h" | ||
53 | #include "map.h" | ||
54 | #include "rup.h" | ||
55 | #include "port.h" | ||
56 | #include "riodrvr.h" | ||
57 | #include "rioinfo.h" | ||
58 | #include "func.h" | ||
59 | #include "errors.h" | ||
60 | #include "pci.h" | ||
61 | |||
62 | #include "parmmap.h" | ||
63 | #include "unixrup.h" | ||
64 | #include "board.h" | ||
65 | #include "host.h" | ||
66 | #include "phb.h" | ||
67 | #include "link.h" | ||
68 | #include "cmdblk.h" | ||
69 | #include "route.h" | ||
70 | #include "cirrus.h" | ||
71 | #include "rioioctl.h" | ||
72 | #include "rio_linux.h" | ||
73 | |||
74 | int RIOPCIinit(struct rio_info *p, int Mode); | ||
75 | |||
76 | static int RIOScrub(int, u8 __iomem *, int); | ||
77 | |||
78 | |||
79 | /** | ||
80 | ** RIOAssignAT : | ||
81 | ** | ||
82 | ** Fill out the fields in the p->RIOHosts structure now we know we know | ||
83 | ** we have a board present. | ||
84 | ** | ||
85 | ** bits < 0 indicates 8 bit operation requested, | ||
86 | ** bits > 0 indicates 16 bit operation. | ||
87 | */ | ||
88 | |||
89 | int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode) | ||
90 | { | ||
91 | int bits; | ||
92 | struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr; | ||
93 | |||
94 | if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE)) | ||
95 | bits = BYTE_OPERATION; | ||
96 | else | ||
97 | bits = WORD_OPERATION; | ||
98 | |||
99 | /* | ||
100 | ** Board has passed its scrub test. Fill in all the | ||
101 | ** transient stuff. | ||
102 | */ | ||
103 | p->RIOHosts[p->RIONumHosts].Caddr = virtAddr; | ||
104 | p->RIOHosts[p->RIONumHosts].CardP = virtAddr; | ||
105 | |||
106 | /* | ||
107 | ** Revision 01 AT host cards don't support WORD operations, | ||
108 | */ | ||
109 | if (readb(&cardp->DpRevision) == 01) | ||
110 | bits = BYTE_OPERATION; | ||
111 | |||
112 | p->RIOHosts[p->RIONumHosts].Type = RIO_AT; | ||
113 | p->RIOHosts[p->RIONumHosts].Copy = rio_copy_to_card; | ||
114 | /* set this later */ | ||
115 | p->RIOHosts[p->RIONumHosts].Slot = -1; | ||
116 | p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits; | ||
117 | writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE , | ||
118 | &p->RIOHosts[p->RIONumHosts].Control); | ||
119 | writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); | ||
120 | writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE, | ||
121 | &p->RIOHosts[p->RIONumHosts].Control); | ||
122 | writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); | ||
123 | p->RIOHosts[p->RIONumHosts].UniqueNum = | ||
124 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)| | ||
125 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)| | ||
126 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)| | ||
127 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24); | ||
128 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum); | ||
129 | |||
130 | p->RIONumHosts++; | ||
131 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base); | ||
132 | return(1); | ||
133 | } | ||
134 | |||
135 | static u8 val[] = { | ||
136 | #ifdef VERY_LONG_TEST | ||
137 | 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, | ||
138 | 0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36, | ||
139 | #endif | ||
140 | 0xff, 0x00, 0x00 }; | ||
141 | |||
142 | #define TEST_END sizeof(val) | ||
143 | |||
144 | /* | ||
145 | ** RAM test a board. | ||
146 | ** Nothing too complicated, just enough to check it out. | ||
147 | */ | ||
148 | int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot) | ||
149 | { | ||
150 | struct DpRam __iomem *DpRam = caddr; | ||
151 | void __iomem *ram[4]; | ||
152 | int size[4]; | ||
153 | int op, bank; | ||
154 | int nbanks; | ||
155 | |||
156 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=%p, slot=%d\n", | ||
157 | type, DpRam, slot); | ||
158 | |||
159 | RIOHostReset(type, DpRam, slot); | ||
160 | |||
161 | /* | ||
162 | ** Scrub the memory. This comes in several banks: | ||
163 | ** DPsram1 - 7000h bytes | ||
164 | ** DPsram2 - 200h bytes | ||
165 | ** DPsram3 - 7000h bytes | ||
166 | ** scratch - 1000h bytes | ||
167 | */ | ||
168 | |||
169 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n"); | ||
170 | |||
171 | size[0] = DP_SRAM1_SIZE; | ||
172 | size[1] = DP_SRAM2_SIZE; | ||
173 | size[2] = DP_SRAM3_SIZE; | ||
174 | size[3] = DP_SCRATCH_SIZE; | ||
175 | |||
176 | ram[0] = DpRam->DpSram1; | ||
177 | ram[1] = DpRam->DpSram2; | ||
178 | ram[2] = DpRam->DpSram3; | ||
179 | nbanks = (type == RIO_PCI) ? 3 : 4; | ||
180 | if (nbanks == 4) | ||
181 | ram[3] = DpRam->DpScratch; | ||
182 | |||
183 | |||
184 | if (nbanks == 3) { | ||
185 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: %p(0x%x), %p(0x%x), %p(0x%x)\n", | ||
186 | ram[0], size[0], ram[1], size[1], ram[2], size[2]); | ||
187 | } else { | ||
188 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: %p(0x%x), %p(0x%x), %p(0x%x), %p(0x%x)\n", | ||
189 | ram[0], size[0], ram[1], size[1], ram[2], size[2], ram[3], size[3]); | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | ** This scrub operation will test for crosstalk between | ||
194 | ** banks. TEST_END is a magic number, and relates to the offset | ||
195 | ** within the 'val' array used by Scrub. | ||
196 | */ | ||
197 | for (op=0; op<TEST_END; op++) { | ||
198 | for (bank=0; bank<nbanks; bank++) { | ||
199 | if (RIOScrub(op, ram[bank], size[bank]) == RIO_FAIL) { | ||
200 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n", | ||
201 | bank, op); | ||
202 | return RIO_FAIL; | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | |||
207 | rio_dprintk (RIO_DEBUG_INIT, "Test completed\n"); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | |||
212 | /* | ||
213 | ** Scrub an area of RAM. | ||
214 | ** Define PRETEST and POSTTEST for a more thorough checking of the | ||
215 | ** state of the memory. | ||
216 | ** Call with op set to an index into the above 'val' array to determine | ||
217 | ** which value will be written into memory. | ||
218 | ** Call with op set to zero means that the RAM will not be read and checked | ||
219 | ** before it is written. | ||
220 | ** Call with op not zero and the RAM will be read and compared with val[op-1] | ||
221 | ** to check that the data from the previous phase was retained. | ||
222 | */ | ||
223 | |||
224 | static int RIOScrub(int op, u8 __iomem *ram, int size) | ||
225 | { | ||
226 | int off; | ||
227 | unsigned char oldbyte; | ||
228 | unsigned char newbyte; | ||
229 | unsigned char invbyte; | ||
230 | unsigned short oldword; | ||
231 | unsigned short newword; | ||
232 | unsigned short invword; | ||
233 | unsigned short swapword; | ||
234 | |||
235 | if (op) { | ||
236 | oldbyte = val[op-1]; | ||
237 | oldword = oldbyte | (oldbyte<<8); | ||
238 | } else | ||
239 | oldbyte = oldword = 0; /* Tell the compiler we've initilalized them. */ | ||
240 | newbyte = val[op]; | ||
241 | newword = newbyte | (newbyte<<8); | ||
242 | invbyte = ~newbyte; | ||
243 | invword = invbyte | (invbyte<<8); | ||
244 | |||
245 | /* | ||
246 | ** Check that the RAM contains the value that should have been left there | ||
247 | ** by the previous test (not applicable for pass zero) | ||
248 | */ | ||
249 | if (op) { | ||
250 | for (off=0; off<size; off++) { | ||
251 | if (readb(ram + off) != oldbyte) { | ||
252 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, readb(ram + off)); | ||
253 | return RIO_FAIL; | ||
254 | } | ||
255 | } | ||
256 | for (off=0; off<size; off+=2) { | ||
257 | if (readw(ram + off) != oldword) { | ||
258 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword, readw(ram + off)); | ||
259 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram+off+1)); | ||
260 | return RIO_FAIL; | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | ** Now write the INVERSE of the test data into every location, using | ||
267 | ** BYTE write operations, first checking before each byte is written | ||
268 | ** that the location contains the old value still, and checking after | ||
269 | ** the write that the location contains the data specified - this is | ||
270 | ** the BYTE read/write test. | ||
271 | */ | ||
272 | for (off=0; off<size; off++) { | ||
273 | if (op && (readb(ram + off) != oldbyte)) { | ||
274 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, readb(ram + off)); | ||
275 | return RIO_FAIL; | ||
276 | } | ||
277 | writeb(invbyte, ram + off); | ||
278 | if (readb(ram + off) != invbyte) { | ||
279 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, readb(ram + off)); | ||
280 | return RIO_FAIL; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | ** now, use WORD operations to write the test value into every location, | ||
286 | ** check as before that the location contains the previous test value | ||
287 | ** before overwriting, and that it contains the data value written | ||
288 | ** afterwards. | ||
289 | ** This is the WORD operation test. | ||
290 | */ | ||
291 | for (off=0; off<size; off+=2) { | ||
292 | if (readw(ram + off) != invword) { | ||
293 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, readw(ram + off)); | ||
294 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram+off+1)); | ||
295 | return RIO_FAIL; | ||
296 | } | ||
297 | |||
298 | writew(newword, ram + off); | ||
299 | if ( readw(ram + off) != newword ) { | ||
300 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, readw(ram + off)); | ||
301 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1)); | ||
302 | return RIO_FAIL; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | /* | ||
307 | ** now run through the block of memory again, first in byte mode | ||
308 | ** then in word mode, and check that all the locations contain the | ||
309 | ** required test data. | ||
310 | */ | ||
311 | for (off=0; off<size; off++) { | ||
312 | if (readb(ram + off) != newbyte) { | ||
313 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, readb(ram + off)); | ||
314 | return RIO_FAIL; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | for (off=0; off<size; off+=2) { | ||
319 | if (readw(ram + off) != newword ) { | ||
320 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, readw(ram + off)); | ||
321 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1)); | ||
322 | return RIO_FAIL; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | ** time to check out byte swapping errors | ||
328 | */ | ||
329 | swapword = invbyte | (newbyte << 8); | ||
330 | |||
331 | for (off=0; off<size; off+=2) { | ||
332 | writeb(invbyte, &ram[off]); | ||
333 | writeb(newbyte, &ram[off+1]); | ||
334 | } | ||
335 | |||
336 | for ( off=0; off<size; off+=2 ) { | ||
337 | if (readw(ram + off) != swapword) { | ||
338 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, readw(ram + off)); | ||
339 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, readb(ram + off), off+1, readb(ram + off + 1)); | ||
340 | return RIO_FAIL; | ||
341 | } | ||
342 | writew(~swapword, ram + off); | ||
343 | } | ||
344 | |||
345 | for (off=0; off<size; off+=2) { | ||
346 | if (readb(ram + off) != newbyte) { | ||
347 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, readb(ram + off)); | ||
348 | return RIO_FAIL; | ||
349 | } | ||
350 | if (readb(ram + off + 1) != invbyte) { | ||
351 | rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, readb(ram + off + 1)); | ||
352 | return RIO_FAIL; | ||
353 | } | ||
354 | writew(newword, ram + off); | ||
355 | } | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | |||
360 | int RIODefaultName(struct rio_info *p, struct Host *HostP, unsigned int UnitId) | ||
361 | { | ||
362 | memcpy(HostP->Mapping[UnitId].Name, "UNKNOWN RTA X-XX", 17); | ||
363 | HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts); | ||
364 | if ((UnitId+1) > 9) { | ||
365 | HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10); | ||
366 | HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10); | ||
367 | } | ||
368 | else { | ||
369 | HostP->Mapping[UnitId].Name[14]='1'+UnitId; | ||
370 | HostP->Mapping[UnitId].Name[15]=0; | ||
371 | } | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | #define RIO_RELEASE "Linux" | ||
376 | #define RELEASE_ID "1.0" | ||
377 | |||
378 | static struct rioVersion stVersion; | ||
379 | |||
380 | struct rioVersion *RIOVersid(void) | ||
381 | { | ||
382 | strlcpy(stVersion.version, "RIO driver for linux V1.0", | ||
383 | sizeof(stVersion.version)); | ||
384 | strlcpy(stVersion.buildDate, __DATE__, | ||
385 | sizeof(stVersion.buildDate)); | ||
386 | |||
387 | return &stVersion; | ||
388 | } | ||
389 | |||
390 | void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot) | ||
391 | { | ||
392 | /* | ||
393 | ** Reset the Tpu | ||
394 | */ | ||
395 | rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type); | ||
396 | switch ( Type ) { | ||
397 | case RIO_AT: | ||
398 | rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n"); | ||
399 | writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION | | ||
400 | SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); | ||
401 | writeb(0xFF, &DpRamP->DpResetTpu); | ||
402 | udelay(3); | ||
403 | rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); | ||
404 | writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | | ||
405 | BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); | ||
406 | writeb(0xFF, &DpRamP->DpResetTpu); | ||
407 | udelay(3); | ||
408 | break; | ||
409 | case RIO_PCI: | ||
410 | rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n"); | ||
411 | writeb(RIO_PCI_BOOT_FROM_RAM, &DpRamP->DpControl); | ||
412 | writeb(0xFF, &DpRamP->DpResetInt); | ||
413 | writeb(0xFF, &DpRamP->DpResetTpu); | ||
414 | udelay(100); | ||
415 | break; | ||
416 | default: | ||
417 | rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n"); | ||
418 | break; | ||
419 | } | ||
420 | return; | ||
421 | } | ||
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c deleted file mode 100644 index 2e71aecae206..000000000000 --- a/drivers/char/rio/riointr.c +++ /dev/null | |||
@@ -1,645 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : riointr.c | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 10:33:44 | ||
26 | ** Retrieved : 11/6/98 10:33:49 | ||
27 | ** | ||
28 | ** ident @(#)riointr.c 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/tty.h> | ||
36 | #include <linux/tty_flip.h> | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/system.h> | ||
39 | #include <asm/string.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | |||
42 | #include <linux/termios.h> | ||
43 | #include <linux/serial.h> | ||
44 | |||
45 | #include <linux/generic_serial.h> | ||
46 | |||
47 | #include <linux/delay.h> | ||
48 | |||
49 | #include "linux_compat.h" | ||
50 | #include "rio_linux.h" | ||
51 | #include "pkt.h" | ||
52 | #include "daemon.h" | ||
53 | #include "rio.h" | ||
54 | #include "riospace.h" | ||
55 | #include "cmdpkt.h" | ||
56 | #include "map.h" | ||
57 | #include "rup.h" | ||
58 | #include "port.h" | ||
59 | #include "riodrvr.h" | ||
60 | #include "rioinfo.h" | ||
61 | #include "func.h" | ||
62 | #include "errors.h" | ||
63 | #include "pci.h" | ||
64 | |||
65 | #include "parmmap.h" | ||
66 | #include "unixrup.h" | ||
67 | #include "board.h" | ||
68 | #include "host.h" | ||
69 | #include "phb.h" | ||
70 | #include "link.h" | ||
71 | #include "cmdblk.h" | ||
72 | #include "route.h" | ||
73 | #include "cirrus.h" | ||
74 | #include "rioioctl.h" | ||
75 | |||
76 | |||
77 | static void RIOReceive(struct rio_info *, struct Port *); | ||
78 | |||
79 | |||
80 | static char *firstchars(char *p, int nch) | ||
81 | { | ||
82 | static char buf[2][128]; | ||
83 | static int t = 0; | ||
84 | t = !t; | ||
85 | memcpy(buf[t], p, nch); | ||
86 | buf[t][nch] = 0; | ||
87 | return buf[t]; | ||
88 | } | ||
89 | |||
90 | |||
91 | #define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask)) | ||
92 | /* Enable and start the transmission of packets */ | ||
93 | void RIOTxEnable(char *en) | ||
94 | { | ||
95 | struct Port *PortP; | ||
96 | struct rio_info *p; | ||
97 | struct tty_struct *tty; | ||
98 | int c; | ||
99 | struct PKT __iomem *PacketP; | ||
100 | unsigned long flags; | ||
101 | |||
102 | PortP = (struct Port *) en; | ||
103 | p = (struct rio_info *) PortP->p; | ||
104 | tty = PortP->gs.port.tty; | ||
105 | |||
106 | |||
107 | rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt); | ||
108 | |||
109 | if (!PortP->gs.xmit_cnt) | ||
110 | return; | ||
111 | |||
112 | |||
113 | /* This routine is an order of magnitude simpler than the specialix | ||
114 | version. One of the disadvantages is that this version will send | ||
115 | an incomplete packet (usually 64 bytes instead of 72) once for | ||
116 | every 4k worth of data. Let's just say that this won't influence | ||
117 | performance significantly..... */ | ||
118 | |||
119 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
120 | |||
121 | while (can_add_transmit(&PacketP, PortP)) { | ||
122 | c = PortP->gs.xmit_cnt; | ||
123 | if (c > PKT_MAX_DATA_LEN) | ||
124 | c = PKT_MAX_DATA_LEN; | ||
125 | |||
126 | /* Don't copy past the end of the source buffer */ | ||
127 | if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail) | ||
128 | c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail; | ||
129 | |||
130 | { | ||
131 | int t; | ||
132 | t = (c > 10) ? 10 : c; | ||
133 | |||
134 | rio_dprintk(RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", PortP->PortNum, c, firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail, t), firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail + c - t, t)); | ||
135 | } | ||
136 | /* If for one reason or another, we can't copy more data, | ||
137 | we're done! */ | ||
138 | if (c == 0) | ||
139 | break; | ||
140 | |||
141 | rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c); | ||
142 | /* udelay (1); */ | ||
143 | |||
144 | writeb(c, &(PacketP->len)); | ||
145 | if (!(PortP->State & RIO_DELETED)) { | ||
146 | add_transmit(PortP); | ||
147 | /* | ||
148 | ** Count chars tx'd for port statistics reporting | ||
149 | */ | ||
150 | if (PortP->statsGather) | ||
151 | PortP->txchars += c; | ||
152 | } | ||
153 | PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1); | ||
154 | PortP->gs.xmit_cnt -= c; | ||
155 | } | ||
156 | |||
157 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
158 | |||
159 | if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) | ||
160 | tty_wakeup(PortP->gs.port.tty); | ||
161 | |||
162 | } | ||
163 | |||
164 | |||
165 | /* | ||
166 | ** RIO Host Service routine. Does all the work traditionally associated with an | ||
167 | ** interrupt. | ||
168 | */ | ||
169 | static int RupIntr; | ||
170 | static int RxIntr; | ||
171 | static int TxIntr; | ||
172 | |||
173 | void RIOServiceHost(struct rio_info *p, struct Host *HostP) | ||
174 | { | ||
175 | rio_spin_lock(&HostP->HostLock); | ||
176 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { | ||
177 | static int t = 0; | ||
178 | rio_spin_unlock(&HostP->HostLock); | ||
179 | if ((t++ % 200) == 0) | ||
180 | rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags); | ||
181 | return; | ||
182 | } | ||
183 | rio_spin_unlock(&HostP->HostLock); | ||
184 | |||
185 | if (readw(&HostP->ParmMapP->rup_intr)) { | ||
186 | writew(0, &HostP->ParmMapP->rup_intr); | ||
187 | p->RIORupCount++; | ||
188 | RupIntr++; | ||
189 | rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts); | ||
190 | RIOPollHostCommands(p, HostP); | ||
191 | } | ||
192 | |||
193 | if (readw(&HostP->ParmMapP->rx_intr)) { | ||
194 | int port; | ||
195 | |||
196 | writew(0, &HostP->ParmMapP->rx_intr); | ||
197 | p->RIORxCount++; | ||
198 | RxIntr++; | ||
199 | |||
200 | rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts); | ||
201 | /* | ||
202 | ** Loop through every port. If the port is mapped into | ||
203 | ** the system ( i.e. has /dev/ttyXXXX associated ) then it is | ||
204 | ** worth checking. If the port isn't open, grab any packets | ||
205 | ** hanging on its receive queue and stuff them on the free | ||
206 | ** list; check for commands on the way. | ||
207 | */ | ||
208 | for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { | ||
209 | struct Port *PortP = p->RIOPortp[port]; | ||
210 | struct tty_struct *ttyP; | ||
211 | struct PKT __iomem *PacketP; | ||
212 | |||
213 | /* | ||
214 | ** not mapped in - most of the RIOPortp[] information | ||
215 | ** has not been set up! | ||
216 | ** Optimise: ports come in bundles of eight. | ||
217 | */ | ||
218 | if (!PortP->Mapped) { | ||
219 | port += 7; | ||
220 | continue; /* with the next port */ | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | ** If the host board isn't THIS host board, check the next one. | ||
225 | ** optimise: ports come in bundles of eight. | ||
226 | */ | ||
227 | if (PortP->HostP != HostP) { | ||
228 | port += 7; | ||
229 | continue; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | ** Let us see - is the port open? If not, then don't service it. | ||
234 | */ | ||
235 | if (!(PortP->PortState & PORT_ISOPEN)) { | ||
236 | continue; | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | ** find corresponding tty structure. The process of mapping | ||
241 | ** the ports puts these here. | ||
242 | */ | ||
243 | ttyP = PortP->gs.port.tty; | ||
244 | |||
245 | /* | ||
246 | ** Lock the port before we begin working on it. | ||
247 | */ | ||
248 | rio_spin_lock(&PortP->portSem); | ||
249 | |||
250 | /* | ||
251 | ** Process received data if there is any. | ||
252 | */ | ||
253 | if (can_remove_receive(&PacketP, PortP)) | ||
254 | RIOReceive(p, PortP); | ||
255 | |||
256 | /* | ||
257 | ** If there is no data left to be read from the port, and | ||
258 | ** it's handshake bit is set, then we must clear the handshake, | ||
259 | ** so that that downstream RTA is re-enabled. | ||
260 | */ | ||
261 | if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) { | ||
262 | /* | ||
263 | ** MAGIC! ( Basically, handshake the RX buffer, so that | ||
264 | ** the RTAs upstream can be re-enabled. ) | ||
265 | */ | ||
266 | rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n"); | ||
267 | writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); | ||
268 | } | ||
269 | rio_spin_unlock(&PortP->portSem); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | if (readw(&HostP->ParmMapP->tx_intr)) { | ||
274 | int port; | ||
275 | |||
276 | writew(0, &HostP->ParmMapP->tx_intr); | ||
277 | |||
278 | p->RIOTxCount++; | ||
279 | TxIntr++; | ||
280 | rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts); | ||
281 | |||
282 | /* | ||
283 | ** Loop through every port. | ||
284 | ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX | ||
285 | ** associated ) then it is worth checking. | ||
286 | */ | ||
287 | for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { | ||
288 | struct Port *PortP = p->RIOPortp[port]; | ||
289 | struct tty_struct *ttyP; | ||
290 | struct PKT __iomem *PacketP; | ||
291 | |||
292 | /* | ||
293 | ** not mapped in - most of the RIOPortp[] information | ||
294 | ** has not been set up! | ||
295 | */ | ||
296 | if (!PortP->Mapped) { | ||
297 | port += 7; | ||
298 | continue; /* with the next port */ | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | ** If the host board isn't running, then its data structures | ||
303 | ** are no use to us - continue quietly. | ||
304 | */ | ||
305 | if (PortP->HostP != HostP) { | ||
306 | port += 7; | ||
307 | continue; /* with the next port */ | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | ** Let us see - is the port open? If not, then don't service it. | ||
312 | */ | ||
313 | if (!(PortP->PortState & PORT_ISOPEN)) { | ||
314 | continue; | ||
315 | } | ||
316 | |||
317 | rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port); | ||
318 | /* | ||
319 | ** Lock the port before we begin working on it. | ||
320 | */ | ||
321 | rio_spin_lock(&PortP->portSem); | ||
322 | |||
323 | /* | ||
324 | ** If we can't add anything to the transmit queue, then | ||
325 | ** we need do none of this processing. | ||
326 | */ | ||
327 | if (!can_add_transmit(&PacketP, PortP)) { | ||
328 | rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n"); | ||
329 | rio_spin_unlock(&PortP->portSem); | ||
330 | continue; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | ** find corresponding tty structure. The process of mapping | ||
335 | ** the ports puts these here. | ||
336 | */ | ||
337 | ttyP = PortP->gs.port.tty; | ||
338 | /* If ttyP is NULL, the port is getting closed. Forget about it. */ | ||
339 | if (!ttyP) { | ||
340 | rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n"); | ||
341 | rio_spin_unlock(&PortP->portSem); | ||
342 | continue; | ||
343 | } | ||
344 | /* | ||
345 | ** If there is more room available we start up the transmit | ||
346 | ** data process again. This can be direct I/O, if the cookmode | ||
347 | ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the | ||
348 | ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch | ||
349 | ** characters via the line discipline. We must always call | ||
350 | ** the line discipline, | ||
351 | ** so that user input characters can be echoed correctly. | ||
352 | ** | ||
353 | ** ++++ Update +++++ | ||
354 | ** With the advent of double buffering, we now see if | ||
355 | ** TxBufferOut-In is non-zero. If so, then we copy a packet | ||
356 | ** to the output place, and set it going. If this empties | ||
357 | ** the buffer, then we must issue a wakeup( ) on OUT. | ||
358 | ** If it frees space in the buffer then we must issue | ||
359 | ** a wakeup( ) on IN. | ||
360 | ** | ||
361 | ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we | ||
362 | ** have to send a WFLUSH command down the PHB, to mark the | ||
363 | ** end point of a WFLUSH. We also need to clear out any | ||
364 | ** data from the double buffer! ( note that WflushFlag is a | ||
365 | ** *count* of the number of WFLUSH commands outstanding! ) | ||
366 | ** | ||
367 | ** ++++ And there's more! | ||
368 | ** If an RTA is powered off, then on again, and rebooted, | ||
369 | ** whilst it has ports open, then we need to re-open the ports. | ||
370 | ** ( reasonable enough ). We can't do this when we spot the | ||
371 | ** re-boot, in interrupt time, because the queue is probably | ||
372 | ** full. So, when we come in here, we need to test if any | ||
373 | ** ports are in this condition, and re-open the port before | ||
374 | ** we try to send any more data to it. Now, the re-booted | ||
375 | ** RTA will be discarding packets from the PHB until it | ||
376 | ** receives this open packet, but don't worry tooo much | ||
377 | ** about that. The one thing that is interesting is the | ||
378 | ** combination of this effect and the WFLUSH effect! | ||
379 | */ | ||
380 | /* For now don't handle RTA reboots. -- REW. | ||
381 | Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */ | ||
382 | if (PortP->MagicFlags) { | ||
383 | if (PortP->MagicFlags & MAGIC_REBOOT) { | ||
384 | /* | ||
385 | ** well, the RTA has been rebooted, and there is room | ||
386 | ** on its queue to add the open packet that is required. | ||
387 | ** | ||
388 | ** The messy part of this line is trying to decide if | ||
389 | ** we need to call the Param function as a tty or as | ||
390 | ** a modem. | ||
391 | ** DONT USE CLOCAL AS A TEST FOR THIS! | ||
392 | ** | ||
393 | ** If we can't param the port, then move on to the | ||
394 | ** next port. | ||
395 | */ | ||
396 | PortP->InUse = NOT_INUSE; | ||
397 | |||
398 | rio_spin_unlock(&PortP->portSem); | ||
399 | if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) | ||
400 | continue; /* with next port */ | ||
401 | rio_spin_lock(&PortP->portSem); | ||
402 | PortP->MagicFlags &= ~MAGIC_REBOOT; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | ** As mentioned above, this is a tacky hack to cope | ||
407 | ** with WFLUSH | ||
408 | */ | ||
409 | if (PortP->WflushFlag) { | ||
410 | rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n"); | ||
411 | |||
412 | if (PortP->InUse) | ||
413 | rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n"); | ||
414 | } | ||
415 | |||
416 | while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) { | ||
417 | int p; | ||
418 | struct PktCmd __iomem *PktCmdP; | ||
419 | |||
420 | rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n"); | ||
421 | /* | ||
422 | ** make it look just like a WFLUSH command | ||
423 | */ | ||
424 | PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0]; | ||
425 | |||
426 | writeb(RIOC_WFLUSH, &PktCmdP->Command); | ||
427 | |||
428 | p = PortP->HostPort % (u16) PORTS_PER_RTA; | ||
429 | |||
430 | /* | ||
431 | ** If second block of ports for 16 port RTA, add 8 | ||
432 | ** to index 8-15. | ||
433 | */ | ||
434 | if (PortP->SecondBlock) | ||
435 | p += PORTS_PER_RTA; | ||
436 | |||
437 | writeb(p, &PktCmdP->PhbNum); | ||
438 | |||
439 | /* | ||
440 | ** to make debuggery easier | ||
441 | */ | ||
442 | writeb('W', &PacketP->data[2]); | ||
443 | writeb('F', &PacketP->data[3]); | ||
444 | writeb('L', &PacketP->data[4]); | ||
445 | writeb('U', &PacketP->data[5]); | ||
446 | writeb('S', &PacketP->data[6]); | ||
447 | writeb('H', &PacketP->data[7]); | ||
448 | writeb(' ', &PacketP->data[8]); | ||
449 | writeb('0' + PortP->WflushFlag, &PacketP->data[9]); | ||
450 | writeb(' ', &PacketP->data[10]); | ||
451 | writeb(' ', &PacketP->data[11]); | ||
452 | writeb('\0', &PacketP->data[12]); | ||
453 | |||
454 | /* | ||
455 | ** its two bytes long! | ||
456 | */ | ||
457 | writeb(PKT_CMD_BIT | 2, &PacketP->len); | ||
458 | |||
459 | /* | ||
460 | ** queue it! | ||
461 | */ | ||
462 | if (!(PortP->State & RIO_DELETED)) { | ||
463 | add_transmit(PortP); | ||
464 | /* | ||
465 | ** Count chars tx'd for port statistics reporting | ||
466 | */ | ||
467 | if (PortP->statsGather) | ||
468 | PortP->txchars += 2; | ||
469 | } | ||
470 | |||
471 | if (--(PortP->WflushFlag) == 0) { | ||
472 | PortP->MagicFlags &= ~MAGIC_FLUSH; | ||
473 | } | ||
474 | |||
475 | rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag); | ||
476 | } | ||
477 | if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) { | ||
478 | if (PortP->MagicFlags & MAGIC_FLUSH) { | ||
479 | PortP->MagicFlags |= MORE_OUTPUT_EYGOR; | ||
480 | } else { | ||
481 | if (!can_add_transmit(&PacketP, PortP)) { | ||
482 | rio_spin_unlock(&PortP->portSem); | ||
483 | continue; | ||
484 | } | ||
485 | rio_spin_unlock(&PortP->portSem); | ||
486 | RIOTxEnable((char *) PortP); | ||
487 | rio_spin_lock(&PortP->portSem); | ||
488 | PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | |||
493 | |||
494 | /* | ||
495 | ** If we can't add anything to the transmit queue, then | ||
496 | ** we need do none of the remaining processing. | ||
497 | */ | ||
498 | if (!can_add_transmit(&PacketP, PortP)) { | ||
499 | rio_spin_unlock(&PortP->portSem); | ||
500 | continue; | ||
501 | } | ||
502 | |||
503 | rio_spin_unlock(&PortP->portSem); | ||
504 | RIOTxEnable((char *) PortP); | ||
505 | } | ||
506 | } | ||
507 | } | ||
508 | |||
509 | /* | ||
510 | ** Routine for handling received data for tty drivers | ||
511 | */ | ||
512 | static void RIOReceive(struct rio_info *p, struct Port *PortP) | ||
513 | { | ||
514 | struct tty_struct *TtyP; | ||
515 | unsigned short transCount; | ||
516 | struct PKT __iomem *PacketP; | ||
517 | register unsigned int DataCnt; | ||
518 | unsigned char __iomem *ptr; | ||
519 | unsigned char *buf; | ||
520 | int copied = 0; | ||
521 | |||
522 | static int intCount, RxIntCnt; | ||
523 | |||
524 | /* | ||
525 | ** The receive data process is to remove packets from the | ||
526 | ** PHB until there aren't any more or the current cblock | ||
527 | ** is full. When this occurs, there will be some left over | ||
528 | ** data in the packet, that we must do something with. | ||
529 | ** As we haven't unhooked the packet from the read list | ||
530 | ** yet, we can just leave the packet there, having first | ||
531 | ** made a note of how far we got. This means that we need | ||
532 | ** a pointer per port saying where we start taking the | ||
533 | ** data from - this will normally be zero, but when we | ||
534 | ** run out of space it will be set to the offset of the | ||
535 | ** next byte to copy from the packet data area. The packet | ||
536 | ** length field is decremented by the number of bytes that | ||
537 | ** we successfully removed from the packet. When this reaches | ||
538 | ** zero, we reset the offset pointer to be zero, and free | ||
539 | ** the packet from the front of the queue. | ||
540 | */ | ||
541 | |||
542 | intCount++; | ||
543 | |||
544 | TtyP = PortP->gs.port.tty; | ||
545 | if (!TtyP) { | ||
546 | rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n"); | ||
547 | return; | ||
548 | } | ||
549 | |||
550 | if (PortP->State & RIO_THROTTLE_RX) { | ||
551 | rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n"); | ||
552 | return; | ||
553 | } | ||
554 | |||
555 | if (PortP->State & RIO_DELETED) { | ||
556 | while (can_remove_receive(&PacketP, PortP)) { | ||
557 | remove_receive(PortP); | ||
558 | put_free_end(PortP->HostP, PacketP); | ||
559 | } | ||
560 | } else { | ||
561 | /* | ||
562 | ** loop, just so long as: | ||
563 | ** i ) there's some data ( i.e. can_remove_receive ) | ||
564 | ** ii ) we haven't been blocked | ||
565 | ** iii ) there's somewhere to put the data | ||
566 | ** iv ) we haven't outstayed our welcome | ||
567 | */ | ||
568 | transCount = 1; | ||
569 | while (can_remove_receive(&PacketP, PortP) | ||
570 | && transCount) { | ||
571 | RxIntCnt++; | ||
572 | |||
573 | /* | ||
574 | ** check that it is not a command! | ||
575 | */ | ||
576 | if (readb(&PacketP->len) & PKT_CMD_BIT) { | ||
577 | rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n"); | ||
578 | /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */ | ||
579 | rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit)); | ||
580 | rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port)); | ||
581 | rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit)); | ||
582 | rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port)); | ||
583 | rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len)); | ||
584 | rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control)); | ||
585 | rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum)); | ||
586 | rio_dprintk(RIO_DEBUG_INTR, " data bytes: "); | ||
587 | for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++) | ||
588 | rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt])); | ||
589 | remove_receive(PortP); | ||
590 | put_free_end(PortP->HostP, PacketP); | ||
591 | continue; /* with next packet */ | ||
592 | } | ||
593 | |||
594 | /* | ||
595 | ** How many characters can we move 'upstream' ? | ||
596 | ** | ||
597 | ** Determine the minimum of the amount of data | ||
598 | ** available and the amount of space in which to | ||
599 | ** put it. | ||
600 | ** | ||
601 | ** 1. Get the packet length by masking 'len' | ||
602 | ** for only the length bits. | ||
603 | ** 2. Available space is [buffer size] - [space used] | ||
604 | ** | ||
605 | ** Transfer count is the minimum of packet length | ||
606 | ** and available space. | ||
607 | */ | ||
608 | |||
609 | transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK); | ||
610 | rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount); | ||
611 | /* | ||
612 | ** To use the following 'kkprintfs' for debugging - change the '#undef' | ||
613 | ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the | ||
614 | ** driver). | ||
615 | */ | ||
616 | ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart; | ||
617 | |||
618 | tty_prepare_flip_string(TtyP, &buf, transCount); | ||
619 | rio_memcpy_fromio(buf, ptr, transCount); | ||
620 | PortP->RxDataStart += transCount; | ||
621 | writeb(readb(&PacketP->len)-transCount, &PacketP->len); | ||
622 | copied += transCount; | ||
623 | |||
624 | |||
625 | |||
626 | if (readb(&PacketP->len) == 0) { | ||
627 | /* | ||
628 | ** If we have emptied the packet, then we can | ||
629 | ** free it, and reset the start pointer for | ||
630 | ** the next packet. | ||
631 | */ | ||
632 | remove_receive(PortP); | ||
633 | put_free_end(PortP->HostP, PacketP); | ||
634 | PortP->RxDataStart = 0; | ||
635 | } | ||
636 | } | ||
637 | } | ||
638 | if (copied) { | ||
639 | rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied); | ||
640 | tty_flip_buffer_push(TtyP); | ||
641 | } | ||
642 | |||
643 | return; | ||
644 | } | ||
645 | |||
diff --git a/drivers/char/rio/rioioctl.h b/drivers/char/rio/rioioctl.h deleted file mode 100644 index e8af5b30519e..000000000000 --- a/drivers/char/rio/rioioctl.h +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rioioctl.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:13 | ||
26 | ** Retrieved : 11/6/98 11:34:22 | ||
27 | ** | ||
28 | ** ident @(#)rioioctl.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rioioctl_h__ | ||
34 | #define __rioioctl_h__ | ||
35 | |||
36 | /* | ||
37 | ** RIO device driver - user ioctls and associated structures. | ||
38 | */ | ||
39 | |||
40 | struct portStats { | ||
41 | int port; | ||
42 | int gather; | ||
43 | unsigned long txchars; | ||
44 | unsigned long rxchars; | ||
45 | unsigned long opens; | ||
46 | unsigned long closes; | ||
47 | unsigned long ioctls; | ||
48 | }; | ||
49 | |||
50 | #define RIOC ('R'<<8)|('i'<<16)|('o'<<24) | ||
51 | |||
52 | #define RIO_QUICK_CHECK (RIOC | 105) | ||
53 | #define RIO_GATHER_PORT_STATS (RIOC | 193) | ||
54 | #define RIO_RESET_PORT_STATS (RIOC | 194) | ||
55 | #define RIO_GET_PORT_STATS (RIOC | 195) | ||
56 | |||
57 | #endif /* __rioioctl_h__ */ | ||
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c deleted file mode 100644 index 6415f3f32a72..000000000000 --- a/drivers/char/rio/rioparam.c +++ /dev/null | |||
@@ -1,663 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rioparam.c | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 10:33:45 | ||
26 | ** Retrieved : 11/6/98 10:33:50 | ||
27 | ** | ||
28 | ** ident @(#)rioparam.c 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/tty.h> | ||
36 | #include <asm/io.h> | ||
37 | #include <asm/system.h> | ||
38 | #include <asm/string.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | #include <linux/termios.h> | ||
42 | #include <linux/serial.h> | ||
43 | |||
44 | #include <linux/generic_serial.h> | ||
45 | |||
46 | |||
47 | #include "linux_compat.h" | ||
48 | #include "rio_linux.h" | ||
49 | #include "pkt.h" | ||
50 | #include "daemon.h" | ||
51 | #include "rio.h" | ||
52 | #include "riospace.h" | ||
53 | #include "cmdpkt.h" | ||
54 | #include "map.h" | ||
55 | #include "rup.h" | ||
56 | #include "port.h" | ||
57 | #include "riodrvr.h" | ||
58 | #include "rioinfo.h" | ||
59 | #include "func.h" | ||
60 | #include "errors.h" | ||
61 | #include "pci.h" | ||
62 | |||
63 | #include "parmmap.h" | ||
64 | #include "unixrup.h" | ||
65 | #include "board.h" | ||
66 | #include "host.h" | ||
67 | #include "phb.h" | ||
68 | #include "link.h" | ||
69 | #include "cmdblk.h" | ||
70 | #include "route.h" | ||
71 | #include "cirrus.h" | ||
72 | #include "rioioctl.h" | ||
73 | #include "param.h" | ||
74 | |||
75 | |||
76 | |||
77 | /* | ||
78 | ** The Scam, based on email from jeremyr@bugs.specialix.co.uk.... | ||
79 | ** | ||
80 | ** To send a command on a particular port, you put a packet with the | ||
81 | ** command bit set onto the port. The command bit is in the len field, | ||
82 | ** and gets ORed in with the actual byte count. | ||
83 | ** | ||
84 | ** When you send a packet with the command bit set the first | ||
85 | ** data byte (data[0]) is interpreted as the command to execute. | ||
86 | ** It also governs what data structure overlay should accompany the packet. | ||
87 | ** Commands are defined in cirrus/cirrus.h | ||
88 | ** | ||
89 | ** If you want the command to pre-emt data already on the queue for the | ||
90 | ** port, set the pre-emptive bit in conjunction with the command bit. | ||
91 | ** It is not defined what will happen if you set the preemptive bit | ||
92 | ** on a packet that is NOT a command. | ||
93 | ** | ||
94 | ** Pre-emptive commands should be queued at the head of the queue using | ||
95 | ** add_start(), whereas normal commands and data are enqueued using | ||
96 | ** add_end(). | ||
97 | ** | ||
98 | ** Most commands do not use the remaining bytes in the data array. The | ||
99 | ** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and | ||
100 | ** OPEN are currently analogous). With these three commands the following | ||
101 | ** 11 data bytes are all used to pass config information such as baud rate etc. | ||
102 | ** The fields are also defined in cirrus.h. Some contain straightforward | ||
103 | ** information such as the transmit XON character. Two contain the transmit and | ||
104 | ** receive baud rates respectively. For most baud rates there is a direct | ||
105 | ** mapping between the rates defined in <sys/termio.h> and the byte in the | ||
106 | ** packet. There are additional (non UNIX-standard) rates defined in | ||
107 | ** /u/dos/rio/cirrus/h/brates.h. | ||
108 | ** | ||
109 | ** The rest of the data fields contain approximations to the Cirrus registers | ||
110 | ** that are used to program number of bits etc. Each registers bit fields is | ||
111 | ** defined in cirrus.h. | ||
112 | ** | ||
113 | ** NB. Only use those bits that are defined as being driver specific | ||
114 | ** or common to the RTA and the driver. | ||
115 | ** | ||
116 | ** All commands going from RTA->Host will be dealt with by the Host code - you | ||
117 | ** will never see them. As with the SI there will be three fields to look out | ||
118 | ** for in each phb (not yet defined - needs defining a.s.a.p). | ||
119 | ** | ||
120 | ** modem_status - current state of handshake pins. | ||
121 | ** | ||
122 | ** port_status - current port status - equivalent to hi_stat for SI, indicates | ||
123 | ** if port is IDLE_OPEN, IDLE_CLOSED etc. | ||
124 | ** | ||
125 | ** break_status - bit X set if break has been received. | ||
126 | ** | ||
127 | ** Happy hacking. | ||
128 | ** | ||
129 | */ | ||
130 | |||
131 | /* | ||
132 | ** RIOParam is used to open or configure a port. You pass it a PortP, | ||
133 | ** which will have a tty struct attached to it. You also pass a command, | ||
134 | ** either OPEN or CONFIG. The port's setup is taken from the t_ fields | ||
135 | ** of the tty struct inside the PortP, and the port is either opened | ||
136 | ** or re-configured. You must also tell RIOParam if the device is a modem | ||
137 | ** device or not (i.e. top bit of minor number set or clear - take special | ||
138 | ** care when deciding on this!). | ||
139 | ** RIOParam neither flushes nor waits for drain, and is NOT preemptive. | ||
140 | ** | ||
141 | ** RIOParam assumes it will be called at splrio(), and also assumes | ||
142 | ** that CookMode is set correctly in the port structure. | ||
143 | ** | ||
144 | ** NB. for MPX | ||
145 | ** tty lock must NOT have been previously acquired. | ||
146 | */ | ||
147 | int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) | ||
148 | { | ||
149 | struct tty_struct *TtyP; | ||
150 | int retval; | ||
151 | struct phb_param __iomem *phb_param_ptr; | ||
152 | struct PKT __iomem *PacketP; | ||
153 | int res; | ||
154 | u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0; | ||
155 | u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0; | ||
156 | u8 LNext = 0, TxBaud = 0, RxBaud = 0; | ||
157 | int retries = 0xff; | ||
158 | unsigned long flags; | ||
159 | |||
160 | func_enter(); | ||
161 | |||
162 | TtyP = PortP->gs.port.tty; | ||
163 | |||
164 | rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP); | ||
165 | |||
166 | if (!TtyP) { | ||
167 | rio_dprintk(RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n"); | ||
168 | |||
169 | func_exit(); | ||
170 | |||
171 | return RIO_FAIL; | ||
172 | } | ||
173 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
174 | |||
175 | if (cmd == RIOC_OPEN) { | ||
176 | /* | ||
177 | ** If the port is set to store or lock the parameters, and it is | ||
178 | ** paramed with OPEN, we want to restore the saved port termio, but | ||
179 | ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot. | ||
180 | */ | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | ** wait for space | ||
185 | */ | ||
186 | while (!(res = can_add_transmit(&PacketP, PortP)) || (PortP->InUse != NOT_INUSE)) { | ||
187 | if (retries-- <= 0) { | ||
188 | break; | ||
189 | } | ||
190 | if (PortP->InUse != NOT_INUSE) { | ||
191 | rio_dprintk(RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n"); | ||
192 | } | ||
193 | |||
194 | if (!res) { | ||
195 | rio_dprintk(RIO_DEBUG_PARAM, "Port has no space on transmit queue\n"); | ||
196 | } | ||
197 | |||
198 | if (SleepFlag != OK_TO_SLEEP) { | ||
199 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
200 | func_exit(); | ||
201 | |||
202 | return RIO_FAIL; | ||
203 | } | ||
204 | |||
205 | rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit\n"); | ||
206 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
207 | retval = RIODelay(PortP, HUNDRED_MS); | ||
208 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
209 | if (retval == RIO_FAIL) { | ||
210 | rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n"); | ||
211 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
212 | func_exit(); | ||
213 | return -EINTR; | ||
214 | } | ||
215 | if (PortP->State & RIO_DELETED) { | ||
216 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
217 | func_exit(); | ||
218 | return 0; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | if (!res) { | ||
223 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
224 | func_exit(); | ||
225 | |||
226 | return RIO_FAIL; | ||
227 | } | ||
228 | |||
229 | rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res); | ||
230 | rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP); | ||
231 | |||
232 | phb_param_ptr = (struct phb_param __iomem *) PacketP->data; | ||
233 | |||
234 | |||
235 | switch (TtyP->termios->c_cflag & CSIZE) { | ||
236 | case CS5: | ||
237 | { | ||
238 | rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n"); | ||
239 | Cor1 |= RIOC_COR1_5BITS; | ||
240 | break; | ||
241 | } | ||
242 | case CS6: | ||
243 | { | ||
244 | rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n"); | ||
245 | Cor1 |= RIOC_COR1_6BITS; | ||
246 | break; | ||
247 | } | ||
248 | case CS7: | ||
249 | { | ||
250 | rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n"); | ||
251 | Cor1 |= RIOC_COR1_7BITS; | ||
252 | break; | ||
253 | } | ||
254 | case CS8: | ||
255 | { | ||
256 | rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n"); | ||
257 | Cor1 |= RIOC_COR1_8BITS; | ||
258 | break; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | if (TtyP->termios->c_cflag & CSTOPB) { | ||
263 | rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n"); | ||
264 | Cor1 |= RIOC_COR1_2STOP; | ||
265 | } else { | ||
266 | rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n"); | ||
267 | Cor1 |= RIOC_COR1_1STOP; | ||
268 | } | ||
269 | |||
270 | if (TtyP->termios->c_cflag & PARENB) { | ||
271 | rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n"); | ||
272 | Cor1 |= RIOC_COR1_NORMAL; | ||
273 | } else { | ||
274 | rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n"); | ||
275 | Cor1 |= RIOC_COR1_NOP; | ||
276 | } | ||
277 | if (TtyP->termios->c_cflag & PARODD) { | ||
278 | rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n"); | ||
279 | Cor1 |= RIOC_COR1_ODD; | ||
280 | } else { | ||
281 | rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n"); | ||
282 | Cor1 |= RIOC_COR1_EVEN; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | ** COR 2 | ||
287 | */ | ||
288 | if (TtyP->termios->c_iflag & IXON) { | ||
289 | rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n"); | ||
290 | Cor2 |= RIOC_COR2_IXON; | ||
291 | } else { | ||
292 | if (PortP->Config & RIO_IXON) { | ||
293 | rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); | ||
294 | Cor2 |= RIOC_COR2_IXON; | ||
295 | } else | ||
296 | rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n"); | ||
297 | } | ||
298 | |||
299 | if (TtyP->termios->c_iflag & IXANY) { | ||
300 | if (PortP->Config & RIO_IXANY) { | ||
301 | rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n"); | ||
302 | Cor2 |= RIOC_COR2_IXANY; | ||
303 | } else | ||
304 | rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); | ||
305 | } | ||
306 | |||
307 | if (TtyP->termios->c_iflag & IXOFF) { | ||
308 | rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); | ||
309 | Cor2 |= RIOC_COR2_IXOFF; | ||
310 | } | ||
311 | |||
312 | if (TtyP->termios->c_cflag & HUPCL) { | ||
313 | rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n"); | ||
314 | Cor2 |= RIOC_COR2_HUPCL; | ||
315 | } | ||
316 | |||
317 | if (C_CRTSCTS(TtyP)) { | ||
318 | rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); | ||
319 | Cor2 |= RIOC_COR2_CTSFLOW; | ||
320 | Cor2 |= RIOC_COR2_RTSFLOW; | ||
321 | } else { | ||
322 | rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); | ||
323 | Cor2 &= ~RIOC_COR2_CTSFLOW; | ||
324 | Cor2 &= ~RIOC_COR2_RTSFLOW; | ||
325 | } | ||
326 | |||
327 | |||
328 | if (TtyP->termios->c_cflag & CLOCAL) { | ||
329 | rio_dprintk(RIO_DEBUG_PARAM, "Local line\n"); | ||
330 | } else { | ||
331 | rio_dprintk(RIO_DEBUG_PARAM, "Possible Modem line\n"); | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | ** COR 4 (there is no COR 3) | ||
336 | */ | ||
337 | if (TtyP->termios->c_iflag & IGNBRK) { | ||
338 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n"); | ||
339 | Cor4 |= RIOC_COR4_IGNBRK; | ||
340 | } | ||
341 | if (!(TtyP->termios->c_iflag & BRKINT)) { | ||
342 | rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n"); | ||
343 | Cor4 |= RIOC_COR4_NBRKINT; | ||
344 | } else { | ||
345 | rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n"); | ||
346 | } | ||
347 | |||
348 | if (TtyP->termios->c_iflag & INLCR) { | ||
349 | rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); | ||
350 | Cor4 |= RIOC_COR4_INLCR; | ||
351 | } | ||
352 | |||
353 | if (TtyP->termios->c_iflag & IGNCR) { | ||
354 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); | ||
355 | Cor4 |= RIOC_COR4_IGNCR; | ||
356 | } | ||
357 | |||
358 | if (TtyP->termios->c_iflag & ICRNL) { | ||
359 | rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); | ||
360 | Cor4 |= RIOC_COR4_ICRNL; | ||
361 | } | ||
362 | if (TtyP->termios->c_iflag & IGNPAR) { | ||
363 | rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); | ||
364 | Cor4 |= RIOC_COR4_IGNPAR; | ||
365 | } | ||
366 | if (TtyP->termios->c_iflag & PARMRK) { | ||
367 | rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n"); | ||
368 | Cor4 |= RIOC_COR4_PARMRK; | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | ** Set the RAISEMOD flag to ensure that the modem lines are raised | ||
373 | ** on reception of a config packet. | ||
374 | ** The download code handles the zero baud condition. | ||
375 | */ | ||
376 | Cor4 |= RIOC_COR4_RAISEMOD; | ||
377 | |||
378 | /* | ||
379 | ** COR 5 | ||
380 | */ | ||
381 | |||
382 | Cor5 = RIOC_COR5_CMOE; | ||
383 | |||
384 | /* | ||
385 | ** Set to monitor tbusy/tstop (or not). | ||
386 | */ | ||
387 | |||
388 | if (PortP->MonitorTstate) | ||
389 | Cor5 |= RIOC_COR5_TSTATE_ON; | ||
390 | else | ||
391 | Cor5 |= RIOC_COR5_TSTATE_OFF; | ||
392 | |||
393 | /* | ||
394 | ** Could set LNE here if you wanted LNext processing. SVR4 will use it. | ||
395 | */ | ||
396 | if (TtyP->termios->c_iflag & ISTRIP) { | ||
397 | rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n"); | ||
398 | if (!(PortP->State & RIO_TRIAD_MODE)) { | ||
399 | Cor5 |= RIOC_COR5_ISTRIP; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | if (TtyP->termios->c_oflag & ONLCR) { | ||
404 | rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); | ||
405 | if (PortP->CookMode == COOK_MEDIUM) | ||
406 | Cor5 |= RIOC_COR5_ONLCR; | ||
407 | } | ||
408 | if (TtyP->termios->c_oflag & OCRNL) { | ||
409 | rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); | ||
410 | if (PortP->CookMode == COOK_MEDIUM) | ||
411 | Cor5 |= RIOC_COR5_OCRNL; | ||
412 | } | ||
413 | if ((TtyP->termios->c_oflag & TABDLY) == TAB3) { | ||
414 | rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n"); | ||
415 | if (PortP->CookMode == COOK_MEDIUM) | ||
416 | Cor5 |= RIOC_COR5_TAB3; | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | ** Flow control bytes. | ||
421 | */ | ||
422 | TxXon = TtyP->termios->c_cc[VSTART]; | ||
423 | TxXoff = TtyP->termios->c_cc[VSTOP]; | ||
424 | RxXon = TtyP->termios->c_cc[VSTART]; | ||
425 | RxXoff = TtyP->termios->c_cc[VSTOP]; | ||
426 | /* | ||
427 | ** LNEXT byte | ||
428 | */ | ||
429 | LNext = 0; | ||
430 | |||
431 | /* | ||
432 | ** Baud rate bytes | ||
433 | */ | ||
434 | rio_dprintk(RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", TtyP->termios->c_cflag, CBAUD); | ||
435 | |||
436 | switch (TtyP->termios->c_cflag & CBAUD) { | ||
437 | #define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break | ||
438 | e(50); | ||
439 | e(75); | ||
440 | e(110); | ||
441 | e(134); | ||
442 | e(150); | ||
443 | e(200); | ||
444 | e(300); | ||
445 | e(600); | ||
446 | e(1200); | ||
447 | e(1800); | ||
448 | e(2400); | ||
449 | e(4800); | ||
450 | e(9600); | ||
451 | e(19200); | ||
452 | e(38400); | ||
453 | e(57600); | ||
454 | e(115200); /* e(230400);e(460800); e(921600); */ | ||
455 | } | ||
456 | |||
457 | rio_dprintk(RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud); | ||
458 | |||
459 | |||
460 | /* | ||
461 | ** Leftovers | ||
462 | */ | ||
463 | if (TtyP->termios->c_cflag & CREAD) | ||
464 | rio_dprintk(RIO_DEBUG_PARAM, "Enable receiver\n"); | ||
465 | #ifdef RCV1EN | ||
466 | if (TtyP->termios->c_cflag & RCV1EN) | ||
467 | rio_dprintk(RIO_DEBUG_PARAM, "RCV1EN (?)\n"); | ||
468 | #endif | ||
469 | #ifdef XMT1EN | ||
470 | if (TtyP->termios->c_cflag & XMT1EN) | ||
471 | rio_dprintk(RIO_DEBUG_PARAM, "XMT1EN (?)\n"); | ||
472 | #endif | ||
473 | if (TtyP->termios->c_lflag & ISIG) | ||
474 | rio_dprintk(RIO_DEBUG_PARAM, "Input character signal generating enabled\n"); | ||
475 | if (TtyP->termios->c_lflag & ICANON) | ||
476 | rio_dprintk(RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n"); | ||
477 | if (TtyP->termios->c_lflag & XCASE) | ||
478 | rio_dprintk(RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n"); | ||
479 | if (TtyP->termios->c_lflag & ECHO) | ||
480 | rio_dprintk(RIO_DEBUG_PARAM, "Enable input echo\n"); | ||
481 | if (TtyP->termios->c_lflag & ECHOE) | ||
482 | rio_dprintk(RIO_DEBUG_PARAM, "Enable echo erase\n"); | ||
483 | if (TtyP->termios->c_lflag & ECHOK) | ||
484 | rio_dprintk(RIO_DEBUG_PARAM, "Enable echo kill\n"); | ||
485 | if (TtyP->termios->c_lflag & ECHONL) | ||
486 | rio_dprintk(RIO_DEBUG_PARAM, "Enable echo newline\n"); | ||
487 | if (TtyP->termios->c_lflag & NOFLSH) | ||
488 | rio_dprintk(RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n"); | ||
489 | #ifdef TOSTOP | ||
490 | if (TtyP->termios->c_lflag & TOSTOP) | ||
491 | rio_dprintk(RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n"); | ||
492 | #endif | ||
493 | #ifdef XCLUDE | ||
494 | if (TtyP->termios->c_lflag & XCLUDE) | ||
495 | rio_dprintk(RIO_DEBUG_PARAM, "Exclusive use of this line\n"); | ||
496 | #endif | ||
497 | if (TtyP->termios->c_iflag & IUCLC) | ||
498 | rio_dprintk(RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n"); | ||
499 | if (TtyP->termios->c_oflag & OPOST) | ||
500 | rio_dprintk(RIO_DEBUG_PARAM, "Enable output post-processing\n"); | ||
501 | if (TtyP->termios->c_oflag & OLCUC) | ||
502 | rio_dprintk(RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n"); | ||
503 | if (TtyP->termios->c_oflag & ONOCR) | ||
504 | rio_dprintk(RIO_DEBUG_PARAM, "No carriage return output at column 0\n"); | ||
505 | if (TtyP->termios->c_oflag & ONLRET) | ||
506 | rio_dprintk(RIO_DEBUG_PARAM, "Newline performs carriage return function\n"); | ||
507 | if (TtyP->termios->c_oflag & OFILL) | ||
508 | rio_dprintk(RIO_DEBUG_PARAM, "Use fill characters for delay\n"); | ||
509 | if (TtyP->termios->c_oflag & OFDEL) | ||
510 | rio_dprintk(RIO_DEBUG_PARAM, "Fill character is DEL\n"); | ||
511 | if (TtyP->termios->c_oflag & NLDLY) | ||
512 | rio_dprintk(RIO_DEBUG_PARAM, "Newline delay set\n"); | ||
513 | if (TtyP->termios->c_oflag & CRDLY) | ||
514 | rio_dprintk(RIO_DEBUG_PARAM, "Carriage return delay set\n"); | ||
515 | if (TtyP->termios->c_oflag & TABDLY) | ||
516 | rio_dprintk(RIO_DEBUG_PARAM, "Tab delay set\n"); | ||
517 | /* | ||
518 | ** These things are kind of useful in a later life! | ||
519 | */ | ||
520 | PortP->Cor2Copy = Cor2; | ||
521 | |||
522 | if (PortP->State & RIO_DELETED) { | ||
523 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
524 | func_exit(); | ||
525 | |||
526 | return RIO_FAIL; | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | ** Actually write the info into the packet to be sent | ||
531 | */ | ||
532 | writeb(cmd, &phb_param_ptr->Cmd); | ||
533 | writeb(Cor1, &phb_param_ptr->Cor1); | ||
534 | writeb(Cor2, &phb_param_ptr->Cor2); | ||
535 | writeb(Cor4, &phb_param_ptr->Cor4); | ||
536 | writeb(Cor5, &phb_param_ptr->Cor5); | ||
537 | writeb(TxXon, &phb_param_ptr->TxXon); | ||
538 | writeb(RxXon, &phb_param_ptr->RxXon); | ||
539 | writeb(TxXoff, &phb_param_ptr->TxXoff); | ||
540 | writeb(RxXoff, &phb_param_ptr->RxXoff); | ||
541 | writeb(LNext, &phb_param_ptr->LNext); | ||
542 | writeb(TxBaud, &phb_param_ptr->TxBaud); | ||
543 | writeb(RxBaud, &phb_param_ptr->RxBaud); | ||
544 | |||
545 | /* | ||
546 | ** Set the length/command field | ||
547 | */ | ||
548 | writeb(12 | PKT_CMD_BIT, &PacketP->len); | ||
549 | |||
550 | /* | ||
551 | ** The packet is formed - now, whack it off | ||
552 | ** to its final destination: | ||
553 | */ | ||
554 | add_transmit(PortP); | ||
555 | /* | ||
556 | ** Count characters transmitted for port statistics reporting | ||
557 | */ | ||
558 | if (PortP->statsGather) | ||
559 | PortP->txchars += 12; | ||
560 | |||
561 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
562 | |||
563 | rio_dprintk(RIO_DEBUG_PARAM, "add_transmit returned.\n"); | ||
564 | /* | ||
565 | ** job done. | ||
566 | */ | ||
567 | func_exit(); | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | |||
573 | /* | ||
574 | ** We can add another packet to a transmit queue if the packet pointer pointed | ||
575 | ** to by the TxAdd pointer has PKT_IN_USE clear in its address. | ||
576 | */ | ||
577 | int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP) | ||
578 | { | ||
579 | struct PKT __iomem *tp; | ||
580 | |||
581 | *PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd)); | ||
582 | |||
583 | return !((unsigned long) tp & PKT_IN_USE); | ||
584 | } | ||
585 | |||
586 | /* | ||
587 | ** To add a packet to the queue, you set the PKT_IN_USE bit in the address, | ||
588 | ** and then move the TxAdd pointer along one position to point to the next | ||
589 | ** packet pointer. You must wrap the pointer from the end back to the start. | ||
590 | */ | ||
591 | void add_transmit(struct Port *PortP) | ||
592 | { | ||
593 | if (readw(PortP->TxAdd) & PKT_IN_USE) { | ||
594 | rio_dprintk(RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!"); | ||
595 | } | ||
596 | writew(readw(PortP->TxAdd) | PKT_IN_USE, PortP->TxAdd); | ||
597 | PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : PortP->TxAdd + 1; | ||
598 | writew(RIO_OFF(PortP->Caddr, PortP->TxAdd), &PortP->PhbP->tx_add); | ||
599 | } | ||
600 | |||
601 | /**************************************** | ||
602 | * Put a packet onto the end of the | ||
603 | * free list | ||
604 | ****************************************/ | ||
605 | void put_free_end(struct Host *HostP, struct PKT __iomem *PktP) | ||
606 | { | ||
607 | struct rio_free_list __iomem *tmp_pointer; | ||
608 | unsigned short old_end, new_end; | ||
609 | unsigned long flags; | ||
610 | |||
611 | rio_spin_lock_irqsave(&HostP->HostLock, flags); | ||
612 | |||
613 | /************************************************* | ||
614 | * Put a packet back onto the back of the free list | ||
615 | * | ||
616 | ************************************************/ | ||
617 | |||
618 | rio_dprintk(RIO_DEBUG_PFE, "put_free_end(PktP=%p)\n", PktP); | ||
619 | |||
620 | if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) { | ||
621 | new_end = RIO_OFF(HostP->Caddr, PktP); | ||
622 | tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end); | ||
623 | writew(new_end, &tmp_pointer->next); | ||
624 | writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev); | ||
625 | writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next); | ||
626 | writew(new_end, &HostP->ParmMapP->free_list_end); | ||
627 | } else { /* First packet on the free list this should never happen! */ | ||
628 | rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n"); | ||
629 | writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end); | ||
630 | tmp_pointer = (struct rio_free_list __iomem *) PktP; | ||
631 | writew(TPNULL, &tmp_pointer->prev); | ||
632 | writew(TPNULL, &tmp_pointer->next); | ||
633 | } | ||
634 | rio_dprintk(RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock); | ||
635 | rio_spin_unlock_irqrestore(&HostP->HostLock, flags); | ||
636 | } | ||
637 | |||
638 | /* | ||
639 | ** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set | ||
640 | ** for the next packet on the queue. It will also set PktP to point to the | ||
641 | ** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear, | ||
642 | ** then can_remove_receive() returns 0. | ||
643 | */ | ||
644 | int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP) | ||
645 | { | ||
646 | if (readw(PortP->RxRemove) & PKT_IN_USE) { | ||
647 | *PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE); | ||
648 | return 1; | ||
649 | } | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | /* | ||
654 | ** To remove a packet from the receive queue you clear its PKT_IN_USE bit, | ||
655 | ** and then bump the pointers. Once the pointers get to the end, they must | ||
656 | ** be wrapped back to the start. | ||
657 | */ | ||
658 | void remove_receive(struct Port *PortP) | ||
659 | { | ||
660 | writew(readw(PortP->RxRemove) & ~PKT_IN_USE, PortP->RxRemove); | ||
661 | PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart : PortP->RxRemove + 1; | ||
662 | writew(RIO_OFF(PortP->Caddr, PortP->RxRemove), &PortP->PhbP->rx_remove); | ||
663 | } | ||
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c deleted file mode 100644 index f9b936ac3394..000000000000 --- a/drivers/char/rio/rioroute.c +++ /dev/null | |||
@@ -1,1039 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : rioroute.c | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 10:33:46 | ||
26 | ** Retrieved : 11/6/98 10:33:50 | ||
27 | ** | ||
28 | ** ident @(#)rioroute.c 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <asm/io.h> | ||
36 | #include <asm/system.h> | ||
37 | #include <asm/string.h> | ||
38 | #include <asm/uaccess.h> | ||
39 | |||
40 | #include <linux/termios.h> | ||
41 | #include <linux/serial.h> | ||
42 | |||
43 | #include <linux/generic_serial.h> | ||
44 | |||
45 | |||
46 | #include "linux_compat.h" | ||
47 | #include "rio_linux.h" | ||
48 | #include "pkt.h" | ||
49 | #include "daemon.h" | ||
50 | #include "rio.h" | ||
51 | #include "riospace.h" | ||
52 | #include "cmdpkt.h" | ||
53 | #include "map.h" | ||
54 | #include "rup.h" | ||
55 | #include "port.h" | ||
56 | #include "riodrvr.h" | ||
57 | #include "rioinfo.h" | ||
58 | #include "func.h" | ||
59 | #include "errors.h" | ||
60 | #include "pci.h" | ||
61 | |||
62 | #include "parmmap.h" | ||
63 | #include "unixrup.h" | ||
64 | #include "board.h" | ||
65 | #include "host.h" | ||
66 | #include "phb.h" | ||
67 | #include "link.h" | ||
68 | #include "cmdblk.h" | ||
69 | #include "route.h" | ||
70 | #include "cirrus.h" | ||
71 | #include "rioioctl.h" | ||
72 | #include "param.h" | ||
73 | |||
74 | static int RIOCheckIsolated(struct rio_info *, struct Host *, unsigned int); | ||
75 | static int RIOIsolate(struct rio_info *, struct Host *, unsigned int); | ||
76 | static int RIOCheck(struct Host *, unsigned int); | ||
77 | static void RIOConCon(struct rio_info *, struct Host *, unsigned int, unsigned int, unsigned int, unsigned int, int); | ||
78 | |||
79 | |||
80 | /* | ||
81 | ** Incoming on the ROUTE_RUP | ||
82 | ** I wrote this while I was tired. Forgive me. | ||
83 | */ | ||
84 | int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem * PacketP) | ||
85 | { | ||
86 | struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; | ||
87 | struct PktCmd_M *PktReplyP; | ||
88 | struct CmdBlk *CmdBlkP; | ||
89 | struct Port *PortP; | ||
90 | struct Map *MapP; | ||
91 | struct Top *TopP; | ||
92 | int ThisLink, ThisLinkMin, ThisLinkMax; | ||
93 | int port; | ||
94 | int Mod, Mod1, Mod2; | ||
95 | unsigned short RtaType; | ||
96 | unsigned int RtaUniq; | ||
97 | unsigned int ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */ | ||
98 | unsigned int OldUnit, NewUnit, OldLink, NewLink; | ||
99 | char *MyType, *MyName; | ||
100 | int Lies; | ||
101 | unsigned long flags; | ||
102 | |||
103 | /* | ||
104 | ** Is this unit telling us it's current link topology? | ||
105 | */ | ||
106 | if (readb(&PktCmdP->Command) == ROUTE_TOPOLOGY) { | ||
107 | MapP = HostP->Mapping; | ||
108 | |||
109 | /* | ||
110 | ** The packet can be sent either by the host or by an RTA. | ||
111 | ** If it comes from the host, then we need to fill in the | ||
112 | ** Topology array in the host structure. If it came in | ||
113 | ** from an RTA then we need to fill in the Mapping structure's | ||
114 | ** Topology array for the unit. | ||
115 | */ | ||
116 | if (Rup >= (unsigned short) MAX_RUP) { | ||
117 | ThisUnit = HOST_ID; | ||
118 | TopP = HostP->Topology; | ||
119 | MyType = "Host"; | ||
120 | MyName = HostP->Name; | ||
121 | ThisLinkMin = ThisLinkMax = Rup - MAX_RUP; | ||
122 | } else { | ||
123 | ThisUnit = Rup + 1; | ||
124 | TopP = HostP->Mapping[Rup].Topology; | ||
125 | MyType = "RTA"; | ||
126 | MyName = HostP->Mapping[Rup].Name; | ||
127 | ThisLinkMin = 0; | ||
128 | ThisLinkMax = LINKS_PER_UNIT - 1; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | ** Lies will not be tolerated. | ||
133 | ** If any pair of links claim to be connected to the same | ||
134 | ** place, then ignore this packet completely. | ||
135 | */ | ||
136 | Lies = 0; | ||
137 | for (ThisLink = ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++) { | ||
138 | /* | ||
139 | ** it won't lie about network interconnect, total disconnects | ||
140 | ** and no-IDs. (or at least, it doesn't *matter* if it does) | ||
141 | */ | ||
142 | if (readb(&PktCmdP->RouteTopology[ThisLink].Unit) > (unsigned short) MAX_RUP) | ||
143 | continue; | ||
144 | |||
145 | for (NewLink = ThisLinkMin; NewLink < ThisLink; NewLink++) { | ||
146 | if ((readb(&PktCmdP->RouteTopology[ThisLink].Unit) == readb(&PktCmdP->RouteTopology[NewLink].Unit)) && (readb(&PktCmdP->RouteTopology[ThisLink].Link) == readb(&PktCmdP->RouteTopology[NewLink].Link))) { | ||
147 | Lies++; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
152 | if (Lies) { | ||
153 | rio_dprintk(RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n", Lies); | ||
154 | rio_dprintk(RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n", | ||
155 | readb(&PktCmdP->RouteTopology[0].Unit), | ||
156 | 'A' + readb(&PktCmdP->RouteTopology[0].Link), | ||
157 | readb(&PktCmdP->RouteTopology[1].Unit), | ||
158 | 'A' + readb(&PktCmdP->RouteTopology[1].Link), readb(&PktCmdP->RouteTopology[2].Unit), 'A' + readb(&PktCmdP->RouteTopology[2].Link), readb(&PktCmdP->RouteTopology[3].Unit), 'A' + readb(&PktCmdP->RouteTopology[3].Link)); | ||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | ** now, process each link. | ||
164 | */ | ||
165 | for (ThisLink = ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++) { | ||
166 | /* | ||
167 | ** this is what it was connected to | ||
168 | */ | ||
169 | OldUnit = TopP[ThisLink].Unit; | ||
170 | OldLink = TopP[ThisLink].Link; | ||
171 | |||
172 | /* | ||
173 | ** this is what it is now connected to | ||
174 | */ | ||
175 | NewUnit = readb(&PktCmdP->RouteTopology[ThisLink].Unit); | ||
176 | NewLink = readb(&PktCmdP->RouteTopology[ThisLink].Link); | ||
177 | |||
178 | if (OldUnit != NewUnit || OldLink != NewLink) { | ||
179 | /* | ||
180 | ** something has changed! | ||
181 | */ | ||
182 | |||
183 | if (NewUnit > MAX_RUP && NewUnit != ROUTE_DISCONNECT && NewUnit != ROUTE_NO_ID && NewUnit != ROUTE_INTERCONNECT) { | ||
184 | rio_dprintk(RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", MyType, MyName, NewUnit, NewLink); | ||
185 | } else { | ||
186 | /* | ||
187 | ** put the new values in | ||
188 | */ | ||
189 | TopP[ThisLink].Unit = NewUnit; | ||
190 | TopP[ThisLink].Link = NewLink; | ||
191 | |||
192 | RIOSetChange(p); | ||
193 | |||
194 | if (OldUnit <= MAX_RUP) { | ||
195 | /* | ||
196 | ** If something has become bust, then re-enable them messages | ||
197 | */ | ||
198 | if (!p->RIONoMessage) | ||
199 | RIOConCon(p, HostP, ThisUnit, ThisLink, OldUnit, OldLink, DISCONNECT); | ||
200 | } | ||
201 | |||
202 | if ((NewUnit <= MAX_RUP) && !p->RIONoMessage) | ||
203 | RIOConCon(p, HostP, ThisUnit, ThisLink, NewUnit, NewLink, CONNECT); | ||
204 | |||
205 | if (NewUnit == ROUTE_NO_ID) | ||
206 | rio_dprintk(RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", MyType, MyName, 'A' + ThisLink); | ||
207 | |||
208 | if (NewUnit == ROUTE_INTERCONNECT) { | ||
209 | if (!p->RIONoMessage) | ||
210 | printk(KERN_DEBUG "rio: %s '%s' (%c) is connected to another network.\n", MyType, MyName, 'A' + ThisLink); | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | ** perform an update for 'the other end', so that these messages | ||
215 | ** only appears once. Only disconnect the other end if it is pointing | ||
216 | ** at us! | ||
217 | */ | ||
218 | if (OldUnit == HOST_ID) { | ||
219 | if (HostP->Topology[OldLink].Unit == ThisUnit && HostP->Topology[OldLink].Link == ThisLink) { | ||
220 | rio_dprintk(RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink + 'A'); | ||
221 | HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT; | ||
222 | HostP->Topology[OldLink].Link = NO_LINK; | ||
223 | } else { | ||
224 | rio_dprintk(RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); | ||
225 | } | ||
226 | } else if (OldUnit <= MAX_RUP) { | ||
227 | if (HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit == ThisUnit && HostP->Mapping[OldUnit - 1].Topology[OldLink].Link == ThisLink) { | ||
228 | rio_dprintk(RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A'); | ||
229 | HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit = ROUTE_DISCONNECT; | ||
230 | HostP->Mapping[OldUnit - 1].Topology[OldLink].Link = NO_LINK; | ||
231 | } else { | ||
232 | rio_dprintk(RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); | ||
233 | } | ||
234 | } | ||
235 | if (NewUnit == HOST_ID) { | ||
236 | rio_dprintk(RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", NewLink + 'A', MyName, ThisLink + 'A'); | ||
237 | HostP->Topology[NewLink].Unit = ThisUnit; | ||
238 | HostP->Topology[NewLink].Link = ThisLink; | ||
239 | } else if (NewUnit <= MAX_RUP) { | ||
240 | rio_dprintk(RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", HostP->Mapping[NewUnit - 1].Name, NewLink + 'A', MyName, ThisLink + 'A'); | ||
241 | HostP->Mapping[NewUnit - 1].Topology[NewLink].Unit = ThisUnit; | ||
242 | HostP->Mapping[NewUnit - 1].Topology[NewLink].Link = ThisLink; | ||
243 | } | ||
244 | } | ||
245 | RIOSetChange(p); | ||
246 | RIOCheckIsolated(p, HostP, OldUnit); | ||
247 | } | ||
248 | } | ||
249 | return 1; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | ** The only other command we recognise is a route_request command | ||
254 | */ | ||
255 | if (readb(&PktCmdP->Command) != ROUTE_REQUEST) { | ||
256 | rio_dprintk(RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %p ROUTE_RUP\n", readb(&PktCmdP->Command), Rup, HostP); | ||
257 | return 1; | ||
258 | } | ||
259 | |||
260 | RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); | ||
261 | |||
262 | /* | ||
263 | ** Determine if 8 or 16 port RTA | ||
264 | */ | ||
265 | RtaType = GetUnitType(RtaUniq); | ||
266 | |||
267 | rio_dprintk(RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq); | ||
268 | |||
269 | Mod = readb(&PktCmdP->ModuleTypes); | ||
270 | Mod1 = LONYBLE(Mod); | ||
271 | if (RtaType == TYPE_RTA16) { | ||
272 | /* | ||
273 | ** Only one ident is set for a 16 port RTA. To make compatible | ||
274 | ** with 8 port, set 2nd ident in Mod2 to the same as Mod1. | ||
275 | */ | ||
276 | Mod2 = Mod1; | ||
277 | rio_dprintk(RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n", p->RIOModuleTypes[Mod1].Name); | ||
278 | } else { | ||
279 | Mod2 = HINYBLE(Mod); | ||
280 | rio_dprintk(RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n", p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | ** try to unhook a command block from the command free list. | ||
285 | */ | ||
286 | if (!(CmdBlkP = RIOGetCmdBlk())) { | ||
287 | rio_dprintk(RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n"); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | ** Fill in the default info on the command block | ||
293 | */ | ||
294 | CmdBlkP->Packet.dest_unit = Rup; | ||
295 | CmdBlkP->Packet.dest_port = ROUTE_RUP; | ||
296 | CmdBlkP->Packet.src_unit = HOST_ID; | ||
297 | CmdBlkP->Packet.src_port = ROUTE_RUP; | ||
298 | CmdBlkP->Packet.len = PKT_CMD_BIT | 1; | ||
299 | CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; | ||
300 | PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; | ||
301 | |||
302 | if (!RIOBootOk(p, HostP, RtaUniq)) { | ||
303 | rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq); | ||
304 | PktReplyP->Command = ROUTE_FOAD; | ||
305 | memcpy(PktReplyP->CommandText, "RT_FOAD", 7); | ||
306 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); | ||
307 | return 1; | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | ** Check to see if the RTA is configured for this host | ||
312 | */ | ||
313 | for (ThisUnit = 0; ThisUnit < MAX_RUP; ThisUnit++) { | ||
314 | rio_dprintk(RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n", | ||
315 | ThisUnit, HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ? "Slot-In-Use" : "Not In Use", HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? "Slot-Tentative" : "Not Tentative", HostP->Mapping[ThisUnit].RtaUniqueNum); | ||
316 | |||
317 | /* | ||
318 | ** We have an entry for it. | ||
319 | */ | ||
320 | if ((HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq)) { | ||
321 | if (RtaType == TYPE_RTA16) { | ||
322 | ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1; | ||
323 | rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n", RtaUniq, ThisUnit, ThisUnit2); | ||
324 | } else | ||
325 | rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n", RtaUniq, ThisUnit); | ||
326 | /* | ||
327 | ** If we have no knowledge of booting it, then the host has | ||
328 | ** been re-booted, and so we must kill the RTA, so that it | ||
329 | ** will be booted again (potentially with new bins) | ||
330 | ** and it will then re-ask for an ID, which we will service. | ||
331 | */ | ||
332 | if ((HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED)) { | ||
333 | if (!(HostP->Mapping[ThisUnit].Flags & MSG_DONE)) { | ||
334 | if (!p->RIONoMessage) | ||
335 | printk(KERN_DEBUG "rio: RTA '%s' is being updated.\n", HostP->Mapping[ThisUnit].Name); | ||
336 | HostP->Mapping[ThisUnit].Flags |= MSG_DONE; | ||
337 | } | ||
338 | PktReplyP->Command = ROUTE_FOAD; | ||
339 | memcpy(PktReplyP->CommandText, "RT_FOAD", 7); | ||
340 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); | ||
341 | return 1; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | ** Send the ID (entry) to this RTA. The ID number is implicit as | ||
346 | ** the offset into the table. It is worth noting at this stage | ||
347 | ** that offset zero in the table contains the entries for the | ||
348 | ** RTA with ID 1!!!! | ||
349 | */ | ||
350 | PktReplyP->Command = ROUTE_ALLOCATE; | ||
351 | PktReplyP->IDNum = ThisUnit + 1; | ||
352 | if (RtaType == TYPE_RTA16) { | ||
353 | if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) | ||
354 | /* | ||
355 | ** Adjust the phb and tx pkt dest_units for 2nd block of 8 | ||
356 | ** only if the RTA has ports associated (SLOT_IN_USE) | ||
357 | */ | ||
358 | RIOFixPhbs(p, HostP, ThisUnit2); | ||
359 | PktReplyP->IDNum2 = ThisUnit2 + 1; | ||
360 | rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2); | ||
361 | } else { | ||
362 | PktReplyP->IDNum2 = ROUTE_NO_ID; | ||
363 | rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum); | ||
364 | } | ||
365 | memcpy(PktReplyP->CommandText, "RT_ALLOCAT", 10); | ||
366 | |||
367 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); | ||
368 | |||
369 | /* | ||
370 | ** If this is a freshly booted RTA, then we need to re-open | ||
371 | ** the ports, if any where open, so that data may once more | ||
372 | ** flow around the system! | ||
373 | */ | ||
374 | if ((HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) && (HostP->Mapping[ThisUnit].SysPort != NO_PORT)) { | ||
375 | /* | ||
376 | ** look at the ports associated with this beast and | ||
377 | ** see if any where open. If they was, then re-open | ||
378 | ** them, using the info from the tty flags. | ||
379 | */ | ||
380 | for (port = 0; port < PORTS_PER_RTA; port++) { | ||
381 | PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]; | ||
382 | if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { | ||
383 | rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); | ||
384 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
385 | PortP->MagicFlags |= MAGIC_REBOOT; | ||
386 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
387 | } | ||
388 | } | ||
389 | if (RtaType == TYPE_RTA16) { | ||
390 | for (port = 0; port < PORTS_PER_RTA; port++) { | ||
391 | PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]; | ||
392 | if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { | ||
393 | rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); | ||
394 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
395 | PortP->MagicFlags |= MAGIC_REBOOT; | ||
396 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | ** keep a copy of the module types! | ||
404 | */ | ||
405 | HostP->UnixRups[ThisUnit].ModTypes = Mod; | ||
406 | if (RtaType == TYPE_RTA16) | ||
407 | HostP->UnixRups[ThisUnit2].ModTypes = Mod; | ||
408 | |||
409 | /* | ||
410 | ** If either of the modules on this unit is read-only or write-only | ||
411 | ** or none-xprint, then we need to transfer that info over to the | ||
412 | ** relevant ports. | ||
413 | */ | ||
414 | if (HostP->Mapping[ThisUnit].SysPort != NO_PORT) { | ||
415 | for (port = 0; port < PORTS_PER_MODULE; port++) { | ||
416 | p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; | ||
417 | p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; | ||
418 | p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; | ||
419 | p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; | ||
420 | } | ||
421 | if (RtaType == TYPE_RTA16) { | ||
422 | for (port = 0; port < PORTS_PER_MODULE; port++) { | ||
423 | p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; | ||
424 | p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; | ||
425 | p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; | ||
426 | p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; | ||
427 | } | ||
428 | } | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | ** Job done, get on with the interrupts! | ||
433 | */ | ||
434 | return 1; | ||
435 | } | ||
436 | } | ||
437 | /* | ||
438 | ** There is no table entry for this RTA at all. | ||
439 | ** | ||
440 | ** Lets check to see if we actually booted this unit - if not, | ||
441 | ** then we reset it and it will go round the loop of being booted | ||
442 | ** we can then worry about trying to fit it into the table. | ||
443 | */ | ||
444 | for (ThisUnit = 0; ThisUnit < HostP->NumExtraBooted; ThisUnit++) | ||
445 | if (HostP->ExtraUnits[ThisUnit] == RtaUniq) | ||
446 | break; | ||
447 | if (ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS) { | ||
448 | /* | ||
449 | ** if the unit wasn't in the table, and the table wasn't full, then | ||
450 | ** we reset the unit, because we didn't boot it. | ||
451 | ** However, if the table is full, it could be that we did boot | ||
452 | ** this unit, and so we won't reboot it, because it isn't really | ||
453 | ** all that disasterous to keep the old bins in most cases. This | ||
454 | ** is a rather tacky feature, but we are on the edge of reallity | ||
455 | ** here, because the implication is that someone has connected | ||
456 | ** 16+MAX_EXTRA_UNITS onto one host. | ||
457 | */ | ||
458 | static int UnknownMesgDone = 0; | ||
459 | |||
460 | if (!UnknownMesgDone) { | ||
461 | if (!p->RIONoMessage) | ||
462 | printk(KERN_DEBUG "rio: One or more unknown RTAs are being updated.\n"); | ||
463 | UnknownMesgDone = 1; | ||
464 | } | ||
465 | |||
466 | PktReplyP->Command = ROUTE_FOAD; | ||
467 | memcpy(PktReplyP->CommandText, "RT_FOAD", 7); | ||
468 | } else { | ||
469 | /* | ||
470 | ** we did boot it (as an extra), and there may now be a table | ||
471 | ** slot free (because of a delete), so we will try to make | ||
472 | ** a tentative entry for it, so that the configurator can see it | ||
473 | ** and fill in the details for us. | ||
474 | */ | ||
475 | if (RtaType == TYPE_RTA16) { | ||
476 | if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) { | ||
477 | RIODefaultName(p, HostP, ThisUnit); | ||
478 | rio_fill_host_slot(ThisUnit, ThisUnit2, RtaUniq, HostP); | ||
479 | } | ||
480 | } else { | ||
481 | if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) { | ||
482 | RIODefaultName(p, HostP, ThisUnit); | ||
483 | rio_fill_host_slot(ThisUnit, 0, RtaUniq, HostP); | ||
484 | } | ||
485 | } | ||
486 | PktReplyP->Command = ROUTE_USED; | ||
487 | memcpy(PktReplyP->CommandText, "RT_USED", 7); | ||
488 | } | ||
489 | RIOQueueCmdBlk(HostP, Rup, CmdBlkP); | ||
490 | return 1; | ||
491 | } | ||
492 | |||
493 | |||
494 | void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit) | ||
495 | { | ||
496 | unsigned short link, port; | ||
497 | struct Port *PortP; | ||
498 | unsigned long flags; | ||
499 | int PortN = HostP->Mapping[unit].SysPort; | ||
500 | |||
501 | rio_dprintk(RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN); | ||
502 | |||
503 | if (PortN != -1) { | ||
504 | unsigned short dest_unit = HostP->Mapping[unit].ID2; | ||
505 | |||
506 | /* | ||
507 | ** Get the link number used for the 1st 8 phbs on this unit. | ||
508 | */ | ||
509 | PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort]; | ||
510 | |||
511 | link = readw(&PortP->PhbP->link); | ||
512 | |||
513 | for (port = 0; port < PORTS_PER_RTA; port++, PortN++) { | ||
514 | unsigned short dest_port = port + 8; | ||
515 | u16 __iomem *TxPktP; | ||
516 | struct PKT __iomem *Pkt; | ||
517 | |||
518 | PortP = p->RIOPortp[PortN]; | ||
519 | |||
520 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
521 | /* | ||
522 | ** If RTA is not powered on, the tx packets will be | ||
523 | ** unset, so go no further. | ||
524 | */ | ||
525 | if (!PortP->TxStart) { | ||
526 | rio_dprintk(RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n"); | ||
527 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
528 | break; | ||
529 | } | ||
530 | |||
531 | /* | ||
532 | ** For the second slot of a 16 port RTA, the driver needs to | ||
533 | ** sort out the phb to port mappings. The dest_unit for this | ||
534 | ** group of 8 phbs is set to the dest_unit of the accompanying | ||
535 | ** 8 port block. The dest_port of the second unit is set to | ||
536 | ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port | ||
537 | ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6 | ||
538 | ** (being the second map ID) will be sent to dest_unit 5, port | ||
539 | ** 14. When this RTA is deleted, dest_unit for ID 6 will be | ||
540 | ** restored, and the dest_port will be reduced by 8. | ||
541 | ** Transmit packets also have a destination field which needs | ||
542 | ** adjusting in the same manner. | ||
543 | ** Note that the unit/port bytes in 'dest' are swapped. | ||
544 | ** We also need to adjust the phb and rup link numbers for the | ||
545 | ** second block of 8 ttys. | ||
546 | */ | ||
547 | for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { | ||
548 | /* | ||
549 | ** *TxPktP is the pointer to the transmit packet on the host | ||
550 | ** card. This needs to be translated into a 32 bit pointer | ||
551 | ** so it can be accessed from the driver. | ||
552 | */ | ||
553 | Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP)); | ||
554 | |||
555 | /* | ||
556 | ** If the packet is used, reset it. | ||
557 | */ | ||
558 | Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE); | ||
559 | writeb(dest_unit, &Pkt->dest_unit); | ||
560 | writeb(dest_port, &Pkt->dest_port); | ||
561 | } | ||
562 | rio_dprintk(RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n", readw(&PortP->PhbP->destination) & 0xff, (readw(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); | ||
563 | writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); | ||
564 | writew(link, &PortP->PhbP->link); | ||
565 | |||
566 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
567 | } | ||
568 | /* | ||
569 | ** Now make sure the range of ports to be serviced includes | ||
570 | ** the 2nd 8 on this 16 port RTA. | ||
571 | */ | ||
572 | if (link > 3) | ||
573 | return; | ||
574 | if (((unit * 8) + 7) > readw(&HostP->LinkStrP[link].last_port)) { | ||
575 | rio_dprintk(RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7); | ||
576 | writew((unit * 8) + 7, &HostP->LinkStrP[link].last_port); | ||
577 | } | ||
578 | } | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | ** Check to see if the new disconnection has isolated this unit. | ||
583 | ** If it has, then invalidate all its link information, and tell | ||
584 | ** the world about it. This is done to ensure that the configurator | ||
585 | ** only gets up-to-date information about what is going on. | ||
586 | */ | ||
587 | static int RIOCheckIsolated(struct rio_info *p, struct Host *HostP, unsigned int UnitId) | ||
588 | { | ||
589 | unsigned long flags; | ||
590 | rio_spin_lock_irqsave(&HostP->HostLock, flags); | ||
591 | |||
592 | if (RIOCheck(HostP, UnitId)) { | ||
593 | rio_dprintk(RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId); | ||
594 | rio_spin_unlock_irqrestore(&HostP->HostLock, flags); | ||
595 | return (0); | ||
596 | } | ||
597 | |||
598 | RIOIsolate(p, HostP, UnitId); | ||
599 | RIOSetChange(p); | ||
600 | rio_spin_unlock_irqrestore(&HostP->HostLock, flags); | ||
601 | return 1; | ||
602 | } | ||
603 | |||
604 | /* | ||
605 | ** Invalidate all the link interconnectivity of this unit, and of | ||
606 | ** all the units attached to it. This will mean that the entire | ||
607 | ** subnet will re-introduce itself. | ||
608 | */ | ||
609 | static int RIOIsolate(struct rio_info *p, struct Host *HostP, unsigned int UnitId) | ||
610 | { | ||
611 | unsigned int link, unit; | ||
612 | |||
613 | UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */ | ||
614 | |||
615 | if (UnitId >= MAX_RUP) /* dontcha just lurv unsigned maths! */ | ||
616 | return (0); | ||
617 | |||
618 | if (HostP->Mapping[UnitId].Flags & BEEN_HERE) | ||
619 | return (0); | ||
620 | |||
621 | HostP->Mapping[UnitId].Flags |= BEEN_HERE; | ||
622 | |||
623 | if (p->RIOPrintDisabled == DO_PRINT) | ||
624 | rio_dprintk(RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name); | ||
625 | |||
626 | for (link = 0; link < LINKS_PER_UNIT; link++) { | ||
627 | unit = HostP->Mapping[UnitId].Topology[link].Unit; | ||
628 | HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT; | ||
629 | HostP->Mapping[UnitId].Topology[link].Link = NO_LINK; | ||
630 | RIOIsolate(p, HostP, unit); | ||
631 | } | ||
632 | HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; | ||
633 | return 1; | ||
634 | } | ||
635 | |||
636 | static int RIOCheck(struct Host *HostP, unsigned int UnitId) | ||
637 | { | ||
638 | unsigned char link; | ||
639 | |||
640 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */ | ||
641 | rio_dprintk(RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId); | ||
642 | |||
643 | if (UnitId == HOST_ID) { | ||
644 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */ | ||
645 | return 1; | ||
646 | } | ||
647 | |||
648 | UnitId--; | ||
649 | |||
650 | if (UnitId >= MAX_RUP) { | ||
651 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */ | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | for (link = 0; link < LINKS_PER_UNIT; link++) { | ||
656 | if (HostP->Mapping[UnitId].Topology[link].Unit == HOST_ID) { | ||
657 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n", | ||
658 | UnitId, 'A'+link)); */ | ||
659 | return 1; | ||
660 | } | ||
661 | } | ||
662 | |||
663 | if (HostP->Mapping[UnitId].Flags & BEEN_HERE) { | ||
664 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */ | ||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | HostP->Mapping[UnitId].Flags |= BEEN_HERE; | ||
669 | |||
670 | for (link = 0; link < LINKS_PER_UNIT; link++) { | ||
671 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */ | ||
672 | if (RIOCheck(HostP, HostP->Mapping[UnitId].Topology[link].Unit)) { | ||
673 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */ | ||
674 | HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; | ||
675 | return 1; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; | ||
680 | |||
681 | /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */ | ||
682 | |||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | /* | ||
687 | ** Returns the type of unit (host, 16/8 port RTA) | ||
688 | */ | ||
689 | |||
690 | unsigned int GetUnitType(unsigned int Uniq) | ||
691 | { | ||
692 | switch ((Uniq >> 28) & 0xf) { | ||
693 | case RIO_AT: | ||
694 | case RIO_MCA: | ||
695 | case RIO_EISA: | ||
696 | case RIO_PCI: | ||
697 | rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Host\n"); | ||
698 | return (TYPE_HOST); | ||
699 | case RIO_RTA_16: | ||
700 | rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n"); | ||
701 | return (TYPE_RTA16); | ||
702 | case RIO_RTA: | ||
703 | rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n"); | ||
704 | return (TYPE_RTA8); | ||
705 | default: | ||
706 | rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n"); | ||
707 | return (99); | ||
708 | } | ||
709 | } | ||
710 | |||
711 | int RIOSetChange(struct rio_info *p) | ||
712 | { | ||
713 | if (p->RIOQuickCheck != NOT_CHANGED) | ||
714 | return (0); | ||
715 | p->RIOQuickCheck = CHANGED; | ||
716 | if (p->RIOSignalProcess) { | ||
717 | rio_dprintk(RIO_DEBUG_ROUTE, "Send SIG-HUP"); | ||
718 | /* | ||
719 | psignal( RIOSignalProcess, SIGHUP ); | ||
720 | */ | ||
721 | } | ||
722 | return (0); | ||
723 | } | ||
724 | |||
725 | static void RIOConCon(struct rio_info *p, | ||
726 | struct Host *HostP, | ||
727 | unsigned int FromId, | ||
728 | unsigned int FromLink, | ||
729 | unsigned int ToId, | ||
730 | unsigned int ToLink, | ||
731 | int Change) | ||
732 | { | ||
733 | char *FromName; | ||
734 | char *FromType; | ||
735 | char *ToName; | ||
736 | char *ToType; | ||
737 | unsigned int tp; | ||
738 | |||
739 | /* | ||
740 | ** 15.10.1998 ARG - ESIL 0759 | ||
741 | ** (Part) fix for port being trashed when opened whilst RTA "disconnected" | ||
742 | ** | ||
743 | ** What's this doing in here anyway ? | ||
744 | ** It was causing the port to be 'unmapped' if opened whilst RTA "disconnected" | ||
745 | ** | ||
746 | ** 09.12.1998 ARG - ESIL 0776 - part fix | ||
747 | ** Okay, We've found out what this was all about now ! | ||
748 | ** Someone had botched this to use RIOHalted to indicated the number of RTAs | ||
749 | ** 'disconnected'. The value in RIOHalted was then being used in the | ||
750 | ** 'RIO_QUICK_CHECK' ioctl. A none zero value indicating that a least one RTA | ||
751 | ** is 'disconnected'. The change was put in to satisfy a customer's needs. | ||
752 | ** Having taken this bit of code out 'RIO_QUICK_CHECK' now no longer works for | ||
753 | ** the customer. | ||
754 | ** | ||
755 | if (Change == CONNECT) { | ||
756 | if (p->RIOHalted) p->RIOHalted --; | ||
757 | } | ||
758 | else { | ||
759 | p->RIOHalted ++; | ||
760 | } | ||
761 | ** | ||
762 | ** So - we need to implement it slightly differently - a new member of the | ||
763 | ** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA | ||
764 | ** connections and disconnections. | ||
765 | */ | ||
766 | if (Change == CONNECT) { | ||
767 | if (p->RIORtaDisCons) | ||
768 | p->RIORtaDisCons--; | ||
769 | } else { | ||
770 | p->RIORtaDisCons++; | ||
771 | } | ||
772 | |||
773 | if (p->RIOPrintDisabled == DONT_PRINT) | ||
774 | return; | ||
775 | |||
776 | if (FromId > ToId) { | ||
777 | tp = FromId; | ||
778 | FromId = ToId; | ||
779 | ToId = tp; | ||
780 | tp = FromLink; | ||
781 | FromLink = ToLink; | ||
782 | ToLink = tp; | ||
783 | } | ||
784 | |||
785 | FromName = FromId ? HostP->Mapping[FromId - 1].Name : HostP->Name; | ||
786 | FromType = FromId ? "RTA" : "HOST"; | ||
787 | ToName = ToId ? HostP->Mapping[ToId - 1].Name : HostP->Name; | ||
788 | ToType = ToId ? "RTA" : "HOST"; | ||
789 | |||
790 | rio_dprintk(RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); | ||
791 | printk(KERN_DEBUG "rio: Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); | ||
792 | } | ||
793 | |||
794 | /* | ||
795 | ** RIORemoveFromSavedTable : | ||
796 | ** | ||
797 | ** Delete and RTA entry from the saved table given to us | ||
798 | ** by the configuration program. | ||
799 | */ | ||
800 | static int RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap) | ||
801 | { | ||
802 | int entry; | ||
803 | |||
804 | /* | ||
805 | ** We loop for all entries even after finding an entry and | ||
806 | ** zeroing it because we may have two entries to delete if | ||
807 | ** it's a 16 port RTA. | ||
808 | */ | ||
809 | for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { | ||
810 | if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum) { | ||
811 | memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); | ||
812 | } | ||
813 | } | ||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | |||
818 | /* | ||
819 | ** RIOCheckDisconnected : | ||
820 | ** | ||
821 | ** Scan the unit links to and return zero if the unit is completely | ||
822 | ** disconnected. | ||
823 | */ | ||
824 | static int RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit) | ||
825 | { | ||
826 | int link; | ||
827 | |||
828 | |||
829 | rio_dprintk(RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit); | ||
830 | /* | ||
831 | ** If the slot is tentative and does not belong to the | ||
832 | ** second half of a 16 port RTA then scan to see if | ||
833 | ** is disconnected. | ||
834 | */ | ||
835 | for (link = 0; link < LINKS_PER_UNIT; link++) { | ||
836 | if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT) | ||
837 | break; | ||
838 | } | ||
839 | |||
840 | /* | ||
841 | ** If not all links are disconnected then we can forget about it. | ||
842 | */ | ||
843 | if (link < LINKS_PER_UNIT) | ||
844 | return 1; | ||
845 | |||
846 | #ifdef NEED_TO_FIX_THIS | ||
847 | /* Ok so all the links are disconnected. But we may have only just | ||
848 | ** made this slot tentative and not yet received a topology update. | ||
849 | ** Lets check how long ago we made it tentative. | ||
850 | */ | ||
851 | rio_dprintk(RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit); | ||
852 | if (drv_getparm(LBOLT, (ulong_t *) & current_time)) | ||
853 | rio_dprintk(RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n"); | ||
854 | |||
855 | elapse_time = current_time - TentTime[unit]; | ||
856 | rio_dprintk(RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n", elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time)); | ||
857 | if (drv_hztousec(elapse_time) < WAIT_TO_FINISH) { | ||
858 | rio_dprintk(RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n", unit, drv_hztousec(elapse_time)); | ||
859 | return 1; | ||
860 | } | ||
861 | #endif | ||
862 | |||
863 | /* | ||
864 | ** We have found an usable slot. | ||
865 | ** If it is half of a 16 port RTA then delete the other half. | ||
866 | */ | ||
867 | if (HostP->Mapping[unit].ID2 != 0) { | ||
868 | int nOther = (HostP->Mapping[unit].ID2) - 1; | ||
869 | |||
870 | rio_dprintk(RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther); | ||
871 | memset(&HostP->Mapping[nOther], 0, sizeof(struct Map)); | ||
872 | } | ||
873 | RIORemoveFromSavedTable(p, &HostP->Mapping[unit]); | ||
874 | |||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | |||
879 | /* | ||
880 | ** RIOFindFreeID : | ||
881 | ** | ||
882 | ** This function scans the given host table for either one | ||
883 | ** or two free unit ID's. | ||
884 | */ | ||
885 | |||
886 | int RIOFindFreeID(struct rio_info *p, struct Host *HostP, unsigned int * pID1, unsigned int * pID2) | ||
887 | { | ||
888 | int unit, tempID; | ||
889 | |||
890 | /* | ||
891 | ** Initialise the ID's to MAX_RUP. | ||
892 | ** We do this to make the loop for setting the ID's as simple as | ||
893 | ** possible. | ||
894 | */ | ||
895 | *pID1 = MAX_RUP; | ||
896 | if (pID2 != NULL) | ||
897 | *pID2 = MAX_RUP; | ||
898 | |||
899 | /* | ||
900 | ** Scan all entries of the host mapping table for free slots. | ||
901 | ** We scan for free slots first and then if that is not successful | ||
902 | ** we start all over again looking for tentative slots we can re-use. | ||
903 | */ | ||
904 | for (unit = 0; unit < MAX_RUP; unit++) { | ||
905 | rio_dprintk(RIO_DEBUG_ROUTE, "Scanning unit %d\n", unit); | ||
906 | /* | ||
907 | ** If the flags are zero then the slot is empty. | ||
908 | */ | ||
909 | if (HostP->Mapping[unit].Flags == 0) { | ||
910 | rio_dprintk(RIO_DEBUG_ROUTE, " This slot is empty.\n"); | ||
911 | /* | ||
912 | ** If we haven't allocated the first ID then do it now. | ||
913 | */ | ||
914 | if (*pID1 == MAX_RUP) { | ||
915 | rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit); | ||
916 | *pID1 = unit; | ||
917 | |||
918 | /* | ||
919 | ** If the second ID is not needed then we can return | ||
920 | ** now. | ||
921 | */ | ||
922 | if (pID2 == NULL) | ||
923 | return 0; | ||
924 | } else { | ||
925 | /* | ||
926 | ** Allocate the second slot and return. | ||
927 | */ | ||
928 | rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit); | ||
929 | *pID2 = unit; | ||
930 | return 0; | ||
931 | } | ||
932 | } | ||
933 | } | ||
934 | |||
935 | /* | ||
936 | ** If we manage to come out of the free slot loop then we | ||
937 | ** need to start all over again looking for tentative slots | ||
938 | ** that we can re-use. | ||
939 | */ | ||
940 | rio_dprintk(RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n"); | ||
941 | for (unit = 0; unit < MAX_RUP; unit++) { | ||
942 | if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) || (HostP->Mapping[unit].Flags == 0)) && !(HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT)) { | ||
943 | rio_dprintk(RIO_DEBUG_ROUTE, " Slot %d looks promising.\n", unit); | ||
944 | |||
945 | if (unit == *pID1) { | ||
946 | rio_dprintk(RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n"); | ||
947 | continue; | ||
948 | } | ||
949 | |||
950 | /* | ||
951 | ** Slot is Tentative or Empty, but not a tentative second | ||
952 | ** slot of a 16 porter. | ||
953 | ** Attempt to free up this slot (and its parnter if | ||
954 | ** it is a 16 port slot. The second slot will become | ||
955 | ** empty after a call to RIOFreeDisconnected so thats why | ||
956 | ** we look for empty slots above as well). | ||
957 | */ | ||
958 | if (HostP->Mapping[unit].Flags != 0) | ||
959 | if (RIOFreeDisconnected(p, HostP, unit) != 0) | ||
960 | continue; | ||
961 | /* | ||
962 | ** If we haven't allocated the first ID then do it now. | ||
963 | */ | ||
964 | if (*pID1 == MAX_RUP) { | ||
965 | rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit); | ||
966 | *pID1 = unit; | ||
967 | |||
968 | /* | ||
969 | ** Clear out this slot now that we intend to use it. | ||
970 | */ | ||
971 | memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); | ||
972 | |||
973 | /* | ||
974 | ** If the second ID is not needed then we can return | ||
975 | ** now. | ||
976 | */ | ||
977 | if (pID2 == NULL) | ||
978 | return 0; | ||
979 | } else { | ||
980 | /* | ||
981 | ** Allocate the second slot and return. | ||
982 | */ | ||
983 | rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n", unit); | ||
984 | *pID2 = unit; | ||
985 | |||
986 | /* | ||
987 | ** Clear out this slot now that we intend to use it. | ||
988 | */ | ||
989 | memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); | ||
990 | |||
991 | /* At this point under the right(wrong?) conditions | ||
992 | ** we may have a first unit ID being higher than the | ||
993 | ** second unit ID. This is a bad idea if we are about | ||
994 | ** to fill the slots with a 16 port RTA. | ||
995 | ** Better check and swap them over. | ||
996 | */ | ||
997 | |||
998 | if (*pID1 > *pID2) { | ||
999 | rio_dprintk(RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2); | ||
1000 | tempID = *pID1; | ||
1001 | *pID1 = *pID2; | ||
1002 | *pID2 = tempID; | ||
1003 | } | ||
1004 | return 0; | ||
1005 | } | ||
1006 | } | ||
1007 | } | ||
1008 | |||
1009 | /* | ||
1010 | ** If we manage to get to the end of the second loop then we | ||
1011 | ** can give up and return a failure. | ||
1012 | */ | ||
1013 | return 1; | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | /* | ||
1018 | ** The link switch scenario. | ||
1019 | ** | ||
1020 | ** Rta Wun (A) is connected to Tuw (A). | ||
1021 | ** The tables are all up to date, and the system is OK. | ||
1022 | ** | ||
1023 | ** If Wun (A) is now moved to Wun (B) before Wun (A) can | ||
1024 | ** become disconnected, then the follow happens: | ||
1025 | ** | ||
1026 | ** Tuw (A) spots the change of unit:link at the other end | ||
1027 | ** of its link and Tuw sends a topology packet reflecting | ||
1028 | ** the change: Tuw (A) now disconnected from Wun (A), and | ||
1029 | ** this is closely followed by a packet indicating that | ||
1030 | ** Tuw (A) is now connected to Wun (B). | ||
1031 | ** | ||
1032 | ** Wun (B) will spot that it has now become connected, and | ||
1033 | ** Wun will send a topology packet, which indicates that | ||
1034 | ** both Wun (A) and Wun (B) is connected to Tuw (A). | ||
1035 | ** | ||
1036 | ** Eventually Wun (A) realises that it is now disconnected | ||
1037 | ** and Wun will send out a topology packet indicating that | ||
1038 | ** Wun (A) is now disconnected. | ||
1039 | */ | ||
diff --git a/drivers/char/rio/riospace.h b/drivers/char/rio/riospace.h deleted file mode 100644 index ffb31d4332b9..000000000000 --- a/drivers/char/rio/riospace.h +++ /dev/null | |||
@@ -1,154 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : riospace.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:13 | ||
26 | ** Retrieved : 11/6/98 11:34:22 | ||
27 | ** | ||
28 | ** ident @(#)riospace.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_riospace_h__ | ||
34 | #define __rio_riospace_h__ | ||
35 | |||
36 | #define RIO_LOCATOR_LEN 16 | ||
37 | #define MAX_RIO_BOARDS 4 | ||
38 | |||
39 | /* | ||
40 | ** DONT change this file. At all. Unless you can rebuild the entire | ||
41 | ** device driver, which you probably can't, then the rest of the | ||
42 | ** driver won't see any changes you make here. So don't make any. | ||
43 | ** In particular, it won't be able to see changes to RIO_SLOTS | ||
44 | */ | ||
45 | |||
46 | struct Conf { | ||
47 | char Locator[24]; | ||
48 | unsigned int StartupTime; | ||
49 | unsigned int SlowCook; | ||
50 | unsigned int IntrPollTime; | ||
51 | unsigned int BreakInterval; | ||
52 | unsigned int Timer; | ||
53 | unsigned int RtaLoadBase; | ||
54 | unsigned int HostLoadBase; | ||
55 | unsigned int XpHz; | ||
56 | unsigned int XpCps; | ||
57 | char *XpOn; | ||
58 | char *XpOff; | ||
59 | unsigned int MaxXpCps; | ||
60 | unsigned int MinXpCps; | ||
61 | unsigned int SpinCmds; | ||
62 | unsigned int FirstAddr; | ||
63 | unsigned int LastAddr; | ||
64 | unsigned int BufferSize; | ||
65 | unsigned int LowWater; | ||
66 | unsigned int LineLength; | ||
67 | unsigned int CmdTime; | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | ** Board types - these MUST correspond to product codes! | ||
72 | */ | ||
73 | #define RIO_EMPTY 0x0 | ||
74 | #define RIO_EISA 0x3 | ||
75 | #define RIO_RTA_16 0x9 | ||
76 | #define RIO_AT 0xA | ||
77 | #define RIO_MCA 0xB | ||
78 | #define RIO_PCI 0xD | ||
79 | #define RIO_RTA 0xE | ||
80 | |||
81 | /* | ||
82 | ** Board data structure. This is used for configuration info | ||
83 | */ | ||
84 | struct Brd { | ||
85 | unsigned char Type; /* RIO_EISA, RIO_MCA, RIO_AT, RIO_EMPTY... */ | ||
86 | unsigned char Ivec; /* POLLED or ivec number */ | ||
87 | unsigned char Mode; /* Control stuff, see below */ | ||
88 | }; | ||
89 | |||
90 | struct Board { | ||
91 | char Locator[RIO_LOCATOR_LEN]; | ||
92 | int NumSlots; | ||
93 | struct Brd Boards[MAX_RIO_BOARDS]; | ||
94 | }; | ||
95 | |||
96 | #define BOOT_FROM_LINK 0x00 | ||
97 | #define BOOT_FROM_RAM 0x01 | ||
98 | #define EXTERNAL_BUS_OFF 0x00 | ||
99 | #define EXTERNAL_BUS_ON 0x02 | ||
100 | #define INTERRUPT_DISABLE 0x00 | ||
101 | #define INTERRUPT_ENABLE 0x04 | ||
102 | #define BYTE_OPERATION 0x00 | ||
103 | #define WORD_OPERATION 0x08 | ||
104 | #define POLLED INTERRUPT_DISABLE | ||
105 | #define IRQ_15 (0x00 | INTERRUPT_ENABLE) | ||
106 | #define IRQ_12 (0x10 | INTERRUPT_ENABLE) | ||
107 | #define IRQ_11 (0x20 | INTERRUPT_ENABLE) | ||
108 | #define IRQ_9 (0x30 | INTERRUPT_ENABLE) | ||
109 | #define SLOW_LINKS 0x00 | ||
110 | #define FAST_LINKS 0x40 | ||
111 | #define SLOW_AT_BUS 0x00 | ||
112 | #define FAST_AT_BUS 0x80 | ||
113 | #define SLOW_PCI_TP 0x00 | ||
114 | #define FAST_PCI_TP 0x80 | ||
115 | /* | ||
116 | ** Debug levels | ||
117 | */ | ||
118 | #define DBG_NONE 0x00000000 | ||
119 | |||
120 | #define DBG_INIT 0x00000001 | ||
121 | #define DBG_OPEN 0x00000002 | ||
122 | #define DBG_CLOSE 0x00000004 | ||
123 | #define DBG_IOCTL 0x00000008 | ||
124 | |||
125 | #define DBG_READ 0x00000010 | ||
126 | #define DBG_WRITE 0x00000020 | ||
127 | #define DBG_INTR 0x00000040 | ||
128 | #define DBG_PROC 0x00000080 | ||
129 | |||
130 | #define DBG_PARAM 0x00000100 | ||
131 | #define DBG_CMD 0x00000200 | ||
132 | #define DBG_XPRINT 0x00000400 | ||
133 | #define DBG_POLL 0x00000800 | ||
134 | |||
135 | #define DBG_DAEMON 0x00001000 | ||
136 | #define DBG_FAIL 0x00002000 | ||
137 | #define DBG_MODEM 0x00004000 | ||
138 | #define DBG_LIST 0x00008000 | ||
139 | |||
140 | #define DBG_ROUTE 0x00010000 | ||
141 | #define DBG_UTIL 0x00020000 | ||
142 | #define DBG_BOOT 0x00040000 | ||
143 | #define DBG_BUFFER 0x00080000 | ||
144 | |||
145 | #define DBG_MON 0x00100000 | ||
146 | #define DBG_SPECIAL 0x00200000 | ||
147 | #define DBG_VPIX 0x00400000 | ||
148 | #define DBG_FLUSH 0x00800000 | ||
149 | |||
150 | #define DBG_QENABLE 0x01000000 | ||
151 | |||
152 | #define DBG_ALWAYS 0x80000000 | ||
153 | |||
154 | #endif /* __rio_riospace_h__ */ | ||
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c deleted file mode 100644 index 3d15802dc0f3..000000000000 --- a/drivers/char/rio/riotable.c +++ /dev/null | |||
@@ -1,941 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : riotable.c | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 10:33:47 | ||
26 | ** Retrieved : 11/6/98 10:33:50 | ||
27 | ** | ||
28 | ** ident @(#)riotable.c 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/errno.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/string.h> | ||
38 | |||
39 | #include <asm/io.h> | ||
40 | #include <asm/system.h> | ||
41 | #include <asm/string.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | |||
44 | #include <linux/termios.h> | ||
45 | #include <linux/serial.h> | ||
46 | |||
47 | #include <linux/generic_serial.h> | ||
48 | |||
49 | |||
50 | #include "linux_compat.h" | ||
51 | #include "rio_linux.h" | ||
52 | #include "pkt.h" | ||
53 | #include "daemon.h" | ||
54 | #include "rio.h" | ||
55 | #include "riospace.h" | ||
56 | #include "cmdpkt.h" | ||
57 | #include "map.h" | ||
58 | #include "rup.h" | ||
59 | #include "port.h" | ||
60 | #include "riodrvr.h" | ||
61 | #include "rioinfo.h" | ||
62 | #include "func.h" | ||
63 | #include "errors.h" | ||
64 | #include "pci.h" | ||
65 | |||
66 | #include "parmmap.h" | ||
67 | #include "unixrup.h" | ||
68 | #include "board.h" | ||
69 | #include "host.h" | ||
70 | #include "phb.h" | ||
71 | #include "link.h" | ||
72 | #include "cmdblk.h" | ||
73 | #include "route.h" | ||
74 | #include "cirrus.h" | ||
75 | #include "rioioctl.h" | ||
76 | #include "param.h" | ||
77 | #include "protsts.h" | ||
78 | |||
79 | /* | ||
80 | ** A configuration table has been loaded. It is now up to us | ||
81 | ** to sort it out and use the information contained therein. | ||
82 | */ | ||
83 | int RIONewTable(struct rio_info *p) | ||
84 | { | ||
85 | int Host, Host1, Host2, NameIsUnique, Entry, SubEnt; | ||
86 | struct Map *MapP; | ||
87 | struct Map *HostMapP; | ||
88 | struct Host *HostP; | ||
89 | |||
90 | char *cptr; | ||
91 | |||
92 | /* | ||
93 | ** We have been sent a new table to install. We need to break | ||
94 | ** it down into little bits and spread it around a bit to see | ||
95 | ** what we have got. | ||
96 | */ | ||
97 | /* | ||
98 | ** Things to check: | ||
99 | ** (things marked 'xx' aren't checked any more!) | ||
100 | ** (1) That there are no booted Hosts/RTAs out there. | ||
101 | ** (2) That the names are properly formed | ||
102 | ** (3) That blank entries really are. | ||
103 | ** xx (4) That hosts mentioned in the table actually exist. xx | ||
104 | ** (5) That the IDs are unique (per host). | ||
105 | ** (6) That host IDs are zero | ||
106 | ** (7) That port numbers are valid | ||
107 | ** (8) That port numbers aren't duplicated | ||
108 | ** (9) That names aren't duplicated | ||
109 | ** xx (10) That hosts that actually exist are mentioned in the table. xx | ||
110 | */ | ||
111 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n"); | ||
112 | if (p->RIOSystemUp) { /* (1) */ | ||
113 | p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED; | ||
114 | return -EBUSY; | ||
115 | } | ||
116 | |||
117 | p->RIOError.Error = NOTHING_WRONG_AT_ALL; | ||
118 | p->RIOError.Entry = -1; | ||
119 | p->RIOError.Other = -1; | ||
120 | |||
121 | for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { | ||
122 | MapP = &p->RIOConnectTable[Entry]; | ||
123 | if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) { | ||
124 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n"); | ||
125 | cptr = MapP->Name; /* (2) */ | ||
126 | cptr[MAX_NAME_LEN - 1] = '\0'; | ||
127 | if (cptr[0] == '\0') { | ||
128 | memcpy(MapP->Name, MapP->RtaUniqueNum ? "RTA NN" : "HOST NN", 8); | ||
129 | MapP->Name[5] = '0' + Entry / 10; | ||
130 | MapP->Name[6] = '0' + Entry % 10; | ||
131 | } | ||
132 | while (*cptr) { | ||
133 | if (*cptr < ' ' || *cptr > '~') { | ||
134 | p->RIOError.Error = BAD_CHARACTER_IN_NAME; | ||
135 | p->RIOError.Entry = Entry; | ||
136 | return -ENXIO; | ||
137 | } | ||
138 | cptr++; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | ** If the entry saved was a tentative entry then just forget | ||
144 | ** about it. | ||
145 | */ | ||
146 | if (MapP->Flags & SLOT_TENTATIVE) { | ||
147 | MapP->HostUniqueNum = 0; | ||
148 | MapP->RtaUniqueNum = 0; | ||
149 | continue; | ||
150 | } | ||
151 | |||
152 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n"); | ||
153 | if (!MapP->RtaUniqueNum && !MapP->HostUniqueNum) { /* (3) */ | ||
154 | if (MapP->ID || MapP->SysPort || MapP->Flags) { | ||
155 | rio_dprintk(RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n", MapP->Name); | ||
156 | p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL; | ||
157 | p->RIOError.Entry = Entry; | ||
158 | return -ENXIO; | ||
159 | } | ||
160 | rio_dprintk(RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n"); | ||
161 | continue; | ||
162 | } | ||
163 | |||
164 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n"); | ||
165 | for (Host = 0; Host < p->RIONumHosts; Host++) { /* (4) */ | ||
166 | if (p->RIOHosts[Host].UniqueNum == MapP->HostUniqueNum) { | ||
167 | HostP = &p->RIOHosts[Host]; | ||
168 | /* | ||
169 | ** having done the lookup, we don't really want to do | ||
170 | ** it again, so hang the host number in a safe place | ||
171 | */ | ||
172 | MapP->Topology[0].Unit = Host; | ||
173 | break; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | if (Host >= p->RIONumHosts) { | ||
178 | rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n", MapP->Name, MapP->HostUniqueNum); | ||
179 | MapP->HostUniqueNum = 0; | ||
180 | /* MapP->RtaUniqueNum = 0; */ | ||
181 | /* MapP->ID = 0; */ | ||
182 | /* MapP->Flags = 0; */ | ||
183 | /* MapP->SysPort = 0; */ | ||
184 | /* MapP->Name[0] = 0; */ | ||
185 | continue; | ||
186 | } | ||
187 | |||
188 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n"); | ||
189 | if (MapP->RtaUniqueNum) { /* (5) */ | ||
190 | if (!MapP->ID) { | ||
191 | rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n", MapP->Name); | ||
192 | p->RIOError.Error = ZERO_RTA_ID; | ||
193 | p->RIOError.Entry = Entry; | ||
194 | return -ENXIO; | ||
195 | } | ||
196 | if (MapP->ID > MAX_RUP) { | ||
197 | rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n", MapP->Name, MapP->ID); | ||
198 | p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; | ||
199 | p->RIOError.Entry = Entry; | ||
200 | return -ENXIO; | ||
201 | } | ||
202 | for (SubEnt = 0; SubEnt < Entry; SubEnt++) { | ||
203 | if (MapP->HostUniqueNum == p->RIOConnectTable[SubEnt].HostUniqueNum && MapP->ID == p->RIOConnectTable[SubEnt].ID) { | ||
204 | rio_dprintk(RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n", MapP->Name, p->RIOConnectTable[SubEnt].Name); | ||
205 | p->RIOError.Error = DUPLICATED_RTA_ID; | ||
206 | p->RIOError.Entry = Entry; | ||
207 | p->RIOError.Other = SubEnt; | ||
208 | return -ENXIO; | ||
209 | } | ||
210 | /* | ||
211 | ** If the RtaUniqueNum is the same, it may be looking at both | ||
212 | ** entries for a 16 port RTA, so check the ids | ||
213 | */ | ||
214 | if ((MapP->RtaUniqueNum == p->RIOConnectTable[SubEnt].RtaUniqueNum) | ||
215 | && (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) { | ||
216 | rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", MapP->Name); | ||
217 | rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", p->RIOConnectTable[SubEnt].Name); | ||
218 | p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER; | ||
219 | p->RIOError.Entry = Entry; | ||
220 | p->RIOError.Other = SubEnt; | ||
221 | return -ENXIO; | ||
222 | } | ||
223 | } | ||
224 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n"); | ||
225 | /* (7a) */ | ||
226 | if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { | ||
227 | rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n", (int) MapP->SysPort, MapP->Name, PORTS_PER_RTA); | ||
228 | p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; | ||
229 | p->RIOError.Entry = Entry; | ||
230 | return -ENXIO; | ||
231 | } | ||
232 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n"); | ||
233 | /* (7b) */ | ||
234 | if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { | ||
235 | rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n", (int) MapP->SysPort, MapP->Name); | ||
236 | p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; | ||
237 | p->RIOError.Entry = Entry; | ||
238 | return -ENXIO; | ||
239 | } | ||
240 | for (SubEnt = 0; SubEnt < Entry; SubEnt++) { | ||
241 | if (p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT) | ||
242 | continue; | ||
243 | if (p->RIOConnectTable[SubEnt].RtaUniqueNum) { | ||
244 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n"); | ||
245 | /* (8) */ | ||
246 | if ((MapP->SysPort != NO_PORT) && (MapP->SysPort == p->RIOConnectTable[SubEnt].SysPort)) { | ||
247 | rio_dprintk(RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n", MapP->Name, p->RIOConnectTable[SubEnt].Name, (int) MapP->SysPort); | ||
248 | p->RIOError.Error = TTY_NUMBER_IN_USE; | ||
249 | p->RIOError.Entry = Entry; | ||
250 | p->RIOError.Other = SubEnt; | ||
251 | return -ENXIO; | ||
252 | } | ||
253 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n"); | ||
254 | if (strcmp(MapP->Name, p->RIOConnectTable[SubEnt].Name) == 0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */ | ||
255 | rio_dprintk(RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name); | ||
256 | p->RIOError.Error = NAME_USED_TWICE; | ||
257 | p->RIOError.Entry = Entry; | ||
258 | p->RIOError.Other = SubEnt; | ||
259 | return -ENXIO; | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | } else { /* (6) */ | ||
264 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n"); | ||
265 | if (MapP->ID) { | ||
266 | rio_dprintk(RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n", MapP->Name); | ||
267 | p->RIOError.Error = HOST_ID_NOT_ZERO; | ||
268 | p->RIOError.Entry = Entry; | ||
269 | return -ENXIO; | ||
270 | } | ||
271 | if (MapP->SysPort != NO_PORT) { | ||
272 | rio_dprintk(RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n", MapP->Name); | ||
273 | p->RIOError.Error = HOST_SYSPORT_BAD; | ||
274 | p->RIOError.Entry = Entry; | ||
275 | return -ENXIO; | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /* | ||
281 | ** wow! if we get here then it's a goody! | ||
282 | */ | ||
283 | |||
284 | /* | ||
285 | ** Zero the (old) entries for each host... | ||
286 | */ | ||
287 | for (Host = 0; Host < RIO_HOSTS; Host++) { | ||
288 | for (Entry = 0; Entry < MAX_RUP; Entry++) { | ||
289 | memset(&p->RIOHosts[Host].Mapping[Entry], 0, sizeof(struct Map)); | ||
290 | } | ||
291 | memset(&p->RIOHosts[Host].Name[0], 0, sizeof(p->RIOHosts[Host].Name)); | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | ** Copy in the new table entries | ||
296 | */ | ||
297 | for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { | ||
298 | rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry); | ||
299 | MapP = &p->RIOConnectTable[Entry]; | ||
300 | |||
301 | /* | ||
302 | ** Now, if it is an empty slot ignore it! | ||
303 | */ | ||
304 | if (MapP->HostUniqueNum == 0) | ||
305 | continue; | ||
306 | |||
307 | /* | ||
308 | ** we saved the host number earlier, so grab it back | ||
309 | */ | ||
310 | HostP = &p->RIOHosts[MapP->Topology[0].Unit]; | ||
311 | |||
312 | /* | ||
313 | ** If it is a host, then we only need to fill in the name field. | ||
314 | */ | ||
315 | if (MapP->ID == 0) { | ||
316 | rio_dprintk(RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name); | ||
317 | memcpy(HostP->Name, MapP->Name, MAX_NAME_LEN); | ||
318 | continue; | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | ** Its an RTA entry, so fill in the host mapping entries for it | ||
323 | ** and the port mapping entries. Notice that entry zero is for | ||
324 | ** ID one. | ||
325 | */ | ||
326 | HostMapP = &HostP->Mapping[MapP->ID - 1]; | ||
327 | |||
328 | if (MapP->Flags & SLOT_IN_USE) { | ||
329 | rio_dprintk(RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name); | ||
330 | /* | ||
331 | ** structure assign, then sort out the bits we shouldn't have done | ||
332 | */ | ||
333 | *HostMapP = *MapP; | ||
334 | |||
335 | HostMapP->Flags = SLOT_IN_USE; | ||
336 | if (MapP->Flags & RTA16_SECOND_SLOT) | ||
337 | HostMapP->Flags |= RTA16_SECOND_SLOT; | ||
338 | |||
339 | RIOReMapPorts(p, HostP, HostMapP); | ||
340 | } else { | ||
341 | rio_dprintk(RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { | ||
346 | p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry]; | ||
347 | } | ||
348 | |||
349 | for (Host = 0; Host < p->RIONumHosts; Host++) { | ||
350 | for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { | ||
351 | p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT; | ||
352 | p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK; | ||
353 | } | ||
354 | for (Entry = 0; Entry < MAX_RUP; Entry++) { | ||
355 | for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { | ||
356 | p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit = ROUTE_DISCONNECT; | ||
357 | p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link = NO_LINK; | ||
358 | } | ||
359 | } | ||
360 | if (!p->RIOHosts[Host].Name[0]) { | ||
361 | memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); | ||
362 | p->RIOHosts[Host].Name[5] += Host; | ||
363 | } | ||
364 | /* | ||
365 | ** Check that default name assigned is unique. | ||
366 | */ | ||
367 | Host1 = Host; | ||
368 | NameIsUnique = 0; | ||
369 | while (!NameIsUnique) { | ||
370 | NameIsUnique = 1; | ||
371 | for (Host2 = 0; Host2 < p->RIONumHosts; Host2++) { | ||
372 | if (Host2 == Host) | ||
373 | continue; | ||
374 | if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name) | ||
375 | == 0) { | ||
376 | NameIsUnique = 0; | ||
377 | Host1++; | ||
378 | if (Host1 >= p->RIONumHosts) | ||
379 | Host1 = 0; | ||
380 | p->RIOHosts[Host].Name[5] = '1' + Host1; | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | /* | ||
385 | ** Rename host if name already used. | ||
386 | */ | ||
387 | if (Host1 != Host) { | ||
388 | rio_dprintk(RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name); | ||
389 | memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); | ||
390 | p->RIOHosts[Host].Name[5] += Host1; | ||
391 | } | ||
392 | rio_dprintk(RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name); | ||
393 | } | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | ** User process needs the config table - build it from first | ||
399 | ** principles. | ||
400 | ** | ||
401 | * FIXME: SMP locking | ||
402 | */ | ||
403 | int RIOApel(struct rio_info *p) | ||
404 | { | ||
405 | int Host; | ||
406 | int link; | ||
407 | int Rup; | ||
408 | int Next = 0; | ||
409 | struct Map *MapP; | ||
410 | struct Host *HostP; | ||
411 | unsigned long flags; | ||
412 | |||
413 | rio_dprintk(RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n"); | ||
414 | |||
415 | memset(&p->RIOConnectTable[0], 0, sizeof(struct Map) * TOTAL_MAP_ENTRIES); | ||
416 | |||
417 | for (Host = 0; Host < RIO_HOSTS; Host++) { | ||
418 | rio_dprintk(RIO_DEBUG_TABLE, "Processing host %d\n", Host); | ||
419 | HostP = &p->RIOHosts[Host]; | ||
420 | rio_spin_lock_irqsave(&HostP->HostLock, flags); | ||
421 | |||
422 | MapP = &p->RIOConnectTable[Next++]; | ||
423 | MapP->HostUniqueNum = HostP->UniqueNum; | ||
424 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { | ||
425 | rio_spin_unlock_irqrestore(&HostP->HostLock, flags); | ||
426 | continue; | ||
427 | } | ||
428 | MapP->RtaUniqueNum = 0; | ||
429 | MapP->ID = 0; | ||
430 | MapP->Flags = SLOT_IN_USE; | ||
431 | MapP->SysPort = NO_PORT; | ||
432 | for (link = 0; link < LINKS_PER_UNIT; link++) | ||
433 | MapP->Topology[link] = HostP->Topology[link]; | ||
434 | memcpy(MapP->Name, HostP->Name, MAX_NAME_LEN); | ||
435 | for (Rup = 0; Rup < MAX_RUP; Rup++) { | ||
436 | if (HostP->Mapping[Rup].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) { | ||
437 | p->RIOConnectTable[Next] = HostP->Mapping[Rup]; | ||
438 | if (HostP->Mapping[Rup].Flags & SLOT_IN_USE) | ||
439 | p->RIOConnectTable[Next].Flags |= SLOT_IN_USE; | ||
440 | if (HostP->Mapping[Rup].Flags & SLOT_TENTATIVE) | ||
441 | p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE; | ||
442 | if (HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT) | ||
443 | p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT; | ||
444 | Next++; | ||
445 | } | ||
446 | } | ||
447 | rio_spin_unlock_irqrestore(&HostP->HostLock, flags); | ||
448 | } | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | ** config.rio has taken a dislike to one of the gross maps entries. | ||
454 | ** if the entry is suitably inactive, then we can gob on it and remove | ||
455 | ** it from the table. | ||
456 | */ | ||
457 | int RIODeleteRta(struct rio_info *p, struct Map *MapP) | ||
458 | { | ||
459 | int host, entry, port, link; | ||
460 | int SysPort; | ||
461 | struct Host *HostP; | ||
462 | struct Map *HostMapP; | ||
463 | struct Port *PortP; | ||
464 | int work_done = 0; | ||
465 | unsigned long lock_flags, sem_flags; | ||
466 | |||
467 | rio_dprintk(RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n", MapP->HostUniqueNum, MapP->RtaUniqueNum); | ||
468 | |||
469 | for (host = 0; host < p->RIONumHosts; host++) { | ||
470 | HostP = &p->RIOHosts[host]; | ||
471 | |||
472 | rio_spin_lock_irqsave(&HostP->HostLock, lock_flags); | ||
473 | |||
474 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { | ||
475 | rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); | ||
476 | continue; | ||
477 | } | ||
478 | |||
479 | for (entry = 0; entry < MAX_RUP; entry++) { | ||
480 | if (MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum) { | ||
481 | HostMapP = &HostP->Mapping[entry]; | ||
482 | rio_dprintk(RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", entry, HostP->Name); | ||
483 | |||
484 | /* | ||
485 | ** Check all four links of the unit are disconnected | ||
486 | */ | ||
487 | for (link = 0; link < LINKS_PER_UNIT; link++) { | ||
488 | if (HostMapP->Topology[link].Unit != ROUTE_DISCONNECT) { | ||
489 | rio_dprintk(RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n"); | ||
490 | p->RIOError.Error = UNIT_IS_IN_USE; | ||
491 | rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); | ||
492 | return -EBUSY; | ||
493 | } | ||
494 | } | ||
495 | /* | ||
496 | ** Slot has been allocated, BUT not booted/routed/ | ||
497 | ** connected/selected or anything else-ed | ||
498 | */ | ||
499 | SysPort = HostMapP->SysPort; | ||
500 | |||
501 | if (SysPort != NO_PORT) { | ||
502 | for (port = SysPort; port < SysPort + PORTS_PER_RTA; port++) { | ||
503 | PortP = p->RIOPortp[port]; | ||
504 | rio_dprintk(RIO_DEBUG_TABLE, "Unmap port\n"); | ||
505 | |||
506 | rio_spin_lock_irqsave(&PortP->portSem, sem_flags); | ||
507 | |||
508 | PortP->Mapped = 0; | ||
509 | |||
510 | if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { | ||
511 | |||
512 | rio_dprintk(RIO_DEBUG_TABLE, "Gob on port\n"); | ||
513 | PortP->TxBufferIn = PortP->TxBufferOut = 0; | ||
514 | /* What should I do | ||
515 | wakeup( &PortP->TxBufferIn ); | ||
516 | wakeup( &PortP->TxBufferOut); | ||
517 | */ | ||
518 | PortP->InUse = NOT_INUSE; | ||
519 | /* What should I do | ||
520 | wakeup( &PortP->InUse ); | ||
521 | signal(PortP->TtyP->t_pgrp,SIGKILL); | ||
522 | ttyflush(PortP->TtyP,(FREAD|FWRITE)); | ||
523 | */ | ||
524 | PortP->State |= RIO_CLOSING | RIO_DELETED; | ||
525 | } | ||
526 | |||
527 | /* | ||
528 | ** For the second slot of a 16 port RTA, the | ||
529 | ** driver needs to reset the changes made to | ||
530 | ** the phb to port mappings in RIORouteRup. | ||
531 | */ | ||
532 | if (PortP->SecondBlock) { | ||
533 | u16 dest_unit = HostMapP->ID; | ||
534 | u16 dest_port = port - SysPort; | ||
535 | u16 __iomem *TxPktP; | ||
536 | struct PKT __iomem *Pkt; | ||
537 | |||
538 | for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { | ||
539 | /* | ||
540 | ** *TxPktP is the pointer to the | ||
541 | ** transmit packet on the host card. | ||
542 | ** This needs to be translated into | ||
543 | ** a 32 bit pointer so it can be | ||
544 | ** accessed from the driver. | ||
545 | */ | ||
546 | Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP)); | ||
547 | rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port); | ||
548 | writew(dest_unit, &Pkt->dest_unit); | ||
549 | writew(dest_port, &Pkt->dest_port); | ||
550 | } | ||
551 | rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); | ||
552 | writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); | ||
553 | } | ||
554 | rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags); | ||
555 | } | ||
556 | } | ||
557 | rio_dprintk(RIO_DEBUG_TABLE, "Entry nulled.\n"); | ||
558 | memset(HostMapP, 0, sizeof(struct Map)); | ||
559 | work_done++; | ||
560 | } | ||
561 | } | ||
562 | rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); | ||
563 | } | ||
564 | |||
565 | /* XXXXX lock me up */ | ||
566 | for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { | ||
567 | if (p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { | ||
568 | memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); | ||
569 | work_done++; | ||
570 | } | ||
571 | if (p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { | ||
572 | memset(&p->RIOConnectTable[entry], 0, sizeof(struct Map)); | ||
573 | work_done++; | ||
574 | } | ||
575 | } | ||
576 | if (work_done) | ||
577 | return 0; | ||
578 | |||
579 | rio_dprintk(RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n"); | ||
580 | p->RIOError.Error = COULDNT_FIND_ENTRY; | ||
581 | return -ENXIO; | ||
582 | } | ||
583 | |||
584 | int RIOAssignRta(struct rio_info *p, struct Map *MapP) | ||
585 | { | ||
586 | int host; | ||
587 | struct Map *HostMapP; | ||
588 | char *sptr; | ||
589 | int link; | ||
590 | |||
591 | |||
592 | rio_dprintk(RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); | ||
593 | |||
594 | if ((MapP->ID != (u16) - 1) && ((int) MapP->ID < (int) 1 || (int) MapP->ID > MAX_RUP)) { | ||
595 | rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); | ||
596 | p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; | ||
597 | return -EINVAL; | ||
598 | } | ||
599 | if (MapP->RtaUniqueNum == 0) { | ||
600 | rio_dprintk(RIO_DEBUG_TABLE, "Rta Unique number zero!\n"); | ||
601 | p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO; | ||
602 | return -EINVAL; | ||
603 | } | ||
604 | if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { | ||
605 | rio_dprintk(RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n", (int) MapP->SysPort, PORTS_PER_RTA); | ||
606 | p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { | ||
610 | rio_dprintk(RIO_DEBUG_TABLE, "Port %d not valid!\n", (int) MapP->SysPort); | ||
611 | p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; | ||
612 | return -EINVAL; | ||
613 | } | ||
614 | |||
615 | /* | ||
616 | ** Copy the name across to the map entry. | ||
617 | */ | ||
618 | MapP->Name[MAX_NAME_LEN - 1] = '\0'; | ||
619 | sptr = MapP->Name; | ||
620 | while (*sptr) { | ||
621 | if (*sptr < ' ' || *sptr > '~') { | ||
622 | rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); | ||
623 | p->RIOError.Error = BAD_CHARACTER_IN_NAME; | ||
624 | return -EINVAL; | ||
625 | } | ||
626 | sptr++; | ||
627 | } | ||
628 | |||
629 | for (host = 0; host < p->RIONumHosts; host++) { | ||
630 | if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { | ||
631 | if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { | ||
632 | p->RIOError.Error = HOST_NOT_RUNNING; | ||
633 | return -ENXIO; | ||
634 | } | ||
635 | |||
636 | /* | ||
637 | ** Now we have a host we need to allocate an ID | ||
638 | ** if the entry does not already have one. | ||
639 | */ | ||
640 | if (MapP->ID == (u16) - 1) { | ||
641 | int nNewID; | ||
642 | |||
643 | rio_dprintk(RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n", MapP->Name); | ||
644 | /* | ||
645 | ** The idea here is to allow RTA's to be assigned | ||
646 | ** before they actually appear on the network. | ||
647 | ** This allows the addition of RTA's without having | ||
648 | ** to plug them in. | ||
649 | ** What we do is: | ||
650 | ** - Find a free ID and allocate it to the RTA. | ||
651 | ** - If this map entry is the second half of a | ||
652 | ** 16 port entry then find the other half and | ||
653 | ** make sure the 2 cross reference each other. | ||
654 | */ | ||
655 | if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0) { | ||
656 | p->RIOError.Error = COULDNT_FIND_ENTRY; | ||
657 | return -EBUSY; | ||
658 | } | ||
659 | MapP->ID = (u16) nNewID + 1; | ||
660 | rio_dprintk(RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID); | ||
661 | HostMapP = &p->RIOHosts[host].Mapping[nNewID]; | ||
662 | HostMapP->RtaUniqueNum = MapP->RtaUniqueNum; | ||
663 | HostMapP->HostUniqueNum = MapP->HostUniqueNum; | ||
664 | HostMapP->ID = MapP->ID; | ||
665 | for (link = 0; link < LINKS_PER_UNIT; link++) { | ||
666 | HostMapP->Topology[link].Unit = ROUTE_DISCONNECT; | ||
667 | HostMapP->Topology[link].Link = NO_LINK; | ||
668 | } | ||
669 | if (MapP->Flags & RTA16_SECOND_SLOT) { | ||
670 | int unit; | ||
671 | |||
672 | for (unit = 0; unit < MAX_RUP; unit++) | ||
673 | if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum == MapP->RtaUniqueNum) | ||
674 | break; | ||
675 | if (unit == MAX_RUP) { | ||
676 | p->RIOError.Error = COULDNT_FIND_ENTRY; | ||
677 | return -EBUSY; | ||
678 | } | ||
679 | HostMapP->Flags |= RTA16_SECOND_SLOT; | ||
680 | HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID; | ||
681 | p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID; | ||
682 | rio_dprintk(RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n", MapP->ID, p->RIOHosts[host].Mapping[unit].ID); | ||
683 | } | ||
684 | } | ||
685 | |||
686 | HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; | ||
687 | |||
688 | if (HostMapP->Flags & SLOT_IN_USE) { | ||
689 | rio_dprintk(RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID); | ||
690 | p->RIOError.Error = ID_ALREADY_IN_USE; | ||
691 | return -EBUSY; | ||
692 | } | ||
693 | |||
694 | /* | ||
695 | ** Assign the sys ports and the name, and mark the slot as | ||
696 | ** being in use. | ||
697 | */ | ||
698 | HostMapP->SysPort = MapP->SysPort; | ||
699 | if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) | ||
700 | memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); | ||
701 | HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED; | ||
702 | #ifdef NEED_TO_FIX | ||
703 | RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID - 1]); | ||
704 | #endif | ||
705 | if (MapP->Flags & RTA16_SECOND_SLOT) | ||
706 | HostMapP->Flags |= RTA16_SECOND_SLOT; | ||
707 | |||
708 | RIOReMapPorts(p, &p->RIOHosts[host], HostMapP); | ||
709 | /* | ||
710 | ** Adjust 2nd block of 8 phbs | ||
711 | */ | ||
712 | if (MapP->Flags & RTA16_SECOND_SLOT) | ||
713 | RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1); | ||
714 | |||
715 | if (HostMapP->SysPort != NO_PORT) { | ||
716 | if (HostMapP->SysPort < p->RIOFirstPortsBooted) | ||
717 | p->RIOFirstPortsBooted = HostMapP->SysPort; | ||
718 | if (HostMapP->SysPort > p->RIOLastPortsBooted) | ||
719 | p->RIOLastPortsBooted = HostMapP->SysPort; | ||
720 | } | ||
721 | if (MapP->Flags & RTA16_SECOND_SLOT) | ||
722 | rio_dprintk(RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n", p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name); | ||
723 | else | ||
724 | rio_dprintk(RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name); | ||
725 | return 0; | ||
726 | } | ||
727 | } | ||
728 | p->RIOError.Error = UNKNOWN_HOST_NUMBER; | ||
729 | rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); | ||
730 | return -ENXIO; | ||
731 | } | ||
732 | |||
733 | |||
734 | int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP) | ||
735 | { | ||
736 | struct Port *PortP; | ||
737 | unsigned int SubEnt; | ||
738 | unsigned int HostPort; | ||
739 | unsigned int SysPort; | ||
740 | u16 RtaType; | ||
741 | unsigned long flags; | ||
742 | |||
743 | rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int) HostMapP->SysPort, HostMapP->ID); | ||
744 | |||
745 | /* | ||
746 | ** We need to tell the UnixRups which sysport the rup corresponds to | ||
747 | */ | ||
748 | HostP->UnixRups[HostMapP->ID - 1].BaseSysPort = HostMapP->SysPort; | ||
749 | |||
750 | if (HostMapP->SysPort == NO_PORT) | ||
751 | return (0); | ||
752 | |||
753 | RtaType = GetUnitType(HostMapP->RtaUniqueNum); | ||
754 | rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n", (int) HostMapP->SysPort, (int) HostMapP->SysPort + PORTS_PER_RTA - 1); | ||
755 | |||
756 | /* | ||
757 | ** now map each of its eight ports | ||
758 | */ | ||
759 | for (SubEnt = 0; SubEnt < PORTS_PER_RTA; SubEnt++) { | ||
760 | rio_dprintk(RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", SubEnt, (int) HostMapP->SysPort); | ||
761 | SysPort = HostMapP->SysPort + SubEnt; /* portnumber within system */ | ||
762 | /* portnumber on host */ | ||
763 | |||
764 | HostPort = (HostMapP->ID - 1) * PORTS_PER_RTA + SubEnt; | ||
765 | |||
766 | rio_dprintk(RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp); | ||
767 | PortP = p->RIOPortp[SysPort]; | ||
768 | rio_dprintk(RIO_DEBUG_TABLE, "Map port\n"); | ||
769 | |||
770 | /* | ||
771 | ** Point at all the real neat data structures | ||
772 | */ | ||
773 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
774 | PortP->HostP = HostP; | ||
775 | PortP->Caddr = HostP->Caddr; | ||
776 | |||
777 | /* | ||
778 | ** The PhbP cannot be filled in yet | ||
779 | ** unless the host has been booted | ||
780 | */ | ||
781 | if ((HostP->Flags & RUN_STATE) == RC_RUNNING) { | ||
782 | struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort]; | ||
783 | PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add)); | ||
784 | PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start)); | ||
785 | PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end)); | ||
786 | PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove)); | ||
787 | PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start)); | ||
788 | PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end)); | ||
789 | } else | ||
790 | PortP->PhbP = NULL; | ||
791 | |||
792 | /* | ||
793 | ** port related flags | ||
794 | */ | ||
795 | PortP->HostPort = HostPort; | ||
796 | /* | ||
797 | ** For each part of a 16 port RTA, RupNum is ID - 1. | ||
798 | */ | ||
799 | PortP->RupNum = HostMapP->ID - 1; | ||
800 | if (HostMapP->Flags & RTA16_SECOND_SLOT) { | ||
801 | PortP->ID2 = HostMapP->ID2 - 1; | ||
802 | PortP->SecondBlock = 1; | ||
803 | } else { | ||
804 | PortP->ID2 = 0; | ||
805 | PortP->SecondBlock = 0; | ||
806 | } | ||
807 | PortP->RtaUniqueNum = HostMapP->RtaUniqueNum; | ||
808 | |||
809 | /* | ||
810 | ** If the port was already mapped then thats all we need to do. | ||
811 | */ | ||
812 | if (PortP->Mapped) { | ||
813 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
814 | continue; | ||
815 | } else | ||
816 | HostMapP->Flags &= ~RTA_NEWBOOT; | ||
817 | |||
818 | PortP->State = 0; | ||
819 | PortP->Config = 0; | ||
820 | /* | ||
821 | ** Check out the module type - if it is special (read only etc.) | ||
822 | ** then we need to set flags in the PortP->Config. | ||
823 | ** Note: For 16 port RTA, all ports are of the same type. | ||
824 | */ | ||
825 | if (RtaType == TYPE_RTA16) { | ||
826 | PortP->Config |= p->RIOModuleTypes[HostP->UnixRups[HostMapP->ID - 1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE]; | ||
827 | } else { | ||
828 | if (SubEnt < PORTS_PER_MODULE) | ||
829 | PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; | ||
830 | else | ||
831 | PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; | ||
832 | } | ||
833 | |||
834 | /* | ||
835 | ** more port related flags | ||
836 | */ | ||
837 | PortP->PortState = 0; | ||
838 | PortP->ModemLines = 0; | ||
839 | PortP->ModemState = 0; | ||
840 | PortP->CookMode = COOK_WELL; | ||
841 | PortP->ParamSem = 0; | ||
842 | PortP->FlushCmdBodge = 0; | ||
843 | PortP->WflushFlag = 0; | ||
844 | PortP->MagicFlags = 0; | ||
845 | PortP->Lock = 0; | ||
846 | PortP->Store = 0; | ||
847 | PortP->FirstOpen = 1; | ||
848 | |||
849 | /* | ||
850 | ** Buffers 'n things | ||
851 | */ | ||
852 | PortP->RxDataStart = 0; | ||
853 | PortP->Cor2Copy = 0; | ||
854 | PortP->Name = &HostMapP->Name[0]; | ||
855 | PortP->statsGather = 0; | ||
856 | PortP->txchars = 0; | ||
857 | PortP->rxchars = 0; | ||
858 | PortP->opens = 0; | ||
859 | PortP->closes = 0; | ||
860 | PortP->ioctls = 0; | ||
861 | if (PortP->TxRingBuffer) | ||
862 | memset(PortP->TxRingBuffer, 0, p->RIOBufferSize); | ||
863 | else if (p->RIOBufferSize) { | ||
864 | PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL); | ||
865 | } | ||
866 | PortP->TxBufferOut = 0; | ||
867 | PortP->TxBufferIn = 0; | ||
868 | PortP->Debug = 0; | ||
869 | /* | ||
870 | ** LastRxTgl stores the state of the rx toggle bit for this | ||
871 | ** port, to be compared with the state of the next pkt received. | ||
872 | ** If the same, we have received the same rx pkt from the RTA | ||
873 | ** twice. Initialise to a value not equal to PHB_RX_TGL or 0. | ||
874 | */ | ||
875 | PortP->LastRxTgl = ~(u8) PHB_RX_TGL; | ||
876 | |||
877 | /* | ||
878 | ** and mark the port as usable | ||
879 | */ | ||
880 | PortP->Mapped = 1; | ||
881 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
882 | } | ||
883 | if (HostMapP->SysPort < p->RIOFirstPortsMapped) | ||
884 | p->RIOFirstPortsMapped = HostMapP->SysPort; | ||
885 | if (HostMapP->SysPort > p->RIOLastPortsMapped) | ||
886 | p->RIOLastPortsMapped = HostMapP->SysPort; | ||
887 | |||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | int RIOChangeName(struct rio_info *p, struct Map *MapP) | ||
892 | { | ||
893 | int host; | ||
894 | struct Map *HostMapP; | ||
895 | char *sptr; | ||
896 | |||
897 | rio_dprintk(RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); | ||
898 | |||
899 | if (MapP->ID > MAX_RUP) { | ||
900 | rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); | ||
901 | p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; | ||
902 | return -EINVAL; | ||
903 | } | ||
904 | |||
905 | MapP->Name[MAX_NAME_LEN - 1] = '\0'; | ||
906 | sptr = MapP->Name; | ||
907 | |||
908 | while (*sptr) { | ||
909 | if (*sptr < ' ' || *sptr > '~') { | ||
910 | rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); | ||
911 | p->RIOError.Error = BAD_CHARACTER_IN_NAME; | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | sptr++; | ||
915 | } | ||
916 | |||
917 | for (host = 0; host < p->RIONumHosts; host++) { | ||
918 | if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { | ||
919 | if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { | ||
920 | p->RIOError.Error = HOST_NOT_RUNNING; | ||
921 | return -ENXIO; | ||
922 | } | ||
923 | if (MapP->ID == 0) { | ||
924 | memcpy(p->RIOHosts[host].Name, MapP->Name, MAX_NAME_LEN); | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; | ||
929 | |||
930 | if (HostMapP->RtaUniqueNum != MapP->RtaUniqueNum) { | ||
931 | p->RIOError.Error = RTA_NUMBER_WRONG; | ||
932 | return -ENXIO; | ||
933 | } | ||
934 | memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); | ||
935 | return 0; | ||
936 | } | ||
937 | } | ||
938 | p->RIOError.Error = UNKNOWN_HOST_NUMBER; | ||
939 | rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); | ||
940 | return -ENXIO; | ||
941 | } | ||
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c deleted file mode 100644 index 8a90393faf3c..000000000000 --- a/drivers/char/rio/riotty.c +++ /dev/null | |||
@@ -1,654 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : riotty.c | ||
24 | ** SID : 1.3 | ||
25 | ** Last Modified : 11/6/98 10:33:47 | ||
26 | ** Retrieved : 11/6/98 10:33:50 | ||
27 | ** | ||
28 | ** ident @(#)riotty.c 1.3 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #define __EXPLICIT_DEF_H__ | ||
34 | |||
35 | #include <linux/module.h> | ||
36 | #include <linux/sched.h> | ||
37 | #include <linux/errno.h> | ||
38 | #include <linux/tty.h> | ||
39 | #include <linux/string.h> | ||
40 | #include <asm/io.h> | ||
41 | #include <asm/system.h> | ||
42 | #include <asm/string.h> | ||
43 | #include <asm/uaccess.h> | ||
44 | |||
45 | #include <linux/termios.h> | ||
46 | |||
47 | #include <linux/serial.h> | ||
48 | |||
49 | #include <linux/generic_serial.h> | ||
50 | |||
51 | |||
52 | #include "linux_compat.h" | ||
53 | #include "rio_linux.h" | ||
54 | #include "pkt.h" | ||
55 | #include "daemon.h" | ||
56 | #include "rio.h" | ||
57 | #include "riospace.h" | ||
58 | #include "cmdpkt.h" | ||
59 | #include "map.h" | ||
60 | #include "rup.h" | ||
61 | #include "port.h" | ||
62 | #include "riodrvr.h" | ||
63 | #include "rioinfo.h" | ||
64 | #include "func.h" | ||
65 | #include "errors.h" | ||
66 | #include "pci.h" | ||
67 | |||
68 | #include "parmmap.h" | ||
69 | #include "unixrup.h" | ||
70 | #include "board.h" | ||
71 | #include "host.h" | ||
72 | #include "phb.h" | ||
73 | #include "link.h" | ||
74 | #include "cmdblk.h" | ||
75 | #include "route.h" | ||
76 | #include "cirrus.h" | ||
77 | #include "rioioctl.h" | ||
78 | #include "param.h" | ||
79 | |||
80 | static void RIOClearUp(struct Port *PortP); | ||
81 | |||
82 | /* Below belongs in func.h */ | ||
83 | int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); | ||
84 | |||
85 | |||
86 | extern struct rio_info *p; | ||
87 | |||
88 | |||
89 | int riotopen(struct tty_struct *tty, struct file *filp) | ||
90 | { | ||
91 | unsigned int SysPort; | ||
92 | int repeat_this = 250; | ||
93 | struct Port *PortP; /* pointer to the port structure */ | ||
94 | unsigned long flags; | ||
95 | int retval = 0; | ||
96 | |||
97 | func_enter(); | ||
98 | |||
99 | /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close | ||
100 | is going to oops. | ||
101 | */ | ||
102 | tty->driver_data = NULL; | ||
103 | |||
104 | SysPort = rio_minor(tty); | ||
105 | |||
106 | if (p->RIOFailed) { | ||
107 | rio_dprintk(RIO_DEBUG_TTY, "System initialisation failed\n"); | ||
108 | func_exit(); | ||
109 | return -ENXIO; | ||
110 | } | ||
111 | |||
112 | rio_dprintk(RIO_DEBUG_TTY, "port open SysPort %d (mapped:%d)\n", SysPort, p->RIOPortp[SysPort]->Mapped); | ||
113 | |||
114 | /* | ||
115 | ** Validate that we have received a legitimate request. | ||
116 | ** Currently, just check that we are opening a port on | ||
117 | ** a host card that actually exists, and that the port | ||
118 | ** has been mapped onto a host. | ||
119 | */ | ||
120 | if (SysPort >= RIO_PORTS) { /* out of range ? */ | ||
121 | rio_dprintk(RIO_DEBUG_TTY, "Illegal port number %d\n", SysPort); | ||
122 | func_exit(); | ||
123 | return -ENXIO; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | ** Grab pointer to the port stucture | ||
128 | */ | ||
129 | PortP = p->RIOPortp[SysPort]; /* Get control struc */ | ||
130 | rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP); | ||
131 | if (!PortP->Mapped) { /* we aren't mapped yet! */ | ||
132 | /* | ||
133 | ** The system doesn't know which RTA this port | ||
134 | ** corresponds to. | ||
135 | */ | ||
136 | rio_dprintk(RIO_DEBUG_TTY, "port not mapped into system\n"); | ||
137 | func_exit(); | ||
138 | return -ENXIO; | ||
139 | } | ||
140 | |||
141 | tty->driver_data = PortP; | ||
142 | |||
143 | PortP->gs.port.tty = tty; | ||
144 | PortP->gs.port.count++; | ||
145 | |||
146 | rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt); | ||
147 | |||
148 | retval = gs_init_port(&PortP->gs); | ||
149 | if (retval) { | ||
150 | PortP->gs.port.count--; | ||
151 | return -ENXIO; | ||
152 | } | ||
153 | /* | ||
154 | ** If the host hasn't been booted yet, then | ||
155 | ** fail | ||
156 | */ | ||
157 | if ((PortP->HostP->Flags & RUN_STATE) != RC_RUNNING) { | ||
158 | rio_dprintk(RIO_DEBUG_TTY, "Host not running\n"); | ||
159 | func_exit(); | ||
160 | return -ENXIO; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | ** If the RTA has not booted yet and the user has choosen to block | ||
165 | ** until the RTA is present then we must spin here waiting for | ||
166 | ** the RTA to boot. | ||
167 | */ | ||
168 | /* I find the above code a bit hairy. I find the below code | ||
169 | easier to read and shorter. Now, if it works too that would | ||
170 | be great... -- REW | ||
171 | */ | ||
172 | rio_dprintk(RIO_DEBUG_TTY, "Checking if RTA has booted... \n"); | ||
173 | while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) { | ||
174 | if (!PortP->WaitUntilBooted) { | ||
175 | rio_dprintk(RIO_DEBUG_TTY, "RTA never booted\n"); | ||
176 | func_exit(); | ||
177 | return -ENXIO; | ||
178 | } | ||
179 | |||
180 | /* Under Linux you'd normally use a wait instead of this | ||
181 | busy-waiting. I'll stick with the old implementation for | ||
182 | now. --REW | ||
183 | */ | ||
184 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { | ||
185 | rio_dprintk(RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n"); | ||
186 | func_exit(); | ||
187 | return -EINTR; | ||
188 | } | ||
189 | if (repeat_this-- <= 0) { | ||
190 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n"); | ||
191 | func_exit(); | ||
192 | return -EIO; | ||
193 | } | ||
194 | } | ||
195 | rio_dprintk(RIO_DEBUG_TTY, "RTA has been booted\n"); | ||
196 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
197 | if (p->RIOHalted) { | ||
198 | goto bombout; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | ** If the port is in the final throws of being closed, | ||
203 | ** we should wait here (politely), waiting | ||
204 | ** for it to finish, so that it doesn't close us! | ||
205 | */ | ||
206 | while ((PortP->State & RIO_CLOSING) && !p->RIOHalted) { | ||
207 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n"); | ||
208 | if (repeat_this-- <= 0) { | ||
209 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); | ||
210 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); | ||
211 | retval = -EINTR; | ||
212 | goto bombout; | ||
213 | } | ||
214 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
215 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { | ||
216 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
217 | retval = -EINTR; | ||
218 | goto bombout; | ||
219 | } | ||
220 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
221 | } | ||
222 | |||
223 | if (!PortP->Mapped) { | ||
224 | rio_dprintk(RIO_DEBUG_TTY, "Port unmapped while closing!\n"); | ||
225 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
226 | retval = -ENXIO; | ||
227 | func_exit(); | ||
228 | return retval; | ||
229 | } | ||
230 | |||
231 | if (p->RIOHalted) { | ||
232 | goto bombout; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | ** 15.10.1998 ARG - ESIL 0761 part fix | ||
237 | ** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure, | ||
238 | ** we need to make sure that the flags are clear when the port is opened. | ||
239 | */ | ||
240 | /* Uh? Suppose I turn these on and then another process opens | ||
241 | the port again? The flags get cleared! Not good. -- REW */ | ||
242 | if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { | ||
243 | PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); | ||
244 | } | ||
245 | |||
246 | if (!(PortP->firstOpen)) { /* First time ? */ | ||
247 | rio_dprintk(RIO_DEBUG_TTY, "First open for this port\n"); | ||
248 | |||
249 | |||
250 | PortP->firstOpen++; | ||
251 | PortP->CookMode = 0; /* XXX RIOCookMode(tp); */ | ||
252 | PortP->InUse = NOT_INUSE; | ||
253 | |||
254 | /* Tentative fix for bug PR27. Didn't work. */ | ||
255 | /* PortP->gs.xmit_cnt = 0; */ | ||
256 | |||
257 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
258 | |||
259 | /* Someone explain to me why this delay/config is | ||
260 | here. If I read the docs correctly the "open" | ||
261 | command piggybacks the parameters immediately. | ||
262 | -- REW */ | ||
263 | RIOParam(PortP, RIOC_OPEN, 1, OK_TO_SLEEP); /* Open the port */ | ||
264 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
265 | |||
266 | /* | ||
267 | ** wait for the port to be not closed. | ||
268 | */ | ||
269 | while (!(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted) { | ||
270 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n", PortP->PortState); | ||
271 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
272 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { | ||
273 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n"); | ||
274 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); | ||
275 | func_exit(); | ||
276 | return -EINTR; | ||
277 | } | ||
278 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
279 | } | ||
280 | |||
281 | if (p->RIOHalted) { | ||
282 | retval = -EIO; | ||
283 | bombout: | ||
284 | /* RIOClearUp( PortP ); */ | ||
285 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
286 | return retval; | ||
287 | } | ||
288 | rio_dprintk(RIO_DEBUG_TTY, "PORT_ISOPEN found\n"); | ||
289 | } | ||
290 | rio_dprintk(RIO_DEBUG_TTY, "Modem - test for carrier\n"); | ||
291 | /* | ||
292 | ** ACTION | ||
293 | ** insert test for carrier here. -- ??? | ||
294 | ** I already see that test here. What's the deal? -- REW | ||
295 | */ | ||
296 | if ((PortP->gs.port.tty->termios->c_cflag & CLOCAL) || | ||
297 | (PortP->ModemState & RIOC_MSVR1_CD)) { | ||
298 | rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); | ||
299 | /* | ||
300 | tp->tm.c_state |= CARR_ON; | ||
301 | wakeup((caddr_t) &tp->tm.c_canq); | ||
302 | */ | ||
303 | PortP->State |= RIO_CARR_ON; | ||
304 | wake_up_interruptible(&PortP->gs.port.open_wait); | ||
305 | } else { /* no carrier - wait for DCD */ | ||
306 | /* | ||
307 | while (!(PortP->gs.port.tty->termios->c_state & CARR_ON) && | ||
308 | !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) | ||
309 | */ | ||
310 | while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) { | ||
311 | rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort); | ||
312 | /* | ||
313 | PortP->gs.port.tty->termios->c_state |= WOPEN; | ||
314 | */ | ||
315 | PortP->State |= RIO_WOPEN; | ||
316 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
317 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { | ||
318 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
319 | /* | ||
320 | ** ACTION: verify that this is a good thing | ||
321 | ** to do here. -- ??? | ||
322 | ** I think it's OK. -- REW | ||
323 | */ | ||
324 | rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort); | ||
325 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); | ||
326 | /* | ||
327 | tp->tm.c_state &= ~WOPEN; | ||
328 | */ | ||
329 | PortP->State &= ~RIO_WOPEN; | ||
330 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
331 | func_exit(); | ||
332 | return -EINTR; | ||
333 | } | ||
334 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
335 | } | ||
336 | PortP->State &= ~RIO_WOPEN; | ||
337 | } | ||
338 | if (p->RIOHalted) | ||
339 | goto bombout; | ||
340 | rio_dprintk(RIO_DEBUG_TTY, "Setting RIO_MOPEN\n"); | ||
341 | PortP->State |= RIO_MOPEN; | ||
342 | |||
343 | if (p->RIOHalted) | ||
344 | goto bombout; | ||
345 | |||
346 | rio_dprintk(RIO_DEBUG_TTY, "high level open done\n"); | ||
347 | |||
348 | /* | ||
349 | ** Count opens for port statistics reporting | ||
350 | */ | ||
351 | if (PortP->statsGather) | ||
352 | PortP->opens++; | ||
353 | |||
354 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
355 | rio_dprintk(RIO_DEBUG_TTY, "Returning from open\n"); | ||
356 | func_exit(); | ||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | ** RIOClose the port. | ||
362 | ** The operating system thinks that this is last close for the device. | ||
363 | ** As there are two interfaces to the port (Modem and tty), we need to | ||
364 | ** check that both are closed before we close the device. | ||
365 | */ | ||
366 | int riotclose(void *ptr) | ||
367 | { | ||
368 | struct Port *PortP = ptr; /* pointer to the port structure */ | ||
369 | int deleted = 0; | ||
370 | int try = -1; /* Disable the timeouts by setting them to -1 */ | ||
371 | int repeat_this = -1; /* Congrats to those having 15 years of | ||
372 | uptime! (You get to break the driver.) */ | ||
373 | unsigned long end_time; | ||
374 | struct tty_struct *tty; | ||
375 | unsigned long flags; | ||
376 | int rv = 0; | ||
377 | |||
378 | rio_dprintk(RIO_DEBUG_TTY, "port close SysPort %d\n", PortP->PortNum); | ||
379 | |||
380 | /* PortP = p->RIOPortp[SysPort]; */ | ||
381 | rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP); | ||
382 | /* tp = PortP->TtyP; *//* Get tty */ | ||
383 | tty = PortP->gs.port.tty; | ||
384 | rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty); | ||
385 | |||
386 | if (PortP->gs.closing_wait) | ||
387 | end_time = jiffies + PortP->gs.closing_wait; | ||
388 | else | ||
389 | end_time = jiffies + MAX_SCHEDULE_TIMEOUT; | ||
390 | |||
391 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
392 | |||
393 | /* | ||
394 | ** Setting this flag will make any process trying to open | ||
395 | ** this port block until we are complete closing it. | ||
396 | */ | ||
397 | PortP->State |= RIO_CLOSING; | ||
398 | |||
399 | if ((PortP->State & RIO_DELETED)) { | ||
400 | rio_dprintk(RIO_DEBUG_TTY, "Close on deleted RTA\n"); | ||
401 | deleted = 1; | ||
402 | } | ||
403 | |||
404 | if (p->RIOHalted) { | ||
405 | RIOClearUp(PortP); | ||
406 | rv = -EIO; | ||
407 | goto close_end; | ||
408 | } | ||
409 | |||
410 | rio_dprintk(RIO_DEBUG_TTY, "Clear bits\n"); | ||
411 | /* | ||
412 | ** clear the open bits for this device | ||
413 | */ | ||
414 | PortP->State &= ~RIO_MOPEN; | ||
415 | PortP->State &= ~RIO_CARR_ON; | ||
416 | PortP->ModemState &= ~RIOC_MSVR1_CD; | ||
417 | /* | ||
418 | ** If the device was open as both a Modem and a tty line | ||
419 | ** then we need to wimp out here, as the port has not really | ||
420 | ** been finally closed (gee, whizz!) The test here uses the | ||
421 | ** bit for the OTHER mode of operation, to see if THAT is | ||
422 | ** still active! | ||
423 | */ | ||
424 | if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { | ||
425 | /* | ||
426 | ** The port is still open for the other task - | ||
427 | ** return, pretending that we are still active. | ||
428 | */ | ||
429 | rio_dprintk(RIO_DEBUG_TTY, "Channel %d still open !\n", PortP->PortNum); | ||
430 | PortP->State &= ~RIO_CLOSING; | ||
431 | if (PortP->firstOpen) | ||
432 | PortP->firstOpen--; | ||
433 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
434 | return -EIO; | ||
435 | } | ||
436 | |||
437 | rio_dprintk(RIO_DEBUG_TTY, "Closing down - everything must go!\n"); | ||
438 | |||
439 | PortP->State &= ~RIO_DYNOROD; | ||
440 | |||
441 | /* | ||
442 | ** This is where we wait for the port | ||
443 | ** to drain down before closing. Bye-bye.... | ||
444 | ** (We never meant to do this) | ||
445 | */ | ||
446 | rio_dprintk(RIO_DEBUG_TTY, "Timeout 1 starts\n"); | ||
447 | |||
448 | if (!deleted) | ||
449 | while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted && (PortP->TxBufferIn != PortP->TxBufferOut)) { | ||
450 | if (repeat_this-- <= 0) { | ||
451 | rv = -EINTR; | ||
452 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); | ||
453 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); | ||
454 | goto close_end; | ||
455 | } | ||
456 | rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); | ||
457 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
458 | if (RIODelay_ni(PortP, HUNDRED_MS * 10) == RIO_FAIL) { | ||
459 | rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); | ||
460 | rv = -EINTR; | ||
461 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
462 | goto close_end; | ||
463 | } | ||
464 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
465 | } | ||
466 | |||
467 | PortP->TxBufferIn = PortP->TxBufferOut = 0; | ||
468 | repeat_this = 0xff; | ||
469 | |||
470 | PortP->InUse = 0; | ||
471 | if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { | ||
472 | /* | ||
473 | ** The port has been re-opened for the other task - | ||
474 | ** return, pretending that we are still active. | ||
475 | */ | ||
476 | rio_dprintk(RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum); | ||
477 | PortP->State &= ~RIO_CLOSING; | ||
478 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
479 | if (PortP->firstOpen) | ||
480 | PortP->firstOpen--; | ||
481 | return -EIO; | ||
482 | } | ||
483 | |||
484 | if (p->RIOHalted) { | ||
485 | RIOClearUp(PortP); | ||
486 | goto close_end; | ||
487 | } | ||
488 | |||
489 | /* Can't call RIOShortCommand with the port locked. */ | ||
490 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
491 | |||
492 | if (RIOShortCommand(p, PortP, RIOC_CLOSE, 1, 0) == RIO_FAIL) { | ||
493 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); | ||
494 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
495 | goto close_end; | ||
496 | } | ||
497 | |||
498 | if (!deleted) | ||
499 | while (try && (PortP->PortState & PORT_ISOPEN)) { | ||
500 | try--; | ||
501 | if (time_after(jiffies, end_time)) { | ||
502 | rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n"); | ||
503 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); | ||
504 | break; | ||
505 | } | ||
506 | rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN); | ||
507 | |||
508 | if (p->RIOHalted) { | ||
509 | RIOClearUp(PortP); | ||
510 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
511 | goto close_end; | ||
512 | } | ||
513 | if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { | ||
514 | rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); | ||
515 | RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); | ||
516 | break; | ||
517 | } | ||
518 | } | ||
519 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
520 | rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try); | ||
521 | |||
522 | /* RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); */ | ||
523 | |||
524 | /* | ||
525 | ** 15.10.1998 ARG - ESIL 0761 part fix | ||
526 | ** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened. | ||
527 | */ | ||
528 | PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); | ||
529 | |||
530 | /* | ||
531 | ** Count opens for port statistics reporting | ||
532 | */ | ||
533 | if (PortP->statsGather) | ||
534 | PortP->closes++; | ||
535 | |||
536 | close_end: | ||
537 | /* XXX: Why would a "DELETED" flag be reset here? I'd have | ||
538 | thought that a "deleted" flag means that the port was | ||
539 | permanently gone, but here we can make it reappear by it | ||
540 | being in close during the "deletion". | ||
541 | */ | ||
542 | PortP->State &= ~(RIO_CLOSING | RIO_DELETED); | ||
543 | if (PortP->firstOpen) | ||
544 | PortP->firstOpen--; | ||
545 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
546 | rio_dprintk(RIO_DEBUG_TTY, "Return from close\n"); | ||
547 | return rv; | ||
548 | } | ||
549 | |||
550 | |||
551 | |||
552 | static void RIOClearUp(struct Port *PortP) | ||
553 | { | ||
554 | rio_dprintk(RIO_DEBUG_TTY, "RIOHalted set\n"); | ||
555 | PortP->Config = 0; /* Direct semaphore */ | ||
556 | PortP->PortState = 0; | ||
557 | PortP->firstOpen = 0; | ||
558 | PortP->FlushCmdBodge = 0; | ||
559 | PortP->ModemState = PortP->CookMode = 0; | ||
560 | PortP->Mapped = 0; | ||
561 | PortP->WflushFlag = 0; | ||
562 | PortP->MagicFlags = 0; | ||
563 | PortP->RxDataStart = 0; | ||
564 | PortP->TxBufferIn = 0; | ||
565 | PortP->TxBufferOut = 0; | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | ** Put a command onto a port. | ||
570 | ** The PortPointer, command, length and arg are passed. | ||
571 | ** The len is the length *inclusive* of the command byte, | ||
572 | ** and so for a command that takes no data, len==1. | ||
573 | ** The arg is a single byte, and is only used if len==2. | ||
574 | ** Other values of len aren't allowed, and will cause | ||
575 | ** a panic. | ||
576 | */ | ||
577 | int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg) | ||
578 | { | ||
579 | struct PKT __iomem *PacketP; | ||
580 | int retries = 20; /* at 10 per second -> 2 seconds */ | ||
581 | unsigned long flags; | ||
582 | |||
583 | rio_dprintk(RIO_DEBUG_TTY, "entering shortcommand.\n"); | ||
584 | |||
585 | if (PortP->State & RIO_DELETED) { | ||
586 | rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); | ||
587 | return RIO_FAIL; | ||
588 | } | ||
589 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
590 | |||
591 | /* | ||
592 | ** If the port is in use for pre-emptive command, then wait for it to | ||
593 | ** be free again. | ||
594 | */ | ||
595 | while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted) { | ||
596 | rio_dprintk(RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", retries); | ||
597 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
598 | if (retries-- <= 0) { | ||
599 | return RIO_FAIL; | ||
600 | } | ||
601 | if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { | ||
602 | return RIO_FAIL; | ||
603 | } | ||
604 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
605 | } | ||
606 | if (PortP->State & RIO_DELETED) { | ||
607 | rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); | ||
608 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
609 | return RIO_FAIL; | ||
610 | } | ||
611 | |||
612 | while (!can_add_transmit(&PacketP, PortP) && !p->RIOHalted) { | ||
613 | rio_dprintk(RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries); | ||
614 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
615 | if (retries-- <= 0) { | ||
616 | rio_dprintk(RIO_DEBUG_TTY, "out of tries. Failing\n"); | ||
617 | return RIO_FAIL; | ||
618 | } | ||
619 | if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { | ||
620 | return RIO_FAIL; | ||
621 | } | ||
622 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
623 | } | ||
624 | |||
625 | if (p->RIOHalted) { | ||
626 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
627 | return RIO_FAIL; | ||
628 | } | ||
629 | |||
630 | /* | ||
631 | ** set the command byte and the argument byte | ||
632 | */ | ||
633 | writeb(command, &PacketP->data[0]); | ||
634 | |||
635 | if (len == 2) | ||
636 | writeb(arg, &PacketP->data[1]); | ||
637 | |||
638 | /* | ||
639 | ** set the length of the packet and set the command bit. | ||
640 | */ | ||
641 | writeb(PKT_CMD_BIT | len, &PacketP->len); | ||
642 | |||
643 | add_transmit(PortP); | ||
644 | /* | ||
645 | ** Count characters transmitted for port statistics reporting | ||
646 | */ | ||
647 | if (PortP->statsGather) | ||
648 | PortP->txchars += len; | ||
649 | |||
650 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
651 | return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL; | ||
652 | } | ||
653 | |||
654 | |||
diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h deleted file mode 100644 index 46e963771c30..000000000000 --- a/drivers/char/rio/route.h +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* R O U T E H E A D E R | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Ian Nandhra / Jeremy Rolls | ||
8 | Date : | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | |||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _route_h | ||
38 | #define _route_h | ||
39 | |||
40 | #define MAX_LINKS 4 | ||
41 | #define MAX_NODES 17 /* Maximum nodes in a subnet */ | ||
42 | #define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for | ||
43 | 1 bit per node */ | ||
44 | #define ROUTE_DATA_SIZE (NODE_BYTES + 2) /* Number of bytes for complete | ||
45 | info about cost etc. */ | ||
46 | #define ROUTES_PER_PACKET ((PKT_MAX_DATA_LEN -2)/ ROUTE_DATA_SIZE) | ||
47 | /* Number of nodes we can squeeze | ||
48 | into one packet */ | ||
49 | #define MAX_TOPOLOGY_PACKETS (MAX_NODES / ROUTES_PER_PACKET + 1) | ||
50 | /************************************************ | ||
51 | * Define the types of command for the ROUTE RUP. | ||
52 | ************************************************/ | ||
53 | #define ROUTE_REQUEST 0 /* Request an ID */ | ||
54 | #define ROUTE_FOAD 1 /* Kill the RTA */ | ||
55 | #define ROUTE_ALREADY 2 /* ID given already */ | ||
56 | #define ROUTE_USED 3 /* All ID's used */ | ||
57 | #define ROUTE_ALLOCATE 4 /* Here it is */ | ||
58 | #define ROUTE_REQ_TOP 5 /* I bet you didn't expect.... | ||
59 | the Topological Inquisition */ | ||
60 | #define ROUTE_TOPOLOGY 6 /* Topology request answered FD */ | ||
61 | /******************************************************************* | ||
62 | * Define the Route Map Structure | ||
63 | * | ||
64 | * The route map gives a pointer to a Link Structure to use. | ||
65 | * This allows Disconnected Links to be checked quickly | ||
66 | ******************************************************************/ | ||
67 | typedef struct COST_ROUTE COST_ROUTE; | ||
68 | struct COST_ROUTE { | ||
69 | unsigned char cost; /* Cost down this link */ | ||
70 | unsigned char route[NODE_BYTES]; /* Nodes through this route */ | ||
71 | }; | ||
72 | |||
73 | typedef struct ROUTE_STR ROUTE_STR; | ||
74 | struct ROUTE_STR { | ||
75 | COST_ROUTE cost_route[MAX_LINKS]; | ||
76 | /* cost / route for this link */ | ||
77 | ushort favoured; /* favoured link */ | ||
78 | }; | ||
79 | |||
80 | |||
81 | #define NO_LINK (short) 5 /* Link unattached */ | ||
82 | #define ROUTE_NO_ID (short) 100 /* No Id */ | ||
83 | #define ROUTE_DISCONNECT (ushort) 0xff /* Not connected */ | ||
84 | #define ROUTE_INTERCONNECT (ushort) 0x40 /* Sub-net interconnect */ | ||
85 | |||
86 | |||
87 | #define SYNC_RUP (ushort) 255 | ||
88 | #define COMMAND_RUP (ushort) 254 | ||
89 | #define ERROR_RUP (ushort) 253 | ||
90 | #define POLL_RUP (ushort) 252 | ||
91 | #define BOOT_RUP (ushort) 251 | ||
92 | #define ROUTE_RUP (ushort) 250 | ||
93 | #define STATUS_RUP (ushort) 249 | ||
94 | #define POWER_RUP (ushort) 248 | ||
95 | |||
96 | #define HIGHEST_RUP (ushort) 255 /* Set to Top one */ | ||
97 | #define LOWEST_RUP (ushort) 248 /* Set to bottom one */ | ||
98 | |||
99 | #endif | ||
100 | |||
101 | /*********** end of file ***********/ | ||
diff --git a/drivers/char/rio/rup.h b/drivers/char/rio/rup.h deleted file mode 100644 index 4ae90cb207a9..000000000000 --- a/drivers/char/rio/rup.h +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | ******* ******* | ||
3 | ******* R U P S T R U C T U R E | ||
4 | ******* ******* | ||
5 | **************************************************************************** | ||
6 | |||
7 | Author : Ian Nandhra | ||
8 | Date : | ||
9 | |||
10 | * | ||
11 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | |||
27 | Version : 0.01 | ||
28 | |||
29 | |||
30 | Mods | ||
31 | ---------------------------------------------------------------------------- | ||
32 | Date By Description | ||
33 | ---------------------------------------------------------------------------- | ||
34 | |||
35 | ***************************************************************************/ | ||
36 | |||
37 | #ifndef _rup_h | ||
38 | #define _rup_h 1 | ||
39 | |||
40 | #define MAX_RUP ((short) 16) | ||
41 | #define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */ | ||
42 | |||
43 | /************************************************* | ||
44 | * Define all the packet request stuff | ||
45 | ************************************************/ | ||
46 | #define TX_RUP_INACTIVE 0 /* Nothing to transmit */ | ||
47 | #define TX_PACKET_READY 1 /* Transmit packet ready */ | ||
48 | #define TX_LOCK_RUP 2 /* Transmit side locked */ | ||
49 | |||
50 | #define RX_RUP_INACTIVE 0 /* Nothing received */ | ||
51 | #define RX_PACKET_READY 1 /* Packet received */ | ||
52 | |||
53 | #define RUP_NO_OWNER 0xff /* RUP not owned by any process */ | ||
54 | |||
55 | struct RUP { | ||
56 | u16 txpkt; /* Outgoing packet */ | ||
57 | u16 rxpkt; /* Incoming packet */ | ||
58 | u16 link; /* Which link to send down? */ | ||
59 | u8 rup_dest_unit[2]; /* Destination unit */ | ||
60 | u16 handshake; /* For handshaking */ | ||
61 | u16 timeout; /* Timeout */ | ||
62 | u16 status; /* Status */ | ||
63 | u16 txcontrol; /* Transmit control */ | ||
64 | u16 rxcontrol; /* Receive control */ | ||
65 | }; | ||
66 | |||
67 | #endif | ||
68 | |||
69 | /*********** end of file ***********/ | ||
diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h deleted file mode 100644 index 7abf0cba0f2c..000000000000 --- a/drivers/char/rio/unixrup.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | ** ----------------------------------------------------------------------------- | ||
3 | ** | ||
4 | ** Perle Specialix driver for Linux | ||
5 | ** Ported from existing RIO Driver for SCO sources. | ||
6 | * | ||
7 | * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | ** | ||
23 | ** Module : unixrup.h | ||
24 | ** SID : 1.2 | ||
25 | ** Last Modified : 11/6/98 11:34:20 | ||
26 | ** Retrieved : 11/6/98 11:34:22 | ||
27 | ** | ||
28 | ** ident @(#)unixrup.h 1.2 | ||
29 | ** | ||
30 | ** ----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #ifndef __rio_unixrup_h__ | ||
34 | #define __rio_unixrup_h__ | ||
35 | |||
36 | /* | ||
37 | ** UnixRup data structure. This contains pointers to actual RUPs on the | ||
38 | ** host card, and all the command/boot control stuff. | ||
39 | */ | ||
40 | struct UnixRup { | ||
41 | struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */ | ||
42 | struct CmdBlk *CmdPendingP; /* The command currently being sent */ | ||
43 | struct RUP __iomem *RupP; /* the Rup to send it to */ | ||
44 | unsigned int Id; /* Id number */ | ||
45 | unsigned int BaseSysPort; /* SysPort of first tty on this RTA */ | ||
46 | unsigned int ModTypes; /* Modules on this RTA */ | ||
47 | spinlock_t RupLock; /* Lock structure for MPX */ | ||
48 | /* struct lockb RupLock; *//* Lock structure for MPX */ | ||
49 | }; | ||
50 | |||
51 | #endif /* __rio_unixrup_h__ */ | ||
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c deleted file mode 100644 index 3f47c2ead8e5..000000000000 --- a/drivers/char/ser_a2232.c +++ /dev/null | |||
@@ -1,831 +0,0 @@ | |||
1 | /* drivers/char/ser_a2232.c */ | ||
2 | |||
3 | /* $Id: ser_a2232.c,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ | ||
4 | |||
5 | /* Linux serial driver for the Amiga A2232 board */ | ||
6 | |||
7 | /* This driver is MAINTAINED. Before applying any changes, please contact | ||
8 | * the author. | ||
9 | */ | ||
10 | |||
11 | /* Copyright (c) 2000-2001 Enver Haase <ehaase@inf.fu-berlin.de> | ||
12 | * alias The A2232 driver project <A2232@gmx.net> | ||
13 | * All rights reserved. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License as published by | ||
17 | * the Free Software Foundation; either version 2 of the License, or | ||
18 | * (at your option) any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | * | ||
29 | */ | ||
30 | /***************************** Documentation ************************/ | ||
31 | /* | ||
32 | * This driver is in EXPERIMENTAL state. That means I could not find | ||
33 | * someone with five A2232 boards with 35 ports running at 19200 bps | ||
34 | * at the same time and test the machine's behaviour. | ||
35 | * However, I know that you can performance-tweak this driver (see | ||
36 | * the source code). | ||
37 | * One thing to consider is the time this driver consumes during the | ||
38 | * Amiga's vertical blank interrupt. Everything that is to be done | ||
39 | * _IS DONE_ when entering the vertical blank interrupt handler of | ||
40 | * this driver. | ||
41 | * However, it would be more sane to only do the job for only ONE card | ||
42 | * instead of ALL cards at a time; or, more generally, to handle only | ||
43 | * SOME ports instead of ALL ports at a time. | ||
44 | * However, as long as no-one runs into problems I guess I shouldn't | ||
45 | * change the driver as it runs fine for me :) . | ||
46 | * | ||
47 | * Version history of this file: | ||
48 | * 0.4 Resolved licensing issues. | ||
49 | * 0.3 Inclusion in the Linux/m68k tree, small fixes. | ||
50 | * 0.2 Added documentation, minor typo fixes. | ||
51 | * 0.1 Initial release. | ||
52 | * | ||
53 | * TO DO: | ||
54 | * - Handle incoming BREAK events. I guess "Stevens: Advanced | ||
55 | * Programming in the UNIX(R) Environment" is a good reference | ||
56 | * on what is to be done. | ||
57 | * - When installing as a module, don't simply 'printk' text, but | ||
58 | * send it to the TTY used by the user. | ||
59 | * | ||
60 | * THANKS TO: | ||
61 | * - Jukka Marin (65EC02 code). | ||
62 | * - The other NetBSD developers on whose A2232 driver I had a | ||
63 | * pretty close look. However, I didn't copy any code so it | ||
64 | * is okay to put my code under the GPL and include it into | ||
65 | * Linux. | ||
66 | */ | ||
67 | /***************************** End of Documentation *****************/ | ||
68 | |||
69 | /***************************** Defines ******************************/ | ||
70 | /* | ||
71 | * Enables experimental 115200 (normal) 230400 (turbo) baud rate. | ||
72 | * The A2232 specification states it can only operate at speeds up to | ||
73 | * 19200 bits per second, and I was not able to send a file via | ||
74 | * "sz"/"rz" and a null-modem cable from one A2232 port to another | ||
75 | * at 115200 bits per second. | ||
76 | * However, this might work for you. | ||
77 | */ | ||
78 | #undef A2232_SPEEDHACK | ||
79 | /* | ||
80 | * Default is not to use RTS/CTS so you could be talked to death. | ||
81 | */ | ||
82 | #define A2232_SUPPRESS_RTSCTS_WARNING | ||
83 | /************************* End of Defines ***************************/ | ||
84 | |||
85 | /***************************** Includes *****************************/ | ||
86 | #include <linux/module.h> | ||
87 | |||
88 | #include <linux/types.h> | ||
89 | #include <linux/interrupt.h> | ||
90 | #include <linux/kernel.h> | ||
91 | #include <linux/errno.h> | ||
92 | #include <linux/sched.h> | ||
93 | #include <linux/tty.h> | ||
94 | |||
95 | #include <asm/setup.h> | ||
96 | #include <asm/amigaints.h> | ||
97 | #include <asm/amigahw.h> | ||
98 | #include <linux/zorro.h> | ||
99 | #include <asm/irq.h> | ||
100 | #include <linux/mutex.h> | ||
101 | |||
102 | #include <linux/delay.h> | ||
103 | |||
104 | #include <linux/serial.h> | ||
105 | #include <linux/generic_serial.h> | ||
106 | #include <linux/tty_flip.h> | ||
107 | |||
108 | #include "ser_a2232.h" | ||
109 | #include "ser_a2232fw.h" | ||
110 | /************************* End of Includes **************************/ | ||
111 | |||
112 | /***************************** Prototypes ***************************/ | ||
113 | /* The interrupt service routine */ | ||
114 | static irqreturn_t a2232_vbl_inter(int irq, void *data); | ||
115 | /* Initialize the port structures */ | ||
116 | static void a2232_init_portstructs(void); | ||
117 | /* Initialize and register TTY drivers. */ | ||
118 | /* returns 0 IFF successful */ | ||
119 | static int a2232_init_drivers(void); | ||
120 | |||
121 | /* BEGIN GENERIC_SERIAL PROTOTYPES */ | ||
122 | static void a2232_disable_tx_interrupts(void *ptr); | ||
123 | static void a2232_enable_tx_interrupts(void *ptr); | ||
124 | static void a2232_disable_rx_interrupts(void *ptr); | ||
125 | static void a2232_enable_rx_interrupts(void *ptr); | ||
126 | static int a2232_carrier_raised(struct tty_port *port); | ||
127 | static void a2232_shutdown_port(void *ptr); | ||
128 | static int a2232_set_real_termios(void *ptr); | ||
129 | static int a2232_chars_in_buffer(void *ptr); | ||
130 | static void a2232_close(void *ptr); | ||
131 | static void a2232_hungup(void *ptr); | ||
132 | /* static void a2232_getserial (void *ptr, struct serial_struct *sp); */ | ||
133 | /* END GENERIC_SERIAL PROTOTYPES */ | ||
134 | |||
135 | /* Functions that the TTY driver struct expects */ | ||
136 | static int a2232_ioctl(struct tty_struct *tty, | ||
137 | unsigned int cmd, unsigned long arg); | ||
138 | static void a2232_throttle(struct tty_struct *tty); | ||
139 | static void a2232_unthrottle(struct tty_struct *tty); | ||
140 | static int a2232_open(struct tty_struct * tty, struct file * filp); | ||
141 | /************************* End of Prototypes ************************/ | ||
142 | |||
143 | /***************************** Global variables *********************/ | ||
144 | /*--------------------------------------------------------------------------- | ||
145 | * Interface from generic_serial.c back here | ||
146 | *--------------------------------------------------------------------------*/ | ||
147 | static struct real_driver a2232_real_driver = { | ||
148 | a2232_disable_tx_interrupts, | ||
149 | a2232_enable_tx_interrupts, | ||
150 | a2232_disable_rx_interrupts, | ||
151 | a2232_enable_rx_interrupts, | ||
152 | a2232_shutdown_port, | ||
153 | a2232_set_real_termios, | ||
154 | a2232_chars_in_buffer, | ||
155 | a2232_close, | ||
156 | a2232_hungup, | ||
157 | NULL /* a2232_getserial */ | ||
158 | }; | ||
159 | |||
160 | static void *a2232_driver_ID = &a2232_driver_ID; // Some memory address WE own. | ||
161 | |||
162 | /* Ports structs */ | ||
163 | static struct a2232_port a2232_ports[MAX_A2232_BOARDS*NUMLINES]; | ||
164 | |||
165 | /* TTY driver structs */ | ||
166 | static struct tty_driver *a2232_driver; | ||
167 | |||
168 | /* nr of cards completely (all ports) and correctly configured */ | ||
169 | static int nr_a2232; | ||
170 | |||
171 | /* zorro_dev structs for the A2232's */ | ||
172 | static struct zorro_dev *zd_a2232[MAX_A2232_BOARDS]; | ||
173 | /***************************** End of Global variables **************/ | ||
174 | |||
175 | /* Helper functions */ | ||
176 | |||
177 | static inline volatile struct a2232memory *a2232mem(unsigned int board) | ||
178 | { | ||
179 | return (volatile struct a2232memory *)ZTWO_VADDR(zd_a2232[board]->resource.start); | ||
180 | } | ||
181 | |||
182 | static inline volatile struct a2232status *a2232stat(unsigned int board, | ||
183 | unsigned int portonboard) | ||
184 | { | ||
185 | volatile struct a2232memory *mem = a2232mem(board); | ||
186 | return &(mem->Status[portonboard]); | ||
187 | } | ||
188 | |||
189 | static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) | ||
190 | { | ||
191 | /* Mostly stolen from other drivers. | ||
192 | Maybe one could implement a more efficient version by not only | ||
193 | transferring one character at a time. | ||
194 | */ | ||
195 | struct tty_struct *tty = port->gs.port.tty; | ||
196 | |||
197 | #if 0 | ||
198 | switch(err) { | ||
199 | case TTY_BREAK: | ||
200 | break; | ||
201 | case TTY_PARITY: | ||
202 | break; | ||
203 | case TTY_OVERRUN: | ||
204 | break; | ||
205 | case TTY_FRAME: | ||
206 | break; | ||
207 | } | ||
208 | #endif | ||
209 | |||
210 | tty_insert_flip_char(tty, ch, err); | ||
211 | tty_flip_buffer_push(tty); | ||
212 | } | ||
213 | |||
214 | /***************************** Functions ****************************/ | ||
215 | /*** BEGIN OF REAL_DRIVER FUNCTIONS ***/ | ||
216 | |||
217 | static void a2232_disable_tx_interrupts(void *ptr) | ||
218 | { | ||
219 | struct a2232_port *port; | ||
220 | volatile struct a2232status *stat; | ||
221 | unsigned long flags; | ||
222 | |||
223 | port = ptr; | ||
224 | stat = a2232stat(port->which_a2232, port->which_port_on_a2232); | ||
225 | stat->OutDisable = -1; | ||
226 | |||
227 | /* Does this here really have to be? */ | ||
228 | local_irq_save(flags); | ||
229 | port->gs.port.flags &= ~GS_TX_INTEN; | ||
230 | local_irq_restore(flags); | ||
231 | } | ||
232 | |||
233 | static void a2232_enable_tx_interrupts(void *ptr) | ||
234 | { | ||
235 | struct a2232_port *port; | ||
236 | volatile struct a2232status *stat; | ||
237 | unsigned long flags; | ||
238 | |||
239 | port = ptr; | ||
240 | stat = a2232stat(port->which_a2232, port->which_port_on_a2232); | ||
241 | stat->OutDisable = 0; | ||
242 | |||
243 | /* Does this here really have to be? */ | ||
244 | local_irq_save(flags); | ||
245 | port->gs.port.flags |= GS_TX_INTEN; | ||
246 | local_irq_restore(flags); | ||
247 | } | ||
248 | |||
249 | static void a2232_disable_rx_interrupts(void *ptr) | ||
250 | { | ||
251 | struct a2232_port *port; | ||
252 | port = ptr; | ||
253 | port->disable_rx = -1; | ||
254 | } | ||
255 | |||
256 | static void a2232_enable_rx_interrupts(void *ptr) | ||
257 | { | ||
258 | struct a2232_port *port; | ||
259 | port = ptr; | ||
260 | port->disable_rx = 0; | ||
261 | } | ||
262 | |||
263 | static int a2232_carrier_raised(struct tty_port *port) | ||
264 | { | ||
265 | struct a2232_port *ap = container_of(port, struct a2232_port, gs.port); | ||
266 | return ap->cd_status; | ||
267 | } | ||
268 | |||
269 | static void a2232_shutdown_port(void *ptr) | ||
270 | { | ||
271 | struct a2232_port *port; | ||
272 | volatile struct a2232status *stat; | ||
273 | unsigned long flags; | ||
274 | |||
275 | port = ptr; | ||
276 | stat = a2232stat(port->which_a2232, port->which_port_on_a2232); | ||
277 | |||
278 | local_irq_save(flags); | ||
279 | |||
280 | port->gs.port.flags &= ~GS_ACTIVE; | ||
281 | |||
282 | if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) { | ||
283 | /* Set DTR and RTS to Low, flush output. | ||
284 | The NetBSD driver "msc.c" does it this way. */ | ||
285 | stat->Command = ( (stat->Command & ~A2232CMD_CMask) | | ||
286 | A2232CMD_Close ); | ||
287 | stat->OutFlush = -1; | ||
288 | stat->Setup = -1; | ||
289 | } | ||
290 | |||
291 | local_irq_restore(flags); | ||
292 | |||
293 | /* After analyzing control flow, I think a2232_shutdown_port | ||
294 | is actually the last call from the system when at application | ||
295 | level someone issues a "echo Hello >>/dev/ttyY0". | ||
296 | Therefore I think the MOD_DEC_USE_COUNT should be here and | ||
297 | not in "a2232_close()". See the comment in "sx.c", too. | ||
298 | If you run into problems, compile this driver into the | ||
299 | kernel instead of compiling it as a module. */ | ||
300 | } | ||
301 | |||
302 | static int a2232_set_real_termios(void *ptr) | ||
303 | { | ||
304 | unsigned int cflag, baud, chsize, stopb, parity, softflow; | ||
305 | int rate; | ||
306 | int a2232_param, a2232_cmd; | ||
307 | unsigned long flags; | ||
308 | unsigned int i; | ||
309 | struct a2232_port *port = ptr; | ||
310 | volatile struct a2232status *status; | ||
311 | volatile struct a2232memory *mem; | ||
312 | |||
313 | if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; | ||
314 | |||
315 | status = a2232stat(port->which_a2232, port->which_port_on_a2232); | ||
316 | mem = a2232mem(port->which_a2232); | ||
317 | |||
318 | a2232_param = a2232_cmd = 0; | ||
319 | |||
320 | // get baud rate | ||
321 | baud = port->gs.baud; | ||
322 | if (baud == 0) { | ||
323 | /* speed == 0 -> drop DTR, do nothing else */ | ||
324 | local_irq_save(flags); | ||
325 | // Clear DTR (and RTS... mhhh). | ||
326 | status->Command = ( (status->Command & ~A2232CMD_CMask) | | ||
327 | A2232CMD_Close ); | ||
328 | status->OutFlush = -1; | ||
329 | status->Setup = -1; | ||
330 | |||
331 | local_irq_restore(flags); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | rate = A2232_BAUD_TABLE_NOAVAIL; | ||
336 | for (i=0; i < A2232_BAUD_TABLE_NUM_RATES * 3; i += 3){ | ||
337 | if (a2232_baud_table[i] == baud){ | ||
338 | if (mem->Common.Crystal == A2232_TURBO) rate = a2232_baud_table[i+2]; | ||
339 | else rate = a2232_baud_table[i+1]; | ||
340 | } | ||
341 | } | ||
342 | if (rate == A2232_BAUD_TABLE_NOAVAIL){ | ||
343 | printk("a2232: Board %d Port %d unsupported baud rate: %d baud. Using another.\n",port->which_a2232,port->which_port_on_a2232,baud); | ||
344 | // This is useful for both (turbo or normal) Crystal versions. | ||
345 | rate = A2232PARAM_B9600; | ||
346 | } | ||
347 | a2232_param |= rate; | ||
348 | |||
349 | cflag = port->gs.port.tty->termios->c_cflag; | ||
350 | |||
351 | // get character size | ||
352 | chsize = cflag & CSIZE; | ||
353 | switch (chsize){ | ||
354 | case CS8: a2232_param |= A2232PARAM_8Bit; break; | ||
355 | case CS7: a2232_param |= A2232PARAM_7Bit; break; | ||
356 | case CS6: a2232_param |= A2232PARAM_6Bit; break; | ||
357 | case CS5: a2232_param |= A2232PARAM_5Bit; break; | ||
358 | default: printk("a2232: Board %d Port %d unsupported character size: %d. Using 8 data bits.\n", | ||
359 | port->which_a2232,port->which_port_on_a2232,chsize); | ||
360 | a2232_param |= A2232PARAM_8Bit; break; | ||
361 | } | ||
362 | |||
363 | // get number of stop bits | ||
364 | stopb = cflag & CSTOPB; | ||
365 | if (stopb){ // two stop bits instead of one | ||
366 | printk("a2232: Board %d Port %d 2 stop bits unsupported. Using 1 stop bit.\n", | ||
367 | port->which_a2232,port->which_port_on_a2232); | ||
368 | } | ||
369 | |||
370 | // Warn if RTS/CTS not wanted | ||
371 | if (!(cflag & CRTSCTS)){ | ||
372 | #ifndef A2232_SUPPRESS_RTSCTS_WARNING | ||
373 | printk("a2232: Board %d Port %d cannot switch off firmware-implemented RTS/CTS hardware flow control.\n", | ||
374 | port->which_a2232,port->which_port_on_a2232); | ||
375 | #endif | ||
376 | } | ||
377 | |||
378 | /* I think this is correct. | ||
379 | However, IXOFF means _input_ flow control and I wonder | ||
380 | if one should care about IXON _output_ flow control, | ||
381 | too. If this makes problems, one should turn the A2232 | ||
382 | firmware XON/XOFF "SoftFlow" flow control off and use | ||
383 | the conventional way of inserting START/STOP characters | ||
384 | by hand in throttle()/unthrottle(). | ||
385 | */ | ||
386 | softflow = !!( port->gs.port.tty->termios->c_iflag & IXOFF ); | ||
387 | |||
388 | // get Parity (Enabled/Disabled? If Enabled, Odd or Even?) | ||
389 | parity = cflag & (PARENB | PARODD); | ||
390 | if (parity & PARENB){ | ||
391 | if (parity & PARODD){ | ||
392 | a2232_cmd |= A2232CMD_OddParity; | ||
393 | } | ||
394 | else{ | ||
395 | a2232_cmd |= A2232CMD_EvenParity; | ||
396 | } | ||
397 | } | ||
398 | else a2232_cmd |= A2232CMD_NoParity; | ||
399 | |||
400 | |||
401 | /* Hmm. Maybe an own a2232_port structure | ||
402 | member would be cleaner? */ | ||
403 | if (cflag & CLOCAL) | ||
404 | port->gs.port.flags &= ~ASYNC_CHECK_CD; | ||
405 | else | ||
406 | port->gs.port.flags |= ASYNC_CHECK_CD; | ||
407 | |||
408 | |||
409 | /* Now we have all parameters and can go to set them: */ | ||
410 | local_irq_save(flags); | ||
411 | |||
412 | status->Param = a2232_param | A2232PARAM_RcvBaud; | ||
413 | status->Command = a2232_cmd | A2232CMD_Open | A2232CMD_Enable; | ||
414 | status->SoftFlow = softflow; | ||
415 | status->OutDisable = 0; | ||
416 | status->Setup = -1; | ||
417 | |||
418 | local_irq_restore(flags); | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static int a2232_chars_in_buffer(void *ptr) | ||
423 | { | ||
424 | struct a2232_port *port; | ||
425 | volatile struct a2232status *status; | ||
426 | unsigned char ret; /* we need modulo-256 arithmetics */ | ||
427 | port = ptr; | ||
428 | status = a2232stat(port->which_a2232, port->which_port_on_a2232); | ||
429 | #if A2232_IOBUFLEN != 256 | ||
430 | #error "Re-Implement a2232_chars_in_buffer()!" | ||
431 | #endif | ||
432 | ret = (status->OutHead - status->OutTail); | ||
433 | return ret; | ||
434 | } | ||
435 | |||
436 | static void a2232_close(void *ptr) | ||
437 | { | ||
438 | a2232_disable_tx_interrupts(ptr); | ||
439 | a2232_disable_rx_interrupts(ptr); | ||
440 | /* see the comment in a2232_shutdown_port above. */ | ||
441 | } | ||
442 | |||
443 | static void a2232_hungup(void *ptr) | ||
444 | { | ||
445 | a2232_close(ptr); | ||
446 | } | ||
447 | /*** END OF REAL_DRIVER FUNCTIONS ***/ | ||
448 | |||
449 | /*** BEGIN FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ | ||
450 | static int a2232_ioctl( struct tty_struct *tty, | ||
451 | unsigned int cmd, unsigned long arg) | ||
452 | { | ||
453 | return -ENOIOCTLCMD; | ||
454 | } | ||
455 | |||
456 | static void a2232_throttle(struct tty_struct *tty) | ||
457 | { | ||
458 | /* Throttle: System cannot take another chars: Drop RTS or | ||
459 | send the STOP char or whatever. | ||
460 | The A2232 firmware does RTS/CTS anyway, and XON/XOFF | ||
461 | if switched on. So the only thing we can do at this | ||
462 | layer here is not taking any characters out of the | ||
463 | A2232 buffer any more. */ | ||
464 | struct a2232_port *port = tty->driver_data; | ||
465 | port->throttle_input = -1; | ||
466 | } | ||
467 | |||
468 | static void a2232_unthrottle(struct tty_struct *tty) | ||
469 | { | ||
470 | /* Unthrottle: dual to "throttle()" above. */ | ||
471 | struct a2232_port *port = tty->driver_data; | ||
472 | port->throttle_input = 0; | ||
473 | } | ||
474 | |||
475 | static int a2232_open(struct tty_struct * tty, struct file * filp) | ||
476 | { | ||
477 | /* More or less stolen from other drivers. */ | ||
478 | int line; | ||
479 | int retval; | ||
480 | struct a2232_port *port; | ||
481 | |||
482 | line = tty->index; | ||
483 | port = &a2232_ports[line]; | ||
484 | |||
485 | tty->driver_data = port; | ||
486 | port->gs.port.tty = tty; | ||
487 | port->gs.port.count++; | ||
488 | retval = gs_init_port(&port->gs); | ||
489 | if (retval) { | ||
490 | port->gs.port.count--; | ||
491 | return retval; | ||
492 | } | ||
493 | port->gs.port.flags |= GS_ACTIVE; | ||
494 | retval = gs_block_til_ready(port, filp); | ||
495 | |||
496 | if (retval) { | ||
497 | port->gs.port.count--; | ||
498 | return retval; | ||
499 | } | ||
500 | |||
501 | a2232_enable_rx_interrupts(port); | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | /*** END OF FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ | ||
506 | |||
507 | static irqreturn_t a2232_vbl_inter(int irq, void *data) | ||
508 | { | ||
509 | #if A2232_IOBUFLEN != 256 | ||
510 | #error "Re-Implement a2232_vbl_inter()!" | ||
511 | #endif | ||
512 | |||
513 | struct a2232_port *port; | ||
514 | volatile struct a2232memory *mem; | ||
515 | volatile struct a2232status *status; | ||
516 | unsigned char newhead; | ||
517 | unsigned char bufpos; /* Must be unsigned char. We need the modulo-256 arithmetics */ | ||
518 | unsigned char ncd, ocd, ccd; /* names consistent with the NetBSD driver */ | ||
519 | volatile u_char *ibuf, *cbuf, *obuf; | ||
520 | int ch, err, n, p; | ||
521 | for (n = 0; n < nr_a2232; n++){ /* for every completely initialized A2232 board */ | ||
522 | mem = a2232mem(n); | ||
523 | for (p = 0; p < NUMLINES; p++){ /* for every port on this board */ | ||
524 | err = 0; | ||
525 | port = &a2232_ports[n*NUMLINES+p]; | ||
526 | if ( port->gs.port.flags & GS_ACTIVE ){ /* if the port is used */ | ||
527 | |||
528 | status = a2232stat(n,p); | ||
529 | |||
530 | if (!port->disable_rx && !port->throttle_input){ /* If input is not disabled */ | ||
531 | newhead = status->InHead; /* 65EC02 write pointer */ | ||
532 | bufpos = status->InTail; | ||
533 | |||
534 | /* check for input for this port */ | ||
535 | if (newhead != bufpos) { | ||
536 | /* buffer for input chars/events */ | ||
537 | ibuf = mem->InBuf[p]; | ||
538 | |||
539 | /* data types of bytes in ibuf */ | ||
540 | cbuf = mem->InCtl[p]; | ||
541 | |||
542 | /* do for all chars */ | ||
543 | while (bufpos != newhead) { | ||
544 | /* which type of input data? */ | ||
545 | switch (cbuf[bufpos]) { | ||
546 | /* switch on input event (CD, BREAK, etc.) */ | ||
547 | case A2232INCTL_EVENT: | ||
548 | switch (ibuf[bufpos++]) { | ||
549 | case A2232EVENT_Break: | ||
550 | /* TODO: Handle BREAK signal */ | ||
551 | break; | ||
552 | /* A2232EVENT_CarrierOn and A2232EVENT_CarrierOff are | ||
553 | handled in a separate queue and should not occur here. */ | ||
554 | case A2232EVENT_Sync: | ||
555 | printk("A2232: 65EC02 software sent SYNC event, don't know what to do. Ignoring."); | ||
556 | break; | ||
557 | default: | ||
558 | printk("A2232: 65EC02 software broken, unknown event type %d occurred.\n",ibuf[bufpos-1]); | ||
559 | } /* event type switch */ | ||
560 | break; | ||
561 | case A2232INCTL_CHAR: | ||
562 | /* Receive incoming char */ | ||
563 | a2232_receive_char(port, ibuf[bufpos], err); | ||
564 | bufpos++; | ||
565 | break; | ||
566 | default: | ||
567 | printk("A2232: 65EC02 software broken, unknown data type %d occurred.\n",cbuf[bufpos]); | ||
568 | bufpos++; | ||
569 | } /* switch on input data type */ | ||
570 | } /* while there's something in the buffer */ | ||
571 | |||
572 | status->InTail = bufpos; /* tell 65EC02 what we've read */ | ||
573 | |||
574 | } /* if there was something in the buffer */ | ||
575 | } /* If input is not disabled */ | ||
576 | |||
577 | /* Now check if there's something to output */ | ||
578 | obuf = mem->OutBuf[p]; | ||
579 | bufpos = status->OutHead; | ||
580 | while ( (port->gs.xmit_cnt > 0) && | ||
581 | (!port->gs.port.tty->stopped) && | ||
582 | (!port->gs.port.tty->hw_stopped) ){ /* While there are chars to transmit */ | ||
583 | if (((bufpos+1) & A2232_IOBUFLENMASK) != status->OutTail) { /* If the A2232 buffer is not full */ | ||
584 | ch = port->gs.xmit_buf[port->gs.xmit_tail]; /* get the next char to transmit */ | ||
585 | port->gs.xmit_tail = (port->gs.xmit_tail+1) & (SERIAL_XMIT_SIZE-1); /* modulo-addition for the gs.xmit_buf ring-buffer */ | ||
586 | obuf[bufpos++] = ch; /* put it into the A2232 buffer */ | ||
587 | port->gs.xmit_cnt--; | ||
588 | } | ||
589 | else{ /* If A2232 the buffer is full */ | ||
590 | break; /* simply stop filling it. */ | ||
591 | } | ||
592 | } | ||
593 | status->OutHead = bufpos; | ||
594 | |||
595 | /* WakeUp if output buffer runs low */ | ||
596 | if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { | ||
597 | tty_wakeup(port->gs.port.tty); | ||
598 | } | ||
599 | } // if the port is used | ||
600 | } // for every port on the board | ||
601 | |||
602 | /* Now check the CD message queue */ | ||
603 | newhead = mem->Common.CDHead; | ||
604 | bufpos = mem->Common.CDTail; | ||
605 | if (newhead != bufpos){ /* There are CD events in queue */ | ||
606 | ocd = mem->Common.CDStatus; /* get old status bits */ | ||
607 | while (newhead != bufpos){ /* read all events */ | ||
608 | ncd = mem->CDBuf[bufpos++]; /* get one event */ | ||
609 | ccd = ncd ^ ocd; /* mask of changed lines */ | ||
610 | ocd = ncd; /* save new status bits */ | ||
611 | for(p=0; p < NUMLINES; p++){ /* for all ports */ | ||
612 | if (ccd & 1){ /* this one changed */ | ||
613 | |||
614 | struct a2232_port *port = &a2232_ports[n*7+p]; | ||
615 | port->cd_status = !(ncd & 1); /* ncd&1 <=> CD is now off */ | ||
616 | |||
617 | if (!(port->gs.port.flags & ASYNC_CHECK_CD)) | ||
618 | ; /* Don't report DCD changes */ | ||
619 | else if (port->cd_status) { // if DCD on: DCD went UP! | ||
620 | |||
621 | /* Are we blocking in open?*/ | ||
622 | wake_up_interruptible(&port->gs.port.open_wait); | ||
623 | } | ||
624 | else { // if DCD off: DCD went DOWN! | ||
625 | if (port->gs.port.tty) | ||
626 | tty_hangup (port->gs.port.tty); | ||
627 | } | ||
628 | |||
629 | } // if CD changed for this port | ||
630 | ccd >>= 1; | ||
631 | ncd >>= 1; /* Shift bits for next line */ | ||
632 | } // for every port | ||
633 | } // while CD events in queue | ||
634 | mem->Common.CDStatus = ocd; /* save new status */ | ||
635 | mem->Common.CDTail = bufpos; /* remove events */ | ||
636 | } // if events in CD queue | ||
637 | |||
638 | } // for every completely initialized A2232 board | ||
639 | return IRQ_HANDLED; | ||
640 | } | ||
641 | |||
642 | static const struct tty_port_operations a2232_port_ops = { | ||
643 | .carrier_raised = a2232_carrier_raised, | ||
644 | }; | ||
645 | |||
646 | static void a2232_init_portstructs(void) | ||
647 | { | ||
648 | struct a2232_port *port; | ||
649 | int i; | ||
650 | |||
651 | for (i = 0; i < MAX_A2232_BOARDS*NUMLINES; i++) { | ||
652 | port = a2232_ports + i; | ||
653 | tty_port_init(&port->gs.port); | ||
654 | port->gs.port.ops = &a2232_port_ops; | ||
655 | port->which_a2232 = i/NUMLINES; | ||
656 | port->which_port_on_a2232 = i%NUMLINES; | ||
657 | port->disable_rx = port->throttle_input = port->cd_status = 0; | ||
658 | port->gs.magic = A2232_MAGIC; | ||
659 | port->gs.close_delay = HZ/2; | ||
660 | port->gs.closing_wait = 30 * HZ; | ||
661 | port->gs.rd = &a2232_real_driver; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | static const struct tty_operations a2232_ops = { | ||
666 | .open = a2232_open, | ||
667 | .close = gs_close, | ||
668 | .write = gs_write, | ||
669 | .put_char = gs_put_char, | ||
670 | .flush_chars = gs_flush_chars, | ||
671 | .write_room = gs_write_room, | ||
672 | .chars_in_buffer = gs_chars_in_buffer, | ||
673 | .flush_buffer = gs_flush_buffer, | ||
674 | .ioctl = a2232_ioctl, | ||
675 | .throttle = a2232_throttle, | ||
676 | .unthrottle = a2232_unthrottle, | ||
677 | .set_termios = gs_set_termios, | ||
678 | .stop = gs_stop, | ||
679 | .start = gs_start, | ||
680 | .hangup = gs_hangup, | ||
681 | }; | ||
682 | |||
683 | static int a2232_init_drivers(void) | ||
684 | { | ||
685 | int error; | ||
686 | |||
687 | a2232_driver = alloc_tty_driver(NUMLINES * nr_a2232); | ||
688 | if (!a2232_driver) | ||
689 | return -ENOMEM; | ||
690 | a2232_driver->owner = THIS_MODULE; | ||
691 | a2232_driver->driver_name = "commodore_a2232"; | ||
692 | a2232_driver->name = "ttyY"; | ||
693 | a2232_driver->major = A2232_NORMAL_MAJOR; | ||
694 | a2232_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
695 | a2232_driver->subtype = SERIAL_TYPE_NORMAL; | ||
696 | a2232_driver->init_termios = tty_std_termios; | ||
697 | a2232_driver->init_termios.c_cflag = | ||
698 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
699 | a2232_driver->init_termios.c_ispeed = 9600; | ||
700 | a2232_driver->init_termios.c_ospeed = 9600; | ||
701 | a2232_driver->flags = TTY_DRIVER_REAL_RAW; | ||
702 | tty_set_operations(a2232_driver, &a2232_ops); | ||
703 | if ((error = tty_register_driver(a2232_driver))) { | ||
704 | printk(KERN_ERR "A2232: Couldn't register A2232 driver, error = %d\n", | ||
705 | error); | ||
706 | put_tty_driver(a2232_driver); | ||
707 | return 1; | ||
708 | } | ||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | static int __init a2232board_init(void) | ||
713 | { | ||
714 | struct zorro_dev *z; | ||
715 | |||
716 | unsigned int boardaddr; | ||
717 | int bcount; | ||
718 | short start; | ||
719 | u_char *from; | ||
720 | volatile u_char *to; | ||
721 | volatile struct a2232memory *mem; | ||
722 | int error, i; | ||
723 | |||
724 | #ifdef CONFIG_SMP | ||
725 | return -ENODEV; /* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */ | ||
726 | #endif | ||
727 | |||
728 | if (!MACH_IS_AMIGA){ | ||
729 | return -ENODEV; | ||
730 | } | ||
731 | |||
732 | printk("Commodore A2232 driver initializing.\n"); /* Say that we're alive. */ | ||
733 | |||
734 | z = NULL; | ||
735 | nr_a2232 = 0; | ||
736 | while ( (z = zorro_find_device(ZORRO_WILDCARD, z)) ){ | ||
737 | if ( (z->id != ZORRO_PROD_CBM_A2232_PROTOTYPE) && | ||
738 | (z->id != ZORRO_PROD_CBM_A2232) ){ | ||
739 | continue; // The board found was no A2232 | ||
740 | } | ||
741 | if (!zorro_request_device(z,"A2232 driver")) | ||
742 | continue; | ||
743 | |||
744 | printk("Commodore A2232 found (#%d).\n",nr_a2232); | ||
745 | |||
746 | zd_a2232[nr_a2232] = z; | ||
747 | |||
748 | boardaddr = ZTWO_VADDR( z->resource.start ); | ||
749 | printk("Board is located at address 0x%x, size is 0x%x.\n", boardaddr, (unsigned int) ((z->resource.end+1) - (z->resource.start))); | ||
750 | |||
751 | mem = (volatile struct a2232memory *) boardaddr; | ||
752 | |||
753 | (void) mem->Enable6502Reset; /* copy the code across to the board */ | ||
754 | to = (u_char *)mem; from = a2232_65EC02code; bcount = sizeof(a2232_65EC02code) - 2; | ||
755 | start = *(short *)from; | ||
756 | from += sizeof(start); | ||
757 | to += start; | ||
758 | while(bcount--) *to++ = *from++; | ||
759 | printk("65EC02 software uploaded to the A2232 memory.\n"); | ||
760 | |||
761 | mem->Common.Crystal = A2232_UNKNOWN; /* use automatic speed check */ | ||
762 | |||
763 | /* start 6502 running */ | ||
764 | (void) mem->ResetBoard; | ||
765 | printk("A2232's 65EC02 CPU up and running.\n"); | ||
766 | |||
767 | /* wait until speed detector has finished */ | ||
768 | for (bcount = 0; bcount < 2000; bcount++) { | ||
769 | udelay(1000); | ||
770 | if (mem->Common.Crystal) | ||
771 | break; | ||
772 | } | ||
773 | printk((mem->Common.Crystal?"A2232 oscillator crystal detected by 65EC02 software: ":"65EC02 software could not determine A2232 oscillator crystal: ")); | ||
774 | switch (mem->Common.Crystal){ | ||
775 | case A2232_UNKNOWN: | ||
776 | printk("Unknown crystal.\n"); | ||
777 | break; | ||
778 | case A2232_NORMAL: | ||
779 | printk ("Normal crystal.\n"); | ||
780 | break; | ||
781 | case A2232_TURBO: | ||
782 | printk ("Turbo crystal.\n"); | ||
783 | break; | ||
784 | default: | ||
785 | printk ("0x%x. Huh?\n",mem->Common.Crystal); | ||
786 | } | ||
787 | |||
788 | nr_a2232++; | ||
789 | |||
790 | } | ||
791 | |||
792 | printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */ | ||
793 | |||
794 | a2232_init_portstructs(); | ||
795 | |||
796 | /* | ||
797 | a2232_init_drivers also registers the drivers. Must be here because all boards | ||
798 | have to be detected first. | ||
799 | */ | ||
800 | if (a2232_init_drivers()) return -ENODEV; // maybe we should use a different -Exxx? | ||
801 | |||
802 | error = request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0, | ||
803 | "A2232 serial VBL", a2232_driver_ID); | ||
804 | if (error) { | ||
805 | for (i = 0; i < nr_a2232; i++) | ||
806 | zorro_release_device(zd_a2232[i]); | ||
807 | tty_unregister_driver(a2232_driver); | ||
808 | put_tty_driver(a2232_driver); | ||
809 | } | ||
810 | return error; | ||
811 | } | ||
812 | |||
813 | static void __exit a2232board_exit(void) | ||
814 | { | ||
815 | int i; | ||
816 | |||
817 | for (i = 0; i < nr_a2232; i++) { | ||
818 | zorro_release_device(zd_a2232[i]); | ||
819 | } | ||
820 | |||
821 | tty_unregister_driver(a2232_driver); | ||
822 | put_tty_driver(a2232_driver); | ||
823 | free_irq(IRQ_AMIGA_VERTB, a2232_driver_ID); | ||
824 | } | ||
825 | |||
826 | module_init(a2232board_init); | ||
827 | module_exit(a2232board_exit); | ||
828 | |||
829 | MODULE_AUTHOR("Enver Haase"); | ||
830 | MODULE_DESCRIPTION("Amiga A2232 multi-serial board driver"); | ||
831 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/ser_a2232.h b/drivers/char/ser_a2232.h deleted file mode 100644 index bc09eb9e118b..000000000000 --- a/drivers/char/ser_a2232.h +++ /dev/null | |||
@@ -1,202 +0,0 @@ | |||
1 | /* drivers/char/ser_a2232.h */ | ||
2 | |||
3 | /* $Id: ser_a2232.h,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ | ||
4 | |||
5 | /* Linux serial driver for the Amiga A2232 board */ | ||
6 | |||
7 | /* This driver is MAINTAINED. Before applying any changes, please contact | ||
8 | * the author. | ||
9 | */ | ||
10 | |||
11 | /* Copyright (c) 2000-2001 Enver Haase <ehaase@inf.fu-berlin.de> | ||
12 | * alias The A2232 driver project <A2232@gmx.net> | ||
13 | * All rights reserved. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License as published by | ||
17 | * the Free Software Foundation; either version 2 of the License, or | ||
18 | * (at your option) any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #ifndef _SER_A2232_H_ | ||
32 | #define _SER_A2232_H_ | ||
33 | |||
34 | /* | ||
35 | How many boards are to be supported at maximum; | ||
36 | "up to five A2232 Multiport Serial Cards may be installed in a | ||
37 | single Amiga 2000" states the A2232 User's Guide. If you have | ||
38 | more slots available, you might want to change the value below. | ||
39 | */ | ||
40 | #define MAX_A2232_BOARDS 5 | ||
41 | |||
42 | #ifndef A2232_NORMAL_MAJOR | ||
43 | /* This allows overriding on the compiler commandline, or in a "major.h" | ||
44 | include or something like that */ | ||
45 | #define A2232_NORMAL_MAJOR 224 /* /dev/ttyY* */ | ||
46 | #define A2232_CALLOUT_MAJOR 225 /* /dev/cuy* */ | ||
47 | #endif | ||
48 | |||
49 | /* Some magic is always good - Who knows :) */ | ||
50 | #define A2232_MAGIC 0x000a2232 | ||
51 | |||
52 | /* A2232 port structure to keep track of the | ||
53 | status of every single line used */ | ||
54 | struct a2232_port{ | ||
55 | struct gs_port gs; | ||
56 | unsigned int which_a2232; | ||
57 | unsigned int which_port_on_a2232; | ||
58 | short disable_rx; | ||
59 | short throttle_input; | ||
60 | short cd_status; | ||
61 | }; | ||
62 | |||
63 | #define NUMLINES 7 /* number of lines per board */ | ||
64 | #define A2232_IOBUFLEN 256 /* number of bytes per buffer */ | ||
65 | #define A2232_IOBUFLENMASK 0xff /* mask for maximum number of bytes */ | ||
66 | |||
67 | |||
68 | #define A2232_UNKNOWN 0 /* crystal not known */ | ||
69 | #define A2232_NORMAL 1 /* normal A2232 (1.8432 MHz oscillator) */ | ||
70 | #define A2232_TURBO 2 /* turbo A2232 (3.6864 MHz oscillator) */ | ||
71 | |||
72 | |||
73 | struct a2232common { | ||
74 | char Crystal; /* normal (1) or turbo (2) board? */ | ||
75 | u_char Pad_a; | ||
76 | u_char TimerH; /* timer value after speed check */ | ||
77 | u_char TimerL; | ||
78 | u_char CDHead; /* head pointer for CD message queue */ | ||
79 | u_char CDTail; /* tail pointer for CD message queue */ | ||
80 | u_char CDStatus; | ||
81 | u_char Pad_b; | ||
82 | }; | ||
83 | |||
84 | struct a2232status { | ||
85 | u_char InHead; /* input queue head */ | ||
86 | u_char InTail; /* input queue tail */ | ||
87 | u_char OutDisable; /* disables output */ | ||
88 | u_char OutHead; /* output queue head */ | ||
89 | u_char OutTail; /* output queue tail */ | ||
90 | u_char OutCtrl; /* soft flow control character to send */ | ||
91 | u_char OutFlush; /* flushes output buffer */ | ||
92 | u_char Setup; /* causes reconfiguration */ | ||
93 | u_char Param; /* parameter byte - see A2232PARAM */ | ||
94 | u_char Command; /* command byte - see A2232CMD */ | ||
95 | u_char SoftFlow; /* enables xon/xoff flow control */ | ||
96 | /* private 65EC02 fields: */ | ||
97 | u_char XonOff; /* stores XON/XOFF enable/disable */ | ||
98 | }; | ||
99 | |||
100 | #define A2232_MEMPAD1 \ | ||
101 | (0x0200 - NUMLINES * sizeof(struct a2232status) - \ | ||
102 | sizeof(struct a2232common)) | ||
103 | #define A2232_MEMPAD2 (0x2000 - NUMLINES * A2232_IOBUFLEN - A2232_IOBUFLEN) | ||
104 | |||
105 | struct a2232memory { | ||
106 | struct a2232status Status[NUMLINES]; /* 0x0000-0x006f status areas */ | ||
107 | struct a2232common Common; /* 0x0070-0x0077 common flags */ | ||
108 | u_char Dummy1[A2232_MEMPAD1]; /* 0x00XX-0x01ff */ | ||
109 | u_char OutBuf[NUMLINES][A2232_IOBUFLEN];/* 0x0200-0x08ff output bufs */ | ||
110 | u_char InBuf[NUMLINES][A2232_IOBUFLEN]; /* 0x0900-0x0fff input bufs */ | ||
111 | u_char InCtl[NUMLINES][A2232_IOBUFLEN]; /* 0x1000-0x16ff control data */ | ||
112 | u_char CDBuf[A2232_IOBUFLEN]; /* 0x1700-0x17ff CD event buffer */ | ||
113 | u_char Dummy2[A2232_MEMPAD2]; /* 0x1800-0x2fff */ | ||
114 | u_char Code[0x1000]; /* 0x3000-0x3fff code area */ | ||
115 | u_short InterruptAck; /* 0x4000 intr ack */ | ||
116 | u_char Dummy3[0x3ffe]; /* 0x4002-0x7fff */ | ||
117 | u_short Enable6502Reset; /* 0x8000 Stop board, */ | ||
118 | /* 6502 RESET line held low */ | ||
119 | u_char Dummy4[0x3ffe]; /* 0x8002-0xbfff */ | ||
120 | u_short ResetBoard; /* 0xc000 reset board & run, */ | ||
121 | /* 6502 RESET line held high */ | ||
122 | }; | ||
123 | |||
124 | #undef A2232_MEMPAD1 | ||
125 | #undef A2232_MEMPAD2 | ||
126 | |||
127 | #define A2232INCTL_CHAR 0 /* corresponding byte in InBuf is a character */ | ||
128 | #define A2232INCTL_EVENT 1 /* corresponding byte in InBuf is an event */ | ||
129 | |||
130 | #define A2232EVENT_Break 1 /* break set */ | ||
131 | #define A2232EVENT_CarrierOn 2 /* carrier raised */ | ||
132 | #define A2232EVENT_CarrierOff 3 /* carrier dropped */ | ||
133 | #define A2232EVENT_Sync 4 /* don't know, defined in 2232.ax */ | ||
134 | |||
135 | #define A2232CMD_Enable 0x1 /* enable/DTR bit */ | ||
136 | #define A2232CMD_Close 0x2 /* close the device */ | ||
137 | #define A2232CMD_Open 0xb /* open the device */ | ||
138 | #define A2232CMD_CMask 0xf /* command mask */ | ||
139 | #define A2232CMD_RTSOff 0x0 /* turn off RTS */ | ||
140 | #define A2232CMD_RTSOn 0x8 /* turn on RTS */ | ||
141 | #define A2232CMD_Break 0xd /* transmit a break */ | ||
142 | #define A2232CMD_RTSMask 0xc /* mask for RTS stuff */ | ||
143 | #define A2232CMD_NoParity 0x00 /* don't use parity */ | ||
144 | #define A2232CMD_OddParity 0x20 /* odd parity */ | ||
145 | #define A2232CMD_EvenParity 0x60 /* even parity */ | ||
146 | #define A2232CMD_ParityMask 0xe0 /* parity mask */ | ||
147 | |||
148 | #define A2232PARAM_B115200 0x0 /* baud rates */ | ||
149 | #define A2232PARAM_B50 0x1 | ||
150 | #define A2232PARAM_B75 0x2 | ||
151 | #define A2232PARAM_B110 0x3 | ||
152 | #define A2232PARAM_B134 0x4 | ||
153 | #define A2232PARAM_B150 0x5 | ||
154 | #define A2232PARAM_B300 0x6 | ||
155 | #define A2232PARAM_B600 0x7 | ||
156 | #define A2232PARAM_B1200 0x8 | ||
157 | #define A2232PARAM_B1800 0x9 | ||
158 | #define A2232PARAM_B2400 0xa | ||
159 | #define A2232PARAM_B3600 0xb | ||
160 | #define A2232PARAM_B4800 0xc | ||
161 | #define A2232PARAM_B7200 0xd | ||
162 | #define A2232PARAM_B9600 0xe | ||
163 | #define A2232PARAM_B19200 0xf | ||
164 | #define A2232PARAM_BaudMask 0xf /* baud rate mask */ | ||
165 | #define A2232PARAM_RcvBaud 0x10 /* enable receive baud rate */ | ||
166 | #define A2232PARAM_8Bit 0x00 /* numbers of bits */ | ||
167 | #define A2232PARAM_7Bit 0x20 | ||
168 | #define A2232PARAM_6Bit 0x40 | ||
169 | #define A2232PARAM_5Bit 0x60 | ||
170 | #define A2232PARAM_BitMask 0x60 /* numbers of bits mask */ | ||
171 | |||
172 | |||
173 | /* Standard speeds tables, -1 means unavailable, -2 means 0 baud: switch off line */ | ||
174 | #define A2232_BAUD_TABLE_NOAVAIL -1 | ||
175 | #define A2232_BAUD_TABLE_NUM_RATES (18) | ||
176 | static int a2232_baud_table[A2232_BAUD_TABLE_NUM_RATES*3] = { | ||
177 | //Baud //Normal //Turbo | ||
178 | 50, A2232PARAM_B50, A2232_BAUD_TABLE_NOAVAIL, | ||
179 | 75, A2232PARAM_B75, A2232_BAUD_TABLE_NOAVAIL, | ||
180 | 110, A2232PARAM_B110, A2232_BAUD_TABLE_NOAVAIL, | ||
181 | 134, A2232PARAM_B134, A2232_BAUD_TABLE_NOAVAIL, | ||
182 | 150, A2232PARAM_B150, A2232PARAM_B75, | ||
183 | 200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, | ||
184 | 300, A2232PARAM_B300, A2232PARAM_B150, | ||
185 | 600, A2232PARAM_B600, A2232PARAM_B300, | ||
186 | 1200, A2232PARAM_B1200, A2232PARAM_B600, | ||
187 | 1800, A2232PARAM_B1800, A2232_BAUD_TABLE_NOAVAIL, | ||
188 | 2400, A2232PARAM_B2400, A2232PARAM_B1200, | ||
189 | 4800, A2232PARAM_B4800, A2232PARAM_B2400, | ||
190 | 9600, A2232PARAM_B9600, A2232PARAM_B4800, | ||
191 | 19200, A2232PARAM_B19200, A2232PARAM_B9600, | ||
192 | 38400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B19200, | ||
193 | 57600, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, | ||
194 | #ifdef A2232_SPEEDHACK | ||
195 | 115200, A2232PARAM_B115200, A2232_BAUD_TABLE_NOAVAIL, | ||
196 | 230400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B115200 | ||
197 | #else | ||
198 | 115200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, | ||
199 | 230400, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL | ||
200 | #endif | ||
201 | }; | ||
202 | #endif | ||
diff --git a/drivers/char/ser_a2232fw.ax b/drivers/char/ser_a2232fw.ax deleted file mode 100644 index 736438032768..000000000000 --- a/drivers/char/ser_a2232fw.ax +++ /dev/null | |||
@@ -1,529 +0,0 @@ | |||
1 | ;.lib "axm" | ||
2 | ; | ||
3 | ;begin | ||
4 | ;title "A2232 serial board driver" | ||
5 | ; | ||
6 | ;set modules "2232" | ||
7 | ;set executable "2232.bin" | ||
8 | ; | ||
9 | ;;;;set nolink | ||
10 | ; | ||
11 | ;set temporary directory "t:" | ||
12 | ; | ||
13 | ;set assembly options "-m6502 -l60:t:list" | ||
14 | ;set link options "bin"; loadadr" | ||
15 | ;;;bin2c 2232.bin msc6502.h msc6502code | ||
16 | ;end | ||
17 | ; | ||
18 | ; | ||
19 | ; ### Commodore A2232 serial board driver for NetBSD by JM v1.3 ### | ||
20 | ; | ||
21 | ; - Created 950501 by JM - | ||
22 | ; | ||
23 | ; | ||
24 | ; Serial board driver software. | ||
25 | ; | ||
26 | ; | ||
27 | % Copyright (c) 1995 Jukka Marin <jmarin@jmp.fi>. | ||
28 | % All rights reserved. | ||
29 | % | ||
30 | % Redistribution and use in source and binary forms, with or without | ||
31 | % modification, are permitted provided that the following conditions | ||
32 | % are met: | ||
33 | % 1. Redistributions of source code must retain the above copyright | ||
34 | % notice, and the entire permission notice in its entirety, | ||
35 | % including the disclaimer of warranties. | ||
36 | % 2. Redistributions in binary form must reproduce the above copyright | ||
37 | % notice, this list of conditions and the following disclaimer in the | ||
38 | % documentation and/or other materials provided with the distribution. | ||
39 | % 3. The name of the author may not be used to endorse or promote | ||
40 | % products derived from this software without specific prior | ||
41 | % written permission. | ||
42 | % | ||
43 | % ALTERNATIVELY, this product may be distributed under the terms of | ||
44 | % the GNU General Public License, in which case the provisions of the | ||
45 | % GPL are required INSTEAD OF the above restrictions. (This clause is | ||
46 | % necessary due to a potential bad interaction between the GPL and | ||
47 | % the restrictions contained in a BSD-style copyright.) | ||
48 | % | ||
49 | % THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED | ||
50 | % WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
51 | % OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
52 | % DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | ||
53 | % INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
54 | % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
55 | % SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
56 | % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
57 | % STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
58 | % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
59 | % OF THE POSSIBILITY OF SUCH DAMAGE. | ||
60 | ; | ||
61 | ; | ||
62 | ; Bugs: | ||
63 | ; | ||
64 | ; - Can't send a break yet | ||
65 | ; | ||
66 | ; | ||
67 | ; | ||
68 | ; Edited: | ||
69 | ; | ||
70 | ; - 950501 by JM -> v0.1 - Created this file. | ||
71 | ; - 951029 by JM -> v1.3 - Carrier Detect events now queued in a separate | ||
72 | ; queue. | ||
73 | ; | ||
74 | ; | ||
75 | |||
76 | |||
77 | CODE equ $3800 ; start address for program code | ||
78 | |||
79 | |||
80 | CTL_CHAR equ $00 ; byte in ibuf is a character | ||
81 | CTL_EVENT equ $01 ; byte in ibuf is an event | ||
82 | |||
83 | EVENT_BREAK equ $01 | ||
84 | EVENT_CDON equ $02 | ||
85 | EVENT_CDOFF equ $03 | ||
86 | EVENT_SYNC equ $04 | ||
87 | |||
88 | XON equ $11 | ||
89 | XOFF equ $13 | ||
90 | |||
91 | |||
92 | VARBASE macro *starting_address ; was VARINIT | ||
93 | _varbase set \1 | ||
94 | endm | ||
95 | |||
96 | VARDEF macro *name space_needs | ||
97 | \1 equ _varbase | ||
98 | _varbase set _varbase+\2 | ||
99 | endm | ||
100 | |||
101 | |||
102 | stz macro * address | ||
103 | db $64,\1 | ||
104 | endm | ||
105 | |||
106 | stzax macro * address | ||
107 | db $9e,<\1,>\1 | ||
108 | endm | ||
109 | |||
110 | |||
111 | biti macro * immediate value | ||
112 | db $89,\1 | ||
113 | endm | ||
114 | |||
115 | smb0 macro * address | ||
116 | db $87,\1 | ||
117 | endm | ||
118 | smb1 macro * address | ||
119 | db $97,\1 | ||
120 | endm | ||
121 | smb2 macro * address | ||
122 | db $a7,\1 | ||
123 | endm | ||
124 | smb3 macro * address | ||
125 | db $b7,\1 | ||
126 | endm | ||
127 | smb4 macro * address | ||
128 | db $c7,\1 | ||
129 | endm | ||
130 | smb5 macro * address | ||
131 | db $d7,\1 | ||
132 | endm | ||
133 | smb6 macro * address | ||
134 | db $e7,\1 | ||
135 | endm | ||
136 | smb7 macro * address | ||
137 | db $f7,\1 | ||
138 | endm | ||
139 | |||
140 | |||
141 | |||
142 | ;-----------------------------------------------------------------------; | ||
143 | ; ; | ||
144 | ; stuff common for all ports, non-critical (run once / loop) ; | ||
145 | ; ; | ||
146 | DO_SLOW macro * port_number ; | ||
147 | .local ; ; | ||
148 | lda CIA+C_PA ; check all CD inputs ; | ||
149 | cmp CommonCDo ; changed from previous accptd? ; | ||
150 | beq =over ; nope, do nothing else here ; | ||
151 | ; ; | ||
152 | cmp CommonCDb ; bouncing? ; | ||
153 | beq =nobounce ; nope -> ; | ||
154 | ; ; | ||
155 | sta CommonCDb ; save current state ; | ||
156 | lda #64 ; reinitialize counter ; | ||
157 | sta CommonCDc ; ; | ||
158 | jmp =over ; skip CD save ; | ||
159 | ; ; | ||
160 | =nobounce dec CommonCDc ; no, decrement bounce counter ; | ||
161 | bpl =over ; not done yet, so skip CD save ; | ||
162 | ; ; | ||
163 | =saveCD ldx CDHead ; get write index ; | ||
164 | sta cdbuf,x ; save status in buffer ; | ||
165 | inx ; ; | ||
166 | cpx CDTail ; buffer full? ; | ||
167 | .if ne ; no: preserve status: ; | ||
168 | stx CDHead ; update index in RAM ; | ||
169 | sta CommonCDo ; save state for the next check ; | ||
170 | .end ; ; | ||
171 | =over .end local ; | ||
172 | endm ; | ||
173 | ; | ||
174 | ;-----------------------------------------------------------------------; | ||
175 | |||
176 | |||
177 | ; port specific stuff (no data transfer) | ||
178 | |||
179 | DO_PORT macro * port_number | ||
180 | .local ; ; | ||
181 | lda SetUp\1 ; reconfiguration request? ; | ||
182 | .if ne ; yes: ; | ||
183 | lda SoftFlow\1 ; get XON/XOFF flag ; | ||
184 | sta XonOff\1 ; save it ; | ||
185 | lda Param\1 ; get parameter ; | ||
186 | ora #%00010000 ; use baud generator for Rx ; | ||
187 | sta ACIA\1+A_CTRL ; store in control register ; | ||
188 | stz OutDisable\1 ; enable transmit output ; | ||
189 | stz SetUp\1 ; no reconfiguration no more ; | ||
190 | .end ; ; | ||
191 | ; ; | ||
192 | lda InHead\1 ; get write index ; | ||
193 | sbc InTail\1 ; buffer full soon? ; | ||
194 | cmp #200 ; 200 chars or more in buffer? ; | ||
195 | lda Command\1 ; get Command reg value ; | ||
196 | and #%11110011 ; turn RTS OFF by default ; | ||
197 | .if cc ; still room in buffer: ; | ||
198 | ora #%00001000 ; turn RTS ON ; | ||
199 | .end ; ; | ||
200 | sta ACIA\1+A_CMD ; set/clear RTS ; | ||
201 | ; ; | ||
202 | lda OutFlush\1 ; request to flush output buffer; | ||
203 | .if ne ; yessh! ; | ||
204 | lda OutHead\1 ; get head ; | ||
205 | sta OutTail\1 ; save as tail ; | ||
206 | stz OutDisable\1 ; enable transmit output ; | ||
207 | stz OutFlush\1 ; clear request ; | ||
208 | .end | ||
209 | .end local | ||
210 | endm | ||
211 | |||
212 | |||
213 | DO_DATA macro * port number | ||
214 | .local | ||
215 | lda ACIA\1+A_SR ; read ACIA status register ; | ||
216 | biti [1<<3] ; something received? ; | ||
217 | .if ne ; yes: ; | ||
218 | biti [1<<1] ; framing error? ; | ||
219 | .if ne ; yes: ; | ||
220 | lda ACIA\1+A_DATA ; read received character ; | ||
221 | bne =SEND ; not break -> ignore it ; | ||
222 | ldx InHead\1 ; get write pointer ; | ||
223 | lda #CTL_EVENT ; get type of byte ; | ||
224 | sta ictl\1,x ; save it in InCtl buffer ; | ||
225 | lda #EVENT_BREAK ; event code ; | ||
226 | sta ibuf\1,x ; save it as well ; | ||
227 | inx ; ; | ||
228 | cpx InTail\1 ; still room in buffer? ; | ||
229 | .if ne ; absolutely: ; | ||
230 | stx InHead\1 ; update index in memory ; | ||
231 | .end ; ; | ||
232 | jmp =SEND ; go check if anything to send ; | ||
233 | .end ; ; | ||
234 | ; normal char received: ; | ||
235 | ldx InHead\1 ; get write index ; | ||
236 | lda ACIA\1+A_DATA ; read received character ; | ||
237 | sta ibuf\1,x ; save char in buffer ; | ||
238 | stzax ictl\1 ; set type to CTL_CHAR ; | ||
239 | inx ; ; | ||
240 | cpx InTail\1 ; buffer full? ; | ||
241 | .if ne ; no: preserve character: ; | ||
242 | stx InHead\1 ; update index in RAM ; | ||
243 | .end ; ; | ||
244 | and #$7f ; mask off parity if any ; | ||
245 | cmp #XOFF ; XOFF from remote host? ; | ||
246 | .if eq ; yes: ; | ||
247 | lda XonOff\1 ; if XON/XOFF handshaking.. ; | ||
248 | sta OutDisable\1 ; ..disable transmitter ; | ||
249 | .end ; ; | ||
250 | .end ; ; | ||
251 | ; ; | ||
252 | ; BUFFER FULL CHECK WAS HERE ; | ||
253 | ; ; | ||
254 | =SEND lda ACIA\1+A_SR ; transmit register empty? ; | ||
255 | and #[1<<4] ; ; | ||
256 | .if ne ; yes: ; | ||
257 | ldx OutCtrl\1 ; sending out XON/XOFF? ; | ||
258 | .if ne ; yes: ; | ||
259 | lda CIA+C_PB ; check CTS signal ; | ||
260 | and #[1<<\1] ; (for this port only) ; | ||
261 | bne =DONE ; not allowed to send -> done ; | ||
262 | stx ACIA\1+A_DATA ; transmit control char ; | ||
263 | stz OutCtrl\1 ; clear flag ; | ||
264 | jmp =DONE ; and we're done ; | ||
265 | .end ; ; | ||
266 | ; ; | ||
267 | ldx OutTail\1 ; anything to transmit? ; | ||
268 | cpx OutHead\1 ; ; | ||
269 | .if ne ; yes: ; | ||
270 | lda OutDisable\1 ; allowed to transmit? ; | ||
271 | .if eq ; yes: ; | ||
272 | lda CIA+C_PB ; check CTS signal ; | ||
273 | and #[1<<\1] ; (for this port only) ; | ||
274 | bne =DONE ; not allowed to send -> done ; | ||
275 | lda obuf\1,x ; get a char from buffer ; | ||
276 | sta ACIA\1+A_DATA ; send it away ; | ||
277 | inc OutTail\1 ; update read index ; | ||
278 | .end ; ; | ||
279 | .end ; ; | ||
280 | .end ; ; | ||
281 | =DONE .end local | ||
282 | endm | ||
283 | |||
284 | |||
285 | |||
286 | PORTVAR macro * port number | ||
287 | VARDEF InHead\1 1 | ||
288 | VARDEF InTail\1 1 | ||
289 | VARDEF OutDisable\1 1 | ||
290 | VARDEF OutHead\1 1 | ||
291 | VARDEF OutTail\1 1 | ||
292 | VARDEF OutCtrl\1 1 | ||
293 | VARDEF OutFlush\1 1 | ||
294 | VARDEF SetUp\1 1 | ||
295 | VARDEF Param\1 1 | ||
296 | VARDEF Command\1 1 | ||
297 | VARDEF SoftFlow\1 1 | ||
298 | ; private: | ||
299 | VARDEF XonOff\1 1 | ||
300 | endm | ||
301 | |||
302 | |||
303 | VARBASE 0 ; start variables at address $0000 | ||
304 | PORTVAR 0 ; define variables for port 0 | ||
305 | PORTVAR 1 ; define variables for port 1 | ||
306 | PORTVAR 2 ; define variables for port 2 | ||
307 | PORTVAR 3 ; define variables for port 3 | ||
308 | PORTVAR 4 ; define variables for port 4 | ||
309 | PORTVAR 5 ; define variables for port 5 | ||
310 | PORTVAR 6 ; define variables for port 6 | ||
311 | |||
312 | |||
313 | |||
314 | VARDEF Crystal 1 ; 0 = unknown, 1 = normal, 2 = turbo | ||
315 | VARDEF Pad_a 1 | ||
316 | VARDEF TimerH 1 | ||
317 | VARDEF TimerL 1 | ||
318 | VARDEF CDHead 1 | ||
319 | VARDEF CDTail 1 | ||
320 | VARDEF CDStatus 1 | ||
321 | VARDEF Pad_b 1 | ||
322 | |||
323 | VARDEF CommonCDo 1 ; for carrier detect optimization | ||
324 | VARDEF CommonCDc 1 ; for carrier detect debouncing | ||
325 | VARDEF CommonCDb 1 ; for carrier detect debouncing | ||
326 | |||
327 | |||
328 | VARBASE $0200 | ||
329 | VARDEF obuf0 256 ; output data (characters only) | ||
330 | VARDEF obuf1 256 | ||
331 | VARDEF obuf2 256 | ||
332 | VARDEF obuf3 256 | ||
333 | VARDEF obuf4 256 | ||
334 | VARDEF obuf5 256 | ||
335 | VARDEF obuf6 256 | ||
336 | |||
337 | VARDEF ibuf0 256 ; input data (characters, events etc - see ictl) | ||
338 | VARDEF ibuf1 256 | ||
339 | VARDEF ibuf2 256 | ||
340 | VARDEF ibuf3 256 | ||
341 | VARDEF ibuf4 256 | ||
342 | VARDEF ibuf5 256 | ||
343 | VARDEF ibuf6 256 | ||
344 | |||
345 | VARDEF ictl0 256 ; input control information (type of data in ibuf) | ||
346 | VARDEF ictl1 256 | ||
347 | VARDEF ictl2 256 | ||
348 | VARDEF ictl3 256 | ||
349 | VARDEF ictl4 256 | ||
350 | VARDEF ictl5 256 | ||
351 | VARDEF ictl6 256 | ||
352 | |||
353 | VARDEF cdbuf 256 ; CD event queue | ||
354 | |||
355 | |||
356 | ACIA0 equ $4400 | ||
357 | ACIA1 equ $4c00 | ||
358 | ACIA2 equ $5400 | ||
359 | ACIA3 equ $5c00 | ||
360 | ACIA4 equ $6400 | ||
361 | ACIA5 equ $6c00 | ||
362 | ACIA6 equ $7400 | ||
363 | |||
364 | A_DATA equ $00 | ||
365 | A_SR equ $02 | ||
366 | A_CMD equ $04 | ||
367 | A_CTRL equ $06 | ||
368 | ; 00 write transmit data read received data | ||
369 | ; 02 reset ACIA read status register | ||
370 | ; 04 write command register read command register | ||
371 | ; 06 write control register read control register | ||
372 | |||
373 | CIA equ $7c00 ; 8520 CIA | ||
374 | C_PA equ $00 ; port A data register | ||
375 | C_PB equ $02 ; port B data register | ||
376 | C_DDRA equ $04 ; data direction register for port A | ||
377 | C_DDRB equ $06 ; data direction register for port B | ||
378 | C_TAL equ $08 ; timer A | ||
379 | C_TAH equ $0a | ||
380 | C_TBL equ $0c ; timer B | ||
381 | C_TBH equ $0e | ||
382 | C_TODL equ $10 ; TOD LSB | ||
383 | C_TODM equ $12 ; TOD middle byte | ||
384 | C_TODH equ $14 ; TOD MSB | ||
385 | C_DATA equ $18 ; serial data register | ||
386 | C_INTCTRL equ $1a ; interrupt control register | ||
387 | C_CTRLA equ $1c ; control register A | ||
388 | C_CTRLB equ $1e ; control register B | ||
389 | |||
390 | |||
391 | |||
392 | |||
393 | |||
394 | section main,code,CODE-2 | ||
395 | |||
396 | db >CODE,<CODE | ||
397 | |||
398 | ;-----------------------------------------------------------------------; | ||
399 | ; here's the initialization code: ; | ||
400 | ; ; | ||
401 | R_RESET ldx #$ff ; | ||
402 | txs ; initialize stack pointer ; | ||
403 | cld ; in case a 6502 is used... ; | ||
404 | ldx #0 ; ; | ||
405 | lda #0 ; ; | ||
406 | ldy #Crystal ; this many bytes to clear ; | ||
407 | clr_loop sta 0,x ; clear zero page variables ; | ||
408 | inx ; ; | ||
409 | dey ; ; | ||
410 | bne clr_loop ; ; | ||
411 | ; ; | ||
412 | stz CommonCDo ; force CD test at boot ; | ||
413 | stz CommonCDb ; ; | ||
414 | stz CDHead ; clear queue ; | ||
415 | stz CDTail ; ; | ||
416 | ; ; | ||
417 | lda #0 ; ; | ||
418 | sta Pad_a ; ; | ||
419 | lda #170 ; test cmp ; | ||
420 | cmp #100 ; ; | ||
421 | .if cs ; ; | ||
422 | inc Pad_a ; C was set ; | ||
423 | .end ; ; | ||
424 | ; | ||
425 | ;-----------------------------------------------------------------------; | ||
426 | ; Speed check ; | ||
427 | ;-----------------------------------------------------------------------; | ||
428 | ; | ||
429 | lda Crystal ; speed already set? ; | ||
430 | beq DoSpeedy ; ; | ||
431 | jmp LOOP ; yes, skip speed test ; | ||
432 | ; ; | ||
433 | DoSpeedy lda #%10011000 ; 8N1, 1200/2400 bps ; | ||
434 | sta ACIA0+A_CTRL ; ; | ||
435 | lda #%00001011 ; enable DTR ; | ||
436 | sta ACIA0+A_CMD ; ; | ||
437 | lda ACIA0+A_SR ; read status register ; | ||
438 | ; ; | ||
439 | lda #%10000000 ; disable all ints (unnecessary); | ||
440 | sta CIA+C_INTCTRL ; ; | ||
441 | lda #255 ; program the timer ; | ||
442 | sta CIA+C_TAL ; ; | ||
443 | sta CIA+C_TAH ; ; | ||
444 | ; ; | ||
445 | ldx #0 ; ; | ||
446 | stx ACIA0+A_DATA ; transmit a zero ; | ||
447 | nop ; ; | ||
448 | nop ; ; | ||
449 | lda ACIA0+A_SR ; read status ; | ||
450 | nop ; ; | ||
451 | nop ; ; | ||
452 | stx ACIA0+A_DATA ; transmit a zero ; | ||
453 | Speedy1 lda ACIA0+A_SR ; read status ; | ||
454 | and #[1<<4] ; transmit data reg empty? ; | ||
455 | beq Speedy1 ; not yet, wait more ; | ||
456 | ; ; | ||
457 | lda #%00010001 ; load & start the timer ; | ||
458 | stx ACIA0+A_DATA ; transmit one more zero ; | ||
459 | sta CIA+C_CTRLA ; ; | ||
460 | Speedy2 lda ACIA0+A_SR ; read status ; | ||
461 | and #[1<<4] ; transmit data reg empty? ; | ||
462 | beq Speedy2 ; not yet, wait more ; | ||
463 | stx CIA+C_CTRLA ; stop the timer ; | ||
464 | ; ; | ||
465 | lda CIA+C_TAL ; copy timer value for 68k ; | ||
466 | sta TimerL ; ; | ||
467 | lda CIA+C_TAH ; ; | ||
468 | sta TimerH ; ; | ||
469 | cmp #$d0 ; turbo or normal? ; | ||
470 | .if cs ; ; | ||
471 | lda #2 ; turbo! :-) ; | ||
472 | .else ; ; | ||
473 | lda #1 ; normal :-( ; | ||
474 | .end ; ; | ||
475 | sta Crystal ; ; | ||
476 | lda #0 ; ; | ||
477 | sta ACIA0+A_SR ; ; | ||
478 | sta ACIA0+A_CTRL ; reset UART ; | ||
479 | sta ACIA0+A_CMD ; ; | ||
480 | ; | ||
481 | jmp LOOP ; | ||
482 | ; | ||
483 | ; ; | ||
484 | ;-----------------------------------------------------------------------; | ||
485 | ; ; | ||
486 | ; The Real Thing: ; | ||
487 | ; ; | ||
488 | LOOP DO_SLOW ; do non-critical things ; | ||
489 | jsr do_input ; check for received data | ||
490 | DO_PORT 0 | ||
491 | jsr do_input | ||
492 | DO_PORT 1 | ||
493 | jsr do_input | ||
494 | DO_PORT 2 | ||
495 | jsr do_input | ||
496 | DO_PORT 3 | ||
497 | jsr do_input | ||
498 | DO_PORT 4 | ||
499 | jsr do_input | ||
500 | DO_PORT 5 | ||
501 | jsr do_input | ||
502 | DO_PORT 6 | ||
503 | jsr do_input | ||
504 | jmp LOOP | ||
505 | |||
506 | |||
507 | do_input DO_DATA 0 | ||
508 | DO_DATA 1 | ||
509 | DO_DATA 2 | ||
510 | DO_DATA 3 | ||
511 | DO_DATA 4 | ||
512 | DO_DATA 5 | ||
513 | DO_DATA 6 | ||
514 | rts | ||
515 | |||
516 | |||
517 | ;-----------------------------------------------------------------------; | ||
518 | section vectors,data,$3ffa | ||
519 | dw $d0d0 | ||
520 | dw R_RESET | ||
521 | dw $c0ce | ||
522 | ;-----------------------------------------------------------------------; | ||
523 | |||
524 | |||
525 | |||
526 | end | ||
527 | |||
528 | |||
529 | |||
diff --git a/drivers/char/ser_a2232fw.h b/drivers/char/ser_a2232fw.h deleted file mode 100644 index e09a30acfe5c..000000000000 --- a/drivers/char/ser_a2232fw.h +++ /dev/null | |||
@@ -1,306 +0,0 @@ | |||
1 | /* drivers/char/ser_a2232fw.h */ | ||
2 | |||
3 | /* $Id: ser_a2232fw.h,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ | ||
4 | |||
5 | /* | ||
6 | * Copyright (c) 1995 Jukka Marin <jmarin@jmp.fi>. | ||
7 | * All rights reserved. | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, and the entire permission notice in its entirety, | ||
14 | * including the disclaimer of warranties. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. The name of the author may not be used to endorse or promote | ||
19 | * products derived from this software without specific prior | ||
20 | * written permission. | ||
21 | * | ||
22 | * ALTERNATIVELY, this product may be distributed under the terms of | ||
23 | * the GNU Public License, in which case the provisions of the GPL are | ||
24 | * required INSTEAD OF the above restrictions. (This clause is | ||
25 | * necessary due to a potential bad interaction between the GPL and | ||
26 | * the restrictions contained in a BSD-style copyright.) | ||
27 | * | ||
28 | * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED | ||
29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
30 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
31 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | ||
32 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
33 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
34 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
37 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
38 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
39 | * | ||
40 | */ | ||
41 | |||
42 | /* This is the 65EC02 code by Jukka Marin that is executed by | ||
43 | the A2232's 65EC02 processor (base address: 0x3800) | ||
44 | Source file: ser_a2232fw.ax | ||
45 | Version: 1.3 (951029) | ||
46 | Known Bugs: Cannot send a break yet | ||
47 | */ | ||
48 | static unsigned char a2232_65EC02code[] = { | ||
49 | 0x38, 0x00, 0xA2, 0xFF, 0x9A, 0xD8, 0xA2, 0x00, | ||
50 | 0xA9, 0x00, 0xA0, 0x54, 0x95, 0x00, 0xE8, 0x88, | ||
51 | 0xD0, 0xFA, 0x64, 0x5C, 0x64, 0x5E, 0x64, 0x58, | ||
52 | 0x64, 0x59, 0xA9, 0x00, 0x85, 0x55, 0xA9, 0xAA, | ||
53 | 0xC9, 0x64, 0x90, 0x02, 0xE6, 0x55, 0xA5, 0x54, | ||
54 | 0xF0, 0x03, 0x4C, 0x92, 0x38, 0xA9, 0x98, 0x8D, | ||
55 | 0x06, 0x44, 0xA9, 0x0B, 0x8D, 0x04, 0x44, 0xAD, | ||
56 | 0x02, 0x44, 0xA9, 0x80, 0x8D, 0x1A, 0x7C, 0xA9, | ||
57 | 0xFF, 0x8D, 0x08, 0x7C, 0x8D, 0x0A, 0x7C, 0xA2, | ||
58 | 0x00, 0x8E, 0x00, 0x44, 0xEA, 0xEA, 0xAD, 0x02, | ||
59 | 0x44, 0xEA, 0xEA, 0x8E, 0x00, 0x44, 0xAD, 0x02, | ||
60 | 0x44, 0x29, 0x10, 0xF0, 0xF9, 0xA9, 0x11, 0x8E, | ||
61 | 0x00, 0x44, 0x8D, 0x1C, 0x7C, 0xAD, 0x02, 0x44, | ||
62 | 0x29, 0x10, 0xF0, 0xF9, 0x8E, 0x1C, 0x7C, 0xAD, | ||
63 | 0x08, 0x7C, 0x85, 0x57, 0xAD, 0x0A, 0x7C, 0x85, | ||
64 | 0x56, 0xC9, 0xD0, 0x90, 0x05, 0xA9, 0x02, 0x4C, | ||
65 | 0x82, 0x38, 0xA9, 0x01, 0x85, 0x54, 0xA9, 0x00, | ||
66 | 0x8D, 0x02, 0x44, 0x8D, 0x06, 0x44, 0x8D, 0x04, | ||
67 | 0x44, 0x4C, 0x92, 0x38, 0xAD, 0x00, 0x7C, 0xC5, | ||
68 | 0x5C, 0xF0, 0x1F, 0xC5, 0x5E, 0xF0, 0x09, 0x85, | ||
69 | 0x5E, 0xA9, 0x40, 0x85, 0x5D, 0x4C, 0xB8, 0x38, | ||
70 | 0xC6, 0x5D, 0x10, 0x0E, 0xA6, 0x58, 0x9D, 0x00, | ||
71 | 0x17, 0xE8, 0xE4, 0x59, 0xF0, 0x04, 0x86, 0x58, | ||
72 | 0x85, 0x5C, 0x20, 0x23, 0x3A, 0xA5, 0x07, 0xF0, | ||
73 | 0x0F, 0xA5, 0x0A, 0x85, 0x0B, 0xA5, 0x08, 0x09, | ||
74 | 0x10, 0x8D, 0x06, 0x44, 0x64, 0x02, 0x64, 0x07, | ||
75 | 0xA5, 0x00, 0xE5, 0x01, 0xC9, 0xC8, 0xA5, 0x09, | ||
76 | 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, | ||
77 | 0x44, 0xA5, 0x06, 0xF0, 0x08, 0xA5, 0x03, 0x85, | ||
78 | 0x04, 0x64, 0x02, 0x64, 0x06, 0x20, 0x23, 0x3A, | ||
79 | 0xA5, 0x13, 0xF0, 0x0F, 0xA5, 0x16, 0x85, 0x17, | ||
80 | 0xA5, 0x14, 0x09, 0x10, 0x8D, 0x06, 0x4C, 0x64, | ||
81 | 0x0E, 0x64, 0x13, 0xA5, 0x0C, 0xE5, 0x0D, 0xC9, | ||
82 | 0xC8, 0xA5, 0x15, 0x29, 0xF3, 0xB0, 0x02, 0x09, | ||
83 | 0x08, 0x8D, 0x04, 0x4C, 0xA5, 0x12, 0xF0, 0x08, | ||
84 | 0xA5, 0x0F, 0x85, 0x10, 0x64, 0x0E, 0x64, 0x12, | ||
85 | 0x20, 0x23, 0x3A, 0xA5, 0x1F, 0xF0, 0x0F, 0xA5, | ||
86 | 0x22, 0x85, 0x23, 0xA5, 0x20, 0x09, 0x10, 0x8D, | ||
87 | 0x06, 0x54, 0x64, 0x1A, 0x64, 0x1F, 0xA5, 0x18, | ||
88 | 0xE5, 0x19, 0xC9, 0xC8, 0xA5, 0x21, 0x29, 0xF3, | ||
89 | 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x54, 0xA5, | ||
90 | 0x1E, 0xF0, 0x08, 0xA5, 0x1B, 0x85, 0x1C, 0x64, | ||
91 | 0x1A, 0x64, 0x1E, 0x20, 0x23, 0x3A, 0xA5, 0x2B, | ||
92 | 0xF0, 0x0F, 0xA5, 0x2E, 0x85, 0x2F, 0xA5, 0x2C, | ||
93 | 0x09, 0x10, 0x8D, 0x06, 0x5C, 0x64, 0x26, 0x64, | ||
94 | 0x2B, 0xA5, 0x24, 0xE5, 0x25, 0xC9, 0xC8, 0xA5, | ||
95 | 0x2D, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, | ||
96 | 0x04, 0x5C, 0xA5, 0x2A, 0xF0, 0x08, 0xA5, 0x27, | ||
97 | 0x85, 0x28, 0x64, 0x26, 0x64, 0x2A, 0x20, 0x23, | ||
98 | 0x3A, 0xA5, 0x37, 0xF0, 0x0F, 0xA5, 0x3A, 0x85, | ||
99 | 0x3B, 0xA5, 0x38, 0x09, 0x10, 0x8D, 0x06, 0x64, | ||
100 | 0x64, 0x32, 0x64, 0x37, 0xA5, 0x30, 0xE5, 0x31, | ||
101 | 0xC9, 0xC8, 0xA5, 0x39, 0x29, 0xF3, 0xB0, 0x02, | ||
102 | 0x09, 0x08, 0x8D, 0x04, 0x64, 0xA5, 0x36, 0xF0, | ||
103 | 0x08, 0xA5, 0x33, 0x85, 0x34, 0x64, 0x32, 0x64, | ||
104 | 0x36, 0x20, 0x23, 0x3A, 0xA5, 0x43, 0xF0, 0x0F, | ||
105 | 0xA5, 0x46, 0x85, 0x47, 0xA5, 0x44, 0x09, 0x10, | ||
106 | 0x8D, 0x06, 0x6C, 0x64, 0x3E, 0x64, 0x43, 0xA5, | ||
107 | 0x3C, 0xE5, 0x3D, 0xC9, 0xC8, 0xA5, 0x45, 0x29, | ||
108 | 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x6C, | ||
109 | 0xA5, 0x42, 0xF0, 0x08, 0xA5, 0x3F, 0x85, 0x40, | ||
110 | 0x64, 0x3E, 0x64, 0x42, 0x20, 0x23, 0x3A, 0xA5, | ||
111 | 0x4F, 0xF0, 0x0F, 0xA5, 0x52, 0x85, 0x53, 0xA5, | ||
112 | 0x50, 0x09, 0x10, 0x8D, 0x06, 0x74, 0x64, 0x4A, | ||
113 | 0x64, 0x4F, 0xA5, 0x48, 0xE5, 0x49, 0xC9, 0xC8, | ||
114 | 0xA5, 0x51, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, | ||
115 | 0x8D, 0x04, 0x74, 0xA5, 0x4E, 0xF0, 0x08, 0xA5, | ||
116 | 0x4B, 0x85, 0x4C, 0x64, 0x4A, 0x64, 0x4E, 0x20, | ||
117 | 0x23, 0x3A, 0x4C, 0x92, 0x38, 0xAD, 0x02, 0x44, | ||
118 | 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, | ||
119 | 0xAD, 0x00, 0x44, 0xD0, 0x32, 0xA6, 0x00, 0xA9, | ||
120 | 0x01, 0x9D, 0x00, 0x10, 0xA9, 0x01, 0x9D, 0x00, | ||
121 | 0x09, 0xE8, 0xE4, 0x01, 0xF0, 0x02, 0x86, 0x00, | ||
122 | 0x4C, 0x65, 0x3A, 0xA6, 0x00, 0xAD, 0x00, 0x44, | ||
123 | 0x9D, 0x00, 0x09, 0x9E, 0x00, 0x10, 0xE8, 0xE4, | ||
124 | 0x01, 0xF0, 0x02, 0x86, 0x00, 0x29, 0x7F, 0xC9, | ||
125 | 0x13, 0xD0, 0x04, 0xA5, 0x0B, 0x85, 0x02, 0xAD, | ||
126 | 0x02, 0x44, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x05, | ||
127 | 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, 0xD0, | ||
128 | 0x21, 0x8E, 0x00, 0x44, 0x64, 0x05, 0x4C, 0x98, | ||
129 | 0x3A, 0xA6, 0x04, 0xE4, 0x03, 0xF0, 0x13, 0xA5, | ||
130 | 0x02, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, | ||
131 | 0xD0, 0x08, 0xBD, 0x00, 0x02, 0x8D, 0x00, 0x44, | ||
132 | 0xE6, 0x04, 0xAD, 0x02, 0x4C, 0x89, 0x08, 0xF0, | ||
133 | 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x4C, | ||
134 | 0xD0, 0x32, 0xA6, 0x0C, 0xA9, 0x01, 0x9D, 0x00, | ||
135 | 0x11, 0xA9, 0x01, 0x9D, 0x00, 0x0A, 0xE8, 0xE4, | ||
136 | 0x0D, 0xF0, 0x02, 0x86, 0x0C, 0x4C, 0xDA, 0x3A, | ||
137 | 0xA6, 0x0C, 0xAD, 0x00, 0x4C, 0x9D, 0x00, 0x0A, | ||
138 | 0x9E, 0x00, 0x11, 0xE8, 0xE4, 0x0D, 0xF0, 0x02, | ||
139 | 0x86, 0x0C, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, | ||
140 | 0xA5, 0x17, 0x85, 0x0E, 0xAD, 0x02, 0x4C, 0x29, | ||
141 | 0x10, 0xF0, 0x2C, 0xA6, 0x11, 0xF0, 0x0F, 0xAD, | ||
142 | 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x21, 0x8E, 0x00, | ||
143 | 0x4C, 0x64, 0x11, 0x4C, 0x0D, 0x3B, 0xA6, 0x10, | ||
144 | 0xE4, 0x0F, 0xF0, 0x13, 0xA5, 0x0E, 0xD0, 0x0F, | ||
145 | 0xAD, 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x08, 0xBD, | ||
146 | 0x00, 0x03, 0x8D, 0x00, 0x4C, 0xE6, 0x10, 0xAD, | ||
147 | 0x02, 0x54, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, | ||
148 | 0xF0, 0x1B, 0xAD, 0x00, 0x54, 0xD0, 0x32, 0xA6, | ||
149 | 0x18, 0xA9, 0x01, 0x9D, 0x00, 0x12, 0xA9, 0x01, | ||
150 | 0x9D, 0x00, 0x0B, 0xE8, 0xE4, 0x19, 0xF0, 0x02, | ||
151 | 0x86, 0x18, 0x4C, 0x4F, 0x3B, 0xA6, 0x18, 0xAD, | ||
152 | 0x00, 0x54, 0x9D, 0x00, 0x0B, 0x9E, 0x00, 0x12, | ||
153 | 0xE8, 0xE4, 0x19, 0xF0, 0x02, 0x86, 0x18, 0x29, | ||
154 | 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x23, 0x85, | ||
155 | 0x1A, 0xAD, 0x02, 0x54, 0x29, 0x10, 0xF0, 0x2C, | ||
156 | 0xA6, 0x1D, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, | ||
157 | 0x04, 0xD0, 0x21, 0x8E, 0x00, 0x54, 0x64, 0x1D, | ||
158 | 0x4C, 0x82, 0x3B, 0xA6, 0x1C, 0xE4, 0x1B, 0xF0, | ||
159 | 0x13, 0xA5, 0x1A, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, | ||
160 | 0x29, 0x04, 0xD0, 0x08, 0xBD, 0x00, 0x04, 0x8D, | ||
161 | 0x00, 0x54, 0xE6, 0x1C, 0xAD, 0x02, 0x5C, 0x89, | ||
162 | 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, | ||
163 | 0x00, 0x5C, 0xD0, 0x32, 0xA6, 0x24, 0xA9, 0x01, | ||
164 | 0x9D, 0x00, 0x13, 0xA9, 0x01, 0x9D, 0x00, 0x0C, | ||
165 | 0xE8, 0xE4, 0x25, 0xF0, 0x02, 0x86, 0x24, 0x4C, | ||
166 | 0xC4, 0x3B, 0xA6, 0x24, 0xAD, 0x00, 0x5C, 0x9D, | ||
167 | 0x00, 0x0C, 0x9E, 0x00, 0x13, 0xE8, 0xE4, 0x25, | ||
168 | 0xF0, 0x02, 0x86, 0x24, 0x29, 0x7F, 0xC9, 0x13, | ||
169 | 0xD0, 0x04, 0xA5, 0x2F, 0x85, 0x26, 0xAD, 0x02, | ||
170 | 0x5C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x29, 0xF0, | ||
171 | 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, 0x21, | ||
172 | 0x8E, 0x00, 0x5C, 0x64, 0x29, 0x4C, 0xF7, 0x3B, | ||
173 | 0xA6, 0x28, 0xE4, 0x27, 0xF0, 0x13, 0xA5, 0x26, | ||
174 | 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, | ||
175 | 0x08, 0xBD, 0x00, 0x05, 0x8D, 0x00, 0x5C, 0xE6, | ||
176 | 0x28, 0xAD, 0x02, 0x64, 0x89, 0x08, 0xF0, 0x3B, | ||
177 | 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x64, 0xD0, | ||
178 | 0x32, 0xA6, 0x30, 0xA9, 0x01, 0x9D, 0x00, 0x14, | ||
179 | 0xA9, 0x01, 0x9D, 0x00, 0x0D, 0xE8, 0xE4, 0x31, | ||
180 | 0xF0, 0x02, 0x86, 0x30, 0x4C, 0x39, 0x3C, 0xA6, | ||
181 | 0x30, 0xAD, 0x00, 0x64, 0x9D, 0x00, 0x0D, 0x9E, | ||
182 | 0x00, 0x14, 0xE8, 0xE4, 0x31, 0xF0, 0x02, 0x86, | ||
183 | 0x30, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, | ||
184 | 0x3B, 0x85, 0x32, 0xAD, 0x02, 0x64, 0x29, 0x10, | ||
185 | 0xF0, 0x2C, 0xA6, 0x35, 0xF0, 0x0F, 0xAD, 0x02, | ||
186 | 0x7C, 0x29, 0x10, 0xD0, 0x21, 0x8E, 0x00, 0x64, | ||
187 | 0x64, 0x35, 0x4C, 0x6C, 0x3C, 0xA6, 0x34, 0xE4, | ||
188 | 0x33, 0xF0, 0x13, 0xA5, 0x32, 0xD0, 0x0F, 0xAD, | ||
189 | 0x02, 0x7C, 0x29, 0x10, 0xD0, 0x08, 0xBD, 0x00, | ||
190 | 0x06, 0x8D, 0x00, 0x64, 0xE6, 0x34, 0xAD, 0x02, | ||
191 | 0x6C, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, | ||
192 | 0x1B, 0xAD, 0x00, 0x6C, 0xD0, 0x32, 0xA6, 0x3C, | ||
193 | 0xA9, 0x01, 0x9D, 0x00, 0x15, 0xA9, 0x01, 0x9D, | ||
194 | 0x00, 0x0E, 0xE8, 0xE4, 0x3D, 0xF0, 0x02, 0x86, | ||
195 | 0x3C, 0x4C, 0xAE, 0x3C, 0xA6, 0x3C, 0xAD, 0x00, | ||
196 | 0x6C, 0x9D, 0x00, 0x0E, 0x9E, 0x00, 0x15, 0xE8, | ||
197 | 0xE4, 0x3D, 0xF0, 0x02, 0x86, 0x3C, 0x29, 0x7F, | ||
198 | 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x47, 0x85, 0x3E, | ||
199 | 0xAD, 0x02, 0x6C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, | ||
200 | 0x41, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x20, | ||
201 | 0xD0, 0x21, 0x8E, 0x00, 0x6C, 0x64, 0x41, 0x4C, | ||
202 | 0xE1, 0x3C, 0xA6, 0x40, 0xE4, 0x3F, 0xF0, 0x13, | ||
203 | 0xA5, 0x3E, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, | ||
204 | 0x20, 0xD0, 0x08, 0xBD, 0x00, 0x07, 0x8D, 0x00, | ||
205 | 0x6C, 0xE6, 0x40, 0xAD, 0x02, 0x74, 0x89, 0x08, | ||
206 | 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, | ||
207 | 0x74, 0xD0, 0x32, 0xA6, 0x48, 0xA9, 0x01, 0x9D, | ||
208 | 0x00, 0x16, 0xA9, 0x01, 0x9D, 0x00, 0x0F, 0xE8, | ||
209 | 0xE4, 0x49, 0xF0, 0x02, 0x86, 0x48, 0x4C, 0x23, | ||
210 | 0x3D, 0xA6, 0x48, 0xAD, 0x00, 0x74, 0x9D, 0x00, | ||
211 | 0x0F, 0x9E, 0x00, 0x16, 0xE8, 0xE4, 0x49, 0xF0, | ||
212 | 0x02, 0x86, 0x48, 0x29, 0x7F, 0xC9, 0x13, 0xD0, | ||
213 | 0x04, 0xA5, 0x53, 0x85, 0x4A, 0xAD, 0x02, 0x74, | ||
214 | 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x4D, 0xF0, 0x0F, | ||
215 | 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x21, 0x8E, | ||
216 | 0x00, 0x74, 0x64, 0x4D, 0x4C, 0x56, 0x3D, 0xA6, | ||
217 | 0x4C, 0xE4, 0x4B, 0xF0, 0x13, 0xA5, 0x4A, 0xD0, | ||
218 | 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x08, | ||
219 | 0xBD, 0x00, 0x08, 0x8D, 0x00, 0x74, 0xE6, 0x4C, | ||
220 | 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
221 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
222 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
223 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
224 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
225 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
226 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
227 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
228 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
229 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
230 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
231 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
232 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
233 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
234 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
235 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
236 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
237 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
238 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
239 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
240 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
241 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
242 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
243 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
244 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
245 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
246 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
247 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
248 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
249 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
250 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
251 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
252 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
253 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
254 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
255 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
256 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
257 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
258 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
259 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
260 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
261 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
262 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
263 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
264 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
265 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
266 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
267 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
268 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
269 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
270 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
271 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
272 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
273 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
274 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
275 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
276 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
277 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
278 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
279 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
280 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
281 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
282 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
283 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
284 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
285 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
286 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
287 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
288 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
289 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
290 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
291 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
292 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
293 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
294 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
295 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
296 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
297 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
298 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
299 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
300 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
301 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
302 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
303 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
304 | 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xD0, 0x00, 0x38, | ||
305 | 0xCE, 0xC0, | ||
306 | }; | ||
diff --git a/drivers/char/sx.c b/drivers/char/sx.c deleted file mode 100644 index 1291462bcddb..000000000000 --- a/drivers/char/sx.c +++ /dev/null | |||
@@ -1,2894 +0,0 @@ | |||
1 | /* sx.c -- driver for the Specialix SX series cards. | ||
2 | * | ||
3 | * This driver will also support the older SI, and XIO cards. | ||
4 | * | ||
5 | * | ||
6 | * (C) 1998 - 2004 R.E.Wolff@BitWizard.nl | ||
7 | * | ||
8 | * Simon Allen (simonallen@cix.compulink.co.uk) wrote a previous | ||
9 | * version of this driver. Some fragments may have been copied. (none | ||
10 | * yet :-) | ||
11 | * | ||
12 | * Specialix pays for the development and support of this driver. | ||
13 | * Please DO contact support@specialix.co.uk if you require | ||
14 | * support. But please read the documentation (sx.txt) first. | ||
15 | * | ||
16 | * | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or | ||
19 | * modify it under the terms of the GNU General Public License as | ||
20 | * published by the Free Software Foundation; either version 2 of | ||
21 | * the License, or (at your option) any later version. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be | ||
24 | * useful, but WITHOUT ANY WARRANTY; without even the implied | ||
25 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
26 | * PURPOSE. See the GNU General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public | ||
29 | * License along with this program; if not, write to the Free | ||
30 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, | ||
31 | * USA. | ||
32 | * | ||
33 | * Revision history: | ||
34 | * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff | ||
35 | * - Fixed module and port counting | ||
36 | * - Fixed signal handling | ||
37 | * - Fixed an Ooops | ||
38 | * | ||
39 | * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl | ||
40 | * - Fixed some sx_dprintk typos | ||
41 | * - added detection for an invalid board/module configuration | ||
42 | * | ||
43 | * Revision 1.31 2000/03/06 12:00:00 wolff,pvdl | ||
44 | * - Added support for EISA | ||
45 | * | ||
46 | * Revision 1.30 2000/01/21 17:43:06 wolff | ||
47 | * - Added support for SX+ | ||
48 | * | ||
49 | * Revision 1.26 1999/08/05 15:22:14 wolff | ||
50 | * - Port to 2.3.x | ||
51 | * - Reformatted to Linus' liking. | ||
52 | * | ||
53 | * Revision 1.25 1999/07/30 14:24:08 wolff | ||
54 | * Had accidentally left "gs_debug" set to "-1" instead of "off" (=0). | ||
55 | * | ||
56 | * Revision 1.24 1999/07/28 09:41:52 wolff | ||
57 | * - I noticed the remark about use-count straying in sx.txt. I checked | ||
58 | * sx_open, and found a few places where that could happen. I hope it's | ||
59 | * fixed now. | ||
60 | * | ||
61 | * Revision 1.23 1999/07/28 08:56:06 wolff | ||
62 | * - Fixed crash when sx_firmware run twice. | ||
63 | * - Added sx_slowpoll as a module parameter (I guess nobody really wanted | ||
64 | * to change it from the default... ) | ||
65 | * - Fixed a stupid editing problem I introduced in 1.22. | ||
66 | * - Fixed dropping characters on a termios change. | ||
67 | * | ||
68 | * Revision 1.22 1999/07/26 21:01:43 wolff | ||
69 | * Russell Brown noticed that I had overlooked 4 out of six modem control | ||
70 | * signals in sx_getsignals. Ooops. | ||
71 | * | ||
72 | * Revision 1.21 1999/07/23 09:11:33 wolff | ||
73 | * I forgot to free dynamically allocated memory when the driver is unloaded. | ||
74 | * | ||
75 | * Revision 1.20 1999/07/20 06:25:26 wolff | ||
76 | * The "closing wait" wasn't honoured. Thanks to James Griffiths for | ||
77 | * reporting this. | ||
78 | * | ||
79 | * Revision 1.19 1999/07/11 08:59:59 wolff | ||
80 | * Fixed an oops in close, when an open was pending. Changed the memtest | ||
81 | * a bit. Should also test the board in word-mode, however my card fails the | ||
82 | * memtest then. I still have to figure out what is wrong... | ||
83 | * | ||
84 | * Revision 1.18 1999/06/10 09:38:42 wolff | ||
85 | * Changed the format of the firmware revision from %04x to %x.%02x . | ||
86 | * | ||
87 | * Revision 1.17 1999/06/04 09:44:35 wolff | ||
88 | * fixed problem: reference to pci stuff when config_pci was off... | ||
89 | * Thanks to Jorge Novo for noticing this. | ||
90 | * | ||
91 | * Revision 1.16 1999/06/02 08:30:15 wolff | ||
92 | * added/removed the workaround for the DCD bug in the Firmware. | ||
93 | * A bit more debugging code to locate that... | ||
94 | * | ||
95 | * Revision 1.15 1999/06/01 11:35:30 wolff | ||
96 | * when DCD is left low (floating?), on TA's the firmware first tells us | ||
97 | * that DCD is high, but after a short while suddenly comes to the | ||
98 | * conclusion that it is low. All this would be fine, if it weren't that | ||
99 | * Unix requires us to send a "hangup" signal in that case. This usually | ||
100 | * all happens BEFORE the program has had a chance to ioctl the device | ||
101 | * into clocal mode.. | ||
102 | * | ||
103 | * Revision 1.14 1999/05/25 11:18:59 wolff | ||
104 | * Added PCI-fix. | ||
105 | * Added checks for return code of sx_sendcommand. | ||
106 | * Don't issue "reconfig" if port isn't open yet. (bit us on TA modules...) | ||
107 | * | ||
108 | * Revision 1.13 1999/04/29 15:18:01 wolff | ||
109 | * Fixed an "oops" that showed on SuSE 6.0 systems. | ||
110 | * Activate DTR again after stty 0. | ||
111 | * | ||
112 | * Revision 1.12 1999/04/29 07:49:52 wolff | ||
113 | * Improved "stty 0" handling a bit. (used to change baud to 9600 assuming | ||
114 | * the connection would be dropped anyway. That is not always the case, | ||
115 | * and confuses people). | ||
116 | * Told the card to always monitor the modem signals. | ||
117 | * Added support for dynamic gs_debug adjustments. | ||
118 | * Now tells the rest of the system the number of ports. | ||
119 | * | ||
120 | * Revision 1.11 1999/04/24 11:11:30 wolff | ||
121 | * Fixed two stupid typos in the memory test. | ||
122 | * | ||
123 | * Revision 1.10 1999/04/24 10:53:39 wolff | ||
124 | * Added some of Christian's suggestions. | ||
125 | * Fixed an HW_COOK_IN bug (ISIG was not in I_OTHER. We used to trust the | ||
126 | * card to send the signal to the process.....) | ||
127 | * | ||
128 | * Revision 1.9 1999/04/23 07:26:38 wolff | ||
129 | * Included Christian Lademann's 2.0 compile-warning fixes and interrupt | ||
130 | * assignment redesign. | ||
131 | * Cleanup of some other stuff. | ||
132 | * | ||
133 | * Revision 1.8 1999/04/16 13:05:30 wolff | ||
134 | * fixed a DCD change unnoticed bug. | ||
135 | * | ||
136 | * Revision 1.7 1999/04/14 22:19:51 wolff | ||
137 | * Fixed typo that showed up in 2.0.x builds (get_user instead of Get_user!) | ||
138 | * | ||
139 | * Revision 1.6 1999/04/13 18:40:20 wolff | ||
140 | * changed misc-minor to 161, as assigned by HPA. | ||
141 | * | ||
142 | * Revision 1.5 1999/04/13 15:12:25 wolff | ||
143 | * Fixed use-count leak when "hangup" occurred. | ||
144 | * Added workaround for a stupid-PCIBIOS bug. | ||
145 | * | ||
146 | * | ||
147 | * Revision 1.4 1999/04/01 22:47:40 wolff | ||
148 | * Fixed < 1M linux-2.0 problem. | ||
149 | * (vremap isn't compatible with ioremap in that case) | ||
150 | * | ||
151 | * Revision 1.3 1999/03/31 13:45:45 wolff | ||
152 | * Firmware loading is now done through a separate IOCTL. | ||
153 | * | ||
154 | * Revision 1.2 1999/03/28 12:22:29 wolff | ||
155 | * rcs cleanup | ||
156 | * | ||
157 | * Revision 1.1 1999/03/28 12:10:34 wolff | ||
158 | * Readying for release on 2.0.x (sorry David, 1.01 becomes 1.1 for RCS). | ||
159 | * | ||
160 | * Revision 0.12 1999/03/28 09:20:10 wolff | ||
161 | * Fixed problem in 0.11, continueing cleanup. | ||
162 | * | ||
163 | * Revision 0.11 1999/03/28 08:46:44 wolff | ||
164 | * cleanup. Not good. | ||
165 | * | ||
166 | * Revision 0.10 1999/03/28 08:09:43 wolff | ||
167 | * Fixed loosing characters on close. | ||
168 | * | ||
169 | * Revision 0.9 1999/03/21 22:52:01 wolff | ||
170 | * Ported back to 2.2.... (minor things) | ||
171 | * | ||
172 | * Revision 0.8 1999/03/21 22:40:33 wolff | ||
173 | * Port to 2.0 | ||
174 | * | ||
175 | * Revision 0.7 1999/03/21 19:06:34 wolff | ||
176 | * Fixed hangup processing. | ||
177 | * | ||
178 | * Revision 0.6 1999/02/05 08:45:14 wolff | ||
179 | * fixed real_raw problems. Inclusion into kernel imminent. | ||
180 | * | ||
181 | * Revision 0.5 1998/12/21 23:51:06 wolff | ||
182 | * Snatched a nasty bug: sx_transmit_chars was getting re-entered, and it | ||
183 | * shouldn't have. THATs why I want to have transmit interrupts even when | ||
184 | * the buffer is empty. | ||
185 | * | ||
186 | * Revision 0.4 1998/12/17 09:34:46 wolff | ||
187 | * PPP works. ioctl works. Basically works! | ||
188 | * | ||
189 | * Revision 0.3 1998/12/15 13:05:18 wolff | ||
190 | * It works! Wow! Gotta start implementing IOCTL and stuff.... | ||
191 | * | ||
192 | * Revision 0.2 1998/12/01 08:33:53 wolff | ||
193 | * moved over to 2.1.130 | ||
194 | * | ||
195 | * Revision 0.1 1998/11/03 21:23:51 wolff | ||
196 | * Initial revision. Detects SX card. | ||
197 | * | ||
198 | * */ | ||
199 | |||
200 | #define SX_VERSION 1.33 | ||
201 | |||
202 | #include <linux/module.h> | ||
203 | #include <linux/kdev_t.h> | ||
204 | #include <linux/kernel.h> | ||
205 | #include <linux/sched.h> | ||
206 | #include <linux/ioport.h> | ||
207 | #include <linux/interrupt.h> | ||
208 | #include <linux/errno.h> | ||
209 | #include <linux/tty.h> | ||
210 | #include <linux/tty_flip.h> | ||
211 | #include <linux/mm.h> | ||
212 | #include <linux/serial.h> | ||
213 | #include <linux/fcntl.h> | ||
214 | #include <linux/major.h> | ||
215 | #include <linux/delay.h> | ||
216 | #include <linux/eisa.h> | ||
217 | #include <linux/pci.h> | ||
218 | #include <linux/slab.h> | ||
219 | #include <linux/init.h> | ||
220 | #include <linux/miscdevice.h> | ||
221 | #include <linux/bitops.h> | ||
222 | |||
223 | #include <asm/io.h> | ||
224 | #include <asm/uaccess.h> | ||
225 | |||
226 | /* The 3.0.0 version of sxboards/sxwindow.h uses BYTE and WORD.... */ | ||
227 | #define BYTE u8 | ||
228 | #define WORD u16 | ||
229 | |||
230 | /* .... but the 3.0.4 version uses _u8 and _u16. */ | ||
231 | #define _u8 u8 | ||
232 | #define _u16 u16 | ||
233 | |||
234 | #include "sxboards.h" | ||
235 | #include "sxwindow.h" | ||
236 | |||
237 | #include <linux/generic_serial.h> | ||
238 | #include "sx.h" | ||
239 | |||
240 | /* I don't think that this driver can handle more than 256 ports on | ||
241 | one machine. You'll have to increase the number of boards in sx.h | ||
242 | if you want more than 4 boards. */ | ||
243 | |||
244 | #ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 | ||
245 | #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 | ||
246 | #endif | ||
247 | |||
248 | /* Configurable options: | ||
249 | (Don't be too sure that it'll work if you toggle them) */ | ||
250 | |||
251 | /* Am I paranoid or not ? ;-) */ | ||
252 | #undef SX_PARANOIA_CHECK | ||
253 | |||
254 | /* 20 -> 2000 per second. The card should rate-limit interrupts at 100 | ||
255 | Hz, but it is user configurable. I don't recommend going above 1000 | ||
256 | Hz. The interrupt ratelimit might trigger if the interrupt is | ||
257 | shared with a very active other device. */ | ||
258 | #define IRQ_RATE_LIMIT 20 | ||
259 | |||
260 | /* Sharing interrupts is possible now. If the other device wants more | ||
261 | than 2000 interrupts per second, we'd gracefully decline further | ||
262 | interrupts. That's not what we want. On the other hand, if the | ||
263 | other device interrupts 2000 times a second, don't use the SX | ||
264 | interrupt. Use polling. */ | ||
265 | #undef IRQ_RATE_LIMIT | ||
266 | |||
267 | #if 0 | ||
268 | /* Not implemented */ | ||
269 | /* | ||
270 | * The following defines are mostly for testing purposes. But if you need | ||
271 | * some nice reporting in your syslog, you can define them also. | ||
272 | */ | ||
273 | #define SX_REPORT_FIFO | ||
274 | #define SX_REPORT_OVERRUN | ||
275 | #endif | ||
276 | |||
277 | /* Function prototypes */ | ||
278 | static void sx_disable_tx_interrupts(void *ptr); | ||
279 | static void sx_enable_tx_interrupts(void *ptr); | ||
280 | static void sx_disable_rx_interrupts(void *ptr); | ||
281 | static void sx_enable_rx_interrupts(void *ptr); | ||
282 | static int sx_carrier_raised(struct tty_port *port); | ||
283 | static void sx_shutdown_port(void *ptr); | ||
284 | static int sx_set_real_termios(void *ptr); | ||
285 | static void sx_close(void *ptr); | ||
286 | static int sx_chars_in_buffer(void *ptr); | ||
287 | static int sx_init_board(struct sx_board *board); | ||
288 | static int sx_init_portstructs(int nboards, int nports); | ||
289 | static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | ||
290 | unsigned long arg); | ||
291 | static int sx_init_drivers(void); | ||
292 | |||
293 | static struct tty_driver *sx_driver; | ||
294 | |||
295 | static DEFINE_MUTEX(sx_boards_lock); | ||
296 | static struct sx_board boards[SX_NBOARDS]; | ||
297 | static struct sx_port *sx_ports; | ||
298 | static int sx_initialized; | ||
299 | static int sx_nports; | ||
300 | static int sx_debug; | ||
301 | |||
302 | /* You can have the driver poll your card. | ||
303 | - Set sx_poll to 1 to poll every timer tick (10ms on Intel). | ||
304 | This is used when the card cannot use an interrupt for some reason. | ||
305 | |||
306 | - set sx_slowpoll to 100 to do an extra poll once a second (on Intel). If | ||
307 | the driver misses an interrupt (report this if it DOES happen to you!) | ||
308 | everything will continue to work.... | ||
309 | */ | ||
310 | static int sx_poll = 1; | ||
311 | static int sx_slowpoll; | ||
312 | |||
313 | /* The card limits the number of interrupts per second. | ||
314 | At 115k2 "100" should be sufficient. | ||
315 | If you're using higher baudrates, you can increase this... | ||
316 | */ | ||
317 | |||
318 | static int sx_maxints = 100; | ||
319 | |||
320 | #ifdef CONFIG_ISA | ||
321 | |||
322 | /* These are the only open spaces in my computer. Yours may have more | ||
323 | or less.... -- REW | ||
324 | duh: Card at 0xa0000 is possible on HP Netserver?? -- pvdl | ||
325 | */ | ||
326 | static int sx_probe_addrs[] = { | ||
327 | 0xc0000, 0xd0000, 0xe0000, | ||
328 | 0xc8000, 0xd8000, 0xe8000 | ||
329 | }; | ||
330 | static int si_probe_addrs[] = { | ||
331 | 0xc0000, 0xd0000, 0xe0000, | ||
332 | 0xc8000, 0xd8000, 0xe8000, 0xa0000 | ||
333 | }; | ||
334 | static int si1_probe_addrs[] = { | ||
335 | 0xd0000 | ||
336 | }; | ||
337 | |||
338 | #define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs) | ||
339 | #define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs) | ||
340 | #define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs) | ||
341 | |||
342 | module_param_array(sx_probe_addrs, int, NULL, 0); | ||
343 | module_param_array(si_probe_addrs, int, NULL, 0); | ||
344 | #endif | ||
345 | |||
346 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. | ||
347 | Some architectures may need more. */ | ||
348 | static int sx_irqmask = -1; | ||
349 | |||
350 | module_param(sx_poll, int, 0); | ||
351 | module_param(sx_slowpoll, int, 0); | ||
352 | module_param(sx_maxints, int, 0); | ||
353 | module_param(sx_debug, int, 0); | ||
354 | module_param(sx_irqmask, int, 0); | ||
355 | |||
356 | MODULE_LICENSE("GPL"); | ||
357 | |||
358 | static struct real_driver sx_real_driver = { | ||
359 | sx_disable_tx_interrupts, | ||
360 | sx_enable_tx_interrupts, | ||
361 | sx_disable_rx_interrupts, | ||
362 | sx_enable_rx_interrupts, | ||
363 | sx_shutdown_port, | ||
364 | sx_set_real_termios, | ||
365 | sx_chars_in_buffer, | ||
366 | sx_close, | ||
367 | }; | ||
368 | |||
369 | /* | ||
370 | This driver can spew a whole lot of debugging output at you. If you | ||
371 | need maximum performance, you should disable the DEBUG define. To | ||
372 | aid in debugging in the field, I'm leaving the compile-time debug | ||
373 | features enabled, and disable them "runtime". That allows me to | ||
374 | instruct people with problems to enable debugging without requiring | ||
375 | them to recompile... | ||
376 | */ | ||
377 | #define DEBUG | ||
378 | |||
379 | #ifdef DEBUG | ||
380 | #define sx_dprintk(f, str...) if (sx_debug & f) printk (str) | ||
381 | #else | ||
382 | #define sx_dprintk(f, str...) /* nothing */ | ||
383 | #endif | ||
384 | |||
385 | #define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__func__) | ||
386 | #define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__func__) | ||
387 | |||
388 | #define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ | ||
389 | __func__, port->line) | ||
390 | |||
391 | /* | ||
392 | * Firmware loader driver specific routines | ||
393 | * | ||
394 | */ | ||
395 | |||
396 | static const struct file_operations sx_fw_fops = { | ||
397 | .owner = THIS_MODULE, | ||
398 | .unlocked_ioctl = sx_fw_ioctl, | ||
399 | .llseek = noop_llseek, | ||
400 | }; | ||
401 | |||
402 | static struct miscdevice sx_fw_device = { | ||
403 | SXCTL_MISC_MINOR, "sxctl", &sx_fw_fops | ||
404 | }; | ||
405 | |||
406 | #ifdef SX_PARANOIA_CHECK | ||
407 | |||
408 | /* This doesn't work. Who's paranoid around here? Not me! */ | ||
409 | |||
410 | static inline int sx_paranoia_check(struct sx_port const *port, | ||
411 | char *name, const char *routine) | ||
412 | { | ||
413 | static const char *badmagic = KERN_ERR "sx: Warning: bad sx port magic " | ||
414 | "number for device %s in %s\n"; | ||
415 | static const char *badinfo = KERN_ERR "sx: Warning: null sx port for " | ||
416 | "device %s in %s\n"; | ||
417 | |||
418 | if (!port) { | ||
419 | printk(badinfo, name, routine); | ||
420 | return 1; | ||
421 | } | ||
422 | if (port->magic != SX_MAGIC) { | ||
423 | printk(badmagic, name, routine); | ||
424 | return 1; | ||
425 | } | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | #else | ||
430 | #define sx_paranoia_check(a,b,c) 0 | ||
431 | #endif | ||
432 | |||
433 | /* The timeouts. First try 30 times as fast as possible. Then give | ||
434 | the card some time to breathe between accesses. (Otherwise the | ||
435 | processor on the card might not be able to access its OWN bus... */ | ||
436 | |||
437 | #define TIMEOUT_1 30 | ||
438 | #define TIMEOUT_2 1000000 | ||
439 | |||
440 | #ifdef DEBUG | ||
441 | static void my_hd_io(void __iomem *p, int len) | ||
442 | { | ||
443 | int i, j, ch; | ||
444 | unsigned char __iomem *addr = p; | ||
445 | |||
446 | for (i = 0; i < len; i += 16) { | ||
447 | printk("%p ", addr + i); | ||
448 | for (j = 0; j < 16; j++) { | ||
449 | printk("%02x %s", readb(addr + j + i), | ||
450 | (j == 7) ? " " : ""); | ||
451 | } | ||
452 | for (j = 0; j < 16; j++) { | ||
453 | ch = readb(addr + j + i); | ||
454 | printk("%c", (ch < 0x20) ? '.' : | ||
455 | ((ch > 0x7f) ? '.' : ch)); | ||
456 | } | ||
457 | printk("\n"); | ||
458 | } | ||
459 | } | ||
460 | static void my_hd(void *p, int len) | ||
461 | { | ||
462 | int i, j, ch; | ||
463 | unsigned char *addr = p; | ||
464 | |||
465 | for (i = 0; i < len; i += 16) { | ||
466 | printk("%p ", addr + i); | ||
467 | for (j = 0; j < 16; j++) { | ||
468 | printk("%02x %s", addr[j + i], (j == 7) ? " " : ""); | ||
469 | } | ||
470 | for (j = 0; j < 16; j++) { | ||
471 | ch = addr[j + i]; | ||
472 | printk("%c", (ch < 0x20) ? '.' : | ||
473 | ((ch > 0x7f) ? '.' : ch)); | ||
474 | } | ||
475 | printk("\n"); | ||
476 | } | ||
477 | } | ||
478 | #endif | ||
479 | |||
480 | /* This needs redoing for Alpha -- REW -- Done. */ | ||
481 | |||
482 | static inline void write_sx_byte(struct sx_board *board, int offset, u8 byte) | ||
483 | { | ||
484 | writeb(byte, board->base + offset); | ||
485 | } | ||
486 | |||
487 | static inline u8 read_sx_byte(struct sx_board *board, int offset) | ||
488 | { | ||
489 | return readb(board->base + offset); | ||
490 | } | ||
491 | |||
492 | static inline void write_sx_word(struct sx_board *board, int offset, u16 word) | ||
493 | { | ||
494 | writew(word, board->base + offset); | ||
495 | } | ||
496 | |||
497 | static inline u16 read_sx_word(struct sx_board *board, int offset) | ||
498 | { | ||
499 | return readw(board->base + offset); | ||
500 | } | ||
501 | |||
502 | static int sx_busy_wait_eq(struct sx_board *board, | ||
503 | int offset, int mask, int correctval) | ||
504 | { | ||
505 | int i; | ||
506 | |||
507 | func_enter(); | ||
508 | |||
509 | for (i = 0; i < TIMEOUT_1; i++) | ||
510 | if ((read_sx_byte(board, offset) & mask) == correctval) { | ||
511 | func_exit(); | ||
512 | return 1; | ||
513 | } | ||
514 | |||
515 | for (i = 0; i < TIMEOUT_2; i++) { | ||
516 | if ((read_sx_byte(board, offset) & mask) == correctval) { | ||
517 | func_exit(); | ||
518 | return 1; | ||
519 | } | ||
520 | udelay(1); | ||
521 | } | ||
522 | |||
523 | func_exit(); | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int sx_busy_wait_neq(struct sx_board *board, | ||
528 | int offset, int mask, int badval) | ||
529 | { | ||
530 | int i; | ||
531 | |||
532 | func_enter(); | ||
533 | |||
534 | for (i = 0; i < TIMEOUT_1; i++) | ||
535 | if ((read_sx_byte(board, offset) & mask) != badval) { | ||
536 | func_exit(); | ||
537 | return 1; | ||
538 | } | ||
539 | |||
540 | for (i = 0; i < TIMEOUT_2; i++) { | ||
541 | if ((read_sx_byte(board, offset) & mask) != badval) { | ||
542 | func_exit(); | ||
543 | return 1; | ||
544 | } | ||
545 | udelay(1); | ||
546 | } | ||
547 | |||
548 | func_exit(); | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | /* 5.6.4 of 6210028 r2.3 */ | ||
553 | static int sx_reset(struct sx_board *board) | ||
554 | { | ||
555 | func_enter(); | ||
556 | |||
557 | if (IS_SX_BOARD(board)) { | ||
558 | |||
559 | write_sx_byte(board, SX_CONFIG, 0); | ||
560 | write_sx_byte(board, SX_RESET, 1); /* Value doesn't matter */ | ||
561 | |||
562 | if (!sx_busy_wait_eq(board, SX_RESET_STATUS, 1, 0)) { | ||
563 | printk(KERN_INFO "sx: Card doesn't respond to " | ||
564 | "reset...\n"); | ||
565 | return 0; | ||
566 | } | ||
567 | } else if (IS_EISA_BOARD(board)) { | ||
568 | outb(board->irq << 4, board->eisa_base + 0xc02); | ||
569 | } else if (IS_SI1_BOARD(board)) { | ||
570 | write_sx_byte(board, SI1_ISA_RESET, 0); /*value doesn't matter*/ | ||
571 | } else { | ||
572 | /* Gory details of the SI/ISA board */ | ||
573 | write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_SET); | ||
574 | write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_CLEAR); | ||
575 | write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_CLEAR); | ||
576 | write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_CLEAR); | ||
577 | write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR); | ||
578 | write_sx_byte(board, SI2_ISA_IRQSET, SI2_ISA_IRQSET_CLEAR); | ||
579 | } | ||
580 | |||
581 | func_exit(); | ||
582 | return 1; | ||
583 | } | ||
584 | |||
585 | /* This doesn't work on machines where "NULL" isn't 0 */ | ||
586 | /* If you have one of those, someone will need to write | ||
587 | the equivalent of this, which will amount to about 3 lines. I don't | ||
588 | want to complicate this right now. -- REW | ||
589 | (See, I do write comments every now and then :-) */ | ||
590 | #define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem)) | ||
591 | |||
592 | #define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem)) | ||
593 | #define MODU_OFFSET(board,addr,elem) (addr + OFFSETOF (_SXMODULE, elem)) | ||
594 | #define BRD_OFFSET(board,elem) (OFFSETOF (_SXCARD, elem)) | ||
595 | |||
596 | #define sx_write_channel_byte(port, elem, val) \ | ||
597 | write_sx_byte (port->board, CHAN_OFFSET (port, elem), val) | ||
598 | |||
599 | #define sx_read_channel_byte(port, elem) \ | ||
600 | read_sx_byte (port->board, CHAN_OFFSET (port, elem)) | ||
601 | |||
602 | #define sx_write_channel_word(port, elem, val) \ | ||
603 | write_sx_word (port->board, CHAN_OFFSET (port, elem), val) | ||
604 | |||
605 | #define sx_read_channel_word(port, elem) \ | ||
606 | read_sx_word (port->board, CHAN_OFFSET (port, elem)) | ||
607 | |||
608 | #define sx_write_module_byte(board, addr, elem, val) \ | ||
609 | write_sx_byte (board, MODU_OFFSET (board, addr, elem), val) | ||
610 | |||
611 | #define sx_read_module_byte(board, addr, elem) \ | ||
612 | read_sx_byte (board, MODU_OFFSET (board, addr, elem)) | ||
613 | |||
614 | #define sx_write_module_word(board, addr, elem, val) \ | ||
615 | write_sx_word (board, MODU_OFFSET (board, addr, elem), val) | ||
616 | |||
617 | #define sx_read_module_word(board, addr, elem) \ | ||
618 | read_sx_word (board, MODU_OFFSET (board, addr, elem)) | ||
619 | |||
620 | #define sx_write_board_byte(board, elem, val) \ | ||
621 | write_sx_byte (board, BRD_OFFSET (board, elem), val) | ||
622 | |||
623 | #define sx_read_board_byte(board, elem) \ | ||
624 | read_sx_byte (board, BRD_OFFSET (board, elem)) | ||
625 | |||
626 | #define sx_write_board_word(board, elem, val) \ | ||
627 | write_sx_word (board, BRD_OFFSET (board, elem), val) | ||
628 | |||
629 | #define sx_read_board_word(board, elem) \ | ||
630 | read_sx_word (board, BRD_OFFSET (board, elem)) | ||
631 | |||
632 | static int sx_start_board(struct sx_board *board) | ||
633 | { | ||
634 | if (IS_SX_BOARD(board)) { | ||
635 | write_sx_byte(board, SX_CONFIG, SX_CONF_BUSEN); | ||
636 | } else if (IS_EISA_BOARD(board)) { | ||
637 | write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL); | ||
638 | outb((board->irq << 4) | 4, board->eisa_base + 0xc02); | ||
639 | } else if (IS_SI1_BOARD(board)) { | ||
640 | write_sx_byte(board, SI1_ISA_RESET_CLEAR, 0); | ||
641 | write_sx_byte(board, SI1_ISA_INTCL, 0); | ||
642 | } else { | ||
643 | /* Don't bug me about the clear_set. | ||
644 | I haven't the foggiest idea what it's about -- REW */ | ||
645 | write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_CLEAR); | ||
646 | write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); | ||
647 | } | ||
648 | return 1; | ||
649 | } | ||
650 | |||
651 | #define SX_IRQ_REG_VAL(board) \ | ||
652 | ((board->flags & SX_ISA_BOARD) ? (board->irq << 4) : 0) | ||
653 | |||
654 | /* Note. The SX register is write-only. Therefore, we have to enable the | ||
655 | bus too. This is a no-op, if you don't mess with this driver... */ | ||
656 | static int sx_start_interrupts(struct sx_board *board) | ||
657 | { | ||
658 | |||
659 | /* Don't call this with board->irq == 0 */ | ||
660 | |||
661 | if (IS_SX_BOARD(board)) { | ||
662 | write_sx_byte(board, SX_CONFIG, SX_IRQ_REG_VAL(board) | | ||
663 | SX_CONF_BUSEN | SX_CONF_HOSTIRQ); | ||
664 | } else if (IS_EISA_BOARD(board)) { | ||
665 | inb(board->eisa_base + 0xc03); | ||
666 | } else if (IS_SI1_BOARD(board)) { | ||
667 | write_sx_byte(board, SI1_ISA_INTCL, 0); | ||
668 | write_sx_byte(board, SI1_ISA_INTCL_CLEAR, 0); | ||
669 | } else { | ||
670 | switch (board->irq) { | ||
671 | case 11: | ||
672 | write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET); | ||
673 | break; | ||
674 | case 12: | ||
675 | write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET); | ||
676 | break; | ||
677 | case 15: | ||
678 | write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET); | ||
679 | break; | ||
680 | default: | ||
681 | printk(KERN_INFO "sx: SI/XIO card doesn't support " | ||
682 | "interrupt %d.\n", board->irq); | ||
683 | return 0; | ||
684 | } | ||
685 | write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); | ||
686 | } | ||
687 | |||
688 | return 1; | ||
689 | } | ||
690 | |||
691 | static int sx_send_command(struct sx_port *port, | ||
692 | int command, int mask, int newstat) | ||
693 | { | ||
694 | func_enter2(); | ||
695 | write_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat), command); | ||
696 | func_exit(); | ||
697 | return sx_busy_wait_eq(port->board, CHAN_OFFSET(port, hi_hstat), mask, | ||
698 | newstat); | ||
699 | } | ||
700 | |||
701 | static char *mod_type_s(int module_type) | ||
702 | { | ||
703 | switch (module_type) { | ||
704 | case TA4: | ||
705 | return "TA4"; | ||
706 | case TA8: | ||
707 | return "TA8"; | ||
708 | case TA4_ASIC: | ||
709 | return "TA4_ASIC"; | ||
710 | case TA8_ASIC: | ||
711 | return "TA8_ASIC"; | ||
712 | case MTA_CD1400: | ||
713 | return "MTA_CD1400"; | ||
714 | case SXDC: | ||
715 | return "SXDC"; | ||
716 | default: | ||
717 | return "Unknown/invalid"; | ||
718 | } | ||
719 | } | ||
720 | |||
721 | static char *pan_type_s(int pan_type) | ||
722 | { | ||
723 | switch (pan_type) { | ||
724 | case MOD_RS232DB25: | ||
725 | return "MOD_RS232DB25"; | ||
726 | case MOD_RS232RJ45: | ||
727 | return "MOD_RS232RJ45"; | ||
728 | case MOD_RS422DB25: | ||
729 | return "MOD_RS422DB25"; | ||
730 | case MOD_PARALLEL: | ||
731 | return "MOD_PARALLEL"; | ||
732 | case MOD_2_RS232DB25: | ||
733 | return "MOD_2_RS232DB25"; | ||
734 | case MOD_2_RS232RJ45: | ||
735 | return "MOD_2_RS232RJ45"; | ||
736 | case MOD_2_RS422DB25: | ||
737 | return "MOD_2_RS422DB25"; | ||
738 | case MOD_RS232DB25MALE: | ||
739 | return "MOD_RS232DB25MALE"; | ||
740 | case MOD_2_PARALLEL: | ||
741 | return "MOD_2_PARALLEL"; | ||
742 | case MOD_BLANK: | ||
743 | return "empty"; | ||
744 | default: | ||
745 | return "invalid"; | ||
746 | } | ||
747 | } | ||
748 | |||
749 | static int mod_compat_type(int module_type) | ||
750 | { | ||
751 | return module_type >> 4; | ||
752 | } | ||
753 | |||
754 | static void sx_reconfigure_port(struct sx_port *port) | ||
755 | { | ||
756 | if (sx_read_channel_byte(port, hi_hstat) == HS_IDLE_OPEN) { | ||
757 | if (sx_send_command(port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) { | ||
758 | printk(KERN_WARNING "sx: Sent reconfigure command, but " | ||
759 | "card didn't react.\n"); | ||
760 | } | ||
761 | } else { | ||
762 | sx_dprintk(SX_DEBUG_TERMIOS, "sx: Not sending reconfigure: " | ||
763 | "port isn't open (%02x).\n", | ||
764 | sx_read_channel_byte(port, hi_hstat)); | ||
765 | } | ||
766 | } | ||
767 | |||
768 | static void sx_setsignals(struct sx_port *port, int dtr, int rts) | ||
769 | { | ||
770 | int t; | ||
771 | func_enter2(); | ||
772 | |||
773 | t = sx_read_channel_byte(port, hi_op); | ||
774 | if (dtr >= 0) | ||
775 | t = dtr ? (t | OP_DTR) : (t & ~OP_DTR); | ||
776 | if (rts >= 0) | ||
777 | t = rts ? (t | OP_RTS) : (t & ~OP_RTS); | ||
778 | sx_write_channel_byte(port, hi_op, t); | ||
779 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); | ||
780 | |||
781 | func_exit(); | ||
782 | } | ||
783 | |||
784 | static int sx_getsignals(struct sx_port *port) | ||
785 | { | ||
786 | int i_stat, o_stat; | ||
787 | |||
788 | o_stat = sx_read_channel_byte(port, hi_op); | ||
789 | i_stat = sx_read_channel_byte(port, hi_ip); | ||
790 | |||
791 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) " | ||
792 | "%02x/%02x\n", | ||
793 | (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, | ||
794 | port->c_dcd, tty_port_carrier_raised(&port->gs.port), | ||
795 | sx_read_channel_byte(port, hi_ip), | ||
796 | sx_read_channel_byte(port, hi_state)); | ||
797 | |||
798 | return (((o_stat & OP_DTR) ? TIOCM_DTR : 0) | | ||
799 | ((o_stat & OP_RTS) ? TIOCM_RTS : 0) | | ||
800 | ((i_stat & IP_CTS) ? TIOCM_CTS : 0) | | ||
801 | ((i_stat & IP_DCD) ? TIOCM_CAR : 0) | | ||
802 | ((i_stat & IP_DSR) ? TIOCM_DSR : 0) | | ||
803 | ((i_stat & IP_RI) ? TIOCM_RNG : 0)); | ||
804 | } | ||
805 | |||
806 | static void sx_set_baud(struct sx_port *port) | ||
807 | { | ||
808 | int t; | ||
809 | |||
810 | if (port->board->ta_type == MOD_SXDC) { | ||
811 | switch (port->gs.baud) { | ||
812 | /* Save some typing work... */ | ||
813 | #define e(x) case x: t = BAUD_ ## x; break | ||
814 | e(50); | ||
815 | e(75); | ||
816 | e(110); | ||
817 | e(150); | ||
818 | e(200); | ||
819 | e(300); | ||
820 | e(600); | ||
821 | e(1200); | ||
822 | e(1800); | ||
823 | e(2000); | ||
824 | e(2400); | ||
825 | e(4800); | ||
826 | e(7200); | ||
827 | e(9600); | ||
828 | e(14400); | ||
829 | e(19200); | ||
830 | e(28800); | ||
831 | e(38400); | ||
832 | e(56000); | ||
833 | e(57600); | ||
834 | e(64000); | ||
835 | e(76800); | ||
836 | e(115200); | ||
837 | e(128000); | ||
838 | e(150000); | ||
839 | e(230400); | ||
840 | e(256000); | ||
841 | e(460800); | ||
842 | e(921600); | ||
843 | case 134: | ||
844 | t = BAUD_134_5; | ||
845 | break; | ||
846 | case 0: | ||
847 | t = -1; | ||
848 | break; | ||
849 | default: | ||
850 | /* Can I return "invalid"? */ | ||
851 | t = BAUD_9600; | ||
852 | printk(KERN_INFO "sx: unsupported baud rate: %d.\n", | ||
853 | port->gs.baud); | ||
854 | break; | ||
855 | } | ||
856 | #undef e | ||
857 | if (t > 0) { | ||
858 | /* The baud rate is not set to 0, so we're enabeling DTR... -- REW */ | ||
859 | sx_setsignals(port, 1, -1); | ||
860 | /* XXX This is not TA & MTA compatible */ | ||
861 | sx_write_channel_byte(port, hi_csr, 0xff); | ||
862 | |||
863 | sx_write_channel_byte(port, hi_txbaud, t); | ||
864 | sx_write_channel_byte(port, hi_rxbaud, t); | ||
865 | } else { | ||
866 | sx_setsignals(port, 0, -1); | ||
867 | } | ||
868 | } else { | ||
869 | switch (port->gs.baud) { | ||
870 | #define e(x) case x: t = CSR_ ## x; break | ||
871 | e(75); | ||
872 | e(150); | ||
873 | e(300); | ||
874 | e(600); | ||
875 | e(1200); | ||
876 | e(2400); | ||
877 | e(4800); | ||
878 | e(1800); | ||
879 | e(9600); | ||
880 | e(19200); | ||
881 | e(57600); | ||
882 | e(38400); | ||
883 | /* TA supports 110, but not 115200, MTA supports 115200, but not 110 */ | ||
884 | case 110: | ||
885 | if (port->board->ta_type == MOD_TA) { | ||
886 | t = CSR_110; | ||
887 | break; | ||
888 | } else { | ||
889 | t = CSR_9600; | ||
890 | printk(KERN_INFO "sx: Unsupported baud rate: " | ||
891 | "%d.\n", port->gs.baud); | ||
892 | break; | ||
893 | } | ||
894 | case 115200: | ||
895 | if (port->board->ta_type == MOD_TA) { | ||
896 | t = CSR_9600; | ||
897 | printk(KERN_INFO "sx: Unsupported baud rate: " | ||
898 | "%d.\n", port->gs.baud); | ||
899 | break; | ||
900 | } else { | ||
901 | t = CSR_110; | ||
902 | break; | ||
903 | } | ||
904 | case 0: | ||
905 | t = -1; | ||
906 | break; | ||
907 | default: | ||
908 | t = CSR_9600; | ||
909 | printk(KERN_INFO "sx: Unsupported baud rate: %d.\n", | ||
910 | port->gs.baud); | ||
911 | break; | ||
912 | } | ||
913 | #undef e | ||
914 | if (t >= 0) { | ||
915 | sx_setsignals(port, 1, -1); | ||
916 | sx_write_channel_byte(port, hi_csr, t * 0x11); | ||
917 | } else { | ||
918 | sx_setsignals(port, 0, -1); | ||
919 | } | ||
920 | } | ||
921 | } | ||
922 | |||
923 | /* Simon Allen's version of this routine was 225 lines long. 85 is a lot | ||
924 | better. -- REW */ | ||
925 | |||
926 | static int sx_set_real_termios(void *ptr) | ||
927 | { | ||
928 | struct sx_port *port = ptr; | ||
929 | |||
930 | func_enter2(); | ||
931 | |||
932 | if (!port->gs.port.tty) | ||
933 | return 0; | ||
934 | |||
935 | /* What is this doing here? -- REW | ||
936 | Ha! figured it out. It is to allow you to get DTR active again | ||
937 | if you've dropped it with stty 0. Moved to set_baud, where it | ||
938 | belongs (next to the drop dtr if baud == 0) -- REW */ | ||
939 | /* sx_setsignals (port, 1, -1); */ | ||
940 | |||
941 | sx_set_baud(port); | ||
942 | |||
943 | #define CFLAG port->gs.port.tty->termios->c_cflag | ||
944 | sx_write_channel_byte(port, hi_mr1, | ||
945 | (C_PARENB(port->gs.port.tty) ? MR1_WITH : MR1_NONE) | | ||
946 | (C_PARODD(port->gs.port.tty) ? MR1_ODD : MR1_EVEN) | | ||
947 | (C_CRTSCTS(port->gs.port.tty) ? MR1_RTS_RXFLOW : 0) | | ||
948 | (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) | | ||
949 | (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) | | ||
950 | (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) | | ||
951 | (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0)); | ||
952 | |||
953 | sx_write_channel_byte(port, hi_mr2, | ||
954 | (C_CRTSCTS(port->gs.port.tty) ? MR2_CTS_TXFLOW : 0) | | ||
955 | (C_CSTOPB(port->gs.port.tty) ? MR2_2_STOP : | ||
956 | MR2_1_STOP)); | ||
957 | |||
958 | switch (CFLAG & CSIZE) { | ||
959 | case CS8: | ||
960 | sx_write_channel_byte(port, hi_mask, 0xff); | ||
961 | break; | ||
962 | case CS7: | ||
963 | sx_write_channel_byte(port, hi_mask, 0x7f); | ||
964 | break; | ||
965 | case CS6: | ||
966 | sx_write_channel_byte(port, hi_mask, 0x3f); | ||
967 | break; | ||
968 | case CS5: | ||
969 | sx_write_channel_byte(port, hi_mask, 0x1f); | ||
970 | break; | ||
971 | default: | ||
972 | printk(KERN_INFO "sx: Invalid wordsize: %u\n", | ||
973 | (unsigned int)CFLAG & CSIZE); | ||
974 | break; | ||
975 | } | ||
976 | |||
977 | sx_write_channel_byte(port, hi_prtcl, | ||
978 | (I_IXON(port->gs.port.tty) ? SP_TXEN : 0) | | ||
979 | (I_IXOFF(port->gs.port.tty) ? SP_RXEN : 0) | | ||
980 | (I_IXANY(port->gs.port.tty) ? SP_TANY : 0) | SP_DCEN); | ||
981 | |||
982 | sx_write_channel_byte(port, hi_break, | ||
983 | (I_IGNBRK(port->gs.port.tty) ? BR_IGN : 0 | | ||
984 | I_BRKINT(port->gs.port.tty) ? BR_INT : 0)); | ||
985 | |||
986 | sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.port.tty)); | ||
987 | sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.port.tty)); | ||
988 | sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.port.tty)); | ||
989 | sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.port.tty)); | ||
990 | |||
991 | sx_reconfigure_port(port); | ||
992 | |||
993 | /* Tell line discipline whether we will do input cooking */ | ||
994 | if (I_OTHER(port->gs.port.tty)) { | ||
995 | clear_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); | ||
996 | } else { | ||
997 | set_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); | ||
998 | } | ||
999 | sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", | ||
1000 | (unsigned int)port->gs.port.tty->termios->c_iflag, | ||
1001 | I_OTHER(port->gs.port.tty)); | ||
1002 | |||
1003 | /* Tell line discipline whether we will do output cooking. | ||
1004 | * If OPOST is set and no other output flags are set then we can do output | ||
1005 | * processing. Even if only *one* other flag in the O_OTHER group is set | ||
1006 | * we do cooking in software. | ||
1007 | */ | ||
1008 | if (O_OPOST(port->gs.port.tty) && !O_OTHER(port->gs.port.tty)) { | ||
1009 | set_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); | ||
1010 | } else { | ||
1011 | clear_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); | ||
1012 | } | ||
1013 | sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", | ||
1014 | (unsigned int)port->gs.port.tty->termios->c_oflag, | ||
1015 | O_OTHER(port->gs.port.tty)); | ||
1016 | /* port->c_dcd = sx_get_CD (port); */ | ||
1017 | func_exit(); | ||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | /* ********************************************************************** * | ||
1022 | * the interrupt related routines * | ||
1023 | * ********************************************************************** */ | ||
1024 | |||
1025 | /* Note: | ||
1026 | Other drivers use the macro "MIN" to calculate how much to copy. | ||
1027 | This has the disadvantage that it will evaluate parts twice. That's | ||
1028 | expensive when it's IO (and the compiler cannot optimize those away!). | ||
1029 | Moreover, I'm not sure that you're race-free. | ||
1030 | |||
1031 | I assign a value, and then only allow the value to decrease. This | ||
1032 | is always safe. This makes the code a few lines longer, and you | ||
1033 | know I'm dead against that, but I think it is required in this | ||
1034 | case. */ | ||
1035 | |||
1036 | static void sx_transmit_chars(struct sx_port *port) | ||
1037 | { | ||
1038 | int c; | ||
1039 | int tx_ip; | ||
1040 | int txroom; | ||
1041 | |||
1042 | func_enter2(); | ||
1043 | sx_dprintk(SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n", | ||
1044 | port, port->gs.xmit_cnt); | ||
1045 | |||
1046 | if (test_and_set_bit(SX_PORT_TRANSMIT_LOCK, &port->locks)) { | ||
1047 | return; | ||
1048 | } | ||
1049 | |||
1050 | while (1) { | ||
1051 | c = port->gs.xmit_cnt; | ||
1052 | |||
1053 | sx_dprintk(SX_DEBUG_TRANSMIT, "Copying %d ", c); | ||
1054 | tx_ip = sx_read_channel_byte(port, hi_txipos); | ||
1055 | |||
1056 | /* Took me 5 minutes to deduce this formula. | ||
1057 | Luckily it is literally in the manual in section 6.5.4.3.5 */ | ||
1058 | txroom = (sx_read_channel_byte(port, hi_txopos) - tx_ip - 1) & | ||
1059 | 0xff; | ||
1060 | |||
1061 | /* Don't copy more bytes than there is room for in the buffer */ | ||
1062 | if (c > txroom) | ||
1063 | c = txroom; | ||
1064 | sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom); | ||
1065 | |||
1066 | /* Don't copy past the end of the hardware transmit buffer */ | ||
1067 | if (c > 0x100 - tx_ip) | ||
1068 | c = 0x100 - tx_ip; | ||
1069 | |||
1070 | sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100 - tx_ip); | ||
1071 | |||
1072 | /* Don't copy pas the end of the source buffer */ | ||
1073 | if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) | ||
1074 | c = SERIAL_XMIT_SIZE - port->gs.xmit_tail; | ||
1075 | |||
1076 | sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%ld) \n", | ||
1077 | c, SERIAL_XMIT_SIZE - port->gs.xmit_tail); | ||
1078 | |||
1079 | /* If for one reason or another, we can't copy more data, we're | ||
1080 | done! */ | ||
1081 | if (c == 0) | ||
1082 | break; | ||
1083 | |||
1084 | memcpy_toio(port->board->base + CHAN_OFFSET(port, hi_txbuf) + | ||
1085 | tx_ip, port->gs.xmit_buf + port->gs.xmit_tail, c); | ||
1086 | |||
1087 | /* Update the pointer in the card */ | ||
1088 | sx_write_channel_byte(port, hi_txipos, (tx_ip + c) & 0xff); | ||
1089 | |||
1090 | /* Update the kernel buffer end */ | ||
1091 | port->gs.xmit_tail = (port->gs.xmit_tail + c) & | ||
1092 | (SERIAL_XMIT_SIZE - 1); | ||
1093 | |||
1094 | /* This one last. (this is essential) | ||
1095 | It would allow others to start putting more data into the | ||
1096 | buffer! */ | ||
1097 | port->gs.xmit_cnt -= c; | ||
1098 | } | ||
1099 | |||
1100 | if (port->gs.xmit_cnt == 0) { | ||
1101 | sx_disable_tx_interrupts(port); | ||
1102 | } | ||
1103 | |||
1104 | if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { | ||
1105 | tty_wakeup(port->gs.port.tty); | ||
1106 | sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", | ||
1107 | port->gs.wakeup_chars); | ||
1108 | } | ||
1109 | |||
1110 | clear_bit(SX_PORT_TRANSMIT_LOCK, &port->locks); | ||
1111 | func_exit(); | ||
1112 | } | ||
1113 | |||
1114 | /* Note the symmetry between receiving chars and transmitting them! | ||
1115 | Note: The kernel should have implemented both a receive buffer and | ||
1116 | a transmit buffer. */ | ||
1117 | |||
1118 | /* Inlined: Called only once. Remove the inline when you add another call */ | ||
1119 | static inline void sx_receive_chars(struct sx_port *port) | ||
1120 | { | ||
1121 | int c; | ||
1122 | int rx_op; | ||
1123 | struct tty_struct *tty; | ||
1124 | int copied = 0; | ||
1125 | unsigned char *rp; | ||
1126 | |||
1127 | func_enter2(); | ||
1128 | tty = port->gs.port.tty; | ||
1129 | while (1) { | ||
1130 | rx_op = sx_read_channel_byte(port, hi_rxopos); | ||
1131 | c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff; | ||
1132 | |||
1133 | sx_dprintk(SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); | ||
1134 | |||
1135 | /* Don't copy past the end of the hardware receive buffer */ | ||
1136 | if (rx_op + c > 0x100) | ||
1137 | c = 0x100 - rx_op; | ||
1138 | |||
1139 | sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); | ||
1140 | |||
1141 | /* Don't copy more bytes than there is room for in the buffer */ | ||
1142 | |||
1143 | c = tty_prepare_flip_string(tty, &rp, c); | ||
1144 | |||
1145 | sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); | ||
1146 | |||
1147 | /* If for one reason or another, we can't copy more data, we're done! */ | ||
1148 | if (c == 0) | ||
1149 | break; | ||
1150 | |||
1151 | sx_dprintk(SX_DEBUG_RECEIVE, "Copying over %d chars. First is " | ||
1152 | "%d at %lx\n", c, read_sx_byte(port->board, | ||
1153 | CHAN_OFFSET(port, hi_rxbuf) + rx_op), | ||
1154 | CHAN_OFFSET(port, hi_rxbuf)); | ||
1155 | memcpy_fromio(rp, port->board->base + | ||
1156 | CHAN_OFFSET(port, hi_rxbuf) + rx_op, c); | ||
1157 | |||
1158 | /* This one last. ( Not essential.) | ||
1159 | It allows the card to start putting more data into the | ||
1160 | buffer! | ||
1161 | Update the pointer in the card */ | ||
1162 | sx_write_channel_byte(port, hi_rxopos, (rx_op + c) & 0xff); | ||
1163 | |||
1164 | copied += c; | ||
1165 | } | ||
1166 | if (copied) { | ||
1167 | struct timeval tv; | ||
1168 | |||
1169 | do_gettimeofday(&tv); | ||
1170 | sx_dprintk(SX_DEBUG_RECEIVE, "pushing flipq port %d (%3d " | ||
1171 | "chars): %d.%06d (%d/%d)\n", port->line, | ||
1172 | copied, (int)(tv.tv_sec % 60), (int)tv.tv_usec, | ||
1173 | tty->raw, tty->real_raw); | ||
1174 | |||
1175 | /* Tell the rest of the system the news. Great news. New | ||
1176 | characters! */ | ||
1177 | tty_flip_buffer_push(tty); | ||
1178 | /* tty_schedule_flip (tty); */ | ||
1179 | } | ||
1180 | |||
1181 | func_exit(); | ||
1182 | } | ||
1183 | |||
1184 | /* Inlined: it is called only once. Remove the inline if you add another | ||
1185 | call */ | ||
1186 | static inline void sx_check_modem_signals(struct sx_port *port) | ||
1187 | { | ||
1188 | int hi_state; | ||
1189 | int c_dcd; | ||
1190 | |||
1191 | hi_state = sx_read_channel_byte(port, hi_state); | ||
1192 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", | ||
1193 | port->c_dcd, tty_port_carrier_raised(&port->gs.port)); | ||
1194 | |||
1195 | if (hi_state & ST_BREAK) { | ||
1196 | hi_state &= ~ST_BREAK; | ||
1197 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a break.\n"); | ||
1198 | sx_write_channel_byte(port, hi_state, hi_state); | ||
1199 | gs_got_break(&port->gs); | ||
1200 | } | ||
1201 | if (hi_state & ST_DCD) { | ||
1202 | hi_state &= ~ST_DCD; | ||
1203 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); | ||
1204 | sx_write_channel_byte(port, hi_state, hi_state); | ||
1205 | c_dcd = tty_port_carrier_raised(&port->gs.port); | ||
1206 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); | ||
1207 | if (c_dcd != port->c_dcd) { | ||
1208 | port->c_dcd = c_dcd; | ||
1209 | if (tty_port_carrier_raised(&port->gs.port)) { | ||
1210 | /* DCD went UP */ | ||
1211 | if ((sx_read_channel_byte(port, hi_hstat) != | ||
1212 | HS_IDLE_CLOSED) && | ||
1213 | !(port->gs.port.tty->termios-> | ||
1214 | c_cflag & CLOCAL)) { | ||
1215 | /* Are we blocking in open? */ | ||
1216 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " | ||
1217 | "active, unblocking open\n"); | ||
1218 | wake_up_interruptible(&port->gs.port. | ||
1219 | open_wait); | ||
1220 | } else { | ||
1221 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " | ||
1222 | "raised. Ignoring.\n"); | ||
1223 | } | ||
1224 | } else { | ||
1225 | /* DCD went down! */ | ||
1226 | if (!(port->gs.port.tty->termios->c_cflag & CLOCAL)){ | ||
1227 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " | ||
1228 | "dropped. hanging up....\n"); | ||
1229 | tty_hangup(port->gs.port.tty); | ||
1230 | } else { | ||
1231 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " | ||
1232 | "dropped. ignoring.\n"); | ||
1233 | } | ||
1234 | } | ||
1235 | } else { | ||
1236 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us " | ||
1237 | "DCD changed, but it didn't.\n"); | ||
1238 | } | ||
1239 | } | ||
1240 | } | ||
1241 | |||
1242 | /* This is what an interrupt routine should look like. | ||
1243 | * Small, elegant, clear. | ||
1244 | */ | ||
1245 | |||
1246 | static irqreturn_t sx_interrupt(int irq, void *ptr) | ||
1247 | { | ||
1248 | struct sx_board *board = ptr; | ||
1249 | struct sx_port *port; | ||
1250 | int i; | ||
1251 | |||
1252 | func_enter(); | ||
1253 | sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, | ||
1254 | board->irq); | ||
1255 | |||
1256 | /* AAargh! The order in which to do these things is essential and | ||
1257 | not trivial. | ||
1258 | |||
1259 | - Rate limit goes before "recursive". Otherwise a series of | ||
1260 | recursive calls will hang the machine in the interrupt routine. | ||
1261 | |||
1262 | - hardware twiddling goes before "recursive". Otherwise when we | ||
1263 | poll the card, and a recursive interrupt happens, we won't | ||
1264 | ack the card, so it might keep on interrupting us. (especially | ||
1265 | level sensitive interrupt systems like PCI). | ||
1266 | |||
1267 | - Rate limit goes before hardware twiddling. Otherwise we won't | ||
1268 | catch a card that has gone bonkers. | ||
1269 | |||
1270 | - The "initialized" test goes after the hardware twiddling. Otherwise | ||
1271 | the card will stick us in the interrupt routine again. | ||
1272 | |||
1273 | - The initialized test goes before recursive. | ||
1274 | */ | ||
1275 | |||
1276 | #ifdef IRQ_RATE_LIMIT | ||
1277 | /* Aaargh! I'm ashamed. This costs more lines-of-code than the | ||
1278 | actual interrupt routine!. (Well, used to when I wrote that | ||
1279 | comment) */ | ||
1280 | { | ||
1281 | static int lastjif; | ||
1282 | static int nintr = 0; | ||
1283 | |||
1284 | if (lastjif == jiffies) { | ||
1285 | if (++nintr > IRQ_RATE_LIMIT) { | ||
1286 | free_irq(board->irq, board); | ||
1287 | printk(KERN_ERR "sx: Too many interrupts. " | ||
1288 | "Turning off interrupt %d.\n", | ||
1289 | board->irq); | ||
1290 | } | ||
1291 | } else { | ||
1292 | lastjif = jiffies; | ||
1293 | nintr = 0; | ||
1294 | } | ||
1295 | } | ||
1296 | #endif | ||
1297 | |||
1298 | if (board->irq == irq) { | ||
1299 | /* Tell the card we've noticed the interrupt. */ | ||
1300 | |||
1301 | sx_write_board_word(board, cc_int_pending, 0); | ||
1302 | if (IS_SX_BOARD(board)) { | ||
1303 | write_sx_byte(board, SX_RESET_IRQ, 1); | ||
1304 | } else if (IS_EISA_BOARD(board)) { | ||
1305 | inb(board->eisa_base + 0xc03); | ||
1306 | write_sx_word(board, 8, 0); | ||
1307 | } else { | ||
1308 | write_sx_byte(board, SI2_ISA_INTCLEAR, | ||
1309 | SI2_ISA_INTCLEAR_CLEAR); | ||
1310 | write_sx_byte(board, SI2_ISA_INTCLEAR, | ||
1311 | SI2_ISA_INTCLEAR_SET); | ||
1312 | } | ||
1313 | } | ||
1314 | |||
1315 | if (!sx_initialized) | ||
1316 | return IRQ_HANDLED; | ||
1317 | if (!(board->flags & SX_BOARD_INITIALIZED)) | ||
1318 | return IRQ_HANDLED; | ||
1319 | |||
1320 | if (test_and_set_bit(SX_BOARD_INTR_LOCK, &board->locks)) { | ||
1321 | printk(KERN_ERR "Recursive interrupt! (%d)\n", board->irq); | ||
1322 | return IRQ_HANDLED; | ||
1323 | } | ||
1324 | |||
1325 | for (i = 0; i < board->nports; i++) { | ||
1326 | port = &board->ports[i]; | ||
1327 | if (port->gs.port.flags & GS_ACTIVE) { | ||
1328 | if (sx_read_channel_byte(port, hi_state)) { | ||
1329 | sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: " | ||
1330 | "modem signal change?... \n",i); | ||
1331 | sx_check_modem_signals(port); | ||
1332 | } | ||
1333 | if (port->gs.xmit_cnt) { | ||
1334 | sx_transmit_chars(port); | ||
1335 | } | ||
1336 | if (!(port->gs.port.flags & SX_RX_THROTTLE)) { | ||
1337 | sx_receive_chars(port); | ||
1338 | } | ||
1339 | } | ||
1340 | } | ||
1341 | |||
1342 | clear_bit(SX_BOARD_INTR_LOCK, &board->locks); | ||
1343 | |||
1344 | sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, | ||
1345 | board->irq); | ||
1346 | func_exit(); | ||
1347 | return IRQ_HANDLED; | ||
1348 | } | ||
1349 | |||
1350 | static void sx_pollfunc(unsigned long data) | ||
1351 | { | ||
1352 | struct sx_board *board = (struct sx_board *)data; | ||
1353 | |||
1354 | func_enter(); | ||
1355 | |||
1356 | sx_interrupt(0, board); | ||
1357 | |||
1358 | mod_timer(&board->timer, jiffies + sx_poll); | ||
1359 | func_exit(); | ||
1360 | } | ||
1361 | |||
1362 | /* ********************************************************************** * | ||
1363 | * Here are the routines that actually * | ||
1364 | * interface with the generic_serial driver * | ||
1365 | * ********************************************************************** */ | ||
1366 | |||
1367 | /* Ehhm. I don't know how to fiddle with interrupts on the SX card. --REW */ | ||
1368 | /* Hmm. Ok I figured it out. You don't. */ | ||
1369 | |||
1370 | static void sx_disable_tx_interrupts(void *ptr) | ||
1371 | { | ||
1372 | struct sx_port *port = ptr; | ||
1373 | func_enter2(); | ||
1374 | |||
1375 | port->gs.port.flags &= ~GS_TX_INTEN; | ||
1376 | |||
1377 | func_exit(); | ||
1378 | } | ||
1379 | |||
1380 | static void sx_enable_tx_interrupts(void *ptr) | ||
1381 | { | ||
1382 | struct sx_port *port = ptr; | ||
1383 | int data_in_buffer; | ||
1384 | func_enter2(); | ||
1385 | |||
1386 | /* First transmit the characters that we're supposed to */ | ||
1387 | sx_transmit_chars(port); | ||
1388 | |||
1389 | /* The sx card will never interrupt us if we don't fill the buffer | ||
1390 | past 25%. So we keep considering interrupts off if that's the case. */ | ||
1391 | data_in_buffer = (sx_read_channel_byte(port, hi_txipos) - | ||
1392 | sx_read_channel_byte(port, hi_txopos)) & 0xff; | ||
1393 | |||
1394 | /* XXX Must be "HIGH_WATER" for SI card according to doc. */ | ||
1395 | if (data_in_buffer < LOW_WATER) | ||
1396 | port->gs.port.flags &= ~GS_TX_INTEN; | ||
1397 | |||
1398 | func_exit(); | ||
1399 | } | ||
1400 | |||
1401 | static void sx_disable_rx_interrupts(void *ptr) | ||
1402 | { | ||
1403 | /* struct sx_port *port = ptr; */ | ||
1404 | func_enter(); | ||
1405 | |||
1406 | func_exit(); | ||
1407 | } | ||
1408 | |||
1409 | static void sx_enable_rx_interrupts(void *ptr) | ||
1410 | { | ||
1411 | /* struct sx_port *port = ptr; */ | ||
1412 | func_enter(); | ||
1413 | |||
1414 | func_exit(); | ||
1415 | } | ||
1416 | |||
1417 | /* Jeez. Isn't this simple? */ | ||
1418 | static int sx_carrier_raised(struct tty_port *port) | ||
1419 | { | ||
1420 | struct sx_port *sp = container_of(port, struct sx_port, gs.port); | ||
1421 | return ((sx_read_channel_byte(sp, hi_ip) & IP_DCD) != 0); | ||
1422 | } | ||
1423 | |||
1424 | /* Jeez. Isn't this simple? */ | ||
1425 | static int sx_chars_in_buffer(void *ptr) | ||
1426 | { | ||
1427 | struct sx_port *port = ptr; | ||
1428 | func_enter2(); | ||
1429 | |||
1430 | func_exit(); | ||
1431 | return ((sx_read_channel_byte(port, hi_txipos) - | ||
1432 | sx_read_channel_byte(port, hi_txopos)) & 0xff); | ||
1433 | } | ||
1434 | |||
1435 | static void sx_shutdown_port(void *ptr) | ||
1436 | { | ||
1437 | struct sx_port *port = ptr; | ||
1438 | |||
1439 | func_enter(); | ||
1440 | |||
1441 | port->gs.port.flags &= ~GS_ACTIVE; | ||
1442 | if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { | ||
1443 | sx_setsignals(port, 0, 0); | ||
1444 | sx_reconfigure_port(port); | ||
1445 | } | ||
1446 | |||
1447 | func_exit(); | ||
1448 | } | ||
1449 | |||
1450 | /* ********************************************************************** * | ||
1451 | * Here are the routines that actually * | ||
1452 | * interface with the rest of the system * | ||
1453 | * ********************************************************************** */ | ||
1454 | |||
1455 | static int sx_open(struct tty_struct *tty, struct file *filp) | ||
1456 | { | ||
1457 | struct sx_port *port; | ||
1458 | int retval, line; | ||
1459 | unsigned long flags; | ||
1460 | |||
1461 | func_enter(); | ||
1462 | |||
1463 | if (!sx_initialized) { | ||
1464 | return -EIO; | ||
1465 | } | ||
1466 | |||
1467 | line = tty->index; | ||
1468 | sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, " | ||
1469 | "np=%d)\n", task_pid_nr(current), line, tty, | ||
1470 | current->signal->tty, sx_nports); | ||
1471 | |||
1472 | if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) | ||
1473 | return -ENODEV; | ||
1474 | |||
1475 | port = &sx_ports[line]; | ||
1476 | port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a | ||
1477 | 1 -> 0 transition. */ | ||
1478 | |||
1479 | sx_dprintk(SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd); | ||
1480 | |||
1481 | spin_lock_irqsave(&port->gs.driver_lock, flags); | ||
1482 | |||
1483 | tty->driver_data = port; | ||
1484 | port->gs.port.tty = tty; | ||
1485 | port->gs.port.count++; | ||
1486 | spin_unlock_irqrestore(&port->gs.driver_lock, flags); | ||
1487 | |||
1488 | sx_dprintk(SX_DEBUG_OPEN, "starting port\n"); | ||
1489 | |||
1490 | /* | ||
1491 | * Start up serial port | ||
1492 | */ | ||
1493 | retval = gs_init_port(&port->gs); | ||
1494 | sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n"); | ||
1495 | if (retval) { | ||
1496 | port->gs.port.count--; | ||
1497 | return retval; | ||
1498 | } | ||
1499 | |||
1500 | port->gs.port.flags |= GS_ACTIVE; | ||
1501 | if (port->gs.port.count <= 1) | ||
1502 | sx_setsignals(port, 1, 1); | ||
1503 | |||
1504 | #if 0 | ||
1505 | if (sx_debug & SX_DEBUG_OPEN) | ||
1506 | my_hd(port, sizeof(*port)); | ||
1507 | #else | ||
1508 | if (sx_debug & SX_DEBUG_OPEN) | ||
1509 | my_hd_io(port->board->base + port->ch_base, sizeof(*port)); | ||
1510 | #endif | ||
1511 | |||
1512 | if (port->gs.port.count <= 1) { | ||
1513 | if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { | ||
1514 | printk(KERN_ERR "sx: Card didn't respond to LOPEN " | ||
1515 | "command.\n"); | ||
1516 | spin_lock_irqsave(&port->gs.driver_lock, flags); | ||
1517 | port->gs.port.count--; | ||
1518 | spin_unlock_irqrestore(&port->gs.driver_lock, flags); | ||
1519 | return -EIO; | ||
1520 | } | ||
1521 | } | ||
1522 | |||
1523 | retval = gs_block_til_ready(port, filp); | ||
1524 | sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", | ||
1525 | retval, port->gs.port.count); | ||
1526 | |||
1527 | if (retval) { | ||
1528 | /* | ||
1529 | * Don't lower gs.port.count here because sx_close() will be called later | ||
1530 | */ | ||
1531 | |||
1532 | return retval; | ||
1533 | } | ||
1534 | /* tty->low_latency = 1; */ | ||
1535 | |||
1536 | port->c_dcd = sx_carrier_raised(&port->gs.port); | ||
1537 | sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); | ||
1538 | |||
1539 | func_exit(); | ||
1540 | return 0; | ||
1541 | |||
1542 | } | ||
1543 | |||
1544 | static void sx_close(void *ptr) | ||
1545 | { | ||
1546 | struct sx_port *port = ptr; | ||
1547 | /* Give the port 5 seconds to close down. */ | ||
1548 | int to = 5 * HZ; | ||
1549 | |||
1550 | func_enter(); | ||
1551 | |||
1552 | sx_setsignals(port, 0, 0); | ||
1553 | sx_reconfigure_port(port); | ||
1554 | sx_send_command(port, HS_CLOSE, 0, 0); | ||
1555 | |||
1556 | while (to-- && (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED)) | ||
1557 | if (msleep_interruptible(10)) | ||
1558 | break; | ||
1559 | if (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) { | ||
1560 | if (sx_send_command(port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) | ||
1561 | != 1) { | ||
1562 | printk(KERN_ERR "sx: sent the force_close command, but " | ||
1563 | "card didn't react\n"); | ||
1564 | } else | ||
1565 | sx_dprintk(SX_DEBUG_CLOSE, "sent the force_close " | ||
1566 | "command.\n"); | ||
1567 | } | ||
1568 | |||
1569 | sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", | ||
1570 | 5 * HZ - to - 1, port->gs.port.count); | ||
1571 | |||
1572 | if (port->gs.port.count) { | ||
1573 | sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", | ||
1574 | port->gs.port.count); | ||
1575 | /*printk("%s SETTING port count to zero: %p count: %d\n", | ||
1576 | __func__, port, port->gs.port.count); | ||
1577 | port->gs.port.count = 0;*/ | ||
1578 | } | ||
1579 | |||
1580 | func_exit(); | ||
1581 | } | ||
1582 | |||
1583 | /* This is relatively thorough. But then again it is only 20 lines. */ | ||
1584 | #define MARCHUP for (i = min; i < max; i++) | ||
1585 | #define MARCHDOWN for (i = max - 1; i >= min; i--) | ||
1586 | #define W0 write_sx_byte(board, i, 0x55) | ||
1587 | #define W1 write_sx_byte(board, i, 0xaa) | ||
1588 | #define R0 if (read_sx_byte(board, i) != 0x55) return 1 | ||
1589 | #define R1 if (read_sx_byte(board, i) != 0xaa) return 1 | ||
1590 | |||
1591 | /* This memtest takes a human-noticable time. You normally only do it | ||
1592 | once a boot, so I guess that it is worth it. */ | ||
1593 | static int do_memtest(struct sx_board *board, int min, int max) | ||
1594 | { | ||
1595 | int i; | ||
1596 | |||
1597 | /* This is a marchb. Theoretically, marchb catches much more than | ||
1598 | simpler tests. In practise, the longer test just catches more | ||
1599 | intermittent errors. -- REW | ||
1600 | (For the theory behind memory testing see: | ||
1601 | Testing Semiconductor Memories by A.J. van de Goor.) */ | ||
1602 | MARCHUP { | ||
1603 | W0; | ||
1604 | } | ||
1605 | MARCHUP { | ||
1606 | R0; | ||
1607 | W1; | ||
1608 | R1; | ||
1609 | W0; | ||
1610 | R0; | ||
1611 | W1; | ||
1612 | } | ||
1613 | MARCHUP { | ||
1614 | R1; | ||
1615 | W0; | ||
1616 | W1; | ||
1617 | } | ||
1618 | MARCHDOWN { | ||
1619 | R1; | ||
1620 | W0; | ||
1621 | W1; | ||
1622 | W0; | ||
1623 | } | ||
1624 | MARCHDOWN { | ||
1625 | R0; | ||
1626 | W1; | ||
1627 | W0; | ||
1628 | } | ||
1629 | |||
1630 | return 0; | ||
1631 | } | ||
1632 | |||
1633 | #undef MARCHUP | ||
1634 | #undef MARCHDOWN | ||
1635 | #undef W0 | ||
1636 | #undef W1 | ||
1637 | #undef R0 | ||
1638 | #undef R1 | ||
1639 | |||
1640 | #define MARCHUP for (i = min; i < max; i += 2) | ||
1641 | #define MARCHDOWN for (i = max - 1; i >= min; i -= 2) | ||
1642 | #define W0 write_sx_word(board, i, 0x55aa) | ||
1643 | #define W1 write_sx_word(board, i, 0xaa55) | ||
1644 | #define R0 if (read_sx_word(board, i) != 0x55aa) return 1 | ||
1645 | #define R1 if (read_sx_word(board, i) != 0xaa55) return 1 | ||
1646 | |||
1647 | #if 0 | ||
1648 | /* This memtest takes a human-noticable time. You normally only do it | ||
1649 | once a boot, so I guess that it is worth it. */ | ||
1650 | static int do_memtest_w(struct sx_board *board, int min, int max) | ||
1651 | { | ||
1652 | int i; | ||
1653 | |||
1654 | MARCHUP { | ||
1655 | W0; | ||
1656 | } | ||
1657 | MARCHUP { | ||
1658 | R0; | ||
1659 | W1; | ||
1660 | R1; | ||
1661 | W0; | ||
1662 | R0; | ||
1663 | W1; | ||
1664 | } | ||
1665 | MARCHUP { | ||
1666 | R1; | ||
1667 | W0; | ||
1668 | W1; | ||
1669 | } | ||
1670 | MARCHDOWN { | ||
1671 | R1; | ||
1672 | W0; | ||
1673 | W1; | ||
1674 | W0; | ||
1675 | } | ||
1676 | MARCHDOWN { | ||
1677 | R0; | ||
1678 | W1; | ||
1679 | W0; | ||
1680 | } | ||
1681 | |||
1682 | return 0; | ||
1683 | } | ||
1684 | #endif | ||
1685 | |||
1686 | static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | ||
1687 | unsigned long arg) | ||
1688 | { | ||
1689 | long rc = 0; | ||
1690 | int __user *descr = (int __user *)arg; | ||
1691 | int i; | ||
1692 | static struct sx_board *board = NULL; | ||
1693 | int nbytes, offset; | ||
1694 | unsigned long data; | ||
1695 | char *tmp; | ||
1696 | |||
1697 | func_enter(); | ||
1698 | |||
1699 | if (!capable(CAP_SYS_RAWIO)) | ||
1700 | return -EPERM; | ||
1701 | |||
1702 | tty_lock(); | ||
1703 | |||
1704 | sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); | ||
1705 | |||
1706 | if (!board) | ||
1707 | board = &boards[0]; | ||
1708 | if (board->flags & SX_BOARD_PRESENT) { | ||
1709 | sx_dprintk(SX_DEBUG_FIRMWARE, "Board present! (%x)\n", | ||
1710 | board->flags); | ||
1711 | } else { | ||
1712 | sx_dprintk(SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", | ||
1713 | board->flags); | ||
1714 | for (i = 0; i < SX_NBOARDS; i++) | ||
1715 | sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); | ||
1716 | sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); | ||
1717 | rc = -EIO; | ||
1718 | goto out; | ||
1719 | } | ||
1720 | |||
1721 | switch (cmd) { | ||
1722 | case SXIO_SET_BOARD: | ||
1723 | sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); | ||
1724 | rc = -EIO; | ||
1725 | if (arg >= SX_NBOARDS) | ||
1726 | break; | ||
1727 | sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n"); | ||
1728 | if (!(boards[arg].flags & SX_BOARD_PRESENT)) | ||
1729 | break; | ||
1730 | sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n"); | ||
1731 | board = &boards[arg]; | ||
1732 | rc = 0; | ||
1733 | /* FIXME: And this does ... nothing?? */ | ||
1734 | break; | ||
1735 | case SXIO_GET_TYPE: | ||
1736 | rc = -ENOENT; /* If we manage to miss one, return error. */ | ||
1737 | if (IS_SX_BOARD(board)) | ||
1738 | rc = SX_TYPE_SX; | ||
1739 | if (IS_CF_BOARD(board)) | ||
1740 | rc = SX_TYPE_CF; | ||
1741 | if (IS_SI_BOARD(board)) | ||
1742 | rc = SX_TYPE_SI; | ||
1743 | if (IS_SI1_BOARD(board)) | ||
1744 | rc = SX_TYPE_SI; | ||
1745 | if (IS_EISA_BOARD(board)) | ||
1746 | rc = SX_TYPE_SI; | ||
1747 | sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc); | ||
1748 | break; | ||
1749 | case SXIO_DO_RAMTEST: | ||
1750 | if (sx_initialized) { /* Already initialized: better not ramtest the board. */ | ||
1751 | rc = -EPERM; | ||
1752 | break; | ||
1753 | } | ||
1754 | if (IS_SX_BOARD(board)) { | ||
1755 | rc = do_memtest(board, 0, 0x7000); | ||
1756 | if (!rc) | ||
1757 | rc = do_memtest(board, 0, 0x7000); | ||
1758 | /*if (!rc) rc = do_memtest_w (board, 0, 0x7000); */ | ||
1759 | } else { | ||
1760 | rc = do_memtest(board, 0, 0x7ff8); | ||
1761 | /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */ | ||
1762 | } | ||
1763 | sx_dprintk(SX_DEBUG_FIRMWARE, | ||
1764 | "returning memtest result= %ld\n", rc); | ||
1765 | break; | ||
1766 | case SXIO_DOWNLOAD: | ||
1767 | if (sx_initialized) {/* Already initialized */ | ||
1768 | rc = -EEXIST; | ||
1769 | break; | ||
1770 | } | ||
1771 | if (!sx_reset(board)) { | ||
1772 | rc = -EIO; | ||
1773 | break; | ||
1774 | } | ||
1775 | sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); | ||
1776 | |||
1777 | tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER); | ||
1778 | if (!tmp) { | ||
1779 | rc = -ENOMEM; | ||
1780 | break; | ||
1781 | } | ||
1782 | /* FIXME: check returns */ | ||
1783 | get_user(nbytes, descr++); | ||
1784 | get_user(offset, descr++); | ||
1785 | get_user(data, descr++); | ||
1786 | while (nbytes && data) { | ||
1787 | for (i = 0; i < nbytes; i += SX_CHUNK_SIZE) { | ||
1788 | if (copy_from_user(tmp, (char __user *)data + i, | ||
1789 | (i + SX_CHUNK_SIZE > nbytes) ? | ||
1790 | nbytes - i : SX_CHUNK_SIZE)) { | ||
1791 | kfree(tmp); | ||
1792 | rc = -EFAULT; | ||
1793 | goto out; | ||
1794 | } | ||
1795 | memcpy_toio(board->base2 + offset + i, tmp, | ||
1796 | (i + SX_CHUNK_SIZE > nbytes) ? | ||
1797 | nbytes - i : SX_CHUNK_SIZE); | ||
1798 | } | ||
1799 | |||
1800 | get_user(nbytes, descr++); | ||
1801 | get_user(offset, descr++); | ||
1802 | get_user(data, descr++); | ||
1803 | } | ||
1804 | kfree(tmp); | ||
1805 | sx_nports += sx_init_board(board); | ||
1806 | rc = sx_nports; | ||
1807 | break; | ||
1808 | case SXIO_INIT: | ||
1809 | if (sx_initialized) { /* Already initialized */ | ||
1810 | rc = -EEXIST; | ||
1811 | break; | ||
1812 | } | ||
1813 | /* This is not allowed until all boards are initialized... */ | ||
1814 | for (i = 0; i < SX_NBOARDS; i++) { | ||
1815 | if ((boards[i].flags & SX_BOARD_PRESENT) && | ||
1816 | !(boards[i].flags & SX_BOARD_INITIALIZED)) { | ||
1817 | rc = -EIO; | ||
1818 | break; | ||
1819 | } | ||
1820 | } | ||
1821 | for (i = 0; i < SX_NBOARDS; i++) | ||
1822 | if (!(boards[i].flags & SX_BOARD_PRESENT)) | ||
1823 | break; | ||
1824 | |||
1825 | sx_dprintk(SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, " | ||
1826 | "%d channels, first board: %d ports\n", | ||
1827 | i, sx_nports, boards[0].nports); | ||
1828 | rc = sx_init_portstructs(i, sx_nports); | ||
1829 | sx_init_drivers(); | ||
1830 | if (rc >= 0) | ||
1831 | sx_initialized++; | ||
1832 | break; | ||
1833 | case SXIO_SETDEBUG: | ||
1834 | sx_debug = arg; | ||
1835 | break; | ||
1836 | case SXIO_GETDEBUG: | ||
1837 | rc = sx_debug; | ||
1838 | break; | ||
1839 | case SXIO_GETGSDEBUG: | ||
1840 | case SXIO_SETGSDEBUG: | ||
1841 | rc = -EINVAL; | ||
1842 | break; | ||
1843 | case SXIO_GETNPORTS: | ||
1844 | rc = sx_nports; | ||
1845 | break; | ||
1846 | default: | ||
1847 | rc = -ENOTTY; | ||
1848 | break; | ||
1849 | } | ||
1850 | out: | ||
1851 | tty_unlock(); | ||
1852 | func_exit(); | ||
1853 | return rc; | ||
1854 | } | ||
1855 | |||
1856 | static int sx_break(struct tty_struct *tty, int flag) | ||
1857 | { | ||
1858 | struct sx_port *port = tty->driver_data; | ||
1859 | int rv; | ||
1860 | |||
1861 | func_enter(); | ||
1862 | tty_lock(); | ||
1863 | |||
1864 | if (flag) | ||
1865 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); | ||
1866 | else | ||
1867 | rv = sx_send_command(port, HS_STOP, -1, HS_IDLE_OPEN); | ||
1868 | if (rv != 1) | ||
1869 | printk(KERN_ERR "sx: couldn't send break (%x).\n", | ||
1870 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); | ||
1871 | tty_unlock(); | ||
1872 | func_exit(); | ||
1873 | return 0; | ||
1874 | } | ||
1875 | |||
1876 | static int sx_tiocmget(struct tty_struct *tty) | ||
1877 | { | ||
1878 | struct sx_port *port = tty->driver_data; | ||
1879 | return sx_getsignals(port); | ||
1880 | } | ||
1881 | |||
1882 | static int sx_tiocmset(struct tty_struct *tty, | ||
1883 | unsigned int set, unsigned int clear) | ||
1884 | { | ||
1885 | struct sx_port *port = tty->driver_data; | ||
1886 | int rts = -1, dtr = -1; | ||
1887 | |||
1888 | if (set & TIOCM_RTS) | ||
1889 | rts = 1; | ||
1890 | if (set & TIOCM_DTR) | ||
1891 | dtr = 1; | ||
1892 | if (clear & TIOCM_RTS) | ||
1893 | rts = 0; | ||
1894 | if (clear & TIOCM_DTR) | ||
1895 | dtr = 0; | ||
1896 | |||
1897 | sx_setsignals(port, dtr, rts); | ||
1898 | sx_reconfigure_port(port); | ||
1899 | return 0; | ||
1900 | } | ||
1901 | |||
1902 | static int sx_ioctl(struct tty_struct *tty, | ||
1903 | unsigned int cmd, unsigned long arg) | ||
1904 | { | ||
1905 | int rc; | ||
1906 | struct sx_port *port = tty->driver_data; | ||
1907 | void __user *argp = (void __user *)arg; | ||
1908 | |||
1909 | /* func_enter2(); */ | ||
1910 | |||
1911 | rc = 0; | ||
1912 | tty_lock(); | ||
1913 | switch (cmd) { | ||
1914 | case TIOCGSERIAL: | ||
1915 | rc = gs_getserial(&port->gs, argp); | ||
1916 | break; | ||
1917 | case TIOCSSERIAL: | ||
1918 | rc = gs_setserial(&port->gs, argp); | ||
1919 | break; | ||
1920 | default: | ||
1921 | rc = -ENOIOCTLCMD; | ||
1922 | break; | ||
1923 | } | ||
1924 | tty_unlock(); | ||
1925 | |||
1926 | /* func_exit(); */ | ||
1927 | return rc; | ||
1928 | } | ||
1929 | |||
1930 | /* The throttle/unthrottle scheme for the Specialix card is different | ||
1931 | * from other drivers and deserves some explanation. | ||
1932 | * The Specialix hardware takes care of XON/XOFF | ||
1933 | * and CTS/RTS flow control itself. This means that all we have to | ||
1934 | * do when signalled by the upper tty layer to throttle/unthrottle is | ||
1935 | * to make a note of it here. When we come to read characters from the | ||
1936 | * rx buffers on the card (sx_receive_chars()) we look to see if the | ||
1937 | * upper layer can accept more (as noted here in sx_rx_throt[]). | ||
1938 | * If it can't we simply don't remove chars from the cards buffer. | ||
1939 | * When the tty layer can accept chars, we again note that here and when | ||
1940 | * sx_receive_chars() is called it will remove them from the cards buffer. | ||
1941 | * The card will notice that a ports buffer has drained below some low | ||
1942 | * water mark and will unflow control the line itself, using whatever | ||
1943 | * flow control scheme is in use for that port. -- Simon Allen | ||
1944 | */ | ||
1945 | |||
1946 | static void sx_throttle(struct tty_struct *tty) | ||
1947 | { | ||
1948 | struct sx_port *port = tty->driver_data; | ||
1949 | |||
1950 | func_enter2(); | ||
1951 | /* If the port is using any type of input flow | ||
1952 | * control then throttle the port. | ||
1953 | */ | ||
1954 | if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { | ||
1955 | port->gs.port.flags |= SX_RX_THROTTLE; | ||
1956 | } | ||
1957 | func_exit(); | ||
1958 | } | ||
1959 | |||
1960 | static void sx_unthrottle(struct tty_struct *tty) | ||
1961 | { | ||
1962 | struct sx_port *port = tty->driver_data; | ||
1963 | |||
1964 | func_enter2(); | ||
1965 | /* Always unthrottle even if flow control is not enabled on | ||
1966 | * this port in case we disabled flow control while the port | ||
1967 | * was throttled | ||
1968 | */ | ||
1969 | port->gs.port.flags &= ~SX_RX_THROTTLE; | ||
1970 | func_exit(); | ||
1971 | return; | ||
1972 | } | ||
1973 | |||
1974 | /* ********************************************************************** * | ||
1975 | * Here are the initialization routines. * | ||
1976 | * ********************************************************************** */ | ||
1977 | |||
1978 | static int sx_init_board(struct sx_board *board) | ||
1979 | { | ||
1980 | int addr; | ||
1981 | int chans; | ||
1982 | int type; | ||
1983 | |||
1984 | func_enter(); | ||
1985 | |||
1986 | /* This is preceded by downloading the download code. */ | ||
1987 | |||
1988 | board->flags |= SX_BOARD_INITIALIZED; | ||
1989 | |||
1990 | if (read_sx_byte(board, 0)) | ||
1991 | /* CF boards may need this. */ | ||
1992 | write_sx_byte(board, 0, 0); | ||
1993 | |||
1994 | /* This resets the processor again, to make sure it didn't do any | ||
1995 | foolish things while we were downloading the image */ | ||
1996 | if (!sx_reset(board)) | ||
1997 | return 0; | ||
1998 | |||
1999 | sx_start_board(board); | ||
2000 | udelay(10); | ||
2001 | if (!sx_busy_wait_neq(board, 0, 0xff, 0)) { | ||
2002 | printk(KERN_ERR "sx: Ooops. Board won't initialize.\n"); | ||
2003 | return 0; | ||
2004 | } | ||
2005 | |||
2006 | /* Ok. So now the processor on the card is running. It gathered | ||
2007 | some info for us... */ | ||
2008 | sx_dprintk(SX_DEBUG_INIT, "The sxcard structure:\n"); | ||
2009 | if (sx_debug & SX_DEBUG_INIT) | ||
2010 | my_hd_io(board->base, 0x10); | ||
2011 | sx_dprintk(SX_DEBUG_INIT, "the first sx_module structure:\n"); | ||
2012 | if (sx_debug & SX_DEBUG_INIT) | ||
2013 | my_hd_io(board->base + 0x80, 0x30); | ||
2014 | |||
2015 | sx_dprintk(SX_DEBUG_INIT, "init_status: %x, %dk memory, firmware " | ||
2016 | "V%x.%02x,\n", | ||
2017 | read_sx_byte(board, 0), read_sx_byte(board, 1), | ||
2018 | read_sx_byte(board, 5), read_sx_byte(board, 4)); | ||
2019 | |||
2020 | if (read_sx_byte(board, 0) == 0xff) { | ||
2021 | printk(KERN_INFO "sx: No modules found. Sorry.\n"); | ||
2022 | board->nports = 0; | ||
2023 | return 0; | ||
2024 | } | ||
2025 | |||
2026 | chans = 0; | ||
2027 | |||
2028 | if (IS_SX_BOARD(board)) { | ||
2029 | sx_write_board_word(board, cc_int_count, sx_maxints); | ||
2030 | } else { | ||
2031 | if (sx_maxints) | ||
2032 | sx_write_board_word(board, cc_int_count, | ||
2033 | SI_PROCESSOR_CLOCK / 8 / sx_maxints); | ||
2034 | } | ||
2035 | |||
2036 | /* grab the first module type... */ | ||
2037 | /* board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */ | ||
2038 | board->ta_type = mod_compat_type(sx_read_module_byte(board, 0x80, | ||
2039 | mc_chip)); | ||
2040 | |||
2041 | /* XXX byteorder */ | ||
2042 | for (addr = 0x80; addr != 0; addr = read_sx_word(board, addr) & 0x7fff){ | ||
2043 | type = sx_read_module_byte(board, addr, mc_chip); | ||
2044 | sx_dprintk(SX_DEBUG_INIT, "Module at %x: %d channels\n", | ||
2045 | addr, read_sx_byte(board, addr + 2)); | ||
2046 | |||
2047 | chans += sx_read_module_byte(board, addr, mc_type); | ||
2048 | |||
2049 | sx_dprintk(SX_DEBUG_INIT, "module is an %s, which has %s/%s " | ||
2050 | "panels\n", | ||
2051 | mod_type_s(type), | ||
2052 | pan_type_s(sx_read_module_byte(board, addr, | ||
2053 | mc_mods) & 0xf), | ||
2054 | pan_type_s(sx_read_module_byte(board, addr, | ||
2055 | mc_mods) >> 4)); | ||
2056 | |||
2057 | sx_dprintk(SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC " | ||
2058 | "version: %x\n", | ||
2059 | sx_read_module_byte(board, addr, mc_rev1), | ||
2060 | sx_read_module_byte(board, addr, mc_rev2), | ||
2061 | sx_read_module_byte(board, addr, mc_mtaasic_rev)); | ||
2062 | |||
2063 | /* The following combinations are illegal: It should theoretically | ||
2064 | work, but timing problems make the bus HANG. */ | ||
2065 | |||
2066 | if (mod_compat_type(type) != board->ta_type) { | ||
2067 | printk(KERN_ERR "sx: This is an invalid " | ||
2068 | "configuration.\nDon't mix TA/MTA/SXDC on the " | ||
2069 | "same hostadapter.\n"); | ||
2070 | chans = 0; | ||
2071 | break; | ||
2072 | } | ||
2073 | if ((IS_EISA_BOARD(board) || | ||
2074 | IS_SI_BOARD(board)) && | ||
2075 | (mod_compat_type(type) == 4)) { | ||
2076 | printk(KERN_ERR "sx: This is an invalid " | ||
2077 | "configuration.\nDon't use SXDCs on an SI/XIO " | ||
2078 | "adapter.\n"); | ||
2079 | chans = 0; | ||
2080 | break; | ||
2081 | } | ||
2082 | #if 0 /* Problem fixed: firmware 3.05 */ | ||
2083 | if (IS_SX_BOARD(board) && (type == TA8)) { | ||
2084 | /* There are some issues with the firmware and the DCD/RTS | ||
2085 | lines. It might work if you tie them together or something. | ||
2086 | It might also work if you get a newer sx_firmware. Therefore | ||
2087 | this is just a warning. */ | ||
2088 | printk(KERN_WARNING | ||
2089 | "sx: The SX host doesn't work too well " | ||
2090 | "with the TA8 adapters.\nSpecialix is working on it.\n"); | ||
2091 | } | ||
2092 | #endif | ||
2093 | } | ||
2094 | |||
2095 | if (chans) { | ||
2096 | if (board->irq > 0) { | ||
2097 | /* fixed irq, probably PCI */ | ||
2098 | if (sx_irqmask & (1 << board->irq)) { /* may we use this irq? */ | ||
2099 | if (request_irq(board->irq, sx_interrupt, | ||
2100 | IRQF_SHARED | IRQF_DISABLED, | ||
2101 | "sx", board)) { | ||
2102 | printk(KERN_ERR "sx: Cannot allocate " | ||
2103 | "irq %d.\n", board->irq); | ||
2104 | board->irq = 0; | ||
2105 | } | ||
2106 | } else | ||
2107 | board->irq = 0; | ||
2108 | } else if (board->irq < 0 && sx_irqmask) { | ||
2109 | /* auto-allocate irq */ | ||
2110 | int irqnr; | ||
2111 | int irqmask = sx_irqmask & (IS_SX_BOARD(board) ? | ||
2112 | SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK); | ||
2113 | for (irqnr = 15; irqnr > 0; irqnr--) | ||
2114 | if (irqmask & (1 << irqnr)) | ||
2115 | if (!request_irq(irqnr, sx_interrupt, | ||
2116 | IRQF_SHARED | IRQF_DISABLED, | ||
2117 | "sx", board)) | ||
2118 | break; | ||
2119 | if (!irqnr) | ||
2120 | printk(KERN_ERR "sx: Cannot allocate IRQ.\n"); | ||
2121 | board->irq = irqnr; | ||
2122 | } else | ||
2123 | board->irq = 0; | ||
2124 | |||
2125 | if (board->irq) { | ||
2126 | /* Found a valid interrupt, start up interrupts! */ | ||
2127 | sx_dprintk(SX_DEBUG_INIT, "Using irq %d.\n", | ||
2128 | board->irq); | ||
2129 | sx_start_interrupts(board); | ||
2130 | board->poll = sx_slowpoll; | ||
2131 | board->flags |= SX_IRQ_ALLOCATED; | ||
2132 | } else { | ||
2133 | /* no irq: setup board for polled operation */ | ||
2134 | board->poll = sx_poll; | ||
2135 | sx_dprintk(SX_DEBUG_INIT, "Using poll-interval %d.\n", | ||
2136 | board->poll); | ||
2137 | } | ||
2138 | |||
2139 | /* The timer should be initialized anyway: That way we can | ||
2140 | safely del_timer it when the module is unloaded. */ | ||
2141 | setup_timer(&board->timer, sx_pollfunc, (unsigned long)board); | ||
2142 | |||
2143 | if (board->poll) | ||
2144 | mod_timer(&board->timer, jiffies + board->poll); | ||
2145 | } else { | ||
2146 | board->irq = 0; | ||
2147 | } | ||
2148 | |||
2149 | board->nports = chans; | ||
2150 | sx_dprintk(SX_DEBUG_INIT, "returning %d ports.", board->nports); | ||
2151 | |||
2152 | func_exit(); | ||
2153 | return chans; | ||
2154 | } | ||
2155 | |||
2156 | static void __devinit printheader(void) | ||
2157 | { | ||
2158 | static int header_printed; | ||
2159 | |||
2160 | if (!header_printed) { | ||
2161 | printk(KERN_INFO "Specialix SX driver " | ||
2162 | "(C) 1998/1999 R.E.Wolff@BitWizard.nl\n"); | ||
2163 | printk(KERN_INFO "sx: version " __stringify(SX_VERSION) "\n"); | ||
2164 | header_printed = 1; | ||
2165 | } | ||
2166 | } | ||
2167 | |||
2168 | static int __devinit probe_sx(struct sx_board *board) | ||
2169 | { | ||
2170 | struct vpd_prom vpdp; | ||
2171 | char *p; | ||
2172 | int i; | ||
2173 | |||
2174 | func_enter(); | ||
2175 | |||
2176 | if (!IS_CF_BOARD(board)) { | ||
2177 | sx_dprintk(SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", | ||
2178 | board->base + SX_VPD_ROM); | ||
2179 | |||
2180 | if (sx_debug & SX_DEBUG_PROBE) | ||
2181 | my_hd_io(board->base + SX_VPD_ROM, 0x40); | ||
2182 | |||
2183 | p = (char *)&vpdp; | ||
2184 | for (i = 0; i < sizeof(struct vpd_prom); i++) | ||
2185 | *p++ = read_sx_byte(board, SX_VPD_ROM + i * 2); | ||
2186 | |||
2187 | if (sx_debug & SX_DEBUG_PROBE) | ||
2188 | my_hd(&vpdp, 0x20); | ||
2189 | |||
2190 | sx_dprintk(SX_DEBUG_PROBE, "checking identifier...\n"); | ||
2191 | |||
2192 | if (strncmp(vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) { | ||
2193 | sx_dprintk(SX_DEBUG_PROBE, "Got non-SX identifier: " | ||
2194 | "'%s'\n", vpdp.identifier); | ||
2195 | return 0; | ||
2196 | } | ||
2197 | } | ||
2198 | |||
2199 | printheader(); | ||
2200 | |||
2201 | if (!IS_CF_BOARD(board)) { | ||
2202 | printk(KERN_DEBUG "sx: Found an SX board at %lx\n", | ||
2203 | board->hw_base); | ||
2204 | printk(KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, " | ||
2205 | "uniq ID:%08x, ", | ||
2206 | vpdp.hwrev, vpdp.hwass, vpdp.uniqid); | ||
2207 | printk("Manufactured: %d/%d\n", 1970 + vpdp.myear, vpdp.mweek); | ||
2208 | |||
2209 | if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != | ||
2210 | SX_PCI_UNIQUEID1) && (((vpdp.uniqid >> 24) & | ||
2211 | SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) { | ||
2212 | /* This might be a bit harsh. This was the primary | ||
2213 | reason the SX/ISA card didn't work at first... */ | ||
2214 | printk(KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA " | ||
2215 | "card. Sorry: giving up.\n"); | ||
2216 | return (0); | ||
2217 | } | ||
2218 | |||
2219 | if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == | ||
2220 | SX_ISA_UNIQUEID1) { | ||
2221 | if (((unsigned long)board->hw_base) & 0x8000) { | ||
2222 | printk(KERN_WARNING "sx: Warning: There may be " | ||
2223 | "hardware problems with the card at " | ||
2224 | "%lx.\n", board->hw_base); | ||
2225 | printk(KERN_WARNING "sx: Read sx.txt for more " | ||
2226 | "info.\n"); | ||
2227 | } | ||
2228 | } | ||
2229 | } | ||
2230 | |||
2231 | board->nports = -1; | ||
2232 | |||
2233 | /* This resets the processor, and keeps it off the bus. */ | ||
2234 | if (!sx_reset(board)) | ||
2235 | return 0; | ||
2236 | sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); | ||
2237 | |||
2238 | func_exit(); | ||
2239 | return 1; | ||
2240 | } | ||
2241 | |||
2242 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | ||
2243 | |||
2244 | /* Specialix probes for this card at 32k increments from 640k to 16M. | ||
2245 | I consider machines with less than 16M unlikely nowadays, so I'm | ||
2246 | not probing above 1Mb. Also, 0xa0000, 0xb0000, are taken by the VGA | ||
2247 | card. 0xe0000 and 0xf0000 are taken by the BIOS. That only leaves | ||
2248 | 0xc0000, 0xc8000, 0xd0000 and 0xd8000 . */ | ||
2249 | |||
2250 | static int __devinit probe_si(struct sx_board *board) | ||
2251 | { | ||
2252 | int i; | ||
2253 | |||
2254 | func_enter(); | ||
2255 | sx_dprintk(SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at " | ||
2256 | "%p.\n", board->hw_base, board->base + SI2_ISA_ID_BASE); | ||
2257 | |||
2258 | if (sx_debug & SX_DEBUG_PROBE) | ||
2259 | my_hd_io(board->base + SI2_ISA_ID_BASE, 0x8); | ||
2260 | |||
2261 | if (!IS_EISA_BOARD(board)) { | ||
2262 | if (IS_SI1_BOARD(board)) { | ||
2263 | for (i = 0; i < 8; i++) { | ||
2264 | write_sx_byte(board, SI2_ISA_ID_BASE + 7 - i,i); | ||
2265 | } | ||
2266 | } | ||
2267 | for (i = 0; i < 8; i++) { | ||
2268 | if ((read_sx_byte(board, SI2_ISA_ID_BASE + 7 - i) & 7) | ||
2269 | != i) { | ||
2270 | func_exit(); | ||
2271 | return 0; | ||
2272 | } | ||
2273 | } | ||
2274 | } | ||
2275 | |||
2276 | /* Now we're pretty much convinced that there is an SI board here, | ||
2277 | but to prevent trouble, we'd better double check that we don't | ||
2278 | have an SI1 board when we're probing for an SI2 board.... */ | ||
2279 | |||
2280 | write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); | ||
2281 | if (IS_SI1_BOARD(board)) { | ||
2282 | /* This should be an SI1 board, which has this | ||
2283 | location writable... */ | ||
2284 | if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { | ||
2285 | func_exit(); | ||
2286 | return 0; | ||
2287 | } | ||
2288 | } else { | ||
2289 | /* This should be an SI2 board, which has the bottom | ||
2290 | 3 bits non-writable... */ | ||
2291 | if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { | ||
2292 | func_exit(); | ||
2293 | return 0; | ||
2294 | } | ||
2295 | } | ||
2296 | |||
2297 | /* Now we're pretty much convinced that there is an SI board here, | ||
2298 | but to prevent trouble, we'd better double check that we don't | ||
2299 | have an SI1 board when we're probing for an SI2 board.... */ | ||
2300 | |||
2301 | write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); | ||
2302 | if (IS_SI1_BOARD(board)) { | ||
2303 | /* This should be an SI1 board, which has this | ||
2304 | location writable... */ | ||
2305 | if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { | ||
2306 | func_exit(); | ||
2307 | return 0; | ||
2308 | } | ||
2309 | } else { | ||
2310 | /* This should be an SI2 board, which has the bottom | ||
2311 | 3 bits non-writable... */ | ||
2312 | if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { | ||
2313 | func_exit(); | ||
2314 | return 0; | ||
2315 | } | ||
2316 | } | ||
2317 | |||
2318 | printheader(); | ||
2319 | |||
2320 | printk(KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base); | ||
2321 | /* Compared to the SX boards, it is a complete guess as to what | ||
2322 | this card is up to... */ | ||
2323 | |||
2324 | board->nports = -1; | ||
2325 | |||
2326 | /* This resets the processor, and keeps it off the bus. */ | ||
2327 | if (!sx_reset(board)) | ||
2328 | return 0; | ||
2329 | sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); | ||
2330 | |||
2331 | func_exit(); | ||
2332 | return 1; | ||
2333 | } | ||
2334 | #endif | ||
2335 | |||
2336 | static const struct tty_operations sx_ops = { | ||
2337 | .break_ctl = sx_break, | ||
2338 | .open = sx_open, | ||
2339 | .close = gs_close, | ||
2340 | .write = gs_write, | ||
2341 | .put_char = gs_put_char, | ||
2342 | .flush_chars = gs_flush_chars, | ||
2343 | .write_room = gs_write_room, | ||
2344 | .chars_in_buffer = gs_chars_in_buffer, | ||
2345 | .flush_buffer = gs_flush_buffer, | ||
2346 | .ioctl = sx_ioctl, | ||
2347 | .throttle = sx_throttle, | ||
2348 | .unthrottle = sx_unthrottle, | ||
2349 | .set_termios = gs_set_termios, | ||
2350 | .stop = gs_stop, | ||
2351 | .start = gs_start, | ||
2352 | .hangup = gs_hangup, | ||
2353 | .tiocmget = sx_tiocmget, | ||
2354 | .tiocmset = sx_tiocmset, | ||
2355 | }; | ||
2356 | |||
2357 | static const struct tty_port_operations sx_port_ops = { | ||
2358 | .carrier_raised = sx_carrier_raised, | ||
2359 | }; | ||
2360 | |||
2361 | static int sx_init_drivers(void) | ||
2362 | { | ||
2363 | int error; | ||
2364 | |||
2365 | func_enter(); | ||
2366 | |||
2367 | sx_driver = alloc_tty_driver(sx_nports); | ||
2368 | if (!sx_driver) | ||
2369 | return 1; | ||
2370 | sx_driver->owner = THIS_MODULE; | ||
2371 | sx_driver->driver_name = "specialix_sx"; | ||
2372 | sx_driver->name = "ttyX"; | ||
2373 | sx_driver->major = SX_NORMAL_MAJOR; | ||
2374 | sx_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
2375 | sx_driver->subtype = SERIAL_TYPE_NORMAL; | ||
2376 | sx_driver->init_termios = tty_std_termios; | ||
2377 | sx_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
2378 | sx_driver->init_termios.c_ispeed = 9600; | ||
2379 | sx_driver->init_termios.c_ospeed = 9600; | ||
2380 | sx_driver->flags = TTY_DRIVER_REAL_RAW; | ||
2381 | tty_set_operations(sx_driver, &sx_ops); | ||
2382 | |||
2383 | if ((error = tty_register_driver(sx_driver))) { | ||
2384 | put_tty_driver(sx_driver); | ||
2385 | printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n", | ||
2386 | error); | ||
2387 | return 1; | ||
2388 | } | ||
2389 | func_exit(); | ||
2390 | return 0; | ||
2391 | } | ||
2392 | |||
2393 | static int sx_init_portstructs(int nboards, int nports) | ||
2394 | { | ||
2395 | struct sx_board *board; | ||
2396 | struct sx_port *port; | ||
2397 | int i, j; | ||
2398 | int addr, chans; | ||
2399 | int portno; | ||
2400 | |||
2401 | func_enter(); | ||
2402 | |||
2403 | /* Many drivers statically allocate the maximum number of ports | ||
2404 | There is no reason not to allocate them dynamically. | ||
2405 | Is there? -- REW */ | ||
2406 | sx_ports = kcalloc(nports, sizeof(struct sx_port), GFP_KERNEL); | ||
2407 | if (!sx_ports) | ||
2408 | return -ENOMEM; | ||
2409 | |||
2410 | port = sx_ports; | ||
2411 | for (i = 0; i < nboards; i++) { | ||
2412 | board = &boards[i]; | ||
2413 | board->ports = port; | ||
2414 | for (j = 0; j < boards[i].nports; j++) { | ||
2415 | sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); | ||
2416 | tty_port_init(&port->gs.port); | ||
2417 | port->gs.port.ops = &sx_port_ops; | ||
2418 | port->gs.magic = SX_MAGIC; | ||
2419 | port->gs.close_delay = HZ / 2; | ||
2420 | port->gs.closing_wait = 30 * HZ; | ||
2421 | port->board = board; | ||
2422 | port->gs.rd = &sx_real_driver; | ||
2423 | #ifdef NEW_WRITE_LOCKING | ||
2424 | port->gs.port_write_mutex = MUTEX; | ||
2425 | #endif | ||
2426 | spin_lock_init(&port->gs.driver_lock); | ||
2427 | /* | ||
2428 | * Initializing wait queue | ||
2429 | */ | ||
2430 | port++; | ||
2431 | } | ||
2432 | } | ||
2433 | |||
2434 | port = sx_ports; | ||
2435 | portno = 0; | ||
2436 | for (i = 0; i < nboards; i++) { | ||
2437 | board = &boards[i]; | ||
2438 | board->port_base = portno; | ||
2439 | /* Possibly the configuration was rejected. */ | ||
2440 | sx_dprintk(SX_DEBUG_PROBE, "Board has %d channels\n", | ||
2441 | board->nports); | ||
2442 | if (board->nports <= 0) | ||
2443 | continue; | ||
2444 | /* XXX byteorder ?? */ | ||
2445 | for (addr = 0x80; addr != 0; | ||
2446 | addr = read_sx_word(board, addr) & 0x7fff) { | ||
2447 | chans = sx_read_module_byte(board, addr, mc_type); | ||
2448 | sx_dprintk(SX_DEBUG_PROBE, "Module at %x: %d " | ||
2449 | "channels\n", addr, chans); | ||
2450 | sx_dprintk(SX_DEBUG_PROBE, "Port at"); | ||
2451 | for (j = 0; j < chans; j++) { | ||
2452 | /* The "sx-way" is the way it SHOULD be done. | ||
2453 | That way in the future, the firmware may for | ||
2454 | example pack the structures a bit more | ||
2455 | efficient. Neil tells me it isn't going to | ||
2456 | happen anytime soon though. */ | ||
2457 | if (IS_SX_BOARD(board)) | ||
2458 | port->ch_base = sx_read_module_word( | ||
2459 | board, addr + j * 2, | ||
2460 | mc_chan_pointer); | ||
2461 | else | ||
2462 | port->ch_base = addr + 0x100 + 0x300 *j; | ||
2463 | |||
2464 | sx_dprintk(SX_DEBUG_PROBE, " %x", | ||
2465 | port->ch_base); | ||
2466 | port->line = portno++; | ||
2467 | port++; | ||
2468 | } | ||
2469 | sx_dprintk(SX_DEBUG_PROBE, "\n"); | ||
2470 | } | ||
2471 | /* This has to be done earlier. */ | ||
2472 | /* board->flags |= SX_BOARD_INITIALIZED; */ | ||
2473 | } | ||
2474 | |||
2475 | func_exit(); | ||
2476 | return 0; | ||
2477 | } | ||
2478 | |||
2479 | static unsigned int sx_find_free_board(void) | ||
2480 | { | ||
2481 | unsigned int i; | ||
2482 | |||
2483 | for (i = 0; i < SX_NBOARDS; i++) | ||
2484 | if (!(boards[i].flags & SX_BOARD_PRESENT)) | ||
2485 | break; | ||
2486 | |||
2487 | return i; | ||
2488 | } | ||
2489 | |||
2490 | static void __exit sx_release_drivers(void) | ||
2491 | { | ||
2492 | func_enter(); | ||
2493 | tty_unregister_driver(sx_driver); | ||
2494 | put_tty_driver(sx_driver); | ||
2495 | func_exit(); | ||
2496 | } | ||
2497 | |||
2498 | static void __devexit sx_remove_card(struct sx_board *board, | ||
2499 | struct pci_dev *pdev) | ||
2500 | { | ||
2501 | if (board->flags & SX_BOARD_INITIALIZED) { | ||
2502 | /* The board should stop messing with us. (actually I mean the | ||
2503 | interrupt) */ | ||
2504 | sx_reset(board); | ||
2505 | if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED)) | ||
2506 | free_irq(board->irq, board); | ||
2507 | |||
2508 | /* It is safe/allowed to del_timer a non-active timer */ | ||
2509 | del_timer(&board->timer); | ||
2510 | if (pdev) { | ||
2511 | #ifdef CONFIG_PCI | ||
2512 | iounmap(board->base2); | ||
2513 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); | ||
2514 | #endif | ||
2515 | } else { | ||
2516 | iounmap(board->base); | ||
2517 | release_region(board->hw_base, board->hw_len); | ||
2518 | } | ||
2519 | |||
2520 | board->flags &= ~(SX_BOARD_INITIALIZED | SX_BOARD_PRESENT); | ||
2521 | } | ||
2522 | } | ||
2523 | |||
2524 | #ifdef CONFIG_EISA | ||
2525 | |||
2526 | static int __devinit sx_eisa_probe(struct device *dev) | ||
2527 | { | ||
2528 | struct eisa_device *edev = to_eisa_device(dev); | ||
2529 | struct sx_board *board; | ||
2530 | unsigned long eisa_slot = edev->base_addr; | ||
2531 | unsigned int i; | ||
2532 | int retval = -EIO; | ||
2533 | |||
2534 | mutex_lock(&sx_boards_lock); | ||
2535 | i = sx_find_free_board(); | ||
2536 | if (i == SX_NBOARDS) { | ||
2537 | mutex_unlock(&sx_boards_lock); | ||
2538 | goto err; | ||
2539 | } | ||
2540 | board = &boards[i]; | ||
2541 | board->flags |= SX_BOARD_PRESENT; | ||
2542 | mutex_unlock(&sx_boards_lock); | ||
2543 | |||
2544 | dev_info(dev, "XIO : Signature found in EISA slot %lu, " | ||
2545 | "Product %d Rev %d (REPORT THIS TO LKLM)\n", | ||
2546 | eisa_slot >> 12, | ||
2547 | inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2), | ||
2548 | inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3)); | ||
2549 | |||
2550 | board->eisa_base = eisa_slot; | ||
2551 | board->flags &= ~SX_BOARD_TYPE; | ||
2552 | board->flags |= SI_EISA_BOARD; | ||
2553 | |||
2554 | board->hw_base = ((inb(eisa_slot + 0xc01) << 8) + | ||
2555 | inb(eisa_slot + 0xc00)) << 16; | ||
2556 | board->hw_len = SI2_EISA_WINDOW_LEN; | ||
2557 | if (!request_region(board->hw_base, board->hw_len, "sx")) { | ||
2558 | dev_err(dev, "can't request region\n"); | ||
2559 | goto err_flag; | ||
2560 | } | ||
2561 | board->base2 = | ||
2562 | board->base = ioremap_nocache(board->hw_base, SI2_EISA_WINDOW_LEN); | ||
2563 | if (!board->base) { | ||
2564 | dev_err(dev, "can't remap memory\n"); | ||
2565 | goto err_reg; | ||
2566 | } | ||
2567 | |||
2568 | sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base); | ||
2569 | sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base); | ||
2570 | board->irq = inb(eisa_slot + 0xc02) >> 4; | ||
2571 | sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq); | ||
2572 | |||
2573 | if (!probe_si(board)) | ||
2574 | goto err_unmap; | ||
2575 | |||
2576 | dev_set_drvdata(dev, board); | ||
2577 | |||
2578 | return 0; | ||
2579 | err_unmap: | ||
2580 | iounmap(board->base); | ||
2581 | err_reg: | ||
2582 | release_region(board->hw_base, board->hw_len); | ||
2583 | err_flag: | ||
2584 | board->flags &= ~SX_BOARD_PRESENT; | ||
2585 | err: | ||
2586 | return retval; | ||
2587 | } | ||
2588 | |||
2589 | static int __devexit sx_eisa_remove(struct device *dev) | ||
2590 | { | ||
2591 | struct sx_board *board = dev_get_drvdata(dev); | ||
2592 | |||
2593 | sx_remove_card(board, NULL); | ||
2594 | |||
2595 | return 0; | ||
2596 | } | ||
2597 | |||
2598 | static struct eisa_device_id sx_eisa_tbl[] = { | ||
2599 | { "SLX" }, | ||
2600 | { "" } | ||
2601 | }; | ||
2602 | |||
2603 | MODULE_DEVICE_TABLE(eisa, sx_eisa_tbl); | ||
2604 | |||
2605 | static struct eisa_driver sx_eisadriver = { | ||
2606 | .id_table = sx_eisa_tbl, | ||
2607 | .driver = { | ||
2608 | .name = "sx", | ||
2609 | .probe = sx_eisa_probe, | ||
2610 | .remove = __devexit_p(sx_eisa_remove), | ||
2611 | } | ||
2612 | }; | ||
2613 | |||
2614 | #endif | ||
2615 | |||
2616 | #ifdef CONFIG_PCI | ||
2617 | /******************************************************** | ||
2618 | * Setting bit 17 in the CNTRL register of the PLX 9050 * | ||
2619 | * chip forces a retry on writes while a read is pending.* | ||
2620 | * This is to prevent the card locking up on Intel Xeon * | ||
2621 | * multiprocessor systems with the NX chipset. -- NV * | ||
2622 | ********************************************************/ | ||
2623 | |||
2624 | /* Newer cards are produced with this bit set from the configuration | ||
2625 | EEprom. As the bit is read/write for the CPU, we can fix it here, | ||
2626 | if we detect that it isn't set correctly. -- REW */ | ||
2627 | |||
2628 | static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board) | ||
2629 | { | ||
2630 | unsigned int hwbase; | ||
2631 | void __iomem *rebase; | ||
2632 | unsigned int t; | ||
2633 | |||
2634 | #define CNTRL_REG_OFFSET 0x50 | ||
2635 | #define CNTRL_REG_GOODVALUE 0x18260000 | ||
2636 | |||
2637 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); | ||
2638 | hwbase &= PCI_BASE_ADDRESS_MEM_MASK; | ||
2639 | rebase = ioremap_nocache(hwbase, 0x80); | ||
2640 | t = readl(rebase + CNTRL_REG_OFFSET); | ||
2641 | if (t != CNTRL_REG_GOODVALUE) { | ||
2642 | printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> " | ||
2643 | "%08x\n", t, CNTRL_REG_GOODVALUE); | ||
2644 | writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); | ||
2645 | } | ||
2646 | iounmap(rebase); | ||
2647 | } | ||
2648 | #endif | ||
2649 | |||
2650 | static int __devinit sx_pci_probe(struct pci_dev *pdev, | ||
2651 | const struct pci_device_id *ent) | ||
2652 | { | ||
2653 | #ifdef CONFIG_PCI | ||
2654 | struct sx_board *board; | ||
2655 | unsigned int i, reg; | ||
2656 | int retval = -EIO; | ||
2657 | |||
2658 | mutex_lock(&sx_boards_lock); | ||
2659 | i = sx_find_free_board(); | ||
2660 | if (i == SX_NBOARDS) { | ||
2661 | mutex_unlock(&sx_boards_lock); | ||
2662 | goto err; | ||
2663 | } | ||
2664 | board = &boards[i]; | ||
2665 | board->flags |= SX_BOARD_PRESENT; | ||
2666 | mutex_unlock(&sx_boards_lock); | ||
2667 | |||
2668 | retval = pci_enable_device(pdev); | ||
2669 | if (retval) | ||
2670 | goto err_flag; | ||
2671 | |||
2672 | board->flags &= ~SX_BOARD_TYPE; | ||
2673 | board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD : | ||
2674 | SX_CFPCI_BOARD; | ||
2675 | |||
2676 | /* CF boards use base address 3.... */ | ||
2677 | reg = IS_CF_BOARD(board) ? 3 : 2; | ||
2678 | retval = pci_request_region(pdev, reg, "sx"); | ||
2679 | if (retval) { | ||
2680 | dev_err(&pdev->dev, "can't request region\n"); | ||
2681 | goto err_flag; | ||
2682 | } | ||
2683 | board->hw_base = pci_resource_start(pdev, reg); | ||
2684 | board->base2 = | ||
2685 | board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board)); | ||
2686 | if (!board->base) { | ||
2687 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
2688 | goto err_reg; | ||
2689 | } | ||
2690 | |||
2691 | /* Most of the stuff on the CF board is offset by 0x18000 .... */ | ||
2692 | if (IS_CF_BOARD(board)) | ||
2693 | board->base += 0x18000; | ||
2694 | |||
2695 | board->irq = pdev->irq; | ||
2696 | |||
2697 | dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base, | ||
2698 | board->irq, board->flags); | ||
2699 | |||
2700 | if (!probe_sx(board)) { | ||
2701 | retval = -EIO; | ||
2702 | goto err_unmap; | ||
2703 | } | ||
2704 | |||
2705 | fix_sx_pci(pdev, board); | ||
2706 | |||
2707 | pci_set_drvdata(pdev, board); | ||
2708 | |||
2709 | return 0; | ||
2710 | err_unmap: | ||
2711 | iounmap(board->base2); | ||
2712 | err_reg: | ||
2713 | pci_release_region(pdev, reg); | ||
2714 | err_flag: | ||
2715 | board->flags &= ~SX_BOARD_PRESENT; | ||
2716 | err: | ||
2717 | return retval; | ||
2718 | #else | ||
2719 | return -ENODEV; | ||
2720 | #endif | ||
2721 | } | ||
2722 | |||
2723 | static void __devexit sx_pci_remove(struct pci_dev *pdev) | ||
2724 | { | ||
2725 | struct sx_board *board = pci_get_drvdata(pdev); | ||
2726 | |||
2727 | sx_remove_card(board, pdev); | ||
2728 | } | ||
2729 | |||
2730 | /* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say | ||
2731 | its because the standard requires it. So check for SUBVENDOR_ID. */ | ||
2732 | static struct pci_device_id sx_pci_tbl[] = { | ||
2733 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, | ||
2734 | .subvendor = PCI_ANY_ID, .subdevice = 0x0200 }, | ||
2735 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, | ||
2736 | .subvendor = PCI_ANY_ID, .subdevice = 0x0300 }, | ||
2737 | { 0 } | ||
2738 | }; | ||
2739 | |||
2740 | MODULE_DEVICE_TABLE(pci, sx_pci_tbl); | ||
2741 | |||
2742 | static struct pci_driver sx_pcidriver = { | ||
2743 | .name = "sx", | ||
2744 | .id_table = sx_pci_tbl, | ||
2745 | .probe = sx_pci_probe, | ||
2746 | .remove = __devexit_p(sx_pci_remove) | ||
2747 | }; | ||
2748 | |||
2749 | static int __init sx_init(void) | ||
2750 | { | ||
2751 | #ifdef CONFIG_EISA | ||
2752 | int retval1; | ||
2753 | #endif | ||
2754 | #ifdef CONFIG_ISA | ||
2755 | struct sx_board *board; | ||
2756 | unsigned int i; | ||
2757 | #endif | ||
2758 | unsigned int found = 0; | ||
2759 | int retval; | ||
2760 | |||
2761 | func_enter(); | ||
2762 | sx_dprintk(SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", | ||
2763 | sx_debug); | ||
2764 | if (abs((long)(&sx_debug) - sx_debug) < 0x10000) { | ||
2765 | printk(KERN_WARNING "sx: sx_debug is an address, instead of a " | ||
2766 | "value. Assuming -1.\n(%p)\n", &sx_debug); | ||
2767 | sx_debug = -1; | ||
2768 | } | ||
2769 | |||
2770 | if (misc_register(&sx_fw_device) < 0) { | ||
2771 | printk(KERN_ERR "SX: Unable to register firmware loader " | ||
2772 | "driver.\n"); | ||
2773 | return -EIO; | ||
2774 | } | ||
2775 | #ifdef CONFIG_ISA | ||
2776 | for (i = 0; i < NR_SX_ADDRS; i++) { | ||
2777 | board = &boards[found]; | ||
2778 | board->hw_base = sx_probe_addrs[i]; | ||
2779 | board->hw_len = SX_WINDOW_LEN; | ||
2780 | if (!request_region(board->hw_base, board->hw_len, "sx")) | ||
2781 | continue; | ||
2782 | board->base2 = | ||
2783 | board->base = ioremap_nocache(board->hw_base, board->hw_len); | ||
2784 | if (!board->base) | ||
2785 | goto err_sx_reg; | ||
2786 | board->flags &= ~SX_BOARD_TYPE; | ||
2787 | board->flags |= SX_ISA_BOARD; | ||
2788 | board->irq = sx_irqmask ? -1 : 0; | ||
2789 | |||
2790 | if (probe_sx(board)) { | ||
2791 | board->flags |= SX_BOARD_PRESENT; | ||
2792 | found++; | ||
2793 | } else { | ||
2794 | iounmap(board->base); | ||
2795 | err_sx_reg: | ||
2796 | release_region(board->hw_base, board->hw_len); | ||
2797 | } | ||
2798 | } | ||
2799 | |||
2800 | for (i = 0; i < NR_SI_ADDRS; i++) { | ||
2801 | board = &boards[found]; | ||
2802 | board->hw_base = si_probe_addrs[i]; | ||
2803 | board->hw_len = SI2_ISA_WINDOW_LEN; | ||
2804 | if (!request_region(board->hw_base, board->hw_len, "sx")) | ||
2805 | continue; | ||
2806 | board->base2 = | ||
2807 | board->base = ioremap_nocache(board->hw_base, board->hw_len); | ||
2808 | if (!board->base) | ||
2809 | goto err_si_reg; | ||
2810 | board->flags &= ~SX_BOARD_TYPE; | ||
2811 | board->flags |= SI_ISA_BOARD; | ||
2812 | board->irq = sx_irqmask ? -1 : 0; | ||
2813 | |||
2814 | if (probe_si(board)) { | ||
2815 | board->flags |= SX_BOARD_PRESENT; | ||
2816 | found++; | ||
2817 | } else { | ||
2818 | iounmap(board->base); | ||
2819 | err_si_reg: | ||
2820 | release_region(board->hw_base, board->hw_len); | ||
2821 | } | ||
2822 | } | ||
2823 | for (i = 0; i < NR_SI1_ADDRS; i++) { | ||
2824 | board = &boards[found]; | ||
2825 | board->hw_base = si1_probe_addrs[i]; | ||
2826 | board->hw_len = SI1_ISA_WINDOW_LEN; | ||
2827 | if (!request_region(board->hw_base, board->hw_len, "sx")) | ||
2828 | continue; | ||
2829 | board->base2 = | ||
2830 | board->base = ioremap_nocache(board->hw_base, board->hw_len); | ||
2831 | if (!board->base) | ||
2832 | goto err_si1_reg; | ||
2833 | board->flags &= ~SX_BOARD_TYPE; | ||
2834 | board->flags |= SI1_ISA_BOARD; | ||
2835 | board->irq = sx_irqmask ? -1 : 0; | ||
2836 | |||
2837 | if (probe_si(board)) { | ||
2838 | board->flags |= SX_BOARD_PRESENT; | ||
2839 | found++; | ||
2840 | } else { | ||
2841 | iounmap(board->base); | ||
2842 | err_si1_reg: | ||
2843 | release_region(board->hw_base, board->hw_len); | ||
2844 | } | ||
2845 | } | ||
2846 | #endif | ||
2847 | #ifdef CONFIG_EISA | ||
2848 | retval1 = eisa_driver_register(&sx_eisadriver); | ||
2849 | #endif | ||
2850 | retval = pci_register_driver(&sx_pcidriver); | ||
2851 | |||
2852 | if (found) { | ||
2853 | printk(KERN_INFO "sx: total of %d boards detected.\n", found); | ||
2854 | retval = 0; | ||
2855 | } else if (retval) { | ||
2856 | #ifdef CONFIG_EISA | ||
2857 | retval = retval1; | ||
2858 | if (retval1) | ||
2859 | #endif | ||
2860 | misc_deregister(&sx_fw_device); | ||
2861 | } | ||
2862 | |||
2863 | func_exit(); | ||
2864 | return retval; | ||
2865 | } | ||
2866 | |||
2867 | static void __exit sx_exit(void) | ||
2868 | { | ||
2869 | int i; | ||
2870 | |||
2871 | func_enter(); | ||
2872 | #ifdef CONFIG_EISA | ||
2873 | eisa_driver_unregister(&sx_eisadriver); | ||
2874 | #endif | ||
2875 | pci_unregister_driver(&sx_pcidriver); | ||
2876 | |||
2877 | for (i = 0; i < SX_NBOARDS; i++) | ||
2878 | sx_remove_card(&boards[i], NULL); | ||
2879 | |||
2880 | if (misc_deregister(&sx_fw_device) < 0) { | ||
2881 | printk(KERN_INFO "sx: couldn't deregister firmware loader " | ||
2882 | "device\n"); | ||
2883 | } | ||
2884 | sx_dprintk(SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", | ||
2885 | sx_initialized); | ||
2886 | if (sx_initialized) | ||
2887 | sx_release_drivers(); | ||
2888 | |||
2889 | kfree(sx_ports); | ||
2890 | func_exit(); | ||
2891 | } | ||
2892 | |||
2893 | module_init(sx_init); | ||
2894 | module_exit(sx_exit); | ||
diff --git a/drivers/char/sx.h b/drivers/char/sx.h deleted file mode 100644 index 87c2defdead7..000000000000 --- a/drivers/char/sx.h +++ /dev/null | |||
@@ -1,201 +0,0 @@ | |||
1 | |||
2 | /* | ||
3 | * sx.h | ||
4 | * | ||
5 | * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl | ||
6 | * | ||
7 | * SX serial driver. | ||
8 | * -- Supports SI, XIO and SX host cards. | ||
9 | * -- Supports TAs, MTAs and SXDCs. | ||
10 | * | ||
11 | * Version 1.3 -- March, 1999. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #define SX_NBOARDS 4 | ||
16 | #define SX_PORTSPERBOARD 32 | ||
17 | #define SX_NPORTS (SX_NBOARDS * SX_PORTSPERBOARD) | ||
18 | |||
19 | #ifdef __KERNEL__ | ||
20 | |||
21 | #define SX_MAGIC 0x12345678 | ||
22 | |||
23 | struct sx_port { | ||
24 | struct gs_port gs; | ||
25 | struct wait_queue *shutdown_wait; | ||
26 | int ch_base; | ||
27 | int c_dcd; | ||
28 | struct sx_board *board; | ||
29 | int line; | ||
30 | unsigned long locks; | ||
31 | }; | ||
32 | |||
33 | struct sx_board { | ||
34 | int magic; | ||
35 | void __iomem *base; | ||
36 | void __iomem *base2; | ||
37 | unsigned long hw_base; | ||
38 | resource_size_t hw_len; | ||
39 | int eisa_base; | ||
40 | int port_base; /* Number of the first port */ | ||
41 | struct sx_port *ports; | ||
42 | int nports; | ||
43 | int flags; | ||
44 | int irq; | ||
45 | int poll; | ||
46 | int ta_type; | ||
47 | struct timer_list timer; | ||
48 | unsigned long locks; | ||
49 | }; | ||
50 | |||
51 | struct vpd_prom { | ||
52 | unsigned short id; | ||
53 | char hwrev; | ||
54 | char hwass; | ||
55 | int uniqid; | ||
56 | char myear; | ||
57 | char mweek; | ||
58 | char hw_feature[5]; | ||
59 | char oem_id; | ||
60 | char identifier[16]; | ||
61 | }; | ||
62 | |||
63 | #ifndef MOD_RS232DB25MALE | ||
64 | #define MOD_RS232DB25MALE 0x0a | ||
65 | #endif | ||
66 | |||
67 | #define SI_ISA_BOARD 0x00000001 | ||
68 | #define SX_ISA_BOARD 0x00000002 | ||
69 | #define SX_PCI_BOARD 0x00000004 | ||
70 | #define SX_CFPCI_BOARD 0x00000008 | ||
71 | #define SX_CFISA_BOARD 0x00000010 | ||
72 | #define SI_EISA_BOARD 0x00000020 | ||
73 | #define SI1_ISA_BOARD 0x00000040 | ||
74 | |||
75 | #define SX_BOARD_PRESENT 0x00001000 | ||
76 | #define SX_BOARD_INITIALIZED 0x00002000 | ||
77 | #define SX_IRQ_ALLOCATED 0x00004000 | ||
78 | |||
79 | #define SX_BOARD_TYPE 0x000000ff | ||
80 | |||
81 | #define IS_SX_BOARD(board) (board->flags & (SX_PCI_BOARD | SX_CFPCI_BOARD | \ | ||
82 | SX_ISA_BOARD | SX_CFISA_BOARD)) | ||
83 | |||
84 | #define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD) | ||
85 | #define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD) | ||
86 | |||
87 | #define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD) | ||
88 | |||
89 | #define IS_CF_BOARD(board) (board->flags & (SX_CFISA_BOARD | SX_CFPCI_BOARD)) | ||
90 | |||
91 | /* The SI processor clock is required to calculate the cc_int_count register | ||
92 | value for the SI cards. */ | ||
93 | #define SI_PROCESSOR_CLOCK 25000000 | ||
94 | |||
95 | |||
96 | /* port flags */ | ||
97 | /* Make sure these don't clash with gs flags or async flags */ | ||
98 | #define SX_RX_THROTTLE 0x0000001 | ||
99 | |||
100 | |||
101 | |||
102 | #define SX_PORT_TRANSMIT_LOCK 0 | ||
103 | #define SX_BOARD_INTR_LOCK 0 | ||
104 | |||
105 | |||
106 | |||
107 | /* Debug flags. Add these together to get more debug info. */ | ||
108 | |||
109 | #define SX_DEBUG_OPEN 0x00000001 | ||
110 | #define SX_DEBUG_SETTING 0x00000002 | ||
111 | #define SX_DEBUG_FLOW 0x00000004 | ||
112 | #define SX_DEBUG_MODEMSIGNALS 0x00000008 | ||
113 | #define SX_DEBUG_TERMIOS 0x00000010 | ||
114 | #define SX_DEBUG_TRANSMIT 0x00000020 | ||
115 | #define SX_DEBUG_RECEIVE 0x00000040 | ||
116 | #define SX_DEBUG_INTERRUPTS 0x00000080 | ||
117 | #define SX_DEBUG_PROBE 0x00000100 | ||
118 | #define SX_DEBUG_INIT 0x00000200 | ||
119 | #define SX_DEBUG_CLEANUP 0x00000400 | ||
120 | #define SX_DEBUG_CLOSE 0x00000800 | ||
121 | #define SX_DEBUG_FIRMWARE 0x00001000 | ||
122 | #define SX_DEBUG_MEMTEST 0x00002000 | ||
123 | |||
124 | #define SX_DEBUG_ALL 0xffffffff | ||
125 | |||
126 | |||
127 | #define O_OTHER(tty) \ | ||
128 | ((O_OLCUC(tty)) ||\ | ||
129 | (O_ONLCR(tty)) ||\ | ||
130 | (O_OCRNL(tty)) ||\ | ||
131 | (O_ONOCR(tty)) ||\ | ||
132 | (O_ONLRET(tty)) ||\ | ||
133 | (O_OFILL(tty)) ||\ | ||
134 | (O_OFDEL(tty)) ||\ | ||
135 | (O_NLDLY(tty)) ||\ | ||
136 | (O_CRDLY(tty)) ||\ | ||
137 | (O_TABDLY(tty)) ||\ | ||
138 | (O_BSDLY(tty)) ||\ | ||
139 | (O_VTDLY(tty)) ||\ | ||
140 | (O_FFDLY(tty))) | ||
141 | |||
142 | /* Same for input. */ | ||
143 | #define I_OTHER(tty) \ | ||
144 | ((I_INLCR(tty)) ||\ | ||
145 | (I_IGNCR(tty)) ||\ | ||
146 | (I_ICRNL(tty)) ||\ | ||
147 | (I_IUCLC(tty)) ||\ | ||
148 | (L_ISIG(tty))) | ||
149 | |||
150 | #define MOD_TA ( TA>>4) | ||
151 | #define MOD_MTA (MTA_CD1400>>4) | ||
152 | #define MOD_SXDC ( SXDC>>4) | ||
153 | |||
154 | |||
155 | /* We copy the download code over to the card in chunks of ... bytes */ | ||
156 | #define SX_CHUNK_SIZE 128 | ||
157 | |||
158 | #endif /* __KERNEL__ */ | ||
159 | |||
160 | |||
161 | |||
162 | /* Specialix document 6210046-11 page 3 */ | ||
163 | #define SPX(X) (('S'<<24) | ('P' << 16) | (X)) | ||
164 | |||
165 | /* Specialix-Linux specific IOCTLS. */ | ||
166 | #define SPXL(X) (SPX(('L' << 8) | (X))) | ||
167 | |||
168 | |||
169 | #define SXIO_SET_BOARD SPXL(0x01) | ||
170 | #define SXIO_GET_TYPE SPXL(0x02) | ||
171 | #define SXIO_DOWNLOAD SPXL(0x03) | ||
172 | #define SXIO_INIT SPXL(0x04) | ||
173 | #define SXIO_SETDEBUG SPXL(0x05) | ||
174 | #define SXIO_GETDEBUG SPXL(0x06) | ||
175 | #define SXIO_DO_RAMTEST SPXL(0x07) | ||
176 | #define SXIO_SETGSDEBUG SPXL(0x08) | ||
177 | #define SXIO_GETGSDEBUG SPXL(0x09) | ||
178 | #define SXIO_GETNPORTS SPXL(0x0a) | ||
179 | |||
180 | |||
181 | #ifndef SXCTL_MISC_MINOR | ||
182 | /* Allow others to gather this into "major.h" or something like that */ | ||
183 | #define SXCTL_MISC_MINOR 167 | ||
184 | #endif | ||
185 | |||
186 | #ifndef SX_NORMAL_MAJOR | ||
187 | /* This allows overriding on the compiler commandline, or in a "major.h" | ||
188 | include or something like that */ | ||
189 | #define SX_NORMAL_MAJOR 32 | ||
190 | #define SX_CALLOUT_MAJOR 33 | ||
191 | #endif | ||
192 | |||
193 | |||
194 | #define SX_TYPE_SX 0x01 | ||
195 | #define SX_TYPE_SI 0x02 | ||
196 | #define SX_TYPE_CF 0x03 | ||
197 | |||
198 | |||
199 | #define WINDOW_LEN(board) (IS_CF_BOARD(board)?0x20000:SX_WINDOW_LEN) | ||
200 | /* Need a #define for ^^^^^^^ !!! */ | ||
201 | |||
diff --git a/drivers/char/sxboards.h b/drivers/char/sxboards.h deleted file mode 100644 index 427927dc7dbf..000000000000 --- a/drivers/char/sxboards.h +++ /dev/null | |||
@@ -1,206 +0,0 @@ | |||
1 | /************************************************************************/ | ||
2 | /* */ | ||
3 | /* Title : SX/SI/XIO Board Hardware Definitions */ | ||
4 | /* */ | ||
5 | /* Author : N.P.Vassallo */ | ||
6 | /* */ | ||
7 | /* Creation : 16th March 1998 */ | ||
8 | /* */ | ||
9 | /* Version : 3.0.0 */ | ||
10 | /* */ | ||
11 | /* Copyright : (c) Specialix International Ltd. 1998 */ | ||
12 | /* */ | ||
13 | /* Description : Prototypes, structures and definitions */ | ||
14 | /* describing the SX/SI/XIO board hardware */ | ||
15 | /* */ | ||
16 | /************************************************************************/ | ||
17 | |||
18 | /* History... | ||
19 | |||
20 | 3.0.0 16/03/98 NPV Creation. | ||
21 | |||
22 | */ | ||
23 | |||
24 | #ifndef _sxboards_h /* If SXBOARDS.H not already defined */ | ||
25 | #define _sxboards_h 1 | ||
26 | |||
27 | /***************************************************************************** | ||
28 | ******************************* ****************************** | ||
29 | ******************************* Board Types ****************************** | ||
30 | ******************************* ****************************** | ||
31 | *****************************************************************************/ | ||
32 | |||
33 | /* BUS types... */ | ||
34 | #define BUS_ISA 0 | ||
35 | #define BUS_MCA 1 | ||
36 | #define BUS_EISA 2 | ||
37 | #define BUS_PCI 3 | ||
38 | |||
39 | /* Board phases... */ | ||
40 | #define SI1_Z280 1 | ||
41 | #define SI2_Z280 2 | ||
42 | #define SI3_T225 3 | ||
43 | |||
44 | /* Board types... */ | ||
45 | #define CARD_TYPE(bus,phase) (bus<<4|phase) | ||
46 | #define CARD_BUS(type) ((type>>4)&0xF) | ||
47 | #define CARD_PHASE(type) (type&0xF) | ||
48 | |||
49 | #define TYPE_SI1_ISA CARD_TYPE(BUS_ISA,SI1_Z280) | ||
50 | #define TYPE_SI2_ISA CARD_TYPE(BUS_ISA,SI2_Z280) | ||
51 | #define TYPE_SI2_EISA CARD_TYPE(BUS_EISA,SI2_Z280) | ||
52 | #define TYPE_SI2_PCI CARD_TYPE(BUS_PCI,SI2_Z280) | ||
53 | |||
54 | #define TYPE_SX_ISA CARD_TYPE(BUS_ISA,SI3_T225) | ||
55 | #define TYPE_SX_PCI CARD_TYPE(BUS_PCI,SI3_T225) | ||
56 | /***************************************************************************** | ||
57 | ****************************** ****************************** | ||
58 | ****************************** Phase 1 Z280 ****************************** | ||
59 | ****************************** ****************************** | ||
60 | *****************************************************************************/ | ||
61 | |||
62 | /* ISA board details... */ | ||
63 | #define SI1_ISA_WINDOW_LEN 0x10000 /* 64 Kbyte shared memory window */ | ||
64 | //#define SI1_ISA_MEMORY_LEN 0x8000 /* Usable memory - unused define*/ | ||
65 | //#define SI1_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ | ||
66 | //#define SI1_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ | ||
67 | //#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ | ||
68 | //#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ | ||
69 | |||
70 | /* ISA board, register definitions... */ | ||
71 | //#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ | ||
72 | #define SI1_ISA_RESET 0x8000 /* WRITE: Host Reset */ | ||
73 | #define SI1_ISA_RESET_CLEAR 0xc000 /* WRITE: Host Reset clear*/ | ||
74 | #define SI1_ISA_WAIT 0x9000 /* WRITE: Host wait */ | ||
75 | #define SI1_ISA_WAIT_CLEAR 0xd000 /* WRITE: Host wait clear */ | ||
76 | #define SI1_ISA_INTCL 0xa000 /* WRITE: Host Reset */ | ||
77 | #define SI1_ISA_INTCL_CLEAR 0xe000 /* WRITE: Host Reset */ | ||
78 | |||
79 | |||
80 | /***************************************************************************** | ||
81 | ****************************** ****************************** | ||
82 | ****************************** Phase 2 Z280 ****************************** | ||
83 | ****************************** ****************************** | ||
84 | *****************************************************************************/ | ||
85 | |||
86 | /* ISA board details... */ | ||
87 | #define SI2_ISA_WINDOW_LEN 0x8000 /* 32 Kbyte shared memory window */ | ||
88 | #define SI2_ISA_MEMORY_LEN 0x7FF8 /* Usable memory */ | ||
89 | #define SI2_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ | ||
90 | #define SI2_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ | ||
91 | #define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ | ||
92 | #define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ | ||
93 | |||
94 | /* ISA board, register definitions... */ | ||
95 | #define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ | ||
96 | #define SI2_ISA_RESET SI2_ISA_ID_BASE /* WRITE: Host Reset */ | ||
97 | #define SI2_ISA_IRQ11 (SI2_ISA_ID_BASE+1) /* WRITE: Set IRQ11 */ | ||
98 | #define SI2_ISA_IRQ12 (SI2_ISA_ID_BASE+2) /* WRITE: Set IRQ12 */ | ||
99 | #define SI2_ISA_IRQ15 (SI2_ISA_ID_BASE+3) /* WRITE: Set IRQ15 */ | ||
100 | #define SI2_ISA_IRQSET (SI2_ISA_ID_BASE+4) /* WRITE: Set Host Interrupt */ | ||
101 | #define SI2_ISA_INTCLEAR (SI2_ISA_ID_BASE+5) /* WRITE: Enable Host Interrupt */ | ||
102 | |||
103 | #define SI2_ISA_IRQ11_SET 0x10 | ||
104 | #define SI2_ISA_IRQ11_CLEAR 0x00 | ||
105 | #define SI2_ISA_IRQ12_SET 0x10 | ||
106 | #define SI2_ISA_IRQ12_CLEAR 0x00 | ||
107 | #define SI2_ISA_IRQ15_SET 0x10 | ||
108 | #define SI2_ISA_IRQ15_CLEAR 0x00 | ||
109 | #define SI2_ISA_INTCLEAR_SET 0x10 | ||
110 | #define SI2_ISA_INTCLEAR_CLEAR 0x00 | ||
111 | #define SI2_ISA_IRQSET_CLEAR 0x10 | ||
112 | #define SI2_ISA_IRQSET_SET 0x00 | ||
113 | #define SI2_ISA_RESET_SET 0x00 | ||
114 | #define SI2_ISA_RESET_CLEAR 0x10 | ||
115 | |||
116 | /* PCI board details... */ | ||
117 | #define SI2_PCI_WINDOW_LEN 0x100000 /* 1 Mbyte memory window */ | ||
118 | |||
119 | /* PCI board register definitions... */ | ||
120 | #define SI2_PCI_SET_IRQ 0x40001 /* Set Host Interrupt */ | ||
121 | #define SI2_PCI_RESET 0xC0001 /* Host Reset */ | ||
122 | |||
123 | /***************************************************************************** | ||
124 | ****************************** ****************************** | ||
125 | ****************************** Phase 3 T225 ****************************** | ||
126 | ****************************** ****************************** | ||
127 | *****************************************************************************/ | ||
128 | |||
129 | /* General board details... */ | ||
130 | #define SX_WINDOW_LEN 64*1024 /* 64 Kbyte memory window */ | ||
131 | |||
132 | /* ISA board details... */ | ||
133 | #define SX_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ | ||
134 | #define SX_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ | ||
135 | #define SX_ISA_ADDR_STEP SX_WINDOW_LEN /* ISA board address step */ | ||
136 | #define SX_ISA_IRQ_MASK 0x9E00 /* IRQs 15,12,11,10,9 */ | ||
137 | |||
138 | /* Hardware register definitions... */ | ||
139 | #define SX_EVENT_STATUS 0x7800 /* READ: T225 Event Status */ | ||
140 | #define SX_EVENT_STROBE 0x7800 /* WRITE: T225 Event Strobe */ | ||
141 | #define SX_EVENT_ENABLE 0x7880 /* WRITE: T225 Event Enable */ | ||
142 | #define SX_VPD_ROM 0x7C00 /* READ: Vital Product Data ROM */ | ||
143 | #define SX_CONFIG 0x7C00 /* WRITE: Host Configuration Register */ | ||
144 | #define SX_IRQ_STATUS 0x7C80 /* READ: Host Interrupt Status */ | ||
145 | #define SX_SET_IRQ 0x7C80 /* WRITE: Set Host Interrupt */ | ||
146 | #define SX_RESET_STATUS 0x7D00 /* READ: Host Reset Status */ | ||
147 | #define SX_RESET 0x7D00 /* WRITE: Host Reset */ | ||
148 | #define SX_RESET_IRQ 0x7D80 /* WRITE: Reset Host Interrupt */ | ||
149 | |||
150 | /* SX_VPD_ROM definitions... */ | ||
151 | #define SX_VPD_SLX_ID1 0x00 | ||
152 | #define SX_VPD_SLX_ID2 0x01 | ||
153 | #define SX_VPD_HW_REV 0x02 | ||
154 | #define SX_VPD_HW_ASSEM 0x03 | ||
155 | #define SX_VPD_UNIQUEID4 0x04 | ||
156 | #define SX_VPD_UNIQUEID3 0x05 | ||
157 | #define SX_VPD_UNIQUEID2 0x06 | ||
158 | #define SX_VPD_UNIQUEID1 0x07 | ||
159 | #define SX_VPD_MANU_YEAR 0x08 | ||
160 | #define SX_VPD_MANU_WEEK 0x09 | ||
161 | #define SX_VPD_IDENT 0x10 | ||
162 | #define SX_VPD_IDENT_STRING "JET HOST BY KEV#" | ||
163 | |||
164 | /* SX unique identifiers... */ | ||
165 | #define SX_UNIQUEID_MASK 0xF0 | ||
166 | #define SX_ISA_UNIQUEID1 0x20 | ||
167 | #define SX_PCI_UNIQUEID1 0x50 | ||
168 | |||
169 | /* SX_CONFIG definitions... */ | ||
170 | #define SX_CONF_BUSEN 0x02 /* Enable T225 memory and I/O */ | ||
171 | #define SX_CONF_HOSTIRQ 0x04 /* Enable board to host interrupt */ | ||
172 | |||
173 | /* SX bootstrap... */ | ||
174 | #define SX_BOOTSTRAP "\x28\x20\x21\x02\x60\x0a" | ||
175 | #define SX_BOOTSTRAP_SIZE 6 | ||
176 | #define SX_BOOTSTRAP_ADDR (0x8000-SX_BOOTSTRAP_SIZE) | ||
177 | |||
178 | /***************************************************************************** | ||
179 | ********************************** ********************************** | ||
180 | ********************************** EISA ********************************** | ||
181 | ********************************** ********************************** | ||
182 | *****************************************************************************/ | ||
183 | |||
184 | #define SI2_EISA_OFF 0x42 | ||
185 | #define SI2_EISA_VAL 0x01 | ||
186 | #define SI2_EISA_WINDOW_LEN 0x10000 | ||
187 | |||
188 | /***************************************************************************** | ||
189 | *********************************** ********************************** | ||
190 | *********************************** PCI ********************************** | ||
191 | *********************************** ********************************** | ||
192 | *****************************************************************************/ | ||
193 | |||
194 | /* General definitions... */ | ||
195 | |||
196 | #define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ | ||
197 | #define SPX_DEVICE_ID 0x4000 /* SI/XIO boards */ | ||
198 | #define SPX_PLXDEVICE_ID 0x2000 /* SX boards */ | ||
199 | |||
200 | #define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ | ||
201 | #define SI2_SUB_SYS_ID 0x400 /* Phase 2 (Z280) board */ | ||
202 | #define SX_SUB_SYS_ID 0x200 /* Phase 3 (t225) board */ | ||
203 | |||
204 | #endif /*_sxboards_h */ | ||
205 | |||
206 | /* End of SXBOARDS.H */ | ||
diff --git a/drivers/char/sxwindow.h b/drivers/char/sxwindow.h deleted file mode 100644 index cf01b662aefc..000000000000 --- a/drivers/char/sxwindow.h +++ /dev/null | |||
@@ -1,393 +0,0 @@ | |||
1 | /************************************************************************/ | ||
2 | /* */ | ||
3 | /* Title : SX Shared Memory Window Structure */ | ||
4 | /* */ | ||
5 | /* Author : N.P.Vassallo */ | ||
6 | /* */ | ||
7 | /* Creation : 16th March 1998 */ | ||
8 | /* */ | ||
9 | /* Version : 3.0.0 */ | ||
10 | /* */ | ||
11 | /* Copyright : (c) Specialix International Ltd. 1998 */ | ||
12 | /* */ | ||
13 | /* Description : Prototypes, structures and definitions */ | ||
14 | /* describing the SX/SI/XIO cards shared */ | ||
15 | /* memory window structure: */ | ||
16 | /* SXCARD */ | ||
17 | /* SXMODULE */ | ||
18 | /* SXCHANNEL */ | ||
19 | /* */ | ||
20 | /************************************************************************/ | ||
21 | |||
22 | /* History... | ||
23 | |||
24 | 3.0.0 16/03/98 NPV Creation. (based on STRUCT.H) | ||
25 | |||
26 | */ | ||
27 | |||
28 | #ifndef _sxwindow_h /* If SXWINDOW.H not already defined */ | ||
29 | #define _sxwindow_h 1 | ||
30 | |||
31 | /***************************************************************************** | ||
32 | *************************** *************************** | ||
33 | *************************** Common Definitions *************************** | ||
34 | *************************** *************************** | ||
35 | *****************************************************************************/ | ||
36 | |||
37 | typedef struct _SXCARD *PSXCARD; /* SXCARD structure pointer */ | ||
38 | typedef struct _SXMODULE *PMOD; /* SXMODULE structure pointer */ | ||
39 | typedef struct _SXCHANNEL *PCHAN; /* SXCHANNEL structure pointer */ | ||
40 | |||
41 | /***************************************************************************** | ||
42 | ********************************* ********************************* | ||
43 | ********************************* SXCARD ********************************* | ||
44 | ********************************* ********************************* | ||
45 | *****************************************************************************/ | ||
46 | |||
47 | typedef struct _SXCARD | ||
48 | { | ||
49 | BYTE cc_init_status; /* 0x00 Initialisation status */ | ||
50 | BYTE cc_mem_size; /* 0x01 Size of memory on card */ | ||
51 | WORD cc_int_count; /* 0x02 Interrupt count */ | ||
52 | WORD cc_revision; /* 0x04 Download code revision */ | ||
53 | BYTE cc_isr_count; /* 0x06 Count when ISR is run */ | ||
54 | BYTE cc_main_count; /* 0x07 Count when main loop is run */ | ||
55 | WORD cc_int_pending; /* 0x08 Interrupt pending */ | ||
56 | WORD cc_poll_count; /* 0x0A Count when poll is run */ | ||
57 | BYTE cc_int_set_count; /* 0x0C Count when host interrupt is set */ | ||
58 | BYTE cc_rfu[0x80 - 0x0D]; /* 0x0D Pad structure to 128 bytes (0x80) */ | ||
59 | |||
60 | } SXCARD; | ||
61 | |||
62 | /* SXCARD.cc_init_status definitions... */ | ||
63 | #define ADAPTERS_FOUND (BYTE)0x01 | ||
64 | #define NO_ADAPTERS_FOUND (BYTE)0xFF | ||
65 | |||
66 | /* SXCARD.cc_mem_size definitions... */ | ||
67 | #define SX_MEMORY_SIZE (BYTE)0x40 | ||
68 | |||
69 | /* SXCARD.cc_int_count definitions... */ | ||
70 | #define INT_COUNT_DEFAULT 100 /* Hz */ | ||
71 | |||
72 | /***************************************************************************** | ||
73 | ******************************** ******************************** | ||
74 | ******************************** SXMODULE ******************************** | ||
75 | ******************************** ******************************** | ||
76 | *****************************************************************************/ | ||
77 | |||
78 | #define TOP_POINTER(a) ((a)|0x8000) /* Sets top bit of word */ | ||
79 | #define UNTOP_POINTER(a) ((a)&~0x8000) /* Clears top bit of word */ | ||
80 | |||
81 | typedef struct _SXMODULE | ||
82 | { | ||
83 | WORD mc_next; /* 0x00 Next module "pointer" (ORed with 0x8000) */ | ||
84 | BYTE mc_type; /* 0x02 Type of TA in terms of number of channels */ | ||
85 | BYTE mc_mod_no; /* 0x03 Module number on SI bus cable (0 closest to card) */ | ||
86 | BYTE mc_dtr; /* 0x04 Private DTR copy (TA only) */ | ||
87 | BYTE mc_rfu1; /* 0x05 Reserved */ | ||
88 | WORD mc_uart; /* 0x06 UART base address for this module */ | ||
89 | BYTE mc_chip; /* 0x08 Chip type / number of ports */ | ||
90 | BYTE mc_current_uart; /* 0x09 Current uart selected for this module */ | ||
91 | #ifdef DOWNLOAD | ||
92 | PCHAN mc_chan_pointer[8]; /* 0x0A Pointer to each channel structure */ | ||
93 | #else | ||
94 | WORD mc_chan_pointer[8]; /* 0x0A Define as WORD if not compiling into download */ | ||
95 | #endif | ||
96 | WORD mc_rfu2; /* 0x1A Reserved */ | ||
97 | BYTE mc_opens1; /* 0x1C Number of open ports on first four ports on MTA/SXDC */ | ||
98 | BYTE mc_opens2; /* 0x1D Number of open ports on second four ports on MTA/SXDC */ | ||
99 | BYTE mc_mods; /* 0x1E Types of connector module attached to MTA/SXDC */ | ||
100 | BYTE mc_rev1; /* 0x1F Revision of first CD1400 on MTA/SXDC */ | ||
101 | BYTE mc_rev2; /* 0x20 Revision of second CD1400 on MTA/SXDC */ | ||
102 | BYTE mc_mtaasic_rev; /* 0x21 Revision of MTA ASIC 1..4 -> A, B, C, D */ | ||
103 | BYTE mc_rfu3[0x100 - 0x22]; /* 0x22 Pad structure to 256 bytes (0x100) */ | ||
104 | |||
105 | } SXMODULE; | ||
106 | |||
107 | /* SXMODULE.mc_type definitions... */ | ||
108 | #define FOUR_PORTS (BYTE)4 | ||
109 | #define EIGHT_PORTS (BYTE)8 | ||
110 | |||
111 | /* SXMODULE.mc_chip definitions... */ | ||
112 | #define CHIP_MASK 0xF0 | ||
113 | #define TA (BYTE)0 | ||
114 | #define TA4 (TA | FOUR_PORTS) | ||
115 | #define TA8 (TA | EIGHT_PORTS) | ||
116 | #define TA4_ASIC (BYTE)0x0A | ||
117 | #define TA8_ASIC (BYTE)0x0B | ||
118 | #define MTA_CD1400 (BYTE)0x28 | ||
119 | #define SXDC (BYTE)0x48 | ||
120 | |||
121 | /* SXMODULE.mc_mods definitions... */ | ||
122 | #define MOD_RS232DB25 0x00 /* RS232 DB25 (socket/plug) */ | ||
123 | #define MOD_RS232RJ45 0x01 /* RS232 RJ45 (shielded/opto-isolated) */ | ||
124 | #define MOD_RESERVED_2 0x02 /* Reserved (RS485) */ | ||
125 | #define MOD_RS422DB25 0x03 /* RS422 DB25 Socket */ | ||
126 | #define MOD_RESERVED_4 0x04 /* Reserved */ | ||
127 | #define MOD_PARALLEL 0x05 /* Parallel */ | ||
128 | #define MOD_RESERVED_6 0x06 /* Reserved (RS423) */ | ||
129 | #define MOD_RESERVED_7 0x07 /* Reserved */ | ||
130 | #define MOD_2_RS232DB25 0x08 /* Rev 2.0 RS232 DB25 (socket/plug) */ | ||
131 | #define MOD_2_RS232RJ45 0x09 /* Rev 2.0 RS232 RJ45 */ | ||
132 | #define MOD_RESERVED_A 0x0A /* Rev 2.0 Reserved */ | ||
133 | #define MOD_2_RS422DB25 0x0B /* Rev 2.0 RS422 DB25 */ | ||
134 | #define MOD_RESERVED_C 0x0C /* Rev 2.0 Reserved */ | ||
135 | #define MOD_2_PARALLEL 0x0D /* Rev 2.0 Parallel */ | ||
136 | #define MOD_RESERVED_E 0x0E /* Rev 2.0 Reserved */ | ||
137 | #define MOD_BLANK 0x0F /* Blank Panel */ | ||
138 | |||
139 | /***************************************************************************** | ||
140 | ******************************** ******************************* | ||
141 | ******************************** SXCHANNEL ******************************* | ||
142 | ******************************** ******************************* | ||
143 | *****************************************************************************/ | ||
144 | |||
145 | #define TX_BUFF_OFFSET 0x60 /* Transmit buffer offset in channel structure */ | ||
146 | #define BUFF_POINTER(a) (((a)+TX_BUFF_OFFSET)|0x8000) | ||
147 | #define UNBUFF_POINTER(a) (jet_channel*)(((a)&~0x8000)-TX_BUFF_OFFSET) | ||
148 | #define BUFFER_SIZE 256 | ||
149 | #define HIGH_WATER ((BUFFER_SIZE / 4) * 3) | ||
150 | #define LOW_WATER (BUFFER_SIZE / 4) | ||
151 | |||
152 | typedef struct _SXCHANNEL | ||
153 | { | ||
154 | WORD next_item; /* 0x00 Offset from window base of next channels hi_txbuf (ORred with 0x8000) */ | ||
155 | WORD addr_uart; /* 0x02 INTERNAL pointer to uart address. Includes FASTPATH bit */ | ||
156 | WORD module; /* 0x04 Offset from window base of parent SXMODULE structure */ | ||
157 | BYTE type; /* 0x06 Chip type / number of ports (copy of mc_chip) */ | ||
158 | BYTE chan_number; /* 0x07 Channel number on the TA/MTA/SXDC */ | ||
159 | WORD xc_status; /* 0x08 Flow control and I/O status */ | ||
160 | BYTE hi_rxipos; /* 0x0A Receive buffer input index */ | ||
161 | BYTE hi_rxopos; /* 0x0B Receive buffer output index */ | ||
162 | BYTE hi_txopos; /* 0x0C Transmit buffer output index */ | ||
163 | BYTE hi_txipos; /* 0x0D Transmit buffer input index */ | ||
164 | BYTE hi_hstat; /* 0x0E Command register */ | ||
165 | BYTE dtr_bit; /* 0x0F INTERNAL DTR control byte (TA only) */ | ||
166 | BYTE txon; /* 0x10 INTERNAL copy of hi_txon */ | ||
167 | BYTE txoff; /* 0x11 INTERNAL copy of hi_txoff */ | ||
168 | BYTE rxon; /* 0x12 INTERNAL copy of hi_rxon */ | ||
169 | BYTE rxoff; /* 0x13 INTERNAL copy of hi_rxoff */ | ||
170 | BYTE hi_mr1; /* 0x14 Mode Register 1 (databits,parity,RTS rx flow)*/ | ||
171 | BYTE hi_mr2; /* 0x15 Mode Register 2 (stopbits,local,CTS tx flow)*/ | ||
172 | BYTE hi_csr; /* 0x16 Clock Select Register (baud rate) */ | ||
173 | BYTE hi_op; /* 0x17 Modem Output Signal */ | ||
174 | BYTE hi_ip; /* 0x18 Modem Input Signal */ | ||
175 | BYTE hi_state; /* 0x19 Channel status */ | ||
176 | BYTE hi_prtcl; /* 0x1A Channel protocol (flow control) */ | ||
177 | BYTE hi_txon; /* 0x1B Transmit XON character */ | ||
178 | BYTE hi_txoff; /* 0x1C Transmit XOFF character */ | ||
179 | BYTE hi_rxon; /* 0x1D Receive XON character */ | ||
180 | BYTE hi_rxoff; /* 0x1E Receive XOFF character */ | ||
181 | BYTE close_prev; /* 0x1F INTERNAL channel previously closed flag */ | ||
182 | BYTE hi_break; /* 0x20 Break and error control */ | ||
183 | BYTE break_state; /* 0x21 INTERNAL copy of hi_break */ | ||
184 | BYTE hi_mask; /* 0x22 Mask for received data */ | ||
185 | BYTE mask; /* 0x23 INTERNAL copy of hi_mask */ | ||
186 | BYTE mod_type; /* 0x24 MTA/SXDC hardware module type */ | ||
187 | BYTE ccr_state; /* 0x25 INTERNAL MTA/SXDC state of CCR register */ | ||
188 | BYTE ip_mask; /* 0x26 Input handshake mask */ | ||
189 | BYTE hi_parallel; /* 0x27 Parallel port flag */ | ||
190 | BYTE par_error; /* 0x28 Error code for parallel loopback test */ | ||
191 | BYTE any_sent; /* 0x29 INTERNAL data sent flag */ | ||
192 | BYTE asic_txfifo_size; /* 0x2A INTERNAL SXDC transmit FIFO size */ | ||
193 | BYTE rfu1[2]; /* 0x2B Reserved */ | ||
194 | BYTE csr; /* 0x2D INTERNAL copy of hi_csr */ | ||
195 | #ifdef DOWNLOAD | ||
196 | PCHAN nextp; /* 0x2E Offset from window base of next channel structure */ | ||
197 | #else | ||
198 | WORD nextp; /* 0x2E Define as WORD if not compiling into download */ | ||
199 | #endif | ||
200 | BYTE prtcl; /* 0x30 INTERNAL copy of hi_prtcl */ | ||
201 | BYTE mr1; /* 0x31 INTERNAL copy of hi_mr1 */ | ||
202 | BYTE mr2; /* 0x32 INTERNAL copy of hi_mr2 */ | ||
203 | BYTE hi_txbaud; /* 0x33 Extended transmit baud rate (SXDC only if((hi_csr&0x0F)==0x0F) */ | ||
204 | BYTE hi_rxbaud; /* 0x34 Extended receive baud rate (SXDC only if((hi_csr&0xF0)==0xF0) */ | ||
205 | BYTE txbreak_state; /* 0x35 INTERNAL MTA/SXDC transmit break state */ | ||
206 | BYTE txbaud; /* 0x36 INTERNAL copy of hi_txbaud */ | ||
207 | BYTE rxbaud; /* 0x37 INTERNAL copy of hi_rxbaud */ | ||
208 | WORD err_framing; /* 0x38 Count of receive framing errors */ | ||
209 | WORD err_parity; /* 0x3A Count of receive parity errors */ | ||
210 | WORD err_overrun; /* 0x3C Count of receive overrun errors */ | ||
211 | WORD err_overflow; /* 0x3E Count of receive buffer overflow errors */ | ||
212 | BYTE rfu2[TX_BUFF_OFFSET - 0x40]; /* 0x40 Reserved until hi_txbuf */ | ||
213 | BYTE hi_txbuf[BUFFER_SIZE]; /* 0x060 Transmit buffer */ | ||
214 | BYTE hi_rxbuf[BUFFER_SIZE]; /* 0x160 Receive buffer */ | ||
215 | BYTE rfu3[0x300 - 0x260]; /* 0x260 Reserved until 768 bytes (0x300) */ | ||
216 | |||
217 | } SXCHANNEL; | ||
218 | |||
219 | /* SXCHANNEL.addr_uart definitions... */ | ||
220 | #define FASTPATH 0x1000 /* Set to indicate fast rx/tx processing (TA only) */ | ||
221 | |||
222 | /* SXCHANNEL.xc_status definitions... */ | ||
223 | #define X_TANY 0x0001 /* XON is any character (TA only) */ | ||
224 | #define X_TION 0x0001 /* Tx interrupts on (MTA only) */ | ||
225 | #define X_TXEN 0x0002 /* Tx XON/XOFF enabled (TA only) */ | ||
226 | #define X_RTSEN 0x0002 /* RTS FLOW enabled (MTA only) */ | ||
227 | #define X_TXRC 0x0004 /* XOFF received (TA only) */ | ||
228 | #define X_RTSLOW 0x0004 /* RTS dropped (MTA only) */ | ||
229 | #define X_RXEN 0x0008 /* Rx XON/XOFF enabled */ | ||
230 | #define X_ANYXO 0x0010 /* XOFF pending/sent or RTS dropped */ | ||
231 | #define X_RXSE 0x0020 /* Rx XOFF sent */ | ||
232 | #define X_NPEND 0x0040 /* Rx XON pending or XOFF pending */ | ||
233 | #define X_FPEND 0x0080 /* Rx XOFF pending */ | ||
234 | #define C_CRSE 0x0100 /* Carriage return sent (TA only) */ | ||
235 | #define C_TEMR 0x0100 /* Tx empty requested (MTA only) */ | ||
236 | #define C_TEMA 0x0200 /* Tx empty acked (MTA only) */ | ||
237 | #define C_ANYP 0x0200 /* Any protocol bar tx XON/XOFF (TA only) */ | ||
238 | #define C_EN 0x0400 /* Cooking enabled (on MTA means port is also || */ | ||
239 | #define C_HIGH 0x0800 /* Buffer previously hit high water */ | ||
240 | #define C_CTSEN 0x1000 /* CTS automatic flow-control enabled */ | ||
241 | #define C_DCDEN 0x2000 /* DCD/DTR checking enabled */ | ||
242 | #define C_BREAK 0x4000 /* Break detected */ | ||
243 | #define C_RTSEN 0x8000 /* RTS automatic flow control enabled (MTA only) */ | ||
244 | #define C_PARITY 0x8000 /* Parity checking enabled (TA only) */ | ||
245 | |||
246 | /* SXCHANNEL.hi_hstat definitions... */ | ||
247 | #define HS_IDLE_OPEN 0x00 /* Channel open state */ | ||
248 | #define HS_LOPEN 0x02 /* Local open command (no modem monitoring) */ | ||
249 | #define HS_MOPEN 0x04 /* Modem open command (wait for DCD signal) */ | ||
250 | #define HS_IDLE_MPEND 0x06 /* Waiting for DCD signal state */ | ||
251 | #define HS_CONFIG 0x08 /* Configuration command */ | ||
252 | #define HS_CLOSE 0x0A /* Close command */ | ||
253 | #define HS_START 0x0C /* Start transmit break command */ | ||
254 | #define HS_STOP 0x0E /* Stop transmit break command */ | ||
255 | #define HS_IDLE_CLOSED 0x10 /* Closed channel state */ | ||
256 | #define HS_IDLE_BREAK 0x12 /* Transmit break state */ | ||
257 | #define HS_FORCE_CLOSED 0x14 /* Force close command */ | ||
258 | #define HS_RESUME 0x16 /* Clear pending XOFF command */ | ||
259 | #define HS_WFLUSH 0x18 /* Flush transmit buffer command */ | ||
260 | #define HS_RFLUSH 0x1A /* Flush receive buffer command */ | ||
261 | #define HS_SUSPEND 0x1C /* Suspend output command (like XOFF received) */ | ||
262 | #define PARALLEL 0x1E /* Parallel port loopback test command (Diagnostics Only) */ | ||
263 | #define ENABLE_RX_INTS 0x20 /* Enable receive interrupts command (Diagnostics Only) */ | ||
264 | #define ENABLE_TX_INTS 0x22 /* Enable transmit interrupts command (Diagnostics Only) */ | ||
265 | #define ENABLE_MDM_INTS 0x24 /* Enable modem interrupts command (Diagnostics Only) */ | ||
266 | #define DISABLE_INTS 0x26 /* Disable interrupts command (Diagnostics Only) */ | ||
267 | |||
268 | /* SXCHANNEL.hi_mr1 definitions... */ | ||
269 | #define MR1_BITS 0x03 /* Data bits mask */ | ||
270 | #define MR1_5_BITS 0x00 /* 5 data bits */ | ||
271 | #define MR1_6_BITS 0x01 /* 6 data bits */ | ||
272 | #define MR1_7_BITS 0x02 /* 7 data bits */ | ||
273 | #define MR1_8_BITS 0x03 /* 8 data bits */ | ||
274 | #define MR1_PARITY 0x1C /* Parity mask */ | ||
275 | #define MR1_ODD 0x04 /* Odd parity */ | ||
276 | #define MR1_EVEN 0x00 /* Even parity */ | ||
277 | #define MR1_WITH 0x00 /* Parity enabled */ | ||
278 | #define MR1_FORCE 0x08 /* Force parity */ | ||
279 | #define MR1_NONE 0x10 /* No parity */ | ||
280 | #define MR1_NOPARITY MR1_NONE /* No parity */ | ||
281 | #define MR1_ODDPARITY (MR1_WITH|MR1_ODD) /* Odd parity */ | ||
282 | #define MR1_EVENPARITY (MR1_WITH|MR1_EVEN) /* Even parity */ | ||
283 | #define MR1_MARKPARITY (MR1_FORCE|MR1_ODD) /* Mark parity */ | ||
284 | #define MR1_SPACEPARITY (MR1_FORCE|MR1_EVEN) /* Space parity */ | ||
285 | #define MR1_RTS_RXFLOW 0x80 /* RTS receive flow control */ | ||
286 | |||
287 | /* SXCHANNEL.hi_mr2 definitions... */ | ||
288 | #define MR2_STOP 0x0F /* Stop bits mask */ | ||
289 | #define MR2_1_STOP 0x07 /* 1 stop bit */ | ||
290 | #define MR2_2_STOP 0x0F /* 2 stop bits */ | ||
291 | #define MR2_CTS_TXFLOW 0x10 /* CTS transmit flow control */ | ||
292 | #define MR2_RTS_TOGGLE 0x20 /* RTS toggle on transmit */ | ||
293 | #define MR2_NORMAL 0x00 /* Normal mode */ | ||
294 | #define MR2_AUTO 0x40 /* Auto-echo mode (TA only) */ | ||
295 | #define MR2_LOCAL 0x80 /* Local echo mode */ | ||
296 | #define MR2_REMOTE 0xC0 /* Remote echo mode (TA only) */ | ||
297 | |||
298 | /* SXCHANNEL.hi_csr definitions... */ | ||
299 | #define CSR_75 0x0 /* 75 baud */ | ||
300 | #define CSR_110 0x1 /* 110 baud (TA), 115200 (MTA/SXDC) */ | ||
301 | #define CSR_38400 0x2 /* 38400 baud */ | ||
302 | #define CSR_150 0x3 /* 150 baud */ | ||
303 | #define CSR_300 0x4 /* 300 baud */ | ||
304 | #define CSR_600 0x5 /* 600 baud */ | ||
305 | #define CSR_1200 0x6 /* 1200 baud */ | ||
306 | #define CSR_2000 0x7 /* 2000 baud */ | ||
307 | #define CSR_2400 0x8 /* 2400 baud */ | ||
308 | #define CSR_4800 0x9 /* 4800 baud */ | ||
309 | #define CSR_1800 0xA /* 1800 baud */ | ||
310 | #define CSR_9600 0xB /* 9600 baud */ | ||
311 | #define CSR_19200 0xC /* 19200 baud */ | ||
312 | #define CSR_57600 0xD /* 57600 baud */ | ||
313 | #define CSR_EXTBAUD 0xF /* Extended baud rate (hi_txbaud/hi_rxbaud) */ | ||
314 | |||
315 | /* SXCHANNEL.hi_op definitions... */ | ||
316 | #define OP_RTS 0x01 /* RTS modem output signal */ | ||
317 | #define OP_DTR 0x02 /* DTR modem output signal */ | ||
318 | |||
319 | /* SXCHANNEL.hi_ip definitions... */ | ||
320 | #define IP_CTS 0x02 /* CTS modem input signal */ | ||
321 | #define IP_DCD 0x04 /* DCD modem input signal */ | ||
322 | #define IP_DSR 0x20 /* DTR modem input signal */ | ||
323 | #define IP_RI 0x40 /* RI modem input signal */ | ||
324 | |||
325 | /* SXCHANNEL.hi_state definitions... */ | ||
326 | #define ST_BREAK 0x01 /* Break received (clear with config) */ | ||
327 | #define ST_DCD 0x02 /* DCD signal changed state */ | ||
328 | |||
329 | /* SXCHANNEL.hi_prtcl definitions... */ | ||
330 | #define SP_TANY 0x01 /* Transmit XON/XANY (if SP_TXEN enabled) */ | ||
331 | #define SP_TXEN 0x02 /* Transmit XON/XOFF flow control */ | ||
332 | #define SP_CEN 0x04 /* Cooking enabled */ | ||
333 | #define SP_RXEN 0x08 /* Rx XON/XOFF enabled */ | ||
334 | #define SP_DCEN 0x20 /* DCD / DTR check */ | ||
335 | #define SP_DTR_RXFLOW 0x40 /* DTR receive flow control */ | ||
336 | #define SP_PAEN 0x80 /* Parity checking enabled */ | ||
337 | |||
338 | /* SXCHANNEL.hi_break definitions... */ | ||
339 | #define BR_IGN 0x01 /* Ignore any received breaks */ | ||
340 | #define BR_INT 0x02 /* Interrupt on received break */ | ||
341 | #define BR_PARMRK 0x04 /* Enable parmrk parity error processing */ | ||
342 | #define BR_PARIGN 0x08 /* Ignore chars with parity errors */ | ||
343 | #define BR_ERRINT 0x80 /* Treat parity/framing/overrun errors as exceptions */ | ||
344 | |||
345 | /* SXCHANNEL.par_error definitions.. */ | ||
346 | #define DIAG_IRQ_RX 0x01 /* Indicate serial receive interrupt (diags only) */ | ||
347 | #define DIAG_IRQ_TX 0x02 /* Indicate serial transmit interrupt (diags only) */ | ||
348 | #define DIAG_IRQ_MD 0x04 /* Indicate serial modem interrupt (diags only) */ | ||
349 | |||
350 | /* SXCHANNEL.hi_txbaud/hi_rxbaud definitions... (SXDC only) */ | ||
351 | #define BAUD_75 0x00 /* 75 baud */ | ||
352 | #define BAUD_115200 0x01 /* 115200 baud */ | ||
353 | #define BAUD_38400 0x02 /* 38400 baud */ | ||
354 | #define BAUD_150 0x03 /* 150 baud */ | ||
355 | #define BAUD_300 0x04 /* 300 baud */ | ||
356 | #define BAUD_600 0x05 /* 600 baud */ | ||
357 | #define BAUD_1200 0x06 /* 1200 baud */ | ||
358 | #define BAUD_2000 0x07 /* 2000 baud */ | ||
359 | #define BAUD_2400 0x08 /* 2400 baud */ | ||
360 | #define BAUD_4800 0x09 /* 4800 baud */ | ||
361 | #define BAUD_1800 0x0A /* 1800 baud */ | ||
362 | #define BAUD_9600 0x0B /* 9600 baud */ | ||
363 | #define BAUD_19200 0x0C /* 19200 baud */ | ||
364 | #define BAUD_57600 0x0D /* 57600 baud */ | ||
365 | #define BAUD_230400 0x0E /* 230400 baud */ | ||
366 | #define BAUD_460800 0x0F /* 460800 baud */ | ||
367 | #define BAUD_921600 0x10 /* 921600 baud */ | ||
368 | #define BAUD_50 0x11 /* 50 baud */ | ||
369 | #define BAUD_110 0x12 /* 110 baud */ | ||
370 | #define BAUD_134_5 0x13 /* 134.5 baud */ | ||
371 | #define BAUD_200 0x14 /* 200 baud */ | ||
372 | #define BAUD_7200 0x15 /* 7200 baud */ | ||
373 | #define BAUD_56000 0x16 /* 56000 baud */ | ||
374 | #define BAUD_64000 0x17 /* 64000 baud */ | ||
375 | #define BAUD_76800 0x18 /* 76800 baud */ | ||
376 | #define BAUD_128000 0x19 /* 128000 baud */ | ||
377 | #define BAUD_150000 0x1A /* 150000 baud */ | ||
378 | #define BAUD_14400 0x1B /* 14400 baud */ | ||
379 | #define BAUD_256000 0x1C /* 256000 baud */ | ||
380 | #define BAUD_28800 0x1D /* 28800 baud */ | ||
381 | |||
382 | /* SXCHANNEL.txbreak_state definiions... */ | ||
383 | #define TXBREAK_OFF 0 /* Not sending break */ | ||
384 | #define TXBREAK_START 1 /* Begin sending break */ | ||
385 | #define TXBREAK_START1 2 /* Begin sending break, part 1 */ | ||
386 | #define TXBREAK_ON 3 /* Sending break */ | ||
387 | #define TXBREAK_STOP 4 /* Stop sending break */ | ||
388 | #define TXBREAK_STOP1 5 /* Stop sending break, part 1 */ | ||
389 | |||
390 | #endif /* _sxwindow_h */ | ||
391 | |||
392 | /* End of SXWINDOW.H */ | ||
393 | |||
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c deleted file mode 100644 index 96838640f575..000000000000 --- a/drivers/char/vme_scc.c +++ /dev/null | |||
@@ -1,1145 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/char/vme_scc.c: MVME147, MVME162, BVME6000 SCC serial ports | ||
3 | * implementation. | ||
4 | * Copyright 1999 Richard Hirst <richard@sleepie.demon.co.uk> | ||
5 | * | ||
6 | * Based on atari_SCC.c which was | ||
7 | * Copyright 1994-95 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> | ||
8 | * Partially based on PC-Linux serial.c by Linus Torvalds and Theodore Ts'o | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file COPYING in the main directory of this archive | ||
12 | * for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/kdev_t.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/ioport.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/tty.h> | ||
24 | #include <linux/tty_flip.h> | ||
25 | #include <linux/mm.h> | ||
26 | #include <linux/serial.h> | ||
27 | #include <linux/fcntl.h> | ||
28 | #include <linux/major.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/miscdevice.h> | ||
31 | #include <linux/console.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <asm/setup.h> | ||
34 | #include <asm/bootinfo.h> | ||
35 | |||
36 | #ifdef CONFIG_MVME147_SCC | ||
37 | #include <asm/mvme147hw.h> | ||
38 | #endif | ||
39 | #ifdef CONFIG_MVME162_SCC | ||
40 | #include <asm/mvme16xhw.h> | ||
41 | #endif | ||
42 | #ifdef CONFIG_BVME6000_SCC | ||
43 | #include <asm/bvme6000hw.h> | ||
44 | #endif | ||
45 | |||
46 | #include <linux/generic_serial.h> | ||
47 | #include "scc.h" | ||
48 | |||
49 | |||
50 | #define CHANNEL_A 0 | ||
51 | #define CHANNEL_B 1 | ||
52 | |||
53 | #define SCC_MINOR_BASE 64 | ||
54 | |||
55 | /* Shadows for all SCC write registers */ | ||
56 | static unsigned char scc_shadow[2][16]; | ||
57 | |||
58 | /* Location to access for SCC register access delay */ | ||
59 | static volatile unsigned char *scc_del = NULL; | ||
60 | |||
61 | /* To keep track of STATUS_REG state for detection of Ext/Status int source */ | ||
62 | static unsigned char scc_last_status_reg[2]; | ||
63 | |||
64 | /***************************** Prototypes *****************************/ | ||
65 | |||
66 | /* Function prototypes */ | ||
67 | static void scc_disable_tx_interrupts(void * ptr); | ||
68 | static void scc_enable_tx_interrupts(void * ptr); | ||
69 | static void scc_disable_rx_interrupts(void * ptr); | ||
70 | static void scc_enable_rx_interrupts(void * ptr); | ||
71 | static int scc_carrier_raised(struct tty_port *port); | ||
72 | static void scc_shutdown_port(void * ptr); | ||
73 | static int scc_set_real_termios(void *ptr); | ||
74 | static void scc_hungup(void *ptr); | ||
75 | static void scc_close(void *ptr); | ||
76 | static int scc_chars_in_buffer(void * ptr); | ||
77 | static int scc_open(struct tty_struct * tty, struct file * filp); | ||
78 | static int scc_ioctl(struct tty_struct * tty, | ||
79 | unsigned int cmd, unsigned long arg); | ||
80 | static void scc_throttle(struct tty_struct *tty); | ||
81 | static void scc_unthrottle(struct tty_struct *tty); | ||
82 | static irqreturn_t scc_tx_int(int irq, void *data); | ||
83 | static irqreturn_t scc_rx_int(int irq, void *data); | ||
84 | static irqreturn_t scc_stat_int(int irq, void *data); | ||
85 | static irqreturn_t scc_spcond_int(int irq, void *data); | ||
86 | static void scc_setsignals(struct scc_port *port, int dtr, int rts); | ||
87 | static int scc_break_ctl(struct tty_struct *tty, int break_state); | ||
88 | |||
89 | static struct tty_driver *scc_driver; | ||
90 | |||
91 | static struct scc_port scc_ports[2]; | ||
92 | |||
93 | /*--------------------------------------------------------------------------- | ||
94 | * Interface from generic_serial.c back here | ||
95 | *--------------------------------------------------------------------------*/ | ||
96 | |||
97 | static struct real_driver scc_real_driver = { | ||
98 | scc_disable_tx_interrupts, | ||
99 | scc_enable_tx_interrupts, | ||
100 | scc_disable_rx_interrupts, | ||
101 | scc_enable_rx_interrupts, | ||
102 | scc_shutdown_port, | ||
103 | scc_set_real_termios, | ||
104 | scc_chars_in_buffer, | ||
105 | scc_close, | ||
106 | scc_hungup, | ||
107 | NULL | ||
108 | }; | ||
109 | |||
110 | |||
111 | static const struct tty_operations scc_ops = { | ||
112 | .open = scc_open, | ||
113 | .close = gs_close, | ||
114 | .write = gs_write, | ||
115 | .put_char = gs_put_char, | ||
116 | .flush_chars = gs_flush_chars, | ||
117 | .write_room = gs_write_room, | ||
118 | .chars_in_buffer = gs_chars_in_buffer, | ||
119 | .flush_buffer = gs_flush_buffer, | ||
120 | .ioctl = scc_ioctl, | ||
121 | .throttle = scc_throttle, | ||
122 | .unthrottle = scc_unthrottle, | ||
123 | .set_termios = gs_set_termios, | ||
124 | .stop = gs_stop, | ||
125 | .start = gs_start, | ||
126 | .hangup = gs_hangup, | ||
127 | .break_ctl = scc_break_ctl, | ||
128 | }; | ||
129 | |||
130 | static const struct tty_port_operations scc_port_ops = { | ||
131 | .carrier_raised = scc_carrier_raised, | ||
132 | }; | ||
133 | |||
134 | /*---------------------------------------------------------------------------- | ||
135 | * vme_scc_init() and support functions | ||
136 | *---------------------------------------------------------------------------*/ | ||
137 | |||
138 | static int __init scc_init_drivers(void) | ||
139 | { | ||
140 | int error; | ||
141 | |||
142 | scc_driver = alloc_tty_driver(2); | ||
143 | if (!scc_driver) | ||
144 | return -ENOMEM; | ||
145 | scc_driver->owner = THIS_MODULE; | ||
146 | scc_driver->driver_name = "scc"; | ||
147 | scc_driver->name = "ttyS"; | ||
148 | scc_driver->major = TTY_MAJOR; | ||
149 | scc_driver->minor_start = SCC_MINOR_BASE; | ||
150 | scc_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
151 | scc_driver->subtype = SERIAL_TYPE_NORMAL; | ||
152 | scc_driver->init_termios = tty_std_termios; | ||
153 | scc_driver->init_termios.c_cflag = | ||
154 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
155 | scc_driver->init_termios.c_ispeed = 9600; | ||
156 | scc_driver->init_termios.c_ospeed = 9600; | ||
157 | scc_driver->flags = TTY_DRIVER_REAL_RAW; | ||
158 | tty_set_operations(scc_driver, &scc_ops); | ||
159 | |||
160 | if ((error = tty_register_driver(scc_driver))) { | ||
161 | printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n", | ||
162 | error); | ||
163 | put_tty_driver(scc_driver); | ||
164 | return 1; | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | |||
171 | /* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1). | ||
172 | */ | ||
173 | |||
174 | static void __init scc_init_portstructs(void) | ||
175 | { | ||
176 | struct scc_port *port; | ||
177 | int i; | ||
178 | |||
179 | for (i = 0; i < 2; i++) { | ||
180 | port = scc_ports + i; | ||
181 | tty_port_init(&port->gs.port); | ||
182 | port->gs.port.ops = &scc_port_ops; | ||
183 | port->gs.magic = SCC_MAGIC; | ||
184 | port->gs.close_delay = HZ/2; | ||
185 | port->gs.closing_wait = 30 * HZ; | ||
186 | port->gs.rd = &scc_real_driver; | ||
187 | #ifdef NEW_WRITE_LOCKING | ||
188 | port->gs.port_write_mutex = MUTEX; | ||
189 | #endif | ||
190 | init_waitqueue_head(&port->gs.port.open_wait); | ||
191 | init_waitqueue_head(&port->gs.port.close_wait); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | |||
196 | #ifdef CONFIG_MVME147_SCC | ||
197 | static int __init mvme147_scc_init(void) | ||
198 | { | ||
199 | struct scc_port *port; | ||
200 | int error; | ||
201 | |||
202 | printk(KERN_INFO "SCC: MVME147 Serial Driver\n"); | ||
203 | /* Init channel A */ | ||
204 | port = &scc_ports[0]; | ||
205 | port->channel = CHANNEL_A; | ||
206 | port->ctrlp = (volatile unsigned char *)M147_SCC_A_ADDR; | ||
207 | port->datap = port->ctrlp + 1; | ||
208 | port->port_a = &scc_ports[0]; | ||
209 | port->port_b = &scc_ports[1]; | ||
210 | error = request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, | ||
211 | "SCC-A TX", port); | ||
212 | if (error) | ||
213 | goto fail; | ||
214 | error = request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, | ||
215 | "SCC-A status", port); | ||
216 | if (error) | ||
217 | goto fail_free_a_tx; | ||
218 | error = request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, | ||
219 | "SCC-A RX", port); | ||
220 | if (error) | ||
221 | goto fail_free_a_stat; | ||
222 | error = request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, | ||
223 | IRQF_DISABLED, "SCC-A special cond", port); | ||
224 | if (error) | ||
225 | goto fail_free_a_rx; | ||
226 | |||
227 | { | ||
228 | SCC_ACCESS_INIT(port); | ||
229 | |||
230 | /* disable interrupts for this channel */ | ||
231 | SCCwrite(INT_AND_DMA_REG, 0); | ||
232 | /* Set the interrupt vector */ | ||
233 | SCCwrite(INT_VECTOR_REG, MVME147_IRQ_SCC_BASE); | ||
234 | /* Interrupt parameters: vector includes status, status low */ | ||
235 | SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); | ||
236 | SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); | ||
237 | } | ||
238 | |||
239 | /* Init channel B */ | ||
240 | port = &scc_ports[1]; | ||
241 | port->channel = CHANNEL_B; | ||
242 | port->ctrlp = (volatile unsigned char *)M147_SCC_B_ADDR; | ||
243 | port->datap = port->ctrlp + 1; | ||
244 | port->port_a = &scc_ports[0]; | ||
245 | port->port_b = &scc_ports[1]; | ||
246 | error = request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, | ||
247 | "SCC-B TX", port); | ||
248 | if (error) | ||
249 | goto fail_free_a_spcond; | ||
250 | error = request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, | ||
251 | "SCC-B status", port); | ||
252 | if (error) | ||
253 | goto fail_free_b_tx; | ||
254 | error = request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, | ||
255 | "SCC-B RX", port); | ||
256 | if (error) | ||
257 | goto fail_free_b_stat; | ||
258 | error = request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, | ||
259 | IRQF_DISABLED, "SCC-B special cond", port); | ||
260 | if (error) | ||
261 | goto fail_free_b_rx; | ||
262 | |||
263 | { | ||
264 | SCC_ACCESS_INIT(port); | ||
265 | |||
266 | /* disable interrupts for this channel */ | ||
267 | SCCwrite(INT_AND_DMA_REG, 0); | ||
268 | } | ||
269 | |||
270 | /* Ensure interrupts are enabled in the PCC chip */ | ||
271 | m147_pcc->serial_cntrl=PCC_LEVEL_SERIAL|PCC_INT_ENAB; | ||
272 | |||
273 | /* Initialise the tty driver structures and register */ | ||
274 | scc_init_portstructs(); | ||
275 | scc_init_drivers(); | ||
276 | |||
277 | return 0; | ||
278 | |||
279 | fail_free_b_rx: | ||
280 | free_irq(MVME147_IRQ_SCCB_RX, port); | ||
281 | fail_free_b_stat: | ||
282 | free_irq(MVME147_IRQ_SCCB_STAT, port); | ||
283 | fail_free_b_tx: | ||
284 | free_irq(MVME147_IRQ_SCCB_TX, port); | ||
285 | fail_free_a_spcond: | ||
286 | free_irq(MVME147_IRQ_SCCA_SPCOND, port); | ||
287 | fail_free_a_rx: | ||
288 | free_irq(MVME147_IRQ_SCCA_RX, port); | ||
289 | fail_free_a_stat: | ||
290 | free_irq(MVME147_IRQ_SCCA_STAT, port); | ||
291 | fail_free_a_tx: | ||
292 | free_irq(MVME147_IRQ_SCCA_TX, port); | ||
293 | fail: | ||
294 | return error; | ||
295 | } | ||
296 | #endif | ||
297 | |||
298 | |||
299 | #ifdef CONFIG_MVME162_SCC | ||
300 | static int __init mvme162_scc_init(void) | ||
301 | { | ||
302 | struct scc_port *port; | ||
303 | int error; | ||
304 | |||
305 | if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA)) | ||
306 | return (-ENODEV); | ||
307 | |||
308 | printk(KERN_INFO "SCC: MVME162 Serial Driver\n"); | ||
309 | /* Init channel A */ | ||
310 | port = &scc_ports[0]; | ||
311 | port->channel = CHANNEL_A; | ||
312 | port->ctrlp = (volatile unsigned char *)MVME_SCC_A_ADDR; | ||
313 | port->datap = port->ctrlp + 2; | ||
314 | port->port_a = &scc_ports[0]; | ||
315 | port->port_b = &scc_ports[1]; | ||
316 | error = request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, | ||
317 | "SCC-A TX", port); | ||
318 | if (error) | ||
319 | goto fail; | ||
320 | error = request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, | ||
321 | "SCC-A status", port); | ||
322 | if (error) | ||
323 | goto fail_free_a_tx; | ||
324 | error = request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, | ||
325 | "SCC-A RX", port); | ||
326 | if (error) | ||
327 | goto fail_free_a_stat; | ||
328 | error = request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, | ||
329 | IRQF_DISABLED, "SCC-A special cond", port); | ||
330 | if (error) | ||
331 | goto fail_free_a_rx; | ||
332 | |||
333 | { | ||
334 | SCC_ACCESS_INIT(port); | ||
335 | |||
336 | /* disable interrupts for this channel */ | ||
337 | SCCwrite(INT_AND_DMA_REG, 0); | ||
338 | /* Set the interrupt vector */ | ||
339 | SCCwrite(INT_VECTOR_REG, MVME162_IRQ_SCC_BASE); | ||
340 | /* Interrupt parameters: vector includes status, status low */ | ||
341 | SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); | ||
342 | SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); | ||
343 | } | ||
344 | |||
345 | /* Init channel B */ | ||
346 | port = &scc_ports[1]; | ||
347 | port->channel = CHANNEL_B; | ||
348 | port->ctrlp = (volatile unsigned char *)MVME_SCC_B_ADDR; | ||
349 | port->datap = port->ctrlp + 2; | ||
350 | port->port_a = &scc_ports[0]; | ||
351 | port->port_b = &scc_ports[1]; | ||
352 | error = request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, | ||
353 | "SCC-B TX", port); | ||
354 | if (error) | ||
355 | goto fail_free_a_spcond; | ||
356 | error = request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, | ||
357 | "SCC-B status", port); | ||
358 | if (error) | ||
359 | goto fail_free_b_tx; | ||
360 | error = request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, | ||
361 | "SCC-B RX", port); | ||
362 | if (error) | ||
363 | goto fail_free_b_stat; | ||
364 | error = request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, | ||
365 | IRQF_DISABLED, "SCC-B special cond", port); | ||
366 | if (error) | ||
367 | goto fail_free_b_rx; | ||
368 | |||
369 | { | ||
370 | SCC_ACCESS_INIT(port); /* Either channel will do */ | ||
371 | |||
372 | /* disable interrupts for this channel */ | ||
373 | SCCwrite(INT_AND_DMA_REG, 0); | ||
374 | } | ||
375 | |||
376 | /* Ensure interrupts are enabled in the MC2 chip */ | ||
377 | *(volatile char *)0xfff4201d = 0x14; | ||
378 | |||
379 | /* Initialise the tty driver structures and register */ | ||
380 | scc_init_portstructs(); | ||
381 | scc_init_drivers(); | ||
382 | |||
383 | return 0; | ||
384 | |||
385 | fail_free_b_rx: | ||
386 | free_irq(MVME162_IRQ_SCCB_RX, port); | ||
387 | fail_free_b_stat: | ||
388 | free_irq(MVME162_IRQ_SCCB_STAT, port); | ||
389 | fail_free_b_tx: | ||
390 | free_irq(MVME162_IRQ_SCCB_TX, port); | ||
391 | fail_free_a_spcond: | ||
392 | free_irq(MVME162_IRQ_SCCA_SPCOND, port); | ||
393 | fail_free_a_rx: | ||
394 | free_irq(MVME162_IRQ_SCCA_RX, port); | ||
395 | fail_free_a_stat: | ||
396 | free_irq(MVME162_IRQ_SCCA_STAT, port); | ||
397 | fail_free_a_tx: | ||
398 | free_irq(MVME162_IRQ_SCCA_TX, port); | ||
399 | fail: | ||
400 | return error; | ||
401 | } | ||
402 | #endif | ||
403 | |||
404 | |||
405 | #ifdef CONFIG_BVME6000_SCC | ||
406 | static int __init bvme6000_scc_init(void) | ||
407 | { | ||
408 | struct scc_port *port; | ||
409 | int error; | ||
410 | |||
411 | printk(KERN_INFO "SCC: BVME6000 Serial Driver\n"); | ||
412 | /* Init channel A */ | ||
413 | port = &scc_ports[0]; | ||
414 | port->channel = CHANNEL_A; | ||
415 | port->ctrlp = (volatile unsigned char *)BVME_SCC_A_ADDR; | ||
416 | port->datap = port->ctrlp + 4; | ||
417 | port->port_a = &scc_ports[0]; | ||
418 | port->port_b = &scc_ports[1]; | ||
419 | error = request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, | ||
420 | "SCC-A TX", port); | ||
421 | if (error) | ||
422 | goto fail; | ||
423 | error = request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, | ||
424 | "SCC-A status", port); | ||
425 | if (error) | ||
426 | goto fail_free_a_tx; | ||
427 | error = request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, | ||
428 | "SCC-A RX", port); | ||
429 | if (error) | ||
430 | goto fail_free_a_stat; | ||
431 | error = request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, | ||
432 | IRQF_DISABLED, "SCC-A special cond", port); | ||
433 | if (error) | ||
434 | goto fail_free_a_rx; | ||
435 | |||
436 | { | ||
437 | SCC_ACCESS_INIT(port); | ||
438 | |||
439 | /* disable interrupts for this channel */ | ||
440 | SCCwrite(INT_AND_DMA_REG, 0); | ||
441 | /* Set the interrupt vector */ | ||
442 | SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE); | ||
443 | /* Interrupt parameters: vector includes status, status low */ | ||
444 | SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); | ||
445 | SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); | ||
446 | } | ||
447 | |||
448 | /* Init channel B */ | ||
449 | port = &scc_ports[1]; | ||
450 | port->channel = CHANNEL_B; | ||
451 | port->ctrlp = (volatile unsigned char *)BVME_SCC_B_ADDR; | ||
452 | port->datap = port->ctrlp + 4; | ||
453 | port->port_a = &scc_ports[0]; | ||
454 | port->port_b = &scc_ports[1]; | ||
455 | error = request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, | ||
456 | "SCC-B TX", port); | ||
457 | if (error) | ||
458 | goto fail_free_a_spcond; | ||
459 | error = request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, | ||
460 | "SCC-B status", port); | ||
461 | if (error) | ||
462 | goto fail_free_b_tx; | ||
463 | error = request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, | ||
464 | "SCC-B RX", port); | ||
465 | if (error) | ||
466 | goto fail_free_b_stat; | ||
467 | error = request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, | ||
468 | IRQF_DISABLED, "SCC-B special cond", port); | ||
469 | if (error) | ||
470 | goto fail_free_b_rx; | ||
471 | |||
472 | { | ||
473 | SCC_ACCESS_INIT(port); /* Either channel will do */ | ||
474 | |||
475 | /* disable interrupts for this channel */ | ||
476 | SCCwrite(INT_AND_DMA_REG, 0); | ||
477 | } | ||
478 | |||
479 | /* Initialise the tty driver structures and register */ | ||
480 | scc_init_portstructs(); | ||
481 | scc_init_drivers(); | ||
482 | |||
483 | return 0; | ||
484 | |||
485 | fail: | ||
486 | free_irq(BVME_IRQ_SCCA_STAT, port); | ||
487 | fail_free_a_tx: | ||
488 | free_irq(BVME_IRQ_SCCA_RX, port); | ||
489 | fail_free_a_stat: | ||
490 | free_irq(BVME_IRQ_SCCA_SPCOND, port); | ||
491 | fail_free_a_rx: | ||
492 | free_irq(BVME_IRQ_SCCB_TX, port); | ||
493 | fail_free_a_spcond: | ||
494 | free_irq(BVME_IRQ_SCCB_STAT, port); | ||
495 | fail_free_b_tx: | ||
496 | free_irq(BVME_IRQ_SCCB_RX, port); | ||
497 | fail_free_b_stat: | ||
498 | free_irq(BVME_IRQ_SCCB_SPCOND, port); | ||
499 | fail_free_b_rx: | ||
500 | return error; | ||
501 | } | ||
502 | #endif | ||
503 | |||
504 | |||
505 | static int __init vme_scc_init(void) | ||
506 | { | ||
507 | int res = -ENODEV; | ||
508 | |||
509 | #ifdef CONFIG_MVME147_SCC | ||
510 | if (MACH_IS_MVME147) | ||
511 | res = mvme147_scc_init(); | ||
512 | #endif | ||
513 | #ifdef CONFIG_MVME162_SCC | ||
514 | if (MACH_IS_MVME16x) | ||
515 | res = mvme162_scc_init(); | ||
516 | #endif | ||
517 | #ifdef CONFIG_BVME6000_SCC | ||
518 | if (MACH_IS_BVME6000) | ||
519 | res = bvme6000_scc_init(); | ||
520 | #endif | ||
521 | return res; | ||
522 | } | ||
523 | |||
524 | module_init(vme_scc_init); | ||
525 | |||
526 | |||
527 | /*--------------------------------------------------------------------------- | ||
528 | * Interrupt handlers | ||
529 | *--------------------------------------------------------------------------*/ | ||
530 | |||
531 | static irqreturn_t scc_rx_int(int irq, void *data) | ||
532 | { | ||
533 | unsigned char ch; | ||
534 | struct scc_port *port = data; | ||
535 | struct tty_struct *tty = port->gs.port.tty; | ||
536 | SCC_ACCESS_INIT(port); | ||
537 | |||
538 | ch = SCCread_NB(RX_DATA_REG); | ||
539 | if (!tty) { | ||
540 | printk(KERN_WARNING "scc_rx_int with NULL tty!\n"); | ||
541 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | ||
542 | return IRQ_HANDLED; | ||
543 | } | ||
544 | tty_insert_flip_char(tty, ch, 0); | ||
545 | |||
546 | /* Check if another character is already ready; in that case, the | ||
547 | * spcond_int() function must be used, because this character may have an | ||
548 | * error condition that isn't signalled by the interrupt vector used! | ||
549 | */ | ||
550 | if (SCCread(INT_PENDING_REG) & | ||
551 | (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) { | ||
552 | scc_spcond_int (irq, data); | ||
553 | return IRQ_HANDLED; | ||
554 | } | ||
555 | |||
556 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | ||
557 | |||
558 | tty_flip_buffer_push(tty); | ||
559 | return IRQ_HANDLED; | ||
560 | } | ||
561 | |||
562 | |||
563 | static irqreturn_t scc_spcond_int(int irq, void *data) | ||
564 | { | ||
565 | struct scc_port *port = data; | ||
566 | struct tty_struct *tty = port->gs.port.tty; | ||
567 | unsigned char stat, ch, err; | ||
568 | int int_pending_mask = port->channel == CHANNEL_A ? | ||
569 | IPR_A_RX : IPR_B_RX; | ||
570 | SCC_ACCESS_INIT(port); | ||
571 | |||
572 | if (!tty) { | ||
573 | printk(KERN_WARNING "scc_spcond_int with NULL tty!\n"); | ||
574 | SCCwrite(COMMAND_REG, CR_ERROR_RESET); | ||
575 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | ||
576 | return IRQ_HANDLED; | ||
577 | } | ||
578 | do { | ||
579 | stat = SCCread(SPCOND_STATUS_REG); | ||
580 | ch = SCCread_NB(RX_DATA_REG); | ||
581 | |||
582 | if (stat & SCSR_RX_OVERRUN) | ||
583 | err = TTY_OVERRUN; | ||
584 | else if (stat & SCSR_PARITY_ERR) | ||
585 | err = TTY_PARITY; | ||
586 | else if (stat & SCSR_CRC_FRAME_ERR) | ||
587 | err = TTY_FRAME; | ||
588 | else | ||
589 | err = 0; | ||
590 | |||
591 | tty_insert_flip_char(tty, ch, err); | ||
592 | |||
593 | /* ++TeSche: *All* errors have to be cleared manually, | ||
594 | * else the condition persists for the next chars | ||
595 | */ | ||
596 | if (err) | ||
597 | SCCwrite(COMMAND_REG, CR_ERROR_RESET); | ||
598 | |||
599 | } while(SCCread(INT_PENDING_REG) & int_pending_mask); | ||
600 | |||
601 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | ||
602 | |||
603 | tty_flip_buffer_push(tty); | ||
604 | return IRQ_HANDLED; | ||
605 | } | ||
606 | |||
607 | |||
608 | static irqreturn_t scc_tx_int(int irq, void *data) | ||
609 | { | ||
610 | struct scc_port *port = data; | ||
611 | SCC_ACCESS_INIT(port); | ||
612 | |||
613 | if (!port->gs.port.tty) { | ||
614 | printk(KERN_WARNING "scc_tx_int with NULL tty!\n"); | ||
615 | SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); | ||
616 | SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); | ||
617 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | ||
618 | return IRQ_HANDLED; | ||
619 | } | ||
620 | while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) { | ||
621 | if (port->x_char) { | ||
622 | SCCwrite(TX_DATA_REG, port->x_char); | ||
623 | port->x_char = 0; | ||
624 | } | ||
625 | else if ((port->gs.xmit_cnt <= 0) || | ||
626 | port->gs.port.tty->stopped || | ||
627 | port->gs.port.tty->hw_stopped) | ||
628 | break; | ||
629 | else { | ||
630 | SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]); | ||
631 | port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1); | ||
632 | if (--port->gs.xmit_cnt <= 0) | ||
633 | break; | ||
634 | } | ||
635 | } | ||
636 | if ((port->gs.xmit_cnt <= 0) || port->gs.port.tty->stopped || | ||
637 | port->gs.port.tty->hw_stopped) { | ||
638 | /* disable tx interrupts */ | ||
639 | SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); | ||
640 | SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); /* disable tx_int on next tx underrun? */ | ||
641 | port->gs.port.flags &= ~GS_TX_INTEN; | ||
642 | } | ||
643 | if (port->gs.port.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) | ||
644 | tty_wakeup(port->gs.port.tty); | ||
645 | |||
646 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | ||
647 | return IRQ_HANDLED; | ||
648 | } | ||
649 | |||
650 | |||
651 | static irqreturn_t scc_stat_int(int irq, void *data) | ||
652 | { | ||
653 | struct scc_port *port = data; | ||
654 | unsigned channel = port->channel; | ||
655 | unsigned char last_sr, sr, changed; | ||
656 | SCC_ACCESS_INIT(port); | ||
657 | |||
658 | last_sr = scc_last_status_reg[channel]; | ||
659 | sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG); | ||
660 | changed = last_sr ^ sr; | ||
661 | |||
662 | if (changed & SR_DCD) { | ||
663 | port->c_dcd = !!(sr & SR_DCD); | ||
664 | if (!(port->gs.port.flags & ASYNC_CHECK_CD)) | ||
665 | ; /* Don't report DCD changes */ | ||
666 | else if (port->c_dcd) { | ||
667 | wake_up_interruptible(&port->gs.port.open_wait); | ||
668 | } | ||
669 | else { | ||
670 | if (port->gs.port.tty) | ||
671 | tty_hangup (port->gs.port.tty); | ||
672 | } | ||
673 | } | ||
674 | SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET); | ||
675 | SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); | ||
676 | return IRQ_HANDLED; | ||
677 | } | ||
678 | |||
679 | |||
680 | /*--------------------------------------------------------------------------- | ||
681 | * generic_serial.c callback funtions | ||
682 | *--------------------------------------------------------------------------*/ | ||
683 | |||
684 | static void scc_disable_tx_interrupts(void *ptr) | ||
685 | { | ||
686 | struct scc_port *port = ptr; | ||
687 | unsigned long flags; | ||
688 | SCC_ACCESS_INIT(port); | ||
689 | |||
690 | local_irq_save(flags); | ||
691 | SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); | ||
692 | port->gs.port.flags &= ~GS_TX_INTEN; | ||
693 | local_irq_restore(flags); | ||
694 | } | ||
695 | |||
696 | |||
697 | static void scc_enable_tx_interrupts(void *ptr) | ||
698 | { | ||
699 | struct scc_port *port = ptr; | ||
700 | unsigned long flags; | ||
701 | SCC_ACCESS_INIT(port); | ||
702 | |||
703 | local_irq_save(flags); | ||
704 | SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB); | ||
705 | /* restart the transmitter */ | ||
706 | scc_tx_int (0, port); | ||
707 | local_irq_restore(flags); | ||
708 | } | ||
709 | |||
710 | |||
711 | static void scc_disable_rx_interrupts(void *ptr) | ||
712 | { | ||
713 | struct scc_port *port = ptr; | ||
714 | unsigned long flags; | ||
715 | SCC_ACCESS_INIT(port); | ||
716 | |||
717 | local_irq_save(flags); | ||
718 | SCCmod(INT_AND_DMA_REG, | ||
719 | ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0); | ||
720 | local_irq_restore(flags); | ||
721 | } | ||
722 | |||
723 | |||
724 | static void scc_enable_rx_interrupts(void *ptr) | ||
725 | { | ||
726 | struct scc_port *port = ptr; | ||
727 | unsigned long flags; | ||
728 | SCC_ACCESS_INIT(port); | ||
729 | |||
730 | local_irq_save(flags); | ||
731 | SCCmod(INT_AND_DMA_REG, 0xff, | ||
732 | IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL); | ||
733 | local_irq_restore(flags); | ||
734 | } | ||
735 | |||
736 | |||
737 | static int scc_carrier_raised(struct tty_port *port) | ||
738 | { | ||
739 | struct scc_port *sc = container_of(port, struct scc_port, gs.port); | ||
740 | unsigned channel = sc->channel; | ||
741 | |||
742 | return !!(scc_last_status_reg[channel] & SR_DCD); | ||
743 | } | ||
744 | |||
745 | |||
746 | static void scc_shutdown_port(void *ptr) | ||
747 | { | ||
748 | struct scc_port *port = ptr; | ||
749 | |||
750 | port->gs.port.flags &= ~ GS_ACTIVE; | ||
751 | if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { | ||
752 | scc_setsignals (port, 0, 0); | ||
753 | } | ||
754 | } | ||
755 | |||
756 | |||
757 | static int scc_set_real_termios (void *ptr) | ||
758 | { | ||
759 | /* the SCC has char sizes 5,7,6,8 in that order! */ | ||
760 | static int chsize_map[4] = { 0, 2, 1, 3 }; | ||
761 | unsigned cflag, baud, chsize, channel, brgval = 0; | ||
762 | unsigned long flags; | ||
763 | struct scc_port *port = ptr; | ||
764 | SCC_ACCESS_INIT(port); | ||
765 | |||
766 | if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; | ||
767 | |||
768 | channel = port->channel; | ||
769 | |||
770 | if (channel == CHANNEL_A) | ||
771 | return 0; /* Settings controlled by boot PROM */ | ||
772 | |||
773 | cflag = port->gs.port.tty->termios->c_cflag; | ||
774 | baud = port->gs.baud; | ||
775 | chsize = (cflag & CSIZE) >> 4; | ||
776 | |||
777 | if (baud == 0) { | ||
778 | /* speed == 0 -> drop DTR */ | ||
779 | local_irq_save(flags); | ||
780 | SCCmod(TX_CTRL_REG, ~TCR_DTR, 0); | ||
781 | local_irq_restore(flags); | ||
782 | return 0; | ||
783 | } | ||
784 | else if ((MACH_IS_MVME16x && (baud < 50 || baud > 38400)) || | ||
785 | (MACH_IS_MVME147 && (baud < 50 || baud > 19200)) || | ||
786 | (MACH_IS_BVME6000 &&(baud < 50 || baud > 76800))) { | ||
787 | printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud); | ||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | if (cflag & CLOCAL) | ||
792 | port->gs.port.flags &= ~ASYNC_CHECK_CD; | ||
793 | else | ||
794 | port->gs.port.flags |= ASYNC_CHECK_CD; | ||
795 | |||
796 | #ifdef CONFIG_MVME147_SCC | ||
797 | if (MACH_IS_MVME147) | ||
798 | brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; | ||
799 | #endif | ||
800 | #ifdef CONFIG_MVME162_SCC | ||
801 | if (MACH_IS_MVME16x) | ||
802 | brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; | ||
803 | #endif | ||
804 | #ifdef CONFIG_BVME6000_SCC | ||
805 | if (MACH_IS_BVME6000) | ||
806 | brgval = (BVME_SCC_RTxC + baud/2) / (16 * 2 * baud) - 2; | ||
807 | #endif | ||
808 | /* Now we have all parameters and can go to set them: */ | ||
809 | local_irq_save(flags); | ||
810 | |||
811 | /* receiver's character size and auto-enables */ | ||
812 | SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE), | ||
813 | (chsize_map[chsize] << 6) | | ||
814 | ((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0)); | ||
815 | /* parity and stop bits (both, Tx and Rx), clock mode never changes */ | ||
816 | SCCmod (AUX1_CTRL_REG, | ||
817 | ~(A1CR_PARITY_MASK | A1CR_MODE_MASK), | ||
818 | ((cflag & PARENB | ||
819 | ? (cflag & PARODD ? A1CR_PARITY_ODD : A1CR_PARITY_EVEN) | ||
820 | : A1CR_PARITY_NONE) | ||
821 | | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1))); | ||
822 | /* sender's character size, set DTR for valid baud rate */ | ||
823 | SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR); | ||
824 | /* clock sources never change */ | ||
825 | /* disable BRG before changing the value */ | ||
826 | SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0); | ||
827 | /* BRG value */ | ||
828 | SCCwrite(TIMER_LOW_REG, brgval & 0xff); | ||
829 | SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff); | ||
830 | /* BRG enable, and clock source never changes */ | ||
831 | SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB); | ||
832 | |||
833 | local_irq_restore(flags); | ||
834 | |||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | |||
839 | static int scc_chars_in_buffer (void *ptr) | ||
840 | { | ||
841 | struct scc_port *port = ptr; | ||
842 | SCC_ACCESS_INIT(port); | ||
843 | |||
844 | return (SCCread (SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0 : 1; | ||
845 | } | ||
846 | |||
847 | |||
848 | /* Comment taken from sx.c (2.4.0): | ||
849 | I haven't the foggiest why the decrement use count has to happen | ||
850 | here. The whole linux serial drivers stuff needs to be redesigned. | ||
851 | My guess is that this is a hack to minimize the impact of a bug | ||
852 | elsewhere. Thinking about it some more. (try it sometime) Try | ||
853 | running minicom on a serial port that is driven by a modularized | ||
854 | driver. Have the modem hangup. Then remove the driver module. Then | ||
855 | exit minicom. I expect an "oops". -- REW */ | ||
856 | |||
857 | static void scc_hungup(void *ptr) | ||
858 | { | ||
859 | scc_disable_tx_interrupts(ptr); | ||
860 | scc_disable_rx_interrupts(ptr); | ||
861 | } | ||
862 | |||
863 | |||
864 | static void scc_close(void *ptr) | ||
865 | { | ||
866 | scc_disable_tx_interrupts(ptr); | ||
867 | scc_disable_rx_interrupts(ptr); | ||
868 | } | ||
869 | |||
870 | |||
871 | /*--------------------------------------------------------------------------- | ||
872 | * Internal support functions | ||
873 | *--------------------------------------------------------------------------*/ | ||
874 | |||
875 | static void scc_setsignals(struct scc_port *port, int dtr, int rts) | ||
876 | { | ||
877 | unsigned long flags; | ||
878 | unsigned char t; | ||
879 | SCC_ACCESS_INIT(port); | ||
880 | |||
881 | local_irq_save(flags); | ||
882 | t = SCCread(TX_CTRL_REG); | ||
883 | if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR); | ||
884 | if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS); | ||
885 | SCCwrite(TX_CTRL_REG, t); | ||
886 | local_irq_restore(flags); | ||
887 | } | ||
888 | |||
889 | |||
890 | static void scc_send_xchar(struct tty_struct *tty, char ch) | ||
891 | { | ||
892 | struct scc_port *port = tty->driver_data; | ||
893 | |||
894 | port->x_char = ch; | ||
895 | if (ch) | ||
896 | scc_enable_tx_interrupts(port); | ||
897 | } | ||
898 | |||
899 | |||
900 | /*--------------------------------------------------------------------------- | ||
901 | * Driver entrypoints referenced from above | ||
902 | *--------------------------------------------------------------------------*/ | ||
903 | |||
904 | static int scc_open (struct tty_struct * tty, struct file * filp) | ||
905 | { | ||
906 | int line = tty->index; | ||
907 | int retval; | ||
908 | struct scc_port *port = &scc_ports[line]; | ||
909 | int i, channel = port->channel; | ||
910 | unsigned long flags; | ||
911 | SCC_ACCESS_INIT(port); | ||
912 | #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_MVME147_SCC) | ||
913 | static const struct { | ||
914 | unsigned reg, val; | ||
915 | } mvme_init_tab[] = { | ||
916 | /* Values for MVME162 and MVME147 */ | ||
917 | /* no parity, 1 stop bit, async, 1:16 */ | ||
918 | { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, | ||
919 | /* parity error is special cond, ints disabled, no DMA */ | ||
920 | { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, | ||
921 | /* Rx 8 bits/char, no auto enable, Rx off */ | ||
922 | { RX_CTRL_REG, RCR_CHSIZE_8 }, | ||
923 | /* DTR off, Tx 8 bits/char, RTS off, Tx off */ | ||
924 | { TX_CTRL_REG, TCR_CHSIZE_8 }, | ||
925 | /* special features off */ | ||
926 | { AUX2_CTRL_REG, 0 }, | ||
927 | { CLK_CTRL_REG, CCR_RXCLK_BRG | CCR_TXCLK_BRG }, | ||
928 | { DPLL_CTRL_REG, DCR_BRG_ENAB | DCR_BRG_USE_PCLK }, | ||
929 | /* Start Rx */ | ||
930 | { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, | ||
931 | /* Start Tx */ | ||
932 | { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, | ||
933 | /* Ext/Stat ints: DCD only */ | ||
934 | { INT_CTRL_REG, ICR_ENAB_DCD_INT }, | ||
935 | /* Reset Ext/Stat ints */ | ||
936 | { COMMAND_REG, CR_EXTSTAT_RESET }, | ||
937 | /* ...again */ | ||
938 | { COMMAND_REG, CR_EXTSTAT_RESET }, | ||
939 | }; | ||
940 | #endif | ||
941 | #if defined(CONFIG_BVME6000_SCC) | ||
942 | static const struct { | ||
943 | unsigned reg, val; | ||
944 | } bvme_init_tab[] = { | ||
945 | /* Values for BVME6000 */ | ||
946 | /* no parity, 1 stop bit, async, 1:16 */ | ||
947 | { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, | ||
948 | /* parity error is special cond, ints disabled, no DMA */ | ||
949 | { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, | ||
950 | /* Rx 8 bits/char, no auto enable, Rx off */ | ||
951 | { RX_CTRL_REG, RCR_CHSIZE_8 }, | ||
952 | /* DTR off, Tx 8 bits/char, RTS off, Tx off */ | ||
953 | { TX_CTRL_REG, TCR_CHSIZE_8 }, | ||
954 | /* special features off */ | ||
955 | { AUX2_CTRL_REG, 0 }, | ||
956 | { CLK_CTRL_REG, CCR_RTxC_XTAL | CCR_RXCLK_BRG | CCR_TXCLK_BRG }, | ||
957 | { DPLL_CTRL_REG, DCR_BRG_ENAB }, | ||
958 | /* Start Rx */ | ||
959 | { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, | ||
960 | /* Start Tx */ | ||
961 | { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, | ||
962 | /* Ext/Stat ints: DCD only */ | ||
963 | { INT_CTRL_REG, ICR_ENAB_DCD_INT }, | ||
964 | /* Reset Ext/Stat ints */ | ||
965 | { COMMAND_REG, CR_EXTSTAT_RESET }, | ||
966 | /* ...again */ | ||
967 | { COMMAND_REG, CR_EXTSTAT_RESET }, | ||
968 | }; | ||
969 | #endif | ||
970 | if (!(port->gs.port.flags & ASYNC_INITIALIZED)) { | ||
971 | local_irq_save(flags); | ||
972 | #if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC) | ||
973 | if (MACH_IS_MVME147 || MACH_IS_MVME16x) { | ||
974 | for (i = 0; i < ARRAY_SIZE(mvme_init_tab); ++i) | ||
975 | SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val); | ||
976 | } | ||
977 | #endif | ||
978 | #if defined(CONFIG_BVME6000_SCC) | ||
979 | if (MACH_IS_BVME6000) { | ||
980 | for (i = 0; i < ARRAY_SIZE(bvme_init_tab); ++i) | ||
981 | SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val); | ||
982 | } | ||
983 | #endif | ||
984 | |||
985 | /* remember status register for detection of DCD and CTS changes */ | ||
986 | scc_last_status_reg[channel] = SCCread(STATUS_REG); | ||
987 | |||
988 | port->c_dcd = 0; /* Prevent initial 1->0 interrupt */ | ||
989 | scc_setsignals (port, 1,1); | ||
990 | local_irq_restore(flags); | ||
991 | } | ||
992 | |||
993 | tty->driver_data = port; | ||
994 | port->gs.port.tty = tty; | ||
995 | port->gs.port.count++; | ||
996 | retval = gs_init_port(&port->gs); | ||
997 | if (retval) { | ||
998 | port->gs.port.count--; | ||
999 | return retval; | ||
1000 | } | ||
1001 | port->gs.port.flags |= GS_ACTIVE; | ||
1002 | retval = gs_block_til_ready(port, filp); | ||
1003 | |||
1004 | if (retval) { | ||
1005 | port->gs.port.count--; | ||
1006 | return retval; | ||
1007 | } | ||
1008 | |||
1009 | port->c_dcd = tty_port_carrier_raised(&port->gs.port); | ||
1010 | |||
1011 | scc_enable_rx_interrupts(port); | ||
1012 | |||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | static void scc_throttle (struct tty_struct * tty) | ||
1018 | { | ||
1019 | struct scc_port *port = tty->driver_data; | ||
1020 | unsigned long flags; | ||
1021 | SCC_ACCESS_INIT(port); | ||
1022 | |||
1023 | if (tty->termios->c_cflag & CRTSCTS) { | ||
1024 | local_irq_save(flags); | ||
1025 | SCCmod(TX_CTRL_REG, ~TCR_RTS, 0); | ||
1026 | local_irq_restore(flags); | ||
1027 | } | ||
1028 | if (I_IXOFF(tty)) | ||
1029 | scc_send_xchar(tty, STOP_CHAR(tty)); | ||
1030 | } | ||
1031 | |||
1032 | |||
1033 | static void scc_unthrottle (struct tty_struct * tty) | ||
1034 | { | ||
1035 | struct scc_port *port = tty->driver_data; | ||
1036 | unsigned long flags; | ||
1037 | SCC_ACCESS_INIT(port); | ||
1038 | |||
1039 | if (tty->termios->c_cflag & CRTSCTS) { | ||
1040 | local_irq_save(flags); | ||
1041 | SCCmod(TX_CTRL_REG, 0xff, TCR_RTS); | ||
1042 | local_irq_restore(flags); | ||
1043 | } | ||
1044 | if (I_IXOFF(tty)) | ||
1045 | scc_send_xchar(tty, START_CHAR(tty)); | ||
1046 | } | ||
1047 | |||
1048 | |||
1049 | static int scc_ioctl(struct tty_struct *tty, | ||
1050 | unsigned int cmd, unsigned long arg) | ||
1051 | { | ||
1052 | return -ENOIOCTLCMD; | ||
1053 | } | ||
1054 | |||
1055 | |||
1056 | static int scc_break_ctl(struct tty_struct *tty, int break_state) | ||
1057 | { | ||
1058 | struct scc_port *port = tty->driver_data; | ||
1059 | unsigned long flags; | ||
1060 | SCC_ACCESS_INIT(port); | ||
1061 | |||
1062 | local_irq_save(flags); | ||
1063 | SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, | ||
1064 | break_state ? TCR_SEND_BREAK : 0); | ||
1065 | local_irq_restore(flags); | ||
1066 | return 0; | ||
1067 | } | ||
1068 | |||
1069 | |||
1070 | /*--------------------------------------------------------------------------- | ||
1071 | * Serial console stuff... | ||
1072 | *--------------------------------------------------------------------------*/ | ||
1073 | |||
1074 | #define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0) | ||
1075 | |||
1076 | static void scc_ch_write (char ch) | ||
1077 | { | ||
1078 | volatile char *p = NULL; | ||
1079 | |||
1080 | #ifdef CONFIG_MVME147_SCC | ||
1081 | if (MACH_IS_MVME147) | ||
1082 | p = (volatile char *)M147_SCC_A_ADDR; | ||
1083 | #endif | ||
1084 | #ifdef CONFIG_MVME162_SCC | ||
1085 | if (MACH_IS_MVME16x) | ||
1086 | p = (volatile char *)MVME_SCC_A_ADDR; | ||
1087 | #endif | ||
1088 | #ifdef CONFIG_BVME6000_SCC | ||
1089 | if (MACH_IS_BVME6000) | ||
1090 | p = (volatile char *)BVME_SCC_A_ADDR; | ||
1091 | #endif | ||
1092 | |||
1093 | do { | ||
1094 | scc_delay(); | ||
1095 | } | ||
1096 | while (!(*p & 4)); | ||
1097 | scc_delay(); | ||
1098 | *p = 8; | ||
1099 | scc_delay(); | ||
1100 | *p = ch; | ||
1101 | } | ||
1102 | |||
1103 | /* The console must be locked when we get here. */ | ||
1104 | |||
1105 | static void scc_console_write (struct console *co, const char *str, unsigned count) | ||
1106 | { | ||
1107 | unsigned long flags; | ||
1108 | |||
1109 | local_irq_save(flags); | ||
1110 | |||
1111 | while (count--) | ||
1112 | { | ||
1113 | if (*str == '\n') | ||
1114 | scc_ch_write ('\r'); | ||
1115 | scc_ch_write (*str++); | ||
1116 | } | ||
1117 | local_irq_restore(flags); | ||
1118 | } | ||
1119 | |||
1120 | static struct tty_driver *scc_console_device(struct console *c, int *index) | ||
1121 | { | ||
1122 | *index = c->index; | ||
1123 | return scc_driver; | ||
1124 | } | ||
1125 | |||
1126 | static struct console sercons = { | ||
1127 | .name = "ttyS", | ||
1128 | .write = scc_console_write, | ||
1129 | .device = scc_console_device, | ||
1130 | .flags = CON_PRINTBUFFER, | ||
1131 | .index = -1, | ||
1132 | }; | ||
1133 | |||
1134 | |||
1135 | static int __init vme_scc_console_init(void) | ||
1136 | { | ||
1137 | if (vme_brdtype == VME_TYPE_MVME147 || | ||
1138 | vme_brdtype == VME_TYPE_MVME162 || | ||
1139 | vme_brdtype == VME_TYPE_MVME172 || | ||
1140 | vme_brdtype == VME_TYPE_BVME4000 || | ||
1141 | vme_brdtype == VME_TYPE_BVME6000) | ||
1142 | register_console(&sercons); | ||
1143 | return 0; | ||
1144 | } | ||
1145 | console_initcall(vme_scc_console_init); | ||