v2.4.9.9 -> v2.4.9.10
[opensuse:kernel.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.8 $$Date: 2000/07/06 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 Ivan Passos <ivan@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  * Revision 2.3.2.8   2000/07/06 18:14:16 ivan
29  * Fixed the PCI detection function to work properly on Alpha systems.
30  * Implemented support for TIOCSERGETLSR ioctl.
31  * Implemented full support for non-standard baud rates.
32  *
33  * Revision 2.3.2.7   2000/06/01 18:26:34 ivan
34  * Request PLX I/O region, although driver doesn't use it, to avoid
35  * problems with other drivers accessing it.
36  * Removed count for on-board buffer characters in cy_chars_in_buffer
37  * (Cyclades-Z only).
38  *
39  * Revision 2.3.2.6   2000/05/05 13:56:05 ivan
40  * Driver now reports physical instead of virtual memory addresses.
41  * Masks were added to some Cyclades-Z read accesses.
42  * Implemented workaround for PLX9050 bug that would cause a system lockup
43  * in certain systems, depending on the MMIO addresses allocated to the
44  * board.
45  * Changed the Tx interrupt programming in the CD1400 chips to boost up
46  * performance (Cyclom-Y only).
47  * Code is now compliant with the new module interface (module_[init|exit]).
48  * Make use of the PCI helper functions to access PCI resources.
49  * Did some code "housekeeping".
50  *
51  * Revision 2.3.2.5   2000/01/19 14:35:33 ivan
52  * Fixed bug in cy_set_termios on CRTSCTS flag turnoff.
53  *
54  * Revision 2.3.2.4   2000/01/17 09:19:40 ivan
55  * Fixed SMP locking in Cyclom-Y interrupt handler.
56  *
57  * Revision 2.3.2.3   1999/12/28 12:11:39 ivan
58  * Added a new cyclades_card field called nports to allow the driver to
59  * know the exact number of ports found by the Z firmware after its load;
60  * RX buffer contention prevention logic on interrupt op mode revisited
61  * (Cyclades-Z only);
62  * Revisited printk's for Z debug;
63  * Driver now makes sure that the constant SERIAL_XMIT_SIZE is defined;
64  *
65  * Revision 2.3.2.2   1999/10/01 11:27:43 ivan
66  * Fixed bug in cyz_poll that would make all ports but port 0 
67  * unable to transmit/receive data (Cyclades-Z only);
68  * Implemented logic to prevent the RX buffer from being stuck with data
69  * due to a driver / firmware race condition in interrupt op mode
70  * (Cyclades-Z only);
71  * Fixed bug in block_til_ready logic that would lead to a system crash;
72  * Revisited cy_close spinlock usage;
73  *
74  * Revision 2.3.2.1   1999/09/28 11:01:22 ivan
75  * Revisited CONFIG_PCI conditional compilation for PCI board support;
76  * Implemented TIOCGICOUNT and TIOCMIWAIT ioctl support;
77  * _Major_ cleanup on the Cyclades-Z interrupt support code / logic;
78  * Removed CTS handling from the driver -- this is now completely handled
79  * by the firmware (Cyclades-Z only);
80  * Flush RX on-board buffers on a port open (Cyclades-Z only);
81  * Fixed handling of ASYNC_SPD_* TTY flags;
82  * Module unload now unmaps all memory area allocated by ioremap;
83  *
84  * Revision 2.3.1.1   1999/07/15 16:45:53 ivan
85  * Removed CY_PROC conditional compilation;
86  * Implemented SMP-awareness for the driver;
87  * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off] 
88  * functions;
89  * The driver now accepts memory addresses (maddr=0xMMMMM) and IRQs
90  * (irq=NN) as parameters (only for ISA boards);
91  * Fixed bug in set_line_char that would prevent the Cyclades-Z 
92  * ports from being configured at speeds above 115.2Kbps;
93  * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control
94  * switching from working properly;
95  * The driver now only prints IRQ info for the Cyclades-Z if it's 
96  * configured to work in interrupt mode;
97  *
98  * Revision 2.2.2.3   1999/06/28 11:13:29 ivan
99  * Added support for interrupt mode operation for the Z cards;
100  * Removed the driver inactivity control for the Z;
101  * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when 
102  * the Z firmware is not loaded yet;
103  * Replaced the "manual" Z Tx flush buffer by a call to a FW command of 
104  * same functionality;
105  * Implemented workaround for IRQ setting loss on the PCI configuration 
106  * registers after a PCI bridge EEPROM reload (affects PLX9060 only);
107  *
108  * Revision 2.2.2.2  1999/05/14 17:18:15 ivan
109  * /proc entry location changed to /proc/tty/driver/cyclades;
110  * Added support to shared IRQ's (only for PCI boards);
111  * Added support for Cobalt Qube2 systems;
112  * IRQ [de]allocation scheme revisited;
113  * BREAK implementation changed in order to make use of the 'break_ctl'
114  * TTY facility;
115  * Fixed typo in TTY structure field 'driver_name';
116  * Included a PCI bridge reset and EEPROM reload in the board 
117  * initialization code (for both Y and Z series).
118  *
119  * Revision 2.2.2.1  1999/04/08 16:17:43 ivan
120  * Fixed a bug in cy_wait_until_sent that was preventing the port to be 
121  * closed properly after a SIGINT;
122  * Module usage counter scheme revisited;
123  * Added support to the upcoming Y PCI boards (i.e., support to additional
124  * PCI Device ID's).
125  * 
126  * Revision 2.2.1.10 1999/01/20 16:14:29 ivan
127  * Removed all unnecessary page-alignement operations in ioremap calls
128  * (ioremap is currently safe for these operations).
129  *
130  * Revision 2.2.1.9  1998/12/30 18:18:30 ivan
131  * Changed access to PLX PCI bridge registers from I/O to MMIO, in 
132  * order to make PLX9050-based boards work with certain motherboards.
133  *
134  * Revision 2.2.1.8  1998/11/13 12:46:20 ivan
135  * cy_close function now resets (correctly) the tty->closing flag;
136  * JIFFIES_DIFF macro fixed.
137  *
138  * Revision 2.2.1.7  1998/09/03 12:07:28 ivan
139  * Fixed bug in cy_close function, which was not informing HW of
140  * which port should have the reception disabled before doing so;
141  * fixed Cyclom-8YoP hardware detection bug.
142  *
143  * Revision 2.2.1.6  1998/08/20 17:15:39 ivan
144  * Fixed bug in cy_close function, which causes malfunction
145  * of one of the first 4 ports when a higher port is closed
146  * (Cyclom-Y only).
147  *
148  * Revision 2.2.1.5  1998/08/10 18:10:28 ivan
149  * Fixed Cyclom-4Yo hardware detection bug.
150  *
151  * Revision 2.2.1.4  1998/08/04 11:02:50 ivan
152  * /proc/cyclades implementation with great collaboration of 
153  * Marc Lewis <marc@blarg.net>;
154  * cyy_interrupt was changed to avoid occurence of kernel oopses
155  * during PPP operation.
156  *
157  * Revision 2.2.1.3  1998/06/01 12:09:10 ivan
158  * General code review in order to comply with 2.1 kernel standards;
159  * data loss prevention for slow devices revisited (cy_wait_until_sent
160  * was created);
161  * removed conditional compilation for new/old PCI structure support 
162  * (now the driver only supports the new PCI structure).
163  *
164  * Revision 2.2.1.1  1998/03/19 16:43:12 ivan
165  * added conditional compilation for new/old PCI structure support;
166  * removed kernel series (2.0.x / 2.1.x) conditional compilation.
167  *
168  * Revision 2.1.1.3  1998/03/16 18:01:12 ivan
169  * cleaned up the data loss fix;
170  * fixed XON/XOFF handling once more (Cyclades-Z);
171  * general review of the driver routines;
172  * introduction of a mechanism to prevent data loss with slow 
173  * printers, by forcing a delay before closing the port.
174  *
175  * Revision 2.1.1.2  1998/02/17 16:50:00 ivan
176  * fixed detection/handling of new CD1400 in Ye boards;
177  * fixed XON/XOFF handling (Cyclades-Z);
178  * fixed data loss caused by a premature port close;
179  * introduction of a flag that holds the CD1400 version ID per port
180  * (used by the CYGETCD1400VER new ioctl).
181  *
182  * Revision 2.1.1.1  1997/12/03 17:31:19 ivan
183  * Code review for the module cleanup routine;
184  * fixed RTS and DTR status report for new CD1400's in get_modem_info;
185  * includes anonymous changes regarding signal_pending.
186  * 
187  * Revision 2.1  1997/11/01 17:42:41 ivan
188  * Changes in the driver to support Alpha systems (except 8Zo V_1);
189  * BREAK fix for the Cyclades-Z boards;
190  * driver inactivity control by FW implemented;
191  * introduction of flag that allows driver to take advantage of 
192  * a special CD1400 feature related to HW flow control;
193  * added support for the CD1400  rev. J (Cyclom-Y boards);
194  * introduction of ioctls to:
195  *  - control the rtsdtr_inv flag (Cyclom-Y);
196  *  - control the rflow flag (Cyclom-Y);
197  *  - adjust the polling interval (Cyclades-Z);
198  *
199  * Revision 1.36.4.33  1997/06/27 19:00:00  ivan
200  * Fixes related to kernel version conditional 
201  * compilation.
202  *  
203  * Revision 1.36.4.32  1997/06/14 19:30:00  ivan
204  * Compatibility issues between kernels 2.0.x and 
205  * 2.1.x (mainly related to clear_bit function).
206  *  
207  * Revision 1.36.4.31  1997/06/03 15:30:00  ivan
208  * Changes to define the memory window according to the 
209  * board type.
210  *  
211  * Revision 1.36.4.30  1997/05/16 15:30:00  daniel
212  * Changes to support new cycladesZ boards.
213  *
214  * Revision 1.36.4.29  1997/05/12 11:30:00  daniel
215  * Merge of Bentson's and Daniel's version 1.36.4.28.
216  * Corrects bug in cy_detect_pci: check if there are more
217  * ports than the number of static structs allocated.
218  * Warning message during initialization if this driver is
219  * used with the new generation of cycladesZ boards.  Those
220  * will be supported only in next release of the driver.
221  * Corrects bug in cy_detect_pci and cy_detect_isa that
222  * returned wrong number of VALID boards, when a cyclomY
223  * was found with no serial modules connected.
224  * Changes to use current (2.1.x) kernel subroutine names
225  * and created macros for compilation with 2.0.x kernel,
226  * instead of the other way around.
227  *
228  * Revision 1.36.4.28  1997/05/?? ??:00:00  bentson
229  * Change queue_task_irq_off to queue_task_irq.
230  * The inline function queue_task_irq_off (tqueue.h)
231  * was removed from latest releases of 2.1.x kernel.
232  * Use of macro __init to mark the initialization
233  * routines, so memory can be reused.
234  * Also incorporate implementation of critical region
235  * in function cleanup_module() created by anonymous
236  * linuxer.
237  *
238  * Revision 1.36.4.28  1997/04/25 16:00:00  daniel
239  * Change to support new firmware that solves DCD problem:
240  * application could fail to receive SIGHUP signal when DCD
241  * varying too fast.
242  *
243  * Revision 1.36.4.27  1997/03/26 10:30:00  daniel
244  * Changed for support linux versions 2.1.X.
245  * Backward compatible with linux versions 2.0.X.
246  * Corrected illegal use of filler field in
247  * CH_CTRL struct.
248  * Deleted some debug messages.
249  *
250  * Revision 1.36.4.26  1997/02/27 12:00:00  daniel
251  * Included check for NULL tty pointer in cyz_poll.
252  *
253  * Revision 1.36.4.25  1997/02/26 16:28:30  bentson
254  * Bill Foster at Blarg! Online services noticed that
255  * some of the switch elements of -Z modem control
256  * lacked a closing "break;"
257  *
258  * Revision 1.36.4.24  1997/02/24 11:00:00  daniel
259  * Changed low water threshold for buffer xmit_buf
260  *
261  * Revision 1.36.4.23  1996/12/02 21:50:16  bentson
262  * Marcio provided fix to modem status fetch for -Z
263  *
264  * Revision 1.36.4.22  1996/10/28 22:41:17  bentson
265  * improve mapping of -Z control page (thanks to Steve
266  * Price <stevep@fa.tdktca.com> for help on this)
267  *
268  * Revision 1.36.4.21  1996/09/10 17:00:10  bentson
269  * shift from CPU-bound to memcopy in cyz_polling operation
270  *
271  * Revision 1.36.4.20  1996/09/09 18:30:32  Bentson
272  * Added support to set and report higher speeds.
273  *
274  * Revision 1.36.4.19c  1996/08/09 10:00:00  Marcio Saito
275  * Some fixes in the HW flow control for the BETA release.
276  * Don't try to register the IRQ.
277  *
278  * Revision 1.36.4.19  1996/08/08 16:23:18  Bentson
279  * make sure "cyc" appears in all kernel messages; all soft interrupts
280  * handled by same routine; recognize out-of-band reception; comment
281  * out some diagnostic messages; leave RTS/CTS flow control to hardware;
282  * fix race condition in -Z buffer management; only -Y needs to explictly
283  * flush chars; tidy up some startup messages;
284  *
285  * Revision 1.36.4.18  1996/07/25 18:57:31  bentson
286  * shift MOD_INC_USE_COUNT location to match
287  * serial.c; purge some diagnostic messages;
288  *
289  * Revision 1.36.4.17  1996/07/25 18:01:08  bentson
290  * enable modem status messages and fetch & process them; note
291  * time of last activity type for each port; set_line_char now
292  * supports more than line 0 and treats 0 baud correctly;
293  * get_modem_info senses rs_status;
294  *
295  * Revision 1.36.4.16  1996/07/20 08:43:15  bentson
296  * barely works--now's time to turn on
297  * more features 'til it breaks
298  *
299  * Revision 1.36.4.15  1996/07/19 22:30:06  bentson
300  * check more -Z board status; shorten boot message
301  *
302  * Revision 1.36.4.14  1996/07/19 22:20:37  bentson
303  * fix reference to ch_ctrl in startup; verify return
304  * values from cyz_issue_cmd and cyz_update_channel;
305  * more stuff to get modem control correct;
306  *
307  * Revision 1.36.4.13  1996/07/11 19:53:33  bentson
308  * more -Z stuff folded in; re-order changes to put -Z stuff
309  * after -Y stuff (to make changes clearer)
310  *
311  * Revision 1.36.4.12  1996/07/11 15:40:55  bentson
312  * Add code to poll Cyclades-Z.  Add code to get & set RS-232 control.
313  * Add code to send break.  Clear firmware ID word at startup (so
314  * that other code won't talk to inactive board).
315  *
316  * Revision 1.36.4.11  1996/07/09 05:28:29  bentson
317  * add code for -Z in set_line_char
318  *
319  * Revision 1.36.4.10  1996/07/08 19:28:37  bentson
320  * fold more -Z stuff (or in some cases, error messages)
321  * into driver; add text to "don't know what to do" messages.
322  *
323  * Revision 1.36.4.9  1996/07/08 18:38:38  bentson
324  * moved compile-time flags near top of file; cosmetic changes
325  * to narrow text (to allow 2-up printing); changed many declarations
326  * to "static" to limit external symbols; shuffled code order to
327  * coalesce -Y and -Z specific code, also to put internal functions
328  * in order of tty_driver structure; added code to recognize -Z
329  * ports (and for moment, do nothing or report error); add cy_startup
330  * to parse boot command line for extra base addresses for ISA probes;
331  *
332  * Revision 1.36.4.8  1996/06/25 17:40:19  bentson
333  * reorder some code, fix types of some vars (int vs. long),
334  * add cy_setup to support user declared ISA addresses
335  *
336  * Revision 1.36.4.7  1996/06/21 23:06:18  bentson
337  * dump ioctl based firmware load (it's now a user level
338  * program); ensure uninitialzed ports cannot be used
339  *
340  * Revision 1.36.4.6  1996/06/20 23:17:19  bentson
341  * rename vars and restructure some code
342  *
343  * Revision 1.36.4.5  1996/06/14 15:09:44  bentson
344  * get right status back after boot load
345  *
346  * Revision 1.36.4.4  1996/06/13 19:51:44  bentson
347  * successfully loads firmware
348  *
349  * Revision 1.36.4.3  1996/06/13 06:08:33  bentson
350  * add more of the code for the boot/load ioctls
351  *
352  * Revision 1.36.4.2  1996/06/11 21:00:51  bentson
353  * start to add Z functionality--starting with ioctl
354  * for loading firmware
355  *
356  * Revision 1.36.4.1  1996/06/10 18:03:02  bentson
357  * added code to recognize Z/PCI card at initialization; report
358  * presence, but card is not initialized (because firmware needs
359  * to be loaded)
360  *
361  * Revision 1.36.3.8  1996/06/07 16:29:00  bentson
362  * starting minor number at zero; added missing verify_area
363  * as noted by Heiko Eissfeldt <heiko@colossus.escape.de>
364  *
365  * Revision 1.36.3.7  1996/04/19 21:06:18  bentson
366  * remove unneeded boot message & fix CLOCAL hardware flow
367  * control (Miquel van Smoorenburg <miquels@Q.cistron.nl>);
368  * remove unused diagnostic statements; minor 0 is first;
369  *
370  * Revision 1.36.3.6  1996/03/13 13:21:17  marcio
371  * The kernel function vremap (available only in later 1.3.xx kernels)
372  * allows the access to memory addresses above the RAM. This revision
373  * of the driver supports PCI boards below 1Mb (device id 0x100) and
374  * above 1Mb (device id 0x101).
375  *
376  * Revision 1.36.3.5  1996/03/07 15:20:17  bentson
377  * Some global changes to interrupt handling spilled into
378  * this driver--mostly unused arguments in system function
379  * calls.  Also added change by Marcio Saito which should
380  * reduce lost interrupts at startup by fast processors.
381  *
382  * Revision 1.36.3.4  1995/11/13  20:45:10  bentson
383  * Changes by Corey Minyard <minyard@wf-rch.cirr.com> distributed
384  * in 1.3.41 kernel to remove a possible race condition, extend
385  * some error messages, and let the driver run as a loadable module
386  * Change by Alan Wendt <alan@ez0.ezlink.com> to remove a
387  * possible race condition.
388  * Change by Marcio Saito <marcio@cyclades.com> to fix PCI addressing.
389  *
390  * Revision 1.36.3.3  1995/11/13  19:44:48  bentson
391  * Changes by Linus Torvalds in 1.3.33 kernel distribution
392  * required due to reordering of driver initialization.
393  * Drivers are now initialized *after* memory management.
394  *
395  * Revision 1.36.3.2  1995/09/08  22:07:14  bentson
396  * remove printk from ISR; fix typo
397  *
398  * Revision 1.36.3.1  1995/09/01  12:00:42  marcio
399  * Minor fixes in the PCI board support. PCI function calls in
400  * conditional compilation (CONFIG_PCI). Thanks to Jim Duncan
401  * <duncan@okay.com>. "bad serial count" message removed.
402  *
403  * Revision 1.36.3  1995/08/22  09:19:42  marcio
404  * Cyclom-Y/PCI support added. Changes in the cy_init routine and
405  * board initialization. Changes in the boot messages. The driver
406  * supports up to 4 boards and 64 ports by default.
407  *
408  * Revision 1.36.1.4  1995/03/29  06:14:14  bentson
409  * disambiguate between Cyclom-16Y and Cyclom-32Ye;
410  *
411  * Revision 1.36.1.3  1995/03/23  22:15:35  bentson
412  * add missing break in modem control block in ioctl switch statement
413  * (discovered by Michael Edward Chastain <mec@jobe.shell.portal.com>);
414  *
415  * Revision 1.36.1.2  1995/03/22  19:16:22  bentson
416  * make sure CTS flow control is set as soon as possible (thanks
417  * to note from David Lambert <lambert@chesapeake.rps.slb.com>);
418  *
419  * Revision 1.36.1.1  1995/03/13  15:44:43  bentson
420  * initialize defaults for receive threshold and stale data timeout;
421  * cosmetic changes;
422  *
423  * Revision 1.36  1995/03/10  23:33:53  bentson
424  * added support of chips 4-7 in 32 port Cyclom-Ye;
425  * fix cy_interrupt pointer dereference problem
426  * (Joe Portman <baron@aa.net>);
427  * give better error response if open is attempted on non-existent port
428  * (Zachariah Vaum <jchryslr@netcom.com>);
429  * correct command timeout (Kenneth Lerman <lerman@@seltd.newnet.com>);
430  * conditional compilation for -16Y on systems with fast, noisy bus;
431  * comment out diagnostic print function;
432  * cleaned up table of base addresses;
433  * set receiver time-out period register to correct value,
434  * set receive threshold to better default values,
435  * set chip timer to more accurate 200 Hz ticking,
436  * add code to monitor and modify receive parameters
437  * (Rik Faith <faith@cs.unc.edu> Nick Simicich
438  * <njs@scifi.emi.net>);
439  *
440  * Revision 1.35  1994/12/16  13:54:18  steffen
441  * additional patch by Marcio Saito for board detection
442  * Accidently left out in 1.34
443  *
444  * Revision 1.34  1994/12/10  12:37:12  steffen
445  * This is the corrected version as suggested by Marcio Saito
446  *
447  * Revision 1.33  1994/12/01  22:41:18  bentson
448  * add hooks to support more high speeds directly; add tytso
449  * patch regarding CLOCAL wakeups
450  *
451  * Revision 1.32  1994/11/23  19:50:04  bentson
452  * allow direct kernel control of higher signalling rates;
453  * look for cards at additional locations
454  *
455  * Revision 1.31  1994/11/16  04:33:28  bentson
456  * ANOTHER fix from Corey Minyard, minyard@wf-rch.cirr.com--
457  * a problem in chars_in_buffer has been resolved by some
458  * small changes;  this should yield smoother output
459  *
460  * Revision 1.30  1994/11/16  04:28:05  bentson
461  * Fix from Corey Minyard, Internet: minyard@metronet.com,
462  * UUCP: minyard@wf-rch.cirr.com, WORK: minyardbnr.ca, to
463  * cy_hangup that appears to clear up much (all?) of the
464  * DTR glitches; also he's added/cleaned-up diagnostic messages
465  *
466  * Revision 1.29  1994/11/16  04:16:07  bentson
467  * add change proposed by Ralph Sims, ralphs@halcyon.com, to
468  * operate higher speeds in same way as other serial ports;
469  * add more serial ports (for up to two 16-port muxes).
470  *
471  * Revision 1.28  1994/11/04  00:13:16  root
472  * turn off diagnostic messages
473  *
474  * Revision 1.27  1994/11/03  23:46:37  root
475  * bunch of changes to bring driver into greater conformance
476  * with the serial.c driver (looking for missed fixes)
477  *
478  * Revision 1.26  1994/11/03  22:40:36  root
479  * automatic interrupt probing fixed.
480  *
481  * Revision 1.25  1994/11/03  20:17:02  root
482  * start to implement auto-irq
483  *
484  * Revision 1.24  1994/11/03  18:01:55  root
485  * still working on modem signals--trying not to drop DTR
486  * during the getty/login processes
487  *
488  * Revision 1.23  1994/11/03  17:51:36  root
489  * extend baud rate support; set receive threshold as function
490  * of baud rate; fix some problems with RTS/CTS;
491  *
492  * Revision 1.22  1994/11/02  18:05:35  root
493  * changed arguments to udelay to type long to get
494  * delays to be of correct duration
495  *
496  * Revision 1.21  1994/11/02  17:37:30  root
497  * employ udelay (after calibrating loops_per_second earlier
498  * in init/main.c) instead of using home-grown delay routines
499  *
500  * Revision 1.20  1994/11/02  03:11:38  root
501  * cy_chars_in_buffer forces a return value of 0 to let
502  * login work (don't know why it does); some functions
503  * that were returning EFAULT, now executes the code;
504  * more work on deciding when to disable xmit interrupts;
505  *
506  * Revision 1.19  1994/11/01  20:10:14  root
507  * define routine to start transmission interrupts (by enabling
508  * transmit interrupts); directly enable/disable modem interrupts;
509  *
510  * Revision 1.18  1994/11/01  18:40:45  bentson
511  * Don't always enable transmit interrupts in startup; interrupt on
512  * TxMpty instead of TxRdy to help characters get out before shutdown;
513  * restructure xmit interrupt to check for chars first and quit if
514  * none are ready to go; modem status (MXVRx) is upright, _not_ inverted
515  * (to my view);
516  *
517  * Revision 1.17  1994/10/30  04:39:45  bentson
518  * rename serial_driver and callout_driver to cy_serial_driver and
519  * cy_callout_driver to avoid linkage interference; initialize
520  * info->type to PORT_CIRRUS; ruggedize paranoia test; elide ->port
521  * from cyclades_port structure; add paranoia check to cy_close;
522  *
523  * Revision 1.16  1994/10/30  01:14:33  bentson
524  * change major numbers; add some _early_ return statements;
525  *
526  * Revision 1.15  1994/10/29  06:43:15  bentson
527  * final tidying up for clean compile;  enable some error reporting
528  *
529  * Revision 1.14  1994/10/28  20:30:22  Bentson
530  * lots of changes to drag the driver towards the new tty_io
531  * structures and operation.  not expected to work, but may
532  * compile cleanly.
533  *
534  * Revision 1.13  1994/07/21  23:08:57  Bentson
535  * add some diagnostic cruft; support 24 lines (for testing
536  * both -8Y and -16Y cards; be more thorough in servicing all
537  * chips during interrupt; add "volatile" a few places to
538  * circumvent compiler optimizations; fix base & offset
539  * computations in block_til_ready (was causing chip 0 to
540  * stop operation)
541  *
542  * Revision 1.12  1994/07/19  16:42:11  Bentson
543  * add some hackery for kernel version 1.1.8; expand
544  * error messages; refine timing for delay loops and
545  * declare loop params volatile
546  *
547  * Revision 1.11  1994/06/11  21:53:10  bentson
548  * get use of save_car right in transmit interrupt service
549  *
550  * Revision 1.10.1.1  1994/06/11  21:31:18  bentson
551  * add some diagnostic printing; try to fix save_car stuff
552  *
553  * Revision 1.10  1994/06/11  20:36:08  bentson
554  * clean up compiler warnings
555  *
556  * Revision 1.9  1994/06/11  19:42:46  bentson
557  * added a bunch of code to support modem signalling
558  *
559  * Revision 1.8  1994/06/11  17:57:07  bentson
560  * recognize break & parity error
561  *
562  * Revision 1.7  1994/06/05  05:51:34  bentson
563  * Reorder baud table to be monotonic; add cli to CP; discard
564  * incoming characters and status if the line isn't open; start to
565  * fold code into cy_throttle; start to port get_serial_info,
566  * set_serial_info, get_modem_info, set_modem_info, and send_break
567  * from serial.c; expand cy_ioctl; relocate and expand config_setup;
568  * get flow control characters from tty struct; invalidate ports w/o
569  * hardware;
570  *
571  * Revision 1.6  1994/05/31  18:42:21  bentson
572  * add a loop-breaker in the interrupt service routine;
573  * note when port is initialized so that it can be shut
574  * down under the right conditions; receive works without
575  * any obvious errors
576  *
577  * Revision 1.5  1994/05/30  00:55:02  bentson
578  * transmit works without obvious errors
579  *
580  * Revision 1.4  1994/05/27  18:46:27  bentson
581  * incorporated more code from lib_y.c; can now print short
582  * strings under interrupt control to port zero; seems to
583  * select ports/channels/lines correctly
584  *
585  * Revision 1.3  1994/05/25  22:12:44  bentson
586  * shifting from multi-port on a card to proper multiplexor
587  * data structures;  added skeletons of most routines
588  *
589  * Revision 1.2  1994/05/19  13:21:43  bentson
590  * start to crib from other sources
591  *
592  */
593
594 /* If you need to install more boards than NR_CARDS, change the constant
595    in the definition below. No other change is necessary to support up to
596    eight boards. Beyond that you'll have to extend cy_isa_addresses. */
597
598 #define NR_CARDS        4
599
600 /*
601    If the total number of ports is larger than NR_PORTS, change this
602    constant in the definition below. No other change is necessary to
603    support more boards/ports. */
604
605 #define NR_PORTS        256
606
607 #define ZE_V1_NPORTS    64
608 #define ZO_V1   0
609 #define ZO_V2   1
610 #define ZE_V1   2
611
612 #define SERIAL_PARANOIA_CHECK
613 #undef  CY_DEBUG_OPEN
614 #undef  CY_DEBUG_THROTTLE
615 #undef  CY_DEBUG_OTHER
616 #undef  CY_DEBUG_IO
617 #undef  CY_DEBUG_COUNT
618 #undef  CY_DEBUG_DTR
619 #undef  CY_DEBUG_WAIT_UNTIL_SENT
620 #undef  CY_DEBUG_INTERRUPTS
621 #undef  CY_16Y_HACK
622 #undef  CY_ENABLE_MONITORING
623 #undef  CY_PCI_DEBUG
624
625 #if 0
626 #define PAUSE __asm__("nop");
627 #else
628 #define PAUSE ;
629 #endif
630
631 /*
632  * Include section 
633  */
634 #include <linux/config.h>
635 #include <linux/module.h>
636 #include <linux/errno.h>
637 #include <linux/signal.h>
638 #include <linux/sched.h>
639 #include <linux/timer.h>
640 #include <linux/interrupt.h>
641 #include <linux/tty.h>
642 #include <linux/serial.h>
643 #include <linux/major.h>
644 #include <linux/string.h>
645 #include <linux/fcntl.h>
646 #include <linux/ptrace.h>
647 #include <linux/cyclades.h>
648 #include <linux/mm.h>
649 #include <linux/ioport.h>
650 #include <linux/init.h>
651 #include <linux/delay.h>
652 #include <linux/spinlock.h>
653
654 #include <asm/system.h>
655 #include <asm/io.h>
656 #include <asm/irq.h>
657 #include <asm/uaccess.h>
658 #include <asm/bitops.h>
659
660 #define CY_LOCK(info,flags)                                     \
661                 do {                                            \
662                 spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \
663                 } while (0)
664                 
665 #define CY_UNLOCK(info,flags)                                   \
666                 do {                                            \
667                 spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \
668                 } while (0)
669
670 #include <linux/types.h>
671 #include <linux/kernel.h>
672 #include <linux/pci.h>
673 #include <linux/version.h>
674
675 #include <linux/stat.h>
676 #include <linux/proc_fs.h>
677
678 #define cy_put_user     put_user
679
680 static unsigned long 
681 cy_get_user(unsigned long *addr)
682 {
683         unsigned long result = 0;
684         int error = get_user (result, addr);
685         if (error)
686                 printk ("cyclades: cy_get_user: error == %d\n", error);
687         return result;
688 }
689
690 #ifndef MIN
691 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
692 #endif
693
694 #define IS_CYC_Z(card) ((card).num_chips == -1)
695
696 #define Z_FPGA_CHECK(card) \
697     ((cy_readl(&((struct RUNTIME_9060 *) \
698                  ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
699
700 #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 *) \
701                         ((card).ctl_addr))->mail_box_0)) || \
702                         Z_FPGA_CHECK(card)) && \
703                         (ZFIRM_ID==cy_readl(&((struct FIRM_ID *) \
704                         ((card).base_addr+ID_ADDRESS))->signature)))
705
706 #ifndef SERIAL_XMIT_SIZE
707 #define SERIAL_XMIT_SIZE        (MIN(PAGE_SIZE, 4096))
708 #endif
709 #define WAKEUP_CHARS            256
710
711 #define STD_COM_FLAGS (0)
712
713 #define JIFFIES_DIFF(n, j)      ((j) - (n))
714
715 static DECLARE_TASK_QUEUE(tq_cyclades);
716
717 static struct tty_driver cy_serial_driver, cy_callout_driver;
718 static int serial_refcount;
719
720 #ifdef CONFIG_ISA
721 /* This is the address lookup table. The driver will probe for
722    Cyclom-Y/ISA boards at all addresses in here. If you want the
723    driver to probe addresses at a different address, add it to
724    this table.  If the driver is probing some other board and
725    causing problems, remove the offending address from this table.
726    The cy_setup function extracts additional addresses from the
727    boot options line.  The form is "cyclades=address,address..."
728 */
729
730 static unsigned char *cy_isa_addresses[] = {
731         (unsigned char *) 0xD0000,
732         (unsigned char *) 0xD2000,
733         (unsigned char *) 0xD4000,
734         (unsigned char *) 0xD6000,
735         (unsigned char *) 0xD8000,
736         (unsigned char *) 0xDA000,
737         (unsigned char *) 0xDC000,
738         (unsigned char *) 0xDE000,
739         0,0,0,0,0,0,0,0
740 };
741 #define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
742
743 #ifdef MODULE
744 static long maddr[NR_CARDS] = { 0, };
745 static int irq[NR_CARDS]  = { 0, };
746
747 MODULE_PARM(maddr, "1-" __MODULE_STRING(NR_CARDS) "l");
748 MODULE_PARM(irq, "1-" __MODULE_STRING(NR_CARDS) "i");
749 #endif
750
751 #endif /* CONFIG_ISA */
752
753 /* This is the per-card data structure containing address, irq, number of
754    channels, etc. This driver supports a maximum of NR_CARDS cards.
755 */
756 static struct cyclades_card cy_card[NR_CARDS];
757
758 /* This is the per-channel data structure containing pointers, flags
759  and variables for the port. This driver supports a maximum of NR_PORTS.
760 */
761 static struct cyclades_port cy_port[NR_PORTS];
762
763 static int cy_next_channel; /* next minor available */
764
765 static struct tty_struct *serial_table[NR_PORTS];
766 static struct termios *serial_termios[NR_PORTS];
767 static struct termios *serial_termios_locked[NR_PORTS];
768
769 /*
770  * tmp_buf is used as a temporary buffer by serial_write.  We need to
771  * lock it in case the copy_from_user blocks while swapping in a page,
772  * and some other program tries to do a serial write at the same time.
773  * Since the lock will only come under contention when the system is
774  * swapping and available memory is low, it makes sense to share one
775  * buffer across all the serial ports, since it significantly saves
776  * memory if large numbers of serial ports are open.  This buffer is
777  * allocated when the first cy_open occurs.
778  */
779 static unsigned char *tmp_buf;
780 DECLARE_MUTEX(tmp_buf_sem);
781
782 /*
783  * This is used to look up the divisor speeds and the timeouts
784  * We're normally limited to 15 distinct baud rates.  The extra
785  * are accessed via settings in info->flags.
786  *      0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
787  *     10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
788  *                                               HI            VHI
789  *     20
790  */
791 static int baud_table[] = {
792        0,    50,    75,   110,   134,   150,   200,   300,   600,  1200,
793     1800,  2400,  4800,  9600, 19200, 38400, 57600, 76800,115200,150000,
794   230400,     0};
795
796 static char baud_co_25[] = {  /* 25 MHz clock option table */
797     /* value =>    00    01   02    03    04 */
798     /* divide by    8    32   128   512  2048 */
799     0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,  0x03,  0x02,
800     0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00};
801
802 static char baud_bpr_25[] = {  /* 25 MHz baud rate period table */
803     0x00,  0xf5,  0xa3,  0x6f,  0x5c,  0x51,  0xf5,  0xa3,  0x51,  0xa3,
804     0x6d,  0x51,  0xa3,  0x51,  0xa3,  0x51,  0x36,  0x29,  0x1b,  0x15};
805
806 static char baud_co_60[] = {  /* 60 MHz clock option table (CD1400 J) */
807     /* value =>    00    01   02    03    04 */
808     /* divide by    8    32   128   512  2048 */
809     0x00,  0x00,  0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,
810     0x03,  0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,
811     0x00};
812
813 static char baud_bpr_60[] = {  /* 60 MHz baud rate period table (CD1400 J) */
814     0x00,  0x82,  0x21,  0xff,  0xdb,  0xc3,  0x92,  0x62,  0xc3,  0x62,
815     0x41,  0xc3,  0x62,  0xc3,  0x62,  0xc3,  0x82,  0x62,  0x41,  0x32,
816     0x21};
817
818 static char baud_cor3[] = {  /* receive threshold */
819     0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
820     0x0a,  0x0a,  0x0a,  0x09,  0x09,  0x08,  0x08,  0x08,  0x08,  0x07,
821     0x07};
822
823 /*
824  * The Cyclades driver implements HW flow control as any serial driver.
825  * The cyclades_port structure member rflow and the vector rflow_thr 
826  * allows us to take advantage of a special feature in the CD1400 to avoid 
827  * data loss even when the system interrupt latency is too high. These flags 
828  * are to be used only with very special applications. Setting these flags 
829  * requires the use of a special cable (DTR and RTS reversed). In the new 
830  * CD1400-based boards (rev. 6.00 or later), there is no need for special 
831  * cables.
832  */
833
834 static char rflow_thr[] = {  /* rflow threshold */
835     0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
836     0x00,  0x00,  0x00,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
837     0x0a};
838
839 /*  The Cyclom-Ye has placed the sequential chips in non-sequential
840  *  address order.  This look-up table overcomes that problem.
841  */
842 static int cy_chip_offset [] =
843     { 0x0000,
844       0x0400,
845       0x0800,
846       0x0C00,
847       0x0200,
848       0x0600,
849       0x0A00,
850       0x0E00
851     };
852
853 /* PCI related definitions */
854
855 static unsigned short   cy_pci_nboard;
856 static unsigned short   cy_isa_nboard;
857 static unsigned short   cy_nboard;
858 #ifdef CONFIG_PCI
859 static unsigned short   cy_pci_dev_id[] = {
860                             PCI_DEVICE_ID_CYCLOM_Y_Lo,  /* PCI < 1Mb */
861                             PCI_DEVICE_ID_CYCLOM_Y_Hi,  /* PCI > 1Mb */
862                             PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */
863                             PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */
864                             PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */
865                             PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */
866                             PCI_DEVICE_ID_CYCLOM_Z_Lo,  /* Z PCI < 1Mb */
867                             PCI_DEVICE_ID_CYCLOM_Z_Hi,  /* Z PCI > 1Mb */
868                             0                           /* end of table */
869                         };
870 #endif
871
872 static void cy_start(struct tty_struct *);
873 static void set_line_char(struct cyclades_port *);
874 static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong);
875 #ifdef CONFIG_ISA
876 static unsigned detect_isa_irq (volatile ucchar *);
877 #endif /* CONFIG_ISA */
878
879 static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
880
881 #ifndef CONFIG_CYZ_INTR
882 static void cyz_poll(unsigned long);
883
884 /* The Cyclades-Z polling cycle is defined by this variable */
885 static long cyz_polling_cycle = CZ_DEF_POLL;
886
887 static int cyz_timeron = 0;
888 static struct timer_list cyz_timerlist = {
889     function: cyz_poll
890 };
891 #else /* CONFIG_CYZ_INTR */
892 static void cyz_rx_restart(unsigned long);
893 static struct timer_list cyz_rx_full_timer[NR_PORTS];
894 #endif /* CONFIG_CYZ_INTR */
895
896 static inline int
897 serial_paranoia_check(struct cyclades_port *info,
898                         kdev_t device, const char *routine)
899 {
900 #ifdef SERIAL_PARANOIA_CHECK
901     static const char *badmagic =
902         "cyc Warning: bad magic number for serial struct (%s) in %s\n";
903     static const char *badinfo =
904         "cyc Warning: null cyclades_port for (%s) in %s\n";
905     static const char *badrange =
906         "cyc Warning: cyclades_port out of range for (%s) in %s\n";
907
908     if (!info) {
909         printk(badinfo, kdevname(device), routine);
910         return 1;
911     }
912
913     if( (long)info < (long)(&cy_port[0])
914     || (long)(&cy_port[NR_PORTS]) < (long)info ){
915         printk(badrange, kdevname(device), routine);
916         return 1;
917     }
918
919     if (info->magic != CYCLADES_MAGIC) {
920         printk(badmagic, kdevname(device), routine);
921         return 1;
922     }
923 #endif
924         return 0;
925 } /* serial_paranoia_check */
926
927 /*
928  * This routine is used by the interrupt handler to schedule
929  * processing in the software interrupt portion of the driver
930  * (also known as the "bottom half").  This can be called any
931  * number of times for any channel without harm.
932  */
933 static inline void
934 cy_sched_event(struct cyclades_port *info, int event)
935 {
936     info->event |= 1 << event; /* remember what kind of event and who */
937     queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */
938     mark_bh(CYCLADES_BH);                       /* then trigger event */
939 } /* cy_sched_event */
940
941
942 /*
943  * This routine is used to handle the "bottom half" processing for the
944  * serial driver, known also the "software interrupt" processing.
945  * This processing is done at the kernel interrupt level, after the
946  * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
947  * is where time-consuming activities which can not be done in the
948  * interrupt driver proper are done; the interrupt driver schedules
949  * them using cy_sched_event(), and they get done here.
950  *
951  * This is done through one level of indirection--the task queue.
952  * When a hardware interrupt service routine wants service by the
953  * driver's bottom half, it enqueues the appropriate tq_struct (one
954  * per port) to the tq_cyclades work queue and sets a request flag
955  * via mark_bh for processing that queue.  When the time is right,
956  * do_cyclades_bh is called (because of the mark_bh) and it requests
957  * that the work queue be processed.
958  *
959  * Although this may seem unwieldy, it gives the system a way to
960  * pass an argument (in this case the pointer to the cyclades_port
961  * structure) to the bottom half of the driver.  Previous kernels
962  * had to poll every port to see if that port needed servicing.
963  */
964 static void
965 do_cyclades_bh(void)
966 {
967     run_task_queue(&tq_cyclades);
968 } /* do_cyclades_bh */
969
970 static void
971 do_softint(void *private_)
972 {
973   struct cyclades_port *info = (struct cyclades_port *) private_;
974   struct tty_struct    *tty;
975
976     tty = info->tty;
977     if (!tty)
978         return;
979
980     if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
981         tty_hangup(info->tty);
982         wake_up_interruptible(&info->open_wait);
983         info->flags &= ~(ASYNC_NORMAL_ACTIVE|
984                              ASYNC_CALLOUT_ACTIVE);
985     }
986     if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
987         wake_up_interruptible(&info->open_wait);
988     }
989 #ifdef CONFIG_CYZ_INTR
990     if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) {
991         if (cyz_rx_full_timer[info->line].function == NULL) {
992             cyz_rx_full_timer[info->line].expires = jiffies + 1;
993             cyz_rx_full_timer[info->line].function = cyz_rx_restart;
994             cyz_rx_full_timer[info->line].data = (unsigned long)info;
995             add_timer(&cyz_rx_full_timer[info->line]);
996         }
997     }
998 #endif
999     if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) {
1000         wake_up_interruptible(&info->delta_msr_wait);
1001     }
1002     if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
1003         if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
1004         && tty->ldisc.write_wakeup){
1005             (tty->ldisc.write_wakeup)(tty);
1006         }
1007         wake_up_interruptible(&tty->write_wait);
1008     }
1009 #ifdef Z_WAKE
1010     if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
1011         wake_up_interruptible(&info->shutdown_wait);
1012     }
1013 #endif
1014 } /* do_softint */
1015
1016
1017 /***********************************************************/
1018 /********* Start of block of Cyclom-Y specific code ********/
1019
1020 /* This routine waits up to 1000 micro-seconds for the previous
1021    command to the Cirrus chip to complete and then issues the
1022    new command.  An error is returned if the previous command
1023    didn't finish within the time limit.
1024
1025    This function is only called from inside spinlock-protected code.
1026  */
1027 static int
1028 cyy_issue_cmd(volatile ucchar *base_addr, u_char cmd, int index)
1029 {
1030   volatile int  i;
1031
1032     /* Check to see that the previous command has completed */
1033     for(i = 0 ; i < 100 ; i++){
1034         if (cy_readb(base_addr+(CyCCR<<index)) == 0){
1035             break;
1036         }
1037         udelay(10L);
1038     }
1039     /* if the CCR never cleared, the previous command
1040        didn't finish within the "reasonable time" */
1041     if (i == 100)       return (-1);
1042
1043     /* Issue the new command */
1044     cy_writeb((u_long)base_addr+(CyCCR<<index), cmd);
1045
1046     return(0);
1047 } /* cyy_issue_cmd */
1048
1049 #ifdef CONFIG_ISA
1050 /* ISA interrupt detection code */
1051 static unsigned 
1052 detect_isa_irq (volatile ucchar *address)
1053 {
1054   int irq;
1055   unsigned long irqs, flags;
1056   int save_xir, save_car;
1057   int index = 0; /* IRQ probing is only for ISA */
1058
1059     /* forget possible initially masked and pending IRQ */
1060     irq = probe_irq_off(probe_irq_on());
1061
1062     /* Clear interrupts on the board first */
1063     cy_writeb((u_long)address + (Cy_ClrIntr<<index), 0);
1064                               /* Cy_ClrIntr is 0x1800 */
1065
1066     irqs = probe_irq_on();
1067     /* Wait ... */
1068     udelay(5000L);
1069
1070     /* Enable the Tx interrupts on the CD1400 */
1071     save_flags(flags); cli();
1072         cy_writeb((u_long)address + (CyCAR<<index), 0);
1073         cyy_issue_cmd(address, CyCHAN_CTL|CyENB_XMTR, index);
1074
1075         cy_writeb((u_long)address + (CyCAR<<index), 0);
1076         cy_writeb((u_long)address + (CySRER<<index), 
1077                 cy_readb(address + (CySRER<<index)) | CyTxRdy);
1078     restore_flags(flags);
1079
1080     /* Wait ... */
1081     udelay(5000L);
1082
1083     /* Check which interrupt is in use */
1084     irq = probe_irq_off(irqs);
1085
1086     /* Clean up */
1087     save_xir = (u_char) cy_readb(address + (CyTIR<<index));
1088     save_car = cy_readb(address + (CyCAR<<index));
1089     cy_writeb((u_long)address + (CyCAR<<index), (save_xir & 0x3));
1090     cy_writeb((u_long)address + (CySRER<<index),
1091         cy_readb(address + (CySRER<<index)) & ~CyTxRdy);
1092     cy_writeb((u_long)address + (CyTIR<<index), (save_xir & 0x3f));
1093     cy_writeb((u_long)address + (CyCAR<<index), (save_car));
1094     cy_writeb((u_long)address + (Cy_ClrIntr<<index), 0);
1095                               /* Cy_ClrIntr is 0x1800 */
1096
1097     return (irq > 0)? irq : 0;
1098 }
1099 #endif /* CONFIG_ISA */
1100
1101 /* The real interrupt service routine is called
1102    whenever the card wants its hand held--chars
1103    received, out buffer empty, modem change, etc.
1104  */
1105 static void
1106 cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1107 {
1108   struct tty_struct *tty;
1109   int status;
1110   struct cyclades_card *cinfo;
1111   struct cyclades_port *info;
1112   volatile unsigned char *base_addr, *card_base_addr;
1113   int chip;
1114   int save_xir, channel, save_car;
1115   char data;
1116   volatile int char_count;
1117   int outch;
1118   int i,j,index;
1119   int too_many;
1120   int had_work;
1121   int mdm_change;
1122   int mdm_status;
1123
1124     if((cinfo = (struct cyclades_card *)dev_id) == 0){
1125 #ifdef CY_DEBUG_INTERRUPTS
1126         printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
1127 #endif
1128         return; /* spurious interrupt */
1129     }
1130
1131     card_base_addr = (unsigned char *)cinfo->base_addr;
1132     index = cinfo->bus_index;
1133
1134
1135     /* This loop checks all chips in the card.  Make a note whenever
1136        _any_ chip had some work to do, as this is considered an
1137        indication that there will be more to do.  Only when no chip
1138        has any work does this outermost loop exit.
1139      */
1140     do{
1141         had_work = 0;
1142         for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) {
1143             base_addr = (unsigned char *)
1144                        (cinfo->base_addr + (cy_chip_offset[chip]<<index));
1145             too_many = 0;
1146             while ( (status = cy_readb(base_addr+(CySVRR<<index))) != 0x00) {
1147                 had_work++;
1148                 /* The purpose of the following test is to ensure that
1149                    no chip can monopolize the driver.  This forces the
1150                    chips to be checked in a round-robin fashion (after
1151                    draining each of a bunch (1000) of characters).
1152                  */
1153                 if(1000<too_many++){
1154                     break;
1155                 }
1156                 if (status & CySRReceive) { /* reception interrupt */
1157 #ifdef CY_DEBUG_INTERRUPTS
1158                     printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
1159 #endif
1160                     /* determine the channel & change to that context */
1161                     spin_lock(&cinfo->card_lock);
1162                     save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
1163                     channel = (u_short ) (save_xir & CyIRChannel);
1164                     i = channel + chip * 4 + cinfo->first_line;
1165                     info = &cy_port[i];
1166                     info->last_active = jiffies;
1167                     save_car = cy_readb(base_addr+(CyCAR<<index));
1168                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1169
1170                     /* if there is nowhere to put the data, discard it */
1171                     if(info->tty == 0){
1172                         j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1173                         if ( j == CyIVRRxEx ) { /* exception */
1174                             data = cy_readb(base_addr+(CyRDSR<<index));
1175                         } else { /* normal character reception */
1176                             char_count = cy_readb(base_addr+(CyRDCR<<index));
1177                             while(char_count--){
1178                                 data = cy_readb(base_addr+(CyRDSR<<index));
1179                             }
1180                         }
1181                     }else{ /* there is an open port for this data */
1182                         tty = info->tty;
1183                         j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1184                         if ( j == CyIVRRxEx ) { /* exception */
1185                             data = cy_readb(base_addr+(CyRDSR<<index));
1186
1187                             /* For statistics only */
1188                             if (data & CyBREAK)
1189                                 info->icount.brk++;
1190                             else if(data & CyFRAME)
1191                                 info->icount.frame++;
1192                             else if(data & CyPARITY)
1193                                 info->icount.parity++;
1194                             else if(data & CyOVERRUN)
1195                                 info->icount.overrun++;
1196
1197                             if(data & info->ignore_status_mask){
1198                                 info->icount.rx++;
1199                                 continue;
1200                             }
1201                             if (tty->flip.count < TTY_FLIPBUF_SIZE){
1202                                 tty->flip.count++;
1203                                 if (data & info->read_status_mask){
1204                                     if(data & CyBREAK){
1205                                         *tty->flip.flag_buf_ptr++ =
1206                                                             TTY_BREAK;
1207                                         *tty->flip.char_buf_ptr++ =
1208                                           cy_readb(base_addr+(CyRDSR<<index));
1209                                         info->icount.rx++;
1210                                         if (info->flags & ASYNC_SAK){
1211                                             do_SAK(tty);
1212                                         }
1213                                     }else if(data & CyFRAME){
1214                                         *tty->flip.flag_buf_ptr++ =
1215                                                             TTY_FRAME;
1216                                         *tty->flip.char_buf_ptr++ =
1217                                           cy_readb(base_addr+(CyRDSR<<index));
1218                                         info->icount.rx++;
1219                                         info->idle_stats.frame_errs++;
1220                                     }else if(data & CyPARITY){
1221                                         *tty->flip.flag_buf_ptr++ =
1222                                                             TTY_PARITY;
1223                                         *tty->flip.char_buf_ptr++ =
1224                                           cy_readb(base_addr+(CyRDSR<<index));
1225                                         info->icount.rx++;
1226                                         info->idle_stats.parity_errs++;
1227                                     }else if(data & CyOVERRUN){
1228                                         *tty->flip.flag_buf_ptr++ =
1229                                                             TTY_OVERRUN;
1230                                         *tty->flip.char_buf_ptr++ = 0;
1231                                         info->icount.rx++;
1232                                         /* If the flip buffer itself is
1233                                            overflowing, we still lose
1234                                            the next incoming character.
1235                                          */
1236                                         if(tty->flip.count
1237                                                    < TTY_FLIPBUF_SIZE){
1238                                             tty->flip.count++;
1239                                             *tty->flip.flag_buf_ptr++ =
1240                                                              TTY_NORMAL;
1241                                            *tty->flip.char_buf_ptr++ =
1242                                             cy_readb(base_addr+(CyRDSR<<index));
1243                                             info->icount.rx++;
1244                                         }
1245                                         info->idle_stats.overruns++;
1246                                     /* These two conditions may imply */
1247                                     /* a normal read should be done. */
1248                                     /* }else if(data & CyTIMEOUT){ */
1249                                     /* }else if(data & CySPECHAR){ */
1250                                     }else{
1251                                         *tty->flip.flag_buf_ptr++ = 0;
1252                                         *tty->flip.char_buf_ptr++ = 0;
1253                                         info->icount.rx++;
1254                                     }
1255                                 }else{
1256                                     *tty->flip.flag_buf_ptr++ = 0;
1257                                     *tty->flip.char_buf_ptr++ = 0;
1258                                     info->icount.rx++;
1259                                 }
1260                             }else{
1261                                 /* there was a software buffer
1262                                    overrun and nothing could be
1263                                    done about it!!! */
1264                                 info->icount.buf_overrun++;
1265                                 info->idle_stats.overruns++;
1266                             }
1267                         } else { /* normal character reception */
1268                             /* load # chars available from the chip */
1269                             char_count = cy_readb(base_addr+(CyRDCR<<index));
1270
1271 #ifdef CY_ENABLE_MONITORING
1272                             ++info->mon.int_count;
1273                             info->mon.char_count += char_count;
1274                             if (char_count > info->mon.char_max)
1275                                info->mon.char_max = char_count;
1276                             info->mon.char_last = char_count;
1277 #endif
1278                             info->idle_stats.recv_bytes += char_count;
1279                             info->idle_stats.recv_idle   = jiffies;
1280                             while(char_count--){
1281                                 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1282                                         break;
1283                                 }
1284                                 tty->flip.count++;
1285                                 data = cy_readb(base_addr+(CyRDSR<<index));
1286                                 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1287                                 *tty->flip.char_buf_ptr++ = data;
1288                                 info->icount.rx++;
1289 #ifdef CY_16Y_HACK
1290                                 udelay(10L);
1291 #endif
1292                             }
1293                         }
1294                         queue_task(&tty->flip.tqueue, &tq_timer);
1295                     }
1296                     /* end of service */
1297                     cy_writeb((u_long)base_addr+(CyRIR<<index), (save_xir & 0x3f));
1298                     cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1299                     spin_unlock(&cinfo->card_lock);
1300                 }
1301
1302
1303                 if (status & CySRTransmit) { /* transmission interrupt */
1304                     /* Since we only get here when the transmit buffer
1305                        is empty, we know we can always stuff a dozen
1306                        characters. */
1307 #ifdef CY_DEBUG_INTERRUPTS
1308                     printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
1309 #endif
1310
1311                     /* determine the channel & change to that context */
1312                     spin_lock(&cinfo->card_lock);
1313                     save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index));
1314                     channel = (u_short ) (save_xir & CyIRChannel);
1315                     i = channel + chip * 4 + cinfo->first_line;
1316                     save_car = cy_readb(base_addr+(CyCAR<<index));
1317                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1318
1319                     /* validate the port# (as configured and open) */
1320                     if( (i < 0) || (NR_PORTS <= i) ){
1321                         cy_writeb((u_long)base_addr+(CySRER<<index),
1322                              cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1323                         goto txend;
1324                     }
1325                     info = &cy_port[i];
1326                     info->last_active = jiffies;
1327                     if(info->tty == 0){
1328                         cy_writeb((u_long)base_addr+(CySRER<<index),
1329                              cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1330                         goto txdone;
1331                     }
1332
1333                     /* load the on-chip space for outbound data */
1334                     char_count = info->xmit_fifo_size;
1335
1336                     if(info->x_char) { /* send special char */
1337                         outch = info->x_char;
1338                         cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1339                         char_count--;
1340                         info->icount.tx++;
1341                         info->x_char = 0;
1342                     }
1343
1344                     if (info->breakon || info->breakoff) {
1345                         if (info->breakon) {
1346                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0); 
1347                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0x81);
1348                             info->breakon = 0;
1349                             char_count -= 2;
1350                         }
1351                         if (info->breakoff) {
1352                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0); 
1353                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0x83);
1354                             info->breakoff = 0;
1355                             char_count -= 2;
1356                         }
1357                     }
1358
1359                     while (char_count-- > 0){
1360                         if (!info->xmit_cnt){
1361                             if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
1362                                 cy_writeb((u_long)base_addr+(CySRER<<index),
1363                                           cy_readb(base_addr+(CySRER<<index)) &
1364                                           ~CyTxMpty);
1365                             } else {
1366                                 cy_writeb((u_long)base_addr+(CySRER<<index),
1367                                           ((cy_readb(base_addr+(CySRER<<index))
1368                                             & ~CyTxRdy)
1369                                            | CyTxMpty));
1370                             }
1371                             goto txdone;
1372                         }
1373                         if (info->xmit_buf == 0){
1374                             cy_writeb((u_long)base_addr+(CySRER<<index),
1375                                 cy_readb(base_addr+(CySRER<<index)) & 
1376                                         ~CyTxRdy);
1377                             goto txdone;
1378                         }
1379                         if (info->tty->stopped || info->tty->hw_stopped){
1380                             cy_writeb((u_long)base_addr+(CySRER<<index),
1381                                 cy_readb(base_addr+(CySRER<<index)) & 
1382                                         ~CyTxRdy);
1383                             goto txdone;
1384                         }
1385                         /* Because the Embedded Transmit Commands have
1386                            been enabled, we must check to see if the
1387                            escape character, NULL, is being sent.  If it
1388                            is, we must ensure that there is room for it
1389                            to be doubled in the output stream.  Therefore
1390                            we no longer advance the pointer when the
1391                            character is fetched, but rather wait until
1392                            after the check for a NULL output character.
1393                            This is necessary because there may not be
1394                            room for the two chars needed to send a NULL.)
1395                          */
1396                         outch = info->xmit_buf[info->xmit_tail];
1397                         if( outch ){
1398                             info->xmit_cnt--;
1399                             info->xmit_tail = (info->xmit_tail + 1)
1400                                                       & (SERIAL_XMIT_SIZE - 1);
1401                             cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1402                             info->icount.tx++;
1403                         }else{
1404                             if(char_count > 1){
1405                                 info->xmit_cnt--;
1406                                 info->xmit_tail = (info->xmit_tail + 1)
1407                                                       & (SERIAL_XMIT_SIZE - 1);
1408                                 cy_writeb((u_long)base_addr+(CyTDR<<index), 
1409                                           outch);
1410                                 cy_writeb((u_long)base_addr+(CyTDR<<index), 0);
1411                                 info->icount.tx++;
1412                                 char_count--;
1413                             }else{
1414                             }
1415                         }
1416                     }
1417
1418         txdone:
1419                     if (info->xmit_cnt < WAKEUP_CHARS) {
1420                         cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1421                     }
1422         txend:
1423                     /* end of service */
1424                     cy_writeb((u_long)base_addr+(CyTIR<<index), 
1425                               (save_xir & 0x3f));
1426                     cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1427                     spin_unlock(&cinfo->card_lock);
1428                 }
1429
1430                 if (status & CySRModem) {        /* modem interrupt */
1431
1432                     /* determine the channel & change to that context */
1433                     spin_lock(&cinfo->card_lock);
1434                     save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));
1435                     channel = (u_short ) (save_xir & CyIRChannel);
1436                     info = &cy_port[channel + chip * 4
1437                                            + cinfo->first_line];
1438                     info->last_active = jiffies;
1439                     save_car = cy_readb(base_addr+(CyCAR<<index));
1440                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1441
1442                     mdm_change = cy_readb(base_addr+(CyMISR<<index));
1443                     mdm_status = cy_readb(base_addr+(CyMSVR1<<index));
1444
1445                     if(info->tty == 0){/* no place for data, ignore it*/
1446                         ;
1447                     }else{
1448                         if (mdm_change & CyANY_DELTA) {
1449                             /* For statistics only */
1450                             if (mdm_change & CyDCD)     info->icount.dcd++;
1451                             if (mdm_change & CyCTS)     info->icount.cts++;
1452                             if (mdm_change & CyDSR)     info->icount.dsr++;
1453                             if (mdm_change & CyRI)      info->icount.rng++;
1454
1455                             cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
1456                         }
1457
1458                         if((mdm_change & CyDCD)
1459                         && (info->flags & ASYNC_CHECK_CD)){
1460                             if(mdm_status & CyDCD){
1461                                 cy_sched_event(info,
1462                                     Cy_EVENT_OPEN_WAKEUP);
1463                             }else if(!((info->flags
1464                                         & ASYNC_CALLOUT_ACTIVE)
1465                                  &&(info->flags
1466                                     & ASYNC_CALLOUT_NOHUP))){
1467                                 cy_sched_event(info,
1468                                     Cy_EVENT_HANGUP);
1469                             }
1470                         }
1471                         if((mdm_change & CyCTS)
1472                         && (info->flags & ASYNC_CTS_FLOW)){
1473                             if(info->tty->hw_stopped){
1474                                 if(mdm_status & CyCTS){
1475                                     /* cy_start isn't used
1476                                          because... !!! */
1477                                     info->tty->hw_stopped = 0;
1478                                   cy_writeb((u_long)base_addr+(CySRER<<index),
1479                                        cy_readb(base_addr+(CySRER<<index)) | 
1480                                        CyTxRdy);
1481                                     cy_sched_event(info,
1482                                         Cy_EVENT_WRITE_WAKEUP);
1483                                 }
1484                             }else{
1485                                 if(!(mdm_status & CyCTS)){
1486                                     /* cy_stop isn't used
1487                                          because ... !!! */
1488                                     info->tty->hw_stopped = 1;
1489                                   cy_writeb((u_long)base_addr+(CySRER<<index),
1490                                        cy_readb(base_addr+(CySRER<<index)) & 
1491                                        ~CyTxRdy);
1492                                 }
1493                             }
1494                         }
1495                         if(mdm_change & CyDSR){
1496                         }
1497                         if(mdm_change & CyRI){
1498                         }
1499                     }
1500                     /* end of service */
1501                     cy_writeb((u_long)base_addr+(CyMIR<<index), 
1502                               (save_xir & 0x3f));
1503                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_car);
1504                     spin_unlock(&cinfo->card_lock);
1505                 }
1506             }          /* end while status != 0 */
1507         }            /* end loop for chips... */
1508     } while(had_work);
1509
1510    /* clear interrupts */
1511    spin_lock(&cinfo->card_lock);
1512    cy_writeb((u_long)card_base_addr + (Cy_ClrIntr<<index), 0);
1513                                 /* Cy_ClrIntr is 0x1800 */
1514    spin_unlock(&cinfo->card_lock);
1515 } /* cyy_interrupt */
1516
1517 /***********************************************************/
1518 /********* End of block of Cyclom-Y specific code **********/
1519 /******** Start of block of Cyclades-Z specific code *********/
1520 /***********************************************************/
1521
1522 static int
1523 cyz_fetch_msg( struct cyclades_card *cinfo,
1524             uclong *channel, ucchar *cmd, uclong *param)
1525 {
1526   struct FIRM_ID *firm_id;
1527   struct ZFW_CTRL *zfw_ctrl;
1528   struct BOARD_CTRL *board_ctrl;
1529   unsigned long loc_doorbell;
1530
1531     firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1532     if (!ISZLOADED(*cinfo)){
1533         return (-1);
1534     }
1535     zfw_ctrl = (struct ZFW_CTRL *)
1536                 (cinfo->base_addr + 
1537                  (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1538     board_ctrl = &zfw_ctrl->board_ctrl;
1539
1540     loc_doorbell = cy_readl(&((struct RUNTIME_9060 *)
1541                      (cinfo->ctl_addr))->loc_doorbell);
1542     if (loc_doorbell){
1543         *cmd = (char)(0xff & loc_doorbell);
1544         *channel = cy_readl(&board_ctrl->fwcmd_channel);
1545         *param = (uclong)cy_readl(&board_ctrl->fwcmd_param);
1546         cy_writel(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->loc_doorbell, 
1547                  0xffffffff);
1548         return 1;
1549     }
1550     return 0;
1551 } /* cyz_fetch_msg */
1552
1553 static int
1554 cyz_issue_cmd( struct cyclades_card *cinfo,
1555             uclong channel, ucchar cmd, uclong param)
1556 {
1557   struct FIRM_ID *firm_id;
1558   struct ZFW_CTRL *zfw_ctrl;
1559   struct BOARD_CTRL *board_ctrl;
1560   volatile uclong *pci_doorbell;
1561   int index;
1562
1563     firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1564     if (!ISZLOADED(*cinfo)){
1565         return (-1);
1566     }
1567     zfw_ctrl = (struct ZFW_CTRL *)
1568                 (cinfo->base_addr + 
1569                  (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1570     board_ctrl = &zfw_ctrl->board_ctrl;
1571
1572     index = 0;
1573     pci_doorbell = (uclong *)(&((struct RUNTIME_9060 *)
1574                                (cinfo->ctl_addr))->pci_doorbell);
1575     while( (cy_readl(pci_doorbell) & 0xff) != 0){
1576         if (index++ == 1000){
1577             return((int)(cy_readl(pci_doorbell) & 0xff));
1578         }
1579         udelay(50L);
1580     }
1581     cy_writel((u_long)&board_ctrl->hcmd_channel, channel);
1582     cy_writel((u_long)&board_ctrl->hcmd_param , param);
1583     cy_writel((u_long)pci_doorbell, (long)cmd);
1584
1585     return(0);
1586 } /* cyz_issue_cmd */
1587
1588 static void
1589 cyz_handle_rx(struct cyclades_port *info, volatile struct CH_CTRL *ch_ctrl,
1590               volatile struct BUF_CTRL *buf_ctrl)
1591 {
1592   struct cyclades_card *cinfo = &cy_card[info->card];
1593   struct tty_struct *tty = info->tty;
1594   volatile int char_count;
1595 #ifdef BLOCKMOVE
1596   int small_count;
1597 #else
1598   char data;
1599 #endif
1600   volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
1601
1602     rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get);
1603     rx_put = cy_readl(&buf_ctrl->rx_put);
1604     rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
1605     rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr);
1606     if (rx_put >= rx_get)
1607         char_count = rx_put - rx_get;
1608     else
1609         char_count = rx_put - rx_get + rx_bufsize;
1610
1611     if ( char_count ) {
1612         info->last_active = jiffies;
1613         info->jiffies[1] = jiffies;
1614
1615 #ifdef CY_ENABLE_MONITORING
1616         info->mon.int_count++;
1617         info->mon.char_count += char_count;
1618         if (char_count > info->mon.char_max)
1619             info->mon.char_max = char_count;
1620         info->mon.char_last = char_count;
1621 #endif
1622         if(tty == 0){
1623             /* flush received characters */
1624             new_rx_get = (new_rx_get + char_count) & (rx_bufsize - 1);
1625             info->rflush_count++;
1626         }else{
1627 #ifdef BLOCKMOVE
1628             /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
1629                for performance, but because of buffer boundaries, there
1630                may be several steps to the operation */
1631             while(0 < (small_count = 
1632                        min_t(unsigned int, (rx_bufsize - new_rx_get),
1633                        min_t(unsigned int, (TTY_FLIPBUF_SIZE - tty->flip.count), char_count))
1634                  )) {
1635                 memcpy_fromio(tty->flip.char_buf_ptr,
1636                               (char *)(cinfo->base_addr
1637                                        + rx_bufaddr + new_rx_get),
1638                               small_count);
1639
1640                 tty->flip.char_buf_ptr += small_count;
1641                 memset(tty->flip.flag_buf_ptr, TTY_NORMAL, small_count);
1642                 tty->flip.flag_buf_ptr += small_count;
1643                 new_rx_get = (new_rx_get + small_count) & (rx_bufsize - 1);
1644                 char_count -= small_count;
1645                 info->icount.rx += small_count;
1646                 info->idle_stats.recv_bytes += small_count;
1647                 tty->flip.count += small_count;
1648             }
1649 #else
1650             while(char_count--){
1651                 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1652                     break;
1653                 }
1654                 data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get);
1655                 new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1);
1656                 tty->flip.count++;
1657                 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1658                 *tty->flip.char_buf_ptr++ = data;
1659                 info->idle_stats.recv_bytes++;
1660                 info->icount.rx++;
1661             }
1662 #endif
1663 #ifdef CONFIG_CYZ_INTR
1664             /* Recalculate the number of chars in the RX buffer and issue
1665                a cmd in case it's higher than the RX high water mark */
1666             rx_put = cy_readl(&buf_ctrl->rx_put);
1667             if (rx_put >= rx_get)
1668                 char_count = rx_put - rx_get;
1669             else
1670                 char_count = rx_put - rx_get + rx_bufsize;
1671             if(char_count >= cy_readl(&buf_ctrl->rx_threshold)) {
1672                 cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
1673             }
1674 #endif
1675             info->idle_stats.recv_idle = jiffies;
1676             queue_task(&tty->flip.tqueue, &tq_timer);
1677         }
1678         /* Update rx_get */
1679         cy_writel(&buf_ctrl->rx_get, new_rx_get);
1680     }
1681 }
1682
1683 static void
1684 cyz_handle_tx(struct cyclades_port *info, volatile struct CH_CTRL *ch_ctrl,
1685               volatile struct BUF_CTRL *buf_ctrl)
1686 {
1687   struct cyclades_card *cinfo = &cy_card[info->card];
1688   struct tty_struct *tty = info->tty;
1689   char data;
1690   volatile int char_count;
1691 #ifdef BLOCKMOVE
1692   int small_count;
1693 #endif
1694   volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr;
1695
1696     if (info->xmit_cnt <= 0)    /* Nothing to transmit */
1697         return;
1698
1699     tx_get = cy_readl(&buf_ctrl->tx_get);
1700     tx_put = cy_readl(&buf_ctrl->tx_put);
1701     tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
1702     tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr);
1703     if (tx_put >= tx_get)
1704         char_count = tx_get - tx_put - 1 + tx_bufsize;
1705     else
1706         char_count = tx_get - tx_put - 1;
1707
1708     if ( char_count ) {
1709
1710         if( tty == 0 ){
1711             goto ztxdone;
1712         }
1713
1714         if(info->x_char) { /* send special char */
1715             data = info->x_char;
1716
1717             cy_writeb((cinfo->base_addr + tx_bufaddr + tx_put), data);
1718             tx_put = (tx_put + 1) & (tx_bufsize - 1);
1719             info->x_char = 0;
1720             char_count--;
1721             info->icount.tx++;
1722             info->last_active = jiffies;
1723             info->jiffies[2] = jiffies;
1724         }
1725 #ifdef BLOCKMOVE
1726         while(0 < (small_count = 
1727                    min_t(unsigned int, (tx_bufsize - tx_put),
1728                        min_t(unsigned int, (SERIAL_XMIT_SIZE - info->xmit_tail),
1729                            min_t(unsigned int, info->xmit_cnt, char_count))))) {
1730
1731             memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put),
1732                         &info->xmit_buf[info->xmit_tail],
1733                         small_count);
1734
1735             tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1736             char_count -= small_count;
1737             info->icount.tx += small_count;
1738             info->xmit_cnt -= small_count;
1739             info->xmit_tail = 
1740                 (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
1741             info->last_active = jiffies;
1742             info->jiffies[2] = jiffies;
1743         }
1744 #else
1745         while (info->xmit_cnt && char_count){
1746             data = info->xmit_buf[info->xmit_tail];
1747             info->xmit_cnt--;
1748             info->xmit_tail = (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
1749
1750             cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1751             tx_put = (tx_put + 1) & (tx_bufsize - 1);
1752             char_count--;
1753             info->icount.tx++;
1754             info->last_active = jiffies;
1755             info->jiffies[2] = jiffies;
1756         }
1757 #endif
1758     ztxdone:
1759         if (info->xmit_cnt < WAKEUP_CHARS) {
1760             cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1761         }
1762         /* Update tx_put */
1763         cy_writel(&buf_ctrl->tx_put, tx_put);
1764     }
1765 }
1766
1767 static void
1768 cyz_handle_cmd(struct cyclades_card *cinfo)
1769 {
1770   struct tty_struct *tty;
1771   struct cyclades_port *info;
1772   static volatile struct FIRM_ID *firm_id;
1773   static volatile struct ZFW_CTRL *zfw_ctrl;
1774   static volatile struct BOARD_CTRL *board_ctrl;
1775   static volatile struct CH_CTRL *ch_ctrl;
1776   static volatile struct BUF_CTRL *buf_ctrl;
1777   uclong channel;
1778   ucchar cmd;
1779   uclong param;
1780   uclong hw_ver, fw_ver;
1781   int special_count;
1782   int delta_count;
1783
1784     firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1785     zfw_ctrl = (struct ZFW_CTRL *)
1786                 (cinfo->base_addr + 
1787                  (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1788     board_ctrl = &(zfw_ctrl->board_ctrl);
1789     fw_ver = cy_readl(&board_ctrl->fw_version);
1790     hw_ver = cy_readl(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->mail_box_0);
1791
1792 #ifdef CONFIG_CYZ_INTR
1793     if (!cinfo->nports)
1794         cinfo->nports = (int) cy_readl(&board_ctrl->n_channel);
1795 #endif
1796
1797     while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
1798         special_count = 0;
1799         delta_count = 0;
1800         info = &cy_port[channel + cinfo->first_line];
1801         if((tty = info->tty) == 0) {
1802             continue;
1803         }
1804         ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1805         buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1806
1807         switch(cmd) {
1808             case C_CM_PR_ERROR:
1809                 tty->flip.count++;
1810                 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
1811                 *tty->flip.char_buf_ptr++ = 0;
1812                 info->icount.rx++;
1813                 special_count++;
1814                 break;
1815             case C_CM_FR_ERROR:
1816                 tty->flip.count++;
1817                 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
1818                 *tty->flip.char_buf_ptr++ = 0;
1819                 info->icount.rx++;
1820                 special_count++;
1821                 break;
1822             case C_CM_RXBRK:
1823                 tty->flip.count++;
1824                 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
1825                 *tty->flip.char_buf_ptr++ = 0;
1826                 info->icount.rx++;
1827                 special_count++;
1828                 break;
1829             case C_CM_MDCD:
1830                 info->icount.dcd++;
1831                 delta_count++;
1832                 if (info->flags & ASYNC_CHECK_CD){
1833                     if ((fw_ver > 241 ? 
1834                           ((u_long)param) : 
1835                           cy_readl(&ch_ctrl->rs_status)) & C_RS_DCD) {
1836                         cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
1837                     }else if(!((info->flags & ASYNC_CALLOUT_ACTIVE)
1838                              &&(info->flags & ASYNC_CALLOUT_NOHUP))){
1839                         cy_sched_event(info, Cy_EVENT_HANGUP);
1840                     }
1841                 }
1842                 break;
1843             case C_CM_MCTS:
1844                 info->icount.cts++;
1845                 delta_count++;
1846                 break;
1847             case C_CM_MRI:
1848                 info->icount.rng++;
1849                 delta_count++;
1850                 break;
1851             case C_CM_MDSR:
1852                 info->icount.dsr++;
1853                 delta_count++;
1854                 break;
1855 #ifdef Z_WAKE
1856             case C_CM_IOCTLW:
1857                 cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
1858                 break;
1859 #endif
1860 #ifdef CONFIG_CYZ_INTR
1861             case C_CM_RXHIWM:
1862             case C_CM_RXNNDT:
1863             case C_CM_INTBACK2:
1864                 /* Reception Interrupt */
1865 #ifdef CY_DEBUG_INTERRUPTS
1866                 printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", 
1867                         info->card, channel);
1868 #endif
1869                 cyz_handle_rx(info, ch_ctrl, buf_ctrl);
1870                 break;
1871             case C_CM_TXBEMPTY:
1872             case C_CM_TXLOWWM:
1873             case C_CM_INTBACK:
1874                 /* Transmission Interrupt */
1875 #ifdef CY_DEBUG_INTERRUPTS
1876                 printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r", 
1877                         info->card, channel);
1878 #endif
1879                 cyz_handle_tx(info, ch_ctrl, buf_ctrl);
1880                 break;
1881 #endif /* CONFIG_CYZ_INTR */
1882             case C_CM_FATAL:
1883                 /* should do something with this !!! */
1884                 break;
1885             default:
1886                 break;
1887         }
1888         if(delta_count)
1889             cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
1890         if(special_count)
1891             queue_task(&tty->flip.tqueue, &tq_timer);
1892     }
1893 }
1894
1895 #ifdef CONFIG_CYZ_INTR
1896 static void
1897 cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1898 {
1899   struct cyclades_card *cinfo;
1900
1901     if((cinfo = (struct cyclades_card *)dev_id) == 0){
1902 #ifdef CY_DEBUG_INTERRUPTS
1903         printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
1904 #endif
1905         return; /* spurious interrupt */
1906     }
1907
1908     if (!ISZLOADED(*cinfo)) {
1909 #ifdef CY_DEBUG_INTERRUPTS
1910         printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq);
1911 #endif
1912         return;
1913     }
1914
1915     /* Handle the interrupts */
1916     cyz_handle_cmd(cinfo);
1917
1918     return;
1919 } /* cyz_interrupt */
1920
1921 static void
1922 cyz_rx_restart(unsigned long arg)
1923 {
1924     struct cyclades_port *info = (struct cyclades_port *)arg;
1925     int retval;
1926     int card = info->card;
1927     uclong channel = (info->line) - (cy_card[card].first_line);
1928     unsigned long flags;
1929
1930     CY_LOCK(info, flags);
1931     retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L);
1932     if (retval != 0){
1933         printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", 
1934                info->line, retval);
1935     }
1936     cyz_rx_full_timer[info->line].function = NULL;
1937     CY_UNLOCK(info, flags);
1938 }
1939
1940 #else /* CONFIG_CYZ_INTR */
1941
1942 static void
1943 cyz_poll(unsigned long arg)
1944 {
1945   struct cyclades_card *cinfo;
1946   struct cyclades_port *info;
1947   struct tty_struct *tty;
1948   static volatile struct FIRM_ID *firm_id;
1949   static volatile struct ZFW_CTRL *zfw_ctrl;
1950   static volatile struct BOARD_CTRL *board_ctrl;
1951   static volatile struct CH_CTRL *ch_ctrl;
1952   static volatile struct BUF_CTRL *buf_ctrl;
1953   int card, port;
1954
1955     cyz_timerlist.expires = jiffies + (HZ);
1956     for (card = 0 ; card < NR_CARDS ; card++){
1957         cinfo = &cy_card[card];
1958
1959         if (!IS_CYC_Z(*cinfo)) continue;
1960         if (!ISZLOADED(*cinfo)) continue;
1961
1962         firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1963         zfw_ctrl = (struct ZFW_CTRL *)
1964                     (cinfo->base_addr + 
1965                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1966         board_ctrl = &(zfw_ctrl->board_ctrl);
1967
1968         /* Skip first polling cycle to avoid racing conditions with the FW */
1969         if (!cinfo->intr_enabled) {
1970             cinfo->nports = (int) cy_readl(&board_ctrl->n_channel);
1971             cinfo->intr_enabled = 1;
1972             continue;
1973         }
1974
1975         cyz_handle_cmd(cinfo);
1976
1977         for (port = 0 ; port < cinfo->nports ; port++) {
1978             info = &cy_port[ port + cinfo->first_line ];
1979             tty = info->tty;
1980             ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
1981             buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
1982
1983             cyz_handle_rx(info, ch_ctrl, buf_ctrl);
1984             cyz_handle_tx(info, ch_ctrl, buf_ctrl);
1985         }
1986         /* poll every 'cyz_polling_cycle' period */
1987         cyz_timerlist.expires = jiffies + cyz_polling_cycle;
1988     }
1989     add_timer(&cyz_timerlist);
1990
1991     return;
1992 } /* cyz_poll */
1993
1994 #endif /* CONFIG_CYZ_INTR */
1995
1996 /********** End of block of Cyclades-Z specific code *********/
1997 /***********************************************************/
1998
1999
2000 /* This is called whenever a port becomes active;
2001    interrupts are enabled and DTR & RTS are turned on.
2002  */
2003 static int
2004 startup(struct cyclades_port * info)
2005 {
2006   unsigned long flags;
2007   int retval = 0;
2008   unsigned char *base_addr;
2009   int card,chip,channel,index;
2010   unsigned long page;
2011
2012     card = info->card;
2013     channel = (info->line) - (cy_card[card].first_line);
2014
2015     page = get_free_page(GFP_KERNEL);
2016     if (!page)
2017         return -ENOMEM;
2018
2019     CY_LOCK(info, flags);
2020
2021     if (info->flags & ASYNC_INITIALIZED){
2022         free_page(page);
2023         goto errout;
2024     }
2025
2026     if (!info->type){
2027         if (info->tty){
2028             set_bit(TTY_IO_ERROR, &info->tty->flags);
2029         }
2030         free_page(page);
2031         goto errout;
2032     }
2033
2034     if (info->xmit_buf)
2035         free_page(page);
2036     else
2037         info->xmit_buf = (unsigned char *) page;
2038
2039     CY_UNLOCK(info, flags);
2040
2041     set_line_char(info);
2042
2043     if (!IS_CYC_Z(cy_card[card])) {
2044         chip = channel>>2;
2045         channel &= 0x03;
2046         index = cy_card[card].bus_index;
2047         base_addr = (unsigned char*)
2048                    (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
2049
2050 #ifdef CY_DEBUG_OPEN
2051         printk("cyc startup card %d, chip %d, channel %d, base_addr %lx\n",
2052              card, chip, channel, (long)base_addr);/**/
2053 #endif
2054
2055         CY_LOCK(info, flags);
2056
2057         cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2058
2059         cy_writeb((ulong)base_addr+(CyRTPR<<index), (info->default_timeout
2060                  ? info->default_timeout : 0x02)); /* 10ms rx timeout */
2061
2062         cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index);
2063
2064         cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2065         cy_writeb((ulong)base_addr+(CyMSVR1<<index), CyRTS);
2066         cy_writeb((ulong)base_addr+(CyMSVR2<<index), CyDTR);
2067
2068 #ifdef CY_DEBUG_DTR
2069         printk("cyc:startup raising DTR\n");
2070         printk("     status: 0x%x, 0x%x\n",
2071                 cy_readb(base_addr+(CyMSVR1<<index)), 
2072                 cy_readb(base_addr+(CyMSVR2<<index)));
2073 #endif
2074
2075         cy_writeb((u_long)base_addr+(CySRER<<index),
2076                 cy_readb(base_addr+(CySRER<<index)) | CyRxData);
2077         info->flags |= ASYNC_INITIALIZED;
2078
2079         if (info->tty){
2080             clear_bit(TTY_IO_ERROR, &info->tty->flags);
2081         }
2082         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2083         info->breakon = info->breakoff = 0;
2084         memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2085         info->idle_stats.in_use    =
2086         info->idle_stats.recv_idle =
2087         info->idle_stats.xmit_idle = jiffies;
2088
2089         CY_UNLOCK(info, flags);
2090
2091     } else {
2092       struct FIRM_ID *firm_id;
2093       struct ZFW_CTRL *zfw_ctrl;
2094       struct BOARD_CTRL *board_ctrl;
2095       struct CH_CTRL *ch_ctrl;
2096       int retval;
2097
2098         base_addr = (unsigned char*) (cy_card[card].base_addr);
2099
2100         firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2101         if (!ISZLOADED(cy_card[card])){
2102             return -ENODEV;
2103         }
2104
2105         zfw_ctrl = (struct ZFW_CTRL *)
2106                     (cy_card[card].base_addr + 
2107                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
2108         board_ctrl = &zfw_ctrl->board_ctrl;
2109         ch_ctrl = zfw_ctrl->ch_ctrl;
2110
2111 #ifdef CY_DEBUG_OPEN
2112         printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
2113              card, channel, (long)base_addr);/**/
2114 #endif
2115
2116         CY_LOCK(info, flags);
2117
2118         cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
2119 #ifdef Z_WAKE
2120 #ifdef CONFIG_CYZ_INTR
2121         cy_writel(&ch_ctrl[channel].intr_enable, 
2122                   C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
2123                   C_IN_IOCTLW|
2124                   C_IN_MDCD);
2125 #else
2126         cy_writel(&ch_ctrl[channel].intr_enable, 
2127                   C_IN_IOCTLW|
2128                   C_IN_MDCD);
2129 #endif /* CONFIG_CYZ_INTR */
2130 #else
2131 #ifdef CONFIG_CYZ_INTR
2132         cy_writel(&ch_ctrl[channel].intr_enable, 
2133                   C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
2134                   C_IN_MDCD);
2135 #else
2136         cy_writel(&ch_ctrl[channel].intr_enable, 
2137                   C_IN_MDCD);
2138 #endif /* CONFIG_CYZ_INTR */
2139 #endif /* Z_WAKE */
2140
2141         retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
2142         if (retval != 0){
2143             printk("cyc:startup(1) retval on ttyC%d was %x\n",
2144                    info->line, retval);
2145         }
2146
2147         /* Flush RX buffers before raising DTR and RTS */
2148         retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, 0L);
2149         if (retval != 0){
2150             printk("cyc:startup(2) retval on ttyC%d was %x\n",
2151                    info->line, retval);
2152         }
2153
2154         /* set timeout !!! */
2155         /* set RTS and DTR !!! */
2156         cy_writel(&ch_ctrl[channel].rs_control,
2157              cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR) ;
2158         retval = cyz_issue_cmd(&cy_card[info->card],
2159             channel, C_CM_IOCTLM, 0L);
2160         if (retval != 0){
2161             printk("cyc:startup(3) retval on ttyC%d was %x\n",
2162                    info->line, retval);
2163         }
2164 #ifdef CY_DEBUG_DTR
2165             printk("cyc:startup raising Z DTR\n");
2166 #endif
2167
2168         /* enable send, recv, modem !!! */
2169
2170         info->flags |= ASYNC_INITIALIZED;
2171         if (info->tty){
2172             clear_bit(TTY_IO_ERROR, &info->tty->flags);
2173         }
2174         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2175         info->breakon = info->breakoff = 0;
2176         memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2177         info->idle_stats.in_use    =
2178         info->idle_stats.recv_idle =
2179         info->idle_stats.xmit_idle = jiffies;
2180
2181         CY_UNLOCK(info, flags);
2182     }
2183
2184 #ifdef CY_DEBUG_OPEN
2185         printk(" cyc startup done\n");
2186 #endif
2187         return 0;
2188
2189 errout:
2190         CY_UNLOCK(info, flags);
2191         return retval;
2192 } /* startup */
2193
2194
2195 static void
2196 start_xmit( struct cyclades_port *info )
2197 {
2198   unsigned long flags;
2199   unsigned char *base_addr;
2200   int card,chip,channel,index;
2201
2202     card = info->card;
2203     channel = (info->line) - (cy_card[card].first_line);
2204     if (!IS_CYC_Z(cy_card[card])) {
2205         chip = channel>>2;
2206         channel &= 0x03;
2207         index = cy_card[card].bus_index;
2208         base_addr = (unsigned char*)
2209                        (cy_card[card].base_addr
2210                        + (cy_chip_offset[chip]<<index));
2211
2212         CY_LOCK(info, flags);
2213             cy_writeb((u_long)base_addr+(CyCAR<<index), channel);
2214             cy_writeb((u_long)base_addr+(CySRER<<index), 
2215                cy_readb(base_addr+(CySRER<<index)) | CyTxRdy);
2216         CY_UNLOCK(info, flags);
2217     } else {
2218 #ifdef CONFIG_CYZ_INTR
2219       int retval;
2220
2221         CY_LOCK(info, flags);
2222             retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 0L);
2223             if (retval != 0){
2224                 printk("cyc:start_xmit retval on ttyC%d was %x\n",
2225                        info->line, retval);
2226             }
2227         CY_UNLOCK(info, flags);
2228 #else /* CONFIG_CYZ_INTR */
2229         /* Don't have to do anything at this time */
2230 #endif /* CONFIG_CYZ_INTR */
2231     }
2232 } /* start_xmit */
2233
2234 /*
2235  * This routine shuts down a serial port; interrupts are disabled,
2236  * and DTR is dropped if the hangup on close termio flag is on.
2237  */
2238 static void
2239 shutdown(struct cyclades_port * info)
2240 {
2241   unsigned long flags;
2242   unsigned char *base_addr;
2243   int card,chip,channel,index;
2244
2245     if (!(info->flags & ASYNC_INITIALIZED)){
2246         return;
2247     }
2248
2249     card = info->card;
2250     channel = info->line - cy_card[card].first_line;
2251     if (!IS_CYC_Z(cy_card[card])) {
2252         chip = channel>>2;
2253         channel &= 0x03;
2254         index = cy_card[card].bus_index;
2255         base_addr = (unsigned char*)
2256                        (cy_card[card].base_addr
2257                        + (cy_chip_offset[chip]<<index));
2258
2259 #ifdef CY_DEBUG_OPEN
2260     printk("cyc shutdown Y card %d, chip %d, channel %d, base_addr %lx\n",
2261                 card, chip, channel, (long)base_addr);
2262 #endif
2263
2264         CY_LOCK(info, flags);
2265
2266             /* Clear delta_msr_wait queue to avoid mem leaks. */
2267             wake_up_interruptible(&info->delta_msr_wait);
2268
2269             if (info->xmit_buf){
2270                 unsigned char * temp;
2271                 temp = info->xmit_buf;
2272                 info->xmit_buf = 0;
2273                 free_page((unsigned long) temp);
2274             }
2275             cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2276             if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2277                 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
2278                 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
2279 #ifdef CY_DEBUG_DTR
2280                 printk("cyc shutdown dropping DTR\n");
2281                 printk("     status: 0x%x, 0x%x\n",
2282                     cy_readb(base_addr+(CyMSVR1<<index)), 
2283                     cy_readb(base_addr+(CyMSVR2<<index)));
2284 #endif
2285             }
2286             cyy_issue_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR,index);
2287              /* it may be appropriate to clear _XMIT at
2288                some later date (after testing)!!! */
2289
2290             if (info->tty){
2291                 set_bit(TTY_IO_ERROR, &info->tty->flags);
2292             }
2293             info->flags &= ~ASYNC_INITIALIZED;
2294         CY_UNLOCK(info, flags);
2295     } else {
2296       struct FIRM_ID *firm_id;
2297       struct ZFW_CTRL *zfw_ctrl;
2298       struct BOARD_CTRL *board_ctrl;
2299       struct CH_CTRL *ch_ctrl;
2300       int retval;
2301
2302         base_addr = (unsigned char*) (cy_card[card].base_addr);
2303 #ifdef CY_DEBUG_OPEN
2304     printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
2305                 card, channel, (long)base_addr);
2306 #endif
2307
2308         firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2309         if (!ISZLOADED(cy_card[card])) {
2310             return;
2311         }
2312
2313         zfw_ctrl = (struct ZFW_CTRL *)
2314                     (cy_card[card].base_addr + 
2315                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
2316         board_ctrl = &(zfw_ctrl->board_ctrl);
2317         ch_ctrl = zfw_ctrl->ch_ctrl;
2318
2319         CY_LOCK(info, flags);
2320
2321             if (info->xmit_buf){
2322                 unsigned char * temp;
2323                 temp = info->xmit_buf;
2324                 info->xmit_buf = 0;
2325                 free_page((unsigned long) temp);
2326             }
2327             
2328             if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2329                 cy_writel((u_long)&ch_ctrl[channel].rs_control,
2330                    (uclong)(cy_readl(&ch_ctrl[channel].rs_control) & 
2331                    ~(C_RS_RTS | C_RS_DTR)));
2332                 retval = cyz_issue_cmd(&cy_card[info->card],
2333                         channel, C_CM_IOCTLM, 0L);
2334                 if (retval != 0){
2335                     printk("cyc:shutdown retval on ttyC%d was %x\n",
2336                            info->line, retval);
2337                 }
2338 #ifdef CY_DEBUG_DTR
2339                 printk("cyc:shutdown dropping Z DTR\n");
2340 #endif
2341             }
2342             
2343             if (info->tty){
2344                 set_bit(TTY_IO_ERROR, &info->tty->flags);
2345             }
2346             info->flags &= ~ASYNC_INITIALIZED;
2347
2348         CY_UNLOCK(info, flags);
2349     }
2350
2351 #ifdef CY_DEBUG_OPEN
2352     printk(" cyc shutdown done\n");
2353 #endif
2354     return;
2355 } /* shutdown */
2356
2357
2358 /*
2359  * ------------------------------------------------------------
2360  * cy_open() and friends
2361  * ------------------------------------------------------------
2362  */
2363
2364 static int
2365 block_til_ready(struct tty_struct *tty, struct file * filp,
2366                            struct cyclades_port *info)
2367 {
2368   DECLARE_WAITQUEUE(wait, current);
2369   struct cyclades_card *cinfo;
2370   unsigned long flags;
2371   int chip, channel,index;
2372   int retval;
2373   char *base_addr;
2374
2375     cinfo = &cy_card[info->card];
2376     channel = info->line - cinfo->first_line;
2377
2378     /*
2379      * If the device is in the middle of being closed, then block
2380      * until it's done, and then try again.
2381      */
2382     if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2383         if (info->flags & ASYNC_CLOSING) {
2384             interruptible_sleep_on(&info->close_wait);
2385         }
2386         return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2387     }
2388
2389     /*
2390      * If this is a callout device, then just make sure the normal
2391      * device isn't being used.
2392      */
2393     if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
2394         if (info->flags & ASYNC_NORMAL_ACTIVE){
2395             return -EBUSY;
2396         }
2397         if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2398             (info->flags & ASYNC_SESSION_LOCKOUT) &&
2399             (info->session != current->session)){
2400             return -EBUSY;
2401         }
2402         if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2403             (info->flags & ASYNC_PGRP_LOCKOUT) &&
2404             (info->pgrp != current->pgrp)){
2405             return -EBUSY;
2406         }
2407         info->flags |= ASYNC_CALLOUT_ACTIVE;
2408         return 0;
2409     }
2410
2411     /*
2412      * If non-blocking mode is set, then make the check up front
2413      * and then exit.
2414      */
2415     if ((filp->f_flags & O_NONBLOCK) ||
2416         (tty->flags & (1 << TTY_IO_ERROR))) {
2417         if (info->flags & ASYNC_CALLOUT_ACTIVE){
2418             return -EBUSY;
2419         }
2420         info->flags |= ASYNC_NORMAL_ACTIVE;
2421         return 0;
2422     }
2423
2424     /*
2425      * Block waiting for the carrier detect and the line to become
2426      * free (i.e., not in use by the callout).  While we are in
2427      * this loop, info->count is dropped by one, so that
2428      * cy_close() knows when to free things.  We restore it upon
2429      * exit, either normal or abnormal.
2430      */
2431     retval = 0;
2432     add_wait_queue(&info->open_wait, &wait);
2433 #ifdef CY_DEBUG_OPEN
2434     printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
2435            info->line, info->count);/**/
2436 #endif
2437     CY_LOCK(info, flags);
2438     if (!tty_hung_up_p(filp))
2439         info->count--;
2440     CY_UNLOCK(info, flags);
2441 #ifdef CY_DEBUG_COUNT
2442     printk("cyc block_til_ready: (%d): decrementing count to %d\n",
2443         current->pid, info->count);
2444 #endif
2445     info->blocked_open++;
2446
2447     if (!IS_CYC_Z(*cinfo)) {
2448         chip = channel>>2;
2449         channel &= 0x03;
2450         index = cinfo->bus_index;
2451         base_addr = (char *)(cinfo->base_addr
2452                             + (cy_chip_offset[chip]<<index));
2453
2454         while (1) {
2455             CY_LOCK(info, flags);
2456                 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
2457                     (tty->termios->c_cflag & CBAUD)){
2458                     cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2459                     cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
2460                     cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
2461 #ifdef CY_DEBUG_DTR
2462                     printk("cyc:block_til_ready raising DTR\n");
2463                     printk("     status: 0x%x, 0x%x\n",
2464                         cy_readb(base_addr+(CyMSVR1<<index)), 
2465                         cy_readb(base_addr+(CyMSVR2<<index)));
2466 #endif
2467                 }
2468             CY_UNLOCK(info, flags);
2469
2470             set_current_state(TASK_INTERRUPTIBLE);
2471             if (tty_hung_up_p(filp)
2472             || !(info->flags & ASYNC_INITIALIZED) ){
2473                 retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 
2474                     -EAGAIN : -ERESTARTSYS);
2475                 break;
2476             }
2477
2478             CY_LOCK(info, flags);
2479                 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2480                 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2481                 && !(info->flags & ASYNC_CLOSING)
2482                 && (C_CLOCAL(tty)
2483                     || (cy_readb(base_addr+(CyMSVR1<<index)) & CyDCD))) {
2484                         CY_UNLOCK(info, flags);
2485                         break;
2486                 }
2487             CY_UNLOCK(info, flags);
2488
2489             if (signal_pending(current)) {
2490                 retval = -ERESTARTSYS;
2491                 break;
2492             }
2493 #ifdef CY_DEBUG_OPEN
2494             printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2495                    info->line, info->count);/**/
2496 #endif
2497             schedule();
2498         }
2499     } else {
2500       struct FIRM_ID *firm_id;
2501       struct ZFW_CTRL *zfw_ctrl;
2502       struct BOARD_CTRL *board_ctrl;
2503       struct CH_CTRL *ch_ctrl;
2504       int retval;
2505
2506         base_addr = (char *)(cinfo->base_addr);
2507         firm_id = (struct FIRM_ID *)
2508                         (base_addr + ID_ADDRESS);
2509         if (!ISZLOADED(*cinfo)){
2510             current->state = TASK_RUNNING;
2511             remove_wait_queue(&info->open_wait, &wait);
2512             return -EINVAL;
2513         }
2514
2515         zfw_ctrl = (struct ZFW_CTRL *)
2516                     (base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
2517         board_ctrl = &zfw_ctrl->board_ctrl;
2518         ch_ctrl = zfw_ctrl->ch_ctrl;
2519
2520         while (1) {
2521             if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
2522                 (tty->termios->c_cflag & CBAUD)){
2523                 cy_writel(&ch_ctrl[channel].rs_control,
2524                         cy_readl(&ch_ctrl[channel].rs_control) |
2525                         (C_RS_RTS | C_RS_DTR));
2526                 retval = cyz_issue_cmd(&cy_card[info->card],
2527                                        channel, C_CM_IOCTLM, 0L);
2528                 if (retval != 0){
2529                     printk("cyc:block_til_ready retval on ttyC%d was %x\n",
2530                            info->line, retval);
2531                 }
2532 #ifdef CY_DEBUG_DTR
2533                 printk("cyc:block_til_ready raising Z DTR\n");
2534 #endif
2535             }
2536
2537             set_current_state(TASK_INTERRUPTIBLE);
2538             if (tty_hung_up_p(filp)
2539             || !(info->flags & ASYNC_INITIALIZED) ){
2540                 retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
2541                     -EAGAIN : -ERESTARTSYS);
2542                 break;
2543             }
2544             if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2545             && !(info->flags & ASYNC_CLOSING)
2546             && (C_CLOCAL(tty)
2547               || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) {
2548                 break;
2549             }
2550             if (signal_pending(current)) {
2551                 retval = -ERESTARTSYS;
2552                 break;
2553             }
2554 #ifdef CY_DEBUG_OPEN
2555             printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2556                    info->line, info->count);/**/
2557 #endif
2558             schedule();
2559         }
2560     }
2561     current->state = TASK_RUNNING;
2562     remove_wait_queue(&info->open_wait, &wait);
2563     if (!tty_hung_up_p(filp)){
2564         info->count++;
2565 #ifdef CY_DEBUG_COUNT
2566         printk("cyc:block_til_ready (%d): incrementing count to %d\n",
2567             current->pid, info->count);
2568 #endif
2569     }
2570     info->blocked_open--;
2571 #ifdef CY_DEBUG_OPEN
2572     printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
2573            info->line, info->count);/**/
2574 #endif
2575     if (retval)
2576         return retval;
2577     info->flags |= ASYNC_NORMAL_ACTIVE;
2578     return 0;
2579 } /* block_til_ready */
2580
2581
2582 /*
2583  * This routine is called whenever a serial port is opened.  It
2584  * performs the serial-specific initialization for the tty structure.
2585  */
2586 static int
2587 cy_open(struct tty_struct *tty, struct file * filp)
2588 {
2589   struct cyclades_port  *info;
2590   int retval, line;
2591   unsigned long page;
2592
2593     MOD_INC_USE_COUNT;
2594     line = MINOR(tty->device) - tty->driver.minor_start;
2595     if ((line < 0) || (NR_PORTS <= line)){
2596         MOD_DEC_USE_COUNT;
2597         return -ENODEV;
2598     }
2599     info = &cy_port[line];
2600     if (info->line < 0){
2601         MOD_DEC_USE_COUNT;
2602         return -ENODEV;
2603     }
2604     
2605     /* If the card's firmware hasn't been loaded,
2606        treat it as absent from the system.  This
2607        will make the user pay attention.
2608     */
2609     if (IS_CYC_Z(cy_card[info->card])) {
2610         if (!ISZLOADED(cy_card[info->card])) {
2611             if (((ZE_V1 ==cy_readl(&((struct RUNTIME_9060 *)
2612                 ((cy_card[info->card]).ctl_addr))->mail_box_0)) &&
2613                 Z_FPGA_CHECK(cy_card[info->card])) &&
2614                 (ZFIRM_HLT==cy_readl(&((struct FIRM_ID *)
2615                 ((cy_card[info->card]).base_addr+ID_ADDRESS))->signature)))
2616             {
2617                 printk ("cyc:Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
2618             } else {
2619                 printk("cyc:Cyclades-Z firmware not yet loaded\n");
2620             }
2621             MOD_DEC_USE_COUNT;
2622             return -ENODEV;
2623         }
2624 #ifdef CONFIG_CYZ_INTR
2625         else {
2626             /* In case this Z board is operating in interrupt mode, its 
2627                interrupts should be enabled as soon as the first open happens 
2628                to one of its ports. */
2629             if (!cy_card[info->card].intr_enabled) {
2630                 /* Enable interrupts on the PLX chip */
2631                 cy_writew(cy_card[info->card].ctl_addr+0x68,
2632                         cy_readw(cy_card[info->card].ctl_addr+0x68)|0x0900);
2633                 /* Enable interrupts on the FW */
2634                 retval = cyz_issue_cmd(&cy_card[info->card], 
2635                                         0, C_CM_IRQ_ENBL, 0L);
2636                 if (retval != 0){
2637                     printk("cyc:IRQ enable retval was %x\n", retval);
2638                 }
2639                 cy_card[info->card].intr_enabled = 1;
2640             }
2641         }
2642 #endif /* CONFIG_CYZ_INTR */
2643     }
2644 #ifdef CY_DEBUG_OTHER
2645     printk("cyc:cy_open ttyC%d\n", info->line); /* */
2646 #endif
2647     tty->driver_data = info;
2648     info->tty = tty;
2649     if (serial_paranoia_check(info, tty->device, "cy_open")){
2650         return -ENODEV;
2651     }
2652 #ifdef CY_DEBUG_OPEN
2653     printk("cyc:cy_open ttyC%d, count = %d\n",
2654         info->line, info->count);/**/
2655 #endif
2656     info->count++;
2657 #ifdef CY_DEBUG_COUNT
2658     printk("cyc:cy_open (%d): incrementing count to %d\n",
2659         current->pid, info->count);
2660 #endif
2661     if (!tmp_buf) {
2662         page = get_free_page(GFP_KERNEL);
2663         if (!page)
2664             return -ENOMEM;
2665         if (tmp_buf)
2666             free_page(page);
2667         else
2668             tmp_buf = (unsigned char *) page;
2669     }
2670
2671     /*
2672      * If the port is the middle of closing, bail out now
2673      */
2674     if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2675         if (info->flags & ASYNC_CLOSING)
2676             interruptible_sleep_on(&info->close_wait);
2677         return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2678     }
2679
2680     /*
2681      * Start up serial port
2682      */
2683     retval = startup(info);
2684     if (retval){
2685         return retval;
2686     }
2687
2688     retval = block_til_ready(tty, filp, info);
2689     if (retval) {
2690 #ifdef CY_DEBUG_OPEN
2691         printk("cyc:cy_open returning after block_til_ready with %d\n",
2692                retval);
2693 #endif
2694         return retval;
2695     }
2696
2697     if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
2698         if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
2699             *tty->termios = info->normal_termios;
2700         else 
2701             *tty->termios = info->callout_termios;
2702     }
2703
2704     info->session = current->session;
2705     info->pgrp = current->pgrp;
2706
2707 #ifdef CY_DEBUG_OPEN
2708     printk(" cyc:cy_open done\n");/**/
2709 #endif
2710
2711     return 0;
2712 } /* cy_open */
2713
2714
2715 /*
2716  * cy_wait_until_sent() --- wait until the transmitter is empty
2717  */
2718 static void 
2719 cy_wait_until_sent(struct tty_struct *tty, int timeout)
2720 {
2721   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2722   unsigned char *base_addr;
2723   int card,chip,channel,index;
2724   unsigned long orig_jiffies, char_time;
2725         
2726     if (serial_paranoia_check(info, tty->device, "cy_wait_until_sent"))
2727         return;
2728
2729     if (info->xmit_fifo_size == 0)
2730         return; /* Just in case.... */
2731
2732
2733     orig_jiffies = jiffies;
2734     /*
2735      * Set the check interval to be 1/5 of the estimated time to
2736      * send a single character, and make it at least 1.  The check
2737      * interval should also be less than the timeout.
2738      * 
2739      * Note: we have to use pretty tight timings here to satisfy
2740      * the NIST-PCTS.
2741      */
2742     char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
2743     char_time = char_time / 5;
2744     if (char_time == 0)
2745         char_time = 1;
2746     if (timeout < 0)
2747         timeout = 0;
2748     if (timeout)
2749         char_time = MIN(char_time, timeout);
2750     /*
2751      * If the transmitter hasn't cleared in twice the approximate
2752      * amount of time to send the entire FIFO, it probably won't
2753      * ever clear.  This assumes the UART isn't doing flow
2754      * control, which is currently the case.  Hence, if it ever
2755      * takes longer than info->timeout, this is probably due to a
2756      * UART bug of some kind.  So, we clamp the timeout parameter at
2757      * 2*info->timeout.
2758      */
2759     if (!timeout || timeout > 2*info->timeout)
2760         timeout = 2*info->timeout;
2761 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2762     printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
2763     printk("jiff=%lu...", jiffies);
2764 #endif
2765     card = info->card;
2766     channel = (info->line) - (cy_card[card].first_line);
2767     if (!IS_CYC_Z(cy_card[card])) {
2768         chip = channel>>2;
2769         channel &= 0x03;
2770         index = cy_card[card].bus_index;
2771         base_addr = (unsigned char *)