Import 2.3.10pre1
[davej-history.git] / drivers / char / cyclades.c
blob2d84f18c32af7cf51625f2e9110da6543628ed23
1 #define BLOCKMOVE
2 #define Z_WAKE
3 static char rcsid[] =
4 "$Revision: 2.2.2.2 $$Date: 1999/05/21 17:18:15 $";
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.2.2.2 1999/05/14 17:18:15 ivan
35 * /proc entry location changed to /proc/tty/driver/cyclades;
36 * Added support to shared IRQ's (only for PCI boards);
37 * Added support for Cobalt Qube2 systems;
38 * IRQ [de]allocation scheme revisited;
39 * BREAK implementation changed in order to make use of the 'break_ctl'
40 * TTY facility;
41 * Fixed typo in TTY structure field 'driver_name';
42 * Included a PCI bridge reset and EEPROM reload in the board
43 * initialization code (for both Y and Z series).
45 * Revision 2.2.2.1 1999/04/08 16:17:43 ivan
46 * Fixed a bug in cy_wait_until_sent that was preventing the port to be
47 * closed properly after a SIGINT;
48 * Module usage counter scheme revisited;
49 * Added support to the upcoming Y PCI boards (i.e., support to additional
50 * PCI Device ID's).
52 * Revision 2.2.1.10 1999/01/20 16:14:29 ivan
53 * Removed all unnecessary page-alignement operations in ioremap calls
54 * (ioremap is currently safe for these operations).
56 * Revision 2.2.1.9 1998/12/30 18:18:30 ivan
57 * Changed access to PLX PCI bridge registers from I/O to MMIO, in
58 * order to make PLX9050-based boards work with certain motherboards.
60 * Revision 2.2.1.8 1998/11/13 12:46:20 ivan
61 * cy_close function now resets (correctly) the tty->closing flag;
62 * JIFFIES_DIFF macro fixed.
64 * Revision 2.2.1.7 1998/09/03 12:07:28 ivan
65 * Fixed bug in cy_close function, which was not informing HW of
66 * which port should have the reception disabled before doing so;
67 * fixed Cyclom-8YoP hardware detection bug.
69 * Revision 2.2.1.6 1998/08/20 17:15:39 ivan
70 * Fixed bug in cy_close function, which causes malfunction
71 * of one of the first 4 ports when a higher port is closed
72 * (Cyclom-Y only).
74 * Revision 2.2.1.5 1998/08/10 18:10:28 ivan
75 * Fixed Cyclom-4Yo hardware detection bug.
77 * Revision 2.2.1.4 1998/08/04 11:02:50 ivan
78 * /proc/cyclades implementation with great collaboration of
79 * Marc Lewis <marc@blarg.net>;
80 * cyy_interrupt was changed to avoid occurence of kernel oopses
81 * during PPP operation.
83 * Revision 2.2.1.3 1998/06/01 12:09:10 ivan
84 * General code review in order to comply with 2.1 kernel standards;
85 * data loss prevention for slow devices revisited (cy_wait_until_sent
86 * was created);
87 * removed conditional compilation for new/old PCI structure support
88 * (now the driver only supports the new PCI structure).
90 * Revision 2.2.1.1 1998/03/19 16:43:12 ivan
91 * added conditional compilation for new/old PCI structure support;
92 * removed kernel series (2.0.x / 2.1.x) conditional compilation.
94 * Revision 2.1.1.3 1998/03/16 18:01:12 ivan
95 * cleaned up the data loss fix;
96 * fixed XON/XOFF handling once more (Cyclades-Z);
97 * general review of the driver routines;
98 * introduction of a mechanism to prevent data loss with slow
99 * printers, by forcing a delay before closing the port.
101 * Revision 2.1.1.2 1998/02/17 16:50:00 ivan
102 * fixed detection/handling of new CD1400 in Ye boards;
103 * fixed XON/XOFF handling (Cyclades-Z);
104 * fixed data loss caused by a premature port close;
105 * introduction of a flag that holds the CD1400 version ID per port
106 * (used by the CYGETCD1400VER new ioctl).
108 * Revision 2.1.1.1 1997/12/03 17:31:19 ivan
109 * Code review for the module cleanup routine;
110 * fixed RTS and DTR status report for new CD1400's in get_modem_info;
111 * includes anonymous changes regarding signal_pending.
113 * Revision 2.1 1997/11/01 17:42:41 ivan
114 * Changes in the driver to support Alpha systems (except 8Zo V_1);
115 * BREAK fix for the Cyclades-Z boards;
116 * driver inactivity control by FW implemented;
117 * introduction of flag that allows driver to take advantage of
118 * a special CD1400 feature related to HW flow control;
119 * added support for the CD1400 rev. J (Cyclom-Y boards);
120 * introduction of ioctls to:
121 * - control the rtsdtr_inv flag (Cyclom-Y);
122 * - control the rflow flag (Cyclom-Y);
123 * - adjust the polling interval (Cyclades-Z);
125 * Revision 1.36.4.33 1997/06/27 19:00:00 ivan
126 * Fixes related to kernel version conditional
127 * compilation.
129 * Revision 1.36.4.32 1997/06/14 19:30:00 ivan
130 * Compatibility issues between kernels 2.0.x and
131 * 2.1.x (mainly related to clear_bit function).
133 * Revision 1.36.4.31 1997/06/03 15:30:00 ivan
134 * Changes to define the memory window according to the
135 * board type.
137 * Revision 1.36.4.30 1997/05/16 15:30:00 daniel
138 * Changes to suport new cycladesZ boards.
140 * Revision 1.36.4.29 1997/05/12 11:30:00 daniel
141 * Merge of Bentson's and Daniel's version 1.36.4.28.
142 * Corrects bug in cy_detect_pci: check if there are more
143 * ports than the number of static structs allocated.
144 * Warning message during initialization if this driver is
145 * used with the new generation of cycladesZ boards. Those
146 * will be supported only in next release of the driver.
147 * Corrects bug in cy_detect_pci and cy_detect_isa that
148 * returned wrong number of VALID boards, when a cyclomY
149 * was found with no serial modules connected.
150 * Changes to use current (2.1.x) kernel subroutine names
151 * and created macros for compilation with 2.0.x kernel,
152 * instead of the other way around.
154 * Revision 1.36.4.28 1997/05/?? ??:00:00 bentson
155 * Change queue_task_irq_off to queue_task_irq.
156 * The inline function queue_task_irq_off (tqueue.h)
157 * was removed from latest releases of 2.1.x kernel.
158 * Use of macro __initfunc to mark the initialization
159 * routines, so memory can be reused.
160 * Also incorporate implementation of critical region
161 * in function cleanup_module() created by anonymous
162 * linuxer.
164 * Revision 1.36.4.28 1997/04/25 16:00:00 daniel
165 * Change to support new firmware that solves DCD problem:
166 * application could fail to receive SIGHUP signal when DCD
167 * varying too fast.
169 * Revision 1.36.4.27 1997/03/26 10:30:00 daniel
170 * Changed for suport linux versions 2.1.X.
171 * Backward compatible with linux versions 2.0.X.
172 * Corrected illegal use of filler field in
173 * CH_CTRL struct.
174 * Deleted some debug messages.
176 * Revision 1.36.4.26 1997/02/27 12:00:00 daniel
177 * Included check for NULL tty pointer in cyz_poll.
179 * Revision 1.36.4.25 1997/02/26 16:28:30 bentson
180 * Bill Foster at Blarg! Online services noticed that
181 * some of the switch elements of -Z modem control
182 * lacked a closing "break;"
184 * Revision 1.36.4.24 1997/02/24 11:00:00 daniel
185 * Changed low water threshold for buffer xmit_buf
187 * Revision 1.36.4.23 1996/12/02 21:50:16 bentson
188 * Marcio provided fix to modem status fetch for -Z
190 * Revision 1.36.4.22 1996/10/28 22:41:17 bentson
191 * improve mapping of -Z control page (thanks to Steve
192 * Price <stevep@fa.tdktca.com> for help on this)
194 * Revision 1.36.4.21 1996/09/10 17:00:10 bentson
195 * shift from CPU-bound to memcopy in cyz_polling operation
197 * Revision 1.36.4.20 1996/09/09 18:30:32 Bentson
198 * Added support to set and report higher speeds.
200 * Revision 1.36.4.19c 1996/08/09 10:00:00 Marcio Saito
201 * Some fixes in the HW flow control for the BETA release.
202 * Don't try to register the IRQ.
204 * Revision 1.36.4.19 1996/08/08 16:23:18 Bentson
205 * make sure "cyc" appears in all kernel messages; all soft interrupts
206 * handled by same routine; recognize out-of-band reception; comment
207 * out some diagnostic messages; leave RTS/CTS flow control to hardware;
208 * fix race condition in -Z buffer management; only -Y needs to explictly
209 * flush chars; tidy up some startup messages;
211 * Revision 1.36.4.18 1996/07/25 18:57:31 bentson
212 * shift MOD_INC_USE_COUNT location to match
213 * serial.c; purge some diagnostic messages;
215 * Revision 1.36.4.17 1996/07/25 18:01:08 bentson
216 * enable modem status messages and fetch & process them; note
217 * time of last activity type for each port; set_line_char now
218 * supports more than line 0 and treats 0 baud correctly;
219 * get_modem_info senses rs_status;
221 * Revision 1.36.4.16 1996/07/20 08:43:15 bentson
222 * barely works--now's time to turn on
223 * more features 'til it breaks
225 * Revision 1.36.4.15 1996/07/19 22:30:06 bentson
226 * check more -Z board status; shorten boot message
228 * Revision 1.36.4.14 1996/07/19 22:20:37 bentson
229 * fix reference to ch_ctrl in startup; verify return
230 * values from cyz_issue_cmd and cyz_update_channel;
231 * more stuff to get modem control correct;
233 * Revision 1.36.4.13 1996/07/11 19:53:33 bentson
234 * more -Z stuff folded in; re-order changes to put -Z stuff
235 * after -Y stuff (to make changes clearer)
237 * Revision 1.36.4.12 1996/07/11 15:40:55 bentson
238 * Add code to poll Cyclades-Z. Add code to get & set RS-232 control.
239 * Add code to send break. Clear firmware ID word at startup (so
240 * that other code won't talk to inactive board).
242 * Revision 1.36.4.11 1996/07/09 05:28:29 bentson
243 * add code for -Z in set_line_char
245 * Revision 1.36.4.10 1996/07/08 19:28:37 bentson
246 * fold more -Z stuff (or in some cases, error messages)
247 * into driver; add text to "don't know what to do" messages.
249 * Revision 1.36.4.9 1996/07/08 18:38:38 bentson
250 * moved compile-time flags near top of file; cosmetic changes
251 * to narrow text (to allow 2-up printing); changed many declarations
252 * to "static" to limit external symbols; shuffled code order to
253 * coalesce -Y and -Z specific code, also to put internal functions
254 * in order of tty_driver structure; added code to recognize -Z
255 * ports (and for moment, do nothing or report error); add cy_startup
256 * to parse boot command line for extra base addresses for ISA probes;
258 * Revision 1.36.4.8 1996/06/25 17:40:19 bentson
259 * reorder some code, fix types of some vars (int vs. long),
260 * add cy_setup to support user declared ISA addresses
262 * Revision 1.36.4.7 1996/06/21 23:06:18 bentson
263 * dump ioctl based firmware load (it's now a user level
264 * program); ensure uninitialzed ports cannot be used
266 * Revision 1.36.4.6 1996/06/20 23:17:19 bentson
267 * rename vars and restructure some code
269 * Revision 1.36.4.5 1996/06/14 15:09:44 bentson
270 * get right status back after boot load
272 * Revision 1.36.4.4 1996/06/13 19:51:44 bentson
273 * successfully loads firmware
275 * Revision 1.36.4.3 1996/06/13 06:08:33 bentson
276 * add more of the code for the boot/load ioctls
278 * Revision 1.36.4.2 1996/06/11 21:00:51 bentson
279 * start to add Z functionality--starting with ioctl
280 * for loading firmware
282 * Revision 1.36.4.1 1996/06/10 18:03:02 bentson
283 * added code to recognize Z/PCI card at initialization; report
284 * presence, but card is not initialized (because firmware needs
285 * to be loaded)
287 * Revision 1.36.3.8 1996/06/07 16:29:00 bentson
288 * starting minor number at zero; added missing verify_area
289 * as noted by Heiko Eissfeldt <heiko@colossus.escape.de>
291 * Revision 1.36.3.7 1996/04/19 21:06:18 bentson
292 * remove unneeded boot message & fix CLOCAL hardware flow
293 * control (Miquel van Smoorenburg <miquels@Q.cistron.nl>);
294 * remove unused diagnostic statements; minor 0 is first;
296 * Revision 1.36.3.6 1996/03/13 13:21:17 marcio
297 * The kernel function vremap (available only in later 1.3.xx kernels)
298 * allows the access to memory addresses above the RAM. This revision
299 * of the driver supports PCI boards below 1Mb (device id 0x100) and
300 * above 1Mb (device id 0x101).
302 * Revision 1.36.3.5 1996/03/07 15:20:17 bentson
303 * Some global changes to interrupt handling spilled into
304 * this driver--mostly unused arguments in system function
305 * calls. Also added change by Marcio Saito which should
306 * reduce lost interrupts at startup by fast processors.
308 * Revision 1.36.3.4 1995/11/13 20:45:10 bentson
309 * Changes by Corey Minyard <minyard@wf-rch.cirr.com> distributed
310 * in 1.3.41 kernel to remove a possible race condition, extend
311 * some error messages, and let the driver run as a loadable module
312 * Change by Alan Wendt <alan@ez0.ezlink.com> to remove a
313 * possible race condition.
314 * Change by Marcio Saito <marcio@cyclades.com> to fix PCI addressing.
316 * Revision 1.36.3.3 1995/11/13 19:44:48 bentson
317 * Changes by Linus Torvalds in 1.3.33 kernel distribution
318 * required due to reordering of driver initialization.
319 * Drivers are now initialized *after* memory management.
321 * Revision 1.36.3.2 1995/09/08 22:07:14 bentson
322 * remove printk from ISR; fix typo
324 * Revision 1.36.3.1 1995/09/01 12:00:42 marcio
325 * Minor fixes in the PCI board support. PCI function calls in
326 * conditional compilation (CONFIG_PCI). Thanks to Jim Duncan
327 * <duncan@okay.com>. "bad serial count" message removed.
329 * Revision 1.36.3 1995/08/22 09:19:42 marcio
330 * Cyclom-Y/PCI support added. Changes in the cy_init routine and
331 * board initialization. Changes in the boot messages. The driver
332 * supports up to 4 boards and 64 ports by default.
334 * Revision 1.36.1.4 1995/03/29 06:14:14 bentson
335 * disambiguate between Cyclom-16Y and Cyclom-32Ye;
337 * Revision 1.36.1.3 1995/03/23 22:15:35 bentson
338 * add missing break in modem control block in ioctl switch statement
339 * (discovered by Michael Edward Chastain <mec@jobe.shell.portal.com>);
341 * Revision 1.36.1.2 1995/03/22 19:16:22 bentson
342 * make sure CTS flow control is set as soon as possible (thanks
343 * to note from David Lambert <lambert@chesapeake.rps.slb.com>);
345 * Revision 1.36.1.1 1995/03/13 15:44:43 bentson
346 * initialize defaults for receive threshold and stale data timeout;
347 * cosmetic changes;
349 * Revision 1.36 1995/03/10 23:33:53 bentson
350 * added support of chips 4-7 in 32 port Cyclom-Ye;
351 * fix cy_interrupt pointer dereference problem
352 * (Joe Portman <baron@aa.net>);
353 * give better error response if open is attempted on non-existent port
354 * (Zachariah Vaum <jchryslr@netcom.com>);
355 * correct command timeout (Kenneth Lerman <lerman@@seltd.newnet.com>);
356 * conditional compilation for -16Y on systems with fast, noisy bus;
357 * comment out diagnostic print function;
358 * cleaned up table of base addresses;
359 * set receiver time-out period register to correct value,
360 * set receive threshold to better default values,
361 * set chip timer to more accurate 200 Hz ticking,
362 * add code to monitor and modify receive parameters
363 * (Rik Faith <faith@cs.unc.edu> Nick Simicich
364 * <njs@scifi.emi.net>);
366 * Revision 1.35 1994/12/16 13:54:18 steffen
367 * additional patch by Marcio Saito for board detection
368 * Accidently left out in 1.34
370 * Revision 1.34 1994/12/10 12:37:12 steffen
371 * This is the corrected version as suggested by Marcio Saito
373 * Revision 1.33 1994/12/01 22:41:18 bentson
374 * add hooks to support more high speeds directly; add tytso
375 * patch regarding CLOCAL wakeups
377 * Revision 1.32 1994/11/23 19:50:04 bentson
378 * allow direct kernel control of higher signalling rates;
379 * look for cards at additional locations
381 * Revision 1.31 1994/11/16 04:33:28 bentson
382 * ANOTHER fix from Corey Minyard, minyard@wf-rch.cirr.com--
383 * a problem in chars_in_buffer has been resolved by some
384 * small changes; this should yield smoother output
386 * Revision 1.30 1994/11/16 04:28:05 bentson
387 * Fix from Corey Minyard, Internet: minyard@metronet.com,
388 * UUCP: minyard@wf-rch.cirr.com, WORK: minyardbnr.ca, to
389 * cy_hangup that appears to clear up much (all?) of the
390 * DTR glitches; also he's added/cleaned-up diagnostic messages
392 * Revision 1.29 1994/11/16 04:16:07 bentson
393 * add change proposed by Ralph Sims, ralphs@halcyon.com, to
394 * operate higher speeds in same way as other serial ports;
395 * add more serial ports (for up to two 16-port muxes).
397 * Revision 1.28 1994/11/04 00:13:16 root
398 * turn off diagnostic messages
400 * Revision 1.27 1994/11/03 23:46:37 root
401 * bunch of changes to bring driver into greater conformance
402 * with the serial.c driver (looking for missed fixes)
404 * Revision 1.26 1994/11/03 22:40:36 root
405 * automatic interrupt probing fixed.
407 * Revision 1.25 1994/11/03 20:17:02 root
408 * start to implement auto-irq
410 * Revision 1.24 1994/11/03 18:01:55 root
411 * still working on modem signals--trying not to drop DTR
412 * during the getty/login processes
414 * Revision 1.23 1994/11/03 17:51:36 root
415 * extend baud rate support; set receive threshold as function
416 * of baud rate; fix some problems with RTS/CTS;
418 * Revision 1.22 1994/11/02 18:05:35 root
419 * changed arguments to udelay to type long to get
420 * delays to be of correct duration
422 * Revision 1.21 1994/11/02 17:37:30 root
423 * employ udelay (after calibrating loops_per_second earlier
424 * in init/main.c) instead of using home-grown delay routines
426 * Revision 1.20 1994/11/02 03:11:38 root
427 * cy_chars_in_buffer forces a return value of 0 to let
428 * login work (don't know why it does); some functions
429 * that were returning EFAULT, now executes the code;
430 * more work on deciding when to disable xmit interrupts;
432 * Revision 1.19 1994/11/01 20:10:14 root
433 * define routine to start transmission interrupts (by enabling
434 * transmit interrupts); directly enable/disable modem interrupts;
436 * Revision 1.18 1994/11/01 18:40:45 bentson
437 * Don't always enable transmit interrupts in startup; interrupt on
438 * TxMpty instead of TxRdy to help characters get out before shutdown;
439 * restructure xmit interrupt to check for chars first and quit if
440 * none are ready to go; modem status (MXVRx) is upright, _not_ inverted
441 * (to my view);
443 * Revision 1.17 1994/10/30 04:39:45 bentson
444 * rename serial_driver and callout_driver to cy_serial_driver and
445 * cy_callout_driver to avoid linkage interference; initialize
446 * info->type to PORT_CIRRUS; ruggedize paranoia test; elide ->port
447 * from cyclades_port structure; add paranoia check to cy_close;
449 * Revision 1.16 1994/10/30 01:14:33 bentson
450 * change major numbers; add some _early_ return statements;
452 * Revision 1.15 1994/10/29 06:43:15 bentson
453 * final tidying up for clean compile; enable some error reporting
455 * Revision 1.14 1994/10/28 20:30:22 Bentson
456 * lots of changes to drag the driver towards the new tty_io
457 * structures and operation. not expected to work, but may
458 * compile cleanly.
460 * Revision 1.13 1994/07/21 23:08:57 Bentson
461 * add some diagnostic cruft; support 24 lines (for testing
462 * both -8Y and -16Y cards; be more thorough in servicing all
463 * chips during interrupt; add "volatile" a few places to
464 * circumvent compiler optimizations; fix base & offset
465 * computations in block_til_ready (was causing chip 0 to
466 * stop operation)
468 * Revision 1.12 1994/07/19 16:42:11 Bentson
469 * add some hackery for kernel version 1.1.8; expand
470 * error messages; refine timing for delay loops and
471 * declare loop params volatile
473 * Revision 1.11 1994/06/11 21:53:10 bentson
474 * get use of save_car right in transmit interrupt service
476 * Revision 1.10.1.1 1994/06/11 21:31:18 bentson
477 * add some diagnostic printing; try to fix save_car stuff
479 * Revision 1.10 1994/06/11 20:36:08 bentson
480 * clean up compiler warnings
482 * Revision 1.9 1994/06/11 19:42:46 bentson
483 * added a bunch of code to support modem signalling
485 * Revision 1.8 1994/06/11 17:57:07 bentson
486 * recognize break & parity error
488 * Revision 1.7 1994/06/05 05:51:34 bentson
489 * Reorder baud table to be monotonic; add cli to CP; discard
490 * incoming characters and status if the line isn't open; start to
491 * fold code into cy_throttle; start to port get_serial_info,
492 * set_serial_info, get_modem_info, set_modem_info, and send_break
493 * from serial.c; expand cy_ioctl; relocate and expand config_setup;
494 * get flow control characters from tty struct; invalidate ports w/o
495 * hardware;
497 * Revision 1.6 1994/05/31 18:42:21 bentson
498 * add a loop-breaker in the interrupt service routine;
499 * note when port is initialized so that it can be shut
500 * down under the right conditions; receive works without
501 * any obvious errors
503 * Revision 1.5 1994/05/30 00:55:02 bentson
504 * transmit works without obvious errors
506 * Revision 1.4 1994/05/27 18:46:27 bentson
507 * incorporated more code from lib_y.c; can now print short
508 * strings under interrupt control to port zero; seems to
509 * select ports/channels/lines correctly
511 * Revision 1.3 1994/05/25 22:12:44 bentson
512 * shifting from multi-port on a card to proper multiplexor
513 * data structures; added skeletons of most routines
515 * Revision 1.2 1994/05/19 13:21:43 bentson
516 * start to crib from other sources
520 /* If you need to install more boards than NR_CARDS, change the constant
521 in the definition below. No other change is necessary to support up to
522 eight boards. Beyond that you'll have to extend cy_isa_addresses. */
524 #define NR_CARDS 4
527 If the total number of ports is larger than NR_PORTS, change this
528 constant in the definition below. No other change is necessary to
529 support more boards/ports. */
531 #define NR_PORTS 128
533 #define ZE_V1_NPORTS 64
534 #define ZO_V1 0
535 #define ZO_V2 1
536 #define ZE_V1 2
538 #define SERIAL_PARANOIA_CHECK
539 #undef CY_DEBUG_OPEN
540 #undef CY_DEBUG_THROTTLE
541 #undef CY_DEBUG_OTHER
542 #undef CY_DEBUG_IO
543 #undef CY_DEBUG_COUNT
544 #undef CY_DEBUG_DTR
545 #undef CY_DEBUG_WAIT_UNTIL_SENT
546 #undef CY_DEBUG_INTERRUPTS
547 #undef CY_16Y_HACK
548 #undef CY_ENABLE_MONITORING
549 #undef CY_PCI_DEBUG
550 #undef CY_PROC
552 #if 0
553 #define PAUSE __asm__("nop");
554 #else
555 #define PAUSE ;
556 #endif
558 #define cy_min(a,b) (((a)<(b))?(a):(b))
560 #if 0
561 /********
562 * For the next two macros, it is assumed that the buffer size is a
563 * power of 2
564 ********/
566 #define CHARS_IN_BUF(buf_ctrl) \
567 ((cy_readl(&buf_ctrl->rx_put) - \
568 cy_readl(&buf_ctrl->rx_get) + \
569 cy_readl(&buf_ctrl->rx_bufsize)) & \
570 (cy_readl(&buf_ctrl->rx_bufsize) - 1))
572 #define SPACE_IN_BUF(buf_ctrl) \
573 ((cy_readl(&buf_ctrl->tx_get) - \
574 cy_readl(&buf_ctrl->tx_put) + \
575 cy_readl(&buf_ctrl->tx_bufsize) - 1) & \
576 (cy_readl(&buf_ctrl->tx_bufsize) - 1))
577 #endif
580 * Include section
582 #include <linux/config.h>
583 #include <linux/module.h>
584 #include <linux/errno.h>
585 #include <linux/signal.h>
586 #include <linux/sched.h>
587 #include <linux/timer.h>
588 #include <linux/interrupt.h>
589 #include <linux/tty.h>
590 #include <linux/serial.h>
591 #include <linux/major.h>
592 #include <linux/string.h>
593 #include <linux/fcntl.h>
594 #include <linux/ptrace.h>
595 #include <linux/cyclades.h>
596 #include <linux/mm.h>
597 #include <linux/init.h>
598 #include <linux/delay.h>
600 #include <asm/system.h>
601 #include <asm/io.h>
602 #include <asm/irq.h>
603 #include <asm/uaccess.h>
604 #include <asm/bitops.h>
606 #include <linux/types.h>
607 #include <linux/kernel.h>
608 #include <linux/pci.h>
609 #include <linux/version.h>
611 #include <linux/stat.h>
612 #include <linux/proc_fs.h>
614 #ifdef CONFIG_COBALT_27
615 #include <asm/page.h>
616 #include <asm/pgtable.h>
618 #define CACHED_TO_UNCACHED(x) (((unsigned long)(x) & \
619 (unsigned long)0x1fffffff) + KSEG1)
620 #endif
622 #define cy_put_user put_user
624 static unsigned long cy_get_user(unsigned long *addr)
626 unsigned long result = 0;
627 int error = get_user (result, addr);
628 if (error)
629 printk ("cyclades: cy_get_user: error == %d\n", error);
630 return result;
633 #ifndef MIN
634 #define MIN(a,b) ((a) < (b) ? (a) : (b))
635 #endif
637 #define IS_CYC_Z(card) ((card).num_chips == -1)
639 #define Z_FPGA_CHECK(card) \
640 ((cy_readl(&((struct RUNTIME_9060 *) \
641 ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
643 #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 *) \
644 ((card).ctl_addr))->mail_box_0)) || \
645 Z_FPGA_CHECK(card)) && \
646 (ZFIRM_ID==cy_readl(&((struct FIRM_ID *) \
647 ((card).base_addr+ID_ADDRESS))->signature)))
649 #define WAKEUP_CHARS (SERIAL_XMIT_SIZE-256)
651 #define STD_COM_FLAGS (0)
653 #define JIFFIES_DIFF(n, j) ((j) - (n))
655 static DECLARE_TASK_QUEUE(tq_cyclades);
657 static struct tty_driver cy_serial_driver, cy_callout_driver;
658 static int serial_refcount;
660 #ifndef CONFIG_COBALT_27
661 static volatile int cy_irq_triggered;
662 static volatile int cy_triggered;
663 static int cy_wild_int_mask;
664 static volatile ucchar *intr_base_addr;
666 /* This is the address lookup table. The driver will probe for
667 Cyclom-Y/ISA boards at all addresses in here. If you want the
668 driver to probe addresses at a different address, add it to
669 this table. If the driver is probing some other board and
670 causing problems, remove the offending address from this table.
671 The cy_setup function extracts additional addresses from the
672 boot options line. The form is "cyclades=address,address..."
675 static unsigned char *cy_isa_addresses[] = {
676 (unsigned char *) 0xD0000,
677 (unsigned char *) 0xD2000,
678 (unsigned char *) 0xD4000,
679 (unsigned char *) 0xD6000,
680 (unsigned char *) 0xD8000,
681 (unsigned char *) 0xDA000,
682 (unsigned char *) 0xDC000,
683 (unsigned char *) 0xDE000,
684 0,0,0,0,0,0,0,0
686 #define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
688 #endif /* CONFIG_COBALT_27 */
690 /* This is the per-card data structure containing address, irq, number of
691 channels, etc. This driver supports a maximum of NR_CARDS cards.
693 static struct cyclades_card cy_card[NR_CARDS];
695 /* This is the per-channel data structure containing pointers, flags
696 and variables for the port. This driver supports a maximum of NR_PORTS.
698 static struct cyclades_port cy_port[NR_PORTS];
700 static int cy_next_channel = 0; /* next minor available */
702 static struct tty_struct *serial_table[NR_PORTS];
703 static struct termios *serial_termios[NR_PORTS];
704 static struct termios *serial_termios_locked[NR_PORTS];
707 * tmp_buf is used as a temporary buffer by serial_write. We need to
708 * lock it in case the copy_from_user blocks while swapping in a page,
709 * and some other program tries to do a serial write at the same time.
710 * Since the lock will only come under contention when the system is
711 * swapping and available memory is low, it makes sense to share one
712 * buffer across all the serial ports, since it significantly saves
713 * memory if large numbers of serial ports are open. This buffer is
714 * allocated when the first cy_open occurs.
716 static unsigned char *tmp_buf;
717 DECLARE_MUTEX(tmp_buf_sem);
720 * This is used to look up the divisor speeds and the timeouts
721 * We're normally limited to 15 distinct baud rates. The extra
722 * are accessed via settings in info->flags.
723 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
724 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
725 * HI VHI
726 * 20
728 static int baud_table[] = {
729 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
730 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,115200,150000,
731 230400, 0};
733 static char baud_co_25[] = { /* 25 MHz clock option table */
734 /* value => 00 01 02 03 04 */
735 /* divide by 8 32 128 512 2048 */
736 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
737 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
739 static char baud_bpr_25[] = { /* 25 MHz baud rate period table */
740 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
741 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15};
743 static char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */
744 /* value => 00 01 02 03 04 */
745 /* divide by 8 32 128 512 2048 */
746 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
747 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
748 0x00};
750 static char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */
751 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
752 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
753 0x21};
755 static char baud_cor3[] = { /* receive threshold */
756 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
757 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
758 0x07};
761 * The Cyclades driver implements HW flow control as any serial driver.
762 * The cyclades_port structure member rflow and the vector rflow_thr
763 * allows us to take advantage of a special feature in the CD1400 to avoid
764 * data loss even when the system interrupt latency is too high. These flags
765 * are to be used only with very special applications. Setting these flags
766 * requires the use of a special cable (DTR and RTS reversed). In the new
767 * CD1400-based boards (rev. 6.00 or later), there is no need for special
768 * cables.
771 static char rflow_thr[] = { /* rflow threshold */
772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
774 0x0a};
776 /* The Cyclom-Ye has placed the sequential chips in non-sequential
777 * address order. This look-up table overcomes that problem.
779 static int cy_chip_offset [] =
780 { 0x0000,
781 0x0400,
782 0x0800,
783 0x0C00,
784 0x0200,
785 0x0600,
786 0x0A00,
787 0x0E00
790 /* PCI related definitions */
792 static unsigned short cy_pci_nboard = 0;
793 static unsigned short cy_isa_nboard = 0;
794 static unsigned short cy_nboard = 0;
795 static unsigned short cy_pci_dev_id[] = {
796 PCI_DEVICE_ID_CYCLOM_Y_Lo, /* PCI < 1Mb */
797 PCI_DEVICE_ID_CYCLOM_Y_Hi, /* PCI > 1Mb */
798 PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */
799 PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */
800 PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */
801 PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */
802 PCI_DEVICE_ID_CYCLOM_Z_Lo, /* Z PCI < 1Mb */
803 PCI_DEVICE_ID_CYCLOM_Z_Hi, /* Z PCI > 1Mb */
804 0 /* end of table */
808 static void cy_start(struct tty_struct *);
809 static void set_line_char(struct cyclades_port *);
810 #ifndef CONFIG_COBALT_27
811 static void cy_probe(int, void *, struct pt_regs *);
812 #endif /* CONFIG_COBALT_27 */
813 static void cyz_poll(unsigned long);
814 #ifdef CYCLOM_SHOW_STATUS
815 static void show_status(int);
816 #endif
818 static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
820 /* The Cyclades-Z polling cycle is defined by this variable */
821 static long cyz_polling_cycle = CZ_DEF_POLL;
823 static int cyz_timeron = 0;
824 static struct timer_list
825 cyz_timerlist = {
826 NULL, NULL, 0, 0, cyz_poll
829 /**************************************************
830 error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
831 copy_to_user (to, from, count);
832 ***************************************************************
833 error = verify_area(VERIFY_READ, (void *) arg, sizeof(unsigned long *));
834 copy_from_user(to, from, count);
835 **************************************************/
838 static inline int
839 serial_paranoia_check(struct cyclades_port *info,
840 kdev_t device, const char *routine)
842 #ifdef SERIAL_PARANOIA_CHECK
843 static const char *badmagic =
844 "cyc Warning: bad magic number for serial struct (%s) in %s\n";
845 static const char *badinfo =
846 "cyc Warning: null cyclades_port for (%s) in %s\n";
847 static const char *badrange =
848 "cyc Warning: cyclades_port out of range for (%s) in %s\n";
850 if (!info) {
851 printk(badinfo, kdevname(device), routine);
852 return 1;
855 if( (long)info < (long)(&cy_port[0])
856 || (long)(&cy_port[NR_PORTS]) < (long)info ){
857 printk(badrange, kdevname(device), routine);
858 return 1;
861 if (info->magic != CYCLADES_MAGIC) {
862 printk(badmagic, kdevname(device), routine);
863 return 1;
865 #endif
866 return 0;
867 } /* serial_paranoia_check */
870 * This routine is used by the interrupt handler to schedule
871 * processing in the software interrupt portion of the driver
872 * (also known as the "bottom half"). This can be called any
873 * number of times for any channel without harm.
875 static inline void
876 cy_sched_event(struct cyclades_port *info, int event)
878 info->event |= 1 << event; /* remember what kind of event and who */
879 queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */
880 mark_bh(CYCLADES_BH); /* then trigger event */
881 } /* cy_sched_event */
885 * This routine is used to handle the "bottom half" processing for the
886 * serial driver, known also the "software interrupt" processing.
887 * This processing is done at the kernel interrupt level, after the
888 * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
889 * is where time-consuming activities which can not be done in the
890 * interrupt driver proper are done; the interrupt driver schedules
891 * them using cy_sched_event(), and they get done here.
893 * This is done through one level of indirection--the task queue.
894 * When a hardware interrupt service routine wants service by the
895 * driver's bottom half, it enqueues the appropriate tq_struct (one
896 * per port) to the tq_cyclades work queue and sets a request flag
897 * via mark_bh for processing that queue. When the time is right,
898 * do_cyclades_bh is called (because of the mark_bh) and it requests
899 * that the work queue be processed.
901 * Although this may seem unwieldy, it gives the system a way to
902 * pass an argument (in this case the pointer to the cyclades_port
903 * structure) to the bottom half of the driver. Previous kernels
904 * had to poll every port to see if that port needed servicing.
906 static void
907 do_cyclades_bh(void)
909 run_task_queue(&tq_cyclades);
910 } /* do_cyclades_bh */
912 static void
913 do_softint(void *private_)
915 struct cyclades_port *info = (struct cyclades_port *) private_;
916 struct tty_struct *tty;
918 tty = info->tty;
919 if (!tty)
920 return;
922 if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
923 tty_hangup(info->tty);
924 wake_up_interruptible(&info->open_wait);
925 info->flags &= ~(ASYNC_NORMAL_ACTIVE|
926 ASYNC_CALLOUT_ACTIVE);
928 if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
929 wake_up_interruptible(&info->open_wait);
931 if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
932 if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
933 && tty->ldisc.write_wakeup){
934 (tty->ldisc.write_wakeup)(tty);
936 wake_up_interruptible(&tty->write_wait);
938 #ifdef Z_WAKE
939 if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
940 wake_up_interruptible(&info->shutdown_wait);
942 #endif
943 } /* do_softint */
946 /***********************************************************/
947 /********* Start of block of Cyclom-Y specific code ********/
949 /* This routine waits up to 1000 micro-seconds for the previous
950 command to the Cirrus chip to complete and then issues the
951 new command. An error is returned if the previous command
952 didn't finish within the time limit.
954 static int
955 cyy_issue_cmd(volatile ucchar *base_addr, u_char cmd, int index)
957 unsigned long flags;
958 volatile int i;
960 save_flags(flags); cli();
961 /* Check to see that the previous command has completed */
962 for(i = 0 ; i < 100 ; i++){
963 if (cy_readb(base_addr+(CyCCR<<index)) == 0){
964 break;
966 udelay(10L);
968 /* if the CCR never cleared, the previous command
969 didn't finish within the "reasonable time" */
970 if ( i == 100 ) {
971 restore_flags(flags);
972 return (-1);
975 /* Issue the new command */
976 cy_writeb((u_long)base_addr+(CyCCR<<index), cmd);
977 restore_flags(flags);
978 return(0);
979 } /* cyy_issue_cmd */
981 #ifndef CONFIG_COBALT_27 /* ISA interrupt detection code */
983 static int probe_ready;
986 * Grab all interrupts in preparation for doing an automatic irq
987 * detection. dontgrab is a mask of irq's _not_ to grab. Returns a
988 * mask of irq's which were grabbed and should therefore be freed
989 * using free_all_interrupts().
991 static int
992 grab_all_interrupts(int dontgrab)
994 int irq_lines = 0;
995 int i, mask;
997 for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
998 if (!(mask & dontgrab)
999 && !request_irq(i, cy_probe,
1000 SA_INTERRUPT, "serial probe", NULL)) {
1001 irq_lines |= mask;
1004 return irq_lines;
1005 } /* grab_all_interrupts */
1008 * Release all interrupts grabbed by grab_all_interrupts
1010 static void
1011 free_all_interrupts(int irq_lines)
1013 int i;
1015 for (i = 0; i < 16; i++) {
1016 if (irq_lines & (1 << i)) {
1017 free_irq(i,NULL);
1020 } /* free_all_interrupts */
1023 * This routine returns a bitfield of "wild interrupts". Basically,
1024 * any unclaimed interrupts which is flapping around.
1026 static int
1027 check_wild_interrupts(void)
1029 int i, mask;
1030 int wild_interrupts = 0;
1031 int irq_lines;
1032 unsigned long timeout;
1033 unsigned long flags;
1035 /*Turn on interrupts (they may be off) */
1036 save_flags(flags); sti();
1038 irq_lines = grab_all_interrupts(0);
1041 * Delay for 0.1 seconds -- we use a busy loop since this may
1042 * occur during the bootup sequence
1044 timeout = jiffies+(HZ/10);
1045 while (time_after_eq(timeout, jiffies))
1048 cy_triggered = 0; /* Reset after letting things settle */
1050 timeout = jiffies+(HZ/10);
1051 while (time_after_eq(timeout, jiffies))
1054 for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
1055 if ((cy_triggered & (1 << i)) &&
1056 (irq_lines & (1 << i))) {
1057 wild_interrupts |= mask;
1060 free_all_interrupts(irq_lines);
1061 restore_flags(flags);
1062 return wild_interrupts;
1063 } /* check_wild_interrupts */
1066 * This routine is called by do_auto_irq(); it attempts to determine
1067 * which interrupt a serial port is configured to use. It is not
1068 * fool-proof, but it works a large part of the time.
1070 static int
1071 get_auto_irq(volatile ucchar *address)
1073 unsigned long timeout;
1074 volatile ucchar *base_addr;
1075 int index;
1076 unsigned long flags;
1078 index = 0; /* IRQ probing is only for ISA */
1079 base_addr = address;
1080 intr_base_addr = address;
1083 * Enable interrupts and see who answers
1085 cy_irq_triggered = 0;
1086 save_flags(flags); cli();
1087 cy_writeb((u_long)base_addr+(CyCAR<<index), 0);
1088 cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_XMTR,index);
1089 cy_writeb((u_long)base_addr+(CySRER<<index),
1090 cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
1091 probe_ready = 1;
1092 restore_flags(flags);
1094 timeout = jiffies+(HZ/50);
1095 while (time_after_eq(timeout, jiffies)) {
1096 if (cy_irq_triggered)
1097 break;
1099 probe_ready = 0;
1100 return(cy_irq_triggered);
1101 } /* get_auto_irq */
1104 * Calls get_auto_irq() multiple times, to make sure we don't get
1105 * faked out by random interrupts
1107 static int
1108 do_auto_irq(volatile ucchar *address)
1110 int irq_lines = 0;
1111 int irq_try_1 = 0, irq_try_2 = 0;
1112 int retries;
1113 unsigned long flags;
1115 /* Turn on interrupts (they may be off) */
1116 save_flags(flags); sti();
1118 probe_ready = 0;
1120 cy_wild_int_mask = check_wild_interrupts();
1122 irq_lines = grab_all_interrupts(cy_wild_int_mask);
1124 for (retries = 0; retries < 5; retries++) {
1125 if (!irq_try_1)
1126 irq_try_1 = get_auto_irq(address);
1127 if (!irq_try_2)
1128 irq_try_2 = get_auto_irq(address);
1129 if (irq_try_1 && irq_try_2) {
1130 if (irq_try_1 == irq_try_2)
1131 break;
1132 irq_try_1 = irq_try_2 = 0;
1135 restore_flags(flags);
1136 free_all_interrupts(irq_lines);
1137 return (irq_try_1 == irq_try_2) ? irq_try_1 : 0;
1138 } /* do_auto_irq */
1142 * This interrupt routine is used
1143 * while we are probing for submarines.
1145 static void
1146 cy_probe(int irq, void *dev_id, struct pt_regs *regs)
1148 int save_xir, save_car;
1149 int index = 0; /* probing interrupts is only for ISA */
1151 if (!probe_ready) {
1152 cy_writeb((u_long)intr_base_addr+(Cy_ClrIntr<<index), 0);
1153 return;
1156 cy_irq_triggered = irq;
1157 cy_triggered |= 1 << irq;
1159 if(cy_readb(intr_base_addr+(CySVRR<<index)) != 0) {
1160 save_xir = (u_char) cy_readb(intr_base_addr+(CyTIR<<index));
1161 save_car = cy_readb(intr_base_addr+(CyCAR<<index));
1162 cy_writeb((u_long)intr_base_addr+(CyCAR<<index), (save_xir & 0x3));
1163 cy_writeb((u_long)intr_base_addr+(CySRER<<index),
1164 cy_readb(intr_base_addr+(CySRER<<index)) & ~CyTxMpty);
1165 cy_writeb((u_long)intr_base_addr+(CyTIR<<index), (save_xir & 0x3f));
1166 cy_writeb((u_long)intr_base_addr+(CyCAR<<index), (save_car));
1168 cy_writeb((u_long)intr_base_addr+(Cy_ClrIntr<<index), 0);
1169 /* Cy_ClrIntr is 0x1800 */
1170 return;
1171 } /* cy_probe */
1173 #endif /* CONFIG_COBALT_27 */
1175 /* The real interrupt service routine is called
1176 whenever the card wants its hand held--chars
1177 received, out buffer empty, modem change, etc.
1179 static void
1180 cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1182 struct tty_struct *tty;
1183 int status;
1184 struct cyclades_card *cinfo;
1185 struct cyclades_port *info;
1186 volatile unsigned char *base_addr, *card_base_addr;
1187 int chip;
1188 int save_xir, channel, save_car;
1189 char data;
1190 volatile int char_count;
1191 int outch;
1192 int i,j,index;
1193 int too_many;
1194 int had_work;
1195 int mdm_change;
1196 int mdm_status;
1198 if((cinfo = (struct cyclades_card *)dev_id) == 0){
1199 #ifdef CY_DEBUG_INTERRUPTS
1200 printk("cy_interrupt: spurious interrupt %d\n\r", irq);
1201 #endif
1202 return; /* spurious interrupt */
1205 card_base_addr = (unsigned char *)cinfo->base_addr;
1206 index = cinfo->bus_index;
1209 /* This loop checks all chips in the card. Make a note whenever
1210 _any_ chip had some work to do, as this is considered an
1211 indication that there will be more to do. Only when no chip
1212 has any work does this outermost loop exit.
1215 had_work = 0;
1216 for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) {
1217 base_addr = (unsigned char *)
1218 (cinfo->base_addr + (cy_chip_offset[chip]<<index));
1219 too_many = 0;
1220 while ( (status = cy_readb(base_addr+(CySVRR<<index))) != 0x00) {
1221 had_work++;
1222 /* The purpose of the following test is to ensure that
1223 no chip can monopolize the driver. This forces the
1224 chips to be checked in a round-robin fashion (after
1225 draining each of a bunch (1000) of characters).
1227 if(1000<too_many++){
1228 break;
1230 if (status & CySRReceive) { /* reception interrupt */
1231 #ifdef CY_DEBUG_INTERRUPTS
1232 printk("cy_interrupt: rcvd intr, chip %d\n\r", chip);
1233 #endif
1234 /* determine the channel & change to that context */
1235 save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
1236 channel = (u_short ) (save_xir & CyIRChannel);
1237 i = channel + chip * 4 + cinfo->first_line;
1238 info = &cy_port[i];
1239 info->last_active = jiffies;
1240 save_car = cy_readb(base_addr+(CyCAR<<index));
1241 cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1243 /* if there is nowhere to put the data, discard it */
1244 if(info->tty == 0){
1245 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1246 if ( j == CyIVRRxEx ) { /* exception */
1247 data = cy_readb(base_addr+(CyRDSR<<index));
1248 } else { /* normal character reception */
1249 char_count = cy_readb(base_addr+(CyRDCR<<index));
1250 while(char_count--){
1251 data = cy_readb(base_addr+(CyRDSR<<index));
1254 }else{ /* there is an open port for this data */
1255 tty = info->tty;
1256 j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1257 if ( j == CyIVRRxEx ) { /* exception */
1258 data = cy_readb(base_addr+(CyRDSR<<index));
1259 if(data & info->ignore_status_mask){
1260 continue;
1262 if (tty->flip.count < TTY_FLIPBUF_SIZE){
1263 tty->flip.count++;
1264 if (data & info->read_status_mask){
1265 if(data & CyBREAK){
1266 *tty->flip.flag_buf_ptr++ =
1267 TTY_BREAK;
1268 *tty->flip.char_buf_ptr++ =
1269 cy_readb(base_addr+(CyRDSR<<index));
1270 if (info->flags & ASYNC_SAK){
1271 do_SAK(tty);
1273 }else if(data & CyFRAME){
1274 *tty->flip.flag_buf_ptr++ =
1275 TTY_FRAME;
1276 *tty->flip.char_buf_ptr++ =
1277 cy_readb(base_addr+(CyRDSR<<index));
1278 info->idle_stats.frame_errs++;
1279 }else if(data & CyPARITY){
1280 *tty->flip.flag_buf_ptr++ =
1281 TTY_PARITY;
1282 *tty->flip.char_buf_ptr++ =
1283 cy_readb(base_addr+(CyRDSR<<index));
1284 info->idle_stats.parity_errs++;
1285 }else if(data & CyOVERRUN){
1286 *tty->flip.flag_buf_ptr++ =
1287 TTY_OVERRUN;
1288 *tty->flip.char_buf_ptr++ = 0;
1289 /* If the flip buffer itself is
1290 overflowing, we still lose
1291 the next incoming character.
1293 if(tty->flip.count
1294 < TTY_FLIPBUF_SIZE){
1295 tty->flip.count++;
1296 *tty->flip.flag_buf_ptr++ =
1297 TTY_NORMAL;
1298 *tty->flip.char_buf_ptr++ =
1299 cy_readb(base_addr+(CyRDSR<<index));
1301 info->idle_stats.overruns++;
1302 /* These two conditions may imply */
1303 /* a normal read should be done. */
1304 /* }else if(data & CyTIMEOUT){ */
1305 /* }else if(data & CySPECHAR){ */
1306 }else{
1307 *tty->flip.flag_buf_ptr++ = 0;
1308 *tty->flip.char_buf_ptr++ = 0;
1310 }else{
1311 *tty->flip.flag_buf_ptr++ = 0;
1312 *tty->flip.char_buf_ptr++ = 0;
1314 }else{
1315 /* there was a software buffer
1316 overrun and nothing could be
1317 done about it!!! */
1318 info->idle_stats.overruns++;
1320 } else { /* normal character reception */
1321 /* load # chars available from the chip */
1322 char_count = cy_readb(base_addr+(CyRDCR<<index));
1324 #ifdef CY_ENABLE_MONITORING
1325 ++info->mon.int_count;
1326 info->mon.char_count += char_count;
1327 if (char_count > info->mon.char_max)
1328 info->mon.char_max = char_count;
1329 info->mon.char_last = char_count;
1330 #endif
1331 info->idle_stats.recv_bytes += char_count;
1332 info->idle_stats.recv_idle = jiffies;
1333 while(char_count--){
1334 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1335 break;
1337 tty->flip.count++;
1338 data = cy_readb(base_addr+(CyRDSR<<index));
1339 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1340 *tty->flip.char_buf_ptr++ = data;
1341 #ifdef CY_16Y_HACK
1342 udelay(10L);
1343 #endif
1346 queue_task(&tty->flip.tqueue, &tq_timer);
1348 /* end of service */
1349 cy_writeb((u_long)base_addr+(CyRIR<<index), (save_xir & 0x3f));
1350 cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1354 if (status & CySRTransmit) { /* transmission interrupt */
1355 /* Since we only get here when the transmit buffer
1356 is empty, we know we can always stuff a dozen
1357 characters. */
1358 #ifdef CY_DEBUG_INTERRUPTS
1359 printk("cy_interrupt: xmit intr, chip %d\n\r", chip);
1360 #endif
1362 /* determine the channel & change to that context */
1363 save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index));
1364 channel = (u_short ) (save_xir & CyIRChannel);
1365 i = channel + chip * 4 + cinfo->first_line;
1366 save_car = cy_readb(base_addr+(CyCAR<<index));
1367 cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1369 /* validate the port# (as configured and open) */
1370 if( (i < 0) || (NR_PORTS <= i) ){
1371 cy_writeb((u_long)base_addr+(CySRER<<index),
1372 cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
1373 goto txend;
1375 info = &cy_port[i];
1376 info->last_active = jiffies;
1377 if(info->tty == 0){
1378 cy_writeb((u_long)base_addr+(CySRER<<index),
1379 cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
1380 goto txdone;
1383 /* load the on-chip space for outbound data */
1384 char_count = info->xmit_fifo_size;
1387 if(info->x_char) { /* send special char */
1388 outch = info->x_char;
1389 cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1390 char_count--;
1391 info->x_char = 0;
1394 if (info->breakon || info->breakoff) {
1395 if (info->breakon) {
1396 cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
1397 cy_writeb((u_long)base_addr + (CyTDR<<index), 0x81);
1398 info->breakon = 0;
1399 char_count -= 2;
1401 if (info->breakoff) {
1402 cy_writeb((u_long)base_addr + (CyTDR<<index), 0);
1403 cy_writeb((u_long)base_addr + (CyTDR<<index), 0x83);
1404 info->breakoff = 0;
1405 char_count -= 2;
1409 while (char_count-- > 0){
1410 if (!info->xmit_cnt){
1411 cy_writeb((u_long)base_addr+(CySRER<<index),
1412 cy_readb(base_addr+(CySRER<<index)) &
1413 ~CyTxMpty);
1414 goto txdone;
1416 if (info->xmit_buf == 0){
1417 cy_writeb((u_long)base_addr+(CySRER<<index),
1418 cy_readb(base_addr+(CySRER<<index)) &
1419 ~CyTxMpty);
1420 goto txdone;
1422 if (info->tty->stopped || info->tty->hw_stopped){
1423 cy_writeb((u_long)base_addr+(CySRER<<index),
1424 cy_readb(base_addr+(CySRER<<index)) &
1425 ~CyTxMpty);
1426 goto txdone;
1428 /* Because the Embedded Transmit Commands have
1429 been enabled, we must check to see if the
1430 escape character, NULL, is being sent. If it
1431 is, we must ensure that there is room for it
1432 to be doubled in the output stream. Therefore
1433 we no longer advance the pointer when the
1434 character is fetched, but rather wait until
1435 after the check for a NULL output character.
1436 This is necessary because there may not be
1437 room for the two chars needed to send a NULL.)
1439 outch = info->xmit_buf[info->xmit_tail];
1440 if( outch ){
1441 info->xmit_cnt--;
1442 info->xmit_tail = (info->xmit_tail + 1)
1443 & (SERIAL_XMIT_SIZE - 1);
1444 cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1445 }else{
1446 if(char_count > 1){
1447 info->xmit_cnt--;
1448 info->xmit_tail = (info->xmit_tail + 1)
1449 & (SERIAL_XMIT_SIZE - 1);
1450 cy_writeb((u_long)base_addr+(CyTDR<<index),
1451 outch);
1452 cy_writeb((u_long)base_addr+(CyTDR<<index), 0);
1453 char_count--;
1454 }else{
1459 txdone:
1460 if (info->xmit_cnt < WAKEUP_CHARS) {
1461 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1463 txend:
1464 /* end of service */
1465 cy_writeb((u_long)base_addr+(CyTIR<<index),
1466 (save_xir & 0x3f));
1467 cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1470 if (status & CySRModem) { /* modem interrupt */
1472 /* determine the channel & change to that context */
1473 save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));
1474 channel = (u_short ) (save_xir & CyIRChannel);
1475 info = &cy_port[channel + chip * 4
1476 + cinfo->first_line];
1477 info->last_active = jiffies;
1478 save_car = cy_readb(base_addr+(CyCAR<<index));
1479 cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1481 mdm_change = cy_readb(base_addr+(CyMISR<<index));
1482 mdm_status = cy_readb(base_addr+(CyMSVR1<<index));
1484 if(info->tty == 0){/* no place for data, ignore it*/
1486 }else{
1487 if((mdm_change & CyDCD)
1488 && (info->flags & ASYNC_CHECK_CD)){
1489 if(mdm_status & CyDCD){
1490 cy_sched_event(info,
1491 Cy_EVENT_OPEN_WAKEUP);
1492 }else if(!((info->flags
1493 & ASYNC_CALLOUT_ACTIVE)
1494 &&(info->flags
1495 & ASYNC_CALLOUT_NOHUP))){
1496 cy_sched_event(info,
1497 Cy_EVENT_HANGUP);
1500 if((mdm_change & CyCTS)
1501 && (info->flags & ASYNC_CTS_FLOW)){
1502 if(info->tty->hw_stopped){
1503 if(mdm_status & CyCTS){
1504 /* cy_start isn't used
1505 because... !!! */
1506 info->tty->hw_stopped = 0;
1507 cy_writeb((u_long)base_addr+(CySRER<<index),
1508 cy_readb(base_addr+(CySRER<<index)) |
1509 CyTxMpty);
1510 cy_sched_event(info,
1511 Cy_EVENT_WRITE_WAKEUP);
1513 }else{
1514 if(!(mdm_status & CyCTS)){
1515 /* cy_stop isn't used
1516 because ... !!! */
1517 info->tty->hw_stopped = 1;
1518 cy_writeb((u_long)base_addr+(CySRER<<index),
1519 cy_readb(base_addr+(CySRER<<index)) &
1520 ~CyTxMpty);
1524 if(mdm_status & CyDSR){
1526 if(mdm_status & CyRI){
1529 /* end of service */
1530 cy_writeb((u_long)base_addr+(CyMIR<<index),
1531 (save_xir & 0x3f));
1532 cy_writeb((u_long)base_addr+(CyCAR<<index), save_car);
1534 } /* end while status != 0 */
1535 } /* end loop for chips... */
1536 } while(had_work);
1538 /* clear interrupts */
1539 cy_writeb((u_long)card_base_addr + (Cy_ClrIntr<<index), 0);
1540 /* Cy_ClrIntr is 0x1800 */
1541 } /* cyy_interrupt */
1543 /***********************************************************/
1544 /********* End of block of Cyclom-Y specific code **********/
1545 /******** Start of block of Cyclades-Z specific code *********/
1546 /***********************************************************/
1549 static int
1550 cyz_fetch_msg( struct cyclades_card *cinfo,
1551 uclong *channel, ucchar *cmd, uclong *param)
1553 struct FIRM_ID *firm_id;
1554 struct ZFW_CTRL *zfw_ctrl;
1555 struct BOARD_CTRL *board_ctrl;
1556 unsigned long loc_doorbell;
1558 firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1559 if (!ISZLOADED(*cinfo)){
1560 return (-1);
1562 zfw_ctrl = (struct ZFW_CTRL *)
1563 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1564 board_ctrl = &zfw_ctrl->board_ctrl;
1566 loc_doorbell = cy_readl(&((struct RUNTIME_9060 *)
1567 (cinfo->ctl_addr))->loc_doorbell);
1568 if (loc_doorbell){
1569 *cmd = (char)(0xff & loc_doorbell);
1570 *channel = cy_readl(&board_ctrl->fwcmd_channel);
1571 *param = (uclong)cy_readl(&board_ctrl->fwcmd_param);
1572 cy_writel(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->loc_doorbell,
1573 0xffffffff);
1574 return 1;
1576 return 0;
1577 } /* cyz_fetch_msg */
1580 static int
1581 cyz_issue_cmd( struct cyclades_card *cinfo,
1582 uclong channel, ucchar cmd, uclong param)
1584 struct FIRM_ID *firm_id;
1585 struct ZFW_CTRL *zfw_ctrl;
1586 struct BOARD_CTRL *board_ctrl;
1587 volatile uclong *pci_doorbell;
1588 int index;
1590 firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1591 if (!ISZLOADED(*cinfo)){
1592 return (-1);
1594 zfw_ctrl = (struct ZFW_CTRL *)
1595 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1596 board_ctrl = &zfw_ctrl->board_ctrl;
1598 index = 0;
1599 pci_doorbell = (uclong *)(&((struct RUNTIME_9060 *)
1600 (cinfo->ctl_addr))->pci_doorbell);
1601 while( (cy_readl(pci_doorbell) & 0xff) != 0){
1602 if (index++ == 1000){
1603 return(-1);
1605 udelay(50L);
1607 cy_writel((u_long)&board_ctrl->hcmd_channel, channel);
1608 cy_writel((u_long)&board_ctrl->hcmd_param , param);
1609 cy_writel((u_long)pci_doorbell, (long)cmd);
1611 return(0);
1612 } /* cyz_issue_cmd */
1615 #if 0
1616 static int
1617 cyz_update_channel( struct cyclades_card *cinfo,
1618 u_long channel, u_char mode, u_char cmd)
1620 struct FIRM_ID *firm_id =
1621 (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1622 struct ZFW_CTRL *zfw_ctrl;
1623 struct CH_CTRL *ch_ctrl;
1625 if (!ISZLOADED(*cinfo)){
1626 return (-1);
1628 zfw_ctrl = (struct ZFW_CTRL *)
1629 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1630 ch_ctrl = zfw_ctrl->ch_ctrl;
1632 cy_writel(&ch_ctrl[channel].op_mode, (uclong)mode);
1634 return cyz_issue_cmd(cinfo, channel, cmd, 0L);
1636 } /* cyz_update_channel */
1637 #endif
1640 static void
1641 cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1643 } /* cyz_interrupt */
1646 static void
1647 cyz_poll(unsigned long arg)
1649 static volatile struct FIRM_ID *firm_id;
1650 static volatile struct ZFW_CTRL *zfw_ctrl;
1651 static volatile struct BOARD_CTRL *board_ctrl;
1652 static volatile struct CH_CTRL *ch_ctrl;
1653 static volatile struct BUF_CTRL *buf_ctrl;
1654 struct cyclades_card *cinfo;
1655 struct cyclades_port *info;
1656 struct tty_struct *tty;
1657 int card, port;
1658 int char_count;
1659 #ifdef BLOCKMOVE
1660 int small_count;
1661 #endif
1662 char data;
1663 uclong channel;
1664 ucchar cmd;
1665 uclong param;
1666 uclong hw_ver, fw_ver;
1667 volatile uclong tx_put, tx_get, tx_bufsize;
1668 volatile uclong rx_put, rx_get, rx_bufsize;
1670 cyz_timerlist.expires = jiffies + (HZ);
1671 for (card = 0 ; card < NR_CARDS ; card++){
1672 cinfo = &cy_card[card];
1673 if (!IS_CYC_Z(*cinfo)) continue;
1676 firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1677 if (!ISZLOADED(*cinfo)) {
1678 cinfo->inact_ctrl = 0;
1679 continue;
1682 zfw_ctrl = (struct ZFW_CTRL *)
1683 (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
1684 board_ctrl = &(zfw_ctrl->board_ctrl);
1685 fw_ver = cy_readl(&board_ctrl->fw_version);
1686 hw_ver = cy_readl(&((struct RUNTIME_9060 *)
1687 (cinfo->ctl_addr))->mail_box_0);
1689 /* Enables the firmware inactivity control */
1690 if ((fw_ver > 0x00000310L) && (!cinfo->inact_ctrl)) {
1691 param = cyz_issue_cmd( &cy_card[card], 0L, C_CM_TINACT, 0L);
1692 cinfo->inact_ctrl = 1;
1695 while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1){
1696 char_count = 0;
1697 info = &cy_port[ channel + cinfo->first_line ];
1698 if((tty = info->tty) == 0) continue;
1699 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1700 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1701 info->jiffies[0] = jiffies;
1703 switch(cmd){
1704 case C_CM_PR_ERROR:
1705 tty->flip.count++;
1706 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
1707 *tty->flip.char_buf_ptr++ = 0;
1708 char_count++;
1709 break;
1710 case C_CM_FR_ERROR:
1711 tty->flip.count++;
1712 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
1713 *tty->flip.char_buf_ptr++ = 0;
1714 char_count++;
1715 break;
1716 case C_CM_RXBRK:
1717 tty->flip.count++;
1718 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
1719 *tty->flip.char_buf_ptr++ = 0;
1720 char_count++;
1721 break;
1722 case C_CM_MDCD:
1723 if (info->flags & ASYNC_CHECK_CD){
1724 if ((fw_ver > 241 ?
1725 ((u_long)param) :
1726 cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
1727 cy_sched_event(info,
1728 Cy_EVENT_OPEN_WAKEUP);
1729 }else if(!((info->flags
1730 & ASYNC_CALLOUT_ACTIVE)
1731 &&(info->flags
1732 & ASYNC_CALLOUT_NOHUP))){
1733 cy_sched_event(info,
1734 Cy_EVENT_HANGUP);
1737 break;
1738 case C_CM_MCTS:
1739 if (info->flags & ASYNC_CTS_FLOW) {
1740 if(info->tty->hw_stopped){
1741 if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
1742 /* cy_start isn't used because...
1743 HW flow is handled by the board */
1744 cy_sched_event(info,
1745 Cy_EVENT_WRITE_WAKEUP);
1747 }else{
1748 if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
1749 /* cy_stop isn't used because
1750 HW flow is handled by the board */
1754 break;
1755 case C_CM_MRI:
1756 break;
1757 case C_CM_MDSR:
1758 break;
1759 #ifdef Z_WAKE
1760 case C_CM_IOCTLW:
1761 cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
1762 break;
1763 #endif
1764 case C_CM_FATAL:
1765 /* should do something with this !!! */
1766 break;
1768 if(char_count){
1769 queue_task(&tty->flip.tqueue, &tq_timer);
1772 for (port = 0; port < cy_readl(&board_ctrl->n_channel); port++){
1773 info = &cy_port[ port + cinfo->first_line ];
1774 tty = info->tty;
1775 ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
1776 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
1778 /* Removed due to compilation problems in Alpha systems */
1779 // if ((char_count = CHARS_IN_BUF(buf_ctrl))){
1781 rx_get = cy_readl(&buf_ctrl->rx_get);
1782 rx_put = cy_readl(&buf_ctrl->rx_put);
1783 rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
1784 if (rx_put >= rx_get)
1785 char_count = rx_put - rx_get;
1786 else
1787 char_count = rx_put - rx_get + rx_bufsize;
1789 if ( char_count ){
1791 info->last_active = jiffies;
1792 info->jiffies[1] = jiffies;
1794 #ifdef CY_ENABLE_MONITORING
1795 info->mon.int_count++;
1796 info->mon.char_count += char_count;
1797 if (char_count > info->mon.char_max)
1798 info->mon.char_max = char_count;
1799 info->mon.char_last = char_count;
1800 #endif
1801 info->idle_stats.recv_bytes += char_count;
1802 info->idle_stats.recv_idle = jiffies;
1803 if( tty == 0){
1804 /* flush received characters */
1805 rx_get = (rx_get + char_count) & (rx_bufsize - 1);
1806 info->rflush_count++;
1807 }else{
1808 #ifdef BLOCKMOVE
1809 /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
1810 for performance, but because of buffer boundaries, there
1811 may be several steps to the operation */
1812 while(0 < (small_count
1813 = cy_min((rx_bufsize - rx_get),
1814 cy_min((TTY_FLIPBUF_SIZE - tty->flip.count),
1815 char_count)))){
1817 memcpy_fromio(tty->flip.char_buf_ptr,
1818 (char *)(cinfo->base_addr
1819 + cy_readl(&buf_ctrl->rx_bufaddr)
1820 + rx_get),
1821 small_count);
1823 tty->flip.char_buf_ptr += small_count;
1824 memset(tty->flip.flag_buf_ptr,
1825 TTY_NORMAL,
1826 small_count);
1827 tty->flip.flag_buf_ptr += small_count;
1828 rx_get = (rx_get + small_count) & (rx_bufsize - 1);
1829 char_count -= small_count;
1830 tty->flip.count += small_count;
1832 #else
1833 while(char_count--){
1834 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1835 break;
1837 data = cy_readb(cinfo->base_addr +
1838 cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
1839 rx_get = (rx_get + 1) & (rx_bufsize - 1);
1840 tty->flip.count++;
1841 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1842 *tty->flip.char_buf_ptr++ = data;
1844 #endif
1845 queue_task(&tty->flip.tqueue, &tq_timer);
1847 /* Update rx_get */
1848 cy_writel(&buf_ctrl->rx_get, rx_get);
1851 /* Removed due to compilation problems in Alpha systems */
1852 // if ((char_count = SPACE_IN_BUF(buf_ctrl))){
1854 tx_get = cy_readl(&buf_ctrl->tx_get);
1855 tx_put = cy_readl(&buf_ctrl->tx_put);
1856 tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
1857 if (tx_put >= tx_get)
1858 char_count = tx_get - tx_put - 1 + tx_bufsize;
1859 else
1860 char_count = tx_get - tx_put - 1;
1862 if ( char_count ){
1864 if( tty == 0 ){
1865 goto ztxdone;
1868 if(info->x_char) { /* send special char */
1869 data = info->x_char;
1871 cy_writeb((cinfo->base_addr +
1872 cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
1873 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1874 info->x_char = 0;
1875 char_count--;
1876 info->last_active = jiffies;
1877 info->jiffies[2] = jiffies;
1879 #ifdef BLOCKMOVE
1880 while(0 < (small_count
1881 = cy_min((tx_bufsize - tx_put),
1882 cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
1883 cy_min(info->xmit_cnt, char_count))))){
1885 memcpy_toio((char *)(cinfo->base_addr
1886 + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
1887 &info->xmit_buf[info->xmit_tail],
1888 small_count);
1890 tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1891 char_count -= small_count;
1892 info->xmit_cnt -= small_count;
1893 info->xmit_tail =
1894 (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
1895 info->last_active = jiffies;
1896 info->jiffies[2] = jiffies;
1898 #else
1899 while (info->xmit_cnt && char_count){
1900 data = info->xmit_buf[info->xmit_tail];
1901 info->xmit_cnt--;
1902 info->xmit_tail =
1903 (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
1905 cy_writeb(cinfo->base_addr +
1906 cy_readl(&buf_ctrl->tx_bufaddr) + tx_put,
1907 data);
1908 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1909 char_count--;
1910 info->last_active = jiffies;
1911 info->jiffies[2] = jiffies;
1914 #endif
1915 ztxdone:
1916 if (info->xmit_cnt < WAKEUP_CHARS) {
1917 cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1919 /* Update tx_put */
1920 cy_writel(&buf_ctrl->tx_put, tx_put);
1923 /* poll every 40 ms */
1924 cyz_timerlist.expires = jiffies + cyz_polling_cycle;
1926 /* refresh inactivity counter */
1927 if (cinfo->inact_ctrl) {
1928 cy_writel(&board_ctrl->inactivity, (uclong) ZF_TINACT);
1931 add_timer(&cyz_timerlist);
1933 return;
1934 } /* cyz_poll */
1937 /********** End of block of Cyclades-Z specific code *********/
1938 /***********************************************************/
1941 /* This is called whenever a port becomes active;
1942 interrupts are enabled and DTR & RTS are turned on.
1944 static int
1945 startup(struct cyclades_port * info)
1947 unsigned long flags;
1948 int retval = 0;
1949 unsigned char *base_addr;
1950 int card,chip,channel,index;
1951 unsigned long page;
1953 page = get_free_page(GFP_KERNEL);
1954 if (!page)
1955 return -ENOMEM;
1957 save_flags(flags); cli();
1959 if (info->flags & ASYNC_INITIALIZED){
1960 free_page(page);
1961 goto errout;
1964 if (!info->type){
1965 if (info->tty){
1966 set_bit(TTY_IO_ERROR, &info->tty->flags);
1968 free_page(page);
1969 goto errout;
1972 if (info->xmit_buf)
1973 free_page(page);
1974 else
1975 info->xmit_buf = (unsigned char *) page;
1977 set_line_char(info);
1979 card = info->card;
1980 channel = (info->line) - (cy_card[card].first_line);
1981 if (!IS_CYC_Z(cy_card[card])) {
1982 chip = channel>>2;
1983 channel &= 0x03;
1984 index = cy_card[card].bus_index;
1985 base_addr = (unsigned char*)
1986 (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
1988 #ifdef CY_DEBUG_OPEN
1989 printk("cyc startup card %d, chip %d, channel %d, base_addr %lx\n",
1990 card, chip, channel, (long)base_addr);/**/
1991 #endif
1993 cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
1995 cy_writeb((ulong)base_addr+(CyRTPR<<index), (info->default_timeout
1996 ? info->default_timeout : 0x02)); /* 10ms rx timeout */
1998 cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index);
2000 cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2001 cy_writeb((ulong)base_addr+(CyMSVR1<<index), CyRTS);
2002 cy_writeb((ulong)base_addr+(CyMSVR2<<index), CyDTR);
2004 #ifdef CY_DEBUG_DTR
2005 printk("cyc:startup raising DTR\n");
2006 printk(" status: 0x%x, 0x%x\n",
2007 cy_readb(base_addr+(CyMSVR1<<index)),
2008 cy_readb(base_addr+(CyMSVR2<<index)));
2009 #endif
2011 cy_writeb((u_long)base_addr+(CySRER<<index),
2012 cy_readb(base_addr+(CySRER<<index)) | CyRxData);
2013 info->flags |= ASYNC_INITIALIZED;
2015 if (info->tty){
2016 clear_bit(TTY_IO_ERROR, &info->tty->flags);
2018 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2019 info->breakon = info->breakoff = 0;
2020 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2021 info->idle_stats.in_use =
2022 info->idle_stats.recv_idle =
2023 info->idle_stats.xmit_idle = jiffies;
2025 restore_flags(flags);
2027 } else {
2028 struct FIRM_ID *firm_id;
2029 struct ZFW_CTRL *zfw_ctrl;
2030 struct BOARD_CTRL *board_ctrl;
2031 struct CH_CTRL *ch_ctrl;
2032 int retval;
2034 restore_flags(flags);
2036 base_addr = (unsigned char*) (cy_card[card].base_addr);
2038 firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2039 if (!ISZLOADED(cy_card[card])){
2040 return -ENODEV;
2043 zfw_ctrl =
2044 (struct ZFW_CTRL *)
2045 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
2046 board_ctrl = &zfw_ctrl->board_ctrl;
2047 ch_ctrl = zfw_ctrl->ch_ctrl;
2049 #ifdef CY_DEBUG_OPEN
2050 printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
2051 card, channel, (long)base_addr);/**/
2052 #endif
2054 cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
2055 #ifdef Z_WAKE
2056 cy_writel(&ch_ctrl[channel].intr_enable,
2057 C_IN_MDCD|C_IN_MCTS|C_IN_IOCTLW);
2058 #else
2059 cy_writel(&ch_ctrl[channel].intr_enable,
2060 C_IN_MDCD|C_IN_MCTS);
2061 #endif
2062 retval = cyz_issue_cmd( &cy_card[card],
2063 channel, C_CM_IOCTL, 0L); /* was C_CM_RESET */
2064 if (retval != 0){
2065 printk("cyc:startup(1) retval was %x\n", retval);
2068 /* set timeout !!! */
2069 /* set RTS and DTR !!! */
2070 cy_writel(&ch_ctrl[channel].rs_control,
2071 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR) ;
2072 retval = cyz_issue_cmd(&cy_card[info->card],
2073 channel, C_CM_IOCTLM, 0L);
2074 if (retval != 0){
2075 printk("cyc:startup(2) retval was %x\n", retval);
2077 #ifdef CY_DEBUG_DTR
2078 printk("cyc:startup raising Z DTR\n");
2079 #endif
2081 /* enable send, recv, modem !!! */
2083 info->flags |= ASYNC_INITIALIZED;
2084 if (info->tty){
2085 clear_bit(TTY_IO_ERROR, &info->tty->flags);
2087 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2088 info->breakon = info->breakoff = 0;
2089 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2090 info->idle_stats.in_use =
2091 info->idle_stats.recv_idle =
2092 info->idle_stats.xmit_idle = jiffies;
2095 #ifdef CY_DEBUG_OPEN
2096 printk(" cyc startup done\n");
2097 #endif
2098 return 0;
2100 errout:
2101 restore_flags(flags);
2102 return retval;
2103 } /* startup */
2106 static void
2107 start_xmit( struct cyclades_port *info )
2109 unsigned long flags;
2110 unsigned char *base_addr;
2111 int card,chip,channel,index;
2113 card = info->card;
2114 channel = (info->line) - (cy_card[card].first_line);
2115 if (!IS_CYC_Z(cy_card[card])) {
2116 chip = channel>>2;
2117 channel &= 0x03;
2118 index = cy_card[card].bus_index;
2119 base_addr = (unsigned char*)
2120 (cy_card[card].base_addr
2121 + (cy_chip_offset[chip]<<index));
2123 save_flags(flags); cli();
2124 cy_writeb((u_long)base_addr+(CyCAR<<index), channel);
2125 cy_writeb((u_long)base_addr+(CySRER<<index),
2126 cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
2127 restore_flags(flags);
2128 } else {
2129 /* Don't have to do anything at this time */
2131 } /* start_xmit */
2135 * This routine shuts down a serial port; interrupts are disabled,
2136 * and DTR is dropped if the hangup on close termio flag is on.
2138 static void
2139 shutdown(struct cyclades_port * info)
2141 unsigned long flags;
2142 unsigned char *base_addr;
2143 int card,chip,channel,index;
2145 if (!(info->flags & ASYNC_INITIALIZED)){
2146 return;
2149 card = info->card;
2150 channel = info->line - cy_card[card].first_line;
2151 if (!IS_CYC_Z(cy_card[card])) {
2152 chip = channel>>2;
2153 channel &= 0x03;
2154 index = cy_card[card].bus_index;
2155 base_addr = (unsigned char*)
2156 (cy_card[card].base_addr
2157 + (cy_chip_offset[chip]<<index));
2159 #ifdef CY_DEBUG_OPEN
2160 printk("cyc shutdown Y card %d, chip %d, channel %d, base_addr %lx\n",
2161 card, chip, channel, (long)base_addr);
2162 #endif
2164 save_flags(flags); cli();
2166 if (info->xmit_buf){
2167 unsigned char * temp;
2168 temp = info->xmit_buf;
2169 info->xmit_buf = 0;
2170 free_page((unsigned long) temp);
2172 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2173 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2174 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
2175 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
2176 #ifdef CY_DEBUG_DTR
2177 printk("cyc shutdown dropping DTR\n");
2178 printk(" status: 0x%x, 0x%x\n",
2179 cy_readb(base_addr+(CyMSVR1<<index)),
2180 cy_readb(base_addr+(CyMSVR2<<index)));
2181 #endif
2183 cyy_issue_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR,index);
2184 /* it may be appropriate to clear _XMIT at
2185 some later date (after testing)!!! */
2187 if (info->tty){
2188 set_bit(TTY_IO_ERROR, &info->tty->flags);
2190 info->flags &= ~ASYNC_INITIALIZED;
2191 restore_flags(flags);
2192 } else {
2193 struct FIRM_ID *firm_id;
2194 struct ZFW_CTRL *zfw_ctrl;
2195 struct BOARD_CTRL *board_ctrl;
2196 struct CH_CTRL *ch_ctrl;
2197 int retval;
2199 base_addr = (unsigned char*) (cy_card[card].base_addr);
2200 #ifdef CY_DEBUG_OPEN
2201 printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
2202 card, channel, (long)base_addr);
2203 #endif
2205 firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2206 if (!ISZLOADED(cy_card[card])) {
2207 return;
2210 zfw_ctrl =
2211 (struct ZFW_CTRL *)
2212 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
2213 board_ctrl = &(zfw_ctrl->board_ctrl);
2214 ch_ctrl = zfw_ctrl->ch_ctrl;
2216 save_flags(flags); cli();
2218 if (info->xmit_buf){
2219 unsigned char * temp;
2220 temp = info->xmit_buf;
2221 info->xmit_buf = 0;
2222 free_page((unsigned long) temp);
2225 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2226 cy_writel((u_long)&ch_ctrl[channel].rs_control,
2227 (uclong)(cy_readl(&ch_ctrl[channel].rs_control) &
2228 ~(C_RS_RTS | C_RS_DTR)));
2229 retval = cyz_issue_cmd(&cy_card[info->card],
2230 channel, C_CM_IOCTLM, 0L);
2231 if (retval != 0){
2232 printk("cyc:shutdown retval (2) was %x\n", retval);
2234 #ifdef CY_DEBUG_DTR
2235 printk("cyc:shutdown dropping Z DTR\n");
2236 #endif
2239 if (info->tty){
2240 set_bit(TTY_IO_ERROR, &info->tty->flags);
2242 info->flags &= ~ASYNC_INITIALIZED;
2244 restore_flags(flags);
2247 #ifdef CY_DEBUG_OPEN
2248 printk(" cyc shutdown done\n");
2249 #endif
2250 return;
2251 } /* shutdown */
2255 * ------------------------------------------------------------
2256 * cy_open() and friends
2257 * ------------------------------------------------------------
2260 static int
2261 block_til_ready(struct tty_struct *tty, struct file * filp,
2262 struct cyclades_port *info)
2264 DECLARE_WAITQUEUE(wait, current);
2265 struct cyclades_card *cinfo;
2266 unsigned long flags;
2267 int chip, channel,index;
2268 int retval;
2269 char *base_addr;
2272 * If the device is in the middle of being closed, then block
2273 * until it's done, and then try again.
2275 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2276 if (info->flags & ASYNC_CLOSING) {
2277 interruptible_sleep_on(&info->close_wait);
2279 return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2283 * If this is a callout device, then just make sure the normal
2284 * device isn't being used.
2286 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
2287 if (info->flags & ASYNC_NORMAL_ACTIVE){
2288 return -EBUSY;
2290 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2291 (info->flags & ASYNC_SESSION_LOCKOUT) &&
2292 (info->session != current->session)){
2293 return -EBUSY;
2295 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2296 (info->flags & ASYNC_PGRP_LOCKOUT) &&
2297 (info->pgrp != current->pgrp)){
2298 return -EBUSY;
2300 info->flags |= ASYNC_CALLOUT_ACTIVE;
2301 return 0;
2305 * If non-blocking mode is set, then make the check up front
2306 * and then exit.
2308 if ((filp->f_flags & O_NONBLOCK) ||
2309 (tty->flags & (1 << TTY_IO_ERROR))) {
2310 if (info->flags & ASYNC_CALLOUT_ACTIVE){
2311 return -EBUSY;
2313 info->flags |= ASYNC_NORMAL_ACTIVE;
2314 return 0;
2318 * Block waiting for the carrier detect and the line to become
2319 * free (i.e., not in use by the callout). While we are in
2320 * this loop, info->count is dropped by one, so that
2321 * cy_close() knows when to free things. We restore it upon
2322 * exit, either normal or abnormal.
2324 retval = 0;
2325 add_wait_queue(&info->open_wait, &wait);
2326 #ifdef CY_DEBUG_OPEN
2327 printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
2328 info->line, info->count);/**/
2329 #endif
2330 save_flags(flags); cli();
2331 if (!tty_hung_up_p(filp))
2332 info->count--;
2333 restore_flags(flags);
2334 #ifdef CY_DEBUG_COUNT
2335 printk("cyc block_til_ready: (%d): decrementing count to %d\n",
2336 current->pid, info->count);
2337 #endif
2338 info->blocked_open++;
2340 cinfo = &cy_card[info->card];
2341 channel = info->line - cinfo->first_line;
2342 if (!IS_CYC_Z(*cinfo)) {
2343 chip = channel>>2;
2344 channel &= 0x03;
2345 index = cinfo->bus_index;
2346 base_addr = (char *)(cinfo->base_addr
2347 + (cy_chip_offset[chip]<<index));
2349 while (1) {
2350 save_flags(flags); cli();
2351 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
2352 (tty->termios->c_cflag & CBAUD)){
2353 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2354 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
2355 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
2356 #ifdef CY_DEBUG_DTR
2357 printk("cyc:block_til_ready raising DTR\n");
2358 printk(" status: 0x%x, 0x%x\n",
2359 cy_readb(base_addr+(CyMSVR1<<index)),
2360 cy_readb(base_addr+(CyMSVR2<<index)));
2361 #endif
2363 restore_flags(flags);
2364 current->state = TASK_INTERRUPTIBLE;
2365 if (tty_hung_up_p(filp)
2366 || !(info->flags & ASYNC_INITIALIZED) ){
2367 return ((info->flags & ASYNC_HUP_NOTIFY) ?
2368 -EAGAIN : -ERESTARTSYS);
2369 break;
2371 save_flags(flags); cli();
2372 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2373 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2374 && !(info->flags & ASYNC_CLOSING)
2375 && (C_CLOCAL(tty)
2376 || (cy_readb(base_addr+(CyMSVR1<<index)) & CyDCD))) {
2377 restore_flags(flags);
2378 break;
2380 restore_flags(flags);
2381 if (signal_pending(current)) {
2382 retval = -ERESTARTSYS;
2383 break;
2385 #ifdef CY_DEBUG_OPEN
2386 printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2387 info->line, info->count);/**/
2388 #endif
2389 schedule();
2391 } else {
2392 struct FIRM_ID *firm_id;
2393 struct ZFW_CTRL *zfw_ctrl;
2394 struct BOARD_CTRL *board_ctrl;
2395 struct CH_CTRL *ch_ctrl;
2396 int retval;
2398 base_addr = (char *)(cinfo->base_addr);
2399 firm_id = (struct FIRM_ID *)
2400 (base_addr + ID_ADDRESS);
2401 if (!ISZLOADED(*cinfo)){
2402 return -EINVAL;
2405 zfw_ctrl =
2406 (struct ZFW_CTRL *)
2407 (base_addr + cy_readl(&firm_id->zfwctrl_addr));
2408 board_ctrl = &zfw_ctrl->board_ctrl;
2409 ch_ctrl = zfw_ctrl->ch_ctrl;
2411 while (1) {
2412 cy_writel(&ch_ctrl[channel].rs_control,
2413 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR);
2414 retval = cyz_issue_cmd(&cy_card[info->card],
2415 channel, C_CM_IOCTLM, 0L);
2416 if (retval != 0){
2417 printk("cyc:block_til_ready retval was %x\n", retval);
2419 #ifdef CY_DEBUG_DTR
2420 printk("cyc:block_til_ready raising Z DTR\n");
2421 #endif
2423 current->state = TASK_INTERRUPTIBLE;
2424 if (tty_hung_up_p(filp)
2425 || !(info->flags & ASYNC_INITIALIZED) ){
2426 return ((info->flags & ASYNC_HUP_NOTIFY) ?
2427 -EAGAIN : -ERESTARTSYS);
2428 break;
2430 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2431 && !(info->flags & ASYNC_CLOSING)
2432 && (C_CLOCAL(tty)
2433 || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) {
2434 break;
2436 if (signal_pending(current)) {
2437 retval = -ERESTARTSYS;
2438 break;
2440 #ifdef CY_DEBUG_OPEN
2441 printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2442 info->line, info->count);/**/
2443 #endif
2444 schedule();
2447 current->state = TASK_RUNNING;
2448 remove_wait_queue(&info->open_wait, &wait);
2449 if (!tty_hung_up_p(filp)){
2450 info->count++;
2451 #ifdef CY_DEBUG_COUNT
2452 printk("cyc:block_til_ready (%d): incrementing count to %d\n",
2453 current->pid, info->count);
2454 #endif
2456 info->blocked_open--;
2457 #ifdef CY_DEBUG_OPEN
2458 printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
2459 info->line, info->count);/**/
2460 #endif
2461 if (retval)
2462 return retval;
2463 info->flags |= ASYNC_NORMAL_ACTIVE;
2464 return 0;
2465 } /* block_til_ready */
2469 * This routine is called whenever a serial port is opened. It
2470 * performs the serial-specific initialization for the tty structure.
2472 static int
2473 cy_open(struct tty_struct *tty, struct file * filp)
2475 struct cyclades_port *info;
2476 int retval, line;
2477 unsigned long page;
2479 MOD_INC_USE_COUNT;
2480 line = MINOR(tty->device) - tty->driver.minor_start;
2481 if ((line < 0) || (NR_PORTS <= line)){
2482 MOD_DEC_USE_COUNT;
2483 return -ENODEV;
2485 info = &cy_port[line];
2486 if (info->line < 0){
2487 MOD_DEC_USE_COUNT;
2488 return -ENODEV;
2491 /* If the card's firmware hasn't been loaded,
2492 treat it as absent from the system. This
2493 will make the user pay attention.
2495 if (IS_CYC_Z(cy_card[info->card])) {
2496 if (!ISZLOADED(cy_card[info->card])) {
2497 if (((ZE_V1 ==cy_readl(&((struct RUNTIME_9060 *)
2498 ((cy_card[info->card]).ctl_addr))->mail_box_0)) &&
2499 Z_FPGA_CHECK(cy_card[info->card])) &&
2500 (ZFIRM_HLT==cy_readl(&((struct FIRM_ID *)
2501 ((cy_card[info->card]).base_addr+ID_ADDRESS))->signature)))
2503 printk ("cyc:Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
2504 } else {
2505 printk("cyc:Cyclades-Z firmware not yet loaded\n");
2507 return -ENODEV;
2510 #ifdef CY_DEBUG_OTHER
2511 printk("cyc:cy_open ttyC%d\n", info->line); /* */
2512 #endif
2513 tty->driver_data = info;
2514 info->tty = tty;
2515 if (serial_paranoia_check(info, tty->device, "cy_open")){
2516 return -ENODEV;
2518 #ifdef CY_DEBUG_OPEN
2519 printk("cyc:cy_open ttyC%d, count = %d\n",
2520 info->line, info->count);/**/
2521 #endif
2522 info->count++;
2523 #ifdef CY_DEBUG_COUNT
2524 printk("cyc:cy_open (%d): incrementing count to %d\n",
2525 current->pid, info->count);
2526 #endif
2527 if (!tmp_buf) {
2528 page = get_free_page(GFP_KERNEL);
2529 if (!page)
2530 return -ENOMEM;
2531 if (tmp_buf)
2532 free_page(page);
2533 else
2534 tmp_buf = (unsigned char *) page;
2538 * If the port is the middle of closing, bail out now
2540 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2541 if (info->flags & ASYNC_CLOSING)
2542 interruptible_sleep_on(&info->close_wait);
2543 return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2547 * Start up serial port
2549 retval = startup(info);
2550 if (retval){
2551 return retval;
2554 retval = block_til_ready(tty, filp, info);
2555 if (retval) {
2556 #ifdef CY_DEBUG_OPEN
2557 printk("cyc:cy_open returning after block_til_ready with %d\n",
2558 retval);
2559 #endif
2560 return retval;
2563 if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
2564 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
2565 *tty->termios = info->normal_termios;
2566 else
2567 *tty->termios = info->callout_termios;
2570 info->session = current->session;
2571 info->pgrp = current->pgrp;
2573 #ifdef CY_DEBUG_OPEN
2574 printk(" cyc:cy_open done\n");/**/
2575 #endif
2577 return 0;
2578 } /* cy_open */
2582 * cy_wait_until_sent() --- wait until the transmitter is empty
2584 static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2586 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2587 unsigned char *base_addr;
2588 int card,chip,channel,index;
2589 unsigned long orig_jiffies, char_time;
2591 if (serial_paranoia_check(info, tty->device, "cy_wait_until_sent"))
2592 return;
2594 if (info->xmit_fifo_size == 0)
2595 return; /* Just in case.... */
2598 orig_jiffies = jiffies;
2600 * Set the check interval to be 1/5 of the estimated time to
2601 * send a single character, and make it at least 1. The check
2602 * interval should also be less than the timeout.
2604 * Note: we have to use pretty tight timings here to satisfy
2605 * the NIST-PCTS.
2607 char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
2608 char_time = char_time / 5;
2609 if (char_time == 0)
2610 char_time = 1;
2611 if (timeout < 0)
2612 timeout = 0;
2613 if (timeout)
2614 char_time = MIN(char_time, timeout);
2616 * If the transmitter hasn't cleared in twice the approximate
2617 * amount of time to send the entire FIFO, it probably won't
2618 * ever clear. This assumes the UART isn't doing flow
2619 * control, which is currently the case. Hence, if it ever
2620 * takes longer than info->timeout, this is probably due to a
2621 * UART bug of some kind. So, we clamp the timeout parameter at
2622 * 2*info->timeout.
2624 if (!timeout || timeout > 2*info->timeout)
2625 timeout = 2*info->timeout;
2626 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2627 printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
2628 printk("jiff=%lu...", jiffies);
2629 #endif
2630 card = info->card;
2631 channel = (info->line) - (cy_card[card].first_line);
2632 if (!IS_CYC_Z(cy_card[card])) {
2633 chip = channel>>2;
2634 channel &= 0x03;
2635 index = cy_card[card].bus_index;
2636 base_addr = (unsigned char *)
2637 (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
2638 while (cy_readb(base_addr+(CySRER<<index)) & CyTxMpty) {
2639 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2640 printk("Not clean (jiff=%lu)...", jiffies);
2641 #endif
2642 current->state = TASK_INTERRUPTIBLE;
2643 schedule_timeout(char_time);
2644 if (signal_pending(current))
2645 break;
2646 if (timeout && time_after(jiffies, orig_jiffies + timeout))
2647 break;
2649 current->state = TASK_RUNNING;
2650 } else {
2651 // Nothing to do!
2653 /* Run one more char cycle */
2654 current->state = TASK_INTERRUPTIBLE;
2655 schedule_timeout(char_time * 5);
2656 current->state = TASK_RUNNING;
2657 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2658 printk("Clean (jiff=%lu)...done\n", jiffies);
2659 #endif
2663 * This routine is called when a particular tty device is closed.
2665 static void
2666 cy_close(struct tty_struct * tty, struct file * filp)
2668 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2669 unsigned long flags;
2671 #ifdef CY_DEBUG_OTHER
2672 printk("cyc:cy_close ttyC%d\n", info->line);
2673 #endif
2675 if (!info || serial_paranoia_check(info, tty->device, "cy_close")){
2676 return;
2679 save_flags(flags); cli();
2681 /* If the TTY is being hung up, nothing to do */
2682 if (tty_hung_up_p(filp)) {
2683 MOD_DEC_USE_COUNT;
2684 restore_flags(flags);
2685 return;
2688 #ifdef CY_DEBUG_OPEN
2689 printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
2690 #endif
2691 if ((tty->count == 1) && (info->count != 1)) {
2693 * Uh, oh. tty->count is 1, which means that the tty
2694 * structure will be freed. Info->count should always
2695 * be one in these conditions. If it's greater than
2696 * one, we've got real problems, since it means the
2697 * serial port won't be shutdown.
2699 printk("cyc:cy_close: bad serial port count; tty->count is 1, "
2700 "info->count is %d\n", info->count);
2701 info->count = 1;
2703 #ifdef CY_DEBUG_COUNT
2704 printk("cyc:cy_close at (%d): decrementing count to %d\n",
2705 current->pid, info->count - 1);
2706 #endif
2707 if (--info->count < 0) {
2708 #ifdef CY_DEBUG_COUNT
2709 printk("cyc:cyc_close setting count to 0\n");
2710 #endif
2711 info->count = 0;
2713 if (info->count) {
2714 MOD_DEC_USE_COUNT;
2715 restore_flags(flags);
2716 return;
2718 info->flags |= ASYNC_CLOSING;
2720 * Save the termios structure, since this port may have
2721 * separate termios for callout and dialin.
2723 if (info->flags & ASYNC_NORMAL_ACTIVE)
2724 info->normal_termios = *tty->termios;
2725 if (info->flags & ASYNC_CALLOUT_ACTIVE)
2726 info->callout_termios = *tty->termios;
2729 * Now we wait for the transmit buffer to clear; and we notify
2730 * the line discipline to only process XON/XOFF characters.
2732 tty->closing = 1;
2733 if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
2734 tty_wait_until_sent(tty, info->closing_wait);
2737 if (!IS_CYC_Z(cy_card[info->card])) {
2738 int channel = info->line - cy_card[info->card].first_line;
2739 int index = cy_card[info->card].bus_index;
2740 unsigned char *base_addr = (unsigned char *)
2741 (cy_card[info->card].base_addr +
2742 (cy_chip_offset[channel>>2] <<index));
2743 /* Stop accepting input */
2744 channel &= 0x03;
2745 cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2746 cy_writeb((u_long)base_addr+(CySRER<<index),
2747 cy_readb(base_addr+(CySRER<<index)) & ~CyRxData);
2748 if (info->flags & ASYNC_INITIALIZED) {
2749 /* Waiting for on-board buffers to be empty before closing
2750 the port */
2751 cy_wait_until_sent(tty, info->timeout);
2753 } else {
2754 #ifdef Z_WAKE
2755 /* Waiting for on-board buffers to be empty before closing the port */
2756 unsigned char *base_addr = (unsigned char *)
2757 cy_card[info->card].base_addr;
2758 struct FIRM_ID *firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2759 struct ZFW_CTRL *zfw_ctrl =
2760 (struct ZFW_CTRL *) (base_addr + cy_readl(&firm_id->zfwctrl_addr));
2761 struct CH_CTRL *ch_ctrl = zfw_ctrl->ch_ctrl;
2762 int channel = info->line - cy_card[info->card].first_line;
2763 int retval;
2765 if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
2766 retval = cyz_issue_cmd(&cy_card[info->card], channel,
2767 C_CM_IOCTLW, 0L);
2768 if (retval != 0){
2769 printk("cyc:shutdown retval (1) was %x\n", retval);
2771 interruptible_sleep_on(&info->shutdown_wait);
2773 #endif
2776 shutdown(info);
2777 if (tty->driver.flush_buffer)
2778 tty->driver.flush_buffer(tty);
2779 if (tty->ldisc.flush_buffer)
2780 tty->ldisc.flush_buffer(tty);
2781 tty->closing = 0;
2782 info->event = 0;
2783 info->tty = 0;
2784 if (info->blocked_open) {
2785 if (info->close_delay) {
2786 current->state = TASK_INTERRUPTIBLE;
2787 schedule_timeout(info->close_delay);
2789 wake_up_interruptible(&info->open_wait);
2791 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
2792 ASYNC_CLOSING);
2793 wake_up_interruptible(&info->close_wait);
2795 #ifdef CY_DEBUG_OTHER
2796 printk(" cyc:cy_close done\n");
2797 #endif
2799 MOD_DEC_USE_COUNT;
2800 restore_flags(flags);
2801 return;
2802 } /* cy_close */
2805 /* This routine gets called when tty_write has put something into
2806 * the write_queue. The characters may come from user space or
2807 * kernel space.
2809 * This routine will return the number of characters actually
2810 * accepted for writing.
2812 * If the port is not already transmitting stuff, start it off by
2813 * enabling interrupts. The interrupt service routine will then
2814 * ensure that the characters are sent.
2815 * If the port is already active, there is no need to kick it.
2818 static int
2819 cy_write(struct tty_struct * tty, int from_user,
2820 const unsigned char *buf, int count)
2822 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
2823 unsigned long flags;
2824 int c, ret = 0;
2826 #ifdef CY_DEBUG_IO
2827 printk("cyc:cy_write ttyC%d\n", info->line); /* */
2828 #endif
2830 if (serial_paranoia_check(info, tty->device, "cy_write")){
2831 return 0;
2834 if (!tty || !info->xmit_buf || !tmp_buf){
2835 return 0;
2838 save_flags(flags);
2840 if (from_user) {
2841 down(&tmp_buf_sem);
2842 while (1) {
2843 c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
2844 SERIAL_XMIT_SIZE - info->xmit_head));
2845 if (c <= 0)
2846 break;
2848 c -= copy_from_user(tmp_buf, buf, c);
2849 if (!c) {
2850 if (!ret) {
2851 ret = -EFAULT;
2853 break;
2855 cli();
2856 c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
2857 SERIAL_XMIT_SIZE - info->xmit_head));
2858 memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
2859 info->xmit_head = ((info->xmit_head + c) & (SERIAL_XMIT_SIZE-1));
2860 info->xmit_cnt += c;
2861 restore_flags(flags);
2862 buf += c;
2863 count -= c;
2864 ret += c;
2866 up(&tmp_buf_sem);
2867 } else {
2868 while (1) {
2869 cli();
2870 c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
2871 SERIAL_XMIT_SIZE - info->xmit_head));
2872 if (c <= 0) {
2873 restore_flags(flags);
2874 break;
2876 memcpy(info->xmit_buf + info->xmit_head, buf, c);
2877 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
2878 info->xmit_cnt += c;
2879 restore_flags(flags);
2880 buf += c;
2881 count -= c;
2882 ret += c;
2886 info->idle_stats.xmit_bytes += ret;
2887 info->idle_stats.xmit_idle = jiffies;
2889 if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
2890 start_xmit(info);
2892 return ret;
2893 } /* cy_write */
2897 * This routine is called by the kernel to write a single
2898 * character to the tty device. If the kernel uses this routine,
2899 * it must call the flush_chars() routine (if defined) when it is
2900 * done stuffing characters into the driver. If there is no room
2901 * in the queue, the character is ignored.
2903 static void
2904 cy_put_char(struct tty_struct *tty, unsigned char ch)
2906 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
2907 unsigned long flags;
2909 #ifdef CY_DEBUG_IO
2910 printk("cyc:cy_put_char ttyC%d\n", info->line);
2911 #endif
2913 if (serial_paranoia_check(info, tty->device, "cy_put_char"))
2914 return;
2916 if (!tty || !info->xmit_buf)
2917 return;
2919 save_flags(flags); cli();
2920 if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
2921 restore_flags(flags);
2922 return;
2925 info->xmit_buf[info->xmit_head++] = ch;
2926 info->xmit_head &= SERIAL_XMIT_SIZE - 1;
2927 info->xmit_cnt++;
2928 info->idle_stats.xmit_bytes++;
2929 info->idle_stats.xmit_idle = jiffies;
2930 restore_flags(flags);
2931 } /* cy_put_char */
2935 * This routine is called by the kernel after it has written a
2936 * series of characters to the tty device using put_char().
2938 static void
2939 cy_flush_chars(struct tty_struct *tty)
2941 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
2942 unsigned long flags;
2943 unsigned char *base_addr;
2944 int card,chip,channel,index;
2946 #ifdef CY_DEBUG_IO
2947 printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */
2948 #endif
2950 if (serial_paranoia_check(info, tty->device, "cy_flush_chars"))
2951 return;
2953 if (info->xmit_cnt <= 0 || tty->stopped
2954 || tty->hw_stopped || !info->xmit_buf)
2955 return;
2957 card = info->card;
2958 channel = info->line - cy_card[card].first_line;
2959 if (!IS_CYC_Z(cy_card[card])) {
2960 chip = channel>>2;
2961 channel &= 0x03;
2962 index = cy_card[card].bus_index;
2963 base_addr = (unsigned char*)
2964 (cy_card[card].base_addr
2965 + (cy_chip_offset[chip]<<index));
2967 save_flags(flags); cli();
2968 cy_writeb((u_long)base_addr+(CyCAR<<index), channel);
2969 cy_writeb((u_long)base_addr+(CySRER<<index),
2970 cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
2971 restore_flags(flags);
2972 } else {
2973 /* Since polling is already in place,
2974 nothing further need be done. */
2976 } /* cy_flush_chars */
2980 * This routine returns the numbers of characters the tty driver
2981 * will accept for queuing to be written. This number is subject
2982 * to change as output buffers get emptied, or if the output flow
2983 * control is activated.
2985 static int
2986 cy_write_room(struct tty_struct *tty)
2988 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
2989 int ret;
2991 #ifdef CY_DEBUG_IO
2992 printk("cyc:cy_write_room ttyC%d\n", info->line); /* */
2993 #endif
2995 if (serial_paranoia_check(info, tty->device, "cy_write_room"))
2996 return 0;
2997 ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
2998 if (ret < 0)
2999 ret = 0;
3000 return ret;
3001 } /* cy_write_room */
3004 static int
3005 cy_chars_in_buffer(struct tty_struct *tty)
3007 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3008 int card, channel;
3010 if (serial_paranoia_check(info, tty->device, "cy_chars_in_buffer"))
3011 return 0;
3013 card = info->card;
3014 channel = (info->line) - (cy_card[card].first_line);
3016 if (!IS_CYC_Z(cy_card[card])) {
3017 #ifdef CY_DEBUG_IO
3018 printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
3019 info->line, info->xmit_cnt); /* */
3020 #endif
3021 return info->xmit_cnt;
3022 } else {
3023 static volatile struct FIRM_ID *firm_id;
3024 static volatile struct ZFW_CTRL *zfw_ctrl;
3025 static volatile struct CH_CTRL *ch_ctrl;
3026 static volatile struct BUF_CTRL *buf_ctrl;
3027 int char_count;
3028 volatile uclong tx_put, tx_get, tx_bufsize;
3030 firm_id = (struct FIRM_ID *)(cy_card[card].base_addr + ID_ADDRESS);
3031 zfw_ctrl = (struct ZFW_CTRL *) (cy_card[card].base_addr +
3032 cy_readl(&firm_id->zfwctrl_addr));
3033 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3034 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
3036 tx_get = cy_readl(&buf_ctrl->tx_get);
3037 tx_put = cy_readl(&buf_ctrl->tx_put);
3038 tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
3039 if (tx_put >= tx_get)
3040 char_count = tx_put - tx_get;
3041 else
3042 char_count = tx_put - tx_get + tx_bufsize;
3043 #ifdef CY_DEBUG_IO
3044 printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
3045 info->line, info->xmit_cnt + char_count); /* */
3046 #endif
3047 return (info->xmit_cnt + char_count);
3049 } /* cy_chars_in_buffer */
3053 * ------------------------------------------------------------
3054 * cy_ioctl() and friends
3055 * ------------------------------------------------------------
3060 * This routine finds or computes the various line characteristics.
3061 * It used to be called config_setup
3063 static void
3064 set_line_char(struct cyclades_port * info)
3066 unsigned long flags;
3067 unsigned char *base_addr;
3068 int card,chip,channel,index;
3069 unsigned cflag, iflag;
3070 unsigned short chip_number;
3071 int baud;
3072 int i;
3075 if (!info->tty || !info->tty->termios){
3076 return;
3078 if (info->line == -1){
3079 return;
3081 cflag = info->tty->termios->c_cflag;
3082 iflag = info->tty->termios->c_iflag;
3084 card = info->card;
3085 channel = (info->line) - (cy_card[card].first_line);
3086 chip_number = channel / 4;
3088 if (!IS_CYC_Z(cy_card[card])) {
3090 index = cy_card[card].bus_index;
3092 /* baud rate */
3093 baud = tty_get_baud_rate(info->tty);
3094 if (baud > CD1400_MAX_SPEED) {
3095 baud = CD1400_MAX_SPEED;
3097 /* find the baud index */
3098 for (i = 0; i < 20; i++) {
3099 if (baud == baud_table[i]) {
3100 break;
3103 if (i == 20) {
3104 i = 19; /* CD1400_MAX_SPEED */
3108 if(info->chip_rev >= CD1400_REV_J) {
3109 /* It is a CD1400 rev. J or later */
3110 info->tbpr = baud_bpr_60[i]; /* Tx BPR */
3111 info->tco = baud_co_60[i]; /* Tx CO */
3112 info->rbpr = baud_bpr_60[i]; /* Rx BPR */
3113 info->rco = baud_co_60[i]; /* Rx CO */
3114 } else {
3115 info->tbpr = baud_bpr_25[i]; /* Tx BPR */
3116 info->tco = baud_co_25[i]; /* Tx CO */
3117 info->rbpr = baud_bpr_25[i]; /* Rx BPR */
3118 info->rco = baud_co_25[i]; /* Rx CO */
3120 if (baud_table[i] == 134) {
3121 info->timeout = (info->xmit_fifo_size*HZ*15/269) + 2;
3122 /* get it right for 134.5 baud */
3123 } else if (baud_table[i]) {
3124 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
3125 /* this needs to be propagated into the card info */
3126 } else {
3127 info->timeout = 0;
3129 /* By tradition (is it a standard?) a baud rate of zero
3130 implies the line should be/has been closed. A bit
3131 later in this routine such a test is performed. */
3133 /* byte size and parity */
3134 info->cor5 = 0;
3135 info->cor4 = 0;
3136 info->cor3 = (info->default_threshold
3137 ? info->default_threshold
3138 : baud_cor3[i]); /* receive threshold */
3139 info->cor2 = CyETC;
3140 switch(cflag & CSIZE){
3141 case CS5:
3142 info->cor1 = Cy_5_BITS;
3143 break;
3144 case CS6:
3145 info->cor1 = Cy_6_BITS;
3146 break;
3147 case CS7:
3148 info->cor1 = Cy_7_BITS;
3149 break;
3150 case CS8:
3151 info->cor1 = Cy_8_BITS;
3152 break;
3154 if(cflag & CSTOPB){
3155 info->cor1 |= Cy_2_STOP;
3157 if (cflag & PARENB){
3158 if (cflag & PARODD){
3159 info->cor1 |= CyPARITY_O;
3160 }else{
3161 info->cor1 |= CyPARITY_E;
3163 }else{
3164 info->cor1 |= CyPARITY_NONE;
3167 /* CTS flow control flag */
3168 if (cflag & CRTSCTS){
3169 info->flags |= ASYNC_CTS_FLOW;
3170 info->cor2 |= CyCtsAE;
3171 }else{
3172 info->flags &= ~ASYNC_CTS_FLOW;
3173 info->cor2 &= ~CyCtsAE;
3175 if (cflag & CLOCAL)
3176 info->flags &= ~ASYNC_CHECK_CD;
3177 else
3178 info->flags |= ASYNC_CHECK_CD;
3180 /***********************************************
3181 The hardware option, CyRtsAO, presents RTS when
3182 the chip has characters to send. Since most modems
3183 use RTS as reverse (inbound) flow control, this
3184 option is not used. If inbound flow control is
3185 necessary, DTR can be programmed to provide the
3186 appropriate signals for use with a non-standard
3187 cable. Contact Marcio Saito for details.
3188 ***********************************************/
3190 chip = channel>>2;
3191 channel &= 0x03;
3192 base_addr = (unsigned char*)
3193 (cy_card[card].base_addr
3194 + (cy_chip_offset[chip]<<index));
3196 save_flags(flags); cli();
3197 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3199 /* tx and rx baud rate */
3201 cy_writeb((u_long)base_addr+(CyTCOR<<index), info->tco);
3202 cy_writeb((u_long)base_addr+(CyTBPR<<index), info->tbpr);
3203 cy_writeb((u_long)base_addr+(CyRCOR<<index), info->rco);
3204 cy_writeb((u_long)base_addr+(CyRBPR<<index), info->rbpr);
3206 /* set line characteristics according configuration */
3208 cy_writeb((u_long)base_addr+(CySCHR1<<index),
3209 START_CHAR(info->tty));
3210 cy_writeb((u_long)base_addr+(CySCHR2<<index),
3211 STOP_CHAR(info->tty));
3212 cy_writeb((u_long)base_addr+(CyCOR1<<index), info->cor1);
3213 cy_writeb((u_long)base_addr+(CyCOR2<<index), info->cor2);
3214 cy_writeb((u_long)base_addr+(CyCOR3<<index), info->cor3);
3215 cy_writeb((u_long)base_addr+(CyCOR4<<index), info->cor4);
3216 cy_writeb((u_long)base_addr+(CyCOR5<<index), info->cor5);
3218 cyy_issue_cmd(base_addr,
3219 CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch,index);
3221 cy_writeb((u_long)base_addr+(CyCAR<<index),
3222 (u_char)channel); /* !!! Is this needed? */
3223 cy_writeb((u_long)base_addr+(CyRTPR<<index), (info->default_timeout
3224 ? info->default_timeout
3225 : 0x02)); /* 10ms rx timeout */
3227 if (C_CLOCAL(info->tty)) {
3228 /* without modem intr */
3229 cy_writeb((u_long)base_addr+(CySRER<<index),
3230 cy_readb(base_addr+(CySRER<<index)) | CyMdmCh);
3231 /* act on 1->0 modem transitions */
3232 if ((cflag & CRTSCTS) && info->rflow) {
3233 cy_writeb((u_long)base_addr+(CyMCOR1<<index),
3234 (CyCTS|rflow_thr[i]));
3235 } else {
3236 cy_writeb((u_long)base_addr+(CyMCOR1<<index), CyCTS);
3238 /* act on 0->1 modem transitions */
3239 cy_writeb((u_long)base_addr+(CyMCOR2<<index), CyCTS);
3240 } else {
3241 /* without modem intr */
3242 cy_writeb((u_long)base_addr+(CySRER<<index),
3243 cy_readb(base_addr+(CySRER<<index)) | CyMdmCh);
3244 /* act on 1->0 modem transitions */
3245 if ((cflag & CRTSCTS) && info->rflow) {
3246 cy_writeb((u_long)base_addr+(CyMCOR1<<index),
3247 (CyDSR|CyCTS|CyRI|CyDCD|rflow_thr[i]));
3248 } else {
3249 cy_writeb((u_long)base_addr+(CyMCOR1<<index),
3250 CyDSR|CyCTS|CyRI|CyDCD);
3252 /* act on 0->1 modem transitions */
3253 cy_writeb((u_long)base_addr+(CyMCOR2<<index),
3254 CyDSR|CyCTS|CyRI|CyDCD);
3257 if(i == 0){ /* baud rate is zero, turn off line */
3258 if (info->rtsdtr_inv) {
3259 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3260 } else {
3261 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3263 #ifdef CY_DEBUG_DTR
3264 printk("cyc:set_line_char dropping DTR\n");
3265 printk(" status: 0x%x,
3266 0x%x\n", cy_readb(base_addr+(CyMSVR1<<index)),
3267 cy_readb(base_addr+(CyMSVR2<<index)));
3268 #endif
3269 }else{
3270 if (info->rtsdtr_inv) {
3271 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3272 } else {
3273 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3275 #ifdef CY_DEBUG_DTR
3276 printk("cyc:set_line_char raising DTR\n");
3277 printk(" status: 0x%x, 0x%x\n",
3278 cy_readb(base_addr+(CyMSVR1<<index)),
3279 cy_readb(base_addr+(CyMSVR2<<index)));
3280 #endif
3283 if (info->tty){
3284 clear_bit(TTY_IO_ERROR, &info->tty->flags);
3287 restore_flags(flags);
3288 } else {
3289 struct FIRM_ID *firm_id;
3290 struct ZFW_CTRL *zfw_ctrl;
3291 struct BOARD_CTRL *board_ctrl;
3292 struct CH_CTRL *ch_ctrl;
3293 struct BUF_CTRL *buf_ctrl;
3294 int retval;
3296 firm_id = (struct FIRM_ID *)
3297 (cy_card[card].base_addr + ID_ADDRESS);
3298 if (!ISZLOADED(cy_card[card])) {
3299 return;
3302 zfw_ctrl = (struct ZFW_CTRL *)
3303 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
3304 board_ctrl = &zfw_ctrl->board_ctrl;
3305 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3306 buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3308 /* baud rate */
3309 baud = tty_get_baud_rate(info->tty);
3310 if (baud > CD1400_MAX_SPEED) {
3311 baud = CD1400_MAX_SPEED;
3313 cy_writel(&ch_ctrl->comm_baud , baud);
3315 if (baud == 134) {
3316 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
3317 /* get it right for 134.5 baud */
3318 } else if (baud) {
3319 info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
3320 /* this needs to be propagated into the card info */
3321 } else {
3322 info->timeout = 0;
3325 /* byte size and parity */
3326 switch(cflag & CSIZE){
3327 case CS5: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS5); break;
3328 case CS6: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS6); break;
3329 case CS7: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS7); break;
3330 case CS8: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS8); break;
3332 if(cflag & CSTOPB){
3333 cy_writel(&ch_ctrl->comm_data_l,
3334 cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
3335 }else{
3336 cy_writel(&ch_ctrl->comm_data_l,
3337 cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
3339 if (cflag & PARENB){
3340 if (cflag & PARODD){
3341 cy_writel(&ch_ctrl->comm_parity , C_PR_ODD);
3342 }else{
3343 cy_writel(&ch_ctrl->comm_parity , C_PR_EVEN);
3345 }else{
3346 cy_writel(&ch_ctrl->comm_parity , C_PR_NONE);
3349 /* CTS flow control flag */
3350 if (cflag & CRTSCTS){
3351 info->flags |= ASYNC_CTS_FLOW;
3352 cy_writel(&ch_ctrl->hw_flow,
3353 cy_readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
3354 }else{
3355 info->flags &= ~ASYNC_CTS_FLOW;
3356 cy_writel(&ch_ctrl->hw_flow,
3357 cy_readl(&ch_ctrl->hw_flow) & ~(C_RS_CTS | C_RS_RTS));
3360 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
3361 if (retval != 0){
3362 printk("cyc:set_line_char retval at %d was %x\n",
3363 __LINE__, retval);
3366 /* CD sensitivity */
3367 if (cflag & CLOCAL){
3368 info->flags &= ~ASYNC_CHECK_CD;
3369 }else{
3370 info->flags |= ASYNC_CHECK_CD;
3373 if (iflag & IXON){
3374 cy_writel(&ch_ctrl->sw_flow,
3375 cy_readl(&ch_ctrl->sw_flow) | C_FL_OXX);
3376 } else {
3377 cy_writel(&ch_ctrl->sw_flow,
3378 cy_readl(&ch_ctrl->sw_flow) & ~C_FL_OXX);
3381 if(baud == 0){ /* baud rate is zero, turn off line */
3382 cy_writel(&ch_ctrl->rs_control,
3383 cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
3384 #ifdef CY_DEBUG_DTR
3385 printk("cyc:set_line_char dropping Z DTR\n");
3386 #endif
3387 }else{
3388 cy_writel(&ch_ctrl->rs_control,
3389 cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
3390 #ifdef CY_DEBUG_DTR
3391 printk("cyc:set_line_char raising Z DTR\n");
3392 #endif
3395 retval = cyz_issue_cmd( &cy_card[card], channel, C_CM_IOCTLM, 0L);
3396 if (retval != 0){
3397 printk("cyc:set_line_char retval at %d was %x\n",
3398 __LINE__, retval);
3401 if (info->tty){
3402 clear_bit(TTY_IO_ERROR, &info->tty->flags);
3407 * Set up the tty->alt_speed kludge
3409 if (info->tty) {
3410 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
3411 info->tty->alt_speed = 57600;
3412 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
3413 info->tty->alt_speed = 115200;
3414 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
3415 info->tty->alt_speed = 230400;
3416 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
3417 info->tty->alt_speed = 460800;
3421 } /* set_line_char */
3424 static int
3425 get_serial_info(struct cyclades_port * info,
3426 struct serial_struct * retinfo)
3428 struct serial_struct tmp;
3429 struct cyclades_card *cinfo = &cy_card[info->card];
3431 if (!retinfo)
3432 return -EFAULT;
3433 memset(&tmp, 0, sizeof(tmp));
3434 tmp.type = info->type;
3435 tmp.line = info->line;
3436 tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
3437 tmp.irq = cinfo->irq;
3438 tmp.flags = info->flags;
3439 tmp.close_delay = info->close_delay;
3440 tmp.baud_base = info->baud;
3441 tmp.custom_divisor = 0; /*!!!*/
3442 tmp.hub6 = 0; /*!!!*/
3443 return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0;
3444 } /* get_serial_info */
3447 static int
3448 set_serial_info(struct cyclades_port * info,
3449 struct serial_struct * new_info)
3451 struct serial_struct new_serial;
3452 struct cyclades_port old_info;
3454 if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
3455 return -EFAULT;
3456 old_info = *info;
3458 if (!capable(CAP_SYS_ADMIN)) {
3459 if ((new_serial.close_delay != info->close_delay) ||
3460 (new_serial.baud_base != info->baud) ||
3461 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
3462 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
3463 return -EPERM;
3464 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
3465 (new_serial.flags & ASYNC_USR_MASK));
3466 info->baud = new_serial.baud_base;
3467 goto check_and_exit;
3472 * OK, past this point, all the error checking has been done.
3473 * At this point, we start making changes.....
3476 info->baud = new_serial.baud_base;
3477 info->flags = ((info->flags & ~ASYNC_FLAGS) |
3478 (new_serial.flags & ASYNC_FLAGS));
3479 info->close_delay = new_serial.close_delay * HZ/100;
3480 info->closing_wait = new_serial.closing_wait * HZ/100;
3482 check_and_exit:
3483 if (info->flags & ASYNC_INITIALIZED){
3484 set_line_char(info);
3485 return 0;
3486 }else{
3487 return startup(info);
3489 } /* set_serial_info */
3492 static int
3493 get_modem_info(struct cyclades_port * info, unsigned int *value)
3495 int card,chip,channel,index;
3496 unsigned char *base_addr;
3497 unsigned long flags;
3498 unsigned char status;
3499 unsigned long lstatus;
3500 unsigned int result;
3501 struct FIRM_ID *firm_id;
3502 struct ZFW_CTRL *zfw_ctrl;
3503 struct BOARD_CTRL *board_ctrl;
3504 struct CH_CTRL *ch_ctrl;
3506 card = info->card;
3507 channel = (info->line) - (cy_card[card].first_line);
3508 if (!IS_CYC_Z(cy_card[card])) {
3509 chip = channel>>2;
3510 channel &= 0x03;
3511 index = cy_card[card].bus_index;
3512 base_addr = (unsigned char*)
3513 (cy_card[card].base_addr
3514 + (cy_chip_offset[chip]<<index));
3516 save_flags(flags); cli();
3517 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3518 status = cy_readb(base_addr+(CyMSVR1<<index));
3519 status |= cy_readb(base_addr+(CyMSVR2<<index));
3520 restore_flags(flags);
3523 if (info->rtsdtr_inv) {
3524 result = ((status & CyRTS) ? TIOCM_DTR : 0)
3525 | ((status & CyDTR) ? TIOCM_RTS : 0);
3526 } else {
3527 result = ((status & CyRTS) ? TIOCM_RTS : 0)
3528 | ((status & CyDTR) ? TIOCM_DTR : 0);
3530 result |= ((status & CyDCD) ? TIOCM_CAR : 0)
3531 | ((status & CyRI) ? TIOCM_RNG : 0)
3532 | ((status & CyDSR) ? TIOCM_DSR : 0)
3533 | ((status & CyCTS) ? TIOCM_CTS : 0);
3534 } else {
3535 base_addr = (unsigned char*) (cy_card[card].base_addr);
3537 if (cy_card[card].num_chips != -1){
3538 return -EINVAL;
3541 firm_id = (struct FIRM_ID *)
3542 (cy_card[card].base_addr + ID_ADDRESS);
3543 if (ISZLOADED(cy_card[card])) {
3544 zfw_ctrl = (struct ZFW_CTRL *)
3545 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
3546 board_ctrl = &zfw_ctrl->board_ctrl;
3547 ch_ctrl = zfw_ctrl->ch_ctrl;
3548 lstatus = cy_readl(&ch_ctrl[channel].rs_status);
3549 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0)
3550 | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0)
3551 | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0)
3552 | ((lstatus & C_RS_RI) ? TIOCM_RNG : 0)
3553 | ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0)
3554 | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
3555 }else{
3556 result = 0;
3557 return -ENODEV;
3561 return cy_put_user(result,(unsigned long *) value);
3562 } /* get_modem_info */
3565 static int
3566 set_modem_info(struct cyclades_port * info, unsigned int cmd,
3567 unsigned int *value)
3569 int card,chip,channel,index;
3570 unsigned char *base_addr;
3571 unsigned long flags;
3572 unsigned int arg = cy_get_user((unsigned long *) value);
3573 struct FIRM_ID *firm_id;
3574 struct ZFW_CTRL *zfw_ctrl;
3575 struct BOARD_CTRL *board_ctrl;
3576 struct CH_CTRL *ch_ctrl;
3577 int retval;
3579 card = info->card;
3580 channel = (info->line) - (cy_card[card].first_line);
3581 if (!IS_CYC_Z(cy_card[card])) {
3582 chip = channel>>2;
3583 channel &= 0x03;
3584 index = cy_card[card].bus_index;
3585 base_addr = (unsigned char*)
3586 (cy_card[card].base_addr
3587 + (cy_chip_offset[chip]<<index));
3589 switch (cmd) {
3590 case TIOCMBIS:
3591 if (arg & TIOCM_RTS){
3592 save_flags(flags); cli();
3593 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3594 if (info->rtsdtr_inv) {
3595 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3596 } else {
3597 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3599 restore_flags(flags);
3601 if (arg & TIOCM_DTR){
3602 save_flags(flags); cli();
3603 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3604 if (info->rtsdtr_inv) {
3605 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3606 } else {
3607 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3609 #ifdef CY_DEBUG_DTR
3610 printk("cyc:set_modem_info raising DTR\n");
3611 printk(" status: 0x%x, 0x%x\n",
3612 cy_readb(base_addr+(CyMSVR1<<index)),
3613 cy_readb(base_addr+(CyMSVR2<<index)));
3614 #endif
3615 restore_flags(flags);
3617 break;
3618 case TIOCMBIC:
3619 if (arg & TIOCM_RTS){
3620 save_flags(flags); cli();
3621 cy_writeb((u_long)base_addr+(CyCAR<<index),
3622 (u_char)channel);
3623 if (info->rtsdtr_inv) {
3624 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3625 } else {
3626 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3628 restore_flags(flags);
3630 if (arg & TIOCM_DTR){
3631 save_flags(flags); cli();
3632 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3633 if (info->rtsdtr_inv) {
3634 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3635 } else {
3636 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3638 #ifdef CY_DEBUG_DTR
3639 printk("cyc:set_modem_info dropping DTR\n");
3640 printk(" status: 0x%x, 0x%x\n",
3641 cy_readb(base_addr+(CyMSVR1<<index)),
3642 cy_readb(base_addr+(CyMSVR2<<index)));
3643 #endif
3644 restore_flags(flags);
3646 break;
3647 case TIOCMSET:
3648 if (arg & TIOCM_RTS){
3649 save_flags(flags); cli();
3650 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3651 if (info->rtsdtr_inv) {
3652 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3653 } else {
3654 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3656 restore_flags(flags);
3657 }else{
3658 save_flags(flags); cli();
3659 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3660 if (info->rtsdtr_inv) {
3661 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3662 } else {
3663 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3665 restore_flags(flags);
3667 if (arg & TIOCM_DTR){
3668 save_flags(flags); cli();
3669 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3670 if (info->rtsdtr_inv) {
3671 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3672 } else {
3673 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3675 #ifdef CY_DEBUG_DTR
3676 printk("cyc:set_modem_info raising DTR\n");
3677 printk(" status: 0x%x, 0x%x\n",
3678 cy_readb(base_addr+(CyMSVR1<<index)),
3679 cy_readb(base_addr+(CyMSVR2<<index)));
3680 #endif
3681 restore_flags(flags);
3682 }else{
3683 save_flags(flags); cli();
3684 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3685 if (info->rtsdtr_inv) {
3686 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3687 } else {
3688 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3691 #ifdef CY_DEBUG_DTR
3692 printk("cyc:set_modem_info dropping DTR\n");
3693 printk(" status: 0x%x, 0x%x\n",
3694 cy_readb(base_addr+(CyMSVR1<<index)),
3695 cy_readb(base_addr+(CyMSVR2<<index)));
3696 #endif
3697 restore_flags(flags);
3699 break;
3700 default:
3701 return -EINVAL;
3703 } else {
3704 base_addr = (unsigned char*) (cy_card[card].base_addr);
3706 firm_id = (struct FIRM_ID *)
3707 (cy_card[card].base_addr + ID_ADDRESS);
3708 if (ISZLOADED(cy_card[card])) {
3709 zfw_ctrl = (struct ZFW_CTRL *)
3710 (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
3711 board_ctrl = &zfw_ctrl->board_ctrl;
3712 ch_ctrl = zfw_ctrl->ch_ctrl;
3714 switch (cmd) {
3715 case TIOCMBIS:
3716 if (arg & TIOCM_RTS){
3717 cy_writel(&ch_ctrl[channel].rs_control,
3718 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS);
3720 if (arg & TIOCM_DTR){
3721 cy_writel(&ch_ctrl[channel].rs_control,
3722 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
3723 #ifdef CY_DEBUG_DTR
3724 printk("cyc:set_modem_info raising Z DTR\n");
3725 #endif
3727 break;
3728 case TIOCMBIC:
3729 if (arg & TIOCM_RTS){
3730 cy_writel(&ch_ctrl[channel].rs_control,
3731 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS);
3733 if (arg & TIOCM_DTR){
3734 cy_writel(&ch_ctrl[channel].rs_control,
3735 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
3736 #ifdef CY_DEBUG_DTR
3737 printk("cyc:set_modem_info clearing Z DTR\n");
3738 #endif
3740 break;
3741 case TIOCMSET:
3742 if (arg & TIOCM_RTS){
3743 cy_writel(&ch_ctrl[channel].rs_control,
3744 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS);
3745 }else{
3746 cy_writel(&ch_ctrl[channel].rs_control,
3747 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS);
3749 if (arg & TIOCM_DTR){
3750 cy_writel(&ch_ctrl[channel].rs_control,
3751 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
3752 #ifdef CY_DEBUG_DTR
3753 printk("cyc:set_modem_info raising Z DTR\n");
3754 #endif
3755 }else{
3756 cy_writel(&ch_ctrl[channel].rs_control,
3757 cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
3758 #ifdef CY_DEBUG_DTR
3759 printk("cyc:set_modem_info clearing Z DTR\n");
3760 #endif
3762 break;
3763 default:
3764 return -EINVAL;
3766 }else{
3767 return -ENODEV;
3769 retval = cyz_issue_cmd(&cy_card[info->card],
3770 channel, C_CM_IOCTLM,0L);
3771 if (retval != 0){
3772 printk("cyc:set_modem_info retval at %d was %x\n",
3773 __LINE__, retval);
3776 return 0;
3777 } /* set_modem_info */
3780 * cy_break() --- routine which turns the break handling on or off
3782 static void
3783 cy_break(struct tty_struct *tty, int break_state)
3785 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
3786 unsigned long flags;
3788 if (serial_paranoia_check(info, tty->device, "cy_break"))
3789 return;
3791 save_flags(flags); cli();
3792 if (!IS_CYC_Z(cy_card[info->card])) {
3793 /* Let the transmit ISR take care of this (since it
3794 requires stuffing characters into the output stream).
3796 if (break_state == -1) {
3797 if (!info->breakon) {
3798 info->breakon = 1;
3799 if (!info->xmit_cnt ) {
3800 start_xmit(info);
3803 } else {
3804 if (!info->breakoff) {
3805 info->breakoff = 1;
3806 if (!info->xmit_cnt ) {
3807 start_xmit(info);
3811 } else {
3812 int retval;
3814 if (break_state == -1) {
3815 retval = cyz_issue_cmd(&cy_card[info->card],
3816 (info->line) - (cy_card[info->card].first_line),
3817 C_CM_SET_BREAK, 0L);
3818 if (retval != 0) {
3819 printk("cyc:cy_break (set) retval at %d was %x\n",
3820 __LINE__, retval);
3822 } else {
3823 retval = cyz_issue_cmd(&cy_card[info->card],
3824 (info->line) - (cy_card[info->card].first_line),
3825 C_CM_CLR_BREAK, 0L);
3826 if (retval != 0) {
3827 printk("cyc:cy_break (clr) retval at %d was %x\n",
3828 __LINE__, retval);
3832 restore_flags(flags);
3834 } /* cy_break */
3836 static int
3837 get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
3840 if(copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
3841 return -EFAULT;
3842 info->mon.int_count = 0;
3843 info->mon.char_count = 0;
3844 info->mon.char_max = 0;
3845 info->mon.char_last = 0;
3846 return 0;
3847 }/* get_mon_info */
3850 static int
3851 set_threshold(struct cyclades_port * info, unsigned long value)
3853 unsigned char *base_addr;
3854 int card,channel,chip,index;
3856 card = info->card;
3857 channel = info->line - cy_card[card].first_line;
3858 if (!IS_CYC_Z(cy_card[card])) {
3859 chip = channel>>2;
3860 channel &= 0x03;
3861 index = cy_card[card].bus_index;
3862 base_addr = (unsigned char*)
3863 (cy_card[card].base_addr
3864 + (cy_chip_offset[chip]<<index));
3866 info->cor3 &= ~CyREC_FIFO;
3867 info->cor3 |= value & CyREC_FIFO;
3868 cy_writeb((u_long)base_addr+(CyCOR3<<index), info->cor3);
3869 cyy_issue_cmd(base_addr,CyCOR_CHANGE|CyCOR3ch,index);
3870 } else {
3871 // Nothing to do!
3873 return 0;
3874 }/* set_threshold */
3877 static int
3878 get_threshold(struct cyclades_port * info, unsigned long *value)
3880 unsigned char *base_addr;
3881 int card,channel,chip,index;
3882 unsigned long tmp;
3884 card = info->card;
3885 channel = info->line - cy_card[card].first_line;
3886 if (!IS_CYC_Z(cy_card[card])) {
3887 chip = channel>>2;
3888 channel &= 0x03;
3889 index = cy_card[card].bus_index;
3890 base_addr = (unsigned char*)
3891 (cy_card[card].base_addr
3892 + (cy_chip_offset[chip]<<index));
3894 tmp = cy_readb(base_addr+(CyCOR3<<index)) & CyREC_FIFO;
3895 return cy_put_user(tmp,value);
3896 } else {
3897 // Nothing to do!
3898 return 0;
3900 }/* get_threshold */
3903 static int
3904 set_default_threshold(struct cyclades_port * info, unsigned long value)
3906 info->default_threshold = value & 0x0f;
3907 return 0;
3908 }/* set_default_threshold */
3911 static int
3912 get_default_threshold(struct cyclades_port * info, unsigned long *value)
3914 return cy_put_user(info->default_threshold,value);
3915 }/* get_default_threshold */
3918 static int
3919 set_timeout(struct cyclades_port * info, unsigned long value)
3921 unsigned char *base_addr;
3922 int card,channel,chip,index;
3924 card = info->card;
3925 channel = info->line - cy_card[card].first_line;
3926 if (!IS_CYC_Z(cy_card[card])) {
3927 chip = channel>>2;
3928 channel &= 0x03;
3929 index = cy_card[card].bus_index;
3930 base_addr = (unsigned char*)
3931 (cy_card[card].base_addr
3932 + (cy_chip_offset[chip]<<index));
3934 cy_writeb((u_long)base_addr+(CyRTPR<<index), value & 0xff);
3935 } else {
3936 // Nothing to do!
3938 return 0;
3939 }/* set_timeout */
3942 static int
3943 get_timeout(struct cyclades_port * info, unsigned long *value)
3945 unsigned char *base_addr;
3946 int card,channel,chip,index;
3947 unsigned long tmp;
3949 card = info->card;
3950 channel = info->line - cy_card[card].first_line;
3951 if (!IS_CYC_Z(cy_card[card])) {
3952 chip = channel>>2;
3953 channel &= 0x03;
3954 index = cy_card[card].bus_index;
3955 base_addr = (unsigned char*)
3956 (cy_card[card].base_addr
3957 + (cy_chip_offset[chip]<<index));
3959 tmp = cy_readb(base_addr+(CyRTPR<<index));
3960 return cy_put_user(tmp,value);
3961 } else {
3962 // Nothing to do!
3963 return 0;
3965 }/* get_timeout */
3968 static int
3969 set_default_timeout(struct cyclades_port * info, unsigned long value)
3971 info->default_timeout = value & 0xff;
3972 return 0;
3973 }/* set_default_timeout */
3976 static int
3977 get_default_timeout(struct cyclades_port * info, unsigned long *value)
3979 return cy_put_user(info->default_timeout,value);
3980 }/* get_default_timeout */
3983 * This routine allows the tty driver to implement device-
3984 * specific ioctl's. If the ioctl number passed in cmd is
3985 * not recognized by the driver, it should return ENOIOCTLCMD.
3987 static int
3988 cy_ioctl(struct tty_struct *tty, struct file * file,
3989 unsigned int cmd, unsigned long arg)
3991 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
3992 int ret_val = 0;
3994 if (serial_paranoia_check(info, tty->device, "cy_ioctl"))
3995 return -ENODEV;
3997 #ifdef CY_DEBUG_OTHER
3998 printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
3999 info->line, cmd, arg); /* */
4000 #endif
4002 switch (cmd) {
4003 case CYGETMON:
4004 ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
4005 break;
4006 case CYGETTHRESH:
4007 ret_val = get_threshold(info, (unsigned long *)arg);
4008 break;
4009 case CYSETTHRESH:
4010 ret_val = set_threshold(info, (unsigned long)arg);
4011 break;
4012 case CYGETDEFTHRESH:
4013 ret_val = get_default_threshold(info, (unsigned long *)arg);
4014 break;
4015 case CYSETDEFTHRESH:
4016 ret_val = set_default_threshold(info, (unsigned long)arg);
4017 break;
4018 case CYGETTIMEOUT:
4019 ret_val = get_timeout(info, (unsigned long *)arg);
4020 break;
4021 case CYSETTIMEOUT:
4022 ret_val = set_timeout(info, (unsigned long)arg);
4023 break;
4024 case CYGETDEFTIMEOUT:
4025 ret_val = get_default_timeout(info, (unsigned long *)arg);
4026 break;
4027 case CYSETDEFTIMEOUT:
4028 ret_val = set_default_timeout(info, (unsigned long)arg);
4029 break;
4030 case CYSETRFLOW:
4031 info->rflow = (int)arg;
4032 ret_val = 0;
4033 break;
4034 case CYGETRFLOW:
4035 ret_val = info->rflow;
4036 break;
4037 case CYSETRTSDTR_INV:
4038 info->rtsdtr_inv = (int)arg;
4039 ret_val = 0;
4040 break;
4041 case CYGETRTSDTR_INV:
4042 ret_val = info->rtsdtr_inv;
4043 break;
4044 case CYGETCARDINFO:
4045 if (copy_to_user((void *)arg, (void *)&cy_card[info->card],
4046 sizeof (struct cyclades_card))) {
4047 ret_val = -EFAULT;
4049 ret_val = 0;
4050 break;
4051 case CYGETCD1400VER:
4052 ret_val = info->chip_rev;
4053 break;
4054 case CYZSETPOLLCYCLE:
4055 cyz_polling_cycle = (arg * HZ) / 1000;
4056 ret_val = 0;
4057 break;
4058 case CYZGETPOLLCYCLE:
4059 ret_val = (cyz_polling_cycle * 1000) / HZ;
4060 break;
4061 case CYSETWAIT:
4062 info->closing_wait = (unsigned short)arg * HZ/100;
4063 ret_val = 0;
4064 break;
4065 case CYGETWAIT:
4066 ret_val = info->closing_wait / (HZ/100);
4067 break;
4068 case TIOCMGET:
4069 ret_val = get_modem_info(info, (unsigned int *) arg);
4070 break;
4071 case TIOCMBIS:
4072 case TIOCMBIC:
4073 case TIOCMSET:
4074 ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
4075 break;
4076 case TIOCGSERIAL:
4077 ret_val = get_serial_info(info, (struct serial_struct *) arg);
4078 break;
4079 case TIOCSSERIAL:
4080 ret_val = set_serial_info(info, (struct serial_struct *) arg);
4081 break;
4082 default:
4083 ret_val = -ENOIOCTLCMD;
4086 #ifdef CY_DEBUG_OTHER
4087 printk(" cyc:cy_ioctl done\n");
4088 #endif
4090 return ret_val;
4091 } /* cy_ioctl */
4095 * This routine allows the tty driver to be notified when
4096 * device's termios settings have changed. Note that a
4097 * well-designed tty driver should be prepared to accept the case
4098 * where old == NULL, and try to do something rational.
4100 static void
4101 cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
4103 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4105 #ifdef CY_DEBUG_OTHER
4106 printk("cyc:cy_set_termios ttyC%d\n", info->line);
4107 #endif
4109 if (tty->termios->c_cflag == old_termios->c_cflag)
4110 return;
4111 set_line_char(info);
4113 if ((old_termios->c_cflag & CRTSCTS) &&
4114 !(tty->termios->c_cflag & CRTSCTS)) {
4115 tty->stopped = 0;
4116 cy_start(tty);
4118 #if 0
4120 * No need to wake up processes in open wait, since they
4121 * sample the CLOCAL flag once, and don't recheck it.
4122 * XXX It's not clear whether the current behavior is correct
4123 * or not. Hence, this may change.....
4125 if (!(old_termios->c_cflag & CLOCAL) &&
4126 (tty->termios->c_cflag & CLOCAL))
4127 wake_up_interruptible(&info->open_wait);
4128 #endif
4130 return;
4131 } /* cy_set_termios */
4133 /* This routine is called by the upper-layer tty layer to signal
4134 that incoming characters should be throttled because the input
4135 buffers are close to full.
4137 static void
4138 cy_throttle(struct tty_struct * tty)
4140 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4141 unsigned long flags;
4142 unsigned char *base_addr;
4143 int card,chip,channel,index;
4145 #ifdef CY_DEBUG_THROTTLE
4146 char buf[64];
4148 printk("cyc:throttle %s: %d....ttyC%d\n",
4149 tty_name(tty, buf),
4150 tty->ldisc.chars_in_buffer(tty), info->line);
4151 #endif
4153 if (serial_paranoia_check(info, tty->device, "cy_throttle")){
4154 return;
4157 if (I_IXOFF(tty)) {
4158 info->x_char = STOP_CHAR(tty);
4159 /* Should use the "Send Special Character" feature!!! */
4162 card = info->card;
4163 channel = info->line - cy_card[card].first_line;
4164 if (!IS_CYC_Z(cy_card[card])) {
4165 chip = channel>>2;
4166 channel &= 0x03;
4167 index = cy_card[card].bus_index;
4168 base_addr = (unsigned char*)
4169 (cy_card[card].base_addr
4170 + (cy_chip_offset[chip]<<index));
4172 save_flags(flags); cli();
4173 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
4174 if (info->rtsdtr_inv) {
4175 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
4176 } else {
4177 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
4179 restore_flags(flags);
4180 } else {
4181 // Nothing to do!
4184 return;
4185 } /* cy_throttle */
4189 * This routine notifies the tty driver that it should signal
4190 * that characters can now be sent to the tty without fear of
4191 * overrunning the input buffers of the line disciplines.
4193 static void
4194 cy_unthrottle(struct tty_struct * tty)
4196 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4197 unsigned long flags;
4198 unsigned char *base_addr;
4199 int card,chip,channel,index;
4201 #ifdef CY_DEBUG_THROTTLE
4202 char buf[64];
4204 printk("cyc:unthrottle %s: %d....ttyC%d\n",
4205 tty_name(tty, buf),
4206 tty->ldisc.chars_in_buffer(tty), info->line);
4207 #endif
4209 if (serial_paranoia_check(info, tty->device, "cy_unthrottle")){
4210 return;
4213 if (I_IXOFF(tty)) {
4214 if (info->x_char)
4215 info->x_char = 0;
4216 else
4217 info->x_char = START_CHAR(tty);
4218 /* Should use the "Send Special Character" feature!!! */
4221 card = info->card;
4222 channel = info->line - cy_card[card].first_line;
4223 if (!IS_CYC_Z(cy_card[card])) {
4224 chip = channel>>2;
4225 channel &= 0x03;
4226 index = cy_card[card].bus_index;
4227 base_addr = (unsigned char*)
4228 (cy_card[card].base_addr
4229 + (cy_chip_offset[chip]<<index));
4231 save_flags(flags); cli();
4232 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
4233 if (info->rtsdtr_inv) {
4234 cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
4235 } else {
4236 cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
4238 restore_flags(flags);
4239 }else{
4240 // Nothing to do!
4243 return;
4244 } /* cy_unthrottle */
4247 /* cy_start and cy_stop provide software output flow control as a
4248 function of XON/XOFF, software CTS, and other such stuff.
4250 static void
4251 cy_stop(struct tty_struct *tty)
4253 struct cyclades_card *cinfo;
4254 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4255 unsigned char *base_addr;
4256 int chip,channel,index;
4257 unsigned long flags;
4259 #ifdef CY_DEBUG_OTHER
4260 printk("cyc:cy_stop ttyC%d\n", info->line); /* */
4261 #endif
4263 if (serial_paranoia_check(info, tty->device, "cy_stop"))
4264 return;
4266 cinfo = &cy_card[info->card];
4267 channel = info->line - cinfo->first_line;
4268 if (!IS_CYC_Z(*cinfo)) {
4269 index = cinfo->bus_index;
4270 chip = channel>>2;
4271 channel &= 0x03;
4272 base_addr = (unsigned char*)
4273 (cy_card[info->card].base_addr
4274 + (cy_chip_offset[chip]<<index));
4276 save_flags(flags); cli();
4277 cy_writeb((u_long)base_addr+(CyCAR<<index),
4278 (u_char)(channel & 0x0003)); /* index channel */
4279 cy_writeb((u_long)base_addr+(CySRER<<index),
4280 cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
4281 restore_flags(flags);
4282 } else {
4283 // Nothing to do!
4286 return;
4287 } /* cy_stop */
4290 static void
4291 cy_start(struct tty_struct *tty)
4293 struct cyclades_card *cinfo;
4294 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4295 unsigned char *base_addr;
4296 int chip,channel,index;
4297 unsigned long flags;
4299 #ifdef CY_DEBUG_OTHER
4300 printk("cyc:cy_start ttyC%d\n", info->line); /* */
4301 #endif
4303 if (serial_paranoia_check(info, tty->device, "cy_start"))
4304 return;
4306 cinfo = &cy_card[info->card];
4307 channel = info->line - cinfo->first_line;
4308 index = cinfo->bus_index;
4309 if (!IS_CYC_Z(*cinfo)) {
4310 chip = channel>>2;
4311 channel &= 0x03;
4312 base_addr = (unsigned char*)
4313 (cy_card[info->card].base_addr
4314 + (cy_chip_offset[chip]<<index));
4316 save_flags(flags); cli();
4317 cy_writeb((u_long)base_addr+(CyCAR<<index),
4318 (u_char)(channel & 0x0003)); /* index channel */
4319 cy_writeb((u_long)base_addr+(CySRER<<index),
4320 cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
4321 restore_flags(flags);
4322 } else {
4323 // Nothing to do!
4326 return;
4327 } /* cy_start */
4330 static void
4331 cy_flush_buffer(struct tty_struct *tty)
4333 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
4334 int card, channel;
4335 unsigned long flags;
4337 #ifdef CY_DEBUG_IO
4338 printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */
4339 #endif
4341 if (serial_paranoia_check(info, tty->device, "cy_flush_buffer"))
4342 return;
4343 save_flags(flags); cli();
4344 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
4345 restore_flags(flags);
4347 card = info->card;
4348 channel = (info->line) - (cy_card[card].first_line);
4350 if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board
4351 buffers as well */
4352 static volatile struct FIRM_ID *firm_id;
4353 static volatile struct ZFW_CTRL *zfw_ctrl;
4354 static volatile struct CH_CTRL *ch_ctrl;
4355 static volatile struct BUF_CTRL *buf_ctrl;
4357 firm_id = (struct FIRM_ID *)(cy_card[card].base_addr + ID_ADDRESS);
4358 zfw_ctrl = (struct ZFW_CTRL *) (cy_card[card].base_addr +
4359 cy_readl(&firm_id->zfwctrl_addr));
4360 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
4361 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
4363 while (cy_readl(&buf_ctrl->tx_get) != cy_readl(&buf_ctrl->tx_put))
4364 cy_writel(&buf_ctrl->tx_put, cy_readl(&buf_ctrl->tx_get));
4366 wake_up_interruptible(&tty->write_wait);
4367 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
4368 && tty->ldisc.write_wakeup)
4369 (tty->ldisc.write_wakeup)(tty);
4370 } /* cy_flush_buffer */
4374 * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
4376 static void
4377 cy_hangup(struct tty_struct *tty)
4379 struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
4381 #ifdef CY_DEBUG_OTHER
4382 printk("cyc:cy_hangup ttyC%d\n", info->line); /* */
4383 #endif
4385 if (serial_paranoia_check(info, tty->device, "cy_hangup"))
4386 return;
4388 cy_flush_buffer(tty);
4389 shutdown(info);
4390 info->event = 0;
4391 info->count = 0;
4392 #ifdef CY_DEBUG_COUNT
4393 printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
4394 #endif
4395 info->tty = 0;
4396 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
4397 wake_up_interruptible(&info->open_wait);
4398 } /* cy_hangup */
4402 * ---------------------------------------------------------------------
4403 * cy_init() and friends
4405 * cy_init() is called at boot-time to initialize the serial driver.
4406 * ---------------------------------------------------------------------
4409 /* initialize chips on Cyclom-Y card -- return number of valid
4410 chips (which is number of ports/4) */
4411 __initfunc(static unsigned short
4412 cyy_init_card(volatile ucchar *true_base_addr,int index))
4414 unsigned int chip_number;
4415 volatile ucchar* base_addr;
4417 cy_writeb((u_long)true_base_addr+(Cy_HwReset<<index), 0);
4418 /* Cy_HwReset is 0x1400 */
4419 cy_writeb((u_long)true_base_addr+(Cy_ClrIntr<<index), 0);
4420 /* Cy_ClrIntr is 0x1800 */
4421 udelay(500L);
4423 for(chip_number=0; chip_number<CyMAX_CHIPS_PER_CARD; chip_number++){
4424 base_addr = true_base_addr
4425 + (cy_chip_offset[chip_number]<<index);
4426 mdelay(1);
4427 if(cy_readb(base_addr+(CyCCR<<index)) != 0x00){
4428 /*************
4429 printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
4430 chip_number, (unsigned long)base_addr);
4431 *************/
4432 return chip_number;
4435 cy_writeb((u_long)base_addr+(CyGFRCR<<index), 0);
4436 udelay(10L);
4438 /* The Cyclom-16Y does not decode address bit 9 and therefore
4439 cannot distinguish between references to chip 0 and a non-
4440 existent chip 4. If the preceding clearing of the supposed
4441 chip 4 GFRCR register appears at chip 0, there is no chip 4
4442 and this must be a Cyclom-16Y, not a Cyclom-32Ye.
4444 if (chip_number == 4
4445 && cy_readb(true_base_addr
4446 + (cy_chip_offset[0]<<index)
4447 + (CyGFRCR<<index)) == 0){
4448 return chip_number;
4451 cy_writeb((u_long)base_addr+(CyCCR<<index), CyCHIP_RESET);
4452 mdelay(1);
4454 if(cy_readb(base_addr+(CyGFRCR<<index)) == 0x00){
4456 printk(" chip #%d at %#6lx is not responding ",
4457 chip_number, (unsigned long)base_addr);
4458 printk("(GFRCR stayed 0)\n",
4460 return chip_number;
4462 if((0xf0 & (cy_readb(base_addr+(CyGFRCR<<index)))) != 0x40){
4464 printk(" chip #%d at %#6lx is not valid (GFRCR == %#2x)\n",
4465 chip_number, (unsigned long)base_addr,
4466 base_addr[CyGFRCR<<index]);
4468 return chip_number;
4470 cy_writeb((u_long)base_addr+(CyGCR<<index), CyCH0_SERIAL);
4471 if (cy_readb(base_addr+(CyGFRCR<<index)) >= CD1400_REV_J){
4472 /* It is a CD1400 rev. J or later */
4473 /* Impossible to reach 5ms with this chip.
4474 Changed to 2ms instead (f = 500 Hz). */
4475 cy_writeb((u_long)base_addr+(CyPPR<<index), CyCLOCK_60_2MS);
4476 } else {
4477 /* f = 200 Hz */
4478 cy_writeb((u_long)base_addr+(CyPPR<<index), CyCLOCK_25_5MS);
4482 printk(" chip #%d at %#6lx is rev 0x%2x\n",
4483 chip_number, (unsigned long)base_addr,
4484 cy_readb(base_addr+(CyGFRCR<<index)));
4487 return chip_number;
4488 } /* cyy_init_card */
4490 #ifndef CONFIG_COBALT_27
4492 * ---------------------------------------------------------------------
4493 * cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
4494 * sets global variables and return the number of ISA boards found.
4495 * ---------------------------------------------------------------------
4497 __initfunc(static int
4498 cy_detect_isa(void))
4500 unsigned short cy_isa_irq,nboard;
4501 volatile ucchar *cy_isa_address;
4502 unsigned short i,j,cy_isa_nchan;
4504 nboard = 0;
4506 /* scan the address table probing for Cyclom-Y/ISA boards */
4507 for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
4508 cy_isa_address = cy_isa_addresses[i];
4509 if (cy_isa_address == 0x0000) {
4510 return(nboard);
4513 /* probe for CD1400... */
4515 #if !defined(__alpha__)
4516 cy_isa_address = ioremap((ulong)cy_isa_address, CyISA_Ywin);
4517 #endif
4518 cy_isa_nchan = CyPORTS_PER_CHIP *
4519 cyy_init_card(cy_isa_address,0);
4520 if (cy_isa_nchan == 0) {
4521 continue;
4524 /* find out the board's irq by probing */
4525 cy_isa_irq = do_auto_irq(cy_isa_address);
4526 if (cy_isa_irq == 0) {
4527 printk("Cyclom-Y/ISA found at 0x%lx ",
4528 (unsigned long) cy_isa_address);
4529 printk("but the IRQ could not be detected.\n");
4530 continue;
4533 if((cy_next_channel+cy_isa_nchan) > NR_PORTS) {
4534 printk("Cyclom-Y/ISA found at 0x%lx ",
4535 (unsigned long) cy_isa_address);
4536 printk("but no more channels are available.\n");
4537 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
4538 return(nboard);
4540 /* fill the next cy_card structure available */
4541 for (j = 0 ; j < NR_CARDS ; j++) {
4542 if (cy_card[j].base_addr == 0) break;
4544 if (j == NR_CARDS) { /* no more cy_cards available */
4545 printk("Cyclom-Y/ISA found at 0x%lx ",
4546 (unsigned long) cy_isa_address);
4547 printk("but no more cards can be used .\n");
4548 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4549 return(nboard);
4552 /* allocate IRQ */
4553 if(request_irq(cy_isa_irq, cyy_interrupt,
4554 SA_INTERRUPT, "Cyclom-Y", &cy_card[j]))
4556 printk("Cyclom-Y/ISA found at 0x%lx ",
4557 (unsigned long) cy_isa_address);
4558 printk("but could not allocate IRQ#%d.\n",
4559 cy_isa_irq);
4560 return(nboard);
4563 /* set cy_card */
4564 cy_card[j].base_addr = (u_long) cy_isa_address;
4565 cy_card[j].ctl_addr = 0;
4566 cy_card[j].irq = (int) cy_isa_irq;
4567 cy_card[j].bus_index = 0;
4568 cy_card[j].first_line = cy_next_channel;
4569 cy_card[j].num_chips = cy_isa_nchan/4;
4570 nboard++;
4572 /* print message */
4573 printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ",
4574 j+1, (unsigned long) cy_isa_address,
4575 (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
4576 cy_isa_irq);
4577 printk("%d channels starting from port %d.\n",
4578 cy_isa_nchan, cy_next_channel);
4579 cy_next_channel += cy_isa_nchan;
4581 return(nboard);
4583 } /* cy_detect_isa */
4584 #endif /* CONFIG_COBALT_27 */
4586 static void plx_init(uclong addr, uclong initctl)
4588 /* Reset PLX */
4589 cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
4590 udelay(100L);
4591 cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
4593 /* Reload Config. Registers from EEPROM */
4594 cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
4595 udelay(100L);
4596 cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
4600 * ---------------------------------------------------------------------
4601 * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI.
4602 * sets global variables and return the number of PCI boards found.
4603 * ---------------------------------------------------------------------
4605 __initfunc(static int
4606 cy_detect_pci(void))
4608 #ifdef CONFIG_PCI
4610 struct pci_dev *pdev = NULL;
4611 unsigned char cyy_rev_id;
4612 unsigned char cy_pci_irq = 0;
4613 uclong cy_pci_addr0, cy_pci_addr1, cy_pci_addr2;
4614 unsigned short i,j,cy_pci_nchan, plx_ver;
4615 unsigned short device_id,dev_index = 0;
4616 uclong mailbox;
4617 uclong Ze_addr0[NR_CARDS], Ze_addr2[NR_CARDS], ZeIndex = 0;
4619 if(pci_present() == 0) { /* PCI bus not present */
4620 return(0);
4622 for (i = 0; i < NR_CARDS; i++) {
4623 /* look for a Cyclades card by vendor and device id */
4624 while((device_id = cy_pci_dev_id[dev_index]) != 0) {
4625 if((pdev = pci_find_device(PCI_VENDOR_ID_CYCLADES,
4626 device_id, pdev)) == NULL) {
4627 dev_index++; /* try next device id */
4628 } else {
4629 break; /* found a board */
4633 if (device_id == 0)
4634 break;
4636 /* read PCI configuration area */
4637 cy_pci_irq = pdev->irq;
4638 cy_pci_addr0 = pdev->base_address[0];
4639 cy_pci_addr1 = pdev->base_address[1];
4640 cy_pci_addr2 = pdev->base_address[2];
4641 pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
4643 device_id &= ~PCI_DEVICE_ID_MASK;
4645 if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo)
4646 || (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){
4647 #ifdef CY_PCI_DEBUG
4648 printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
4649 pdev->bus->number, pdev->devfn);
4650 printk("rev_id=%d) IRQ%d\n",
4651 cyy_rev_id, (int)cy_pci_irq);
4652 printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
4653 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4654 #endif
4655 cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
4656 cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
4658 if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
4659 printk(" Warning: PCI I/O bit incorrectly set. "
4660 "Ignoring it...\n");
4661 cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
4664 #if defined(__alpha__)
4665 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
4666 printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
4667 pdev->bus->number, pdev->devfn);
4668 printk("rev_id=%d) IRQ%d\n",
4669 cyy_rev_id, (int)cy_pci_irq);
4670 printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
4671 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4672 printk("Cyclom-Y/PCI not supported for low addresses in "
4673 "Alpha systems.\n");
4674 i--;
4675 continue;
4677 #else
4678 cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Yctl);
4679 cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ywin);
4680 #endif
4682 #ifdef CY_PCI_DEBUG
4683 printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
4684 (u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
4685 #endif
4686 cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
4687 cyy_init_card((volatile ucchar *)cy_pci_addr2, 1));
4688 if(cy_pci_nchan == 0) {
4689 printk("Cyclom-Y PCI host card with ");
4690 printk("no Serial-Modules at 0x%lx.\n",
4691 (ulong) cy_pci_addr2);
4692 i--;
4693 continue;
4695 if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
4696 printk("Cyclom-Y/PCI found at 0x%lx ",
4697 (ulong) cy_pci_addr2);
4698 printk("but no channels are available.\n");
4699 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
4700 return(i);
4702 /* fill the next cy_card structure available */
4703 for (j = 0 ; j < NR_CARDS ; j++) {
4704 if (cy_card[j].base_addr == 0) break;
4706 if (j == NR_CARDS) { /* no more cy_cards available */
4707 printk("Cyclom-Y/PCI found at 0x%lx ",
4708 (ulong) cy_pci_addr2);
4709 printk("but no more cards can be used.\n");
4710 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4711 return(i);
4714 /* allocate IRQ */
4715 if(request_irq(cy_pci_irq, cyy_interrupt,
4716 SA_SHIRQ, "Cyclom-Y", &cy_card[j]))
4718 printk("Cyclom-Y/PCI found at 0x%lx ",
4719 (ulong) cy_pci_addr2);
4720 printk("but could not allocate IRQ%d.\n",
4721 cy_pci_irq);
4722 return(i);
4725 /* set cy_card */
4726 cy_card[j].base_addr = (ulong)cy_pci_addr2;
4727 cy_card[j].ctl_addr = (ulong)cy_pci_addr0;
4728 cy_card[j].irq = (int) cy_pci_irq;
4729 cy_card[j].bus_index = 1;
4730 cy_card[j].first_line = cy_next_channel;
4731 cy_card[j].num_chips = cy_pci_nchan/4;
4733 /* enable interrupts in the PCI interface */
4734 plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
4735 switch (plx_ver) {
4736 case PLX_9050:
4738 plx_init(cy_pci_addr0, 0x50);
4740 cy_writew(cy_pci_addr0+0x4c,
4741 cy_readw(cy_pci_addr0+0x4c)|0x0040);
4742 break;
4744 case PLX_9060:
4745 case PLX_9080:
4746 default: /* Old boards, use PLX_9060 */
4748 plx_init(cy_pci_addr0, 0x6c);
4750 cy_writew(cy_pci_addr0+0x68,
4751 cy_readw(cy_pci_addr0+0x68)|0x0900);
4752 break;
4755 /* print message */
4756 printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
4757 j+1,
4758 (ulong)cy_pci_addr2,
4759 (ulong)(cy_pci_addr2 + CyPCI_Ywin - 1),
4760 (int)cy_pci_irq);
4761 printk("%d channels starting from port %d.\n",
4762 cy_pci_nchan, cy_next_channel);
4764 cy_next_channel += cy_pci_nchan;
4765 }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo){
4766 /* print message */
4767 printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
4768 pdev->bus->number, pdev->devfn);
4769 printk("rev_id=%d) IRQ%d\n",
4770 cyy_rev_id, (int)cy_pci_irq);
4771 printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
4772 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4773 printk("Cyclades-Z/PCI not supported for low addresses\n");
4774 break;
4775 }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){
4776 #ifdef CY_PCI_DEBUG
4777 printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
4778 pdev->bus->number, pdev->devfn);
4779 printk("rev_id=%d) IRQ%d\n",
4780 cyy_rev_id, (int)cy_pci_irq);
4781 printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
4782 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4783 #endif
4784 cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
4785 #if !defined(__alpha__)
4786 cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Zctl);
4787 #endif
4789 plx_init(cy_pci_addr0, 0x6c);
4791 mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
4792 cy_pci_addr0)->mail_box_0);
4793 cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
4795 if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
4796 printk(" Warning: PCI I/O bit incorrectly set. "
4797 "Ignoring it...\n");
4798 cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
4800 if (mailbox == ZE_V1) {
4801 #if !defined(__alpha__)
4802 cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ze_win);
4803 #endif
4804 if (ZeIndex == NR_CARDS) {
4805 printk("Cyclades-Ze/PCI found at 0x%lx ",
4806 (ulong)cy_pci_addr2);
4807 printk("but no more cards can be used.\n");
4808 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4809 } else {
4810 Ze_addr0[ZeIndex] = cy_pci_addr0;
4811 Ze_addr2[ZeIndex] = cy_pci_addr2;
4812 ZeIndex++;
4814 i--;
4815 continue;
4816 } else {
4817 #if !defined(__alpha__)
4818 cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Zwin);
4819 #endif
4822 #ifdef CY_PCI_DEBUG
4823 printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
4824 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4825 if (mailbox == ZO_V1) {
4826 cy_writel(&((struct RUNTIME_9060 *)
4827 (cy_pci_addr0))->loc_addr_base, WIN_CREG);
4828 PAUSE
4829 printk("Cyclades-8Zo/PCI: FPGA id %lx, ver %lx\n",
4830 (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *)
4831 (cy_pci_addr2))->fpga_id)),
4832 (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *)
4833 (cy_pci_addr2))->fpga_version)));
4834 cy_writel(&((struct RUNTIME_9060 *)
4835 (cy_pci_addr0))->loc_addr_base, WIN_RAM);
4836 } else {
4837 printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n");
4839 #endif
4840 /* The following clears the firmware id word. This ensures
4841 that the driver will not attempt to talk to the board
4842 until it has been properly initialized.
4844 PAUSE
4845 if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
4846 cy_writel((ulong)(cy_pci_addr2+ID_ADDRESS), 0L);
4848 /* This must be a Cyclades-8Zo/PCI. The extendable
4849 version will have a different device_id and will
4850 be allocated its maximum number of ports. */
4851 cy_pci_nchan = 8;
4853 if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
4854 printk("Cyclades-8Zo/PCI found at 0x%lx ",
4855 (ulong)cy_pci_addr2);
4856 printk("but no channels are available.\n");
4857 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
4858 return(i);
4861 /* fill the next cy_card structure available */
4862 for (j = 0 ; j < NR_CARDS ; j++) {
4863 if (cy_card[j].base_addr == 0) break;
4865 if (j == NR_CARDS) { /* no more cy_cards available */
4866 printk("Cyclades-8Zo/PCI found at 0x%lx ",
4867 (ulong)cy_pci_addr2);
4868 printk("but no more cards can be used.\n");
4869 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4870 return(i);
4873 /* allocate IRQ only if board has an IRQ */
4874 if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
4875 if(request_irq(cy_pci_irq,cyz_interrupt,
4876 SA_SHIRQ,"Cyclades-Z",&cy_card[j]))
4878 printk("Could not allocate IRQ%d ",
4879 cy_pci_irq);
4880 printk("for Cyclades-8Zo/PCI at 0x%lx.\n",
4881 (ulong)cy_pci_addr2);
4882 return(i);
4887 /* set cy_card */
4888 cy_card[j].base_addr = cy_pci_addr2;
4889 cy_card[j].ctl_addr = cy_pci_addr0;
4890 cy_card[j].irq = (int) cy_pci_irq;
4891 cy_card[j].bus_index = 1;
4892 cy_card[j].first_line = cy_next_channel;
4893 cy_card[j].num_chips = -1;
4895 /* print message */
4896 /* don't report IRQ if board is no IRQ */
4897 if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
4898 printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
4899 j+1,(ulong)cy_pci_addr2,
4900 (ulong)(cy_pci_addr2 + CyPCI_Zwin - 1),
4901 (int)cy_pci_irq);
4902 }else{
4903 printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
4904 j+1,(ulong)cy_pci_addr2,
4905 (ulong)(cy_pci_addr2 + CyPCI_Zwin - 1));
4907 printk("%d channels starting from port %d.\n",
4908 cy_pci_nchan,cy_next_channel);
4909 cy_next_channel += cy_pci_nchan;
4913 for (; ZeIndex != 0 && i < NR_CARDS; i++) {
4914 cy_pci_addr0 = Ze_addr0[0];
4915 cy_pci_addr2 = Ze_addr2[0];
4916 for (j = 0 ; j < ZeIndex-1 ; j++) {
4917 Ze_addr0[j] = Ze_addr0[j+1];
4918 Ze_addr2[j] = Ze_addr2[j+1];
4920 ZeIndex--;
4921 mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
4922 cy_pci_addr0)->mail_box_0);
4923 #ifdef CY_PCI_DEBUG
4924 printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
4925 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
4926 printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n");
4927 #endif
4928 /* The following clears the firmware id word. This ensures
4929 that the driver will not attempt to talk to the board
4930 until it has been properly initialized.
4932 PAUSE
4933 /* This must be the new Cyclades-Ze/PCI. */
4934 cy_pci_nchan = ZE_V1_NPORTS;
4936 if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
4937 printk("Cyclades-Ze/PCI found at 0x%lx ",
4938 (ulong)cy_pci_addr2);
4939 printk("but no channels are available.\n");
4940 printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
4941 return(i);
4944 /* fill the next cy_card structure available */
4945 for (j = 0 ; j < NR_CARDS ; j++) {
4946 if (cy_card[j].base_addr == 0) break;
4948 if (j == NR_CARDS) { /* no more cy_cards available */
4949 printk("Cyclades-Ze/PCI found at 0x%lx ",
4950 (ulong)cy_pci_addr2);
4951 printk("but no more cards can be used.\n");
4952 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4953 return(i);
4956 /* allocate IRQ only if board has an IRQ */
4957 if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
4958 if(request_irq(cy_pci_irq,cyz_interrupt,
4959 SA_SHIRQ,"Cyclades-Z",&cy_card[j]))
4961 printk("Could not allocate IRQ%d ",
4962 cy_pci_irq);
4963 printk("for Cyclades-Ze/PCI at 0x%lx.\n",
4964 (ulong) cy_pci_addr2);
4965 return(i);
4969 /* set cy_card */
4970 cy_card[j].base_addr = cy_pci_addr2;
4971 cy_card[j].ctl_addr = cy_pci_addr0;
4972 cy_card[j].irq = (int) cy_pci_irq;
4973 cy_card[j].bus_index = 1;
4974 cy_card[j].first_line = cy_next_channel;
4975 cy_card[j].num_chips = -1;
4977 /* print message */
4978 /* don't report IRQ if board is no IRQ */
4979 if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
4980 printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
4981 j+1,(ulong)cy_pci_addr2,
4982 (ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1),
4983 (int)cy_pci_irq);
4984 }else{
4985 printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
4986 j+1,(ulong)cy_pci_addr2,
4987 (ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1));
4989 printk("%d channels starting from port %d.\n",
4990 cy_pci_nchan,cy_next_channel);
4991 cy_next_channel += cy_pci_nchan;
4993 if (ZeIndex != 0) {
4994 printk("Cyclades-Ze/PCI found at 0x%x ",
4995 (unsigned int) Ze_addr2[0]);
4996 printk("but no more cards can be used.\n");
4997 printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
4999 return(i);
5000 #else
5001 return(0);
5002 #endif /* ifdef CONFIG_PCI */
5003 } /* cy_detect_pci */
5007 * This routine prints out the appropriate serial driver version number
5008 * and identifies which options were configured into this driver.
5010 static inline void
5011 show_version(void)
5013 char *rcsvers, *rcsdate, *tmp;
5014 rcsvers = strchr(rcsid, ' '); rcsvers++;
5015 tmp = strchr(rcsvers, ' '); *tmp++ = '\0';
5016 rcsdate = strchr(tmp, ' '); rcsdate++;
5017 tmp = strrchr(rcsdate, ' '); *tmp = '\0';
5018 printk("Cyclades driver %s %s\n",
5019 rcsvers, rcsdate);
5020 printk(" built %s %s\n",
5021 __DATE__, __TIME__);
5022 } /* show_version */
5024 static int
5025 cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
5026 int *eof, void *data)
5028 struct cyclades_port *info;
5029 int i;
5030 int len=0;
5031 off_t begin=0;
5032 off_t pos=0;
5033 int size;
5034 __u32 cur_jifs = jiffies;
5036 size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn IdleIn Overruns Ldisc\n");
5038 pos += size;
5039 len += size;
5041 /* Output one line for each known port */
5042 for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) {
5043 info = &cy_port[i];
5045 if (info->count)
5046 size = sprintf(buf+len,
5047 "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
5048 info->line,
5049 JIFFIES_DIFF(info->idle_stats.in_use, cur_jifs) / HZ,
5050 info->idle_stats.xmit_bytes,
5051 JIFFIES_DIFF(info->idle_stats.xmit_idle, cur_jifs) / HZ,
5052 info->idle_stats.recv_bytes,
5053 JIFFIES_DIFF(info->idle_stats.recv_idle, cur_jifs) / HZ,
5054 info->idle_stats.overruns,
5055 (long) info->tty->ldisc.num);
5056 else
5057 size = sprintf(buf+len,
5058 "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
5059 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
5060 len += size;
5061 pos = begin + len;
5063 if (pos < offset) {
5064 len = 0;
5065 begin = pos;
5067 if (pos > offset + length)
5068 goto done;
5070 *eof = 1;
5071 done:
5072 *start = buf + (offset - begin); /* Start of wanted data */
5073 len -= (offset - begin); /* Start slop */
5074 if (len > length)
5075 len = length; /* Ending slop */
5076 if (len < 0)
5077 len = 0;
5078 return len;
5081 /* The serial driver boot-time initialization code!
5082 Hardware I/O ports are mapped to character special devices on a
5083 first found, first allocated manner. That is, this code searches
5084 for Cyclom cards in the system. As each is found, it is probed
5085 to discover how many chips (and thus how many ports) are present.
5086 These ports are mapped to the tty ports 32 and upward in monotonic
5087 fashion. If an 8-port card is replaced with a 16-port card, the
5088 port mapping on a following card will shift.
5090 This approach is different from what is used in the other serial
5091 device driver because the Cyclom is more properly a multiplexer,
5092 not just an aggregation of serial ports on one card.
5094 If there are more cards with more ports than have been
5095 statically allocated above, a warning is printed and the
5096 extra ports are ignored.
5099 __initfunc(int
5100 cy_init(void))
5102 struct cyclades_port *info;
5103 struct cyclades_card *cinfo;
5104 int number_z_boards = 0;
5105 int board,port,i,index;
5106 unsigned long mailbox;
5107 unsigned short chip_number;
5108 int nports;
5109 #ifdef CY_PROC
5110 struct proc_dir_entry *ent;
5111 #endif
5113 init_bh(CYCLADES_BH, do_cyclades_bh);
5115 show_version();
5117 /* Initialize the tty_driver structure */
5119 memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
5120 cy_serial_driver.magic = TTY_DRIVER_MAGIC;
5121 cy_serial_driver.driver_name = "cyclades";
5122 cy_serial_driver.name = "ttyC";
5123 cy_serial_driver.major = CYCLADES_MAJOR;
5124 cy_serial_driver.minor_start = 0;
5125 cy_serial_driver.num = NR_PORTS;
5126 cy_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
5127 cy_serial_driver.subtype = SERIAL_TYPE_NORMAL;
5128 cy_serial_driver.init_termios = tty_std_termios;
5129 cy_serial_driver.init_termios.c_cflag =
5130 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
5131 cy_serial_driver.flags = TTY_DRIVER_REAL_RAW;
5132 cy_serial_driver.refcount = &serial_refcount;
5133 cy_serial_driver.table = serial_table;
5134 cy_serial_driver.termios = serial_termios;
5135 cy_serial_driver.termios_locked = serial_termios_locked;
5137 cy_serial_driver.open = cy_open;
5138 cy_serial_driver.close = cy_close;
5139 cy_serial_driver.write = cy_write;
5140 cy_serial_driver.put_char = cy_put_char;
5141 cy_serial_driver.flush_chars = cy_flush_chars;
5142 cy_serial_driver.write_room = cy_write_room;
5143 cy_serial_driver.chars_in_buffer = cy_chars_in_buffer;
5144 cy_serial_driver.flush_buffer = cy_flush_buffer;
5145 cy_serial_driver.ioctl = cy_ioctl;
5146 cy_serial_driver.throttle = cy_throttle;
5147 cy_serial_driver.unthrottle = cy_unthrottle;
5148 cy_serial_driver.set_termios = cy_set_termios;
5149 cy_serial_driver.stop = cy_stop;
5150 cy_serial_driver.start = cy_start;
5151 cy_serial_driver.hangup = cy_hangup;
5152 cy_serial_driver.break_ctl = cy_break;
5153 cy_serial_driver.wait_until_sent = cy_wait_until_sent;
5154 cy_serial_driver.read_proc = cyclades_get_proc_info;
5157 * The callout device is just like normal device except for
5158 * major number and the subtype code.
5160 cy_callout_driver = cy_serial_driver;
5161 cy_callout_driver.name = "cub";
5162 cy_callout_driver.major = CYCLADESAUX_MAJOR;
5163 cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
5164 cy_callout_driver.read_proc = 0;
5165 cy_callout_driver.proc_entry = 0;
5168 if (tty_register_driver(&cy_serial_driver))
5169 panic("Couldn't register Cyclades serial driver\n");
5170 if (tty_register_driver(&cy_callout_driver))
5171 panic("Couldn't register Cyclades callout driver\n");
5173 for (i = 0; i < NR_CARDS; i++) {
5174 /* base_addr=0 indicates board not found */
5175 cy_card[i].base_addr = 0;
5178 /* the code below is responsible to find the boards. Each different
5179 type of board has its own detection routine. If a board is found,
5180 the next cy_card structure available is set by the detection
5181 routine. These functions are responsible for checking the
5182 availability of cy_card and cy_port data structures and updating
5183 the cy_next_channel. */
5185 #ifndef CONFIG_COBALT_27
5186 /* look for isa boards */
5187 cy_isa_nboard = cy_detect_isa();
5188 #endif /* CONFIG_COBALT_27 */
5190 /* look for pci boards */
5191 cy_pci_nboard = cy_detect_pci();
5193 cy_nboard = cy_isa_nboard + cy_pci_nboard;
5195 /* invalidate remaining cy_card structures */
5196 for (i = 0 ; i < NR_CARDS ; i++) {
5197 if (cy_card[i].base_addr == 0) {
5198 cy_card[i].first_line = -1;
5199 cy_card[i].ctl_addr = 0;
5200 cy_card[i].irq = 0;
5201 cy_card[i].bus_index = 0;
5202 cy_card[i].first_line = 0;
5203 cy_card[i].num_chips = 0;
5206 /* invalidate remaining cy_port structures */
5207 for (i = cy_next_channel ; i < NR_PORTS ; i++) {
5208 cy_port[i].line = -1;
5209 cy_port[i].magic = -1;
5212 /* initialize per-port data structures for each valid board found */
5213 for (board = 0 ; board < cy_nboard ; board++) {
5214 cinfo = &cy_card[board];
5215 if (cinfo->num_chips == -1){ /* Cyclades-Z */
5216 number_z_boards++;
5217 mailbox = cy_readl(&((struct RUNTIME_9060 *)
5218 cy_card[board].ctl_addr)->mail_box_0);
5219 nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
5220 for (port = cinfo->first_line ;
5221 port < cinfo->first_line + nports;
5222 port++)
5224 info = &cy_port[port];
5225 info->magic = CYCLADES_MAGIC;
5226 info->type = PORT_STARTECH;
5227 info->card = board;
5228 info->line = port;
5229 info->chip_rev = 0;
5230 info->flags = STD_COM_FLAGS;
5231 info->tty = 0;
5232 if (mailbox == ZO_V1)
5233 info->xmit_fifo_size = CYZ_FIFO_SIZE;
5234 else
5235 info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
5236 info->cor1 = 0;
5237 info->cor2 = 0;
5238 info->cor3 = 0;
5239 info->cor4 = 0;
5240 info->cor5 = 0;
5241 info->tbpr = 0;
5242 info->tco = 0;
5243 info->rbpr = 0;
5244 info->rco = 0;
5245 info->close_delay = 5*HZ/10;
5246 info->closing_wait = CLOSING_WAIT_DELAY;
5247 info->x_char = 0;
5248 info->event = 0;
5249 info->count = 0;
5250 #ifdef CY_DEBUG_COUNT
5251 // printk("cyc:cy_init(1) setting Z count to 0\n");
5252 #endif
5253 info->blocked_open = 0;
5254 info->default_threshold = 0;
5255 info->default_timeout = 0;
5256 info->tqueue.routine = do_softint;
5257 info->tqueue.data = info;
5258 info->callout_termios =
5259 cy_callout_driver.init_termios;
5260 info->normal_termios =
5261 cy_serial_driver.init_termios;
5262 init_waitqueue_head(&info->open_wait);
5263 init_waitqueue_head(&info->close_wait);
5264 init_waitqueue_head(&info->shutdown_wait);
5265 /* info->session */
5266 /* info->pgrp */
5267 info->read_status_mask = 0;
5268 /* info->timeout */
5269 /* Bentson's vars */
5270 info->jiffies[0] = 0;
5271 info->jiffies[1] = 0;
5272 info->jiffies[2] = 0;
5273 info->rflush_count = 0;
5275 continue;
5276 }else{ /* Cyclom-Y of some kind*/
5277 index = cinfo->bus_index;
5278 for (port = cinfo->first_line ;
5279 port < cinfo->first_line + 4*cinfo->num_chips ;
5280 port++)
5282 info = &cy_port[port];
5283 info->magic = CYCLADES_MAGIC;
5284 info->type = PORT_CIRRUS;
5285 info->card = board;
5286 info->line = port;
5287 info->flags = STD_COM_FLAGS;
5288 info->tty = 0;
5289 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
5290 info->cor1 = CyPARITY_NONE|Cy_1_STOP|Cy_8_BITS;
5291 info->cor2 = CyETC;
5292 info->cor3 = 0x08; /* _very_ small rcv threshold */
5293 info->cor4 = 0;
5294 info->cor5 = 0;
5295 info->close_delay = 5*HZ/10;
5296 info->closing_wait = CLOSING_WAIT_DELAY;
5297 chip_number = (port - cinfo->first_line) / 4;
5298 if ((info->chip_rev = cy_readb(cinfo->base_addr +
5299 (cy_chip_offset[chip_number]<<index) +
5300 (CyGFRCR<<index))) >= CD1400_REV_J) {
5301 /* It is a CD1400 rev. J or later */
5302 info->tbpr = baud_bpr_60[13]; /* Tx BPR */
5303 info->tco = baud_co_60[13]; /* Tx CO */
5304 info->rbpr = baud_bpr_60[13]; /* Rx BPR */
5305 info->rco = baud_co_60[13]; /* Rx CO */
5306 info->rflow = 0;
5307 info->rtsdtr_inv = 1;
5308 } else {
5309 info->tbpr = baud_bpr_25[13]; /* Tx BPR */
5310 info->tco = baud_co_25[13]; /* Tx CO */
5311 info->rbpr = baud_bpr_25[13]; /* Rx BPR */
5312 info->rco = baud_co_25[13]; /* Rx CO */
5313 info->rflow = 0;
5314 info->rtsdtr_inv = 0;
5316 info->x_char = 0;
5317 info->event = 0;
5318 info->count = 0;
5319 #ifdef CY_DEBUG_COUNT
5320 // printk("cyc:cy_init(2) setting Y count to 0\n");
5321 #endif
5322 info->blocked_open = 0;
5323 info->default_threshold = 0;
5324 info->default_timeout = 0;
5325 info->tqueue.routine = do_softint;
5326 info->tqueue.data = info;
5327 info->callout_termios =
5328 cy_callout_driver.init_termios;
5329 info->normal_termios =
5330 cy_serial_driver.init_termios;
5331 init_waitqueue_head(&info->open_wait);
5332 init_waitqueue_head(&info->close_wait);
5333 init_waitqueue_head(&info->shutdown_wait);
5334 /* info->session */
5335 /* info->pgrp */
5336 info->read_status_mask =
5337 CyTIMEOUT| CySPECHAR| CyBREAK
5338 | CyPARITY| CyFRAME| CyOVERRUN;
5339 /* info->timeout */
5344 if ( number_z_boards && !cyz_timeron){
5345 cyz_timeron++;
5346 cyz_timerlist.expires = jiffies + 1;
5347 add_timer(&cyz_timerlist);
5348 #ifdef CY_PCI_DEBUG
5349 printk("Cyclades-Z polling initialized\n");
5350 #endif
5353 #ifdef CY_PROC
5354 ent = create_proc_entry("cyclades", S_IFREG | S_IRUGO, 0);
5355 ent->read_proc = cyclades_get_proc_info;
5356 #endif
5358 return 0;
5360 } /* cy_init */
5362 #ifdef MODULE
5363 /* See linux/drivers/char/riscom.c for ideas on how to
5364 pass additional base addresses to the driver!!! */
5366 init_module(void)
5368 return(cy_init());
5369 } /* init_module */
5371 void
5372 cleanup_module(void)
5374 int i;
5375 int e1, e2;
5376 unsigned long flags;
5378 if (cyz_timeron){
5379 cyz_timeron = 0;
5380 del_timer(&cyz_timerlist);
5383 save_flags(flags); cli();
5384 remove_bh(CYCLADES_BH);
5386 if ((e1 = tty_unregister_driver(&cy_serial_driver)))
5387 printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
5388 e1);
5389 if ((e2 = tty_unregister_driver(&cy_callout_driver)))
5390 printk("cyc: failed to unregister Cyclades callout driver (%d)\n",
5391 e2);
5393 restore_flags(flags);
5395 for (i = 0; i < NR_CARDS; i++) {
5396 if (cy_card[i].base_addr != 0
5397 && cy_card[i].irq)
5399 free_irq(cy_card[i].irq, &cy_card[i]);
5402 if (tmp_buf) {
5403 free_page((unsigned long) tmp_buf);
5404 tmp_buf = NULL;
5406 #ifdef CY_PROC
5407 remove_proc_entry("cyclades", 0);
5408 #endif
5410 } /* cleanup_module */
5411 #else
5412 /* called by linux/init/main.c to parse command line options */
5413 void
5414 cy_setup(char *str, int *ints)
5416 #ifndef CONFIG_COBALT_27
5417 int i, j;
5419 for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
5420 if (cy_isa_addresses[i] == 0) break;
5422 for (j = 1; j <= ints[0]; j++){
5423 if ( i < NR_ISA_ADDRS ){
5424 cy_isa_addresses[i++] = (unsigned char *)(ints[j]);
5427 #endif /* CONFIG_COBALT_27 */
5429 } /* cy_setup */
5430 #endif
5433 #ifdef CYCLOM_SHOW_STATUS
5434 static void
5435 show_status(int line_num)
5437 unsigned char *base_addr;
5438 int card,chip,channel,index;
5439 struct cyclades_port * info;
5440 unsigned long flags;
5442 info = &cy_port[line_num];
5443 card = info->card;
5444 index = cy_card[card].bus_index;
5445 channel = (info->line) - (cy_card[card].first_line);
5446 chip = channel>>2;
5447 channel &= 0x03;
5448 printk(" card %d, chip %d, channel %d\n", card, chip, channel);/**/
5450 printk(" cy_card\n");
5451 printk(" irq base_addr num_chips first_line = %d %lx %d %d\n",
5452 cy_card[card].irq, (long)cy_card[card].base_addr,
5453 cy_card[card].num_chips, cy_card[card].first_line);
5455 printk(" cy_port\n");
5456 printk(" card line flags = %d %d %x\n",
5457 info->card, info->line, info->flags);
5458 printk(" *tty read_status_mask timeout xmit_fifo_size ",
5459 printk("= %lx %x %x %x\n",
5460 (long)info->tty, info->read_status_mask,
5461 info->timeout, info->xmit_fifo_size);
5462 printk(" cor1,cor2,cor3,cor4,cor5 = %x %x %x %x %x\n",
5463 info->cor1, info->cor2, info->cor3, info->cor4, info->cor5);
5464 printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n",
5465 info->tbpr, info->tco, info->rbpr, info->rco);
5466 printk(" close_delay event count = %d %d %d\n",
5467 info->close_delay, info->event, info->count);
5468 printk(" x_char blocked_open = %x %x\n",
5469 info->x_char, info->blocked_open);
5470 printk(" session pgrp open_wait = %lx %lx %lx\n",
5471 info->session, info->pgrp, (long)info->open_wait);
5474 save_flags(flags); cli();
5476 base_addr = (unsigned char*)
5477 (cy_card[card].base_addr
5478 + (cy_chip_offset[chip]<<index));
5480 /* Global Registers */
5482 printk(" CyGFRCR %x\n", cy_readb(base_addr + CyGFRCR<<index));
5483 printk(" CyCAR %x\n", cy_readb(base_addr + CyCAR<<index));
5484 printk(" CyGCR %x\n", cy_readb(base_addr + CyGCR<<index));
5485 printk(" CySVRR %x\n", cy_readb(base_addr + CySVRR<<index));
5486 printk(" CyRICR %x\n", cy_readb(base_addr + CyRICR<<index));
5487 printk(" CyTICR %x\n", cy_readb(base_addr + CyTICR<<index));
5488 printk(" CyMICR %x\n", cy_readb(base_addr + CyMICR<<index));
5489 printk(" CyRIR %x\n", cy_readb(base_addr + CyRIR<<index));
5490 printk(" CyTIR %x\n", cy_readb(base_addr + CyTIR<<index));
5491 printk(" CyMIR %x\n", cy_readb(base_addr + CyMIR<<index));
5492 printk(" CyPPR %x\n", cy_readb(base_addr + CyPPR<<index));
5494 cy_writeb(base_addr + CyCAR<<index, (u_char)channel);
5496 /* Virtual Registers */
5498 printk(" CyRIVR %x\n", cy_readb(base_addr + CyRIVR<<index));
5499 printk(" CyTIVR %x\n", cy_readb(base_addr + CyTIVR<<index));
5500 printk(" CyMIVR %x\n", cy_readb(base_addr + CyMIVR<<index));
5501 printk(" CyMISR %x\n", cy_readb(base_addr + CyMISR<<index));
5503 /* Channel Registers */
5505 printk(" CyCCR %x\n", cy_readb(base_addr + CyCCR<<index));
5506 printk(" CySRER %x\n", cy_readb(base_addr + CySRER<<index));
5507 printk(" CyCOR1 %x\n", cy_readb(base_addr + CyCOR1<<index));
5508 printk(" CyCOR2 %x\n", cy_readb(base_addr + CyCOR2<<index));
5509 printk(" CyCOR3 %x\n", cy_readb(base_addr + CyCOR3<<index));
5510 printk(" CyCOR4 %x\n", cy_readb(base_addr + CyCOR4<<index));
5511 printk(" CyCOR5 %x\n", cy_readb(base_addr + CyCOR5<<index));
5512 printk(" CyCCSR %x\n", cy_readb(base_addr + CyCCSR<<index));
5513 printk(" CyRDCR %x\n", cy_readb(base_addr + CyRDCR<<index));
5514 printk(" CySCHR1 %x\n", cy_readb(base_addr + CySCHR1<<index));
5515 printk(" CySCHR2 %x\n", cy_readb(base_addr + CySCHR2<<index));
5516 printk(" CySCHR3 %x\n", cy_readb(base_addr + CySCHR3<<index));
5517 printk(" CySCHR4 %x\n", cy_readb(base_addr + CySCHR4<<index));
5518 printk(" CySCRL %x\n", cy_readb(base_addr + CySCRL<<index));
5519 printk(" CySCRH %x\n", cy_readb(base_addr + CySCRH<<index));
5520 printk(" CyLNC %x\n", cy_readb(base_addr + CyLNC<<index));
5521 printk(" CyMCOR1 %x\n", cy_readb(base_addr + CyMCOR1<<index));
5522 printk(" CyMCOR2 %x\n", cy_readb(base_addr + CyMCOR2<<index));
5523 printk(" CyRTPR %x\n", cy_readb(base_addr + CyRTPR<<index));
5524 printk(" CyMSVR1 %x\n", cy_readb(base_addr + CyMSVR1<<index));
5525 printk(" CyMSVR2 %x\n", cy_readb(base_addr + CyMSVR2<<index));
5526 printk(" CyRBPR %x\n", cy_readb(base_addr + CyRBPR<<index));
5527 printk(" CyRCOR %x\n", cy_readb(base_addr + CyRCOR<<index));
5528 printk(" CyTBPR %x\n", cy_readb(base_addr + CyTBPR<<index));
5529 printk(" CyTCOR %x\n", cy_readb(base_addr + CyTCOR<<index));
5531 restore_flags(flags);
5532 } /* show_status */
5533 #endif