Import 2.3.18pre1
[davej-history.git] / drivers / char / cyclades.c
blob94e7e262805846e0dd7ba0a531fd8e9af553c9ac
1 #define BLOCKMOVE
2 #define Z_WAKE
3 static char rcsid[] =
4 "$Revision: 2.3.1.1 $$Date: 1999/07/15 16:45:53 $";
6 /*
7 * linux/drivers/char/cyclades.c
9 * This file contains the driver for the Cyclades Cyclom-Y multiport
10 * serial boards.
12 * Maintained by Ivan Passos (ivan@cyclades.com),
13 * Marcio Saito (marcio@cyclades.com) and
14 * Randolph Bentson (bentson@grieg.seaslug.org).
16 * For Technical support and installation problems, please send e-mail
17 * to support@cyclades.com.
19 * Much of the design and some of the code came from serial.c
20 * which was copyright (C) 1991, 1992 Linus Torvalds. It was
21 * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
22 * and then fixed as suggested by Michael K. Johnson 12/12/92.
24 * This version supports shared IRQ's (only for PCI boards).
26 * This module exports the following rs232 io functions:
27 * int cy_init(void);
28 * int cy_open(struct tty_struct *tty, struct file *filp);
29 * and the following functions for modularization.
30 * int init_module(void);
31 * void cleanup_module(void);
33 * $Log: cyclades.c,v $
34 * Revision 2.3.1.1 1999/07/15 16:45:53 ivan
35 * Removed CY_PROC conditional compilation;
36 * Implemented SMP-awareness for the driver;
37 * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off]
38 * functions;
39 * The driver now accepts memory addresses (maddr=0xMMMMM) and IRQs
40 * (irq=NN) as parameters (only for ISA boards);
41 * Fixed bug in set_line_char that would prevent the Cyclades-Z
42 * ports from being configured at speeds above 115.2Kbps;
43 * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control
44 * switching from working properly;
45 * The driver now only prints IRQ info for the Cyclades-Z if it's
46 * configured to work in interrupt mode;
48 * Revision 2.2.2.3 1999/06/28 11:13:29 ivan
49 * Added support for interrupt mode operation for the Z cards;
50 * Removed the driver inactivity control for the Z;
51 * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when
52 * the Z firmware is not loaded yet;
53 * Replaced the "manual" Z Tx flush buffer by a call to a FW command of
54 * same functionality;
55 * Implemented workaround for IRQ setting loss on the PCI configuration
56 * registers after a PCI bridge EEPROM reload (affects PLX9060 only);
58 * Revision 2.2.2.2 1999/05/14 17:18:15 ivan
59 * /proc entry location changed to /proc/tty/driver/cyclades;
60 * Added support to shared IRQ's (only for PCI boards);
61 * Added support for Cobalt Qube2 systems;
62 * IRQ [de]allocation scheme revisited;
63 * BREAK implementation changed in order to make use of the 'break_ctl'
64 * TTY facility;
65 * Fixed typo in TTY structure field 'driver_name';
66 * Included a PCI bridge reset and EEPROM reload in the board
67 * initialization code (for both Y and Z series).
69 * Revision 2.2.2.1 1999/04/08 16:17:43 ivan
70 * Fixed a bug in cy_wait_until_sent that was preventing the port to be
71 * closed properly after a SIGINT;
72 * Module usage counter scheme revisited;
73 * Added support to the upcoming Y PCI boards (i.e., support to additional
74 * PCI Device ID's).
76 * Revision 2.2.1.10 1999/01/20 16:14:29 ivan
77 * Removed all unnecessary page-alignement operations in ioremap calls
78 * (ioremap is currently safe for these operations).
80 * Revision 2.2.1.9 1998/12/30 18:18:30 ivan
81 * Changed access to PLX PCI bridge registers from I/O to MMIO, in
82 * order to make PLX9050-based boards work with certain motherboards.
84 * Revision 2.2.1.8 1998/11/13 12:46:20 ivan
85 * cy_close function now resets (correctly) the tty->closing flag;
86 * JIFFIES_DIFF macro fixed.
88 * Revision 2.2.1.7 1998/09/03 12:07:28 ivan
89 * Fixed bug in cy_close function, which was not informing HW of
90 * which port should have the reception disabled before doing so;
91 * fixed Cyclom-8YoP hardware detection bug.
93 * Revision 2.2.1.6 1998/08/20 17:15:39 ivan
94 * Fixed bug in cy_close function, which causes malfunction
95 * of one of the first 4 ports when a higher port is closed
96 * (Cyclom-Y only).
98 * Revision 2.2.1.5 1998/08/10 18:10:28 ivan
99 * Fixed Cyclom-4Yo hardware detection bug.
101 * Revision 2.2.1.4 1998/08/04 11:02:50 ivan
102 * /proc/cyclades implementation with great collaboration of
103 * Marc Lewis <marc@blarg.net>;
104 * cyy_interrupt was changed to avoid occurence of kernel oopses
105 * during PPP operation.
107 * Revision 2.2.1.3 1998/06/01 12:09:10 ivan
108 * General code review in order to comply with 2.1 kernel standards;
109 * data loss prevention for slow devices revisited (cy_wait_until_sent
110 * was created);
111 * removed conditional compilation for new/old PCI structure support
112 * (now the driver only supports the new PCI structure).
114 * Revision 2.2.1.1 1998/03/19 16:43:12 ivan
115 * added conditional compilation for new/old PCI structure support;
116 * removed kernel series (2.0.x / 2.1.x) conditional compilation.
118 * Revision 2.1.1.3 1998/03/16 18:01:12 ivan
119 * cleaned up the data loss fix;
120 * fixed XON/XOFF handling once more (Cyclades-Z);
121 * general review of the driver routines;
122 * introduction of a mechanism to prevent data loss with slow
123 * printers, by forcing a delay before closing the port.
125 * Revision 2.1.1.2 1998/02/17 16:50:00 ivan
126 * fixed detection/handling of new CD1400 in Ye boards;
127 * fixed XON/XOFF handling (Cyclades-Z);
128 * fixed data loss caused by a premature port close;
129 * introduction of a flag that holds the CD1400 version ID per port
130 * (used by the CYGETCD1400VER new ioctl).
132 * Revision 2.1.1.1 1997/12/03 17:31:19 ivan
133 * Code review for the module cleanup routine;
134 * fixed RTS and DTR status report for new CD1400's in get_modem_info;
135 * includes anonymous changes regarding signal_pending.
137 * Revision 2.1 1997/11/01 17:42:41 ivan
138 * Changes in the driver to support Alpha systems (except 8Zo V_1);
139 * BREAK fix for the Cyclades-Z boards;
140 * driver inactivity control by FW implemented;
141 * introduction of flag that allows driver to take advantage of
142 * a special CD1400 feature related to HW flow control;
143 * added support for the CD1400 rev. J (Cyclom-Y boards);
144 * introduction of ioctls to:
145 * - control the rtsdtr_inv flag (Cyclom-Y);
146 * - control the rflow flag (Cyclom-Y);
147 * - adjust the polling interval (Cyclades-Z);
149 * Revision 1.36.4.33 1997/06/27 19:00:00 ivan
150 * Fixes related to kernel version conditional
151 * compilation.
153 * Revision 1.36.4.32 1997/06/14 19:30:00 ivan
154 * Compatibility issues between kernels 2.0.x and
155 * 2.1.x (mainly related to clear_bit function).
157 * Revision 1.36.4.31 1997/06/03 15:30:00 ivan
158 * Changes to define the memory window according to the
159 * board type.
161 * Revision 1.36.4.30 1997/05/16 15:30:00 daniel
162 * Changes to suport new cycladesZ boards.
164 * Revision 1.36.4.29 1997/05/12 11:30:00 daniel
165 * Merge of Bentson's and Daniel's version 1.36.4.28.
166 * Corrects bug in cy_detect_pci: check if there are more
167 * ports than the number of static structs allocated.
168 * Warning message during initialization if this driver is
169 * used with the new generation of cycladesZ boards. Those
170 * will be supported only in next release of the driver.
171 * Corrects bug in cy_detect_pci and cy_detect_isa that
172 * returned wrong number of VALID boards, when a cyclomY
173 * was found with no serial modules connected.
174 * Changes to use current (2.1.x) kernel subroutine names
175 * and created macros for compilation with 2.0.x kernel,
176 * instead of the other way around.
178 * Revision 1.36.4.28 1997/05/?? ??:00:00 bentson
179 * Change queue_task_irq_off to queue_task_irq.
180 * The inline function queue_task_irq_off (tqueue.h)
181 * was removed from latest releases of 2.1.x kernel.
182 * Use of macro __init to mark the initialization
183 * routines, so memory can be reused.
184 * Also incorporate implementation of critical region
185 * in function cleanup_module() created by anonymous
186 * linuxer.
188 * Revision 1.36.4.28 1997/04/25 16:00:00 daniel
189 * Change to support new firmware that solves DCD problem:
190 * application could fail to receive SIGHUP signal when DCD
191 * varying too fast.
193 * Revision 1.36.4.27 1997/03/26 10:30:00 daniel
194 * Changed for suport linux versions 2.1.X.
195 * Backward compatible with linux versions 2.0.X.
196 * Corrected illegal use of filler field in
197 * CH_CTRL struct.
198 * Deleted some debug messages.
200 * Revision 1.36.4.26 1997/02/27 12:00:00 daniel
201 * Included check for NULL tty pointer in cyz_poll.
203 * Revision 1.36.4.25 1997/02/26 16:28:30 bentson
204 * Bill Foster at Blarg! Online services noticed that
205 * some of the switch elements of -Z modem control
206 * lacked a closing "break;"
208 * Revision 1.36.4.24 1997/02/24 11:00:00 daniel
209 * Changed low water threshold for buffer xmit_buf
211 * Revision 1.36.4.23 1996/12/02 21:50:16 bentson
212 * Marcio provided fix to modem status fetch for -Z
214 * Revision 1.36.4.22 1996/10/28 22:41:17 bentson
215 * improve mapping of -Z control page (thanks to Steve
216 * Price <stevep@fa.tdktca.com> for help on this)
218 * Revision 1.36.4.21 1996/09/10 17:00:10 bentson
219 * shift from CPU-bound to memcopy in cyz_polling operation
221 * Revision 1.36.4.20 1996/09/09 18:30:32 Bentson
222 * Added support to set and report higher speeds.
224 * Revision 1.36.4.19c 1996/08/09 10:00:00 Marcio Saito
225 * Some fixes in the HW flow control for the BETA release.
226 * Don't try to register the IRQ.
228 * Revision 1.36.4.19 1996/08/08 16:23:18 Bentson
229 * make sure "cyc" appears in all kernel messages; all soft interrupts
230 * handled by same routine; recognize out-of-band reception; comment
231 * out some diagnostic messages; leave RTS/CTS flow control to hardware;
232 * fix race condition in -Z buffer management; only -Y needs to explictly
233 * flush chars; tidy up some startup messages;
235 * Revision 1.36.4.18 1996/07/25 18:57:31 bentson
236 * shift MOD_INC_USE_COUNT location to match
237 * serial.c; purge some diagnostic messages;
239 * Revision 1.36.4.17 1996/07/25 18:01:08 bentson
240 * enable modem status messages and fetch & process them; note
241 * time of last activity type for each port; set_line_char now
242 * supports more than line 0 and treats 0 baud correctly;
243 * get_modem_info senses rs_status;
245 * Revision 1.36.4.16 1996/07/20 08:43:15 bentson
246 * barely works--now's time to turn on
247 * more features 'til it breaks
249 * Revision 1.36.4.15 1996/07/19 22:30:06 bentson
250 * check more -Z board status; shorten boot message
252 * Revision 1.36.4.14 1996/07/19 22:20:37 bentson
253 * fix reference to ch_ctrl in startup; verify return
254 * values from cyz_issue_cmd and cyz_update_channel;
255 * more stuff to get modem control correct;
257 * Revision 1.36.4.13 1996/07/11 19:53:33 bentson
258 * more -Z stuff folded in; re-order changes to put -Z stuff
259 * after -Y stuff (to make changes clearer)
261 * Revision 1.36.4.12 1996/07/11 15:40:55 bentson
262 * Add code to poll Cyclades-Z. Add code to get & set RS-232 control.
263 * Add code to send break. Clear firmware ID word at startup (so
264 * that other code won't talk to inactive board).
266 * Revision 1.36.4.11 1996/07/09 05:28:29 bentson
267 * add code for -Z in set_line_char
269 * Revision 1.36.4.10 1996/07/08 19:28:37 bentson
270 * fold more -Z stuff (or in some cases, error messages)
271 * into driver; add text to "don't know what to do" messages.
273 * Revision 1.36.4.9 1996/07/08 18:38:38 bentson
274 * moved compile-time flags near top of file; cosmetic changes
275 * to narrow text (to allow 2-up printing); changed many declarations
276 * to "static" to limit external symbols; shuffled code order to
277 * coalesce -Y and -Z specific code, also to put internal functions
278 * in order of tty_driver structure; added code to recognize -Z
279 * ports (and for moment, do nothing or report error); add cy_startup
280 * to parse boot command line for extra base addresses for ISA probes;
282 * Revision 1.36.4.8 1996/06/25 17:40:19 bentson
283 * reorder some code, fix types of some vars (int vs. long),
284 * add cy_setup to support user declared ISA addresses
286 * Revision 1.36.4.7 1996/06/21 23:06:18 bentson
287 * dump ioctl based firmware load (it's now a user level
288 * program); ensure uninitialzed ports cannot be used
290 * Revision 1.36.4.6 1996/06/20 23:17:19 bentson
291 * rename vars and restructure some code
293 * Revision 1.36.4.5 1996/06/14 15:09:44 bentson
294 * get right status back after boot load
296 * Revision 1.36.4.4 1996/06/13 19:51:44 bentson
297 * successfully loads firmware
299 * Revision 1.36.4.3 1996/06/13 06:08:33 bentson
300 * add more of the code for the boot/load ioctls
302 * Revision 1.36.4.2 1996/06/11 21:00:51 bentson
303 * start to add Z functionality--starting with ioctl
304 * for loading firmware
306 * Revision 1.36.4.1 1996/06/10 18:03:02 bentson
307 * added code to recognize Z/PCI card at initialization; report
308 * presence, but card is not initialized (because firmware needs
309 * to be loaded)
311 * Revision 1.36.3.8 1996/06/07 16:29:00 bentson
312 * starting minor number at zero; added missing verify_area
313 * as noted by Heiko Eissfeldt <heiko@colossus.escape.de>
315 * Revision 1.36.3.7 1996/04/19 21:06:18 bentson
316 * remove unneeded boot message & fix CLOCAL hardware flow
317 * control (Miquel van Smoorenburg <miquels@Q.cistron.nl>);
318 * remove unused diagnostic statements; minor 0 is first;
320 * Revision 1.36.3.6 1996/03/13 13:21:17 marcio
321 * The kernel function vremap (available only in later 1.3.xx kernels)
322 * allows the access to memory addresses above the RAM. This revision
323 * of the driver supports PCI boards below 1Mb (device id 0x100) and
324 * above 1Mb (device id 0x101).
326 * Revision 1.36.3.5 1996/03/07 15:20:17 bentson
327 * Some global changes to interrupt handling spilled into
328 * this driver--mostly unused arguments in system function
329 * calls. Also added change by Marcio Saito which should
330 * reduce lost interrupts at startup by fast processors.
332 * Revision 1.36.3.4 1995/11/13 20:45:10 bentson
333 * Changes by Corey Minyard <minyard@wf-rch.cirr.com> distributed
334 * in 1.3.41 kernel to remove a possible race condition, extend
335 * some error messages, and let the driver run as a loadable module
336 * Change by Alan Wendt <alan@ez0.ezlink.com> to remove a
337 * possible race condition.
338 * Change by Marcio Saito <marcio@cyclades.com> to fix PCI addressing.
340 * Revision 1.36.3.3 1995/11/13 19:44:48 bentson
341 * Changes by Linus Torvalds in 1.3.33 kernel distribution
342 * required due to reordering of driver initialization.
343 * Drivers are now initialized *after* memory management.
345 * Revision 1.36.3.2 1995/09/08 22:07:14 bentson
346 * remove printk from ISR; fix typo
348 * Revision 1.36.3.1 1995/09/01 12:00:42 marcio
349 * Minor fixes in the PCI board support. PCI function calls in
350 * conditional compilation (CONFIG_PCI). Thanks to Jim Duncan
351 * <duncan@okay.com>. "bad serial count" message removed.
353 * Revision 1.36.3 1995/08/22 09:19:42 marcio
354 * Cyclom-Y/PCI support added. Changes in the cy_init routine and
355 * board initialization. Changes in the boot messages. The driver
356 * supports up to 4 boards and 64 ports by default.
358 * Revision 1.36.1.4 1995/03/29 06:14:14 bentson
359 * disambiguate between Cyclom-16Y and Cyclom-32Ye;
361 * Revision 1.36.1.3 1995/03/23 22:15:35 bentson
362 * add missing break in modem control block in ioctl switch statement
363 * (discovered by Michael Edward Chastain <mec@jobe.shell.portal.com>);
365 * Revision 1.36.1.2 1995/03/22 19:16:22 bentson
366 * make sure CTS flow control is set as soon as possible (thanks
367 * to note from David Lambert <lambert@chesapeake.rps.slb.com>);
369 * Revision 1.36.1.1 1995/03/13 15:44:43 bentson
370 * initialize defaults for receive threshold and stale data timeout;
371 * cosmetic changes;
373 * Revision 1.36 1995/03/10 23:33:53 bentson
374 * added support of chips 4-7 in 32 port Cyclom-Ye;
375 * fix cy_interrupt pointer dereference problem
376 * (Joe Portman <baron@aa.net>);
377 * give better error response if open is attempted on non-existent port
378 * (Zachariah Vaum <jchryslr@netcom.com>);
379 * correct command timeout (Kenneth Lerman <lerman@@seltd.newnet.com>);
380 * conditional compilation for -16Y on systems with fast, noisy bus;
381 * comment out diagnostic print function;
382 * cleaned up table of base addresses;
383 * set receiver time-out period register to correct value,
384 * set receive threshold to better default values,
385 * set chip timer to more accurate 200 Hz ticking,
386 * add code to monitor and modify receive parameters
387 * (Rik Faith <faith@cs.unc.edu> Nick Simicich
388 * <njs@scifi.emi.net>);
390 * Revision 1.35 1994/12/16 13:54:18 steffen
391 * additional patch by Marcio Saito for board detection
392 * Accidently left out in 1.34
394 * Revision 1.34 1994/12/10 12:37:12 steffen
395 * This is the corrected version as suggested by Marcio Saito
397 * Revision 1.33 1994/12/01 22:41:18 bentson
398 * add hooks to support more high speeds directly; add tytso
399 * patch regarding CLOCAL wakeups
401 * Revision 1.32 1994/11/23 19:50:04 bentson
402 * allow direct kernel control of higher signalling rates;
403 * look for cards at additional locations
405 * Revision 1.31 1994/11/16 04:33:28 bentson
406 * ANOTHER fix from Corey Minyard, minyard@wf-rch.cirr.com--
407 * a problem in chars_in_buffer has been resolved by some
408 * small changes; this should yield smoother output
410 * Revision 1.30 1994/11/16 04:28:05 bentson
411 * Fix from Corey Minyard, Internet: minyard@metronet.com,
412 * UUCP: minyard@wf-rch.cirr.com, WORK: minyardbnr.ca, to
413 * cy_hangup that appears to clear up much (all?) of the
414 * DTR glitches; also he's added/cleaned-up diagnostic messages
416 * Revision 1.29 1994/11/16 04:16:07 bentson
417 * add change proposed by Ralph Sims, ralphs@halcyon.com, to
418 * operate higher speeds in same way as other serial ports;
419 * add more serial ports (for up to two 16-port muxes).
421 * Revision 1.28 1994/11/04 00:13:16 root
422 * turn off diagnostic messages
424 * Revision 1.27 1994/11/03 23:46:37 root
425 * bunch of changes to bring driver into greater conformance
426 * with the serial.c driver (looking for missed fixes)
428 * Revision 1.26 1994/11/03 22:40:36 root
429 * automatic interrupt probing fixed.
431 * Revision 1.25 1994/11/03 20:17:02 root
432 * start to implement auto-irq
434 * Revision 1.24 1994/11/03 18:01:55 root
435 * still working on modem signals--trying not to drop DTR
436 * during the getty/login processes
438 * Revision 1.23 1994/11/03 17:51:36 root
439 * extend baud rate support; set receive threshold as function
440 * of baud rate; fix some problems with RTS/CTS;
442 * Revision 1.22 1994/11/02 18:05:35 root
443 * changed arguments to udelay to type long to get
444 * delays to be of correct duration
446 * Revision 1.21 1994/11/02 17:37:30 root
447 * employ udelay (after calibrating loops_per_second earlier
448 * in init/main.c) instead of using home-grown delay routines
450 * Revision 1.20 1994/11/02 03:11:38 root
451 * cy_chars_in_buffer forces a return value of 0 to let
452 * login work (don't know why it does); some functions
453 * that were returning EFAULT, now executes the code;
454 * more work on deciding when to disable xmit interrupts;
456 * Revision 1.19 1994/11/01 20:10:14 root
457 * define routine to start transmission interrupts (by enabling
458 * transmit interrupts); directly enable/disable modem interrupts;
460 * Revision 1.18 1994/11/01 18:40:45 bentson
461 * Don't always enable transmit interrupts in startup; interrupt on
462 * TxMpty instead of TxRdy to help characters get out before shutdown;
463 * restructure xmit interrupt to check for chars first and quit if
464 * none are ready to go; modem status (MXVRx) is upright, _not_ inverted
465 * (to my view);
467 * Revision 1.17 1994/10/30 04:39:45 bentson
468 * rename serial_driver and callout_driver to cy_serial_driver and
469 * cy_callout_driver to avoid linkage interference; initialize
470 * info->type to PORT_CIRRUS; ruggedize paranoia test; elide ->port
471 * from cyclades_port structure; add paranoia check to cy_close;
473 * Revision 1.16 1994/10/30 01:14:33 bentson
474 * change major numbers; add some _early_ return statements;
476 * Revision 1.15 1994/10/29 06:43:15 bentson
477 * final tidying up for clean compile; enable some error reporting
479 * Revision 1.14 1994/10/28 20:30:22 Bentson
480 * lots of changes to drag the driver towards the new tty_io
481 * structures and operation. not expected to work, but may
482 * compile cleanly.
484 * Revision 1.13 1994/07/21 23:08:57 Bentson
485 * add some diagnostic cruft; support 24 lines (for testing
486 * both -8Y and -16Y cards; be more thorough in servicing all
487 * chips during interrupt; add "volatile" a few places to
488 * circumvent compiler optimizations; fix base & offset
489 * computations in block_til_ready (was causing chip 0 to
490 * stop operation)
492 * Revision 1.12 1994/07/19 16:42:11 Bentson
493 * add some hackery for kernel version 1.1.8; expand
494 * error messages; refine timing for delay loops and
495 * declare loop params volatile
497 * Revision 1.11 1994/06/11 21:53:10 bentson
498 * get use of save_car right in transmit interrupt service
500 * Revision 1.10.1.1 1994/06/11 21:31:18 bentson
501 * add some diagnostic printing; try to fix save_car stuff
503 * Revision 1.10 1994/06/11 20:36:08 bentson
504 * clean up compiler warnings
506 * Revision 1.9 1994/06/11 19:42:46 bentson
507 * added a bunch of code to support modem signalling
509 * Revision 1.8 1994/06/11 17:57:07 bentson
510 * recognize break & parity error
512 * Revision 1.7 1994/06/05 05:51:34 bentson
513 * Reorder baud table to be monotonic; add cli to CP; discard
514 * incoming characters and status if the line isn't open; start to
515 * fold code into cy_throttle; start to port get_serial_info,
516 * set_serial_info, get_modem_info, set_modem_info, and send_break
517 * from serial.c; expand cy_ioctl; relocate and expand config_setup;
518 * get flow control characters from tty struct; invalidate ports w/o
519 * hardware;
521 * Revision 1.6 1994/05/31 18:42:21 bentson
522 * add a loop-breaker in the interrupt service routine;
523 * note when port is initialized so that it can be shut
524 * down under the right conditions; receive works without
525 * any obvious errors
527 * Revision 1.5 1994/05/30 00:55:02 bentson
528 * transmit works without obvious errors
530 * Revision 1.4 1994/05/27 18:46:27 bentson
531 * incorporated more code from lib_y.c; can now print short
532 * strings under interrupt control to port zero; seems to
533 * select ports/channels/lines correctly
535 * Revision 1.3 1994/05/25 22:12:44 bentson
536 * shifting from multi-port on a card to proper multiplexor
537 * data structures; added skeletons of most routines
539 * Revision 1.2 1994/05/19 13:21:43 bentson
540 * start to crib from other sources
544 /* If you need to install more boards than NR_CARDS, change the constant
545 in the definition below. No other change is necessary to support up to
546 eight boards. Beyond that you'll have to extend cy_isa_addresses. */
548 #define NR_CARDS 4
551 If the total number of ports is larger than NR_PORTS, change this
552 constant in the definition below. No other change is necessary to
553 support more boards/ports. */
555 #define NR_PORTS 256
557 #define ZE_V1_NPORTS 64
558 #define ZO_V1 0
559 #define ZO_V2 1
560 #define ZE_V1 2
562 #define SERIAL_PARANOIA_CHECK
563 #undef CY_DEBUG_OPEN
564 #undef CY_DEBUG_THROTTLE
565 #undef CY_DEBUG_OTHER
566 #undef CY_DEBUG_IO
567 #undef CY_DEBUG_COUNT
568 #undef CY_DEBUG_DTR
569 #undef CY_DEBUG_WAIT_UNTIL_SENT
570 #undef CY_DEBUG_INTERRUPTS
571 #undef CY_16Y_HACK
572 #undef CY_ENABLE_MONITORING
573 #undef CY_PCI_DEBUG
575 #if 0
576 #define PAUSE __asm__("nop");
577 #else
578 #define PAUSE ;
579 #endif
581 #define cy_min(a,b) (((a)<(b))?(a):(b))
583 #if 0
584 /********
585 * For the next two macros, it is assumed that the buffer size is a
586 * power of 2
587 ********/
589 #define CHARS_IN_BUF(buf_ctrl) \
590 ((cy_readl(&buf_ctrl->rx_put) - \
591 cy_readl(&buf_ctrl->rx_get) + \
592 cy_readl(&buf_ctrl->rx_bufsize)) & \
593 (cy_readl(&buf_ctrl->rx_bufsize) - 1))
595 #define SPACE_IN_BUF(buf_ctrl) \
596 ((cy_readl(&buf_ctrl->tx_get) - \
597 cy_readl(&buf_ctrl->tx_put) + \
598 cy_readl(&buf_ctrl->tx_bufsize) - 1) & \
599 (cy_readl(&buf_ctrl->tx_bufsize) - 1))
600 #endif
603 * Include section
605 #include <linux/config.h>
606 #include <linux/module.h>
607 #include <linux/errno.h>
608 #include <linux/signal.h>
609 #include <linux/sched.h>
610 #include <linux/timer.h>
611 #include <linux/interrupt.h>
612 #include <linux/tty.h>
613 #include <linux/serial.h>
614 #include <linux/major.h>
615 #include <linux/string.h>
616 #include <linux/fcntl.h>
617 #include <linux/ptrace.h>
618 #include <linux/cyclades.h>
619 #include <linux/mm.h>
620 #include <linux/init.h>
621 #include <linux/delay.h>
622 #include <linux/spinlock.h>
624 #include <asm/system.h>
625 #include <asm/io.h>
626 #include <asm/irq.h>
627 #include <asm/uaccess.h>
628 #include <asm/bitops.h>
630 #define CY_LOCK(info,flags) \
631 do { \
632 spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \
633 } while (0)
635 #define CY_UNLOCK(info,flags) \
636 do { \
637 spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \
638 } while (0)
640 #include <linux/types.h>
641 #include <linux/kernel.h>
642 #include <linux/pci.h>
643 #include <linux/version.h>
645 #include <linux/stat.h>
646 #include <linux/proc_fs.h>
648 #ifdef CONFIG_COBALT_27
649 #include <asm/page.h>
650 #include <asm/pgtable.h>
652 #define CACHED_TO_UNCACHED(x) (((unsigned long)(x) & \
653 (unsigned long)0x1fffffff) + KSEG1)
654 #endif
656 #define cy_put_user put_user
658 static unsigned long cy_get_user(unsigned long *addr)
660 unsigned long result = 0;
661 int error = get_user (result, addr);
662 if (error)
663 printk ("cyclades: cy_get_user: error == %d\n", error);
664 return result;
667 #ifndef MIN
668 #define MIN(a,b) ((a) < (b) ? (a) : (b))
669 #endif
671 #define IS_CYC_Z(card) ((card).num_chips == -1)
673 #define Z_FPGA_CHECK(card) \
674 ((cy_readl(&((struct RUNTIME_9060 *) \
675 ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
677 #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 *) \
678 ((card).ctl_addr))->mail_box_0)) || \
679 Z_FPGA_CHECK(card)) && \
680 (ZFIRM_ID==cy_readl(&((struct FIRM_ID *) \
681 ((card).base_addr+ID_ADDRESS))->signature)))
683 #define WAKEUP_CHARS (SERIAL_XMIT_SIZE-256)
685 #define STD_COM_FLAGS (0)
687 #define JIFFIES_DIFF(n, j) ((j) - (n))
689 static DECLARE_TASK_QUEUE(tq_cyclades);
691 static struct tty_driver cy_serial_driver, cy_callout_driver;
692 static int serial_refcount;
694 #ifndef CONFIG_COBALT_27
695 /* This is the address lookup table. The driver will probe for
696 Cyclom-Y/ISA boards at all addresses in here. If you want the
697 driver to probe addresses at a different address, add it to
698 this table. If the driver is probing some other board and
699 causing problems, remove the offending address from this table.
700 The cy_setup function extracts additional addresses from the
701 boot options line. The form is "cyclades=address,address..."
704 static unsigned char *cy_isa_addresses[] = {
705 (unsigned char *) 0xD0000,
706 (unsigned char *) 0xD2000,
707 (unsigned char *) 0xD4000,
708 (unsigned char *) 0xD6000,
709 (unsigned char *) 0xD8000,
710 (unsigned char *) 0xDA000,
711 (unsigned char *) 0xDC000,
712 (unsigned char *) 0xDE000,
713 0,0,0,0,0,0,0,0
715 #define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
717 #ifdef MODULE
718 static int maddr[NR_CARDS] = { 0, };
719 static int irq[NR_CARDS] = { 0, };
721 MODULE_PARM(maddr, "1-" __MODULE_STRING(NR_CARDS) "l");
722 MODULE_PARM(irq, "1-" __MODULE_STRING(NR_CARDS) "i");
723 #endif
725 #endif /* CONFIG_COBALT_27 */
727 /* This is the per-card data structure containing address, irq, number of
728 channels, etc. This driver supports a maximum of NR_CARDS cards.
730 static struct cyclades_card cy_card[NR_CARDS];
732 /* This is the per-channel data structure containing pointers, flags
733 and variables for the port. This driver supports a maximum of NR_PORTS.
735 static struct cyclades_port cy_port[NR_PORTS];
737 static int cy_next_channel = 0; /* next minor available */
739 static struct tty_struct *serial_table[NR_PORTS];
740 static struct termios *serial_termios[NR_PORTS];
741 static struct termios *serial_termios_locked[NR_PORTS];
744 * tmp_buf is used as a temporary buffer by serial_write. We need to
745 * lock it in case the copy_from_user blocks while swapping in a page,
746 * and some other program tries to do a serial write at the same time.
747 * Since the lock will only come under contention when the system is
748 * swapping and available memory is low, it makes sense to share one
749 * buffer across all the serial ports, since it significantly saves
750 * memory if large numbers of serial ports are open. This buffer is
751 * allocated when the first cy_open occurs.
753 static unsigned char *tmp_buf;
754 DECLARE_MUTEX(tmp_buf_sem);
757 * This is used to look up the divisor speeds and the timeouts
758 * We're normally limited to 15 distinct baud rates. The extra
759 * are accessed via settings in info->flags.
760 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
761 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
762 * HI VHI
763 * 20
765 static int baud_table[] = {
766 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
767 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,115200,150000,
768 230400, 0};
770 static char baud_co_25[] = { /* 25 MHz clock option table */
771 /* value => 00 01 02 03 04 */
772 /* divide by 8 32 128 512 2048 */
773 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
774 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
776 static char baud_bpr_25[] = { /* 25 MHz baud rate period table */
777 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
778 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15};
780 static char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */
781 /* value => 00 01 02 03 04 */
782 /* divide by 8 32 128 512 2048 */
783 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
784 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
785 0x00};
787 static char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */
788 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
789 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
790 0x21};
792 static char baud_cor3[] = { /* receive threshold */
793 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
794 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
795 0x07};
798 * The Cyclades driver implements HW flow control as any serial driver.
799 * The cyclades_port structure member rflow and the vector rflow_thr
800 * allows us to take advantage of a special feature in the CD1400 to avoid
801 * data loss even when the system interrupt latency is too high. These flags
802 * are to be used only with very special applications. Setting these flags
803 * requires the use of a special cable (DTR and RTS reversed). In the new
804 * CD1400-based boards (rev. 6.00 or later), there is no need for special
805 * cables.
808 static char rflow_thr[] = { /* rflow threshold */
809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
811 0x0a};
813 /* The Cyclom-Ye has placed the sequential chips in non-sequential
814 * address order. This look-up table overcomes that problem.
816 static int cy_chip_offset [] =
817 { 0x0000,
818 0x0400,
819 0x0800,
820 0x0C00,
821 0x0200,
822 0x0600,
823 0x0A00,
824 0x0E00
827 /* PCI related definitions */
829 static unsigned short cy_pci_nboard = 0;
830 static unsigned short cy_isa_nboard = 0;
831 static unsigned short cy_nboard = 0;
832 static unsigned short cy_pci_dev_id[] = {
833 PCI_DEVICE_ID_CYCLOM_Y_Lo, /* PCI < 1Mb */
834 PCI_DEVICE_ID_CYCLOM_Y_Hi, /* PCI > 1Mb */
835 PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */
836 PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */
837 PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */
838 PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */
839 PCI_DEVICE_ID_CYCLOM_Z_Lo, /* Z PCI < 1Mb */
840 PCI_DEVICE_ID_CYCLOM_Z_Hi, /* Z PCI > 1Mb */
841 0 /* end of table */
845 static void cy_start(struct tty_struct *);
846 static void set_line_char(struct cyclades_port *);
847 #ifndef CONFIG_COBALT_27
848 static unsigned detect_isa_irq (volatile ucchar *);
849 #endif /* CONFIG_COBALT_27 */
850 #ifdef CYCLOM_SHOW_STATUS
851 static void show_status(int);
852 #endif
854 static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
856 #ifndef CONFIG_CYZ_INTR
857 static void cyz_poll(unsigned long);
859 /* The Cyclades-Z polling cycle is defined by this variable */
860 static long cyz_polling_cycle = CZ_DEF_POLL;
862 static int cyz_timeron = 0;
863 static struct timer_list
864 cyz_timerlist = {
865 NULL, NULL, 0, 0, cyz_poll
867 #endif /* CONFIG_CYZ_INTR */
869 /**************************************************
870 error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
871 copy_to_user (to, from, count);
872 ***************************************************************
873 error = verify_area(VERIFY_READ, (void *) arg, sizeof(unsigned long *));
874 copy_from_user(to, from, count);
875 **************************************************/
878 static inline int
879 serial_paranoia_check(struct cyclades_port *info,
880 kdev_t device, const char *routine)
882 #ifdef SERIAL_PARANOIA_CHECK
883 static const char *badmagic =
884 "cyc Warning: bad magic number for serial struct (%s) in %s\n";
885 static const char *badinfo =
886 "cyc Warning: null cyclades_port for (%s) in %s\n";
887 static const char *badrange =
888 "cyc Warning: cyclades_port out of range for (%s) in %s\n";
890 if (!info) {
891 printk(badinfo, kdevname(device), routine);
892 return 1;
895 if( (long)info < (long)(&cy_port[0])
896 || (long)(&cy_port[NR_PORTS]) < (long)info ){
897 printk(badrange, kdevname(device), routine);
898 return 1;
901 if (info->magic != CYCLADES_MAGIC) {
902 printk(badmagic, kdevname(device), routine);
903 return 1;
905 #endif
906 return 0;
907 } /* serial_paranoia_check */
910 * This routine is used by the interrupt handler to schedule
911 * processing in the software interrupt portion of the driver
912 * (also known as the "bottom half"). This can be called any
913 * number of times for any channel without harm.
915 static inline void
916 cy_sched_event(struct cyclades_port *info, int event)
918 info->event |= 1 << event; /* remember what kind of event and who */
919 queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */
920 mark_bh(CYCLADES_BH); /* then trigger event */
921 } /* cy_sched_event */
925 * This routine is used to handle the "bottom half" processing for the
926 * serial driver, known also the "software interrupt" processing.
927 * This processing is done at the kernel interrupt level, after the
928 * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
929 * is where time-consuming activities which can not be done in the
930 * interrupt driver proper are done; the interrupt driver schedules
931 * them using cy_sched_event(), and they get done here.
933 * This is done through one level of indirection--the task queue.
934 * When a hardware interrupt service routine wants service by the
935 * driver's bottom half, it enqueues the appropriate tq_struct (one
936 * per port) to the tq_cyclades work queue and sets a request flag
937 * via mark_bh for processing that queue. When the time is right,
938 * do_cyclades_bh is called (because of the mark_bh) and it requests
939 * that the work queue be processed.
941 * Although this may seem unwieldy, it gives the system a way to
942 * pass an argument (in this case the pointer to the cyclades_port
943 * structure) to the bottom half of the driver. Previous kernels
944 * had to poll every port to see if that port needed servicing.
946 static void
947 do_cyclades_bh(void)
949 run_task_queue(&tq_cyclades);
950 } /* do_cyclades_bh */
952 static void
953 do_softint(void *private_)
955 struct cyclades_port *info = (struct cyclades_port *) private_;
956 struct tty_struct *tty;
958 tty = info->tty;
959 if (!tty)
960 return;
962 if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
963 tty_hangup(info->tty);
964 wake_up_interruptible(&info->open_wait);
965 info->flags &= ~(ASYNC_NORMAL_ACTIVE|
966 ASYNC_CALLOUT_ACTIVE);
968 if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
969 wake_up_interruptible(&info->open_wait);
971 if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
972 if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
973 && tty->ldisc.write_wakeup){
974 (tty->ldisc.write_wakeup)(tty);
976 wake_up_interruptible(&tty->write_wait);
978 #ifdef Z_WAKE
979 if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
980 wake_up_interruptible(&info->shutdown_wait);
982 #endif
983 } /* do_softint */
986 /***********************************************************/
987 /********* Start of block of Cyclom-Y specific code ********/
989 /* This routine waits up to 1000 micro-seconds for the previous
990 command to the Cirrus chip to complete and then issues the
991 new command. An error is returned if the previous command
992 didn't finish within the time limit.
994 This function is only called from inside spinlock-protected code.
996 static int
997 cyy_issue_cmd(volatile ucchar *base_addr, u_char cmd, int index)
999 volatile int i;
1001 /* Check to see that the previous command has completed */
1002 for(i = 0 ; i < 100 ; i++){
1003 if (cy_readb(base_addr+(CyCCR<<index)) == 0){
1004 break;
1006 udelay(10L);
1008 /* if the CCR never cleared, the previous command
1009 didn't finish within the "reasonable time" */
1010 if (i == 100) return (-1);
1012 /* Issue the new command */
1013 cy_writeb((u_long)base_addr+(CyCCR<<index), cmd);
1015 return(0);
1016 } /* cyy_issue_cmd */
1018 #ifndef CONFIG_COBALT_27 /* ISA interrupt detection code */
1019 static unsigned detect_isa_irq (volatile ucchar *address)
1021 int irq;
1022 unsigned long irqs, flags;
1023 int save_xir, save_car;
1024 int index = 0; /* IRQ probing is only for ISA */
1026 /* forget possible initially masked and pending IRQ */
1027 irq = probe_irq_off(probe_irq_on());
1029 /* Clear interrupts on the board first */
1030 cy_writeb((u_long)address + (Cy_ClrIntr<<index), 0);
1031 /* Cy_ClrIntr is 0x1800 */
1033 irqs = probe_irq_on();
1034 /* Wait ... */
1035 udelay(5000L);
1037 /* Enable the Tx interrupts on the CD1400 */
1038 save_flags(flags); cli();
1039 cy_writeb((u_long)address + (CyCAR<<index), 0);
1040 cyy_issue_cmd(address, CyCHAN_CTL|CyENB_XMTR, index);
1042 cy_writeb((u_long)address + (CyCAR<<index), 0);
1043 cy_writeb((u_long)address + (CySRER<<index),
1044 cy_readb(address + (CySRER<<index)) | CyTxMpty);
1045 restore_flags(flags);
1047 /* Wait ... */
1048 udelay(5000L);
1050 /* Check which interrupt is in use */
1051 irq = probe_irq_off(irqs);
1053 /* Clean up */
1054 save_xir = (u_char) cy_readb(address + (CyTIR<<index));
1055 save_car = cy_readb(address + (CyCAR<<index));
1056 cy_writeb((u_long)address + (CyCAR<<index), (save_xir & 0x3));
1057 cy_writeb((u_long)address + (CySRER<<index),
1058 cy_readb(address + (CySRER<<index)) & ~CyTxMpty);
1059 cy_writeb((u_long)address + (CyTIR<<index), (save_xir & 0x3f));
1060 cy_writeb((u_long)address + (CyCAR<<index), (save_car));
1061 cy_writeb((u_long)address + (Cy_ClrIntr<<index), 0);
1062 /* Cy_ClrIntr is 0x1800 */
1064 return (irq > 0)? irq : 0;
1066 #endif /* CONFIG_COBALT_27 */
1068 /* The real interrupt service routine is called
1069 whenever the card wants its hand held--chars
1070 received, out buffer empty, modem change, etc.
1072 static void
1073 cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1075 struct tty_struct *tty;
1076 int status;
1077 struct cyclades_card *cinfo;
1078 struct cyclades_port *info;
1079 volatile unsigned char *base_addr, *card_base_addr;
1080 int chip;
1081 int save_xir, channel, save_car;
1082 char data;
1083 volatile int char_count;
1084 int outch;
1085 int i,j,index;
1086 int too_many;
1087 int had_work;
1088 int mdm_change;
1089 int mdm_status;
1091 if((cinfo = (struct cyclades_card *)dev_id) == 0){
1092 #ifdef CY_DEBUG_INTERRUPTS
1093 printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
1094 #endif
1095 return; /* spurious interrupt */
1098 card_base_addr = (unsigned char *)cinfo->base_addr;
1099 index = cinfo->bus_index;
1102 /* This loop checks all chips in the card. Make a note whenever
1103 _any_ chip had some work to do, as this is considered an
1104 indication that there will be more to do. Only when no chip
1105 has any work does this outermost loop exit.
1108 had_work = 0;
1109 for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) {
1110 base_addr = (unsigned char *)
1111 (cinfo->base_addr + (cy_chip_offset[chip]<<index));
1112 too_many = 0;
1113 while ( (status = cy_readb(base_addr+(CySVRR<<index))) != 0x00) {
1114 had_work++;
1115 /* The purpose of the following test is to ensure that
1116 no chip can monopolize the driver. This forces the
1117 chips to be checked in a round-robin fashion (after
1118 draining each of a bunch (1000) of characters).
1120 if(1000<too_many++){
1121 break;
1123 if (status & CySRReceive) { /* reception interrupt */
1124 #ifdef CY_DEBUG_INTERRUPTS
1125 printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
1126 #endif
1127 /* determine the channel & change to that context */
1128 spin_lock(&cinfo->card_lock);
1129 save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
1130 channel = (u_short ) (save_xir & CyIRChannel);
1131 i = channel + chip * 4 + cinfo->first_line;
1132 info = &cy_port[i];
1133 info->last_active = jiffies;
1134 save_car = cy_readb(base_addr+(CyCAR<<index));
1135 cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1136 spin_unlock(&cinfo->card_lock);
1138 /* if there is nowhere to put the data, discard it */
1139 if(info->tty == 0){
1140 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1141 if ( j == CyIVRRxEx ) { /* exception */
1142 data = cy_readb(base_addr+(CyRDSR<<index));
1143 } else { /* normal character reception */
1144 char_count = cy_readb(base_addr+(CyRDCR<<index));
1145 while(char_count--){
1146 data = cy_readb(base_addr+(CyRDSR<<index));
1149 }else{ /* there is an open port for this data */
1150 tty = info->tty;
1151 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1152 if ( j == CyIVRRxEx ) { /* exception */
1153 data = cy_readb(base_addr+(CyRDSR<<index));
1154 if(data & info->ignore_status_mask){
1155 continue;
1157 if (tty->flip.count < TTY_FLIPBUF_SIZE){
1158 tty->flip.count++;
1159 if (data & info->read_status_mask){
1160 if(data & CyBREAK){
1161 *tty->flip.flag_buf_ptr++ =
1162 TTY_BREAK;
1163 *tty->flip.char_buf_ptr++ =
1164 cy_readb(base_addr+(CyRDSR<<index));
1165 if (info->flags & ASYNC_SAK){
1166 do_SAK(tty);
1168 }else if(data & CyFRAME){
1169 *tty->flip.flag_buf_ptr++ =
1170 TTY_FRAME;
1171 *tty->flip.char_buf_ptr++ =
1172 cy_readb(base_addr+(CyRDSR<<index));
1173 info->idle_stats.frame_errs++;
1174 }else if(data & CyPARITY){
1175 *tty->flip.flag_buf_ptr++ =
1176 TTY_PARITY;
1177 *tty->flip.char_buf_ptr++ =
1178 cy_readb(base_addr+(CyRDSR<<index));
1179 info->idle_stats.parity_errs++;
1180 }else if(data & CyOVERRUN){
1181 *tty->flip.flag_buf_ptr++ =
1182 TTY_OVERRUN;
1183 *tty->flip.char_buf_ptr++ = 0;
1184 /* If the flip buffer itself is
1185 overflowing, we still lose
1186 the next incoming character.
1188 if(tty->flip.count
1189 < TTY_FLIPBUF_SIZE){
1190 tty->flip.count++;
1191 *tty->flip.flag_buf_ptr++ =
1192 TTY_NORMAL;
1193 *tty->flip.char_buf_ptr++ =
1194 cy_readb(base_addr+(CyRDSR<<index));
1196 info->idle_stats.overruns++;
1197 /* These two conditions may imply */
1198 /* a normal read should be done. */
1199 /* }else if(data & CyTIMEOUT){ */
1200 /* }else if(data & CySPECHAR){ */
1201 }else{
1202 *tty->flip.flag_buf_ptr++ = 0;
1203 *tty->flip.char_buf_ptr++ = 0;
1205 }else{
1206 *tty->flip.flag_buf_ptr++ = 0;
1207 *tty->flip.char_buf_ptr++ = 0;
1209 }else{
1210 /* there was a software buffer
1211 overrun and nothing could be
1212 done about it!!! */
1213 info->idle_stats.overruns++;
1215 } else { /* normal character reception */
1216 /* load # chars available from the chip */
1217 char_count = cy_readb(base_addr+(CyRDCR<<index));
1219 #ifdef CY_ENABLE_MONITORING
1220 ++info->mon.int_count;
1221 info->mon.char_count += char_count;
1222 if (char_count > info->mon.char_max)
1223 info->mon.char_max = char_count;
1224 info->mon.char_last = char_count;
1225 #endif
1226 info->idle_stats.recv_bytes += char_count;
1227 info->idle_stats.recv_idle = jiffies;
1228 while(char_count--){
1229 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1230 break;
1232 tty->flip.count++;
1233 data = cy_readb(base_addr+(CyRDSR<<index));
1234 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1235 *tty->flip.char_buf_ptr++ = data;
1236 #ifdef CY_16Y_HACK
1237 udelay(10L);
1238 #endif
1241 queue_task(&tty->flip.tqueue, &tq_timer);
1243 /* end of service */
1244 spin_lock(&cinfo->card_lock);
1245 cy_writeb((u_long)base_addr+(CyRIR<<index), (save_xir & 0x3f));
1246 cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1247 spin_unlock(&cinfo->card_lock);
1251 if (status & CySRTransmit) { /* transmission interrupt */
1252 /* Since we only get here when the transmit buffer
1253 is empty, we know we can always stuff a dozen
1254 characters. */
1255 #ifdef CY_DEBUG_INTERRUPTS
1256 printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
1257 #endif
1259 /* determine the channel & change to that context */
1260 spin_lock(&cinfo->card_lock);
1261 save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index));
1262 channel = (u_short ) (save_xir & CyIRChannel);
1263 i = channel + chip * 4 + cinfo->first_line;
1264 save_car = cy_readb(base_addr+(CyCAR<<index));
1265 cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1266 spin_unlock(&cinfo->card_lock);
1268 /* validate the port# (as configured and open) */
1269 if( (i < 0) || (NR_PORTS <= i) ){
1270 spin_lock(&cinfo->card_lock);
1271 cy_writeb((u_long)base_addr+(CySRER<<index),
1272 cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
1273 spin_unlock(&cinfo->card_lock);
1274 goto txend;
1276 info = &cy_port[i];
1277 info->last_active = jiffies;
1278 if(info->tty == 0){
1279 spin_lock(&cinfo->card_lock);
1280 cy_writeb((u_long)base_addr+(CySRER<<index),
1281 cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
1282 spin_unlock(&cinfo->card_lock);
1283 goto txdone;
1286 /* load the on-chip space for outbound data */
1287 char_count = info->xmit_fifo_size;
1290 if(info->x_char) { /* send special char */
1291 outch = info->x_char;
1292 cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1293 char_count--;
1294 info->x_char = 0;
1297 if (info->breakon || info->breakoff) {
1298 if (info->breakon) {
1299 cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
1300 cy_writeb((u_long)base_addr + (CyTDR<<index), 0x81);
1301 info->breakon = 0;
1302 char_count -= 2;
1304 if (info->breakoff) {
1305 cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
1306 cy_writeb((u_long)base_addr + (CyTDR<<index), 0x83);
1307 info->breakoff = 0;
1308 char_count -= 2;
1312 while (char_count-- > 0){
1313 if (!info->xmit_cnt){
1314 spin_lock(&cinfo->card_lock);
1315 cy_writeb((u_long)base_addr+(CySRER<<index),
1316 cy_readb(base_addr+(CySRER<<index)) &
1317 ~CyTxMpty);
1318 spin_unlock(&cinfo->card_lock);
1319 goto txdone;
1321 if (info->xmit_buf == 0){
1322 spin_lock(&cinfo->card_lock);
1323 cy_writeb((u_long)base_addr+(CySRER<<index),
1324 cy_readb(base_addr+(CySRER<<index)) &
1325 ~CyTxMpty);
1326 spin_unlock(&cinfo->card_lock);
1327 goto txdone;
1329 if (info->tty->stopped || info->tty->hw_stopped){
1330 spin_lock(&cinfo->card_lock);
1331 cy_writeb((u_long)base_addr+(CySRER<<index),
1332 cy_readb(base_addr+(CySRER<<index)) &
1333 ~CyTxMpty);
1334 spin_unlock(&cinfo->card_lock);
1335 goto txdone;
1337 /* Because the Embedded Transmit Commands have
1338 been enabled, we must check to see if the
1339 escape character, NULL, is being sent. If it
1340 is, we must ensure that there is room for it
1341 to be doubled in the output stream. Therefore
1342 we no longer advance the pointer when the
1343 character is fetched, but rather wait until
1344 after the check for a NULL output character.
1345 This is necessary because there may not be
1346 room for the two chars needed to send a NULL.)
1348 outch = info->xmit_buf[info->xmit_tail];
1349 if( outch ){
1350 info->xmit_cnt--;
1351 info->xmit_tail = (info->xmit_tail + 1)
1352 & (SERIAL_XMIT_SIZE - 1);
1353 cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1354 }else{
1355 if(char_count > 1){
1356 info->xmit_cnt--;
1357 info->xmit_tail = (info->xmit_tail + 1)
1358 & (SERIAL_XMIT_SIZE - 1);
1359 cy_writeb((u_long)base_addr+(CyTDR<<index),
1360 outch);
1361 cy_writeb((u_long)base_addr+(CyTDR<<index), 0);
1362 char_count--;
1363 }else{
1368 txdone:
1369 if (info->xmit_cnt < WAKEUP_CHARS) {
1370 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1372 txend:
1373 /* end of service */
1374 spin_lock(&cinfo->card_lock);
1375 cy_writeb((u_long)base_addr+(CyTIR<<index),
1376 (save_xir & 0x3f));
1377 cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1378 spin_unlock(&cinfo->card_lock);
1381 if (status & CySRModem) { /* modem interrupt */
1383 /* determine the channel & change to that context */
1384 spin_lock(&cinfo->card_lock);
1385 save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));
1386 channel = (u_short ) (save_xir & CyIRChannel);
1387 info = &cy_port[channel + chip * 4
1388 + cinfo->first_line];
1389 info->last_active = jiffies;
1390 save_car = cy_readb(base_addr+(CyCAR<<index));
1391 cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1393 mdm_change = cy_readb(base_addr+(CyMISR<<index));
1394 mdm_status = cy_readb(base_addr+(CyMSVR1<<index));
1395 spin_unlock(&cinfo->card_lock);
1397 if(info->tty == 0){/* no place for data, ignore it*/
1399 }else{
1400 if((mdm_change & CyDCD)
1401 && (info->flags & ASYNC_CHECK_CD)){
1402 if(mdm_status & CyDCD){
1403 cy_sched_event(info,
1404 Cy_EVENT_OPEN_WAKEUP);
1405 }else if(!((info->flags
1406 & ASYNC_CALLOUT_ACTIVE)
1407 &&(info->flags
1408 & ASYNC_CALLOUT_NOHUP))){
1409 cy_sched_event(info,
1410 Cy_EVENT_HANGUP);
1413 if((mdm_change & CyCTS)
1414 && (info->flags & ASYNC_CTS_FLOW)){
1415 if(info->tty->hw_stopped){
1416 if(mdm_status & CyCTS){
1417 /* cy_start isn't used
1418 because... !!! */
1419 info->tty->hw_stopped = 0;
1420 spin_lock(&cinfo->card_lock);
1421 cy_writeb((u_long)base_addr+(CySRER<<index),
1422 cy_readb(base_addr+(CySRER<<index)) |
1423 CyTxMpty);
1424 spin_unlock(&cinfo->card_lock);
1425 cy_sched_event(info,
1426 Cy_EVENT_WRITE_WAKEUP);
1428 }else{
1429 if(!(mdm_status & CyCTS)){
1430 /* cy_stop isn't used
1431 because ... !!! */
1432 info->tty->hw_stopped = 1;
1433 spin_lock(&cinfo->card_lock);
1434 cy_writeb((u_long)base_addr+(CySRER<<index),
1435 cy_readb(base_addr+(CySRER<<index)) &
1436 ~CyTxMpty);
1437 spin_unlock(&cinfo->card_lock);
1441 if(mdm_status & CyDSR){
1443 if(mdm_status & CyRI){
1446 /* end of service */
1447 spin_lock(&cinfo->card_lock);
1448 cy_writeb((u_long)base_addr+(CyMIR<<index),
1449 (save_xir & 0x3f));
1450 cy_writeb((u_long)base_addr+(CyCAR<<index), save_car);
1451 spin_unlock(&cinfo->card_lock);
1453 } /* end while status != 0 */
1454 } /* end loop for chips... */
1455 } while(had_work);
1457 /* clear interrupts */
1458 spin_lock(&cinfo->card_lock);
1459 cy_writeb((u_long)card_base_addr + (Cy_ClrIntr<<index), 0);
1460 /* Cy_ClrIntr is 0x1800 */
1461 spin_unlock(&cinfo->card_lock);
1462 } /* cyy_interrupt */
1464 /***********************************************************/
1465 /********* End of block of Cyclom-Y specific code **********/
1466 /******** Start of block of Cyclades-Z specific code *********/
1467 /***********************************************************/
1470 static int
1471 cyz_fetch_msg( struct cyclades_card *cinfo,
1472 uclong *channel, ucchar *cmd, uclong *param)
1474 struct FIRM_ID *firm_id;
1475 struct ZFW_CTRL *zfw_ctrl;
1476 struct BOARD_CTRL *board_ctrl;
1477 unsigned long loc_doorbell;
1479 firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1480 if (!ISZLOADED(*cinfo)){
1481 return (-1);
1483 zfw_ctrl = (struct ZFW_CTRL *)
1484 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1485 board_ctrl = &zfw_ctrl->board_ctrl;
1487 loc_doorbell = cy_readl(&((struct RUNTIME_9060 *)
1488 (cinfo->ctl_addr))->loc_doorbell);
1489 if (loc_doorbell){
1490 *cmd = (char)(0xff & loc_doorbell);
1491 *channel = cy_readl(&board_ctrl->fwcmd_channel);
1492 *param = (uclong)cy_readl(&board_ctrl->fwcmd_param);
1493 cy_writel(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->loc_doorbell,
1494 0xffffffff);
1495 return 1;
1497 return 0;
1498 } /* cyz_fetch_msg */
1501 static int
1502 cyz_issue_cmd( struct cyclades_card *cinfo,
1503 uclong channel, ucchar cmd, uclong param)
1505 struct FIRM_ID *firm_id;
1506 struct ZFW_CTRL *zfw_ctrl;
1507 struct BOARD_CTRL *board_ctrl;
1508 volatile uclong *pci_doorbell;
1509 int index;
1511 firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1512 if (!ISZLOADED(*cinfo)){
1513 return (-1);
1515 zfw_ctrl = (struct ZFW_CTRL *)
1516 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1517 board_ctrl = &zfw_ctrl->board_ctrl;
1519 index = 0;
1520 pci_doorbell = (uclong *)(&((struct RUNTIME_9060 *)
1521 (cinfo->ctl_addr))->pci_doorbell);
1522 while( (cy_readl(pci_doorbell) & 0xff) != 0){
1523 if (index++ == 1000){
1524 return(-1);
1526 udelay(50L);
1528 cy_writel((u_long)&board_ctrl->hcmd_channel, channel);
1529 cy_writel((u_long)&board_ctrl->hcmd_param , param);
1530 cy_writel((u_long)pci_doorbell, (long)cmd);
1532 return(0);
1533 } /* cyz_issue_cmd */
1535 #ifdef CONFIG_CYZ_INTR
1536 static void
1537 cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1539 struct tty_struct *tty;
1540 struct cyclades_card *cinfo;
1541 struct cyclades_port *info;
1542 static volatile struct FIRM_ID *firm_id;
1543 static volatile struct ZFW_CTRL *zfw_ctrl;
1544 static volatile struct BOARD_CTRL *board_ctrl;
1545 static volatile struct CH_CTRL *ch_ctrl;
1546 static volatile struct BUF_CTRL *buf_ctrl;
1547 uclong channel;
1548 ucchar cmd;
1549 uclong param;
1550 uclong hw_ver, fw_ver;
1551 char data;
1552 volatile int char_count, special_count;
1553 #ifdef BLOCKMOVE
1554 int small_count;
1555 #endif
1556 volatile uclong tx_put, tx_get, tx_bufsize;
1557 volatile uclong rx_put, rx_get, rx_bufsize;
1559 if((cinfo = (struct cyclades_card *)dev_id) == 0){
1560 #ifdef CY_DEBUG_INTERRUPTS
1561 printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
1562 #endif
1563 return; /* spurious interrupt */
1566 firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1567 if (!ISZLOADED(*cinfo)) {
1568 #ifdef CY_DEBUG_INTERRUPTS
1569 printk("cyz_interrupt: board not yet loaded (INT %d).\n\r", irq);
1570 #endif
1571 return;
1574 zfw_ctrl = (struct ZFW_CTRL *)
1575 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1576 board_ctrl = &(zfw_ctrl->board_ctrl);
1577 fw_ver = cy_readl(&board_ctrl->fw_version);
1578 hw_ver = cy_readl(&((struct RUNTIME_9060 *)
1579 (cinfo->ctl_addr))->mail_box_0);
1581 while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
1582 special_count = 0;
1583 info = &cy_port[channel + cinfo->first_line];
1584 if((tty = info->tty) == 0) continue;
1585 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1586 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1588 switch(cmd){
1589 case C_CM_PR_ERROR:
1590 tty->flip.count++;
1591 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
1592 *tty->flip.char_buf_ptr++ = 0;
1593 special_count++;
1594 break;
1595 case C_CM_FR_ERROR:
1596 tty->flip.count++;
1597 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
1598 *tty->flip.char_buf_ptr++ = 0;
1599 special_count++;
1600 break;
1601 case C_CM_RXBRK:
1602 tty->flip.count++;
1603 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
1604 *tty->flip.char_buf_ptr++ = 0;
1605 special_count++;
1606 break;
1607 case C_CM_MDCD:
1608 if (info->flags & ASYNC_CHECK_CD){
1609 if ((fw_ver > 241 ?
1610 ((u_long)param) :
1611 cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
1612 /* SP("Open Wakeup\n"); */
1613 cy_sched_event(info,
1614 Cy_EVENT_OPEN_WAKEUP);
1615 }else if(!((info->flags
1616 & ASYNC_CALLOUT_ACTIVE)
1617 &&(info->flags
1618 & ASYNC_CALLOUT_NOHUP))){
1619 /* SP("Hangup\n"); */
1620 cy_sched_event(info,
1621 Cy_EVENT_HANGUP);
1624 break;
1625 case C_CM_MCTS:
1626 if (info->flags & ASYNC_CTS_FLOW) {
1627 if(info->tty->hw_stopped){
1628 if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
1629 /* cy_start isn't used because...
1630 HW flow is handled by the board */
1631 /* SP("Write Wakeup\n"); */
1632 cy_sched_event(info,
1633 Cy_EVENT_WRITE_WAKEUP);
1635 }else{
1636 if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
1637 /* cy_stop isn't used because
1638 HW flow is handled by the board */
1639 /* SP("Write stop\n"); */
1643 break;
1644 case C_CM_MRI:
1645 break;
1646 case C_CM_MDSR:
1647 break;
1648 #ifdef Z_WAKE
1649 case C_CM_IOCTLW:
1650 cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
1651 break;
1652 #endif
1653 case C_CM_RXHIWM:
1654 case C_CM_RXNNDT:
1655 /* Reception Interrupt */
1656 #ifdef CY_DEBUG_INTERRUPTS
1657 printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r",
1658 info->card, channel);
1659 #endif
1661 rx_get = cy_readl(&buf_ctrl->rx_get);
1662 rx_put = cy_readl(&buf_ctrl->rx_put);
1663 rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
1664 if (rx_put >= rx_get)
1665 char_count = rx_put - rx_get;
1666 else
1667 char_count = rx_put - rx_get + rx_bufsize;
1669 if ( char_count ){
1671 #ifdef CY_ENABLE_MONITORING
1672 info->mon.int_count++;
1673 info->mon.char_count += char_count;
1674 if (char_count > info->mon.char_max)
1675 info->mon.char_max = char_count;
1676 info->mon.char_last = char_count;
1677 #endif
1678 info->idle_stats.recv_bytes += char_count;
1679 info->idle_stats.recv_idle = jiffies;
1680 if( tty == 0){
1681 /* flush received characters */
1682 rx_get = (rx_get + char_count) & (rx_bufsize - 1);
1683 /* SP("-"); */
1684 info->rflush_count++;
1685 }else{
1686 #ifdef BLOCKMOVE
1687 /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
1688 for performance, but because of buffer boundaries, there
1689 may be several steps to the operation */
1690 while(0 < (small_count
1691 = cy_min((rx_bufsize - rx_get),
1692 cy_min((TTY_FLIPBUF_SIZE - tty->flip.count),
1693 char_count)))){
1695 memcpy_fromio(tty->flip.char_buf_ptr,
1696 (char *)(cinfo->base_addr
1697 + cy_readl(&buf_ctrl->rx_bufaddr)
1698 + rx_get),
1699 small_count);
1701 tty->flip.char_buf_ptr += small_count;
1702 memset(tty->flip.flag_buf_ptr,
1703 TTY_NORMAL,
1704 small_count);
1705 tty->flip.flag_buf_ptr += small_count;
1706 rx_get = (rx_get + small_count) & (rx_bufsize - 1);
1707 char_count -= small_count;
1708 tty->flip.count += small_count;
1710 #else
1711 while(char_count--){
1712 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1713 break;
1715 data = cy_readb(cinfo->base_addr +
1716 cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
1717 rx_get = (rx_get + 1) & (rx_bufsize - 1);
1718 tty->flip.count++;
1719 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1720 *tty->flip.char_buf_ptr++ = data;
1722 #endif
1723 queue_task(&tty->flip.tqueue, &tq_timer);
1725 /* Update rx_get */
1726 cy_writel(&buf_ctrl->rx_get, rx_get);
1728 break;
1729 case C_CM_TXBEMPTY:
1730 case C_CM_TXLOWWM:
1731 case C_CM_INTBACK:
1732 /* Transmission Interrupt */
1733 #ifdef CY_DEBUG_INTERRUPTS
1734 printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r",
1735 info->card, channel);
1736 #endif
1738 tx_get = cy_readl(&buf_ctrl->tx_get);
1739 tx_put = cy_readl(&buf_ctrl->tx_put);
1740 tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
1741 if (tx_put >= tx_get)
1742 char_count = tx_get - tx_put - 1 + tx_bufsize;
1743 else
1744 char_count = tx_get - tx_put - 1;
1746 if ( char_count ){
1748 if( tty == 0 ){
1749 goto ztxdone;
1752 if(info->x_char) { /* send special char */
1753 data = info->x_char;
1755 cy_writeb((cinfo->base_addr +
1756 cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
1757 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1758 info->x_char = 0;
1759 char_count--;
1761 #ifdef BLOCKMOVE
1762 while(0 < (small_count
1763 = cy_min((tx_bufsize - tx_put),
1764 cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
1765 cy_min(info->xmit_cnt, char_count))))){
1767 memcpy_toio((char *)(cinfo->base_addr
1768 + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
1769 &info->xmit_buf[info->xmit_tail],
1770 small_count);
1772 tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1773 char_count -= small_count;
1774 info->xmit_cnt -= small_count;
1775 info->xmit_tail =
1776 (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
1778 #else
1779 while (info->xmit_cnt && char_count){
1780 data = info->xmit_buf[info->xmit_tail];
1781 info->xmit_cnt--;
1782 info->xmit_tail =
1783 (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
1785 cy_writeb(cinfo->base_addr +
1786 cy_readl(&buf_ctrl->tx_bufaddr) + tx_put,
1787 data);
1788 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1789 char_count--;
1792 #endif
1793 ztxdone:
1794 if (info->xmit_cnt < WAKEUP_CHARS) {
1795 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1797 /* Update tx_put */
1798 cy_writel(&buf_ctrl->tx_put, tx_put);
1800 break;
1801 case C_CM_FATAL:
1802 /* should do something with this !!! */
1803 break;
1805 if(special_count){
1806 queue_task(&tty->flip.tqueue, &tq_timer);
1810 return;
1811 } /* cyz_interrupt */
1813 #else /* CONFIG_CYZ_INTR */
1815 static void
1816 cyz_poll(unsigned long arg)
1818 static volatile struct FIRM_ID *firm_id;
1819 static volatile struct ZFW_CTRL *zfw_ctrl;
1820 static volatile struct BOARD_CTRL *board_ctrl;
1821 static volatile struct CH_CTRL *ch_ctrl;
1822 static volatile struct BUF_CTRL *buf_ctrl;
1823 struct cyclades_card *cinfo;
1824 struct cyclades_port *info;
1825 struct tty_struct *tty;
1826 int card, port;
1827 int char_count;
1828 #ifdef BLOCKMOVE
1829 int small_count;
1830 #endif
1831 char data;
1832 uclong channel;
1833 ucchar cmd;
1834 uclong param;
1835 uclong hw_ver, fw_ver;
1836 volatile uclong tx_put, tx_get, tx_bufsize;
1837 volatile uclong rx_put, rx_get, rx_bufsize;
1839 cyz_timerlist.expires = jiffies + (HZ);
1840 for (card = 0 ; card < NR_CARDS ; card++){
1841 cinfo = &cy_card[card];
1842 if (!IS_CYC_Z(*cinfo)) continue;
1845 firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1846 if (!ISZLOADED(*cinfo)) {
1847 continue;
1850 zfw_ctrl = (struct ZFW_CTRL *)
1851 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1852 board_ctrl = &(zfw_ctrl->board_ctrl);
1853 fw_ver = cy_readl(&board_ctrl->fw_version);
1854 hw_ver = cy_readl(&((struct RUNTIME_9060 *)
1855 (cinfo->ctl_addr))->mail_box_0);
1857 while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1){
1858 char_count = 0;
1859 info = &cy_port[ channel + cinfo->first_line ];
1860 if((tty = info->tty) == 0) continue;
1861 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1862 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1863 info->jiffies[0] = jiffies;
1865 switch(cmd){
1866 case C_CM_PR_ERROR:
1867 tty->flip.count++;
1868 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
1869 *tty->flip.char_buf_ptr++ = 0;
1870 char_count++;
1871 break;
1872 case C_CM_FR_ERROR:
1873 tty->flip.count++;
1874 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
1875 *tty->flip.char_buf_ptr++ = 0;
1876 char_count++;
1877 break;
1878 case C_CM_RXBRK:
1879 tty->flip.count++;
1880 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
1881 *tty->flip.char_buf_ptr++ = 0;
1882 char_count++;
1883 break;
1884 case C_CM_MDCD:
1885 if (info->flags & ASYNC_CHECK_CD){
1886 if ((fw_ver > 241 ?
1887 ((u_long)param) :
1888 cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
1889 cy_sched_event(info,
1890 Cy_EVENT_OPEN_WAKEUP);
1891 }else if(!((info->flags
1892 & ASYNC_CALLOUT_ACTIVE)
1893 &&(info->flags
1894 & ASYNC_CALLOUT_NOHUP))){
1895 cy_sched_event(info,
1896 Cy_EVENT_HANGUP);
1899 break;
1900 case C_CM_MCTS:
1901 if (info->flags & ASYNC_CTS_FLOW) {
1902 if(info->tty->hw_stopped){
1903 if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
1904 /* cy_start isn't used because...
1905 HW flow is handled by the board */
1906 cy_sched_event(info,
1907 Cy_EVENT_WRITE_WAKEUP);
1909 }else{
1910 if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
1911 /* cy_stop isn't used because
1912 HW flow is handled by the board */
1916 break;
1917 case C_CM_MRI:
1918 break;
1919 case C_CM_MDSR:
1920 break;
1921 #ifdef Z_WAKE
1922 case C_CM_IOCTLW:
1923 cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
1924 break;
1925 #endif
1926 case C_CM_FATAL:
1927 /* should do something with this !!! */
1928 break;
1930 if(char_count){
1931 queue_task(&tty->flip.tqueue, &tq_timer);
1934 for (port = 0; port < cy_readl(&board_ctrl->n_channel); port++){
1935 info = &cy_port[ port + cinfo->first_line ];
1936 tty = info->tty;
1937 ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
1938 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
1940 /* Removed due to compilation problems in Alpha systems */
1941 // if ((char_count = CHARS_IN_BUF(buf_ctrl))){
1943 rx_get = cy_readl(&buf_ctrl->rx_get);
1944 rx_put = cy_readl(&buf_ctrl->rx_put);
1945 rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
1946 if (rx_put >= rx_get)
1947 char_count = rx_put - rx_get;
1948 else
1949 char_count = rx_put - rx_get + rx_bufsize;
1951 if ( char_count ){
1953 info->last_active = jiffies;
1954 info->jiffies[1] = jiffies;
1956 #ifdef CY_ENABLE_MONITORING
1957 info->mon.int_count++;
1958 info->mon.char_count += char_count;
1959 if (char_count > info->mon.char_max)
1960 info->mon.char_max = char_count;
1961 info->mon.char_last = char_count;
1962 #endif
1963 info->idle_stats.recv_bytes += char_count;
1964 info->idle_stats.recv_idle = jiffies;
1965 if( tty == 0){
1966 /* flush received characters */
1967 rx_get = (rx_get + char_count) & (rx_bufsize - 1);
1968 info->rflush_count++;
1969 }else{
1970 #ifdef BLOCKMOVE
1971 /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
1972 for performance, but because of buffer boundaries, there
1973 may be several steps to the operation */
1974 while(0 < (small_count
1975 = cy_min((rx_bufsize - rx_get),
1976 cy_min((TTY_FLIPBUF_SIZE - tty->flip.count),
1977 char_count)))){
1979 memcpy_fromio(tty->flip.char_buf_ptr,
1980 (char *)(cinfo->base_addr
1981 + cy_readl(&buf_ctrl->rx_bufaddr)
1982 + rx_get),
1983 small_count);
1985 tty->flip.char_buf_ptr += small_count;
1986 memset(tty->flip.flag_buf_ptr,
1987 TTY_NORMAL,
1988 small_count);
1989 tty->flip.flag_buf_ptr += small_count;
1990 rx_get = (rx_get + small_count) & (rx_bufsize - 1);
1991 char_count -= small_count;
1992 tty->flip.count += small_count;
1994 #else
1995 while(char_count--){
1996 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1997 break;
1999 data = cy_readb(cinfo->base_addr +
2000 cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
2001 rx_get = (rx_get + 1) & (rx_bufsize - 1);
2002 tty->flip.count++;
2003 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
2004 *tty->flip.char_buf_ptr++ = data;
2006 #endif
2007 queue_task(&tty->flip.tqueue, &tq_timer);
2009 /* Update rx_get */
2010 cy_writel(&buf_ctrl->rx_get, rx_get);
2013 /* Removed due to compilation problems in Alpha systems */
2014 // if ((char_count = SPACE_IN_BUF(buf_ctrl))){
2016 tx_get = cy_readl(&buf_ctrl->tx_get);
2017 tx_put = cy_readl(&buf_ctrl->tx_put);
2018 tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
2019 if (tx_put >= tx_get)
2020 char_count = tx_get - tx_put - 1 + tx_bufsize;
2021 else
2022 char_count = tx_get - tx_put - 1;
2024 if ( char_count ){
2026 if( tty == 0 ){
2027 goto ztxdone;
2030 if(info->x_char) { /* send special char */
2031 data = info->x_char;
2033 cy_writeb((cinfo->base_addr +
2034 cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
2035 tx_put = (tx_put + 1) & (tx_bufsize - 1);
2036 info->x_char = 0;
2037 char_count--;
2038 info->last_active = jiffies;
2039 info->jiffies[2] = jiffies;
2041 #ifdef BLOCKMOVE
2042 while(0 < (small_count
2043 = cy_min((tx_bufsize - tx_put),
2044 cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
2045 cy_min(info->xmit_cnt, char_count))))){
2047 memcpy_toio((char *)(cinfo->base_addr
2048 + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
2049 &info->xmit_buf[info->xmit_tail],
2050 small_count);
2052 tx_put = (tx_put + small_count) & (tx_bufsize - 1);
2053 char_count -= small_count;
2054 info->xmit_cnt -= small_count;
2055 info->xmit_tail =
2056 (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
2057 info->last_active = jiffies;
2058 info->jiffies[2] = jiffies;
2060 #else
2061 while (info->xmit_cnt && char_count){
2062 data = info->xmit_buf[info->xmit_tail];
2063 info->xmit_cnt--;
2064 info->xmit_tail =
2065 (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
2067 cy_writeb(cinfo->base_addr +
2068 cy_readl(&buf_ctrl->tx_bufaddr) + tx_put,
2069 data);
2070 tx_put = (tx_put + 1) & (tx_bufsize - 1);
2071 char_count--;
2072 info->last_active = jiffies;
2073 info->jiffies[2] = jiffies;
2076 #endif
2077 ztxdone:
2078 if (info->xmit_cnt < WAKEUP_CHARS) {
2079 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
2081 /* Update tx_put */
2082 cy_writel(&buf_ctrl->tx_put, tx_put);
2085 /* poll every 40 ms */
2086 cyz_timerlist.expires = jiffies + cyz_polling_cycle;
2088 add_timer(&cyz_timerlist);
2090 return;
2091 } /* cyz_poll */
2093 #endif /* CONFIG_CYZ_INTR */
2095 /********** End of block of Cyclades-Z specific code *********/
2096 /***********************************************************/
2099 /* This is called whenever a port becomes active;
2100 interrupts are enabled and DTR & RTS are turned on.
2102 static int
2103 startup(struct cyclades_port * info)
2105 unsigned long flags;
2106 int retval = 0;
2107 unsigned char *base_addr;
2108 int card,chip,channel,index;
2109 unsigned long page;
2111 card = info->card;
2112 channel = (info->line) - (cy_card[card].first_line);
2114 page = get_free_page(GFP_KERNEL);
2115 if (!page)
2116 return -ENOMEM;
2118 CY_LOCK(info, flags);
2120 if (info->flags & ASYNC_INITIALIZED){
2121 free_page(page);
2122 goto errout;
2125 if (!info->type){
2126 if (info->tty){
2127 set_bit(TTY_IO_ERROR, &info->tty->flags);
2129 free_page(page);
2130 goto errout;
2133 if (info->xmit_buf)
2134 free_page(page);
2135 else
2136 info->xmit_buf = (unsigned char *) page;
2138 CY_UNLOCK(info, flags);
2140 set_line_char(info);
2142 if (!IS_CYC_Z(cy_card[card])) {
2143 chip = channel>>2;
2144 channel &= 0x03;
2145 index = cy_card[card].bus_index;
2146 base_addr = (unsigned char*)
2147 (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
2149 #ifdef CY_DEBUG_OPEN
2150 printk("cyc startup card %d, chip %d, channel %d, base_addr %lx\n",
2151 card, chip, channel, (long)base_addr);/**/
2152 #endif
2154 CY_LOCK(info, flags);
2156 cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2158 cy_writeb((ulong)base_addr+(CyRTPR<<index), (info->default_timeout
2159 ? info->default_timeout : 0x02)); /* 10ms rx timeout */
2161 cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index);
2163 cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2164 cy_writeb((ulong)base_addr+(CyMSVR1<<index), CyRTS);
2165 cy_writeb((ulong)base_addr+(CyMSVR2<<index), CyDTR);
2167 #ifdef CY_DEBUG_DTR
2168 printk("cyc:startup raising DTR\n");
2169 printk(" status: 0x%x, 0x%x\n",
2170 cy_readb(base_addr+(CyMSVR1<<index)),
2171 cy_readb(base_addr+(CyMSVR2<<index)));
2172 #endif
2174 cy_writeb((u_long)base_addr+(CySRER<<index),
2175 cy_readb(base_addr+(CySRER<<index)) | CyRxData);
2176 info->flags |= ASYNC_INITIALIZED;
2178 if (info->tty){
2179 clear_bit(TTY_IO_ERROR, &info->tty->flags);
2181 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2182 info->breakon = info->breakoff = 0;
2183 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2184 info->idle_stats.in_use =
2185 info->idle_stats.recv_idle =
2186 info->idle_stats.xmit_idle = jiffies;
2188 CY_UNLOCK(info, flags);
2190 } else {
2191 struct FIRM_ID *firm_id;
2192 struct ZFW_CTRL *zfw_ctrl;
2193 struct BOARD_CTRL *board_ctrl;
2194 struct CH_CTRL *ch_ctrl;
2195 int retval;
2197 base_addr = (unsigned char*) (cy_card[card].base_addr);
2199 firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2200 if (!ISZLOADED(cy_card[card])){
2201 return -ENODEV;
2204 zfw_ctrl =
2205 (struct ZFW_CTRL *)
2206 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
2207 board_ctrl = &zfw_ctrl->board_ctrl;
2208 ch_ctrl = zfw_ctrl->ch_ctrl;
2210 #ifdef CY_DEBUG_OPEN
2211 printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
2212 card, channel, (long)base_addr);/**/
2213 #endif
2215 CY_LOCK(info, flags);
2217 cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
2218 #ifdef Z_WAKE
2219 #ifdef CONFIG_CYZ_INTR
2220 cy_writel(&ch_ctrl[channel].intr_enable,
2221 C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
2222 C_IN_IOCTLW|
2223 C_IN_MDCD|C_IN_MCTS);
2224 #else
2225 cy_writel(&ch_ctrl[channel].intr_enable,
2226 C_IN_IOCTLW|
2227 C_IN_MDCD|C_IN_MCTS);
2228 #endif /* CONFIG_CYZ_INTR */
2229 #else
2230 #ifdef CONFIG_CYZ_INTR
2231 cy_writel(&ch_ctrl[channel].intr_enable,
2232 C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
2233 C_IN_MDCD|C_IN_MCTS);
2234 #else
2235 cy_writel(&ch_ctrl[channel].intr_enable,
2236 C_IN_MDCD|C_IN_MCTS);
2237 #endif /* CONFIG_CYZ_INTR */
2238 #endif /* Z_WAKE */
2240 retval = cyz_issue_cmd( &cy_card[card],
2241 channel, C_CM_IOCTL, 0L); /* was C_CM_RESET */
2242 if (retval != 0){
2243 printk("cyc:startup(1) retval was %x\n", retval);
2246 /* set timeout !!! */
2247 /* set RTS and DTR !!! */
2248 cy_writel(&ch_ctrl[channel].rs_control,
2249 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR) ;
2250 retval = cyz_issue_cmd(&cy_card[info->card],
2251 channel, C_CM_IOCTLM, 0L);
2252 if (retval != 0){
2253 printk("cyc:startup(2) retval was %x\n", retval);
2255 #ifdef CY_DEBUG_DTR
2256 printk("cyc:startup raising Z DTR\n");
2257 #endif
2259 /* enable send, recv, modem !!! */
2261 info->flags |= ASYNC_INITIALIZED;
2262 if (info->tty){
2263 clear_bit(TTY_IO_ERROR, &info->tty->flags);
2265 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2266 info->breakon = info->breakoff = 0;
2267 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2268 info->idle_stats.in_use =
2269 info->idle_stats.recv_idle =
2270 info->idle_stats.xmit_idle = jiffies;
2272 CY_UNLOCK(info, flags);
2275 #ifdef CY_DEBUG_OPEN
2276 printk(" cyc startup done\n");
2277 #endif
2278 return 0;
2280 errout:
2281 CY_UNLOCK(info, flags);
2282 return retval;
2283 } /* startup */
2286 static void
2287 start_xmit( struct cyclades_port *info )
2289 unsigned long flags;
2290 unsigned char *base_addr;
2291 int card,chip,channel,index;
2293 card = info->card;
2294 channel = (info->line) - (cy_card[card].first_line);
2295 if (!IS_CYC_Z(cy_card[card])) {
2296 chip = channel>>2;
2297 channel &= 0x03;
2298 index = cy_card[card].bus_index;
2299 base_addr = (unsigned char*)
2300 (cy_card[card].base_addr
2301 + (cy_chip_offset[chip]<<index));
2303 CY_LOCK(info, flags);
2304 cy_writeb((u_long)base_addr+(CyCAR<<index), channel);
2305 cy_writeb((u_long)base_addr+(CySRER<<index),
2306 cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
2307 CY_UNLOCK(info, flags);
2308 } else {
2309 #ifdef CONFIG_CYZ_INTR
2310 int retval;
2312 CY_LOCK(info, flags);
2313 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 0L);
2314 if (retval != 0){
2315 printk("cyc:start_xmit retval was %x\n", retval);
2317 CY_UNLOCK(info, flags);
2318 #else /* CONFIG_CYZ_INTR */
2319 /* Don't have to do anything at this time */
2320 #endif /* CONFIG_CYZ_INTR */
2322 } /* start_xmit */
2325 * This routine shuts down a serial port; interrupts are disabled,
2326 * and DTR is dropped if the hangup on close termio flag is on.
2328 static void
2329 shutdown(struct cyclades_port * info)
2331 unsigned long flags;
2332 unsigned char *base_addr;
2333 int card,chip,channel,index;
2335 if (!(info->flags & ASYNC_INITIALIZED)){
2336 return;
2339 card = info->card;
2340 channel = info->line - cy_card[card].first_line;
2341 if (!IS_CYC_Z(cy_card[card])) {
2342 chip = channel>>2;
2343 channel &= 0x03;
2344 index = cy_card[card].bus_index;
2345 base_addr = (unsigned char*)
2346 (cy_card[card].base_addr
2347 + (cy_chip_offset[chip]<<index));
2349 #ifdef CY_DEBUG_OPEN
2350 printk("cyc shutdown Y card %d, chip %d, channel %d, base_addr %lx\n",
2351 card, chip, channel, (long)base_addr);
2352 #endif
2354 CY_LOCK(info, flags);
2356 if (info->xmit_buf){
2357 unsigned char * temp;
2358 temp = info->xmit_buf;
2359 info->xmit_buf = 0;
2360 free_page((unsigned long) temp);
2362 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2363 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2364 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
2365 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
2366 #ifdef CY_DEBUG_DTR
2367 printk("cyc shutdown dropping DTR\n");
2368 printk(" status: 0x%x, 0x%x\n",
2369 cy_readb(base_addr+(CyMSVR1<<index)),
2370 cy_readb(base_addr+(CyMSVR2<<index)));
2371 #endif
2373 cyy_issue_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR,index);
2374 /* it may be appropriate to clear _XMIT at
2375 some later date (after testing)!!! */
2377 if (info->tty){
2378 set_bit(TTY_IO_ERROR, &info->tty->flags);
2380 info->flags &= ~ASYNC_INITIALIZED;
2381 CY_UNLOCK(info, flags);
2382 } else {
2383 struct FIRM_ID *firm_id;
2384 struct ZFW_CTRL *zfw_ctrl;
2385 struct BOARD_CTRL *board_ctrl;
2386 struct CH_CTRL *ch_ctrl;
2387 int retval;
2389 base_addr = (unsigned char*) (cy_card[card].base_addr);
2390 #ifdef CY_DEBUG_OPEN
2391 printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
2392 card, channel, (long)base_addr);
2393 #endif
2395 firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2396 if (!ISZLOADED(cy_card[card])) {
2397 return;
2400 zfw_ctrl =
2401 (struct ZFW_CTRL *)
2402 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
2403 board_ctrl = &(zfw_ctrl->board_ctrl);
2404 ch_ctrl = zfw_ctrl->ch_ctrl;
2406 CY_LOCK(info, flags);
2408 if (info->xmit_buf){
2409 unsigned char * temp;
2410 temp = info->xmit_buf;
2411 info->xmit_buf = 0;
2412 free_page((unsigned long) temp);
2415 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2416 cy_writel((u_long)&ch_ctrl[channel].rs_control,
2417 (uclong)(cy_readl(&ch_ctrl[channel].rs_control) &
2418 ~(C_RS_RTS | C_RS_DTR)));
2419 retval = cyz_issue_cmd(&cy_card[info->card],
2420 channel, C_CM_IOCTLM, 0L);
2421 if (retval != 0){
2422 printk("cyc:shutdown retval (2) was %x\n", retval);
2424 #ifdef CY_DEBUG_DTR
2425 printk("cyc:shutdown dropping Z DTR\n");
2426 #endif
2429 if (info->tty){
2430 set_bit(TTY_IO_ERROR, &info->tty->flags);
2432 info->flags &= ~ASYNC_INITIALIZED;
2434 CY_UNLOCK(info, flags);
2437 #ifdef CY_DEBUG_OPEN
2438 printk(" cyc shutdown done\n");
2439 #endif
2440 return;
2441 } /* shutdown */
2445 * ------------------------------------------------------------
2446 * cy_open() and friends
2447 * ------------------------------------------------------------
2450 static int
2451 block_til_ready(struct tty_struct *tty, struct file * filp,
2452 struct cyclades_port *info)
2454 DECLARE_WAITQUEUE(wait, current);
2455 struct cyclades_card *cinfo;
2456 unsigned long flags;
2457 int chip, channel,index;
2458 int retval;
2459 char *base_addr;
2461 cinfo = &cy_card[info->card];
2462 channel = info->line - cinfo->first_line;
2465 * If the device is in the middle of being closed, then block
2466 * until it's done, and then try again.
2468 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2469 if (info->flags & ASYNC_CLOSING) {
2470 interruptible_sleep_on(&info->close_wait);
2472 return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2476 * If this is a callout device, then just make sure the normal
2477 * device isn't being used.
2479 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
2480 if (info->flags & ASYNC_NORMAL_ACTIVE){
2481 return -EBUSY;
2483 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2484 (info->flags & ASYNC_SESSION_LOCKOUT) &&
2485 (info->session != current->session)){
2486 return -EBUSY;
2488 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2489 (info->flags & ASYNC_PGRP_LOCKOUT) &&
2490 (info->pgrp != current->pgrp)){
2491 return -EBUSY;
2493 info->flags |= ASYNC_CALLOUT_ACTIVE;
2494 return 0;
2498 * If non-blocking mode is set, then make the check up front
2499 * and then exit.
2501 if ((filp->f_flags & O_NONBLOCK) ||
2502 (tty->flags & (1 << TTY_IO_ERROR))) {
2503 if (info->flags & ASYNC_CALLOUT_ACTIVE){
2504 return -EBUSY;
2506 info->flags |= ASYNC_NORMAL_ACTIVE;
2507 return 0;
2511 * Block waiting for the carrier detect and the line to become
2512 * free (i.e., not in use by the callout). While we are in
2513 * this loop, info->count is dropped by one, so that
2514 * cy_close() knows when to free things. We restore it upon
2515 * exit, either normal or abnormal.
2517 retval = 0;
2518 add_wait_queue(&info->open_wait, &wait);
2519 #ifdef CY_DEBUG_OPEN
2520 printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
2521 info->line, info->count);/**/
2522 #endif
2523 CY_LOCK(info, flags);
2524 if (!tty_hung_up_p(filp))
2525 info->count--;
2526 CY_UNLOCK(info, flags);
2527 #ifdef CY_DEBUG_COUNT
2528 printk("cyc block_til_ready: (%d): decrementing count to %d\n",
2529 current->pid, info->count);
2530 #endif
2531 info->blocked_open++;
2533 if (!IS_CYC_Z(*cinfo)) {
2534 chip = channel>>2;
2535 channel &= 0x03;
2536 index = cinfo->bus_index;
2537 base_addr = (char *)(cinfo->base_addr
2538 + (cy_chip_offset[chip]<<index));
2540 while (1) {
2541 CY_LOCK(info, flags);
2542 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
2543 (tty->termios->c_cflag & CBAUD)){
2544 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2545 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
2546 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
2547 #ifdef CY_DEBUG_DTR
2548 printk("cyc:block_til_ready raising DTR\n");
2549 printk(" status: 0x%x, 0x%x\n",
2550 cy_readb(base_addr+(CyMSVR1<<index)),
2551 cy_readb(base_addr+(CyMSVR2<<index)));
2552 #endif
2554 CY_UNLOCK(info, flags);
2556 set_current_state(TASK_INTERRUPTIBLE);
2557 if (tty_hung_up_p(filp)
2558 || !(info->flags & ASYNC_INITIALIZED) ){
2559 return ((info->flags & ASYNC_HUP_NOTIFY) ?
2560 -EAGAIN : -ERESTARTSYS);
2561 break;
2564 CY_LOCK(info, flags);
2565 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2566 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2567 && !(info->flags & ASYNC_CLOSING)
2568 && (C_CLOCAL(tty)
2569 || (cy_readb(base_addr+(CyMSVR1<<index)) & CyDCD))) {
2570 CY_UNLOCK(info, flags);
2571 break;
2573 CY_UNLOCK(info, flags);
2575 if (signal_pending(current)) {
2576 retval = -ERESTARTSYS;
2577 break;
2579 #ifdef CY_DEBUG_OPEN
2580 printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2581 info->line, info->count);/**/
2582 #endif
2583 schedule();
2585 } else {
2586 struct FIRM_ID *firm_id;
2587 struct ZFW_CTRL *zfw_ctrl;
2588 struct BOARD_CTRL *board_ctrl;
2589 struct CH_CTRL *ch_ctrl;
2590 int retval;
2592 base_addr = (char *)(cinfo->base_addr);
2593 firm_id = (struct FIRM_ID *)
2594 (base_addr + ID_ADDRESS);
2595 if (!ISZLOADED(*cinfo)){
2596 return -EINVAL;
2599 zfw_ctrl =
2600 (struct ZFW_CTRL *)
2601 (base_addr + cy_readl(&firm_id->zfwctrl_addr));
2602 board_ctrl = &zfw_ctrl->board_ctrl;
2603 ch_ctrl = zfw_ctrl->ch_ctrl;
2605 while (1) {
2606 cy_writel(&ch_ctrl[channel].rs_control,
2607 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR);
2608 retval = cyz_issue_cmd(&cy_card[info->card],
2609 channel, C_CM_IOCTLM, 0L);
2610 if (retval != 0){
2611 printk("cyc:block_til_ready retval was %x\n", retval);
2613 #ifdef CY_DEBUG_DTR
2614 printk("cyc:block_til_ready raising Z DTR\n");
2615 #endif
2617 set_current_state(TASK_INTERRUPTIBLE);
2618 if (tty_hung_up_p(filp)
2619 || !(info->flags & ASYNC_INITIALIZED) ){
2620 return ((info->flags & ASYNC_HUP_NOTIFY) ?
2621 -EAGAIN : -ERESTARTSYS);
2622 break;
2624 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2625 && !(info->flags & ASYNC_CLOSING)
2626 && (C_CLOCAL(tty)
2627 || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) {
2628 break;
2630 if (signal_pending(current)) {
2631 retval = -ERESTARTSYS;
2632 break;
2634 #ifdef CY_DEBUG_OPEN
2635 printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2636 info->line, info->count);/**/
2637 #endif
2638 schedule();
2641 current->state = TASK_RUNNING;
2642 remove_wait_queue(&info->open_wait, &wait);
2643 if (!tty_hung_up_p(filp)){
2644 info->count++;
2645 #ifdef CY_DEBUG_COUNT
2646 printk("cyc:block_til_ready (%d): incrementing count to %d\n",
2647 current->pid, info->count);
2648 #endif
2650 info->blocked_open--;
2651 #ifdef CY_DEBUG_OPEN
2652 printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
2653 info->line, info->count);/**/
2654 #endif
2655 if (retval)
2656 return retval;
2657 info->flags |= ASYNC_NORMAL_ACTIVE;
2658 return 0;
2659 } /* block_til_ready */
2663 * This routine is called whenever a serial port is opened. It
2664 * performs the serial-specific initialization for the tty structure.
2666 static int
2667 cy_open(struct tty_struct *tty, struct file * filp)
2669 struct cyclades_port *info;
2670 int retval, line;
2671 unsigned long page;
2673 MOD_INC_USE_COUNT;
2674 line = MINOR(tty->device) - tty->driver.minor_start;
2675 if ((line < 0) || (NR_PORTS <= line)){
2676 MOD_DEC_USE_COUNT;
2677 return -ENODEV;
2679 info = &cy_port[line];
2680 if (info->line < 0){
2681 MOD_DEC_USE_COUNT;
2682 return -ENODEV;
2685 /* If the card's firmware hasn't been loaded,
2686 treat it as absent from the system. This
2687 will make the user pay attention.
2689 if (IS_CYC_Z(cy_card[info->card])) {
2690 if (!ISZLOADED(cy_card[info->card])) {
2691 if (((ZE_V1 ==cy_readl(&((struct RUNTIME_9060 *)
2692 ((cy_card[info->card]).ctl_addr))->mail_box_0)) &&
2693 Z_FPGA_CHECK(cy_card[info->card])) &&
2694 (ZFIRM_HLT==cy_readl(&((struct FIRM_ID *)
2695 ((cy_card[info->card]).base_addr+ID_ADDRESS))->signature)))
2697 printk ("cyc:Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
2698 } else {
2699 printk("cyc:Cyclades-Z firmware not yet loaded\n");
2701 MOD_DEC_USE_COUNT;
2702 return -ENODEV;
2704 #ifdef CONFIG_CYZ_INTR
2705 else {
2706 /* In case this Z board is operating in interrupt mode, its
2707 interrupts should be enabled as soon as the first open happens
2708 to one of its ports. */
2709 if (!cy_card[info->card].intr_enabled) {
2710 retval = cyz_issue_cmd(&cy_card[info->card],
2711 0, C_CM_IRQ_ENBL, 0L);
2712 if (retval != 0){
2713 printk("cyc:IRQ enable retval was %x\n", retval);
2715 cy_card[info->card].intr_enabled = 1;
2718 #endif /* CONFIG_CYZ_INTR */
2720 #ifdef CY_DEBUG_OTHER
2721 printk("cyc:cy_open ttyC%d\n", info->line); /* */
2722 #endif
2723 tty->driver_data = info;
2724 info->tty = tty;
2725 if (serial_paranoia_check(info, tty->device, "cy_open")){
2726 return -ENODEV;
2728 #ifdef CY_DEBUG_OPEN
2729 printk("cyc:cy_open ttyC%d, count = %d\n",
2730 info->line, info->count);/**/
2731 #endif
2732 info->count++;
2733 #ifdef CY_DEBUG_COUNT
2734 printk("cyc:cy_open (%d): incrementing count to %d\n",
2735 current->pid, info->count);
2736 #endif
2737 if (!tmp_buf) {
2738 page = get_free_page(GFP_KERNEL);
2739 if (!page)
2740 return -ENOMEM;
2741 if (tmp_buf)
2742 free_page(page);
2743 else
2744 tmp_buf = (unsigned char *) page;
2748 * If the port is the middle of closing, bail out now
2750 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2751 if (info->flags & ASYNC_CLOSING)
2752 interruptible_sleep_on(&info->close_wait);
2753 return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2757 * Start up serial port
2759 retval = startup(info);
2760 if (retval){
2761 return retval;
2764 retval = block_til_ready(tty, filp, info);
2765 if (retval) {
2766 #ifdef CY_DEBUG_OPEN
2767 printk("cyc:cy_open returning after block_til_ready with %d\n",
2768 retval);
2769 #endif
2770 return retval;
2773 if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
2774 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
2775 *tty->termios = info->normal_termios;
2776 else
2777 *tty->termios = info->callout_termios;
2780 info->session = current->session;
2781 info->pgrp = current->pgrp;
2783 #ifdef CY_DEBUG_OPEN
2784 printk(" cyc:cy_open done\n");/**/
2785 #endif
2787 return 0;
2788 } /* cy_open */
2792 * cy_wait_until_sent() --- wait until the transmitter is empty
2794 static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2796 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2797 unsigned char *base_addr;
2798 int card,chip,channel,index;
2799 unsigned long orig_jiffies, char_time;
2801 if (serial_paranoia_check(info, tty->device, "cy_wait_until_sent"))
2802 return;
2804 if (info->xmit_fifo_size == 0)
2805 return; /* Just in case.... */
2808 orig_jiffies = jiffies;
2810 * Set the check interval to be 1/5 of the estimated time to
2811 * send a single character, and make it at least 1. The check
2812 * interval should also be less than the timeout.
2814 * Note: we have to use pretty tight timings here to satisfy
2815 * the NIST-PCTS.
2817 char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
2818 char_time = char_time / 5;
2819 if (char_time == 0)
2820 char_time = 1;
2821 if (timeout < 0)
2822 timeout = 0;
2823 if (timeout)
2824 char_time = MIN(char_time, timeout);
2826 * If the transmitter hasn't cleared in twice the approximate
2827 * amount of time to send the entire FIFO, it probably won't
2828 * ever clear. This assumes the UART isn't doing flow
2829 * control, which is currently the case. Hence, if it ever
2830 * takes longer than info->timeout, this is probably due to a
2831 * UART bug of some kind. So, we clamp the timeout parameter at
2832 * 2*info->timeout.
2834 if (!timeout || timeout > 2*info->timeout)
2835 timeout = 2*info->timeout;
2836 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2837 printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
2838 printk("jiff=%lu...", jiffies);
2839 #endif
2840 card = info->card;
2841 channel = (info->line) - (cy_card[card].first_line);
2842 if (!IS_CYC_Z(cy_card[card])) {
2843 chip = channel>>2;
2844 channel &= 0x03;
2845 index = cy_card[card].bus_index;
2846 base_addr = (unsigned char *)
2847 (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
2848 while (cy_readb(base_addr+(CySRER<<index)) & CyTxMpty) {
2849 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2850 printk("Not clean (jiff=%lu)...", jiffies);
2851 #endif
2852 current->state = TASK_INTERRUPTIBLE;
2853 schedule_timeout(char_time);
2854 if (signal_pending(current))
2855 break;
2856 if (timeout && time_after(jiffies, orig_jiffies + timeout))
2857 break;
2859 current->state = TASK_RUNNING;
2860 } else {
2861 // Nothing to do!
2863 /* Run one more char cycle */
2864 current->state = TASK_INTERRUPTIBLE;
2865 schedule_timeout(char_time * 5);
2866 current->state = TASK_RUNNING;
2867 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2868 printk("Clean (jiff=%lu)...done\n", jiffies);
2869 #endif
2873 * This routine is called when a particular tty device is closed.
2875 static void
2876 cy_close(struct tty_struct * tty, struct file * filp)
2878 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2879 unsigned long flags;
2881 #ifdef CY_DEBUG_OTHER
2882 printk("cyc:cy_close ttyC%d\n", info->line);
2883 #endif
2885 if (!info || serial_paranoia_check(info, tty->device, "cy_close")){
2886 return;
2889 CY_LOCK(info, flags);
2890 /* If the TTY is being hung up, nothing to do */
2891 if (tty_hung_up_p(filp)) {
2892 MOD_DEC_USE_COUNT;
2893 CY_UNLOCK(info, flags);
2894 return;
2897 #ifdef CY_DEBUG_OPEN
2898 printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
2899 #endif
2900 if ((tty->count == 1) && (info->count != 1)) {
2902 * Uh, oh. tty->count is 1, which means that the tty
2903 * structure will be freed. Info->count should always
2904 * be one in these conditions. If it's greater than
2905 * one, we've got real problems, since it means the
2906 * serial port won't be shutdown.
2908 printk("cyc:cy_close: bad serial port count; tty->count is 1, "
2909 "info->count is %d\n", info->count);
2910 info->count = 1;
2912 #ifdef CY_DEBUG_COUNT
2913 printk("cyc:cy_close at (%d): decrementing count to %d\n",
2914 current->pid, info->count - 1);
2915 #endif
2916 if (--info->count < 0) {
2917 #ifdef CY_DEBUG_COUNT
2918 printk("cyc:cyc_close setting count to 0\n");
2919 #endif
2920 info->count = 0;
2922 if (info->count) {
2923 MOD_DEC_USE_COUNT;
2924 CY_UNLOCK(info, flags);
2925 return;
2927 info->flags |= ASYNC_CLOSING;
2929 * Save the termios structure, since this port may have
2930 * separate termios for callout and dialin.
2932 if (info->flags & ASYNC_NORMAL_ACTIVE)
2933 info->normal_termios = *tty->termios;
2934 if (info->flags & ASYNC_CALLOUT_ACTIVE)
2935 info->callout_termios = *tty->termios;
2938 * Now we wait for the transmit buffer to clear; and we notify
2939 * the line discipline to only process XON/XOFF characters.
2941 tty->closing = 1;
2942 CY_UNLOCK(info, flags);
2943 if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
2944 tty_wait_until_sent(tty, info->closing_wait);
2946 CY_LOCK(info, flags);
2948 if (!IS_CYC_Z(cy_card[info->card])) {
2949 int channel = info->line - cy_card[info->card].first_line;
2950 int index = cy_card[info->card].bus_index;
2951 unsigned char *base_addr = (unsigned char *)
2952 (cy_card[info->card].base_addr +
2953 (cy_chip_offset[channel>>2] <<index));
2954 /* Stop accepting input */
2955 channel &= 0x03;
2956 cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2957 cy_writeb((u_long)base_addr+(CySRER<<index),
2958 cy_readb(base_addr+(CySRER<<index)) & ~CyRxData);
2959 if (info->flags & ASYNC_INITIALIZED) {
2960 /* Waiting for on-board buffers to be empty before closing
2961 the port */
2962 CY_UNLOCK(info, flags);
2963 cy_wait_until_sent(tty, info->timeout);
2964 CY_LOCK(info, flags);
2966 } else {
2967 #ifdef Z_WAKE
2968 /* Waiting for on-board buffers to be empty before closing the port */
2969 unsigned char *base_addr = (unsigned char *)
2970 cy_card[info->card].base_addr;
2971 struct FIRM_ID *firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2972 struct ZFW_CTRL *zfw_ctrl =
2973 (struct ZFW_CTRL *) (base_addr + cy_readl(&firm_id->zfwctrl_addr));
2974 struct CH_CTRL *ch_ctrl = zfw_ctrl->ch_ctrl;
2975 int channel = info->line - cy_card[info->card].first_line;
2976 int retval;
2978 if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
2979 retval = cyz_issue_cmd(&cy_card[info->card], channel,
2980 C_CM_IOCTLW, 0L);
2981 if (retval != 0){
2982 printk("cyc:shutdown retval (1) was %x\n", retval);
2984 CY_UNLOCK(info, flags);
2985 interruptible_sleep_on(&info->shutdown_wait);
2986 CY_LOCK(info, flags);
2988 #endif
2991 CY_UNLOCK(info, flags);
2992 shutdown(info);
2993 if (tty->driver.flush_buffer)
2994 tty->driver.flush_buffer(tty);
2995 if (tty->ldisc.flush_buffer)
2996 tty->ldisc.flush_buffer(tty);
2997 CY_LOCK(info, flags);
2999 tty->closing = 0;
3000 info->event = 0;
3001 info->tty = 0;
3002 if (info->blocked_open) {
3003 if (info->close_delay) {
3004 current->state = TASK_INTERRUPTIBLE;
3005 schedule_timeout(info->close_delay);
3007 wake_up_interruptible(&info->open_wait);
3009 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
3010 ASYNC_CLOSING);
3011 wake_up_interruptible(&info->close_wait);
3013 #ifdef CY_DEBUG_OTHER
3014 printk(" cyc:cy_close done\n");
3015 #endif
3017 MOD_DEC_USE_COUNT;
3018 CY_UNLOCK(info, flags);
3019 return;
3020 } /* cy_close */
3023 /* This routine gets called when tty_write has put something into
3024 * the write_queue. The characters may come from user space or
3025 * kernel space.
3027 * This routine will return the number of characters actually
3028 * accepted for writing.
3030 * If the port is not already transmitting stuff, start it off by
3031 * enabling interrupts. The interrupt service routine will then
3032 * ensure that the characters are sent.
3033 * If the port is already active, there is no need to kick it.
3036 static int
3037 cy_write(struct tty_struct * tty, int from_user,
3038 const unsigned char *buf, int count)
3040 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3041 unsigned long flags;
3042 int c, ret = 0;
3044 #ifdef CY_DEBUG_IO
3045 printk("cyc:cy_write ttyC%d\n", info->line); /* */
3046 #endif
3048 if (serial_paranoia_check(info, tty->device, "cy_write")){
3049 return 0;
3052 if (!tty || !info->xmit_buf || !tmp_buf){
3053 return 0;
3056 CY_LOCK(info, flags);
3057 if (from_user) {
3058 down(&tmp_buf_sem);
3059 while (1) {
3060 c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
3061 SERIAL_XMIT_SIZE - info->xmit_head));
3062 if (c <= 0)
3063 break;
3065 c -= copy_from_user(tmp_buf, buf, c);
3066 if (!c) {
3067 if (!ret) {
3068 ret = -EFAULT;
3070 break;
3072 c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
3073 SERIAL_XMIT_SIZE - info->xmit_head));
3074 memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
3075 info->xmit_head = ((info->xmit_head + c) & (SERIAL_XMIT_SIZE-1));
3076 info->xmit_cnt += c;
3077 buf += c;
3078 count -= c;
3079 ret += c;
3081 up(&tmp_buf_sem);
3082 } else {
3083 while (1) {
3084 c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
3085 SERIAL_XMIT_SIZE - info->xmit_head));
3086 if (c <= 0) {
3087 break;
3089 memcpy(info->xmit_buf + info->xmit_head, buf, c);
3090 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
3091 info->xmit_cnt += c;
3092 buf += c;
3093 count -= c;
3094 ret += c;
3097 CY_UNLOCK(info, flags);
3099 info->idle_stats.xmit_bytes += ret;
3100 info->idle_stats.xmit_idle = jiffies;
3102 if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
3103 start_xmit(info);
3105 return ret;
3106 } /* cy_write */
3110 * This routine is called by the kernel to write a single
3111 * character to the tty device. If the kernel uses this routine,
3112 * it must call the flush_chars() routine (if defined) when it is
3113 * done stuffing characters into the driver. If there is no room
3114 * in the queue, the character is ignored.
3116 static void
3117 cy_put_char(struct tty_struct *tty, unsigned char ch)
3119 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3120 unsigned long flags;
3122 #ifdef CY_DEBUG_IO
3123 printk("cyc:cy_put_char ttyC%d\n", info->line);
3124 #endif
3126 if (serial_paranoia_check(info, tty->device, "cy_put_char"))
3127 return;
3129 if (!tty || !info->xmit_buf)
3130 return;
3132 CY_LOCK(info, flags);
3133 if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
3134 CY_UNLOCK(info, flags);
3135 return;
3138 info->xmit_buf[info->xmit_head++] = ch;
3139 info->xmit_head &= SERIAL_XMIT_SIZE - 1;
3140 info->xmit_cnt++;
3141 info->idle_stats.xmit_bytes++;
3142 info->idle_stats.xmit_idle = jiffies;
3143 CY_UNLOCK(info, flags);
3144 } /* cy_put_char */
3148 * This routine is called by the kernel after it has written a
3149 * series of characters to the tty device using put_char().
3151 static void
3152 cy_flush_chars(struct tty_struct *tty)
3154 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3156 #ifdef CY_DEBUG_IO
3157 printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */
3158 #endif
3160 if (serial_paranoia_check(info, tty->device, "cy_flush_chars"))
3161 return;
3163 if (info->xmit_cnt <= 0 || tty->stopped
3164 || tty->hw_stopped || !info->xmit_buf)
3165 return;
3167 start_xmit(info);
3168 } /* cy_flush_chars */
3172 * This routine returns the numbers of characters the tty driver
3173 * will accept for queuing to be written. This number is subject
3174 * to change as output buffers get emptied, or if the output flow
3175 * control is activated.
3177 static int
3178 cy_write_room(struct tty_struct *tty)
3180 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3181 int ret;
3183 #ifdef CY_DEBUG_IO
3184 printk("cyc:cy_write_room ttyC%d\n", info->line); /* */
3185 #endif
3187 if (serial_paranoia_check(info, tty->device, "cy_write_room"))
3188 return 0;
3189 ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
3190 if (ret < 0)
3191 ret = 0;
3192 return ret;
3193 } /* cy_write_room */
3196 static int
3197 cy_chars_in_buffer(struct tty_struct *tty)
3199 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3200 int card, channel;
3202 if (serial_paranoia_check(info, tty->device, "cy_chars_in_buffer"))
3203 return 0;
3205 card = info->card;
3206 channel = (info->line) - (cy_card[card].first_line);
3208 if (!IS_CYC_Z(cy_card[card])) {
3209 #ifdef CY_DEBUG_IO
3210 printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
3211 info->line, info->xmit_cnt); /* */
3212 #endif
3213 return info->xmit_cnt;
3214 } else {
3215 static volatile struct FIRM_ID *firm_id;
3216 static volatile struct ZFW_CTRL *zfw_ctrl;
3217 static volatile struct CH_CTRL *ch_ctrl;
3218 static volatile struct BUF_CTRL *buf_ctrl;
3219 int char_count;
3220 volatile uclong tx_put, tx_get, tx_bufsize;
3222 firm_id = (struct FIRM_ID *)(cy_card[card].base_addr + ID_ADDRESS);
3223 zfw_ctrl = (struct ZFW_CTRL *) (cy_card[card].base_addr +
3224 cy_readl(&firm_id->zfwctrl_addr));
3225 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3226 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
3228 tx_get = cy_readl(&buf_ctrl->tx_get);
3229 tx_put = cy_readl(&buf_ctrl->tx_put);
3230 tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
3231 if (tx_put >= tx_get)
3232 char_count = tx_put - tx_get;
3233 else
3234 char_count = tx_put - tx_get + tx_bufsize;
3235 #ifdef CY_DEBUG_IO
3236 printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
3237 info->line, info->xmit_cnt + char_count); /* */
3238 #endif
3239 return (info->xmit_cnt + char_count);
3241 } /* cy_chars_in_buffer */
3245 * ------------------------------------------------------------
3246 * cy_ioctl() and friends
3247 * ------------------------------------------------------------
3252 * This routine finds or computes the various line characteristics.
3253 * It used to be called config_setup
3255 static void
3256 set_line_char(struct cyclades_port * info)
3258 unsigned long flags;
3259 unsigned char *base_addr;
3260 int card,chip,channel,index;
3261 unsigned cflag, iflag;
3262 unsigned short chip_number;
3263 int baud;
3264 int i;
3267 if (!info->tty || !info->tty->termios){
3268 return;
3270 if (info->line == -1){
3271 return;
3273 cflag = info->tty->termios->c_cflag;
3274 iflag = info->tty->termios->c_iflag;
3276 card = info->card;
3277 channel = (info->line) - (cy_card[card].first_line);
3278 chip_number = channel / 4;
3280 if (!IS_CYC_Z(cy_card[card])) {
3282 index = cy_card[card].bus_index;
3284 /* baud rate */
3285 baud = tty_get_baud_rate(info->tty);
3286 if (baud > CD1400_MAX_SPEED) {
3287 baud = CD1400_MAX_SPEED;
3289 /* find the baud index */
3290 for (i = 0; i < 20; i++) {
3291 if (baud == baud_table[i]) {
3292 break;
3295 if (i == 20) {
3296 i = 19; /* CD1400_MAX_SPEED */
3300 if(info->chip_rev >= CD1400_REV_J) {
3301 /* It is a CD1400 rev. J or later */
3302 info->tbpr = baud_bpr_60[i]; /* Tx BPR */
3303 info->tco = baud_co_60[i]; /* Tx CO */
3304 info->rbpr = baud_bpr_60[i]; /* Rx BPR */
3305 info->rco = baud_co_60[i]; /* Rx CO */
3306 } else {
3307 info->tbpr = baud_bpr_25[i]; /* Tx BPR */
3308 info->tco = baud_co_25[i]; /* Tx CO */
3309 info->rbpr = baud_bpr_25[i]; /* Rx BPR */
3310 info->rco = baud_co_25[i]; /* Rx CO */
3312 if (baud_table[i] == 134) {
3313 info->timeout = (info->xmit_fifo_size*HZ*15/269) + 2;
3314 /* get it right for 134.5 baud */
3315 } else if (baud_table[i]) {
3316 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
3317 /* this needs to be propagated into the card info */
3318 } else {
3319 info->timeout = 0;
3321 /* By tradition (is it a standard?) a baud rate of zero
3322 implies the line should be/has been closed. A bit
3323 later in this routine such a test is performed. */
3325 /* byte size and parity */
3326 info->cor5 = 0;
3327 info->cor4 = 0;
3328 info->cor3 = (info->default_threshold
3329 ? info->default_threshold
3330 : baud_cor3[i]); /* receive threshold */
3331 info->cor2 = CyETC;
3332 switch(cflag & CSIZE){
3333 case CS5:
3334 info->cor1 = Cy_5_BITS;
3335 break;
3336 case CS6:
3337 info->cor1 = Cy_6_BITS;
3338 break;
3339 case CS7:
3340 info->cor1 = Cy_7_BITS;
3341 break;
3342 case CS8:
3343 info->cor1 = Cy_8_BITS;
3344 break;
3346 if(cflag & CSTOPB){
3347 info->cor1 |= Cy_2_STOP;
3349 if (cflag & PARENB){
3350 if (cflag & PARODD){
3351 info->cor1 |= CyPARITY_O;
3352 }else{
3353 info->cor1 |= CyPARITY_E;
3355 }else{
3356 info->cor1 |= CyPARITY_NONE;
3359 /* CTS flow control flag */
3360 if (cflag & CRTSCTS){
3361 info->flags |= ASYNC_CTS_FLOW;
3362 info->cor2 |= CyCtsAE;
3363 }else{
3364 info->flags &= ~ASYNC_CTS_FLOW;
3365 info->cor2 &= ~CyCtsAE;
3367 if (cflag & CLOCAL)
3368 info->flags &= ~ASYNC_CHECK_CD;
3369 else
3370 info->flags |= ASYNC_CHECK_CD;
3372 /***********************************************
3373 The hardware option, CyRtsAO, presents RTS when
3374 the chip has characters to send. Since most modems
3375 use RTS as reverse (inbound) flow control, this
3376 option is not used. If inbound flow control is
3377 necessary, DTR can be programmed to provide the
3378 appropriate signals for use with a non-standard
3379 cable. Contact Marcio Saito for details.
3380 ***********************************************/
3382 chip = channel>>2;
3383 channel &= 0x03;
3384 base_addr = (unsigned char*)
3385 (cy_card[card].base_addr
3386 + (cy_chip_offset[chip]<<index));
3388 CY_LOCK(info, flags);
3389 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3391 /* tx and rx baud rate */
3393 cy_writeb((u_long)base_addr+(CyTCOR<<index), info->tco);
3394 cy_writeb((u_long)base_addr+(CyTBPR<<index), info->tbpr);
3395 cy_writeb((u_long)base_addr+(CyRCOR<<index), info->rco);
3396 cy_writeb((u_long)base_addr+(CyRBPR<<index), info->rbpr);
3398 /* set line characteristics according configuration */
3400 cy_writeb((u_long)base_addr+(CySCHR1<<index),
3401 START_CHAR(info->tty));
3402 cy_writeb((u_long)base_addr+(CySCHR2<<index),
3403 STOP_CHAR(info->tty));
3404 cy_writeb((u_long)base_addr+(CyCOR1<<index), info->cor1);
3405 cy_writeb((u_long)base_addr+(CyCOR2<<index), info->cor2);
3406 cy_writeb((u_long)base_addr+(CyCOR3<<index), info->cor3);
3407 cy_writeb((u_long)base_addr+(CyCOR4<<index), info->cor4);
3408 cy_writeb((u_long)base_addr+(CyCOR5<<index), info->cor5);
3410 cyy_issue_cmd(base_addr,
3411 CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch,index);
3413 cy_writeb((u_long)base_addr+(CyCAR<<index),
3414 (u_char)channel); /* !!! Is this needed? */
3415 cy_writeb((u_long)base_addr+(CyRTPR<<index), (info->default_timeout
3416 ? info->default_timeout
3417 : 0x02)); /* 10ms rx timeout */
3419 if (C_CLOCAL(info->tty)) {
3420 /* without modem intr */
3421 cy_writeb((u_long)base_addr+(CySRER<<index),
3422 cy_readb(base_addr+(CySRER<<index)) | CyMdmCh);
3423 /* act on 1->0 modem transitions */
3424 if ((cflag & CRTSCTS) && info->rflow) {
3425 cy_writeb((u_long)base_addr+(CyMCOR1<<index),
3426 (CyCTS|rflow_thr[i]));
3427 } else {
3428 cy_writeb((u_long)base_addr+(CyMCOR1<<index), CyCTS);
3430 /* act on 0->1 modem transitions */
3431 cy_writeb((u_long)base_addr+(CyMCOR2<<index), CyCTS);
3432 } else {
3433 /* without modem intr */
3434 cy_writeb((u_long)base_addr+(CySRER<<index),
3435 cy_readb(base_addr+(CySRER<<index)) | CyMdmCh);
3436 /* act on 1->0 modem transitions */
3437 if ((cflag & CRTSCTS) && info->rflow) {
3438 cy_writeb((u_long)base_addr+(CyMCOR1<<index),
3439 (CyDSR|CyCTS|CyRI|CyDCD|rflow_thr[i]));
3440 } else {
3441 cy_writeb((u_long)base_addr+(CyMCOR1<<index),
3442 CyDSR|CyCTS|CyRI|CyDCD);
3444 /* act on 0->1 modem transitions */
3445 cy_writeb((u_long)base_addr+(CyMCOR2<<index),
3446 CyDSR|CyCTS|CyRI|CyDCD);
3449 if(i == 0){ /* baud rate is zero, turn off line */
3450 if (info->rtsdtr_inv) {
3451 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3452 } else {
3453 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3455 #ifdef CY_DEBUG_DTR
3456 printk("cyc:set_line_char dropping DTR\n");
3457 printk(" status: 0x%x,
3458 0x%x\n", cy_readb(base_addr+(CyMSVR1<<index)),
3459 cy_readb(base_addr+(CyMSVR2<<index)));
3460 #endif
3461 }else{
3462 if (info->rtsdtr_inv) {
3463 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3464 } else {
3465 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3467 #ifdef CY_DEBUG_DTR
3468 printk("cyc:set_line_char raising DTR\n");
3469 printk(" status: 0x%x, 0x%x\n",
3470 cy_readb(base_addr+(CyMSVR1<<index)),
3471 cy_readb(base_addr+(CyMSVR2<<index)));
3472 #endif
3475 if (info->tty){
3476 clear_bit(TTY_IO_ERROR, &info->tty->flags);
3478 CY_UNLOCK(info, flags);
3480 } else {
3481 struct FIRM_ID *firm_id;
3482 struct ZFW_CTRL *zfw_ctrl;
3483 struct BOARD_CTRL *board_ctrl;
3484 struct CH_CTRL *ch_ctrl;
3485 struct BUF_CTRL *buf_ctrl;
3486 int retval;
3488 firm_id = (struct FIRM_ID *)
3489 (cy_card[card].base_addr + ID_ADDRESS);
3490 if (!ISZLOADED(cy_card[card])) {
3491 return;
3494 zfw_ctrl = (struct ZFW_CTRL *)
3495 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
3496 board_ctrl = &zfw_ctrl->board_ctrl;
3497 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3498 buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3500 /* baud rate */
3501 baud = tty_get_baud_rate(info->tty);
3502 if (baud > CYZ_MAX_SPEED) {
3503 baud = CYZ_MAX_SPEED;
3505 cy_writel(&ch_ctrl->comm_baud , baud);
3507 if (baud == 134) {
3508 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
3509 /* get it right for 134.5 baud */
3510 } else if (baud) {
3511 info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
3512 /* this needs to be propagated into the card info */
3513 } else {
3514 info->timeout = 0;
3517 /* byte size and parity */
3518 switch(cflag & CSIZE){
3519 case CS5: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS5); break;
3520 case CS6: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS6); break;
3521 case CS7: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS7); break;
3522 case CS8: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS8); break;
3524 if(cflag & CSTOPB){
3525 cy_writel(&ch_ctrl->comm_data_l,
3526 cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
3527 }else{
3528 cy_writel(&ch_ctrl->comm_data_l,
3529 cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
3531 if (cflag & PARENB){
3532 if (cflag & PARODD){
3533 cy_writel(&ch_ctrl->comm_parity , C_PR_ODD);
3534 }else{
3535 cy_writel(&ch_ctrl->comm_parity , C_PR_EVEN);
3537 }else{
3538 cy_writel(&ch_ctrl->comm_parity , C_PR_NONE);
3541 /* CTS flow control flag */
3542 if (cflag & CRTSCTS){
3543 info->flags |= ASYNC_CTS_FLOW;
3544 cy_writel(&ch_ctrl->hw_flow,
3545 cy_readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
3546 }else{
3547 info->flags &= ~ASYNC_CTS_FLOW;
3548 cy_writel(&ch_ctrl->hw_flow,
3549 cy_readl(&ch_ctrl->hw_flow) & ~(C_RS_CTS | C_RS_RTS));
3552 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
3553 if (retval != 0){
3554 printk("cyc:set_line_char retval at %d was %x\n",
3555 __LINE__, retval);
3558 /* CD sensitivity */
3559 if (cflag & CLOCAL){
3560 info->flags &= ~ASYNC_CHECK_CD;
3561 }else{
3562 info->flags |= ASYNC_CHECK_CD;
3565 if (iflag & IXON){
3566 cy_writel(&ch_ctrl->sw_flow,
3567 cy_readl(&ch_ctrl->sw_flow) | C_FL_OXX);
3568 } else {
3569 cy_writel(&ch_ctrl->sw_flow,
3570 cy_readl(&ch_ctrl->sw_flow) & ~C_FL_OXX);
3573 if(baud == 0){ /* baud rate is zero, turn off line */
3574 cy_writel(&ch_ctrl->rs_control,
3575 cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
3576 #ifdef CY_DEBUG_DTR
3577 printk("cyc:set_line_char dropping Z DTR\n");
3578 #endif
3579 }else{
3580 cy_writel(&ch_ctrl->rs_control,
3581 cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
3582 #ifdef CY_DEBUG_DTR
3583 printk("cyc:set_line_char raising Z DTR\n");
3584 #endif
3587 retval = cyz_issue_cmd( &cy_card[card], channel, C_CM_IOCTLM, 0L);
3588 if (retval != 0){
3589 printk("cyc:set_line_char retval at %d was %x\n",
3590 __LINE__, retval);
3593 if (info->tty){
3594 clear_bit(TTY_IO_ERROR, &info->tty->flags);
3599 * Set up the tty->alt_speed kludge
3601 if (info->tty) {
3602 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
3603 info->tty->alt_speed = 57600;
3604 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
3605 info->tty->alt_speed = 115200;
3606 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
3607 info->tty->alt_speed = 230400;
3608 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
3609 info->tty->alt_speed = 460800;
3613 } /* set_line_char */
3616 static int
3617 get_serial_info(struct cyclades_port * info,
3618 struct serial_struct * retinfo)
3620 struct serial_struct tmp;
3621 struct cyclades_card *cinfo = &cy_card[info->card];
3623 if (!retinfo)
3624 return -EFAULT;
3625 memset(&tmp, 0, sizeof(tmp));
3626 tmp.type = info->type;
3627 tmp.line = info->line;
3628 tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
3629 tmp.irq = cinfo->irq;
3630 tmp.flags = info->flags;
3631 tmp.close_delay = info->close_delay;
3632 tmp.baud_base = info->baud;
3633 tmp.custom_divisor = 0; /*!!!*/
3634 tmp.hub6 = 0; /*!!!*/
3635 return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0;
3636 } /* get_serial_info */
3639 static int
3640 set_serial_info(struct cyclades_port * info,
3641 struct serial_struct * new_info)
3643 struct serial_struct new_serial;
3644 struct cyclades_port old_info;
3646 if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
3647 return -EFAULT;
3648 old_info = *info;
3650 if (!capable(CAP_SYS_ADMIN)) {
3651 if ((new_serial.close_delay != info->close_delay) ||
3652 (new_serial.baud_base != info->baud) ||
3653 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
3654 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
3655 return -EPERM;
3656 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
3657 (new_serial.flags & ASYNC_USR_MASK));
3658 info->baud = new_serial.baud_base;
3659 goto check_and_exit;
3664 * OK, past this point, all the error checking has been done.
3665 * At this point, we start making changes.....
3668 info->baud = new_serial.baud_base;
3669 info->flags = ((info->flags & ~ASYNC_FLAGS) |
3670 (new_serial.flags & ASYNC_FLAGS));
3671 info->close_delay = new_serial.close_delay * HZ/100;
3672 info->closing_wait = new_serial.closing_wait * HZ/100;
3674 check_and_exit:
3675 if (info->flags & ASYNC_INITIALIZED){
3676 set_line_char(info);
3677 return 0;
3678 }else{
3679 return startup(info);
3681 } /* set_serial_info */
3684 static int
3685 get_modem_info(struct cyclades_port * info, unsigned int *value)
3687 int card,chip,channel,index;
3688 unsigned char *base_addr;
3689 unsigned long flags;
3690 unsigned char status;
3691 unsigned long lstatus;
3692 unsigned int result;
3693 struct FIRM_ID *firm_id;
3694 struct ZFW_CTRL *zfw_ctrl;
3695 struct BOARD_CTRL *board_ctrl;
3696 struct CH_CTRL *ch_ctrl;
3698 card = info->card;
3699 channel = (info->line) - (cy_card[card].first_line);
3700 if (!IS_CYC_Z(cy_card[card])) {
3701 chip = channel>>2;
3702 channel &= 0x03;
3703 index = cy_card[card].bus_index;
3704 base_addr = (unsigned char*)
3705 (cy_card[card].base_addr
3706 + (cy_chip_offset[chip]<<index));
3708 CY_LOCK(info, flags);
3709 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3710 status = cy_readb(base_addr+(CyMSVR1<<index));
3711 status |= cy_readb(base_addr+(CyMSVR2<<index));
3712 CY_UNLOCK(info, flags);
3714 if (info->rtsdtr_inv) {
3715 result = ((status & CyRTS) ? TIOCM_DTR : 0)
3716 | ((status & CyDTR) ? TIOCM_RTS : 0);
3717 } else {
3718 result = ((status & CyRTS) ? TIOCM_RTS : 0)
3719 | ((status & CyDTR) ? TIOCM_DTR : 0);
3721 result |= ((status & CyDCD) ? TIOCM_CAR : 0)
3722 | ((status & CyRI) ? TIOCM_RNG : 0)
3723 | ((status & CyDSR) ? TIOCM_DSR : 0)
3724 | ((status & CyCTS) ? TIOCM_CTS : 0);
3725 } else {
3726 base_addr = (unsigned char*) (cy_card[card].base_addr);
3728 if (cy_card[card].num_chips != -1){
3729 return -EINVAL;
3732 firm_id = (struct FIRM_ID *)
3733 (cy_card[card].base_addr + ID_ADDRESS);
3734 if (ISZLOADED(cy_card[card])) {
3735 zfw_ctrl = (struct ZFW_CTRL *)
3736 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
3737 board_ctrl = &zfw_ctrl->board_ctrl;
3738 ch_ctrl = zfw_ctrl->ch_ctrl;
3739 lstatus = cy_readl(&ch_ctrl[channel].rs_status);
3740 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0)
3741 | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0)
3742 | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0)
3743 | ((lstatus & C_RS_RI) ? TIOCM_RNG : 0)
3744 | ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0)
3745 | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
3746 }else{
3747 result = 0;
3748 return -ENODEV;
3752 return cy_put_user(result,(unsigned int *) value);
3753 } /* get_modem_info */
3756 static int
3757 set_modem_info(struct cyclades_port * info, unsigned int cmd,
3758 unsigned int *value)
3760 int card,chip,channel,index;
3761 unsigned char *base_addr;
3762 unsigned long flags;
3763 unsigned int arg = cy_get_user((unsigned long *) value);
3764 struct FIRM_ID *firm_id;
3765 struct ZFW_CTRL *zfw_ctrl;
3766 struct BOARD_CTRL *board_ctrl;
3767 struct CH_CTRL *ch_ctrl;
3768 int retval;
3770 card = info->card;
3771 channel = (info->line) - (cy_card[card].first_line);
3772 if (!IS_CYC_Z(cy_card[card])) {
3773 chip = channel>>2;
3774 channel &= 0x03;
3775 index = cy_card[card].bus_index;
3776 base_addr = (unsigned char*)
3777 (cy_card[card].base_addr
3778 + (cy_chip_offset[chip]<<index));
3780 switch (cmd) {
3781 case TIOCMBIS:
3782 if (arg & TIOCM_RTS){
3783 CY_LOCK(info, flags);
3784 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3785 if (info->rtsdtr_inv) {
3786 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3787 } else {
3788 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3790 CY_UNLOCK(info, flags);
3792 if (arg & TIOCM_DTR){
3793 CY_LOCK(info, flags);
3794 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3795 if (info->rtsdtr_inv) {
3796 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3797 } else {
3798 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3800 #ifdef CY_DEBUG_DTR
3801 printk("cyc:set_modem_info raising DTR\n");
3802 printk(" status: 0x%x, 0x%x\n",
3803 cy_readb(base_addr+(CyMSVR1<<index)),
3804 cy_readb(base_addr+(CyMSVR2<<index)));
3805 #endif
3806 CY_UNLOCK(info, flags);
3808 break;
3809 case TIOCMBIC:
3810 if (arg & TIOCM_RTS){
3811 CY_LOCK(info, flags);
3812 cy_writeb((u_long)base_addr+(CyCAR<<index),
3813 (u_char)channel);
3814 if (info->rtsdtr_inv) {
3815 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3816 } else {
3817 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3819 CY_UNLOCK(info, flags);
3821 if (arg & TIOCM_DTR){
3822 CY_LOCK(info, flags);
3823 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3824 if (info->rtsdtr_inv) {
3825 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3826 } else {
3827 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3829 #ifdef CY_DEBUG_DTR
3830 printk("cyc:set_modem_info dropping DTR\n");
3831 printk(" status: 0x%x, 0x%x\n",
3832 cy_readb(base_addr+(CyMSVR1<<index)),
3833 cy_readb(base_addr+(CyMSVR2<<index)));
3834 #endif
3835 CY_UNLOCK(info, flags);
3837 break;
3838 case TIOCMSET:
3839 if (arg & TIOCM_RTS){
3840 CY_LOCK(info, flags);
3841 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3842 if (info->rtsdtr_inv) {
3843 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3844 } else {
3845 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3847 CY_UNLOCK(info, flags);
3848 }else{
3849 CY_LOCK(info, flags);
3850 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3851 if (info->rtsdtr_inv) {
3852 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3853 } else {
3854 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3856 CY_UNLOCK(info, flags);
3858 if (arg & TIOCM_DTR){
3859 CY_LOCK(info, flags);
3860 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3861 if (info->rtsdtr_inv) {
3862 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3863 } else {
3864 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3866 #ifdef CY_DEBUG_DTR
3867 printk("cyc:set_modem_info raising DTR\n");
3868 printk(" status: 0x%x, 0x%x\n",
3869 cy_readb(base_addr+(CyMSVR1<<index)),
3870 cy_readb(base_addr+(CyMSVR2<<index)));
3871 #endif
3872 CY_UNLOCK(info, flags);
3873 }else{
3874 CY_LOCK(info, flags);
3875 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3876 if (info->rtsdtr_inv) {
3877 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3878 } else {
3879 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3882 #ifdef CY_DEBUG_DTR
3883 printk("cyc:set_modem_info dropping DTR\n");
3884 printk(" status: 0x%x, 0x%x\n",
3885 cy_readb(base_addr+(CyMSVR1<<index)),
3886 cy_readb(base_addr+(CyMSVR2<<index)));
3887 #endif
3888 CY_UNLOCK(info, flags);
3890 break;
3891 default:
3892 return -EINVAL;
3894 } else {
3895 base_addr = (unsigned char*) (cy_card[card].base_addr);
3897 firm_id = (struct FIRM_ID *)
3898 (cy_card[card].base_addr + ID_ADDRESS);
3899 if (ISZLOADED(cy_card[card])) {
3900 zfw_ctrl = (struct ZFW_CTRL *)
3901 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
3902 board_ctrl = &zfw_ctrl->board_ctrl;
3903 ch_ctrl = zfw_ctrl->ch_ctrl;
3905 switch (cmd) {
3906 case TIOCMBIS:
3907 if (arg & TIOCM_RTS){
3908 CY_LOCK(info, flags);
3909 cy_writel(&ch_ctrl[channel].rs_control,
3910 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS);
3911 CY_UNLOCK(info, flags);
3913 if (arg & TIOCM_DTR){
3914 CY_LOCK(info, flags);
3915 cy_writel(&ch_ctrl[channel].rs_control,
3916 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
3917 #ifdef CY_DEBUG_DTR
3918 printk("cyc:set_modem_info raising Z DTR\n");
3919 #endif
3920 CY_UNLOCK(info, flags);
3922 break;
3923 case TIOCMBIC:
3924 if (arg & TIOCM_RTS){
3925 CY_LOCK(info, flags);
3926 cy_writel(&ch_ctrl[channel].rs_control,
3927 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS);
3928 CY_UNLOCK(info, flags);
3930 if (arg & TIOCM_DTR){
3931 CY_LOCK(info, flags);
3932 cy_writel(&ch_ctrl[channel].rs_control,
3933 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
3934 #ifdef CY_DEBUG_DTR
3935 printk("cyc:set_modem_info clearing Z DTR\n");
3936 #endif
3937 CY_UNLOCK(info, flags);
3939 break;
3940 case TIOCMSET:
3941 if (arg & TIOCM_RTS){
3942 CY_LOCK(info, flags);
3943 cy_writel(&ch_ctrl[channel].rs_control,
3944 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS);
3945 CY_UNLOCK(info, flags);
3946 }else{
3947 CY_LOCK(info, flags);
3948 cy_writel(&ch_ctrl[channel].rs_control,
3949 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS);
3950 CY_UNLOCK(info, flags);
3952 if (arg & TIOCM_DTR){
3953 CY_LOCK(info, flags);
3954 cy_writel(&ch_ctrl[channel].rs_control,
3955 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
3956 #ifdef CY_DEBUG_DTR
3957 printk("cyc:set_modem_info raising Z DTR\n");
3958 #endif
3959 CY_UNLOCK(info, flags);
3960 }else{
3961 CY_LOCK(info, flags);
3962 cy_writel(&ch_ctrl[channel].rs_control,
3963 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
3964 #ifdef CY_DEBUG_DTR
3965 printk("cyc:set_modem_info clearing Z DTR\n");
3966 #endif
3967 CY_UNLOCK(info, flags);
3969 break;
3970 default:
3971 return -EINVAL;
3973 }else{
3974 return -ENODEV;
3976 CY_LOCK(info, flags);
3977 retval = cyz_issue_cmd(&cy_card[info->card],
3978 channel, C_CM_IOCTLM,0L);
3979 if (retval != 0){
3980 printk("cyc:set_modem_info retval at %d was %x\n",
3981 __LINE__, retval);
3983 CY_UNLOCK(info, flags);
3985 return 0;
3986 } /* set_modem_info */
3989 * cy_break() --- routine which turns the break handling on or off
3991 static void
3992 cy_break(struct tty_struct *tty, int break_state)
3994 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
3995 unsigned long flags;
3997 if (serial_paranoia_check(info, tty->device, "cy_break"))
3998 return;
4000 CY_LOCK(info, flags);
4001 if (!IS_CYC_Z(cy_card[info->card])) {
4002 /* Let the transmit ISR take care of this (since it
4003 requires stuffing characters into the output stream).
4005 if (break_state == -1) {
4006 if (!info->breakon) {
4007 info->breakon = 1;
4008 if (!info->xmit_cnt) {
4009 CY_UNLOCK(info, flags);
4010 start_xmit(info);
4011 CY_LOCK(info, flags);
4014 } else {
4015 if (!info->breakoff) {
4016 info->breakoff = 1;
4017 if (!info->xmit_cnt) {
4018 CY_UNLOCK(info, flags);
4019 start_xmit(info);
4020 CY_LOCK(info, flags);
4024 } else {
4025 int retval;
4027 if (break_state == -1) {
4028 retval = cyz_issue_cmd(&cy_card[info->card],
4029 (info->line) - (cy_card[info->card].first_line),
4030 C_CM_SET_BREAK, 0L);
4031 if (retval != 0) {
4032 printk("cyc:cy_break (set) retval at %d was %x\n",
4033 __LINE__, retval);
4035 } else {
4036 retval = cyz_issue_cmd(&cy_card[info->card],
4037 (info->line) - (cy_card[info->card].first_line),
4038 C_CM_CLR_BREAK, 0L);
4039 if (retval != 0) {
4040 printk("cyc:cy_break (clr) retval at %d was %x\n",
4041 __LINE__, retval);
4045 CY_UNLOCK(info, flags);
4046 } /* cy_break */
4048 static int
4049 get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
4052 if(copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
4053 return -EFAULT;
4054 info->mon.int_count = 0;
4055 info->mon.char_count = 0;
4056 info->mon.char_max = 0;
4057 info->mon.char_last = 0;
4058 return 0;
4059 }/* get_mon_info */
4062 static int
4063 set_threshold(struct cyclades_port * info, unsigned long value)
4065 unsigned char *base_addr;
4066 int card,channel,chip,index;
4067 unsigned long flags;
4069 card = info->card;
4070 channel = info->line - cy_card[card].first_line;
4071 if (!IS_CYC_Z(cy_card[card])) {
4072 chip = channel>>2;
4073 channel &= 0x03;
4074 index = cy_card[card].bus_index;
4075 base_addr = (unsigned char*)
4076 (cy_card[card].base_addr
4077 + (cy_chip_offset[chip]<<index));
4079 info->cor3 &= ~CyREC_FIFO;
4080 info->cor3 |= value & CyREC_FIFO;
4082 CY_LOCK(info, flags);
4083 cy_writeb((u_long)base_addr+(CyCOR3<<index), info->cor3);
4084 cyy_issue_cmd(base_addr,CyCOR_CHANGE|CyCOR3ch,index);
4085 CY_UNLOCK(info, flags);
4086 } else {
4087 // Nothing to do!
4089 return 0;
4090 }/* set_threshold */
4093 static int
4094 get_threshold(struct cyclades_port * info, unsigned long *value)
4096 unsigned char *base_addr;
4097 int card,channel,chip,index;
4098 unsigned long tmp;
4100 card = info->card;
4101 channel = info->line - cy_card[card].first_line;
4102 if (!IS_CYC_Z(cy_card[card])) {
4103 chip = channel>>2;
4104 channel &= 0x03;
4105 index = cy_card[card].bus_index;
4106 base_addr = (unsigned char*)
4107 (cy_card[card].base_addr
4108 + (cy_chip_offset[chip]<<index));
4110 tmp = cy_readb(base_addr+(CyCOR3<<index)) & CyREC_FIFO;
4111 return cy_put_user(tmp,value);
4112 } else {
4113 // Nothing to do!
4114 return 0;
4116 }/* get_threshold */
4119 static int
4120 set_default_threshold(struct cyclades_port * info, unsigned long value)
4122 info->default_threshold = value & 0x0f;
4123 return 0;
4124 }/* set_default_threshold */
4127 static int
4128 get_default_threshold(struct cyclades_port * info, unsigned long *value)
4130 return cy_put_user(info->default_threshold,value);
4131 }/* get_default_threshold */
4134 static int
4135 set_timeout(struct cyclades_port * info, unsigned long value)
4137 unsigned char *base_addr;
4138 int card,channel,chip,index;
4139 unsigned long flags;
4141 card = info->card;
4142 channel = info->line - cy_card[card].first_line;
4143 if (!IS_CYC_Z(cy_card[card])) {
4144 chip = channel>>2;
4145 channel &= 0x03;
4146 index = cy_card[card].bus_index;
4147 base_addr = (unsigned char*)
4148 (cy_card[card].base_addr
4149 + (cy_chip_offset[chip]<<index));
4151 CY_LOCK(info, flags);
4152 cy_writeb((u_long)base_addr+(CyRTPR<<index), value & 0xff);
4153 CY_UNLOCK(info, flags);
4154 } else {
4155 // Nothing to do!
4157 return 0;
4158 }/* set_timeout */
4161 static int
4162 get_timeout(struct cyclades_port * info, unsigned long *value)
4164 unsigned char *base_addr;
4165 int card,channel,chip,index;
4166 unsigned long tmp;
4168 card = info->card;
4169 channel = info->line - cy_card[card].first_line;
4170 if (!IS_CYC_Z(cy_card[card])) {
4171 chip = channel>>2;
4172 channel &= 0x03;
4173 index = cy_card[card].bus_index;
4174 base_addr = (unsigned char*)
4175 (cy_card[card].base_addr
4176 + (cy_chip_offset[chip]<<index));
4178 tmp = cy_readb(base_addr+(CyRTPR<<index));
4179 return cy_put_user(tmp,value);
4180 } else {
4181 // Nothing to do!
4182 return 0;
4184 }/* get_timeout */
4187 static int
4188 set_default_timeout(struct cyclades_port * info, unsigned long value)
4190 info->default_timeout = value & 0xff;
4191 return 0;
4192 }/* set_default_timeout */
4195 static int
4196 get_default_timeout(struct cyclades_port * info, unsigned long *value)
4198 return cy_put_user(info->default_timeout,value);
4199 }/* get_default_timeout */
4202 * This routine allows the tty driver to implement device-
4203 * specific ioctl's. If the ioctl number passed in cmd is
4204 * not recognized by the driver, it should return ENOIOCTLCMD.
4206 static int
4207 cy_ioctl(struct tty_struct *tty, struct file * file,
4208 unsigned int cmd, unsigned long arg)
4210 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
4211 int ret_val = 0;
4213 if (serial_paranoia_check(info, tty->device, "cy_ioctl"))
4214 return -ENODEV;
4216 #ifdef CY_DEBUG_OTHER
4217 printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
4218 info->line, cmd, arg); /* */
4219 #endif
4221 switch (cmd) {
4222 case CYGETMON:
4223 ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
4224 break;
4225 case CYGETTHRESH:
4226 ret_val = get_threshold(info, (unsigned long *)arg);
4227 break;
4228 case CYSETTHRESH:
4229 ret_val = set_threshold(info, (unsigned long)arg);
4230 break;
4231 case CYGETDEFTHRESH:
4232 ret_val = get_default_threshold(info, (unsigned long *)arg);
4233 break;
4234 case CYSETDEFTHRESH:
4235 ret_val = set_default_threshold(info, (unsigned long)arg);
4236 break;
4237 case CYGETTIMEOUT:
4238 ret_val = get_timeout(info, (unsigned long *)arg);
4239 break;
4240 case CYSETTIMEOUT:
4241 ret_val = set_timeout(info, (unsigned long)arg);
4242 break;
4243 case CYGETDEFTIMEOUT:
4244 ret_val = get_default_timeout(info, (unsigned long *)arg);
4245 break;
4246 case CYSETDEFTIMEOUT:
4247 ret_val = set_default_timeout(info, (unsigned long)arg);
4248 break;
4249 case CYSETRFLOW:
4250 info->rflow = (int)arg;
4251 ret_val = 0;
4252 break;
4253 case CYGETRFLOW:
4254 ret_val = info->rflow;
4255 break;
4256 case CYSETRTSDTR_INV:
4257 info->rtsdtr_inv = (int)arg;
4258 ret_val = 0;
4259 break;
4260 case CYGETRTSDTR_INV:
4261 ret_val = info->rtsdtr_inv;
4262 break;
4263 case CYGETCARDINFO:
4264 if (copy_to_user((void *)arg, (void *)&cy_card[info->card],
4265 sizeof (struct cyclades_card))) {
4266 ret_val = -EFAULT;
4268 ret_val = 0;
4269 break;
4270 case CYGETCD1400VER:
4271 ret_val = info->chip_rev;
4272 break;
4273 #ifndef CONFIG_CYZ_INTR
4274 case CYZSETPOLLCYCLE:
4275 cyz_polling_cycle = (arg * HZ) / 1000;
4276 ret_val = 0;
4277 break;
4278 case CYZGETPOLLCYCLE:
4279 ret_val = (cyz_polling_cycle * 1000) / HZ;
4280 break;
4281 #endif /* CONFIG_CYZ_INTR */
4282 case CYSETWAIT:
4283 info->closing_wait = (unsigned short)arg * HZ/100;
4284 ret_val = 0;
4285 break;
4286 case CYGETWAIT:
4287 ret_val = info->closing_wait / (HZ/100);
4288 break;
4289 case TIOCMGET:
4290 ret_val = get_modem_info(info, (unsigned int *) arg);
4291 break;
4292 case TIOCMBIS:
4293 case TIOCMBIC:
4294 case TIOCMSET:
4295 ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
4296 break;
4297 case TIOCGSERIAL:
4298 ret_val = get_serial_info(info, (struct serial_struct *) arg);
4299 break;
4300 case TIOCSSERIAL:
4301 ret_val = set_serial_info(info, (struct serial_struct *) arg);
4302 break;
4303 default:
4304 ret_val = -ENOIOCTLCMD;
4307 #ifdef CY_DEBUG_OTHER
4308 printk(" cyc:cy_ioctl done\n");
4309 #endif
4311 return ret_val;
4312 } /* cy_ioctl */
4316 * This routine allows the tty driver to be notified when
4317 * device's termios settings have changed. Note that a
4318 * well-designed tty driver should be prepared to accept the case
4319 * where old == NULL, and try to do something rational.
4321 static void
4322 cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
4324 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4326 #ifdef CY_DEBUG_OTHER
4327 printk("cyc:cy_set_termios ttyC%d\n", info->line);
4328 #endif
4330 if ((tty->termios->c_cflag == old_termios->c_cflag) &&
4331 ((tty->termios->c_iflag & IXON) == (old_termios->c_iflag & IXON)))
4332 return;
4333 set_line_char(info);
4335 if ((old_termios->c_cflag & CRTSCTS) &&
4336 !(tty->termios->c_cflag & CRTSCTS)) {
4337 tty->stopped = 0;
4338 cy_start(tty);
4340 #if 0
4342 * No need to wake up processes in open wait, since they
4343 * sample the CLOCAL flag once, and don't recheck it.
4344 * XXX It's not clear whether the current behavior is correct
4345 * or not. Hence, this may change.....
4347 if (!(old_termios->c_cflag & CLOCAL) &&
4348 (tty->termios->c_cflag & CLOCAL))
4349 wake_up_interruptible(&info->open_wait);
4350 #endif
4352 return;
4353 } /* cy_set_termios */
4355 /* This routine is called by the upper-layer tty layer to signal
4356 that incoming characters should be throttled because the input
4357 buffers are close to full.
4359 static void
4360 cy_throttle(struct tty_struct * tty)
4362 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4363 unsigned long flags;
4364 unsigned char *base_addr;
4365 int card,chip,channel,index;
4367 #ifdef CY_DEBUG_THROTTLE
4368 char buf[64];
4370 printk("cyc:throttle %s: %d....ttyC%d\n",
4371 tty_name(tty, buf),
4372 tty->ldisc.chars_in_buffer(tty), info->line);
4373 #endif
4375 if (serial_paranoia_check(info, tty->device, "cy_throttle")){
4376 return;
4379 if (I_IXOFF(tty)) {
4380 info->x_char = STOP_CHAR(tty);
4381 /* Should use the "Send Special Character" feature!!! */
4384 card = info->card;
4385 channel = info->line - cy_card[card].first_line;
4386 if (!IS_CYC_Z(cy_card[card])) {
4387 chip = channel>>2;
4388 channel &= 0x03;
4389 index = cy_card[card].bus_index;
4390 base_addr = (unsigned char*)
4391 (cy_card[card].base_addr
4392 + (cy_chip_offset[chip]<<index));
4394 CY_LOCK(info, flags);
4395 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
4396 if (info->rtsdtr_inv) {
4397 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
4398 } else {
4399 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
4401 CY_UNLOCK(info, flags);
4402 } else {
4403 // Nothing to do!
4406 return;
4407 } /* cy_throttle */
4411 * This routine notifies the tty driver that it should signal
4412 * that characters can now be sent to the tty without fear of
4413 * overrunning the input buffers of the line disciplines.
4415 static void
4416 cy_unthrottle(struct tty_struct * tty)
4418 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4419 unsigned long flags;
4420 unsigned char *base_addr;
4421 int card,chip,channel,index;
4423 #ifdef CY_DEBUG_THROTTLE
4424 char buf[64];
4426 printk("cyc:unthrottle %s: %d....ttyC%d\n",
4427 tty_name(tty, buf),
4428 tty->ldisc.chars_in_buffer(tty), info->line);
4429 #endif
4431 if (serial_paranoia_check(info, tty->device, "cy_unthrottle")){
4432 return;
4435 if (I_IXOFF(tty)) {
4436 if (info->x_char)
4437 info->x_char = 0;
4438 else
4439 info->x_char = START_CHAR(tty);
4440 /* Should use the "Send Special Character" feature!!! */
4443 card = info->card;
4444 channel = info->line - cy_card[card].first_line;
4445 if (!IS_CYC_Z(cy_card[card])) {
4446 chip = channel>>2;
4447 channel &= 0x03;
4448 index = cy_card[card].bus_index;
4449 base_addr = (unsigned char*)
4450 (cy_card[card].base_addr
4451 + (cy_chip_offset[chip]<<index));
4453 CY_LOCK(info, flags);
4454 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
4455 if (info->rtsdtr_inv) {
4456 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
4457 } else {
4458 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
4460 CY_UNLOCK(info, flags);
4461 }else{
4462 // Nothing to do!
4465 return;
4466 } /* cy_unthrottle */
4469 /* cy_start and cy_stop provide software output flow control as a
4470 function of XON/XOFF, software CTS, and other such stuff.
4472 static void
4473 cy_stop(struct tty_struct *tty)
4475 struct cyclades_card *cinfo;
4476 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4477 unsigned char *base_addr;
4478 int chip,channel,index;
4479 unsigned long flags;
4481 #ifdef CY_DEBUG_OTHER
4482 printk("cyc:cy_stop ttyC%d\n", info->line); /* */
4483 #endif
4485 if (serial_paranoia_check(info, tty->device, "cy_stop"))
4486 return;
4488 cinfo = &cy_card[info->card];
4489 channel = info->line - cinfo->first_line;
4490 if (!IS_CYC_Z(*cinfo)) {
4491 index = cinfo->bus_index;
4492 chip = channel>>2;
4493 channel &= 0x03;
4494 base_addr = (unsigned char*)
4495 (cy_card[info->card].base_addr
4496 + (cy_chip_offset[chip]<<index));
4498 CY_LOCK(info, flags);
4499 cy_writeb((u_long)base_addr+(CyCAR<<index),
4500 (u_char)(channel & 0x0003)); /* index channel */
4501 cy_writeb((u_long)base_addr+(CySRER<<index),
4502 cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
4503 CY_UNLOCK(info, flags);
4504 } else {
4505 // Nothing to do!
4508 return;
4509 } /* cy_stop */
4512 static void
4513 cy_start(struct tty_struct *tty)
4515 struct cyclades_card *cinfo;
4516 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4517 unsigned char *base_addr;
4518 int chip,channel,index;
4519 unsigned long flags;
4521 #ifdef CY_DEBUG_OTHER
4522 printk("cyc:cy_start ttyC%d\n", info->line); /* */
4523 #endif
4525 if (serial_paranoia_check(info, tty->device, "cy_start"))
4526 return;
4528 cinfo = &cy_card[info->card];
4529 channel = info->line - cinfo->first_line;
4530 index = cinfo->bus_index;
4531 if (!IS_CYC_Z(*cinfo)) {
4532 chip = channel>>2;
4533 channel &= 0x03;
4534 base_addr = (unsigned char*)
4535 (cy_card[info->card].base_addr
4536 + (cy_chip_offset[chip]<<index));
4538 CY_LOCK(info, flags);
4539 cy_writeb((u_long)base_addr+(CyCAR<<index),
4540 (u_char)(channel & 0x0003)); /* index channel */
4541 cy_writeb((u_long)base_addr+(CySRER<<index),
4542 cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
4543 CY_UNLOCK(info, flags);
4544 } else {
4545 // Nothing to do!
4548 return;
4549 } /* cy_start */
4552 static void
4553 cy_flush_buffer(struct tty_struct *tty)
4555 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4556 int card, channel, retval;
4557 unsigned long flags;
4559 #ifdef CY_DEBUG_IO
4560 printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */
4561 #endif
4563 if (serial_paranoia_check(info, tty->device, "cy_flush_buffer"))
4564 return;
4566 card = info->card;
4567 channel = (info->line) - (cy_card[card].first_line);
4569 CY_LOCK(info, flags);
4570 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
4571 CY_UNLOCK(info, flags);
4573 if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board
4574 buffers as well */
4575 CY_LOCK(info, flags);
4576 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
4577 if (retval != 0) {
4578 printk("cyc: flush_buffer retval was %x\n", retval);
4580 CY_UNLOCK(info, flags);
4582 wake_up_interruptible(&tty->write_wait);
4583 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
4584 && tty->ldisc.write_wakeup)
4585 (tty->ldisc.write_wakeup)(tty);
4586 } /* cy_flush_buffer */
4590 * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
4592 static void
4593 cy_hangup(struct tty_struct *tty)
4595 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
4597 #ifdef CY_DEBUG_OTHER
4598 printk("cyc:cy_hangup ttyC%d\n", info->line); /* */
4599 #endif
4601 if (serial_paranoia_check(info, tty->device, "cy_hangup"))
4602 return;
4604 cy_flush_buffer(tty);
4605 shutdown(info);
4606 info->event = 0;
4607 info->count = 0;
4608 #ifdef CY_DEBUG_COUNT
4609 printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
4610 #endif
4611 info->tty = 0;
4612 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
4613 wake_up_interruptible(&info->open_wait);
4614 } /* cy_hangup */
4618 * ---------------------------------------------------------------------
4619 * cy_init() and friends
4621 * cy_init() is called at boot-time to initialize the serial driver.
4622 * ---------------------------------------------------------------------
4625 /* initialize chips on Cyclom-Y card -- return number of valid
4626 chips (which is number of ports/4) */
4627 static unsigned short __init
4628 cyy_init_card(volatile ucchar *true_base_addr,int index)
4630 unsigned int chip_number;
4631 volatile ucchar* base_addr;
4633 cy_writeb((u_long)true_base_addr+(Cy_HwReset<<index), 0);
4634 /* Cy_HwReset is 0x1400 */
4635 cy_writeb((u_long)true_base_addr+(Cy_ClrIntr<<index), 0);
4636 /* Cy_ClrIntr is 0x1800 */
4637 udelay(500L);
4639 for(chip_number=0; chip_number<CyMAX_CHIPS_PER_CARD; chip_number++){
4640 base_addr = true_base_addr
4641 + (cy_chip_offset[chip_number]<<index);
4642 mdelay(1);
4643 if(cy_readb(base_addr+(CyCCR<<index)) != 0x00){
4644 /*************
4645 printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
4646 chip_number, (unsigned long)base_addr);
4647 *************/
4648 return chip_number;
4651 cy_writeb((u_long)base_addr+(CyGFRCR<<index), 0);
4652 udelay(10L);
4654 /* The Cyclom-16Y does not decode address bit 9 and therefore
4655 cannot distinguish between references to chip 0 and a non-
4656 existent chip 4. If the preceding clearing of the supposed
4657 chip 4 GFRCR register appears at chip 0, there is no chip 4
4658 and this must be a Cyclom-16Y, not a Cyclom-32Ye.
4660 if (chip_number == 4
4661 && cy_readb(true_base_addr
4662 + (cy_chip_offset[0]<<index)
4663 + (CyGFRCR<<index)) == 0){
4664 return chip_number;
4667 cy_writeb((u_long)base_addr+(CyCCR<<index), CyCHIP_RESET);
4668 mdelay(1);
4670 if(cy_readb(base_addr+(CyGFRCR<<index)) == 0x00){
4672 printk(" chip #%d at %#6lx is not responding ",
4673 chip_number, (unsigned long)base_addr);
4674 printk("(GFRCR stayed 0)\n",
4676 return chip_number;
4678 if((0xf0 & (cy_readb(base_addr+(CyGFRCR<<index)))) != 0x40){
4680 printk(" chip #%d at %#6lx is not valid (GFRCR == %#2x)\n",
4681 chip_number, (unsigned long)base_addr,
4682 base_addr[CyGFRCR<<index]);
4684 return chip_number;
4686 cy_writeb((u_long)base_addr+(CyGCR<<index), CyCH0_SERIAL);
4687 if (cy_readb(base_addr+(CyGFRCR<<index)) >= CD1400_REV_J){
4688 /* It is a CD1400 rev. J or later */
4689 /* Impossible to reach 5ms with this chip.
4690 Changed to 2ms instead (f = 500 Hz). */
4691 cy_writeb((u_long)base_addr+(CyPPR<<index), CyCLOCK_60_2MS);
4692 } else {
4693 /* f = 200 Hz */
4694 cy_writeb((u_long)base_addr+(CyPPR<<index), CyCLOCK_25_5MS);
4698 printk(" chip #%d at %#6lx is rev 0x%2x\n",
4699 chip_number, (unsigned long)base_addr,
4700 cy_readb(base_addr+(CyGFRCR<<index)));
4703 return chip_number;
4704 } /* cyy_init_card */
4706 #ifndef CONFIG_COBALT_27
4708 * ---------------------------------------------------------------------
4709 * cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
4710 * sets global variables and return the number of ISA boards found.
4711 * ---------------------------------------------------------------------
4713 static int __init
4714 cy_detect_isa(void)
4716 unsigned short cy_isa_irq,nboard;
4717 volatile ucchar *cy_isa_address;
4718 unsigned short i,j,cy_isa_nchan;
4719 #ifdef MODULE
4720 int isparam = 0;
4721 #endif
4723 nboard = 0;
4725 #ifdef MODULE
4726 /* Check for module parameters */
4727 for(i = 0 ; i < NR_CARDS; i++) {
4728 if (maddr[i] || i) {
4729 isparam = 1;
4730 cy_isa_addresses[i] = (ucchar *)maddr[i];
4732 if (!maddr[i])
4733 break;
4735 #endif
4737 /* scan the address table probing for Cyclom-Y/ISA boards */
4738 for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
4739 cy_isa_address = cy_isa_addresses[i];
4740 if (cy_isa_address == 0x0000) {
4741 return(nboard);
4744 /* probe for CD1400... */
4746 #if !defined(__alpha__)
4747 cy_isa_address = ioremap((ulong)cy_isa_address, CyISA_Ywin);
4748 #endif
4749 cy_isa_nchan = CyPORTS_PER_CHIP *
4750 cyy_init_card(cy_isa_address,0);
4751 if (cy_isa_nchan == 0) {
4752 continue;
4755 #ifdef MODULE
4756 if (isparam && irq[i])
4757 cy_isa_irq = irq[i];
4758 else
4759 #endif
4760 /* find out the board's irq by probing */
4761 cy_isa_irq = detect_isa_irq(cy_isa_address);
4762 if (cy_isa_irq == 0) {
4763 printk("Cyclom-Y/ISA found at 0x%lx ",
4764 (unsigned long) cy_isa_address);
4765 printk("but the IRQ could not be detected.\n");
4766 continue;
4769 if((cy_next_channel+cy_isa_nchan) > NR_PORTS) {
4770 printk("Cyclom-Y/ISA found at 0x%lx ",
4771 (unsigned long) cy_isa_address);
4772 printk("but no more channels are available.\n");
4773 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
4774 return(nboard);
4776 /* fill the next cy_card structure available */
4777 for (j = 0 ; j < NR_CARDS ; j++) {
4778 if (cy_card[j].base_addr == 0) break;
4780 if (j == NR_CARDS) { /* no more cy_cards available */
4781 printk("Cyclom-Y/ISA found at 0x%lx ",
4782 (unsigned long) cy_isa_address);
4783 printk("but no more cards can be used .\n");
4784 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4785 return(nboard);
4788 /* allocate IRQ */
4789 if(request_irq(cy_isa_irq, cyy_interrupt,
4790 SA_INTERRUPT, "Cyclom-Y", &cy_card[j]))
4792 printk("Cyclom-Y/ISA found at 0x%lx ",
4793 (unsigned long) cy_isa_address);
4794 printk("but could not allocate IRQ#%d.\n",
4795 cy_isa_irq);
4796 return(nboard);
4799 /* set cy_card */
4800 cy_card[j].base_addr = (u_long) cy_isa_address;
4801 cy_card[j].ctl_addr = 0;
4802 cy_card[j].irq = (int) cy_isa_irq;
4803 cy_card[j].bus_index = 0;
4804 cy_card[j].first_line = cy_next_channel;
4805 cy_card[j].num_chips = cy_isa_nchan/4;
4806 nboard++;
4808 /* print message */
4809 printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ",
4810 j+1, (unsigned long) cy_isa_address,
4811 (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
4812 cy_isa_irq);
4813 printk("%d channels starting from port %d.\n",
4814 cy_isa_nchan, cy_next_channel);
4815 cy_next_channel += cy_isa_nchan;
4817 return(nboard);
4819 } /* cy_detect_isa */
4820 #endif /* CONFIG_COBALT_27 */
4822 static void plx_init(uclong addr, uclong initctl)
4824 /* Reset PLX */
4825 cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
4826 udelay(100L);
4827 cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
4829 /* Reload Config. Registers from EEPROM */
4830 cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
4831 udelay(100L);
4832 cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
4836 * ---------------------------------------------------------------------
4837 * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI.
4838 * sets global variables and return the number of PCI boards found.
4839 * ---------------------------------------------------------------------
4841 static int __init
4842 cy_detect_pci(void)
4844 #ifdef CONFIG_PCI
4846 struct pci_dev *pdev = NULL;
4847 unsigned char cyy_rev_id;
4848 unsigned char cy_pci_irq = 0;
4849 uclong cy_pci_addr0, cy_pci_addr1, cy_pci_addr2;
4850 unsigned short i,j,cy_pci_nchan, plx_ver;
4851 unsigned short device_id,dev_index = 0;
4852 uclong mailbox;
4853 uclong Ze_addr0[NR_CARDS], Ze_addr2[NR_CARDS], ZeIndex = 0;
4855 if(pci_present() == 0) { /* PCI bus not present */
4856 return(0);
4858 for (i = 0; i < NR_CARDS; i++) {
4859 /* look for a Cyclades card by vendor and device id */
4860 while((device_id = cy_pci_dev_id[dev_index]) != 0) {
4861 if((pdev = pci_find_device(PCI_VENDOR_ID_CYCLADES,
4862 device_id, pdev)) == NULL) {
4863 dev_index++; /* try next device id */
4864 } else {
4865 break; /* found a board */
4869 if (device_id == 0)
4870 break;
4872 /* read PCI configuration area */
4873 cy_pci_irq = pdev->irq;
4874 cy_pci_addr0 = pdev->resource[0].start;
4875 cy_pci_addr1 = pdev->resource[1].start;
4876 cy_pci_addr2 = pdev->resource[2].start;
4877 pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
4879 device_id &= ~PCI_DEVICE_ID_MASK;
4881 if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo)
4882 || (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){
4883 #ifdef CY_PCI_DEBUG
4884 printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
4885 pdev->bus->number, pdev->devfn);
4886 printk("rev_id=%d) IRQ%d\n",
4887 cyy_rev_id, (int)cy_pci_irq);
4888 printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
4889 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4890 #endif
4892 if (pdev->resource[2].flags & ~PCI_BASE_ADDRESS_IO_MASK) {
4893 printk(" Warning: PCI I/O bit incorrectly set. "
4894 "Ignoring it...\n");
4895 cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
4898 #if defined(__alpha__)
4899 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
4900 printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
4901 pdev->bus->number, pdev->devfn);
4902 printk("rev_id=%d) IRQ%d\n",
4903 cyy_rev_id, (int)cy_pci_irq);
4904 printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
4905 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4906 printk("Cyclom-Y/PCI not supported for low addresses in "
4907 "Alpha systems.\n");
4908 i--;
4909 continue;
4911 #else
4912 cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Yctl);
4913 cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ywin);
4914 #endif
4916 #ifdef CY_PCI_DEBUG
4917 printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
4918 (u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
4919 #endif
4920 cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
4921 cyy_init_card((volatile ucchar *)cy_pci_addr2, 1));
4922 if(cy_pci_nchan == 0) {
4923 printk("Cyclom-Y PCI host card with ");
4924 printk("no Serial-Modules at 0x%lx.\n",
4925 (ulong) cy_pci_addr2);
4926 i--;
4927 continue;
4929 if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
4930 printk("Cyclom-Y/PCI found at 0x%lx ",
4931 (ulong) cy_pci_addr2);
4932 printk("but no channels are available.\n");
4933 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
4934 return(i);
4936 /* fill the next cy_card structure available */
4937 for (j = 0 ; j < NR_CARDS ; j++) {
4938 if (cy_card[j].base_addr == 0) break;
4940 if (j == NR_CARDS) { /* no more cy_cards available */
4941 printk("Cyclom-Y/PCI found at 0x%lx ",
4942 (ulong) cy_pci_addr2);
4943 printk("but no more cards can be used.\n");
4944 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4945 return(i);
4948 /* allocate IRQ */
4949 if(request_irq(cy_pci_irq, cyy_interrupt,
4950 SA_SHIRQ, "Cyclom-Y", &cy_card[j]))
4952 printk("Cyclom-Y/PCI found at 0x%lx ",
4953 (ulong) cy_pci_addr2);
4954 printk("but could not allocate IRQ%d.\n",
4955 cy_pci_irq);
4956 return(i);
4959 /* set cy_card */
4960 cy_card[j].base_addr = (ulong)cy_pci_addr2;
4961 cy_card[j].ctl_addr = (ulong)cy_pci_addr0;
4962 cy_card[j].irq = (int) cy_pci_irq;
4963 cy_card[j].bus_index = 1;
4964 cy_card[j].first_line = cy_next_channel;
4965 cy_card[j].num_chips = cy_pci_nchan/4;
4967 /* enable interrupts in the PCI interface */
4968 plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
4969 switch (plx_ver) {
4970 case PLX_9050:
4972 plx_init(cy_pci_addr0, 0x50);
4974 cy_writew(cy_pci_addr0+0x4c,
4975 cy_readw(cy_pci_addr0+0x4c)|0x0040);
4976 break;
4978 case PLX_9060:
4979 case PLX_9080:
4980 default: /* Old boards, use PLX_9060 */
4982 plx_init(cy_pci_addr0, 0x6c);
4983 /* For some yet unknown reason, once the PLX9060 reloads
4984 the EEPROM, the IRQ is lost and, thus, we have to
4985 re-write it to the PCI config. registers.
4986 This will remain here until we find a permanent fix. */
4987 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, cy_pci_irq);
4989 cy_writew(cy_pci_addr0+0x68,
4990 cy_readw(cy_pci_addr0+0x68)|0x0900);
4991 break;
4994 /* print message */
4995 printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
4996 j+1,
4997 (ulong)cy_pci_addr2,
4998 (ulong)(cy_pci_addr2 + CyPCI_Ywin - 1),
4999 (int)cy_pci_irq);
5000 printk("%d channels starting from port %d.\n",
5001 cy_pci_nchan, cy_next_channel);
5003 cy_next_channel += cy_pci_nchan;
5004 }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo){
5005 /* print message */
5006 printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
5007 pdev->bus->number, pdev->devfn);
5008 printk("rev_id=%d) IRQ%d\n",
5009 cyy_rev_id, (int)cy_pci_irq);
5010 printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
5011 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
5012 printk("Cyclades-Z/PCI not supported for low addresses\n");
5013 break;
5014 }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){
5015 #ifdef CY_PCI_DEBUG
5016 printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
5017 pdev->bus->number, pdev->devfn);
5018 printk("rev_id=%d) IRQ%d\n",
5019 cyy_rev_id, (int)cy_pci_irq);
5020 printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
5021 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
5022 #endif
5023 cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
5024 #if !defined(__alpha__)
5025 cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Zctl);
5026 #endif
5028 plx_init(cy_pci_addr0, 0x6c);
5029 /* For some yet unknown reason, once the PLX9060 reloads
5030 the EEPROM, the IRQ is lost and, thus, we have to
5031 re-write it to the PCI config. registers.
5032 This will remain here until we find a permanent fix. */
5033 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, cy_pci_irq);
5035 mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
5036 cy_pci_addr0)->mail_box_0);
5037 cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
5039 if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
5040 printk(" Warning: PCI I/O bit incorrectly set. "
5041 "Ignoring it...\n");
5042 cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
5044 if (mailbox == ZE_V1) {
5045 #if !defined(__alpha__)
5046 cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ze_win);
5047 #endif
5048 if (ZeIndex == NR_CARDS) {
5049 printk("Cyclades-Ze/PCI found at 0x%lx ",
5050 (ulong)cy_pci_addr2);
5051 printk("but no more cards can be used.\n");
5052 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
5053 } else {
5054 Ze_addr0[ZeIndex] = cy_pci_addr0;
5055 Ze_addr2[ZeIndex] = cy_pci_addr2;
5056 ZeIndex++;
5058 i--;
5059 continue;
5060 } else {
5061 #if !defined(__alpha__)
5062 cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Zwin);
5063 #endif
5066 #ifdef CY_PCI_DEBUG
5067 printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
5068 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
5069 if (mailbox == ZO_V1) {
5070 cy_writel(&((struct RUNTIME_9060 *)
5071 (cy_pci_addr0))->loc_addr_base, WIN_CREG);
5072 PAUSE
5073 printk("Cyclades-8Zo/PCI: FPGA id %lx, ver %lx\n",
5074 (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *)
5075 (cy_pci_addr2))->fpga_id)),
5076 (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *)
5077 (cy_pci_addr2))->fpga_version)));
5078 cy_writel(&((struct RUNTIME_9060 *)
5079 (cy_pci_addr0))->loc_addr_base, WIN_RAM);
5080 } else {
5081 printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n");
5083 #endif
5084 /* The following clears the firmware id word. This ensures
5085 that the driver will not attempt to talk to the board
5086 until it has been properly initialized.
5088 PAUSE
5089 if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
5090 cy_writel((ulong)(cy_pci_addr2+ID_ADDRESS), 0L);
5092 /* This must be a Cyclades-8Zo/PCI. The extendable
5093 version will have a different device_id and will
5094 be allocated its maximum number of ports. */
5095 cy_pci_nchan = 8;
5097 if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
5098 printk("Cyclades-8Zo/PCI found at 0x%lx ",
5099 (ulong)cy_pci_addr2);
5100 printk("but no channels are available.\n");
5101 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
5102 return(i);
5105 /* fill the next cy_card structure available */
5106 for (j = 0 ; j < NR_CARDS ; j++) {
5107 if (cy_card[j].base_addr == 0) break;
5109 if (j == NR_CARDS) { /* no more cy_cards available */
5110 printk("Cyclades-8Zo/PCI found at 0x%lx ",
5111 (ulong)cy_pci_addr2);
5112 printk("but no more cards can be used.\n");
5113 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
5114 return(i);
5117 #ifdef CONFIG_CYZ_INTR
5118 /* allocate IRQ only if board has an IRQ */
5119 if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
5120 if(request_irq(cy_pci_irq, cyz_interrupt,
5121 SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
5123 printk("Could not allocate IRQ%d ",
5124 cy_pci_irq);
5125 printk("for Cyclades-8Zo/PCI at 0x%lx.\n",
5126 (ulong)cy_pci_addr2);
5127 return(i);
5130 #endif /* CONFIG_CYZ_INTR */
5133 /* set cy_card */
5134 cy_card[j].base_addr = cy_pci_addr2;
5135 cy_card[j].ctl_addr = cy_pci_addr0;
5136 cy_card[j].irq = (int) cy_pci_irq;
5137 cy_card[j].bus_index = 1;
5138 cy_card[j].first_line = cy_next_channel;
5139 cy_card[j].num_chips = -1;
5141 /* print message */
5142 #ifdef CONFIG_CYZ_INTR
5143 /* don't report IRQ if board is no IRQ */
5144 if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
5145 printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
5146 j+1,(ulong)cy_pci_addr2,
5147 (ulong)(cy_pci_addr2 + CyPCI_Zwin - 1),
5148 (int)cy_pci_irq);
5149 else
5150 #endif /* CONFIG_CYZ_INTR */
5151 printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
5152 j+1,(ulong)cy_pci_addr2,
5153 (ulong)(cy_pci_addr2 + CyPCI_Zwin - 1));
5155 printk("%d channels starting from port %d.\n",
5156 cy_pci_nchan,cy_next_channel);
5157 #ifdef CONFIG_CYZ_INTR
5158 /* Enable interrupts on the PLX chip */
5159 cy_writew(cy_pci_addr0+0x68,
5160 cy_readw(cy_pci_addr0+0x68)|0x0900);
5161 #endif /* CONFIG_CYZ_INTR */
5162 cy_next_channel += cy_pci_nchan;
5166 for (; ZeIndex != 0 && i < NR_CARDS; i++) {
5167 cy_pci_addr0 = Ze_addr0[0];
5168 cy_pci_addr2 = Ze_addr2[0];
5169 for (j = 0 ; j < ZeIndex-1 ; j++) {
5170 Ze_addr0[j] = Ze_addr0[j+1];
5171 Ze_addr2[j] = Ze_addr2[j+1];
5173 ZeIndex--;
5174 mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
5175 cy_pci_addr0)->mail_box_0);
5176 #ifdef CY_PCI_DEBUG
5177 printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
5178 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
5179 printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n");
5180 #endif
5181 PAUSE
5182 /* This must be the new Cyclades-Ze/PCI. */
5183 cy_pci_nchan = ZE_V1_NPORTS;
5185 if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
5186 printk("Cyclades-Ze/PCI found at 0x%lx ",
5187 (ulong)cy_pci_addr2);
5188 printk("but no channels are available.\n");
5189 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
5190 return(i);
5193 /* fill the next cy_card structure available */
5194 for (j = 0 ; j < NR_CARDS ; j++) {
5195 if (cy_card[j].base_addr == 0) break;
5197 if (j == NR_CARDS) { /* no more cy_cards available */
5198 printk("Cyclades-Ze/PCI found at 0x%lx ",
5199 (ulong)cy_pci_addr2);
5200 printk("but no more cards can be used.\n");
5201 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
5202 return(i);
5205 #ifdef CONFIG_CYZ_INTR
5206 /* allocate IRQ only if board has an IRQ */
5207 if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
5208 if(request_irq(cy_pci_irq, cyz_interrupt,
5209 SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
5211 printk("Could not allocate IRQ%d ",
5212 cy_pci_irq);
5213 printk("for Cyclades-Ze/PCI at 0x%lx.\n",
5214 (ulong) cy_pci_addr2);
5215 return(i);
5218 #endif /* CONFIG_CYZ_INTR */
5220 /* set cy_card */
5221 cy_card[j].base_addr = cy_pci_addr2;
5222 cy_card[j].ctl_addr = cy_pci_addr0;
5223 cy_card[j].irq = (int) cy_pci_irq;
5224 cy_card[j].bus_index = 1;
5225 cy_card[j].first_line = cy_next_channel;
5226 cy_card[j].num_chips = -1;
5228 /* print message */
5229 #ifdef CONFIG_CYZ_INTR
5230 /* don't report IRQ if board is no IRQ */
5231 if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
5232 printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
5233 j+1,(ulong)cy_pci_addr2,
5234 (ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1),
5235 (int)cy_pci_irq);
5236 else
5237 #endif /* CONFIG_CYZ_INTR */
5238 printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
5239 j+1,(ulong)cy_pci_addr2,
5240 (ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1));
5242 printk("%d channels starting from port %d.\n",
5243 cy_pci_nchan,cy_next_channel);
5244 #ifdef CONFIG_CYZ_INTR
5245 /* Enable interrupts on the PLX chip */
5246 cy_writew(cy_pci_addr0+0x68,
5247 cy_readw(cy_pci_addr0+0x68)|0x0900);
5248 #endif /* CONFIG_CYZ_INTR */
5249 cy_next_channel += cy_pci_nchan;
5251 if (ZeIndex != 0) {
5252 printk("Cyclades-Ze/PCI found at 0x%x ",
5253 (unsigned int) Ze_addr2[0]);
5254 printk("but no more cards can be used.\n");
5255 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
5257 return(i);
5258 #else
5259 return(0);
5260 #endif /* ifdef CONFIG_PCI */
5261 } /* cy_detect_pci */
5265 * This routine prints out the appropriate serial driver version number
5266 * and identifies which options were configured into this driver.
5268 static inline void
5269 show_version(void)
5271 char *rcsvers, *rcsdate, *tmp;
5272 rcsvers = strchr(rcsid, ' '); rcsvers++;
5273 tmp = strchr(rcsvers, ' '); *tmp++ = '\0';
5274 rcsdate = strchr(tmp, ' '); rcsdate++;
5275 tmp = strrchr(rcsdate, ' '); *tmp = '\0';
5276 printk("Cyclades driver %s %s\n",
5277 rcsvers, rcsdate);
5278 printk(" built %s %s\n",
5279 __DATE__, __TIME__);
5280 } /* show_version */
5282 static int
5283 cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
5284 int *eof, void *data)
5286 struct cyclades_port *info;
5287 int i;
5288 int len=0;
5289 off_t begin=0;
5290 off_t pos=0;
5291 int size;
5292 __u32 cur_jifs = jiffies;
5294 size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn IdleIn Overruns Ldisc\n");
5296 pos += size;
5297 len += size;
5299 /* Output one line for each known port */
5300 for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) {
5301 info = &cy_port[i];
5303 if (info->count)
5304 size = sprintf(buf+len,
5305 "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
5306 info->line,
5307 JIFFIES_DIFF(info->idle_stats.in_use, cur_jifs) / HZ,
5308 info->idle_stats.xmit_bytes,
5309 JIFFIES_DIFF(info->idle_stats.xmit_idle, cur_jifs) / HZ,
5310 info->idle_stats.recv_bytes,
5311 JIFFIES_DIFF(info->idle_stats.recv_idle, cur_jifs) / HZ,
5312 info->idle_stats.overruns,
5313 (long) info->tty->ldisc.num);
5314 else
5315 size = sprintf(buf+len,
5316 "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
5317 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
5318 len += size;
5319 pos = begin + len;
5321 if (pos < offset) {
5322 len = 0;
5323 begin = pos;
5325 if (pos > offset + length)
5326 goto done;
5328 *eof = 1;
5329 done:
5330 *start = buf + (offset - begin); /* Start of wanted data */
5331 len -= (offset - begin); /* Start slop */
5332 if (len > length)
5333 len = length; /* Ending slop */
5334 if (len < 0)
5335 len = 0;
5336 return len;
5339 /* The serial driver boot-time initialization code!
5340 Hardware I/O ports are mapped to character special devices on a
5341 first found, first allocated manner. That is, this code searches
5342 for Cyclom cards in the system. As each is found, it is probed
5343 to discover how many chips (and thus how many ports) are present.
5344 These ports are mapped to the tty ports 32 and upward in monotonic
5345 fashion. If an 8-port card is replaced with a 16-port card, the
5346 port mapping on a following card will shift.
5348 This approach is different from what is used in the other serial
5349 device driver because the Cyclom is more properly a multiplexer,
5350 not just an aggregation of serial ports on one card.
5352 If there are more cards with more ports than have been
5353 statically allocated above, a warning is printed and the
5354 extra ports are ignored.
5357 int __init
5358 cy_init(void)
5360 struct cyclades_port *info;
5361 struct cyclades_card *cinfo;
5362 int number_z_boards = 0;
5363 int board,port,i,index;
5364 unsigned long mailbox;
5365 unsigned short chip_number;
5366 int nports;
5368 init_bh(CYCLADES_BH, do_cyclades_bh);
5370 show_version();
5372 /* Initialize the tty_driver structure */
5374 memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
5375 cy_serial_driver.magic = TTY_DRIVER_MAGIC;
5376 cy_serial_driver.driver_name = "cyclades";
5377 cy_serial_driver.name = "ttyC";
5378 cy_serial_driver.major = CYCLADES_MAJOR;
5379 cy_serial_driver.minor_start = 0;
5380 cy_serial_driver.num = NR_PORTS;
5381 cy_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
5382 cy_serial_driver.subtype = SERIAL_TYPE_NORMAL;
5383 cy_serial_driver.init_termios = tty_std_termios;
5384 cy_serial_driver.init_termios.c_cflag =
5385 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
5386 cy_serial_driver.flags = TTY_DRIVER_REAL_RAW;
5387 cy_serial_driver.refcount = &serial_refcount;
5388 cy_serial_driver.table = serial_table;
5389 cy_serial_driver.termios = serial_termios;
5390 cy_serial_driver.termios_locked = serial_termios_locked;
5392 cy_serial_driver.open = cy_open;
5393 cy_serial_driver.close = cy_close;
5394 cy_serial_driver.write = cy_write;
5395 cy_serial_driver.put_char = cy_put_char;
5396 cy_serial_driver.flush_chars = cy_flush_chars;
5397 cy_serial_driver.write_room = cy_write_room;
5398 cy_serial_driver.chars_in_buffer = cy_chars_in_buffer;
5399 cy_serial_driver.flush_buffer = cy_flush_buffer;
5400 cy_serial_driver.ioctl = cy_ioctl;
5401 cy_serial_driver.throttle = cy_throttle;
5402 cy_serial_driver.unthrottle = cy_unthrottle;
5403 cy_serial_driver.set_termios = cy_set_termios;
5404 cy_serial_driver.stop = cy_stop;
5405 cy_serial_driver.start = cy_start;
5406 cy_serial_driver.hangup = cy_hangup;
5407 cy_serial_driver.break_ctl = cy_break;
5408 cy_serial_driver.wait_until_sent = cy_wait_until_sent;
5409 cy_serial_driver.read_proc = cyclades_get_proc_info;
5412 * The callout device is just like normal device except for
5413 * major number and the subtype code.
5415 cy_callout_driver = cy_serial_driver;
5416 cy_callout_driver.name = "cub";
5417 cy_callout_driver.major = CYCLADESAUX_MAJOR;
5418 cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
5419 cy_callout_driver.read_proc = 0;
5420 cy_callout_driver.proc_entry = 0;
5423 if (tty_register_driver(&cy_serial_driver))
5424 panic("Couldn't register Cyclades serial driver\n");
5425 if (tty_register_driver(&cy_callout_driver))
5426 panic("Couldn't register Cyclades callout driver\n");
5428 for (i = 0; i < NR_CARDS; i++) {
5429 /* base_addr=0 indicates board not found */
5430 cy_card[i].base_addr = 0;
5433 /* the code below is responsible to find the boards. Each different
5434 type of board has its own detection routine. If a board is found,
5435 the next cy_card structure available is set by the detection
5436 routine. These functions are responsible for checking the
5437 availability of cy_card and cy_port data structures and updating
5438 the cy_next_channel. */
5440 #ifndef CONFIG_COBALT_27
5441 /* look for isa boards */
5442 cy_isa_nboard = cy_detect_isa();
5443 #endif /* CONFIG_COBALT_27 */
5445 /* look for pci boards */
5446 cy_pci_nboard = cy_detect_pci();
5448 cy_nboard = cy_isa_nboard + cy_pci_nboard;
5450 /* invalidate remaining cy_card structures */
5451 for (i = 0 ; i < NR_CARDS ; i++) {
5452 if (cy_card[i].base_addr == 0) {
5453 cy_card[i].first_line = -1;
5454 cy_card[i].ctl_addr = 0;
5455 cy_card[i].irq = 0;
5456 cy_card[i].bus_index = 0;
5457 cy_card[i].first_line = 0;
5458 cy_card[i].num_chips = 0;
5461 /* invalidate remaining cy_port structures */
5462 for (i = cy_next_channel ; i < NR_PORTS ; i++) {
5463 cy_port[i].line = -1;
5464 cy_port[i].magic = -1;
5467 /* initialize per-port data structures for each valid board found */
5468 for (board = 0 ; board < cy_nboard ; board++) {
5469 cinfo = &cy_card[board];
5470 if (cinfo->num_chips == -1) { /* Cyclades-Z */
5471 number_z_boards++;
5472 mailbox = cy_readl(&((struct RUNTIME_9060 *)
5473 cy_card[board].ctl_addr)->mail_box_0);
5474 nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
5475 cinfo->intr_enabled = 0;
5476 spin_lock_init(&cinfo->card_lock);
5477 for (port = cinfo->first_line ;
5478 port < cinfo->first_line + nports;
5479 port++)
5481 info = &cy_port[port];
5482 info->magic = CYCLADES_MAGIC;
5483 info->type = PORT_STARTECH;
5484 info->card = board;
5485 info->line = port;
5486 info->chip_rev = 0;
5487 info->flags = STD_COM_FLAGS;
5488 info->tty = 0;
5489 if (mailbox == ZO_V1)
5490 info->xmit_fifo_size = CYZ_FIFO_SIZE;
5491 else
5492 info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
5493 info->cor1 = 0;
5494 info->cor2 = 0;
5495 info->cor3 = 0;
5496 info->cor4 = 0;
5497 info->cor5 = 0;
5498 info->tbpr = 0;
5499 info->tco = 0;
5500 info->rbpr = 0;
5501 info->rco = 0;
5502 info->close_delay = 5*HZ/10;
5503 info->closing_wait = CLOSING_WAIT_DELAY;
5504 info->x_char = 0;
5505 info->event = 0;
5506 info->count = 0;
5507 #ifdef CY_DEBUG_COUNT
5508 // printk("cyc:cy_init(1) setting Z count to 0\n");
5509 #endif
5510 info->blocked_open = 0;
5511 info->default_threshold = 0;
5512 info->default_timeout = 0;
5513 info->tqueue.routine = do_softint;
5514 info->tqueue.data = info;
5515 info->callout_termios =
5516 cy_callout_driver.init_termios;
5517 info->normal_termios =
5518 cy_serial_driver.init_termios;
5519 init_waitqueue_head(&info->open_wait);
5520 init_waitqueue_head(&info->close_wait);
5521 init_waitqueue_head(&info->shutdown_wait);
5522 /* info->session */
5523 /* info->pgrp */
5524 info->read_status_mask = 0;
5525 /* info->timeout */
5526 /* Bentson's vars */
5527 info->jiffies[0] = 0;
5528 info->jiffies[1] = 0;
5529 info->jiffies[2] = 0;
5530 info->rflush_count = 0;
5532 continue;
5533 }else{ /* Cyclom-Y of some kind*/
5534 index = cinfo->bus_index;
5535 spin_lock_init(&cinfo->card_lock);
5536 for (port = cinfo->first_line ;
5537 port < cinfo->first_line + 4*cinfo->num_chips ;
5538 port++)
5540 info = &cy_port[port];
5541 info->magic = CYCLADES_MAGIC;
5542 info->type = PORT_CIRRUS;
5543 info->card = board;
5544 info->line = port;
5545 info->flags = STD_COM_FLAGS;
5546 info->tty = 0;
5547 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
5548 info->cor1 = CyPARITY_NONE|Cy_1_STOP|Cy_8_BITS;
5549 info->cor2 = CyETC;
5550 info->cor3 = 0x08; /* _very_ small rcv threshold */
5551 info->cor4 = 0;
5552 info->cor5 = 0;
5553 info->close_delay = 5*HZ/10;
5554 info->closing_wait = CLOSING_WAIT_DELAY;
5555 chip_number = (port - cinfo->first_line) / 4;
5556 if ((info->chip_rev = cy_readb(cinfo->base_addr +
5557 (cy_chip_offset[chip_number]<<index) +
5558 (CyGFRCR<<index))) >= CD1400_REV_J) {
5559 /* It is a CD1400 rev. J or later */
5560 info->tbpr = baud_bpr_60[13]; /* Tx BPR */
5561 info->tco = baud_co_60[13]; /* Tx CO */
5562 info->rbpr = baud_bpr_60[13]; /* Rx BPR */
5563 info->rco = baud_co_60[13]; /* Rx CO */
5564 info->rflow = 0;
5565 info->rtsdtr_inv = 1;
5566 } else {
5567 info->tbpr = baud_bpr_25[13]; /* Tx BPR */
5568 info->tco = baud_co_25[13]; /* Tx CO */
5569 info->rbpr = baud_bpr_25[13]; /* Rx BPR */
5570 info->rco = baud_co_25[13]; /* Rx CO */
5571 info->rflow = 0;
5572 info->rtsdtr_inv = 0;
5574 info->x_char = 0;
5575 info->event = 0;
5576 info->count = 0;
5577 #ifdef CY_DEBUG_COUNT
5578 // printk("cyc:cy_init(2) setting Y count to 0\n");
5579 #endif
5580 info->blocked_open = 0;
5581 info->default_threshold = 0;
5582 info->default_timeout = 0;
5583 info->tqueue.routine = do_softint;
5584 info->tqueue.data = info;
5585 info->callout_termios =
5586 cy_callout_driver.init_termios;
5587 info->normal_termios =
5588 cy_serial_driver.init_termios;
5589 init_waitqueue_head(&info->open_wait);
5590 init_waitqueue_head(&info->close_wait);
5591 init_waitqueue_head(&info->shutdown_wait);
5592 /* info->session */
5593 /* info->pgrp */
5594 info->read_status_mask =
5595 CyTIMEOUT| CySPECHAR| CyBREAK
5596 | CyPARITY| CyFRAME| CyOVERRUN;
5597 /* info->timeout */
5602 #ifndef CONFIG_CYZ_INTR
5603 if (number_z_boards && !cyz_timeron){
5604 cyz_timeron++;
5605 cyz_timerlist.expires = jiffies + 1;
5606 add_timer(&cyz_timerlist);
5607 #ifdef CY_PCI_DEBUG
5608 printk("Cyclades-Z polling initialized\n");
5609 #endif
5611 #endif /* CONFIG_CYZ_INTR */
5613 return 0;
5615 } /* cy_init */
5617 #ifdef MODULE
5618 /* See linux/drivers/char/riscom.c for ideas on how to
5619 pass additional base addresses to the driver!!! */
5621 init_module(void)
5623 return(cy_init());
5624 } /* init_module */
5626 void
5627 cleanup_module(void)
5629 int i;
5630 int e1, e2;
5631 unsigned long flags;
5633 #ifndef CONFIG_CYZ_INTR
5634 if (cyz_timeron){
5635 cyz_timeron = 0;
5636 del_timer(&cyz_timerlist);
5638 #endif /* CONFIG_CYZ_INTR */
5640 save_flags(flags); cli();
5641 remove_bh(CYCLADES_BH);
5643 if ((e1 = tty_unregister_driver(&cy_serial_driver)))
5644 printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
5645 e1);
5646 if ((e2 = tty_unregister_driver(&cy_callout_driver)))
5647 printk("cyc: failed to unregister Cyclades callout driver (%d)\n",
5648 e2);
5650 restore_flags(flags);
5652 for (i = 0; i < NR_CARDS; i++) {
5653 if (cy_card[i].base_addr != 0
5654 #ifndef CONFIG_CYZ_INTR
5655 && cy_card[i].num_chips != -1 /* not a Z card */
5656 #endif /* CONFIG_CYZ_INTR */
5657 && cy_card[i].irq)
5659 free_irq(cy_card[i].irq, &cy_card[i]);
5662 if (tmp_buf) {
5663 free_page((unsigned long) tmp_buf);
5664 tmp_buf = NULL;
5666 } /* cleanup_module */
5667 #else
5668 /* called by linux/init/main.c to parse command line options */
5669 void
5670 cy_setup(char *str, int *ints)
5672 #ifndef CONFIG_COBALT_27
5673 int i, j;
5675 for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
5676 if (cy_isa_addresses[i] == 0) break;
5678 for (j = 1; j <= ints[0]; j++){
5679 if ( i < NR_ISA_ADDRS ){
5680 cy_isa_addresses[i++] = (unsigned char *)(ints[j]);
5683 #endif /* CONFIG_COBALT_27 */
5685 } /* cy_setup */
5686 #endif
5689 #ifdef CYCLOM_SHOW_STATUS
5690 static void
5691 show_status(int line_num)
5693 unsigned char *base_addr;
5694 int card,chip,channel,index;
5695 struct cyclades_port * info;
5696 unsigned long flags;
5698 info = &cy_port[line_num];
5699 card = info->card;
5700 index = cy_card[card].bus_index;
5701 channel = (info->line) - (cy_card[card].first_line);
5702 chip = channel>>2;
5703 channel &= 0x03;
5704 printk(" card %d, chip %d, channel %d\n", card, chip, channel);/**/
5706 printk(" cy_card\n");
5707 printk(" irq base_addr num_chips first_line = %d %lx %d %d\n",
5708 cy_card[card].irq, (long)cy_card[card].base_addr,
5709 cy_card[card].num_chips, cy_card[card].first_line);
5711 printk(" cy_port\n");
5712 printk(" card line flags = %d %d %x\n",
5713 info->card, info->line, info->flags);
5714 printk(" *tty read_status_mask timeout xmit_fifo_size ",
5715 printk("= %lx %x %x %x\n",
5716 (long)info->tty, info->read_status_mask,
5717 info->timeout, info->xmit_fifo_size);
5718 printk(" cor1,cor2,cor3,cor4,cor5 = %x %x %x %x %x\n",
5719 info->cor1, info->cor2, info->cor3, info->cor4, info->cor5);
5720 printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n",
5721 info->tbpr, info->tco, info->rbpr, info->rco);
5722 printk(" close_delay event count = %d %d %d\n",
5723 info->close_delay, info->event, info->count);
5724 printk(" x_char blocked_open = %x %x\n",
5725 info->x_char, info->blocked_open);
5726 printk(" session pgrp open_wait = %lx %lx %lx\n",
5727 info->session, info->pgrp, (long)info->open_wait);
5729 CY_LOCK(info, flags);
5731 base_addr = (unsigned char*)
5732 (cy_card[card].base_addr
5733 + (cy_chip_offset[chip]<<index));
5735 /* Global Registers */
5737 printk(" CyGFRCR %x\n", cy_readb(base_addr + CyGFRCR<<index));
5738 printk(" CyCAR %x\n", cy_readb(base_addr + CyCAR<<index));
5739 printk(" CyGCR %x\n", cy_readb(base_addr + CyGCR<<index));
5740 printk(" CySVRR %x\n", cy_readb(base_addr + CySVRR<<index));
5741 printk(" CyRICR %x\n", cy_readb(base_addr + CyRICR<<index));
5742 printk(" CyTICR %x\n", cy_readb(base_addr + CyTICR<<index));
5743 printk(" CyMICR %x\n", cy_readb(base_addr + CyMICR<<index));
5744 printk(" CyRIR %x\n", cy_readb(base_addr + CyRIR<<index));
5745 printk(" CyTIR %x\n", cy_readb(base_addr + CyTIR<<index));
5746 printk(" CyMIR %x\n", cy_readb(base_addr + CyMIR<<index));
5747 printk(" CyPPR %x\n", cy_readb(base_addr + CyPPR<<index));
5749 cy_writeb(base_addr + CyCAR<<index, (u_char)channel);
5751 /* Virtual Registers */
5753 printk(" CyRIVR %x\n", cy_readb(base_addr + CyRIVR<<index));
5754 printk(" CyTIVR %x\n", cy_readb(base_addr + CyTIVR<<index));
5755 printk(" CyMIVR %x\n", cy_readb(base_addr + CyMIVR<<index));
5756 printk(" CyMISR %x\n", cy_readb(base_addr + CyMISR<<index));
5758 /* Channel Registers */
5760 printk(" CyCCR %x\n", cy_readb(base_addr + CyCCR<<index));
5761 printk(" CySRER %x\n", cy_readb(base_addr + CySRER<<index));
5762 printk(" CyCOR1 %x\n", cy_readb(base_addr + CyCOR1<<index));
5763 printk(" CyCOR2 %x\n", cy_readb(base_addr + CyCOR2<<index));
5764 printk(" CyCOR3 %x\n", cy_readb(base_addr + CyCOR3<<index));
5765 printk(" CyCOR4 %x\n", cy_readb(base_addr + CyCOR4<<index));
5766 printk(" CyCOR5 %x\n", cy_readb(base_addr + CyCOR5<<index));
5767 printk(" CyCCSR %x\n", cy_readb(base_addr + CyCCSR<<index));
5768 printk(" CyRDCR %x\n", cy_readb(base_addr + CyRDCR<<index));
5769 printk(" CySCHR1 %x\n", cy_readb(base_addr + CySCHR1<<index));
5770 printk(" CySCHR2 %x\n", cy_readb(base_addr + CySCHR2<<index));
5771 printk(" CySCHR3 %x\n", cy_readb(base_addr + CySCHR3<<index));
5772 printk(" CySCHR4 %x\n", cy_readb(base_addr + CySCHR4<<index));
5773 printk(" CySCRL %x\n", cy_readb(base_addr + CySCRL<<index));
5774 printk(" CySCRH %x\n", cy_readb(base_addr + CySCRH<<index));
5775 printk(" CyLNC %x\n", cy_readb(base_addr + CyLNC<<index));
5776 printk(" CyMCOR1 %x\n", cy_readb(base_addr + CyMCOR1<<index));
5777 printk(" CyMCOR2 %x\n", cy_readb(base_addr + CyMCOR2<<index));
5778 printk(" CyRTPR %x\n", cy_readb(base_addr + CyRTPR<<index));
5779 printk(" CyMSVR1 %x\n", cy_readb(base_addr + CyMSVR1<<index));
5780 printk(" CyMSVR2 %x\n", cy_readb(base_addr + CyMSVR2<<index));
5781 printk(" CyRBPR %x\n", cy_readb(base_addr + CyRBPR<<index));
5782 printk(" CyRCOR %x\n", cy_readb(base_addr + CyRCOR<<index));
5783 printk(" CyTBPR %x\n", cy_readb(base_addr + CyTBPR<<index));
5784 printk(" CyTCOR %x\n", cy_readb(base_addr + CyTCOR<<index));
5786 CY_UNLOCK(info, flags);
5787 } /* show_status */
5788 #endif