~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/char/cyclades.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 suport 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 suport 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 #define cy_min(a,b) (((a)<(b))?(a):(b))
632 
633 /*
634  * Include section 
635  */
636 #include <linux/config.h>
637 #include <linux/module.h>
638 #include <linux/errno.h>
639 #include <linux/signal.h>
640 #include <linux/sched.h>
641 #include <linux/timer.h>
642 #include <linux/interrupt.h>
643 #include <linux/tty.h>
644 #include <linux/serial.h>
645 #include <linux/major.h>
646 #include <linux/string.h>
647 #include <linux/fcntl.h>
648 #include <linux/ptrace.h>
649 #include <linux/cyclades.h>
650 #include <linux/mm.h>
651 #include <linux/ioport.h>
652 #include <linux/init.h>
653 #include <linux/delay.h>
654 #include <linux/spinlock.h>
655 
656 #include <asm/system.h>
657 #include <asm/io.h>
658 #include <asm/irq.h>
659 #include <asm/uaccess.h>
660 #include <asm/bitops.h>
661 
662 #define CY_LOCK(info,flags)                                     \
663                 do {                                            \
664                 spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \
665                 } while (0)
666                 
667 #define CY_UNLOCK(info,flags)                                   \
668                 do {                                            \
669                 spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \
670                 } while (0)
671 
672 #include <linux/types.h>
673 #include <linux/kernel.h>
674 #include <linux/pci.h>
675 #include <linux/version.h>
676 
677 #include <linux/stat.h>
678 #include <linux/proc_fs.h>
679 
680 #ifdef CONFIG_COBALT_27
681 #include <asm/page.h>
682 #include <asm/pgtable.h>
683 
684 #define CACHED_TO_UNCACHED(x)   (((unsigned long)(x) & \
685                                   (unsigned long)0x1fffffff) + KSEG1)
686 #endif
687 
688 #define cy_put_user     put_user
689 
690 static unsigned long 
691 cy_get_user(unsigned long *addr)
692 {
693         unsigned long result = 0;
694         int error = get_user (result, addr);
695         if (error)
696                 printk ("cyclades: cy_get_user: error == %d\n", error);
697         return result;
698 }
699 
700 #ifndef MIN
701 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
702 #endif
703 
704 #define IS_CYC_Z(card) ((card).num_chips == -1)
705 
706 #define Z_FPGA_CHECK(card) \
707     ((cy_readl(&((struct RUNTIME_9060 *) \
708                  ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
709 
710 #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 *) \
711                         ((card).ctl_addr))->mail_box_0)) || \
712                         Z_FPGA_CHECK(card)) && \
713                         (ZFIRM_ID==cy_readl(&((struct FIRM_ID *) \
714                         ((card).base_addr+ID_ADDRESS))->signature)))
715 
716 #ifndef SERIAL_XMIT_SIZE
717 #define SERIAL_XMIT_SIZE        (MIN(PAGE_SIZE, 4096))
718 #endif
719 #define WAKEUP_CHARS            256
720 
721 #define STD_COM_FLAGS (0)
722 
723 #define JIFFIES_DIFF(n, j)      ((j) - (n))
724 
725 static DECLARE_TASK_QUEUE(tq_cyclades);
726 
727 static struct tty_driver cy_serial_driver, cy_callout_driver;
728 static int serial_refcount;
729 
730 #ifdef CONFIG_ISA
731 /* This is the address lookup table. The driver will probe for
732    Cyclom-Y/ISA boards at all addresses in here. If you want the
733    driver to probe addresses at a different address, add it to
734    this table.  If the driver is probing some other board and
735    causing problems, remove the offending address from this table.
736    The cy_setup function extracts additional addresses from the
737    boot options line.  The form is "cyclades=address,address..."
738 */
739 
740 static unsigned char *cy_isa_addresses[] = {
741         (unsigned char *) 0xD0000,
742         (unsigned char *) 0xD2000,
743         (unsigned char *) 0xD4000,
744         (unsigned char *) 0xD6000,
745         (unsigned char *) 0xD8000,
746         (unsigned char *) 0xDA000,
747         (unsigned char *) 0xDC000,
748         (unsigned char *) 0xDE000,
749         0,0,0,0,0,0,0,0
750 };
751 #define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
752 
753 #ifdef MODULE
754 static int maddr[NR_CARDS] = { 0, };
755 static int irq[NR_CARDS]  = { 0, };
756 
757 MODULE_PARM(maddr, "1-" __MODULE_STRING(NR_CARDS) "l");
758 MODULE_PARM(irq, "1-" __MODULE_STRING(NR_CARDS) "i");
759 #endif
760 
761 #endif /* CONFIG_ISA */
762 
763 /* This is the per-card data structure containing address, irq, number of
764    channels, etc. This driver supports a maximum of NR_CARDS cards.
765 */
766 static struct cyclades_card cy_card[NR_CARDS];
767 
768 /* This is the per-channel data structure containing pointers, flags
769  and variables for the port. This driver supports a maximum of NR_PORTS.
770 */
771 static struct cyclades_port cy_port[NR_PORTS];
772 
773 static int cy_next_channel; /* next minor available */
774 
775 static struct tty_struct *serial_table[NR_PORTS];
776 static struct termios *serial_termios[NR_PORTS];
777 static struct termios *serial_termios_locked[NR_PORTS];
778 
779 /*
780  * tmp_buf is used as a temporary buffer by serial_write.  We need to
781  * lock it in case the copy_from_user blocks while swapping in a page,
782  * and some other program tries to do a serial write at the same time.
783  * Since the lock will only come under contention when the system is
784  * swapping and available memory is low, it makes sense to share one
785  * buffer across all the serial ports, since it significantly saves
786  * memory if large numbers of serial ports are open.  This buffer is
787  * allocated when the first cy_open occurs.
788  */
789 static unsigned char *tmp_buf;
790 DECLARE_MUTEX(tmp_buf_sem);
791 
792 /*
793  * This is used to look up the divisor speeds and the timeouts
794  * We're normally limited to 15 distinct baud rates.  The extra
795  * are accessed via settings in info->flags.
796  *      0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
797  *     10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
798  *                                               HI            VHI
799  *     20
800  */
801 static int baud_table[] = {
802        0,    50,    75,   110,   134,   150,   200,   300,   600,  1200,
803     1800,  2400,  4800,  9600, 19200, 38400, 57600, 76800,115200,150000,
804   230400,     0};
805 
806 static char baud_co_25[] = {  /* 25 MHz clock option table */
807     /* value =>    00    01   02    03    04 */
808     /* divide by    8    32   128   512  2048 */
809     0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,  0x03,  0x02,
810     0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00};
811 
812 static char baud_bpr_25[] = {  /* 25 MHz baud rate period table */
813     0x00,  0xf5,  0xa3,  0x6f,  0x5c,  0x51,  0xf5,  0xa3,  0x51,  0xa3,
814     0x6d,  0x51,  0xa3,  0x51,  0xa3,  0x51,  0x36,  0x29,  0x1b,  0x15};
815 
816 static char baud_co_60[] = {  /* 60 MHz clock option table (CD1400 J) */
817     /* value =>    00    01   02    03    04 */
818     /* divide by    8    32   128   512  2048 */
819     0x00,  0x00,  0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,
820     0x03,  0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,
821     0x00};
822 
823 static char baud_bpr_60[] = {  /* 60 MHz baud rate period table (CD1400 J) */
824     0x00,  0x82,  0x21,  0xff,  0xdb,  0xc3,  0x92,  0x62,  0xc3,  0x62,
825     0x41,  0xc3,  0x62,  0xc3,  0x62,  0xc3,  0x82,  0x62,  0x41,  0x32,
826     0x21};
827 
828 static char baud_cor3[] = {  /* receive threshold */
829     0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
830     0x0a,  0x0a,  0x0a,  0x09,  0x09,  0x08,  0x08,  0x08,  0x08,  0x07,
831     0x07};
832 
833 /*
834  * The Cyclades driver implements HW flow control as any serial driver.
835  * The cyclades_port structure member rflow and the vector rflow_thr 
836  * allows us to take advantage of a special feature in the CD1400 to avoid 
837  * data loss even when the system interrupt latency is too high. These flags 
838  * are to be used only with very special applications. Setting these flags 
839  * requires the use of a special cable (DTR and RTS reversed). In the new 
840  * CD1400-based boards (rev. 6.00 or later), there is no need for special 
841  * cables.
842  */
843 
844 static char rflow_thr[] = {  /* rflow threshold */
845     0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
846     0x00,  0x00,  0x00,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
847     0x0a};
848 
849 /*  The Cyclom-Ye has placed the sequential chips in non-sequential
850  *  address order.  This look-up table overcomes that problem.
851  */
852 static int cy_chip_offset [] =
853     { 0x0000,
854       0x0400,
855       0x0800,
856       0x0C00,
857       0x0200,
858       0x0600,
859       0x0A00,
860       0x0E00
861     };
862 
863 /* PCI related definitions */
864 
865 static unsigned short   cy_pci_nboard;
866 static unsigned short   cy_isa_nboard;
867 static unsigned short   cy_nboard;
868 #ifdef CONFIG_PCI
869 static unsigned short   cy_pci_dev_id[] = {
870                             PCI_DEVICE_ID_CYCLOM_Y_Lo,  /* PCI < 1Mb */
871                             PCI_DEVICE_ID_CYCLOM_Y_Hi,  /* PCI > 1Mb */
872                             PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */
873                             PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */
874                             PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */
875                             PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */
876                             PCI_DEVICE_ID_CYCLOM_Z_Lo,  /* Z PCI < 1Mb */
877                             PCI_DEVICE_ID_CYCLOM_Z_Hi,  /* Z PCI > 1Mb */
878                             0                           /* end of table */
879                         };
880 #endif
881 
882 static void cy_start(struct tty_struct *);
883 static void set_line_char(struct cyclades_port *);
884 static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong);
885 #ifdef CONFIG_ISA
886 static unsigned detect_isa_irq (volatile ucchar *);
887 #endif /* CONFIG_ISA */
888 
889 static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
890 
891 #ifndef CONFIG_CYZ_INTR
892 static void cyz_poll(unsigned long);
893 
894 /* The Cyclades-Z polling cycle is defined by this variable */
895 static long cyz_polling_cycle = CZ_DEF_POLL;
896 
897 static int cyz_timeron = 0;
898 static struct timer_list cyz_timerlist = {
899     function: cyz_poll
900 };
901 #else /* CONFIG_CYZ_INTR */
902 static void cyz_rx_restart(unsigned long);
903 static struct timer_list cyz_rx_full_timer[NR_PORTS];
904 #endif /* CONFIG_CYZ_INTR */
905 
906 static inline int
907 serial_paranoia_check(struct cyclades_port *info,
908                         kdev_t device, const char *routine)
909 {
910 #ifdef SERIAL_PARANOIA_CHECK
911     static const char *badmagic =
912         "cyc Warning: bad magic number for serial struct (%s) in %s\n";
913     static const char *badinfo =
914         "cyc Warning: null cyclades_port for (%s) in %s\n";
915     static const char *badrange =
916         "cyc Warning: cyclades_port out of range for (%s) in %s\n";
917 
918     if (!info) {
919         printk(badinfo, kdevname(device), routine);
920         return 1;
921     }
922 
923     if( (long)info < (long)(&cy_port[0])
924     || (long)(&cy_port[NR_PORTS]) < (long)info ){
925         printk(badrange, kdevname(device), routine);
926         return 1;
927     }
928 
929     if (info->magic != CYCLADES_MAGIC) {
930         printk(badmagic, kdevname(device), routine);
931         return 1;
932     }
933 #endif
934         return 0;
935 } /* serial_paranoia_check */
936 
937 /*
938  * This routine is used by the interrupt handler to schedule
939  * processing in the software interrupt portion of the driver
940  * (also known as the "bottom half").  This can be called any
941  * number of times for any channel without harm.
942  */
943 static inline void
944 cy_sched_event(struct cyclades_port *info, int event)
945 {
946     info->event |= 1 << event; /* remember what kind of event and who */
947     queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */
948     mark_bh(CYCLADES_BH);                       /* then trigger event */
949 } /* cy_sched_event */
950 
951 
952 /*
953  * This routine is used to handle the "bottom half" processing for the
954  * serial driver, known also the "software interrupt" processing.
955  * This processing is done at the kernel interrupt level, after the
956  * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
957  * is where time-consuming activities which can not be done in the
958  * interrupt driver proper are done; the interrupt driver schedules
959  * them using cy_sched_event(), and they get done here.
960  *
961  * This is done through one level of indirection--the task queue.
962  * When a hardware interrupt service routine wants service by the
963  * driver's bottom half, it enqueues the appropriate tq_struct (one
964  * per port) to the tq_cyclades work queue and sets a request flag
965  * via mark_bh for processing that queue.  When the time is right,
966  * do_cyclades_bh is called (because of the mark_bh) and it requests
967  * that the work queue be processed.
968  *
969  * Although this may seem unwieldy, it gives the system a way to
970  * pass an argument (in this case the pointer to the cyclades_port
971  * structure) to the bottom half of the driver.  Previous kernels
972  * had to poll every port to see if that port needed servicing.
973  */
974 static void
975 do_cyclades_bh(void)
976 {
977     run_task_queue(&tq_cyclades);
978 } /* do_cyclades_bh */
979 
980 static void
981 do_softint(void *private_)
982 {
983   struct cyclades_port *info = (struct cyclades_port *) private_;
984   struct tty_struct    *tty;
985 
986     tty = info->tty;
987     if (!tty)
988         return;
989 
990     if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
991         tty_hangup(info->tty);
992         wake_up_interruptible(&info->open_wait);
993         info->flags &= ~(ASYNC_NORMAL_ACTIVE|
994                              ASYNC_CALLOUT_ACTIVE);
995     }
996     if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
997         wake_up_interruptible(&info->open_wait);
998     }
999 #ifdef CONFIG_CYZ_INTR
1000     if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) {
1001         if (cyz_rx_full_timer[info->line].function == NULL) {
1002             cyz_rx_full_timer[info->line].expires = jiffies + 1;
1003             cyz_rx_full_timer[info->line].function = cyz_rx_restart;
1004             cyz_rx_full_timer[info->line].data = (unsigned long)info;
1005             add_timer(&cyz_rx_full_timer[info->line]);
1006         }
1007     }
1008 #endif
1009     if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) {
1010         wake_up_interruptible(&info->delta_msr_wait);
1011     }
1012     if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
1013         if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
1014         && tty->ldisc.write_wakeup){
1015             (tty->ldisc.write_wakeup)(tty);
1016         }
1017         wake_up_interruptible(&tty->write_wait);
1018     }
1019 #ifdef Z_WAKE
1020     if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
1021         wake_up_interruptible(&info->shutdown_wait);
1022     }
1023 #endif
1024 } /* do_softint */
1025 
1026 
1027 /***********************************************************/
1028 /********* Start of block of Cyclom-Y specific code ********/
1029 
1030 /* This routine waits up to 1000 micro-seconds for the previous
1031    command to the Cirrus chip to complete and then issues the
1032    new command.  An error is returned if the previous command
1033    didn't finish within the time limit.
1034 
1035    This function is only called from inside spinlock-protected code.
1036  */
1037 static int
1038 cyy_issue_cmd(volatile ucchar *base_addr, u_char cmd, int index)
1039 {
1040   volatile int  i;
1041 
1042     /* Check to see that the previous command has completed */
1043     for(i = 0 ; i < 100 ; i++){
1044         if (cy_readb(base_addr+(CyCCR<<index)) == 0){
1045             break;
1046         }
1047         udelay(10L);
1048     }
1049     /* if the CCR never cleared, the previous command
1050        didn't finish within the "reasonable time" */
1051     if (i == 100)       return (-1);
1052 
1053     /* Issue the new command */
1054     cy_writeb((u_long)base_addr+(CyCCR<<index), cmd);
1055 
1056     return(0);
1057 } /* cyy_issue_cmd */
1058 
1059 #ifdef CONFIG_ISA
1060 /* ISA interrupt detection code */
1061 static unsigned 
1062 detect_isa_irq (volatile ucchar *address)
1063 {
1064   int irq;
1065   unsigned long irqs, flags;
1066   int save_xir, save_car;
1067   int index = 0; /* IRQ probing is only for ISA */
1068 
1069     /* forget possible initially masked and pending IRQ */
1070     irq = probe_irq_off(probe_irq_on());
1071 
1072     /* Clear interrupts on the board first */
1073     cy_writeb((u_long)address + (Cy_ClrIntr<<index), 0);
1074                               /* Cy_ClrIntr is 0x1800 */
1075 
1076     irqs = probe_irq_on();
1077     /* Wait ... */
1078     udelay(5000L);
1079 
1080     /* Enable the Tx interrupts on the CD1400 */
1081     save_flags(flags); cli();
1082         cy_writeb((u_long)address + (CyCAR<<index), 0);
1083         cyy_issue_cmd(address, CyCHAN_CTL|CyENB_XMTR, index);
1084 
1085         cy_writeb((u_long)address + (CyCAR<<index), 0);
1086         cy_writeb((u_long)address + (CySRER<<index), 
1087                 cy_readb(address + (CySRER<<index)) | CyTxRdy);
1088     restore_flags(flags);
1089 
1090     /* Wait ... */
1091     udelay(5000L);
1092 
1093     /* Check which interrupt is in use */
1094     irq = probe_irq_off(irqs);
1095 
1096     /* Clean up */
1097     save_xir = (u_char) cy_readb(address + (CyTIR<<index));
1098     save_car = cy_readb(address + (CyCAR<<index));
1099     cy_writeb((u_long)address + (CyCAR<<index), (save_xir & 0x3));
1100     cy_writeb((u_long)address + (CySRER<<index),
1101         cy_readb(address + (CySRER<<index)) & ~CyTxRdy);
1102     cy_writeb((u_long)address + (CyTIR<<index), (save_xir & 0x3f));
1103     cy_writeb((u_long)address + (CyCAR<<index), (save_car));
1104     cy_writeb((u_long)address + (Cy_ClrIntr<<index), 0);
1105                               /* Cy_ClrIntr is 0x1800 */
1106 
1107     return (irq > 0)? irq : 0;
1108 }
1109 #endif /* CONFIG_ISA */
1110 
1111 /* The real interrupt service routine is called
1112    whenever the card wants its hand held--chars
1113    received, out buffer empty, modem change, etc.
1114  */
1115 static void
1116 cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1117 {
1118   struct tty_struct *tty;
1119   int status;
1120   struct cyclades_card *cinfo;
1121   struct cyclades_port *info;
1122   volatile unsigned char *base_addr, *card_base_addr;
1123   int chip;
1124   int save_xir, channel, save_car;
1125   char data;
1126   volatile int char_count;
1127   int outch;
1128   int i,j,index;
1129   int too_many;
1130   int had_work;
1131   int mdm_change;
1132   int mdm_status;
1133 
1134     if((cinfo = (struct cyclades_card *)dev_id) == 0){
1135 #ifdef CY_DEBUG_INTERRUPTS
1136         printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
1137 #endif
1138         return; /* spurious interrupt */
1139     }
1140 
1141     card_base_addr = (unsigned char *)cinfo->base_addr;
1142     index = cinfo->bus_index;
1143 
1144 
1145     /* This loop checks all chips in the card.  Make a note whenever
1146        _any_ chip had some work to do, as this is considered an
1147        indication that there will be more to do.  Only when no chip
1148        has any work does this outermost loop exit.
1149      */
1150     do{
1151         had_work = 0;
1152         for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) {
1153             base_addr = (unsigned char *)
1154                        (cinfo->base_addr + (cy_chip_offset[chip]<<index));
1155             too_many = 0;
1156             while ( (status = cy_readb(base_addr+(CySVRR<<index))) != 0x00) {
1157                 had_work++;
1158                 /* The purpose of the following test is to ensure that
1159                    no chip can monopolize the driver.  This forces the
1160                    chips to be checked in a round-robin fashion (after
1161                    draining each of a bunch (1000) of characters).
1162                  */
1163                 if(1000<too_many++){
1164                     break;
1165                 }
1166                 if (status & CySRReceive) { /* reception interrupt */
1167 #ifdef CY_DEBUG_INTERRUPTS
1168                     printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
1169 #endif
1170                     /* determine the channel & change to that context */
1171                     spin_lock(&cinfo->card_lock);
1172                     save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
1173                     channel = (u_short ) (save_xir & CyIRChannel);
1174                     i = channel + chip * 4 + cinfo->first_line;
1175                     info = &cy_port[i];
1176                     info->last_active = jiffies;
1177                     save_car = cy_readb(base_addr+(CyCAR<<index));
1178                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1179 
1180                     /* if there is nowhere to put the data, discard it */
1181                     if(info->tty == 0){
1182                         j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1183                         if ( j == CyIVRRxEx ) { /* exception */
1184                             data = cy_readb(base_addr+(CyRDSR<<index));
1185                         } else { /* normal character reception */
1186                             char_count = cy_readb(base_addr+(CyRDCR<<index));
1187                             while(char_count--){
1188                                 data = cy_readb(base_addr+(CyRDSR<<index));
1189                             }
1190                         }
1191                     }else{ /* there is an open port for this data */
1192                         tty = info->tty;
1193                         j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
1194                         if ( j == CyIVRRxEx ) { /* exception */
1195                             data = cy_readb(base_addr+(CyRDSR<<index));
1196 
1197                             /* For statistics only */
1198                             if (data & CyBREAK)
1199                                 info->icount.brk++;
1200                             else if(data & CyFRAME)
1201                                 info->icount.frame++;
1202                             else if(data & CyPARITY)
1203                                 info->icount.parity++;
1204                             else if(data & CyOVERRUN)
1205                                 info->icount.overrun++;
1206 
1207                             if(data & info->ignore_status_mask){
1208                                 info->icount.rx++;
1209                                 continue;
1210                             }
1211                             if (tty->flip.count < TTY_FLIPBUF_SIZE){
1212                                 tty->flip.count++;
1213                                 if (data & info->read_status_mask){
1214                                     if(data & CyBREAK){
1215                                         *tty->flip.flag_buf_ptr++ =
1216                                                             TTY_BREAK;
1217                                         *tty->flip.char_buf_ptr++ =
1218                                           cy_readb(base_addr+(CyRDSR<<index));
1219                                         info->icount.rx++;
1220                                         if (info->flags & ASYNC_SAK){
1221                                             do_SAK(tty);
1222                                         }
1223                                     }else if(data & CyFRAME){
1224                                         *tty->flip.flag_buf_ptr++ =
1225                                                             TTY_FRAME;
1226                                         *tty->flip.char_buf_ptr++ =
1227                                           cy_readb(base_addr+(CyRDSR<<index));
1228                                         info->icount.rx++;
1229                                         info->idle_stats.frame_errs++;
1230                                     }else if(data & CyPARITY){
1231                                         *tty->flip.flag_buf_ptr++ =
1232                                                             TTY_PARITY;
1233                                         *tty->flip.char_buf_ptr++ =
1234                                           cy_readb(base_addr+(CyRDSR<<index));
1235                                         info->icount.rx++;
1236                                         info->idle_stats.parity_errs++;
1237                                     }else if(data & CyOVERRUN){
1238                                         *tty->flip.flag_buf_ptr++ =
1239                                                             TTY_OVERRUN;
1240                                         *tty->flip.char_buf_ptr++ = 0;
1241                                         info->icount.rx++;
1242                                         /* If the flip buffer itself is
1243                                            overflowing, we still lose
1244                                            the next incoming character.
1245                                          */
1246                                         if(tty->flip.count
1247                                                    < TTY_FLIPBUF_SIZE){
1248                                             tty->flip.count++;
1249                                             *tty->flip.flag_buf_ptr++ =
1250                                                              TTY_NORMAL;
1251                                            *tty->flip.char_buf_ptr++ =
1252                                             cy_readb(base_addr+(CyRDSR<<index));
1253                                             info->icount.rx++;
1254                                         }
1255                                         info->idle_stats.overruns++;
1256                                     /* These two conditions may imply */
1257                                     /* a normal read should be done. */
1258                                     /* }else if(data & CyTIMEOUT){ */
1259                                     /* }else if(data & CySPECHAR){ */
1260                                     }else{
1261                                         *tty->flip.flag_buf_ptr++ = 0;
1262                                         *tty->flip.char_buf_ptr++ = 0;
1263                                         info->icount.rx++;
1264                                     }
1265                                 }else{
1266                                     *tty->flip.flag_buf_ptr++ = 0;
1267                                     *tty->flip.char_buf_ptr++ = 0;
1268                                     info->icount.rx++;
1269                                 }
1270                             }else{
1271                                 /* there was a software buffer
1272                                    overrun and nothing could be
1273                                    done about it!!! */
1274                                 info->icount.buf_overrun++;
1275                                 info->idle_stats.overruns++;
1276                             }
1277                         } else { /* normal character reception */
1278                             /* load # chars available from the chip */
1279                             char_count = cy_readb(base_addr+(CyRDCR<<index));
1280 
1281 #ifdef CY_ENABLE_MONITORING
1282                             ++info->mon.int_count;
1283                             info->mon.char_count += char_count;
1284                             if (char_count > info->mon.char_max)
1285                                info->mon.char_max = char_count;
1286                             info->mon.char_last = char_count;
1287 #endif
1288                             info->idle_stats.recv_bytes += char_count;
1289                             info->idle_stats.recv_idle   = jiffies;
1290                             while(char_count--){
1291                                 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1292                                         break;
1293                                 }
1294                                 tty->flip.count++;
1295                                 data = cy_readb(base_addr+(CyRDSR<<index));
1296                                 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1297                                 *tty->flip.char_buf_ptr++ = data;
1298                                 info->icount.rx++;
1299 #ifdef CY_16Y_HACK
1300                                 udelay(10L);
1301 #endif
1302                             }
1303                         }
1304                         queue_task(&tty->flip.tqueue, &tq_timer);
1305                     }
1306                     /* end of service */
1307                     cy_writeb((u_long)base_addr+(CyRIR<<index), (save_xir & 0x3f));
1308                     cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1309                     spin_unlock(&cinfo->card_lock);
1310                 }
1311 
1312 
1313                 if (status & CySRTransmit) { /* transmission interrupt */
1314                     /* Since we only get here when the transmit buffer
1315                        is empty, we know we can always stuff a dozen
1316                        characters. */
1317 #ifdef CY_DEBUG_INTERRUPTS
1318                     printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
1319 #endif
1320 
1321                     /* determine the channel & change to that context */
1322                     spin_lock(&cinfo->card_lock);
1323                     save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index));
1324                     channel = (u_short ) (save_xir & CyIRChannel);
1325                     i = channel + chip * 4 + cinfo->first_line;
1326                     save_car = cy_readb(base_addr+(CyCAR<<index));
1327                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1328 
1329                     /* validate the port# (as configured and open) */
1330                     if( (i < 0) || (NR_PORTS <= i) ){
1331                         cy_writeb((u_long)base_addr+(CySRER<<index),
1332                              cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1333                         goto txend;
1334                     }
1335                     info = &cy_port[i];
1336                     info->last_active = jiffies;
1337                     if(info->tty == 0){
1338                         cy_writeb((u_long)base_addr+(CySRER<<index),
1339                              cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
1340                         goto txdone;
1341                     }
1342 
1343                     /* load the on-chip space for outbound data */
1344                     char_count = info->xmit_fifo_size;
1345 
1346                     if(info->x_char) { /* send special char */
1347                         outch = info->x_char;
1348                         cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1349                         char_count--;
1350                         info->icount.tx++;
1351                         info->x_char = 0;
1352                     }
1353 
1354                     if (info->breakon || info->breakoff) {
1355                         if (info->breakon) {
1356                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0); 
1357                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0x81);
1358                             info->breakon = 0;
1359                             char_count -= 2;
1360                         }
1361                         if (info->breakoff) {
1362                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0); 
1363                             cy_writeb((u_long)base_addr + (CyTDR<<index), 0x83);
1364                             info->breakoff = 0;
1365                             char_count -= 2;
1366                         }
1367                     }
1368 
1369                     while (char_count-- > 0){
1370                         if (!info->xmit_cnt){
1371                             if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
1372                                 cy_writeb((u_long)base_addr+(CySRER<<index),
1373                                           cy_readb(base_addr+(CySRER<<index)) &
1374                                           ~CyTxMpty);
1375                             } else {
1376                                 cy_writeb((u_long)base_addr+(CySRER<<index),
1377                                           ((cy_readb(base_addr+(CySRER<<index))
1378                                             & ~CyTxRdy)
1379                                            | CyTxMpty));
1380                             }
1381                             goto txdone;
1382                         }
1383                         if (info->xmit_buf == 0){
1384                             cy_writeb((u_long)base_addr+(CySRER<<index),
1385                                 cy_readb(base_addr+(CySRER<<index)) & 
1386                                         ~CyTxRdy);
1387                             goto txdone;
1388                         }
1389                         if (info->tty->stopped || info->tty->hw_stopped){
1390                             cy_writeb((u_long)base_addr+(CySRER<<index),
1391                                 cy_readb(base_addr+(CySRER<<index)) & 
1392                                         ~CyTxRdy);
1393                             goto txdone;
1394                         }
1395                         /* Because the Embedded Transmit Commands have
1396                            been enabled, we must check to see if the
1397                            escape character, NULL, is being sent.  If it
1398                            is, we must ensure that there is room for it
1399                            to be doubled in the output stream.  Therefore
1400                            we no longer advance the pointer when the
1401                            character is fetched, but rather wait until
1402                            after the check for a NULL output character.
1403                            This is necessary because there may not be
1404                            room for the two chars needed to send a NULL.)
1405                          */
1406                         outch = info->xmit_buf[info->xmit_tail];
1407                         if( outch ){
1408                             info->xmit_cnt--;
1409                             info->xmit_tail = (info->xmit_tail + 1)
1410                                                       & (SERIAL_XMIT_SIZE - 1);
1411                             cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
1412                             info->icount.tx++;
1413                         }else{
1414                             if(char_count > 1){
1415                                 info->xmit_cnt--;
1416                                 info->xmit_tail = (info->xmit_tail + 1)
1417                                                       & (SERIAL_XMIT_SIZE - 1);
1418                                 cy_writeb((u_long)base_addr+(CyTDR<<index), 
1419                                           outch);
1420                                 cy_writeb((u_long)base_addr+(CyTDR<<index), 0);
1421                                 info->icount.tx++;
1422                                 char_count--;
1423                             }else{
1424                             }
1425                         }
1426                     }
1427 
1428         txdone:
1429                     if (info->xmit_cnt < WAKEUP_CHARS) {
1430                         cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1431                     }
1432         txend:
1433                     /* end of service */
1434                     cy_writeb((u_long)base_addr+(CyTIR<<index), 
1435                               (save_xir & 0x3f));
1436                     cy_writeb((u_long)base_addr+(CyCAR<<index), (save_car));
1437                     spin_unlock(&cinfo->card_lock);
1438                 }
1439 
1440                 if (status & CySRModem) {        /* modem interrupt */
1441 
1442                     /* determine the channel & change to that context */
1443                     spin_lock(&cinfo->card_lock);
1444                     save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));
1445                     channel = (u_short ) (save_xir & CyIRChannel);
1446                     info = &cy_port[channel + chip * 4
1447                                            + cinfo->first_line];
1448                     info->last_active = jiffies;
1449                     save_car = cy_readb(base_addr+(CyCAR<<index));
1450                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_xir);
1451 
1452                     mdm_change = cy_readb(base_addr+(CyMISR<<index));
1453                     mdm_status = cy_readb(base_addr+(CyMSVR1<<index));
1454 
1455                     if(info->tty == 0){/* no place for data, ignore it*/
1456                         ;
1457                     }else{
1458                         if (mdm_change & CyANY_DELTA) {
1459                             /* For statistics only */
1460                             if (mdm_change & CyDCD)     info->icount.dcd++;
1461                             if (mdm_change & CyCTS)     info->icount.cts++;
1462                             if (mdm_change & CyDSR)     info->icount.dsr++;
1463                             if (mdm_change & CyRI)      info->icount.rng++;
1464 
1465                             cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
1466                         }
1467 
1468                         if((mdm_change & CyDCD)
1469                         && (info->flags & ASYNC_CHECK_CD)){
1470                             if(mdm_status & CyDCD){
1471                                 cy_sched_event(info,
1472                                     Cy_EVENT_OPEN_WAKEUP);
1473                             }else if(!((info->flags
1474                                         & ASYNC_CALLOUT_ACTIVE)
1475                                  &&(info->flags
1476                                     & ASYNC_CALLOUT_NOHUP))){
1477                                 cy_sched_event(info,
1478                                     Cy_EVENT_HANGUP);
1479                             }
1480                         }
1481                         if((mdm_change & CyCTS)
1482                         && (info->flags & ASYNC_CTS_FLOW)){
1483                             if(info->tty->hw_stopped){
1484                                 if(mdm_status & CyCTS){
1485                                     /* cy_start isn't used
1486                                          because... !!! */
1487                                     info->tty->hw_stopped = 0;
1488                                   cy_writeb((u_long)base_addr+(CySRER<<index),
1489                                        cy_readb(base_addr+(CySRER<<index)) | 
1490                                        CyTxRdy);
1491                                     cy_sched_event(info,
1492                                         Cy_EVENT_WRITE_WAKEUP);
1493                                 }
1494                             }else{
1495                                 if(!(mdm_status & CyCTS)){
1496                                     /* cy_stop isn't used
1497                                          because ... !!! */
1498                                     info->tty->hw_stopped = 1;
1499                                   cy_writeb((u_long)base_addr+(CySRER<<index),
1500                                        cy_readb(base_addr+(CySRER<<index)) & 
1501                                        ~CyTxRdy);
1502                                 }
1503                             }
1504                         }
1505                         if(mdm_change & CyDSR){
1506                         }
1507                         if(mdm_change & CyRI){
1508                         }
1509                     }
1510                     /* end of service */
1511                     cy_writeb((u_long)base_addr+(CyMIR<<index), 
1512                               (save_xir & 0x3f));
1513                     cy_writeb((u_long)base_addr+(CyCAR<<index), save_car);
1514                     spin_unlock(&cinfo->card_lock);
1515                 }
1516             }          /* end while status != 0 */
1517         }            /* end loop for chips... */
1518     } while(had_work);
1519 
1520    /* clear interrupts */
1521    spin_lock(&cinfo->card_lock);
1522    cy_writeb((u_long)card_base_addr + (Cy_ClrIntr<<index), 0);
1523                                 /* Cy_ClrIntr is 0x1800 */
1524    spin_unlock(&cinfo->card_lock);
1525 } /* cyy_interrupt */
1526 
1527 /***********************************************************/
1528 /********* End of block of Cyclom-Y specific code **********/
1529 /******** Start of block of Cyclades-Z specific code *********/
1530 /***********************************************************/
1531 
1532 static int
1533 cyz_fetch_msg( struct cyclades_card *cinfo,
1534             uclong *channel, ucchar *cmd, uclong *param)
1535 {
1536   struct FIRM_ID *firm_id;
1537   struct ZFW_CTRL *zfw_ctrl;
1538   struct BOARD_CTRL *board_ctrl;
1539   unsigned long loc_doorbell;
1540 
1541     firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1542     if (!ISZLOADED(*cinfo)){
1543         return (-1);
1544     }
1545     zfw_ctrl = (struct ZFW_CTRL *)
1546                 (cinfo->base_addr + 
1547                  (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1548     board_ctrl = &zfw_ctrl->board_ctrl;
1549 
1550     loc_doorbell = cy_readl(&((struct RUNTIME_9060 *)
1551                      (cinfo->ctl_addr))->loc_doorbell);
1552     if (loc_doorbell){
1553         *cmd = (char)(0xff & loc_doorbell);
1554         *channel = cy_readl(&board_ctrl->fwcmd_channel);
1555         *param = (uclong)cy_readl(&board_ctrl->fwcmd_param);
1556         cy_writel(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->loc_doorbell, 
1557                  0xffffffff);
1558         return 1;
1559     }
1560     return 0;
1561 } /* cyz_fetch_msg */
1562 
1563 static int
1564 cyz_issue_cmd( struct cyclades_card *cinfo,
1565             uclong channel, ucchar cmd, uclong param)
1566 {
1567   struct FIRM_ID *firm_id;
1568   struct ZFW_CTRL *zfw_ctrl;
1569   struct BOARD_CTRL *board_ctrl;
1570   volatile uclong *pci_doorbell;
1571   int index;
1572 
1573     firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1574     if (!ISZLOADED(*cinfo)){
1575         return (-1);
1576     }
1577     zfw_ctrl = (struct ZFW_CTRL *)
1578                 (cinfo->base_addr + 
1579                  (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1580     board_ctrl = &zfw_ctrl->board_ctrl;
1581 
1582     index = 0;
1583     pci_doorbell = (uclong *)(&((struct RUNTIME_9060 *)
1584                                (cinfo->ctl_addr))->pci_doorbell);
1585     while( (cy_readl(pci_doorbell) & 0xff) != 0){
1586         if (index++ == 1000){
1587             return((int)(cy_readl(pci_doorbell) & 0xff));
1588         }
1589         udelay(50L);
1590     }
1591     cy_writel((u_long)&board_ctrl->hcmd_channel, channel);
1592     cy_writel((u_long)&board_ctrl->hcmd_param , param);
1593     cy_writel((u_long)pci_doorbell, (long)cmd);
1594 
1595     return(0);
1596 } /* cyz_issue_cmd */
1597 
1598 static void
1599 cyz_handle_rx(struct cyclades_port *info, volatile struct CH_CTRL *ch_ctrl,
1600               volatile struct BUF_CTRL *buf_ctrl)
1601 {
1602   struct cyclades_card *cinfo = &cy_card[info->card];
1603   struct tty_struct *tty = info->tty;
1604   volatile int char_count;
1605 #ifdef BLOCKMOVE
1606   int small_count;
1607 #else
1608   char data;
1609 #endif
1610   volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
1611 
1612     rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get);
1613     rx_put = cy_readl(&buf_ctrl->rx_put);
1614     rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
1615     rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr);
1616     if (rx_put >= rx_get)
1617         char_count = rx_put - rx_get;
1618     else
1619         char_count = rx_put - rx_get + rx_bufsize;
1620 
1621     if ( char_count ) {
1622         info->last_active = jiffies;
1623         info->jiffies[1] = jiffies;
1624 
1625 #ifdef CY_ENABLE_MONITORING
1626         info->mon.int_count++;
1627         info->mon.char_count += char_count;
1628         if (char_count > info->mon.char_max)
1629             info->mon.char_max = char_count;
1630         info->mon.char_last = char_count;
1631 #endif
1632         if(tty == 0){
1633             /* flush received characters */
1634             new_rx_get = (new_rx_get + char_count) & (rx_bufsize - 1);
1635             info->rflush_count++;
1636         }else{
1637 #ifdef BLOCKMOVE
1638             /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
1639                for performance, but because of buffer boundaries, there
1640                may be several steps to the operation */
1641             while(0 < (small_count = 
1642                        cy_min((rx_bufsize - new_rx_get),
1643                        cy_min((TTY_FLIPBUF_SIZE - tty->flip.count), char_count))
1644                  )) {
1645                 memcpy_fromio(tty->flip.char_buf_ptr,
1646                               (char *)(cinfo->base_addr
1647                                        + rx_bufaddr + new_rx_get),
1648                               small_count);
1649 
1650                 tty->flip.char_buf_ptr += small_count;
1651                 memset(tty->flip.flag_buf_ptr, TTY_NORMAL, small_count);
1652                 tty->flip.flag_buf_ptr += small_count;
1653                 new_rx_get = (new_rx_get + small_count) & (rx_bufsize - 1);
1654                 char_count -= small_count;
1655                 info->icount.rx += small_count;
1656                 info->idle_stats.recv_bytes += small_count;
1657                 tty->flip.count += small_count;
1658             }
1659 #else
1660             while(char_count--){
1661                 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
1662                     break;
1663                 }
1664                 data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get);
1665                 new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1);
1666                 tty->flip.count++;
1667                 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
1668                 *tty->flip.char_buf_ptr++ = data;
1669                 info->idle_stats.recv_bytes++;
1670                 info->icount.rx++;
1671             }
1672 #endif
1673 #ifdef CONFIG_CYZ_INTR
1674             /* Recalculate the number of chars in the RX buffer and issue
1675                a cmd in case it's higher than the RX high water mark */
1676             rx_put = cy_readl(&buf_ctrl->rx_put);
1677             if (rx_put >= rx_get)
1678                 char_count = rx_put - rx_get;
1679             else
1680                 char_count = rx_put - rx_get + rx_bufsize;
1681             if(char_count >= cy_readl(&buf_ctrl->rx_threshold)) {
1682                 cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
1683             }
1684 #endif
1685             info->idle_stats.recv_idle = jiffies;
1686             queue_task(&tty->flip.tqueue, &tq_timer);
1687         }
1688         /* Update rx_get */
1689         cy_writel(&buf_ctrl->rx_get, new_rx_get);
1690     }
1691 }
1692 
1693 static void
1694 cyz_handle_tx(struct cyclades_port *info, volatile struct CH_CTRL *ch_ctrl,
1695               volatile struct BUF_CTRL *buf_ctrl)
1696 {
1697   struct cyclades_card *cinfo = &cy_card[info->card];
1698   struct tty_struct *tty = info->tty;
1699   char data;
1700   volatile int char_count;
1701 #ifdef BLOCKMOVE
1702   int small_count;
1703 #endif
1704   volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr;
1705 
1706     if (info->xmit_cnt <= 0)    /* Nothing to transmit */
1707         return;
1708 
1709     tx_get = cy_readl(&buf_ctrl->tx_get);
1710     tx_put = cy_readl(&buf_ctrl->tx_put);
1711     tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
1712     tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr);
1713     if (tx_put >= tx_get)
1714         char_count = tx_get - tx_put - 1 + tx_bufsize;
1715     else
1716         char_count = tx_get - tx_put - 1;
1717 
1718     if ( char_count ) {
1719 
1720         if( tty == 0 ){
1721             goto ztxdone;
1722         }
1723 
1724         if(info->x_char) { /* send special char */
1725             data = info->x_char;
1726 
1727             cy_writeb((cinfo->base_addr + tx_bufaddr + tx_put), data);
1728             tx_put = (tx_put + 1) & (tx_bufsize - 1);
1729             info->x_char = 0;
1730             char_count--;
1731             info->icount.tx++;
1732             info->last_active = jiffies;
1733             info->jiffies[2] = jiffies;
1734         }
1735 #ifdef BLOCKMOVE
1736         while(0 < (small_count = 
1737                    cy_min((tx_bufsize - tx_put),
1738                    cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
1739                         cy_min(info->xmit_cnt, char_count))))){
1740 
1741             memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put),
1742                         &info->xmit_buf[info->xmit_tail],
1743                         small_count);
1744 
1745             tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1746             char_count -= small_count;
1747             info->icount.tx += small_count;
1748             info->xmit_cnt -= small_count;
1749             info->xmit_tail = 
1750                 (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
1751             info->last_active = jiffies;
1752             info->jiffies[2] = jiffies;
1753         }
1754 #else
1755         while (info->xmit_cnt && char_count){
1756             data = info->xmit_buf[info->xmit_tail];
1757             info->xmit_cnt--;
1758             info->xmit_tail = (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
1759 
1760             cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1761             tx_put = (tx_put + 1) & (tx_bufsize - 1);
1762             char_count--;
1763             info->icount.tx++;
1764             info->last_active = jiffies;
1765             info->jiffies[2] = jiffies;
1766         }
1767 #endif
1768     ztxdone:
1769         if (info->xmit_cnt < WAKEUP_CHARS) {
1770             cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
1771         }
1772         /* Update tx_put */
1773         cy_writel(&buf_ctrl->tx_put, tx_put);
1774     }
1775 }
1776 
1777 static void
1778 cyz_handle_cmd(struct cyclades_card *cinfo)
1779 {
1780   struct tty_struct *tty;
1781   struct cyclades_port *info;
1782   static volatile struct FIRM_ID *firm_id;
1783   static volatile struct ZFW_CTRL *zfw_ctrl;
1784   static volatile struct BOARD_CTRL *board_ctrl;
1785   static volatile struct CH_CTRL *ch_ctrl;
1786   static volatile struct BUF_CTRL *buf_ctrl;
1787   uclong channel;
1788   ucchar cmd;
1789   uclong param;
1790   uclong hw_ver, fw_ver;
1791   int special_count;
1792   int delta_count;
1793 
1794     firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1795     zfw_ctrl = (struct ZFW_CTRL *)
1796                 (cinfo->base_addr + 
1797                  (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1798     board_ctrl = &(zfw_ctrl->board_ctrl);
1799     fw_ver = cy_readl(&board_ctrl->fw_version);
1800     hw_ver = cy_readl(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->mail_box_0);
1801 
1802 #ifdef CONFIG_CYZ_INTR
1803     if (!cinfo->nports)
1804         cinfo->nports = (int) cy_readl(&board_ctrl->n_channel);
1805 #endif
1806 
1807     while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
1808         special_count = 0;
1809         delta_count = 0;
1810         info = &cy_port[channel + cinfo->first_line];
1811         if((tty = info->tty) == 0) {
1812             continue;
1813         }
1814         ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1815         buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1816 
1817         switch(cmd) {
1818             case C_CM_PR_ERROR:
1819                 tty->flip.count++;
1820                 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
1821                 *tty->flip.char_buf_ptr++ = 0;
1822                 info->icount.rx++;
1823                 special_count++;
1824                 break;
1825             case C_CM_FR_ERROR:
1826                 tty->flip.count++;
1827                 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
1828                 *tty->flip.char_buf_ptr++ = 0;
1829                 info->icount.rx++;
1830                 special_count++;
1831                 break;
1832             case C_CM_RXBRK:
1833                 tty->flip.count++;
1834                 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
1835                 *tty->flip.char_buf_ptr++ = 0;
1836                 info->icount.rx++;
1837                 special_count++;
1838                 break;
1839             case C_CM_MDCD:
1840                 info->icount.dcd++;
1841                 delta_count++;
1842                 if (info->flags & ASYNC_CHECK_CD){
1843                     if ((fw_ver > 241 ? 
1844                           ((u_long)param) : 
1845                           cy_readl(&ch_ctrl->rs_status)) & C_RS_DCD) {
1846                         cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
1847                     }else if(!((info->flags & ASYNC_CALLOUT_ACTIVE)
1848                              &&(info->flags & ASYNC_CALLOUT_NOHUP))){
1849                         cy_sched_event(info, Cy_EVENT_HANGUP);
1850                     }
1851                 }
1852                 break;
1853             case C_CM_MCTS:
1854                 info->icount.cts++;
1855                 delta_count++;
1856                 break;
1857             case C_CM_MRI:
1858                 info->icount.rng++;
1859                 delta_count++;
1860                 break;
1861             case C_CM_MDSR:
1862                 info->icount.dsr++;
1863                 delta_count++;
1864                 break;
1865 #ifdef Z_WAKE
1866             case C_CM_IOCTLW:
1867                 cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
1868                 break;
1869 #endif
1870 #ifdef CONFIG_CYZ_INTR
1871             case C_CM_RXHIWM:
1872             case C_CM_RXNNDT:
1873             case C_CM_INTBACK2:
1874                 /* Reception Interrupt */
1875 #ifdef CY_DEBUG_INTERRUPTS
1876                 printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", 
1877                         info->card, channel);
1878 #endif
1879                 cyz_handle_rx(info, ch_ctrl, buf_ctrl);
1880                 break;
1881             case C_CM_TXBEMPTY:
1882             case C_CM_TXLOWWM:
1883             case C_CM_INTBACK:
1884                 /* Transmission Interrupt */
1885 #ifdef CY_DEBUG_INTERRUPTS
1886                 printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r", 
1887                         info->card, channel);
1888 #endif
1889                 cyz_handle_tx(info, ch_ctrl, buf_ctrl);
1890                 break;
1891 #endif /* CONFIG_CYZ_INTR */
1892             case C_CM_FATAL:
1893                 /* should do something with this !!! */
1894                 break;
1895             default:
1896                 break;
1897         }
1898         if(delta_count)
1899             cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
1900         if(special_count)
1901             queue_task(&tty->flip.tqueue, &tq_timer);
1902     }
1903 }
1904 
1905 #ifdef CONFIG_CYZ_INTR
1906 static void
1907 cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1908 {
1909   struct cyclades_card *cinfo;
1910 
1911     if((cinfo = (struct cyclades_card *)dev_id) == 0){
1912 #ifdef CY_DEBUG_INTERRUPTS
1913         printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
1914 #endif
1915         return; /* spurious interrupt */
1916     }
1917 
1918     if (!ISZLOADED(*cinfo)) {
1919 #ifdef CY_DEBUG_INTERRUPTS
1920         printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq);
1921 #endif
1922         return;
1923     }
1924 
1925     /* Handle the interrupts */
1926     cyz_handle_cmd(cinfo);
1927 
1928     return;
1929 } /* cyz_interrupt */
1930 
1931 static void
1932 cyz_rx_restart(unsigned long arg)
1933 {
1934     struct cyclades_port *info = (struct cyclades_port *)arg;
1935     int retval;
1936     int card = info->card;
1937     uclong channel = (info->line) - (cy_card[card].first_line);
1938     unsigned long flags;
1939 
1940     CY_LOCK(info, flags);
1941     retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L);
1942     if (retval != 0){
1943         printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", 
1944                info->line, retval);
1945     }
1946     cyz_rx_full_timer[info->line].function = NULL;
1947     CY_UNLOCK(info, flags);
1948 }
1949 
1950 #else /* CONFIG_CYZ_INTR */
1951 
1952 static void
1953 cyz_poll(unsigned long arg)
1954 {
1955   struct cyclades_card *cinfo;
1956   struct cyclades_port *info;
1957   struct tty_struct *tty;
1958   static volatile struct FIRM_ID *firm_id;
1959   static volatile struct ZFW_CTRL *zfw_ctrl;
1960   static volatile struct BOARD_CTRL *board_ctrl;
1961   static volatile struct CH_CTRL *ch_ctrl;
1962   static volatile struct BUF_CTRL *buf_ctrl;
1963   int card, port;
1964 
1965     cyz_timerlist.expires = jiffies + (HZ);
1966     for (card = 0 ; card < NR_CARDS ; card++){
1967         cinfo = &cy_card[card];
1968 
1969         if (!IS_CYC_Z(*cinfo)) continue;
1970         if (!ISZLOADED(*cinfo)) continue;
1971 
1972         firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
1973         zfw_ctrl = (struct ZFW_CTRL *)
1974                     (cinfo->base_addr + 
1975                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
1976         board_ctrl = &(zfw_ctrl->board_ctrl);
1977 
1978         /* Skip first polling cycle to avoid racing conditions with the FW */
1979         if (!cinfo->intr_enabled) {
1980             cinfo->nports = (int) cy_readl(&board_ctrl->n_channel);
1981             cinfo->intr_enabled = 1;
1982             continue;
1983         }
1984 
1985         cyz_handle_cmd(cinfo);
1986 
1987         for (port = 0 ; port < cinfo->nports ; port++) {
1988             info = &cy_port[ port + cinfo->first_line ];
1989             tty = info->tty;
1990             ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
1991             buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
1992 
1993             cyz_handle_rx(info, ch_ctrl, buf_ctrl);
1994             cyz_handle_tx(info, ch_ctrl, buf_ctrl);
1995         }
1996         /* poll every 'cyz_polling_cycle' period */
1997         cyz_timerlist.expires = jiffies + cyz_polling_cycle;
1998     }
1999     add_timer(&cyz_timerlist);
2000 
2001     return;
2002 } /* cyz_poll */
2003 
2004 #endif /* CONFIG_CYZ_INTR */
2005 
2006 /********** End of block of Cyclades-Z specific code *********/
2007 /***********************************************************/
2008 
2009 
2010 /* This is called whenever a port becomes active;
2011    interrupts are enabled and DTR & RTS are turned on.
2012  */
2013 static int
2014 startup(struct cyclades_port * info)
2015 {
2016   unsigned long flags;
2017   int retval = 0;
2018   unsigned char *base_addr;
2019   int card,chip,channel,index;
2020   unsigned long page;
2021 
2022     card = info->card;
2023     channel = (info->line) - (cy_card[card].first_line);
2024 
2025     page = get_free_page(GFP_KERNEL);
2026     if (!page)
2027         return -ENOMEM;
2028 
2029     CY_LOCK(info, flags);
2030 
2031     if (info->flags & ASYNC_INITIALIZED){
2032         free_page(page);
2033         goto errout;
2034     }
2035 
2036     if (!info->type){
2037         if (info->tty){
2038             set_bit(TTY_IO_ERROR, &info->tty->flags);
2039         }
2040         free_page(page);
2041         goto errout;
2042     }
2043 
2044     if (info->xmit_buf)
2045         free_page(page);
2046     else
2047         info->xmit_buf = (unsigned char *) page;
2048 
2049     CY_UNLOCK(info, flags);
2050 
2051     set_line_char(info);
2052 
2053     if (!IS_CYC_Z(cy_card[card])) {
2054         chip = channel>>2;
2055         channel &= 0x03;
2056         index = cy_card[card].bus_index;
2057         base_addr = (unsigned char*)
2058                    (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
2059 
2060 #ifdef CY_DEBUG_OPEN
2061         printk("cyc startup card %d, chip %d, channel %d, base_addr %lx\n",
2062              card, chip, channel, (long)base_addr);/**/
2063 #endif
2064 
2065         CY_LOCK(info, flags);
2066 
2067         cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2068 
2069         cy_writeb((ulong)base_addr+(CyRTPR<<index), (info->default_timeout
2070                  ? info->default_timeout : 0x02)); /* 10ms rx timeout */
2071 
2072         cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index);
2073 
2074         cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2075         cy_writeb((ulong)base_addr+(CyMSVR1<<index), CyRTS);
2076         cy_writeb((ulong)base_addr+(CyMSVR2<<index), CyDTR);
2077 
2078 #ifdef CY_DEBUG_DTR
2079         printk("cyc:startup raising DTR\n");
2080         printk("     status: 0x%x, 0x%x\n",
2081                 cy_readb(base_addr+(CyMSVR1<<index)), 
2082                 cy_readb(base_addr+(CyMSVR2<<index)));
2083 #endif
2084 
2085         cy_writeb((u_long)base_addr+(CySRER<<index),
2086                 cy_readb(base_addr+(CySRER<<index)) | CyRxData);
2087         info->flags |= ASYNC_INITIALIZED;
2088 
2089         if (info->tty){
2090             clear_bit(TTY_IO_ERROR, &info->tty->flags);
2091         }
2092         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2093         info->breakon = info->breakoff = 0;
2094         memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2095         info->idle_stats.in_use    =
2096         info->idle_stats.recv_idle =
2097         info->idle_stats.xmit_idle = jiffies;
2098 
2099         CY_UNLOCK(info, flags);
2100 
2101     } else {
2102       struct FIRM_ID *firm_id;
2103       struct ZFW_CTRL *zfw_ctrl;
2104       struct BOARD_CTRL *board_ctrl;
2105       struct CH_CTRL *ch_ctrl;
2106       int retval;
2107 
2108         base_addr = (unsigned char*) (cy_card[card].base_addr);
2109 
2110         firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2111         if (!ISZLOADED(cy_card[card])){
2112             return -ENODEV;
2113         }
2114 
2115         zfw_ctrl = (struct ZFW_CTRL *)
2116                     (cy_card[card].base_addr + 
2117                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
2118         board_ctrl = &zfw_ctrl->board_ctrl;
2119         ch_ctrl = zfw_ctrl->ch_ctrl;
2120 
2121 #ifdef CY_DEBUG_OPEN
2122         printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
2123              card, channel, (long)base_addr);/**/
2124 #endif
2125 
2126         CY_LOCK(info, flags);
2127 
2128         cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
2129 #ifdef Z_WAKE
2130 #ifdef CONFIG_CYZ_INTR
2131         cy_writel(&ch_ctrl[channel].intr_enable, 
2132                   C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
2133                   C_IN_IOCTLW|
2134                   C_IN_MDCD);
2135 #else
2136         cy_writel(&ch_ctrl[channel].intr_enable, 
2137                   C_IN_IOCTLW|
2138                   C_IN_MDCD);
2139 #endif /* CONFIG_CYZ_INTR */
2140 #else
2141 #ifdef CONFIG_CYZ_INTR
2142         cy_writel(&ch_ctrl[channel].intr_enable, 
2143                   C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
2144                   C_IN_MDCD);
2145 #else
2146         cy_writel(&ch_ctrl[channel].intr_enable, 
2147                   C_IN_MDCD);
2148 #endif /* CONFIG_CYZ_INTR */
2149 #endif /* Z_WAKE */
2150 
2151         retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
2152         if (retval != 0){
2153             printk("cyc:startup(1) retval on ttyC%d was %x\n",
2154                    info->line, retval);
2155         }
2156 
2157         /* Flush RX buffers before raising DTR and RTS */
2158         retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, 0L);
2159         if (retval != 0){
2160             printk("cyc:startup(2) retval on ttyC%d was %x\n",
2161                    info->line, retval);
2162         }
2163 
2164         /* set timeout !!! */
2165         /* set RTS and DTR !!! */
2166         cy_writel(&ch_ctrl[channel].rs_control,
2167              cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR) ;
2168         retval = cyz_issue_cmd(&cy_card[info->card],
2169             channel, C_CM_IOCTLM, 0L);
2170         if (retval != 0){
2171             printk("cyc:startup(3) retval on ttyC%d was %x\n",
2172                    info->line, retval);
2173         }
2174 #ifdef CY_DEBUG_DTR
2175             printk("cyc:startup raising Z DTR\n");
2176 #endif
2177 
2178         /* enable send, recv, modem !!! */
2179 
2180         info->flags |= ASYNC_INITIALIZED;
2181         if (info->tty){
2182             clear_bit(TTY_IO_ERROR, &info->tty->flags);
2183         }
2184         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2185         info->breakon = info->breakoff = 0;
2186         memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
2187         info->idle_stats.in_use    =
2188         info->idle_stats.recv_idle =
2189         info->idle_stats.xmit_idle = jiffies;
2190 
2191         CY_UNLOCK(info, flags);
2192     }
2193 
2194 #ifdef CY_DEBUG_OPEN
2195         printk(" cyc startup done\n");
2196 #endif
2197         return 0;
2198 
2199 errout:
2200         CY_UNLOCK(info, flags);
2201         return retval;
2202 } /* startup */
2203 
2204 
2205 static void
2206 start_xmit( struct cyclades_port *info )
2207 {
2208   unsigned long flags;
2209   unsigned char *base_addr;
2210   int card,chip,channel,index;
2211 
2212     card = info->card;
2213     channel = (info->line) - (cy_card[card].first_line);
2214     if (!IS_CYC_Z(cy_card[card])) {
2215         chip = channel>>2;
2216         channel &= 0x03;
2217         index = cy_card[card].bus_index;
2218         base_addr = (unsigned char*)
2219                        (cy_card[card].base_addr
2220                        + (cy_chip_offset[chip]<<index));
2221 
2222         CY_LOCK(info, flags);
2223             cy_writeb((u_long)base_addr+(CyCAR<<index), channel);
2224             cy_writeb((u_long)base_addr+(CySRER<<index), 
2225                cy_readb(base_addr+(CySRER<<index)) | CyTxRdy);
2226         CY_UNLOCK(info, flags);
2227     } else {
2228 #ifdef CONFIG_CYZ_INTR
2229       int retval;
2230 
2231         CY_LOCK(info, flags);
2232             retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 0L);
2233             if (retval != 0){
2234                 printk("cyc:start_xmit retval on ttyC%d was %x\n",
2235                        info->line, retval);
2236             }
2237         CY_UNLOCK(info, flags);
2238 #else /* CONFIG_CYZ_INTR */
2239         /* Don't have to do anything at this time */
2240 #endif /* CONFIG_CYZ_INTR */
2241     }
2242 } /* start_xmit */
2243 
2244 /*
2245  * This routine shuts down a serial port; interrupts are disabled,
2246  * and DTR is dropped if the hangup on close termio flag is on.
2247  */
2248 static void
2249 shutdown(struct cyclades_port * info)
2250 {
2251   unsigned long flags;
2252   unsigned char *base_addr;
2253   int card,chip,channel,index;
2254 
2255     if (!(info->flags & ASYNC_INITIALIZED)){
2256         return;
2257     }
2258 
2259     card = info->card;
2260     channel = info->line - cy_card[card].first_line;
2261     if (!IS_CYC_Z(cy_card[card])) {
2262         chip = channel>>2;
2263         channel &= 0x03;
2264         index = cy_card[card].bus_index;
2265         base_addr = (unsigned char*)
2266                        (cy_card[card].base_addr
2267                        + (cy_chip_offset[chip]<<index));
2268 
2269 #ifdef CY_DEBUG_OPEN
2270     printk("cyc shutdown Y card %d, chip %d, channel %d, base_addr %lx\n",
2271                 card, chip, channel, (long)base_addr);
2272 #endif
2273 
2274         CY_LOCK(info, flags);
2275 
2276             /* Clear delta_msr_wait queue to avoid mem leaks. */
2277             wake_up_interruptible(&info->delta_msr_wait);
2278 
2279             if (info->xmit_buf){
2280                 unsigned char * temp;
2281                 temp = info->xmit_buf;
2282                 info->xmit_buf = 0;
2283                 free_page((unsigned long) temp);
2284             }
2285             cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2286             if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2287                 cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
2288                 cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
2289 #ifdef CY_DEBUG_DTR
2290                 printk("cyc shutdown dropping DTR\n");
2291                 printk("     status: 0x%x, 0x%x\n",
2292                     cy_readb(base_addr+(CyMSVR1<<index)), 
2293                     cy_readb(base_addr+(CyMSVR2<<index)));
2294 #endif
2295             }
2296             cyy_issue_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR,index);
2297              /* it may be appropriate to clear _XMIT at
2298                some later date (after testing)!!! */
2299 
2300             if (info->tty){
2301                 set_bit(TTY_IO_ERROR, &info->tty->flags);
2302             }
2303             info->flags &= ~ASYNC_INITIALIZED;
2304         CY_UNLOCK(info, flags);
2305     } else {
2306       struct FIRM_ID *firm_id;
2307       struct ZFW_CTRL *zfw_ctrl;
2308       struct BOARD_CTRL *board_ctrl;
2309       struct CH_CTRL *ch_ctrl;
2310       int retval;
2311 
2312         base_addr = (unsigned char*) (cy_card[card].base_addr);
2313 #ifdef CY_DEBUG_OPEN
2314     printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
2315                 card, channel, (long)base_addr);
2316 #endif
2317 
2318         firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2319         if (!ISZLOADED(cy_card[card])) {
2320             return;
2321         }
2322 
2323         zfw_ctrl = (struct ZFW_CTRL *)
2324                     (cy_card[card].base_addr + 
2325                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
2326         board_ctrl = &(zfw_ctrl->board_ctrl);
2327         ch_ctrl = zfw_ctrl->ch_ctrl;
2328 
2329         CY_LOCK(info, flags);
2330 
2331             if (info->xmit_buf){
2332                 unsigned char * temp;
2333                 temp = info->xmit_buf;
2334                 info->xmit_buf = 0;
2335                 free_page((unsigned long) temp);
2336             }
2337             
2338             if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2339                 cy_writel((u_long)&ch_ctrl[channel].rs_control,
2340                    (uclong)(cy_readl(&ch_ctrl[channel].rs_control) & 
2341                    ~(C_RS_RTS | C_RS_DTR)));
2342                 retval = cyz_issue_cmd(&cy_card[info->card],
2343                         channel, C_CM_IOCTLM, 0L);
2344                 if (retval != 0){
2345                     printk("cyc:shutdown retval on ttyC%d was %x\n",
2346                            info->line, retval);
2347                 }
2348 #ifdef CY_DEBUG_DTR
2349                 printk("cyc:shutdown dropping Z DTR\n");
2350 #endif
2351             }
2352             
2353             if (info->tty){
2354                 set_bit(TTY_IO_ERROR, &info->tty->flags);
2355             }
2356             info->flags &= ~ASYNC_INITIALIZED;
2357 
2358         CY_UNLOCK(info, flags);
2359     }
2360 
2361 #ifdef CY_DEBUG_OPEN
2362     printk(" cyc shutdown done\n");
2363 #endif
2364     return;
2365 } /* shutdown */
2366 
2367 
2368 /*
2369  * ------------------------------------------------------------
2370  * cy_open() and friends
2371  * ------------------------------------------------------------
2372  */
2373 
2374 static int
2375 block_til_ready(struct tty_struct *tty, struct file * filp,
2376                            struct cyclades_port *info)
2377 {
2378   DECLARE_WAITQUEUE(wait, current);
2379   struct cyclades_card *cinfo;
2380   unsigned long flags;
2381   int chip, channel,index;
2382   int retval;
2383   char *base_addr;
2384 
2385     cinfo = &cy_card[info->card];
2386     channel = info->line - cinfo->first_line;
2387 
2388     /*
2389      * If the device is in the middle of being closed, then block
2390      * until it's done, and then try again.
2391      */
2392     if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2393         if (info->flags & ASYNC_CLOSING) {
2394             interruptible_sleep_on(&info->close_wait);
2395         }
2396         return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2397     }
2398 
2399     /*
2400      * If this is a callout device, then just make sure the normal
2401      * device isn't being used.
2402      */
2403     if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
2404         if (info->flags & ASYNC_NORMAL_ACTIVE){
2405             return -EBUSY;
2406         }
2407         if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2408             (info->flags & ASYNC_SESSION_LOCKOUT) &&
2409             (info->session != current->session)){
2410             return -EBUSY;
2411         }
2412         if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2413             (info->flags & ASYNC_PGRP_LOCKOUT) &&
2414             (info->pgrp != current->pgrp)){
2415             return -EBUSY;
2416         }
2417         info->flags |= ASYNC_CALLOUT_ACTIVE;
2418         return 0;
2419     }
2420 
2421     /*
2422      * If non-blocking mode is set, then make the check up front
2423      * and then exit.
2424      */
2425     if ((filp->f_flags & O_NONBLOCK) ||
2426         (tty->flags & (1 << TTY_IO_ERROR))) {
2427         if (info->flags & ASYNC_CALLOUT_ACTIVE){
2428             return -EBUSY;
2429         }
2430         info->flags |= ASYNC_NORMAL_ACTIVE;
2431         return 0;
2432     }
2433 
2434     /*
2435      * Block waiting for the carrier detect and the line to become
2436      * free (i.e., not in use by the callout).  While we are in
2437      * this loop, info->count is dropped by one, so that
2438      * cy_close() knows when to free things.  We restore it upon
2439      * exit, either normal or abnormal.
2440      */
2441     retval = 0;
2442     add_wait_queue(&info->open_wait, &wait);
2443 #ifdef CY_DEBUG_OPEN
2444     printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
2445            info->line, info->count);/**/
2446 #endif
2447     CY_LOCK(info, flags);
2448     if (!tty_hung_up_p(filp))
2449         info->count--;
2450     CY_UNLOCK(info, flags);
2451 #ifdef CY_DEBUG_COUNT
2452     printk("cyc block_til_ready: (%d): decrementing count to %d\n",
2453         current->pid, info->count);
2454 #endif
2455     info->blocked_open++;
2456 
2457     if (!IS_CYC_Z(*cinfo)) {
2458         chip = channel>>2;
2459         channel &= 0x03;
2460         index = cinfo->bus_index;
2461         base_addr = (char *)(cinfo->base_addr
2462                             + (cy_chip_offset[chip]<<index));
2463 
2464         while (1) {
2465             CY_LOCK(info, flags);
2466                 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
2467                     (tty->termios->c_cflag & CBAUD)){
2468                     cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2469                     cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
2470                     cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
2471 #ifdef CY_DEBUG_DTR
2472                     printk("cyc:block_til_ready raising DTR\n");
2473                     printk("     status: 0x%x, 0x%x\n",
2474                         cy_readb(base_addr+(CyMSVR1<<index)), 
2475                         cy_readb(base_addr+(CyMSVR2<<index)));
2476 #endif
2477                 }
2478             CY_UNLOCK(info, flags);
2479 
2480             set_current_state(TASK_INTERRUPTIBLE);
2481             if (tty_hung_up_p(filp)
2482             || !(info->flags & ASYNC_INITIALIZED) ){
2483                 retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 
2484                     -EAGAIN : -ERESTARTSYS);
2485                 break;
2486             }
2487 
2488             CY_LOCK(info, flags);
2489                 cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
2490                 if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2491                 && !(info->flags & ASYNC_CLOSING)
2492                 && (C_CLOCAL(tty)
2493                     || (cy_readb(base_addr+(CyMSVR1<<index)) & CyDCD))) {
2494                         CY_UNLOCK(info, flags);
2495                         break;
2496                 }
2497             CY_UNLOCK(info, flags);
2498 
2499             if (signal_pending(current)) {
2500                 retval = -ERESTARTSYS;
2501                 break;
2502             }
2503 #ifdef CY_DEBUG_OPEN
2504             printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2505                    info->line, info->count);/**/
2506 #endif
2507             schedule();
2508         }
2509     } else {
2510       struct FIRM_ID *firm_id;
2511       struct ZFW_CTRL *zfw_ctrl;
2512       struct BOARD_CTRL *board_ctrl;
2513       struct CH_CTRL *ch_ctrl;
2514       int retval;
2515 
2516         base_addr = (char *)(cinfo->base_addr);
2517         firm_id = (struct FIRM_ID *)
2518                         (base_addr + ID_ADDRESS);
2519         if (!ISZLOADED(*cinfo)){
2520             current->state = TASK_RUNNING;
2521             remove_wait_queue(&info->open_wait, &wait);
2522             return -EINVAL;
2523         }
2524 
2525         zfw_ctrl = (struct ZFW_CTRL *)
2526                     (base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
2527         board_ctrl = &zfw_ctrl->board_ctrl;
2528         ch_ctrl = zfw_ctrl->ch_ctrl;
2529 
2530         while (1) {
2531             if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
2532                 (tty->termios->c_cflag & CBAUD)){
2533                 cy_writel(&ch_ctrl[channel].rs_control,
2534                         cy_readl(&ch_ctrl[channel].rs_control) |
2535                         (C_RS_RTS | C_RS_DTR));
2536                 retval = cyz_issue_cmd(&cy_card[info->card],
2537                                        channel, C_CM_IOCTLM, 0L);
2538                 if (retval != 0){
2539                     printk("cyc:block_til_ready retval on ttyC%d was %x\n",
2540                            info->line, retval);
2541                 }
2542 #ifdef CY_DEBUG_DTR
2543                 printk("cyc:block_til_ready raising Z DTR\n");
2544 #endif
2545             }
2546 
2547             set_current_state(TASK_INTERRUPTIBLE);
2548             if (tty_hung_up_p(filp)
2549             || !(info->flags & ASYNC_INITIALIZED) ){
2550                 retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
2551                     -EAGAIN : -ERESTARTSYS);
2552                 break;
2553             }
2554             if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2555             && !(info->flags & ASYNC_CLOSING)
2556             && (C_CLOCAL(tty)
2557               || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) {
2558                 break;
2559             }
2560             if (signal_pending(current)) {
2561                 retval = -ERESTARTSYS;
2562                 break;
2563             }
2564 #ifdef CY_DEBUG_OPEN
2565             printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
2566                    info->line, info->count);/**/
2567 #endif
2568             schedule();
2569         }
2570     }
2571     current->state = TASK_RUNNING;
2572     remove_wait_queue(&info->open_wait, &wait);
2573     if (!tty_hung_up_p(filp)){
2574         info->count++;
2575 #ifdef CY_DEBUG_COUNT
2576         printk("cyc:block_til_ready (%d): incrementing count to %d\n",
2577             current->pid, info->count);
2578 #endif
2579     }
2580     info->blocked_open--;
2581 #ifdef CY_DEBUG_OPEN
2582     printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
2583            info->line, info->count);/**/
2584 #endif
2585     if (retval)
2586         return retval;
2587     info->flags |= ASYNC_NORMAL_ACTIVE;
2588     return 0;
2589 } /* block_til_ready */
2590 
2591 
2592 /*
2593  * This routine is called whenever a serial port is opened.  It
2594  * performs the serial-specific initialization for the tty structure.
2595  */
2596 static int
2597 cy_open(struct tty_struct *tty, struct file * filp)
2598 {
2599   struct cyclades_port  *info;
2600   int retval, line;
2601   unsigned long page;
2602 
2603     MOD_INC_USE_COUNT;
2604     line = MINOR(tty->device) - tty->driver.minor_start;
2605     if ((line < 0) || (NR_PORTS <= line)){
2606         MOD_DEC_USE_COUNT;
2607         return -ENODEV;
2608     }
2609     info = &cy_port[line];
2610     if (info->line < 0){
2611         MOD_DEC_USE_COUNT;
2612         return -ENODEV;
2613     }
2614     
2615     /* If the card's firmware hasn't been loaded,
2616        treat it as absent from the system.  This
2617        will make the user pay attention.
2618     */
2619     if (IS_CYC_Z(cy_card[info->card])) {
2620         if (!ISZLOADED(cy_card[info->card])) {
2621             if (((ZE_V1 ==cy_readl(&((struct RUNTIME_9060 *)
2622                 ((cy_card[info->card]).ctl_addr))->mail_box_0)) &&
2623                 Z_FPGA_CHECK(cy_card[info->card])) &&
2624                 (ZFIRM_HLT==cy_readl(&((struct FIRM_ID *)
2625                 ((cy_card[info->card]).base_addr+ID_ADDRESS))->signature)))
2626             {
2627                 printk ("cyc:Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
2628             } else {
2629                 printk("cyc:Cyclades-Z firmware not yet loaded\n");
2630             }
2631             MOD_DEC_USE_COUNT;
2632             return -ENODEV;
2633         }
2634 #ifdef CONFIG_CYZ_INTR
2635         else {
2636             /* In case this Z board is operating in interrupt mode, its 
2637                interrupts should be enabled as soon as the first open happens 
2638                to one of its ports. */
2639             if (!cy_card[info->card].intr_enabled) {
2640                 /* Enable interrupts on the PLX chip */
2641                 cy_writew(cy_card[info->card].ctl_addr+0x68,
2642                         cy_readw(cy_card[info->card].ctl_addr+0x68)|0x0900);
2643                 /* Enable interrupts on the FW */
2644                 retval = cyz_issue_cmd(&cy_card[info->card], 
2645                                         0, C_CM_IRQ_ENBL, 0L);
2646                 if (retval != 0){
2647                     printk("cyc:IRQ enable retval was %x\n", retval);
2648                 }
2649                 cy_card[info->card].intr_enabled = 1;
2650             }
2651         }
2652 #endif /* CONFIG_CYZ_INTR */
2653     }
2654 #ifdef CY_DEBUG_OTHER
2655     printk("cyc:cy_open ttyC%d\n", info->line); /* */
2656 #endif
2657     tty->driver_data = info;
2658     info->tty = tty;
2659     if (serial_paranoia_check(info, tty->device, "cy_open")){
2660         return -ENODEV;
2661     }
2662 #ifdef CY_DEBUG_OPEN
2663     printk("cyc:cy_open ttyC%d, count = %d\n",
2664         info->line, info->count);/**/
2665 #endif
2666     info->count++;
2667 #ifdef CY_DEBUG_COUNT
2668     printk("cyc:cy_open (%d): incrementing count to %d\n",
2669         current->pid, info->count);
2670 #endif
2671     if (!tmp_buf) {
2672         page = get_free_page(GFP_KERNEL);
2673         if (!page)
2674             return -ENOMEM;
2675         if (tmp_buf)
2676             free_page(page);
2677         else
2678             tmp_buf = (unsigned char *) page;
2679     }
2680 
2681     /*
2682      * If the port is the middle of closing, bail out now
2683      */
2684     if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2685         if (info->flags & ASYNC_CLOSING)
2686             interruptible_sleep_on(&info->close_wait);
2687         return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
2688     }
2689 
2690     /*
2691      * Start up serial port
2692      */
2693     retval = startup(info);
2694     if (retval){
2695         return retval;
2696     }
2697 
2698     retval = block_til_ready(tty, filp, info);
2699     if (retval) {
2700 #ifdef CY_DEBUG_OPEN
2701         printk("cyc:cy_open returning after block_til_ready with %d\n",
2702                retval);
2703 #endif
2704         return retval;
2705     }
2706 
2707     if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
2708         if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
2709             *tty->termios = info->normal_termios;
2710         else 
2711             *tty->termios = info->callout_termios;
2712     }
2713 
2714     info->session = current->session;
2715     info->pgrp = current->pgrp;
2716 
2717 #ifdef CY_DEBUG_OPEN
2718     printk(" cyc:cy_open done\n");/**/
2719 #endif
2720 
2721     return 0;
2722 } /* cy_open */
2723 
2724 
2725 /*
2726  * cy_wait_until_sent() --- wait until the transmitter is empty
2727  */
2728 static void 
2729 cy_wait_until_sent(struct tty_struct *tty, int timeout)
2730 {
2731   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2732   unsigned char *base_addr;
2733   int card,chip,channel,index;
2734   unsigned long orig_jiffies, char_time;
2735         
2736     if (serial_paranoia_check(info, tty->device, "cy_wait_until_sent"))
2737         return;
2738 
2739     if (info->xmit_fifo_size == 0)
2740         return; /* Just in case.... */
2741 
2742 
2743     orig_jiffies = jiffies;
2744     /*
2745      * Set the check interval to be 1/5 of the estimated time to
2746      * send a single character, and make it at least 1.  The check
2747      * interval should also be less than the timeout.
2748      * 
2749      * Note: we have to use pretty tight timings here to satisfy
2750      * the NIST-PCTS.
2751      */
2752     char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
2753     char_time = char_time / 5;
2754     if (char_time == 0)
2755         char_time = 1;
2756     if (timeout < 0)
2757         timeout = 0;
2758     if (timeout)
2759         char_time = MIN(char_time, timeout);
2760     /*
2761      * If the transmitter hasn't cleared in twice the approximate
2762      * amount of time to send the entire FIFO, it probably won't
2763      * ever clear.  This assumes the UART isn't doing flow
2764      * control, which is currently the case.  Hence, if it ever
2765      * takes longer than info->timeout, this is probably due to a
2766      * UART bug of some kind.  So, we clamp the timeout parameter at
2767      * 2*info->timeout.
2768      */
2769     if (!timeout || timeout > 2*info->timeout)
2770         timeout = 2*info->timeout;
2771 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2772     printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
2773     printk("jiff=%lu...", jiffies);
2774 #endif
2775     card = info->card;
2776     channel = (info->line) - (cy_card[card].first_line);
2777     if (!IS_CYC_Z(cy_card[card])) {
2778         chip = channel>>2;
2779         channel &= 0x03;
2780         index = cy_card[card].bus_index;
2781         base_addr = (unsigned char *)
2782                 (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
2783         while (cy_readb(base_addr+(CySRER<<index)) & CyTxRdy) {
2784 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2785             printk("Not clean (jiff=%lu)...", jiffies);
2786 #endif
2787             current->state = TASK_INTERRUPTIBLE;
2788             schedule_timeout(char_time);
2789             if (signal_pending(current))
2790                 break;
2791             if (timeout && time_after(jiffies, orig_jiffies + timeout))
2792                 break;
2793         }
2794         current->state = TASK_RUNNING;
2795     } else {
2796         // Nothing to do!
2797     }
2798     /* Run one more char cycle */
2799     current->state = TASK_INTERRUPTIBLE;
2800     schedule_timeout(char_time * 5);
2801     current->state = TASK_RUNNING;
2802 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
2803     printk("Clean (jiff=%lu)...done\n", jiffies);
2804 #endif
2805 }
2806 
2807 /*
2808  * This routine is called when a particular tty device is closed.
2809  */
2810 static void
2811 cy_close(struct tty_struct *tty, struct file *filp)
2812 {
2813   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
2814   unsigned long flags;
2815 
2816 #ifdef CY_DEBUG_OTHER
2817     printk("cyc:cy_close ttyC%d\n", info->line);
2818 #endif
2819 
2820     if (!info || serial_paranoia_check(info, tty->device, "cy_close")){
2821         return;
2822     }
2823 
2824     CY_LOCK(info, flags);
2825     /* If the TTY is being hung up, nothing to do */
2826     if (tty_hung_up_p(filp)) {
2827         MOD_DEC_USE_COUNT;
2828         CY_UNLOCK(info, flags);
2829         return;
2830     }
2831         
2832 #ifdef CY_DEBUG_OPEN
2833     printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
2834 #endif
2835     if ((tty->count == 1) && (info->count != 1)) {
2836         /*
2837          * Uh, oh.  tty->count is 1, which means that the tty
2838          * structure will be freed.  Info->count should always
2839          * be one in these conditions.  If it's greater than
2840          * one, we've got real problems, since it means the
2841          * serial port won't be shutdown.
2842          */
2843         printk("cyc:cy_close: bad serial port count; tty->count is 1, "
2844            "info->count is %d\n", info->count);
2845         info->count = 1;
2846     }
2847 #ifdef CY_DEBUG_COUNT
2848     printk("cyc:cy_close at (%d): decrementing count to %d\n",
2849         current->pid, info->count - 1);
2850 #endif
2851     if (--info->count < 0) {
2852 #ifdef CY_DEBUG_COUNT
2853     printk("cyc:cyc_close setting count to 0\n");
2854 #endif
2855         info->count = 0;
2856     }
2857     if (info->count) {
2858         MOD_DEC_USE_COUNT;
2859         CY_UNLOCK(info, flags);
2860         return;
2861     }
2862     info->flags |= ASYNC_CLOSING;
2863     /*
2864      * Save the termios structure, since this port may have
2865      * separate termios for callout and dialin.
2866      */
2867     if (info->flags & ASYNC_NORMAL_ACTIVE)
2868         info->normal_termios = *tty->termios;
2869     if (info->flags & ASYNC_CALLOUT_ACTIVE)
2870         info->callout_termios = *tty->termios;
2871 
2872     /*
2873     * Now we wait for the transmit buffer to clear; and we notify
2874     * the line discipline to only process XON/XOFF characters.
2875     */
2876     tty->closing = 1;
2877     CY_UNLOCK(info, flags);
2878     if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
2879         tty_wait_until_sent(tty, info->closing_wait);
2880     }
2881     CY_LOCK(info, flags);
2882 
2883     if (!IS_CYC_Z(cy_card[info->card])) {
2884         int channel = info->line - cy_card[info->card].first_line;
2885         int index = cy_card[info->card].bus_index;
2886         unsigned char *base_addr = (unsigned char *)
2887                         (cy_card[info->card].base_addr +
2888                          (cy_chip_offset[channel>>2] <<index));
2889         /* Stop accepting input */
2890         channel &= 0x03;
2891         cy_writeb((ulong)base_addr+(CyCAR<<index), (u_char)channel);
2892         cy_writeb((u_long)base_addr+(CySRER<<index),
2893                         cy_readb(base_addr+(CySRER<<index)) & ~CyRxData);
2894         if (info->flags & ASYNC_INITIALIZED) {
2895             /* Waiting for on-board buffers to be empty before closing 
2896                the port */
2897             CY_UNLOCK(info, flags);
2898             cy_wait_until_sent(tty, info->timeout);
2899             CY_LOCK(info, flags);
2900         }
2901     } else {
2902 #ifdef Z_WAKE
2903         /* Waiting for on-board buffers to be empty before closing the port */
2904         unsigned char *base_addr = (unsigned char *) 
2905                                         cy_card[info->card].base_addr;
2906         struct FIRM_ID *firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
2907         struct ZFW_CTRL *zfw_ctrl = (struct ZFW_CTRL *)
2908                 (base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
2909         struct CH_CTRL *ch_ctrl = zfw_ctrl->ch_ctrl;
2910         int channel = info->line - cy_card[info->card].first_line;
2911         int retval;
2912 
2913         if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
2914             retval = cyz_issue_cmd(&cy_card[info->card], channel, 
2915                                    C_CM_IOCTLW, 0L);
2916             if (retval != 0){
2917                 printk("cyc:cy_close retval on ttyC%d was %x\n",
2918                        info->line, retval);
2919             }
2920             CY_UNLOCK(info, flags);
2921             interruptible_sleep_on(&info->shutdown_wait);
2922             CY_LOCK(info, flags);
2923         }
2924 #endif
2925     }
2926 
2927     CY_UNLOCK(info, flags);
2928     shutdown(info);
2929     if (tty->driver.flush_buffer)
2930         tty->driver.flush_buffer(tty);
2931     if (tty->ldisc.flush_buffer)
2932         tty->ldisc.flush_buffer(tty);
2933     CY_LOCK(info, flags);
2934 
2935     tty->closing = 0;
2936     info->event = 0;
2937     info->tty = 0;
2938     if (info->blocked_open) {
2939         CY_UNLOCK(info, flags);
2940         if (info->close_delay) {
2941             current->state = TASK_INTERRUPTIBLE;
2942             schedule_timeout(info->close_delay);
2943         }
2944         wake_up_interruptible(&info->open_wait);
2945         CY_LOCK(info, flags);
2946     }
2947     info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
2948                      ASYNC_CLOSING);
2949     wake_up_interruptible(&info->close_wait);
2950 
2951 #ifdef CY_DEBUG_OTHER
2952     printk(" cyc:cy_close done\n");
2953 #endif
2954 
2955     MOD_DEC_USE_COUNT;
2956     CY_UNLOCK(info, flags);
2957     return;
2958 } /* cy_close */
2959 
2960 
2961 /* This routine gets called when tty_write has put something into
2962  * the write_queue.  The characters may come from user space or
2963  * kernel space.
2964  *
2965  * This routine will return the number of characters actually
2966  * accepted for writing.
2967  *
2968  * If the port is not already transmitting stuff, start it off by
2969  * enabling interrupts.  The interrupt service routine will then
2970  * ensure that the characters are sent.
2971  * If the port is already active, there is no need to kick it.
2972  *
2973  */
2974 static int
2975 cy_write(struct tty_struct * tty, int from_user,
2976            const unsigned char *buf, int count)
2977 {
2978   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
2979   unsigned long flags;
2980   int c, ret = 0;
2981 
2982 #ifdef CY_DEBUG_IO
2983     printk("cyc:cy_write ttyC%d\n", info->line); /* */
2984 #endif
2985 
2986     if (serial_paranoia_check(info, tty->device, "cy_write")){
2987         return 0;
2988     }
2989         
2990     if (!tty || !info->xmit_buf || !tmp_buf){
2991         return 0;
2992     }
2993 
2994     CY_LOCK(info, flags);
2995     if (from_user) {
2996         down(&tmp_buf_sem);
2997         while (1) {
2998             c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
2999                                 SERIAL_XMIT_SIZE - info->xmit_head));
3000             if (c <= 0)
3001                 break;
3002 
3003             c -= copy_from_user(tmp_buf, buf, c);
3004             if (!c) {
3005                 if (!ret) {
3006                     ret = -EFAULT;
3007                 }
3008                 break;
3009             }
3010             c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
3011                         SERIAL_XMIT_SIZE - info->xmit_head));
3012             memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
3013             info->xmit_head = ((info->xmit_head + c) & (SERIAL_XMIT_SIZE-1));
3014             info->xmit_cnt += c;
3015             buf += c;
3016             count -= c;
3017             ret += c;
3018         }
3019         up(&tmp_buf_sem);
3020     } else {
3021         while (1) {
3022             c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, 
3023                         SERIAL_XMIT_SIZE - info->xmit_head));
3024             if (c <= 0) {
3025                 break;
3026             }
3027             memcpy(info->xmit_buf + info->xmit_head, buf, c);
3028             info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
3029             info->xmit_cnt += c;
3030             buf += c;
3031             count -= c;
3032             ret += c;
3033         }
3034     }
3035     CY_UNLOCK(info, flags);
3036 
3037     info->idle_stats.xmit_bytes += ret;
3038     info->idle_stats.xmit_idle   = jiffies;
3039 
3040     if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
3041         start_xmit(info);
3042     }
3043     return ret;
3044 } /* cy_write */
3045 
3046 
3047 /*
3048  * This routine is called by the kernel to write a single
3049  * character to the tty device.  If the kernel uses this routine,
3050  * it must call the flush_chars() routine (if defined) when it is
3051  * done stuffing characters into the driver.  If there is no room
3052  * in the queue, the character is ignored.
3053  */
3054 static void
3055 cy_put_char(struct tty_struct *tty, unsigned char ch)
3056 {
3057   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3058   unsigned long flags;
3059 
3060 #ifdef CY_DEBUG_IO
3061     printk("cyc:cy_put_char ttyC%d\n", info->line);
3062 #endif
3063 
3064     if (serial_paranoia_check(info, tty->device, "cy_put_char"))
3065         return;
3066 
3067     if (!tty || !info->xmit_buf)
3068         return;
3069 
3070     CY_LOCK(info, flags);
3071         if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
3072             CY_UNLOCK(info, flags);
3073             return;
3074         }
3075 
3076         info->xmit_buf[info->xmit_head++] = ch;
3077         info->xmit_head &= SERIAL_XMIT_SIZE - 1;
3078         info->xmit_cnt++;
3079         info->idle_stats.xmit_bytes++;
3080         info->idle_stats.xmit_idle = jiffies;
3081     CY_UNLOCK(info, flags);
3082 } /* cy_put_char */
3083 
3084 
3085 /*
3086  * This routine is called by the kernel after it has written a
3087  * series of characters to the tty device using put_char().  
3088  */
3089 static void
3090 cy_flush_chars(struct tty_struct *tty)
3091 {
3092   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3093                                 
3094 #ifdef CY_DEBUG_IO
3095     printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */
3096 #endif
3097 
3098     if (serial_paranoia_check(info, tty->device, "cy_flush_chars"))
3099         return;
3100 
3101     if (info->xmit_cnt <= 0 || tty->stopped
3102     || tty->hw_stopped || !info->xmit_buf)
3103         return;
3104 
3105     start_xmit(info);
3106 } /* cy_flush_chars */
3107 
3108 
3109 /*
3110  * This routine returns the numbers of characters the tty driver
3111  * will accept for queuing to be written.  This number is subject
3112  * to change as output buffers get emptied, or if the output flow
3113  * control is activated.
3114  */
3115 static int
3116 cy_write_room(struct tty_struct *tty)
3117 {
3118   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3119   int   ret;
3120                                 
3121 #ifdef CY_DEBUG_IO
3122     printk("cyc:cy_write_room ttyC%d\n", info->line); /* */
3123 #endif
3124 
3125     if (serial_paranoia_check(info, tty->device, "cy_write_room"))
3126         return 0;
3127     ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
3128     if (ret < 0)
3129         ret = 0;
3130     return ret;
3131 } /* cy_write_room */
3132 
3133 
3134 static int
3135 cy_chars_in_buffer(struct tty_struct *tty)
3136 {
3137   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
3138   int card, channel;
3139                                 
3140     if (serial_paranoia_check(info, tty->device, "cy_chars_in_buffer"))
3141         return 0;
3142 
3143     card = info->card;
3144     channel = (info->line) - (cy_card[card].first_line);
3145 
3146 #ifdef Z_EXT_CHARS_IN_BUFFER
3147     if (!IS_CYC_Z(cy_card[card])) {
3148 #endif /* Z_EXT_CHARS_IN_BUFFER */
3149 #ifdef CY_DEBUG_IO
3150         printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
3151                 info->line, info->xmit_cnt); /* */
3152 #endif
3153         return info->xmit_cnt;
3154 #ifdef Z_EXT_CHARS_IN_BUFFER
3155     } else {
3156         static volatile struct FIRM_ID *firm_id;
3157         static volatile struct ZFW_CTRL *zfw_ctrl;
3158         static volatile struct CH_CTRL *ch_ctrl;
3159         static volatile struct BUF_CTRL *buf_ctrl;
3160         int char_count;
3161         volatile uclong tx_put, tx_get, tx_bufsize;
3162 
3163         firm_id = (struct FIRM_ID *)(cy_card[card].base_addr + ID_ADDRESS);
3164         zfw_ctrl = (struct ZFW_CTRL *)
3165                     (cy_card[card].base_addr + 
3166                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
3167         ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3168         buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
3169 
3170         tx_get = cy_readl(&buf_ctrl->tx_get);
3171         tx_put = cy_readl(&buf_ctrl->tx_put);
3172         tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
3173         if (tx_put >= tx_get)
3174             char_count = tx_put - tx_get;
3175         else
3176             char_count = tx_put - tx_get + tx_bufsize;
3177 #ifdef CY_DEBUG_IO
3178         printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
3179                 info->line, info->xmit_cnt + char_count); /* */
3180 #endif
3181         return (info->xmit_cnt + char_count);
3182     }
3183 #endif /* Z_EXT_CHARS_IN_BUFFER */
3184 } /* cy_chars_in_buffer */
3185 
3186 
3187 /*
3188  * ------------------------------------------------------------
3189  * cy_ioctl() and friends
3190  * ------------------------------------------------------------
3191  */
3192 
3193 static void
3194 cyy_baud_calc(struct cyclades_port *info, uclong baud)
3195 {
3196     int co, co_val, bpr;
3197     uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000);
3198 
3199     if (baud == 0) {
3200         info->tbpr = info->tco = info->rbpr = info->rco = 0;
3201         return;
3202     }
3203 
3204     /* determine which prescaler to use */
3205     for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
3206         if (cy_clock / co_val / baud > 63)
3207             break;
3208     }
3209 
3210     bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
3211     if (bpr > 255)
3212         bpr = 255;
3213 
3214     info->tbpr = info->rbpr = bpr;
3215     info->tco = info->rco = co;
3216 }
3217 
3218 /*
3219  * This routine finds or computes the various line characteristics.
3220  * It used to be called config_setup
3221  */
3222 static void
3223 set_line_char(struct cyclades_port * info)
3224 {
3225   unsigned long flags;
3226   unsigned char *base_addr;
3227   int card,chip,channel,index;
3228   unsigned cflag, iflag;
3229   unsigned short chip_number;
3230   int baud, baud_rate = 0;
3231   int   i;
3232 
3233 
3234     if (!info->tty || !info->tty->termios){
3235         return;
3236     }
3237     if (info->line == -1){
3238         return;
3239     }
3240     cflag = info->tty->termios->c_cflag;
3241     iflag = info->tty->termios->c_iflag;
3242 
3243     /*
3244      * Set up the tty->alt_speed kludge
3245      */
3246     if (info->tty) {
3247         if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
3248             info->tty->alt_speed = 57600;
3249         if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
3250             info->tty->alt_speed = 115200;
3251         if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
3252             info->tty->alt_speed = 230400;
3253         if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
3254             info->tty->alt_speed = 460800;
3255     }
3256 
3257     card = info->card;
3258     channel = (info->line) - (cy_card[card].first_line);
3259     chip_number = channel / 4;
3260 
3261     if (!IS_CYC_Z(cy_card[card])) {
3262 
3263         index = cy_card[card].bus_index;
3264 
3265         /* baud rate */
3266         baud = tty_get_baud_rate(info->tty);
3267         if ((baud == 38400) &&
3268             ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
3269             if (info->custom_divisor)
3270                 baud_rate = info->baud / info->custom_divisor;
3271             else
3272                 baud_rate = info->baud;
3273         } else if (baud > CD1400_MAX_SPEED) {
3274             baud = CD1400_MAX_SPEED;
3275         }
3276         /* find the baud index */
3277         for (i = 0; i < 20; i++) {
3278             if (baud == baud_table[i]) {
3279                 break;
3280             }
3281         }
3282         if (i == 20) {
3283             i = 19; /* CD1400_MAX_SPEED */
3284         } 
3285 
3286         if ((baud == 38400) &&
3287             ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
3288             cyy_baud_calc(info, baud_rate);
3289         } else {
3290             if(info->chip_rev >= CD1400_REV_J) {
3291                 /* It is a CD1400 rev. J or later */
3292                 info->tbpr = baud_bpr_60[i]; /* Tx BPR */
3293                 info->tco = baud_co_60[i]; /* Tx CO */
3294                 info->rbpr = baud_bpr_60[i]; /* Rx BPR */
3295                 info->rco = baud_co_60[i]; /* Rx CO */
3296             } else {
3297                 info->tbpr = baud_bpr_25[i]; /* Tx BPR */
3298                 info->tco = baud_co_25[i]; /* Tx CO */
3299                 info->rbpr = baud_bpr_25[i]; /* Rx BPR */
3300                 info->rco = baud_co_25[i]; /* Rx CO */
3301             }
3302         }
3303         if (baud_table[i] == 134) {
3304             /* get it right for 134.5 baud */
3305             info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
3306         } else if ((baud == 38400) &&
3307                    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
3308             info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
3309         } else if (baud_table[i]) {
3310             info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
3311             /* this needs to be propagated into the card info */
3312         } else {
3313             info->timeout = 0;
3314         }
3315         /* By tradition (is it a standard?) a baud rate of zero
3316            implies the line should be/has been closed.  A bit
3317            later in this routine such a test is performed. */
3318 
3319         /* byte size and parity */
3320         info->cor5 = 0;
3321         info->cor4 = 0;
3322         info->cor3 = (info->default_threshold
3323                       ? info->default_threshold
3324                       : baud_cor3[i]); /* receive threshold */
3325         info->cor2 = CyETC;
3326         switch(cflag & CSIZE){
3327         case CS5:
3328             info->cor1 = Cy_5_BITS;
3329             break;
3330         case CS6:
3331             info->cor1 = Cy_6_BITS;
3332             break;
3333         case CS7:
3334             info->cor1 = Cy_7_BITS;
3335             break;
3336         case CS8:
3337             info->cor1 = Cy_8_BITS;
3338             break;
3339         }
3340         if(cflag & CSTOPB){
3341             info->cor1 |= Cy_2_STOP;
3342         }
3343         if (cflag & PARENB){
3344             if (cflag & PARODD){
3345                 info->cor1 |= CyPARITY_O;
3346             }else{
3347                 info->cor1 |= CyPARITY_E;
3348             }
3349         }else{
3350             info->cor1 |= CyPARITY_NONE;
3351         }
3352             
3353         /* CTS flow control flag */
3354         if (cflag & CRTSCTS){
3355             info->flags |= ASYNC_CTS_FLOW;
3356             info->cor2 |= CyCtsAE;
3357         }else{
3358             info->flags &= ~ASYNC_CTS_FLOW;
3359             info->cor2 &= ~CyCtsAE;
3360         }
3361         if (cflag & CLOCAL)
3362             info->flags &= ~ASYNC_CHECK_CD;
3363         else
3364             info->flags |= ASYNC_CHECK_CD;
3365 
3366          /***********************************************
3367             The hardware option, CyRtsAO, presents RTS when
3368             the chip has characters to send.  Since most modems
3369             use RTS as reverse (inbound) flow control, this
3370             option is not used.  If inbound flow control is
3371             necessary, DTR can be programmed to provide the
3372             appropriate signals for use with a non-standard
3373             cable.  Contact Marcio Saito for details.
3374          ***********************************************/
3375 
3376         chip = channel>>2;
3377         channel &= 0x03;
3378         base_addr = (unsigned char*)
3379                        (cy_card[card].base_addr
3380                        + (cy_chip_offset[chip]<<index));
3381 
3382         CY_LOCK(info, flags);
3383             cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3384 
3385            /* tx and rx baud rate */
3386 
3387             cy_writeb((u_long)base_addr+(CyTCOR<<index), info->tco);
3388             cy_writeb((u_long)base_addr+(CyTBPR<<index), info->tbpr);
3389             cy_writeb((u_long)base_addr+(CyRCOR<<index), info->rco);
3390             cy_writeb((u_long)base_addr+(CyRBPR<<index), info->rbpr);
3391 
3392             /* set line characteristics  according configuration */
3393 
3394             cy_writeb((u_long)base_addr+(CySCHR1<<index), 
3395                       START_CHAR(info->tty));
3396             cy_writeb((u_long)base_addr+(CySCHR2<<index), 
3397                       STOP_CHAR(info->tty));
3398             cy_writeb((u_long)base_addr+(CyCOR1<<index), info->cor1);
3399             cy_writeb((u_long)base_addr+(CyCOR2<<index), info->cor2);
3400             cy_writeb((u_long)base_addr+(CyCOR3<<index), info->cor3);
3401             cy_writeb((u_long)base_addr+(CyCOR4<<index), info->cor4);
3402             cy_writeb((u_long)base_addr+(CyCOR5<<index), info->cor5);
3403 
3404             cyy_issue_cmd(base_addr,
3405                      CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch,index);
3406 
3407             cy_writeb((u_long)base_addr+(CyCAR<<index), 
3408                       (u_char)channel); /* !!! Is this needed? */
3409             cy_writeb((u_long)base_addr+(CyRTPR<<index), (info->default_timeout
3410                                                  ? info->default_timeout
3411                                                  : 0x02)); /* 10ms rx timeout */
3412 
3413             if (C_CLOCAL(info->tty)) {
3414                 /* without modem intr */
3415                 cy_writeb((u_long)base_addr+(CySRER<<index),
3416                    cy_readb(base_addr+(CySRER<<index)) | CyMdmCh); 
3417                                         /* act on 1->0 modem transitions */
3418                 if ((cflag & CRTSCTS) && info->rflow) {
3419                         cy_writeb((u_long)base_addr+(CyMCOR1<<index), 
3420                                   (CyCTS|rflow_thr[i]));
3421                 } else {
3422                         cy_writeb((u_long)base_addr+(CyMCOR1<<index), CyCTS);
3423                 }
3424                                         /* act on 0->1 modem transitions */
3425                 cy_writeb((u_long)base_addr+(CyMCOR2<<index), CyCTS);
3426             } else {
3427                 /* without modem intr */
3428                 cy_writeb((u_long)base_addr+(CySRER<<index),
3429                    cy_readb(base_addr+(CySRER<<index)) | CyMdmCh); 
3430                                         /* act on 1->0 modem transitions */
3431                 if ((cflag & CRTSCTS) && info->rflow) {
3432                         cy_writeb((u_long)base_addr+(CyMCOR1<<index), 
3433                                   (CyDSR|CyCTS|CyRI|CyDCD|rflow_thr[i]));
3434                 } else {
3435                         cy_writeb((u_long)base_addr+(CyMCOR1<<index), 
3436                                   CyDSR|CyCTS|CyRI|CyDCD);
3437                 }
3438                                         /* act on 0->1 modem transitions */
3439                 cy_writeb((u_long)base_addr+(CyMCOR2<<index), 
3440                           CyDSR|CyCTS|CyRI|CyDCD);
3441             }
3442 
3443             if(i == 0){ /* baud rate is zero, turn off line */
3444                 if (info->rtsdtr_inv) {
3445                         cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
3446                 } else {
3447                         cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
3448                 }
3449 #ifdef CY_DEBUG_DTR
3450                 printk("cyc:set_line_char dropping DTR\n");
3451                 printk("     status: 0x%x,
3452                     0x%x\n", cy_readb(base_addr+(CyMSVR1<<index)),
3453                     cy_readb(base_addr+(CyMSVR2<<index)));
3454 #endif
3455             }else{
3456                 if (info->rtsdtr_inv) {
3457                         cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
3458                 } else {
3459                         cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
3460                 }
3461 #ifdef CY_DEBUG_DTR
3462                 printk("cyc:set_line_char raising DTR\n");
3463                 printk("     status: 0x%x, 0x%x\n",
3464                     cy_readb(base_addr+(CyMSVR1<<index)),
3465                     cy_readb(base_addr+(CyMSVR2<<index)));
3466 #endif
3467             }
3468 
3469             if (info->tty){
3470                 clear_bit(TTY_IO_ERROR, &info->tty->flags);
3471             }
3472         CY_UNLOCK(info, flags);
3473 
3474     } else {
3475       struct FIRM_ID *firm_id;
3476       struct ZFW_CTRL *zfw_ctrl;
3477       struct BOARD_CTRL *board_ctrl;
3478       struct CH_CTRL *ch_ctrl;
3479       struct BUF_CTRL *buf_ctrl;
3480       uclong sw_flow;
3481       int retval;
3482 
3483         firm_id = (struct FIRM_ID *)
3484                         (cy_card[card].base_addr + ID_ADDRESS);
3485         if (!ISZLOADED(cy_card[card])) {
3486             return;
3487         }
3488 
3489         zfw_ctrl = (struct ZFW_CTRL *)
3490                     (cy_card[card].base_addr + 
3491                      (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
3492         board_ctrl = &zfw_ctrl->board_ctrl;
3493         ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3494         buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3495 
3496         /* baud rate */
3497         baud = tty_get_baud_rate(info->tty);
3498         if ((baud == 38400) &&
3499             ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
3500             if (info->custom_divisor)
3501                 baud_rate = info->baud / info->custom_divisor;
3502             else
3503                 baud_rate = info->baud;
3504         } else if (baud > CYZ_MAX_SPEED) {
3505             baud = CYZ_MAX_SPEED;
3506         }
3507         cy_writel(&ch_ctrl->comm_baud , baud);
3508 
3509         if (baud == 134) {
3510             /* get it right for 134.5 baud */
3511             info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
3512         } else if ((baud == 38400) &&
3513                    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
3514             info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
3515         } else if (baud) {
3516             info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
3517             /* this needs to be propagated into the card info */
3518         } else {
3519             info->timeout = 0;
3520         }
3521 
3522         /* byte size and parity */
3523         switch(cflag & CSIZE){
3524         case CS5: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS5); break;
3525         case CS6: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS6); break;
3526         case CS7: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS7); break;
3527         case CS8: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS8); break;
3528         }
3529         if(cflag & CSTOPB){
3530             cy_writel(&ch_ctrl->comm_data_l,
3531                cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
3532         }else{
3533             cy_writel(&ch_ctrl->comm_data_l,
3534                cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
3535         }
3536         if (cflag & PARENB){
3537             if (cflag & PARODD){
3538                 cy_writel(&ch_ctrl->comm_parity , C_PR_ODD);
3539             }else{
3540                 cy_writel(&ch_ctrl->comm_parity , C_PR_EVEN);
3541             }
3542         }else{
3543             cy_writel(&ch_ctrl->comm_parity , C_PR_NONE);
3544         }
3545 
3546         /* CTS flow control flag */
3547         if (cflag & CRTSCTS){
3548             cy_writel(&ch_ctrl->hw_flow,
3549                cy_readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
3550         }else{
3551             cy_writel(&ch_ctrl->hw_flow,
3552                cy_readl(&ch_ctrl->hw_flow) & ~(C_RS_CTS | C_RS_RTS));
3553         }
3554         /* As the HW flow control is done in firmware, the driver doesn't
3555            need to care about it */
3556         info->flags &= ~ASYNC_CTS_FLOW;
3557 
3558         /* XON/XOFF/XANY flow control flags */
3559         sw_flow = 0;
3560         if (iflag & IXON){
3561             sw_flow |= C_FL_OXX;
3562             if (iflag & IXANY)
3563                 sw_flow |= C_FL_OIXANY;
3564         }
3565         cy_writel(&ch_ctrl->sw_flow, sw_flow);
3566 
3567         retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
3568         if (retval != 0){
3569             printk("cyc:set_line_char retval on ttyC%d was %x\n",
3570                    info->line, retval);
3571         }
3572 
3573         /* CD sensitivity */
3574         if (cflag & CLOCAL){
3575             info->flags &= ~ASYNC_CHECK_CD;
3576         }else{
3577             info->flags |= ASYNC_CHECK_CD;
3578         }
3579 
3580         if(baud == 0){ /* baud rate is zero, turn off line */
3581             cy_writel(&ch_ctrl->rs_control,
3582                cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
3583 #ifdef CY_DEBUG_DTR
3584             printk("cyc:set_line_char dropping Z DTR\n");
3585 #endif
3586         }else{
3587             cy_writel(&ch_ctrl->rs_control,
3588                cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
3589 #ifdef CY_DEBUG_DTR
3590             printk("cyc:set_line_char raising Z DTR\n");
3591 #endif
3592         }
3593 
3594         retval = cyz_issue_cmd( &cy_card[card], channel, C_CM_IOCTLM, 0L);
3595         if (retval != 0){
3596             printk("cyc:set_line_char(2) retval on ttyC%d was %x\n",
3597                    info->line, retval);
3598         }
3599 
3600         if (info->tty){
3601             clear_bit(TTY_IO_ERROR, &info->tty->flags);
3602         }
3603     }
3604 } /* set_line_char */
3605 
3606 
3607 static int
3608 get_serial_info(struct cyclades_port * info,
3609                            struct serial_struct * retinfo)
3610 {
3611   struct serial_struct tmp;
3612   struct cyclades_card *cinfo = &cy_card[info->card];
3613 
3614     if (!retinfo)
3615             return -EFAULT;
3616     memset(&tmp, 0, sizeof(tmp));
3617     tmp.type = info->type;
3618     tmp.line = info->line;
3619     tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
3620     tmp.irq = cinfo->irq;
3621     tmp.flags = info->flags;
3622     tmp.close_delay = info->close_delay;
3623     tmp.baud_base = info->baud;
3624     tmp.custom_divisor = info->custom_divisor;
3625     tmp.hub6 = 0;               /*!!!*/
3626     return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0;
3627 } /* get_serial_info */
3628 
3629 
3630 static int
3631 set_serial_info(struct cyclades_port * info,
3632                            struct serial_struct * new_info)
3633 {
3634   struct serial_struct new_serial;
3635   struct cyclades_port old_info;
3636 
3637     if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
3638         return -EFAULT;
3639     old_info = *info;
3640 
3641     if (!capable(CAP_SYS_ADMIN)) {
3642             if ((new_serial.close_delay != info->close_delay) ||
3643                 (new_serial.baud_base != info->baud) ||
3644                 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
3645                  (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
3646                     return -EPERM;
3647             info->flags = ((info->flags & ~ASYNC_USR_MASK) |
3648                            (new_serial.flags & ASYNC_USR_MASK));
3649             info->baud = new_serial.baud_base;
3650             info->custom_divisor = new_serial.custom_divisor;
3651             goto check_and_exit;
3652     }
3653 
3654 
3655     /*
3656      * OK, past this point, all the error checking has been done.
3657      * At this point, we start making changes.....
3658      */
3659 
3660     info->baud = new_serial.baud_base;
3661     info->custom_divisor = new_serial.custom_divisor;
3662     info->flags = ((info->flags & ~ASYNC_FLAGS) |
3663                     (new_serial.flags & ASYNC_FLAGS));
3664     info->close_delay = new_serial.close_delay * HZ/100;
3665     info->closing_wait = new_serial.closing_wait * HZ/100;
3666 
3667 check_and_exit:
3668     if (info->flags & ASYNC_INITIALIZED){
3669         set_line_char(info);
3670         return 0;
3671     }else{
3672         return startup(info);
3673     }
3674 } /* set_serial_info */
3675 
3676 /*
3677  * get_lsr_info - get line status register info
3678  *
3679  * Purpose: Let user call ioctl() to get info when the UART physically
3680  *          is emptied.  On bus types like RS485, the transmitter must
3681  *          release the bus after transmitting. This must be done when
3682  *          the transmit shift register is empty, not be done when the
3683  *          transmit holding register is empty.  This functionality
3684  *          allows an RS485 driver to be written in user space.
3685  */
3686 static int get_lsr_info(struct cyclades_port *info, unsigned int *value)
3687 {
3688     int card, chip, channel, index;
3689     unsigned char status;
3690     unsigned int result;
3691     unsigned long flags;
3692     unsigned char *base_addr;
3693 
3694     card = info->card;
3695     channel = (info->line) - (cy_card[card].first_line);
3696     if (!IS_CYC_Z(cy_card[card])) {
3697         chip = channel>>2;
3698         channel &= 0x03;
3699         index = cy_card[card].bus_index;
3700         base_addr = (unsigned char *)
3701                      (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
3702 
3703         CY_LOCK(info, flags);
3704         status = cy_readb(base_addr+(CySRER<<index)) & (CyTxRdy|CyTxMpty);
3705         CY_UNLOCK(info, flags);
3706         result = (status ? 0 : TIOCSER_TEMT);
3707     } else {
3708         /* Not supported yet */
3709         return -EINVAL;
3710     }
3711     return cy_put_user(result, (unsigned long *) value);
3712 }
3713 
3714 static int
3715 get_modem_info(struct cyclades_port * info, unsigned int *value)
3716 {
3717   int card,chip,channel,index;
3718   unsigned char *base_addr;
3719   unsigned long flags;
3720   unsigned char status;
3721   unsigned long lstatus;
3722   unsigned int result;
3723   struct FIRM_ID *firm_id;
3724   struct ZFW_CTRL *zfw_ctrl;
3725   struct BOARD_CTRL *board_ctrl;
3726   struct CH_CTRL *ch_ctrl;
3727 
3728     card = info->card;
3729     channel = (info->line) - (cy_card[card].first_line);
3730     if (!IS_CYC_Z(cy_card[card])) {
3731         chip = channel>>2;
3732         channel &= 0x03;
3733         index = cy_card[card].bus_index;
3734         base_addr = (unsigned char*)
3735                        (cy_card[card].base_addr
3736                        + (cy_chip_offset[chip]<<index));
3737 
3738         CY_LOCK(info, flags);
3739             cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
3740