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