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