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