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