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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [cyclades.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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