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