File: /usr/src/linux/drivers/char/cyclades.c

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