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