OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [char/] [cyclades.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.