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