Merge branch 'bkl/procfs' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic...
[linux-2.6-block.git] / drivers / char / rocket.c
CommitLineData
1da177e4
LT
1/*
2 * RocketPort device driver for Linux
3 *
4 * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000.
5 *
6 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23/*
24 * Kernel Synchronization:
25 *
26 * This driver has 2 kernel control paths - exception handlers (calls into the driver
27 * from user mode) and the timer bottom half (tasklet). This is a polled driver, interrupts
28 * are not used.
29 *
30 * Critical data:
31 * - rp_table[], accessed through passed "info" pointers, is a global (static) array of
32 * serial port state information and the xmit_buf circular buffer. Protected by
33 * a per port spinlock.
34 * - xmit_flags[], an array of ints indexed by line (port) number, indicating that there
35 * is data to be transmitted. Protected by atomic bit operations.
36 * - rp_num_ports, int indicating number of open ports, protected by atomic operations.
37 *
38 * rp_write() and rp_write_char() functions use a per port semaphore to protect against
39 * simultaneous access to the same port by more than one process.
40 */
41
42/****** Defines ******/
1da177e4
LT
43#define ROCKET_PARANOIA_CHECK
44#define ROCKET_DISABLE_SIMUSAGE
45
46#undef ROCKET_SOFT_FLOW
47#undef ROCKET_DEBUG_OPEN
48#undef ROCKET_DEBUG_INTR
49#undef ROCKET_DEBUG_WRITE
50#undef ROCKET_DEBUG_FLOW
51#undef ROCKET_DEBUG_THROTTLE
52#undef ROCKET_DEBUG_WAIT_UNTIL_SENT
53#undef ROCKET_DEBUG_RECEIVE
54#undef ROCKET_DEBUG_HANGUP
55#undef REV_PCI_ORDER
56#undef ROCKET_DEBUG_IO
57
58#define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */
59
60/****** Kernel includes ******/
61
1da177e4
LT
62#include <linux/module.h>
63#include <linux/errno.h>
64#include <linux/major.h>
65#include <linux/kernel.h>
66#include <linux/signal.h>
67#include <linux/slab.h>
68#include <linux/mm.h>
69#include <linux/sched.h>
70#include <linux/timer.h>
71#include <linux/interrupt.h>
72#include <linux/tty.h>
73#include <linux/tty_driver.h>
74#include <linux/tty_flip.h>
44b7d1b3 75#include <linux/serial.h>
405f5571 76#include <linux/smp_lock.h>
1da177e4
LT
77#include <linux/string.h>
78#include <linux/fcntl.h>
79#include <linux/ptrace.h>
69f545ea 80#include <linux/mutex.h>
1da177e4
LT
81#include <linux/ioport.h>
82#include <linux/delay.h>
8cf5a8c5 83#include <linux/completion.h>
1da177e4
LT
84#include <linux/wait.h>
85#include <linux/pci.h>
44b7d1b3 86#include <linux/uaccess.h>
1da177e4 87#include <asm/atomic.h>
457fb605 88#include <asm/unaligned.h>
1da177e4
LT
89#include <linux/bitops.h>
90#include <linux/spinlock.h>
1da177e4
LT
91#include <linux/init.h>
92
93/****** RocketPort includes ******/
94
95#include "rocket_int.h"
96#include "rocket.h"
97
98#define ROCKET_VERSION "2.09"
99#define ROCKET_DATE "12-June-2003"
100
101/****** RocketPort Local Variables ******/
102
40565f19
JS
103static void rp_do_poll(unsigned long dummy);
104
1da177e4
LT
105static struct tty_driver *rocket_driver;
106
107static struct rocket_version driver_version = {
108 ROCKET_VERSION, ROCKET_DATE
109};
110
111static struct r_port *rp_table[MAX_RP_PORTS]; /* The main repository of serial port state information. */
112static unsigned int xmit_flags[NUM_BOARDS]; /* Bit significant, indicates port had data to transmit. */
113 /* eg. Bit 0 indicates port 0 has xmit data, ... */
114static atomic_t rp_num_ports_open; /* Number of serial ports open */
40565f19 115static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0);
1da177e4
LT
116
117static unsigned long board1; /* ISA addresses, retrieved from rocketport.conf */
118static unsigned long board2;
119static unsigned long board3;
120static unsigned long board4;
121static unsigned long controller;
122static int support_low_speed;
123static unsigned long modem1;
124static unsigned long modem2;
125static unsigned long modem3;
126static unsigned long modem4;
127static unsigned long pc104_1[8];
128static unsigned long pc104_2[8];
129static unsigned long pc104_3[8];
130static unsigned long pc104_4[8];
131static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 };
132
133static int rp_baud_base[NUM_BOARDS]; /* Board config info (Someday make a per-board structure) */
134static unsigned long rcktpt_io_addr[NUM_BOARDS];
135static int rcktpt_type[NUM_BOARDS];
136static int is_PCI[NUM_BOARDS];
137static rocketModel_t rocketModel[NUM_BOARDS];
138static int max_board;
31f35939 139static const struct tty_port_operations rocket_port_ops;
1da177e4
LT
140
141/*
142 * The following arrays define the interrupt bits corresponding to each AIOP.
143 * These bits are different between the ISA and regular PCI boards and the
144 * Universal PCI boards.
145 */
146
147static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
148 AIOP_INTR_BIT_0,
149 AIOP_INTR_BIT_1,
150 AIOP_INTR_BIT_2,
151 AIOP_INTR_BIT_3
152};
153
154static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
155 UPCI_AIOP_INTR_BIT_0,
156 UPCI_AIOP_INTR_BIT_1,
157 UPCI_AIOP_INTR_BIT_2,
158 UPCI_AIOP_INTR_BIT_3
159};
160
f15313bf
AB
161static Byte_t RData[RDATASIZE] = {
162 0x00, 0x09, 0xf6, 0x82,
163 0x02, 0x09, 0x86, 0xfb,
164 0x04, 0x09, 0x00, 0x0a,
165 0x06, 0x09, 0x01, 0x0a,
166 0x08, 0x09, 0x8a, 0x13,
167 0x0a, 0x09, 0xc5, 0x11,
168 0x0c, 0x09, 0x86, 0x85,
169 0x0e, 0x09, 0x20, 0x0a,
170 0x10, 0x09, 0x21, 0x0a,
171 0x12, 0x09, 0x41, 0xff,
172 0x14, 0x09, 0x82, 0x00,
173 0x16, 0x09, 0x82, 0x7b,
174 0x18, 0x09, 0x8a, 0x7d,
175 0x1a, 0x09, 0x88, 0x81,
176 0x1c, 0x09, 0x86, 0x7a,
177 0x1e, 0x09, 0x84, 0x81,
178 0x20, 0x09, 0x82, 0x7c,
179 0x22, 0x09, 0x0a, 0x0a
180};
181
182static Byte_t RRegData[RREGDATASIZE] = {
183 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
184 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
185 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
186 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
187 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
188 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
189 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
190 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
191 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
192 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
193 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
194 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
195 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
196};
197
198static CONTROLLER_T sController[CTL_SIZE] = {
199 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
200 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
201 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
202 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
203 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
204 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
205 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
206 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
207};
208
209static Byte_t sBitMapClrTbl[8] = {
210 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
211};
212
213static Byte_t sBitMapSetTbl[8] = {
214 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
215};
216
217static int sClockPrescale = 0x14;
218
1da177e4
LT
219/*
220 * Line number is the ttySIx number (x), the Minor number. We
221 * assign them sequentially, starting at zero. The following
222 * array keeps track of the line number assigned to a given board/aiop/channel.
223 */
224static unsigned char lineNumbers[MAX_RP_PORTS];
225static unsigned long nextLineNumber;
226
227/***** RocketPort Static Prototypes *********/
228static int __init init_ISA(int i);
229static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
230static void rp_flush_buffer(struct tty_struct *tty);
231static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
232static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
233static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
234static void rp_start(struct tty_struct *tty);
f15313bf
AB
235static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
236 int ChanNum);
237static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
238static void sFlushRxFIFO(CHANNEL_T * ChP);
239static void sFlushTxFIFO(CHANNEL_T * ChP);
240static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
241static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
242static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
243static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
244static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
245static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
246 ByteIO_t * AiopIOList, int AiopIOListSize,
247 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
248 int PeriodicOnly, int altChanRingIndicator,
249 int UPCIRingInd);
250static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
251 ByteIO_t * AiopIOList, int AiopIOListSize,
252 int IRQNum, Byte_t Frequency, int PeriodicOnly);
253static int sReadAiopID(ByteIO_t io);
254static int sReadAiopNumChan(WordIO_t io);
1da177e4 255
1da177e4
LT
256MODULE_AUTHOR("Theodore Ts'o");
257MODULE_DESCRIPTION("Comtrol RocketPort driver");
258module_param(board1, ulong, 0);
259MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1");
260module_param(board2, ulong, 0);
261MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2");
262module_param(board3, ulong, 0);
263MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3");
264module_param(board4, ulong, 0);
265MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4");
266module_param(controller, ulong, 0);
267MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller");
268module_param(support_low_speed, bool, 0);
269MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud");
270module_param(modem1, ulong, 0);
271MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem");
272module_param(modem2, ulong, 0);
273MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem");
274module_param(modem3, ulong, 0);
275MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem");
276module_param(modem4, ulong, 0);
277MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem");
278module_param_array(pc104_1, ulong, NULL, 0);
279MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
280module_param_array(pc104_2, ulong, NULL, 0);
281MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
282module_param_array(pc104_3, ulong, NULL, 0);
283MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
284module_param_array(pc104_4, ulong, NULL, 0);
285MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
286
d269cdd0 287static int rp_init(void);
1da177e4
LT
288static void rp_cleanup_module(void);
289
290module_init(rp_init);
291module_exit(rp_cleanup_module);
292
1da177e4 293
1da177e4 294MODULE_LICENSE("Dual BSD/GPL");
1da177e4
LT
295
296/*************************************************************************/
297/* Module code starts here */
298
299static inline int rocket_paranoia_check(struct r_port *info,
300 const char *routine)
301{
302#ifdef ROCKET_PARANOIA_CHECK
303 if (!info)
304 return 1;
305 if (info->magic != RPORT_MAGIC) {
68562b79
JS
306 printk(KERN_WARNING "Warning: bad magic number for rocketport "
307 "struct in %s\n", routine);
1da177e4
LT
308 return 1;
309 }
310#endif
311 return 0;
312}
313
314
315/* Serial port receive data function. Called (from timer poll) when an AIOPIC signals
316 * that receive data is present on a serial port. Pulls data from FIFO, moves it into the
317 * tty layer.
318 */
319static void rp_do_receive(struct r_port *info,
320 struct tty_struct *tty,
321 CHANNEL_t * cp, unsigned int ChanStatus)
322{
323 unsigned int CharNStat;
cc44a817
PF
324 int ToRecv, wRecv, space;
325 unsigned char *cbuf;
1da177e4
LT
326
327 ToRecv = sGetRxCnt(cp);
1da177e4 328#ifdef ROCKET_DEBUG_INTR
68562b79 329 printk(KERN_INFO "rp_do_receive(%d)...\n", ToRecv);
1da177e4 330#endif
cc44a817
PF
331 if (ToRecv == 0)
332 return;
33f0f88f 333
1da177e4
LT
334 /*
335 * if status indicates there are errored characters in the
336 * FIFO, then enter status mode (a word in FIFO holds
337 * character and status).
338 */
339 if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
340 if (!(ChanStatus & STATMODE)) {
341#ifdef ROCKET_DEBUG_RECEIVE
68562b79 342 printk(KERN_INFO "Entering STATMODE...\n");
1da177e4
LT
343#endif
344 ChanStatus |= STATMODE;
345 sEnRxStatusMode(cp);
346 }
347 }
348
349 /*
350 * if we previously entered status mode, then read down the
351 * FIFO one word at a time, pulling apart the character and
352 * the status. Update error counters depending on status
353 */
354 if (ChanStatus & STATMODE) {
355#ifdef ROCKET_DEBUG_RECEIVE
68562b79
JS
356 printk(KERN_INFO "Ignore %x, read %x...\n",
357 info->ignore_status_mask, info->read_status_mask);
1da177e4
LT
358#endif
359 while (ToRecv) {
cc44a817
PF
360 char flag;
361
1da177e4
LT
362 CharNStat = sInW(sGetTxRxDataIO(cp));
363#ifdef ROCKET_DEBUG_RECEIVE
68562b79 364 printk(KERN_INFO "%x...\n", CharNStat);
1da177e4
LT
365#endif
366 if (CharNStat & STMBREAKH)
367 CharNStat &= ~(STMFRAMEH | STMPARITYH);
368 if (CharNStat & info->ignore_status_mask) {
369 ToRecv--;
370 continue;
371 }
372 CharNStat &= info->read_status_mask;
373 if (CharNStat & STMBREAKH)
cc44a817 374 flag = TTY_BREAK;
1da177e4 375 else if (CharNStat & STMPARITYH)
cc44a817 376 flag = TTY_PARITY;
1da177e4 377 else if (CharNStat & STMFRAMEH)
cc44a817 378 flag = TTY_FRAME;
1da177e4 379 else if (CharNStat & STMRCVROVRH)
cc44a817 380 flag = TTY_OVERRUN;
1da177e4 381 else
cc44a817
PF
382 flag = TTY_NORMAL;
383 tty_insert_flip_char(tty, CharNStat & 0xff, flag);
1da177e4
LT
384 ToRecv--;
385 }
386
387 /*
388 * after we've emptied the FIFO in status mode, turn
389 * status mode back off
390 */
391 if (sGetRxCnt(cp) == 0) {
392#ifdef ROCKET_DEBUG_RECEIVE
393 printk(KERN_INFO "Status mode off.\n");
394#endif
395 sDisRxStatusMode(cp);
396 }
397 } else {
398 /*
399 * we aren't in status mode, so read down the FIFO two
400 * characters at time by doing repeated word IO
401 * transfer.
402 */
cc44a817
PF
403 space = tty_prepare_flip_string(tty, &cbuf, ToRecv);
404 if (space < ToRecv) {
405#ifdef ROCKET_DEBUG_RECEIVE
406 printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space);
407#endif
408 if (space <= 0)
409 return;
410 ToRecv = space;
411 }
1da177e4
LT
412 wRecv = ToRecv >> 1;
413 if (wRecv)
414 sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
415 if (ToRecv & 1)
416 cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
1da177e4
LT
417 }
418 /* Push the data up to the tty layer */
cc44a817 419 tty_flip_buffer_push(tty);
1da177e4
LT
420}
421
422/*
423 * Serial port transmit data function. Called from the timer polling loop as a
424 * result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready
425 * to be sent out the serial port. Data is buffered in rp_table[line].xmit_buf, it is
426 * moved to the port's xmit FIFO. *info is critical data, protected by spinlocks.
427 */
428static void rp_do_transmit(struct r_port *info)
429{
430 int c;
431 CHANNEL_t *cp = &info->channel;
432 struct tty_struct *tty;
433 unsigned long flags;
434
435#ifdef ROCKET_DEBUG_INTR
68562b79 436 printk(KERN_DEBUG "%s\n", __func__);
1da177e4
LT
437#endif
438 if (!info)
439 return;
47b01b3a
AC
440 tty = tty_port_tty_get(&info->port);
441
442 if (tty == NULL) {
443 printk(KERN_WARNING "rp: WARNING %s called with tty==NULL\n", __func__);
1da177e4
LT
444 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
445 return;
446 }
447
448 spin_lock_irqsave(&info->slock, flags);
1da177e4
LT
449 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
450
451 /* Loop sending data to FIFO until done or FIFO full */
452 while (1) {
453 if (tty->stopped || tty->hw_stopped)
454 break;
709107fc
HH
455 c = min(info->xmit_fifo_room, info->xmit_cnt);
456 c = min(c, XMIT_BUF_SIZE - info->xmit_tail);
1da177e4
LT
457 if (c <= 0 || info->xmit_fifo_room <= 0)
458 break;
459 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
460 if (c & 1)
461 sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]);
462 info->xmit_tail += c;
463 info->xmit_tail &= XMIT_BUF_SIZE - 1;
464 info->xmit_cnt -= c;
465 info->xmit_fifo_room -= c;
466#ifdef ROCKET_DEBUG_INTR
68562b79 467 printk(KERN_INFO "tx %d chars...\n", c);
1da177e4
LT
468#endif
469 }
470
471 if (info->xmit_cnt == 0)
472 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
473
474 if (info->xmit_cnt < WAKEUP_CHARS) {
475 tty_wakeup(tty);
1da177e4
LT
476#ifdef ROCKETPORT_HAVE_POLL_WAIT
477 wake_up_interruptible(&tty->poll_wait);
478#endif
479 }
480
481 spin_unlock_irqrestore(&info->slock, flags);
47b01b3a 482 tty_kref_put(tty);
1da177e4
LT
483
484#ifdef ROCKET_DEBUG_INTR
68562b79 485 printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head,
1da177e4
LT
486 info->xmit_tail, info->xmit_fifo_room);
487#endif
488}
489
490/*
491 * Called when a serial port signals it has read data in it's RX FIFO.
492 * It checks what interrupts are pending and services them, including
493 * receiving serial data.
494 */
495static void rp_handle_port(struct r_port *info)
496{
497 CHANNEL_t *cp;
498 struct tty_struct *tty;
499 unsigned int IntMask, ChanStatus;
500
501 if (!info)
502 return;
503
21bed701 504 if ((info->port.flags & ASYNC_INITIALIZED) == 0) {
68562b79
JS
505 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
506 "info->flags & NOT_INIT\n");
1da177e4
LT
507 return;
508 }
47b01b3a
AC
509 tty = tty_port_tty_get(&info->port);
510 if (!tty) {
68562b79 511 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
47b01b3a 512 "tty==NULL\n");
1da177e4
LT
513 return;
514 }
515 cp = &info->channel;
1da177e4
LT
516
517 IntMask = sGetChanIntID(cp) & info->intmask;
518#ifdef ROCKET_DEBUG_INTR
68562b79 519 printk(KERN_INFO "rp_interrupt %02x...\n", IntMask);
1da177e4
LT
520#endif
521 ChanStatus = sGetChanStatus(cp);
522 if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */
523 rp_do_receive(info, tty, cp, ChanStatus);
524 }
525 if (IntMask & DELTA_CD) { /* CD change */
526#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP))
68562b79 527 printk(KERN_INFO "ttyR%d CD now %s...\n", info->line,
1da177e4
LT
528 (ChanStatus & CD_ACT) ? "on" : "off");
529#endif
530 if (!(ChanStatus & CD_ACT) && info->cd_status) {
531#ifdef ROCKET_DEBUG_HANGUP
532 printk(KERN_INFO "CD drop, calling hangup.\n");
533#endif
534 tty_hangup(tty);
535 }
536 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
e60a1084 537 wake_up_interruptible(&info->port.open_wait);
1da177e4
LT
538 }
539#ifdef ROCKET_DEBUG_INTR
540 if (IntMask & DELTA_CTS) { /* CTS change */
541 printk(KERN_INFO "CTS change...\n");
542 }
543 if (IntMask & DELTA_DSR) { /* DSR change */
544 printk(KERN_INFO "DSR change...\n");
545 }
546#endif
47b01b3a 547 tty_kref_put(tty);
1da177e4
LT
548}
549
550/*
551 * The top level polling routine. Repeats every 1/100 HZ (10ms).
552 */
553static void rp_do_poll(unsigned long dummy)
554{
555 CONTROLLER_t *ctlp;
6c0286b1
JS
556 int ctrl, aiop, ch, line;
557 unsigned int xmitmask, i;
1da177e4
LT
558 unsigned int CtlMask;
559 unsigned char AiopMask;
560 Word_t bit;
561
562 /* Walk through all the boards (ctrl's) */
563 for (ctrl = 0; ctrl < max_board; ctrl++) {
564 if (rcktpt_io_addr[ctrl] <= 0)
565 continue;
566
567 /* Get a ptr to the board's control struct */
568 ctlp = sCtlNumToCtlPtr(ctrl);
569
3a4fa0a2 570 /* Get the interrupt status from the board */
1da177e4
LT
571#ifdef CONFIG_PCI
572 if (ctlp->BusType == isPCI)
573 CtlMask = sPCIGetControllerIntStatus(ctlp);
574 else
575#endif
576 CtlMask = sGetControllerIntStatus(ctlp);
577
578 /* Check if any AIOP read bits are set */
579 for (aiop = 0; CtlMask; aiop++) {
580 bit = ctlp->AiopIntrBits[aiop];
581 if (CtlMask & bit) {
582 CtlMask &= ~bit;
583 AiopMask = sGetAiopIntStatus(ctlp, aiop);
584
585 /* Check if any port read bits are set */
586 for (ch = 0; AiopMask; AiopMask >>= 1, ch++) {
587 if (AiopMask & 1) {
588
589 /* Get the line number (/dev/ttyRx number). */
590 /* Read the data from the port. */
591 line = GetLineNumber(ctrl, aiop, ch);
592 rp_handle_port(rp_table[line]);
593 }
594 }
595 }
596 }
597
598 xmitmask = xmit_flags[ctrl];
599
600 /*
601 * xmit_flags contains bit-significant flags, indicating there is data
602 * to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port
603 * 1, ... (32 total possible). The variable i has the aiop and ch
604 * numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc).
605 */
606 if (xmitmask) {
607 for (i = 0; i < rocketModel[ctrl].numPorts; i++) {
608 if (xmitmask & (1 << i)) {
609 aiop = (i & 0x18) >> 3;
610 ch = i & 0x07;
611 line = GetLineNumber(ctrl, aiop, ch);
612 rp_do_transmit(rp_table[line]);
613 }
614 }
615 }
616 }
617
618 /*
619 * Reset the timer so we get called at the next clock tick (10ms).
620 */
621 if (atomic_read(&rp_num_ports_open))
622 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
623}
624
625/*
626 * Initializes the r_port structure for a port, as well as enabling the port on
627 * the board.
628 * Inputs: board, aiop, chan numbers
629 */
630static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
631{
632 unsigned rocketMode;
633 struct r_port *info;
634 int line;
635 CONTROLLER_T *ctlp;
636
637 /* Get the next available line number */
638 line = SetLineNumber(board, aiop, chan);
639
640 ctlp = sCtlNumToCtlPtr(board);
641
642 /* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
dd00cc48 643 info = kzalloc(sizeof (struct r_port), GFP_KERNEL);
1da177e4 644 if (!info) {
68562b79
JS
645 printk(KERN_ERR "Couldn't allocate info struct for line #%d\n",
646 line);
1da177e4
LT
647 return;
648 }
1da177e4
LT
649
650 info->magic = RPORT_MAGIC;
651 info->line = line;
652 info->ctlp = ctlp;
653 info->board = board;
654 info->aiop = aiop;
655 info->chan = chan;
31f35939
AC
656 tty_port_init(&info->port);
657 info->port.ops = &rocket_port_ops;
8cf5a8c5 658 init_completion(&info->close_wait);
1da177e4
LT
659 info->flags &= ~ROCKET_MODE_MASK;
660 switch (pc104[board][line]) {
661 case 422:
662 info->flags |= ROCKET_MODE_RS422;
663 break;
664 case 485:
665 info->flags |= ROCKET_MODE_RS485;
666 break;
667 case 232:
668 default:
669 info->flags |= ROCKET_MODE_RS232;
670 break;
671 }
672
673 info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR;
674 if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
68562b79
JS
675 printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n",
676 board, aiop, chan);
1da177e4
LT
677 kfree(info);
678 return;
679 }
680
681 rocketMode = info->flags & ROCKET_MODE_MASK;
682
683 if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485))
684 sEnRTSToggle(&info->channel);
685 else
686 sDisRTSToggle(&info->channel);
687
688 if (ctlp->boardType == ROCKET_TYPE_PC104) {
689 switch (rocketMode) {
690 case ROCKET_MODE_RS485:
691 sSetInterfaceMode(&info->channel, InterfaceModeRS485);
692 break;
693 case ROCKET_MODE_RS422:
694 sSetInterfaceMode(&info->channel, InterfaceModeRS422);
695 break;
696 case ROCKET_MODE_RS232:
697 default:
698 if (info->flags & ROCKET_RTS_TOGGLE)
699 sSetInterfaceMode(&info->channel, InterfaceModeRS232T);
700 else
701 sSetInterfaceMode(&info->channel, InterfaceModeRS232);
702 break;
703 }
704 }
705 spin_lock_init(&info->slock);
69f545ea 706 mutex_init(&info->write_mtx);
1da177e4 707 rp_table[line] = info;
ac6aec2f
JS
708 tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev :
709 NULL);
1da177e4
LT
710}
711
712/*
713 * Configures a rocketport port according to its termio settings. Called from
714 * user mode into the driver (exception handler). *info CD manipulation is spinlock protected.
715 */
47b01b3a 716static void configure_r_port(struct tty_struct *tty, struct r_port *info,
606d099c 717 struct ktermios *old_termios)
1da177e4
LT
718{
719 unsigned cflag;
720 unsigned long flags;
721 unsigned rocketMode;
722 int bits, baud, divisor;
723 CHANNEL_t *cp;
47b01b3a 724 struct ktermios *t = tty->termios;
1da177e4 725
1da177e4 726 cp = &info->channel;
6df3526b 727 cflag = t->c_cflag;
1da177e4
LT
728
729 /* Byte size and parity */
730 if ((cflag & CSIZE) == CS8) {
731 sSetData8(cp);
732 bits = 10;
733 } else {
734 sSetData7(cp);
735 bits = 9;
736 }
737 if (cflag & CSTOPB) {
738 sSetStop2(cp);
739 bits++;
740 } else {
741 sSetStop1(cp);
742 }
743
744 if (cflag & PARENB) {
745 sEnParity(cp);
746 bits++;
747 if (cflag & PARODD) {
748 sSetOddParity(cp);
749 } else {
750 sSetEvenParity(cp);
751 }
752 } else {
753 sDisParity(cp);
754 }
755
756 /* baud rate */
47b01b3a 757 baud = tty_get_baud_rate(tty);
1da177e4
LT
758 if (!baud)
759 baud = 9600;
760 divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
761 if ((divisor >= 8192 || divisor < 0) && old_termios) {
6df3526b 762 baud = tty_termios_baud_rate(old_termios);
1da177e4
LT
763 if (!baud)
764 baud = 9600;
765 divisor = (rp_baud_base[info->board] / baud) - 1;
766 }
767 if (divisor >= 8192 || divisor < 0) {
768 baud = 9600;
769 divisor = (rp_baud_base[info->board] / baud) - 1;
770 }
771 info->cps = baud / bits;
772 sSetBaud(cp, divisor);
773
6df3526b 774 /* FIXME: Should really back compute a baud rate from the divisor */
47b01b3a 775 tty_encode_baud_rate(tty, baud, baud);
6df3526b 776
1da177e4
LT
777 if (cflag & CRTSCTS) {
778 info->intmask |= DELTA_CTS;
779 sEnCTSFlowCtl(cp);
780 } else {
781 info->intmask &= ~DELTA_CTS;
782 sDisCTSFlowCtl(cp);
783 }
784 if (cflag & CLOCAL) {
785 info->intmask &= ~DELTA_CD;
786 } else {
787 spin_lock_irqsave(&info->slock, flags);
788 if (sGetChanStatus(cp) & CD_ACT)
789 info->cd_status = 1;
790 else
791 info->cd_status = 0;
792 info->intmask |= DELTA_CD;
793 spin_unlock_irqrestore(&info->slock, flags);
794 }
795
796 /*
797 * Handle software flow control in the board
798 */
799#ifdef ROCKET_SOFT_FLOW
47b01b3a 800 if (I_IXON(tty)) {
1da177e4 801 sEnTxSoftFlowCtl(cp);
47b01b3a 802 if (I_IXANY(tty)) {
1da177e4
LT
803 sEnIXANY(cp);
804 } else {
805 sDisIXANY(cp);
806 }
47b01b3a
AC
807 sSetTxXONChar(cp, START_CHAR(tty));
808 sSetTxXOFFChar(cp, STOP_CHAR(tty));
1da177e4
LT
809 } else {
810 sDisTxSoftFlowCtl(cp);
811 sDisIXANY(cp);
812 sClrTxXOFF(cp);
813 }
814#endif
815
816 /*
817 * Set up ignore/read mask words
818 */
819 info->read_status_mask = STMRCVROVRH | 0xFF;
47b01b3a 820 if (I_INPCK(tty))
1da177e4 821 info->read_status_mask |= STMFRAMEH | STMPARITYH;
47b01b3a 822 if (I_BRKINT(tty) || I_PARMRK(tty))
1da177e4
LT
823 info->read_status_mask |= STMBREAKH;
824
825 /*
826 * Characters to ignore
827 */
828 info->ignore_status_mask = 0;
47b01b3a 829 if (I_IGNPAR(tty))
1da177e4 830 info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
47b01b3a 831 if (I_IGNBRK(tty)) {
1da177e4
LT
832 info->ignore_status_mask |= STMBREAKH;
833 /*
834 * If we're ignoring parity and break indicators,
835 * ignore overruns too. (For real raw support).
836 */
47b01b3a 837 if (I_IGNPAR(tty))
1da177e4
LT
838 info->ignore_status_mask |= STMRCVROVRH;
839 }
840
841 rocketMode = info->flags & ROCKET_MODE_MASK;
842
843 if ((info->flags & ROCKET_RTS_TOGGLE)
844 || (rocketMode == ROCKET_MODE_RS485))
845 sEnRTSToggle(cp);
846 else
847 sDisRTSToggle(cp);
848
849 sSetRTS(&info->channel);
850
851 if (cp->CtlP->boardType == ROCKET_TYPE_PC104) {
852 switch (rocketMode) {
853 case ROCKET_MODE_RS485:
854 sSetInterfaceMode(cp, InterfaceModeRS485);
855 break;
856 case ROCKET_MODE_RS422:
857 sSetInterfaceMode(cp, InterfaceModeRS422);
858 break;
859 case ROCKET_MODE_RS232:
860 default:
861 if (info->flags & ROCKET_RTS_TOGGLE)
862 sSetInterfaceMode(cp, InterfaceModeRS232T);
863 else
864 sSetInterfaceMode(cp, InterfaceModeRS232);
865 break;
866 }
867 }
868}
869
31f35939
AC
870static int carrier_raised(struct tty_port *port)
871{
872 struct r_port *info = container_of(port, struct r_port, port);
873 return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0;
874}
875
fcc8ac18 876static void dtr_rts(struct tty_port *port, int on)
5d951fb4
AC
877{
878 struct r_port *info = container_of(port, struct r_port, port);
fcc8ac18
AC
879 if (on) {
880 sSetDTR(&info->channel);
881 sSetRTS(&info->channel);
882 } else {
883 sClrDTR(&info->channel);
884 sClrRTS(&info->channel);
885 }
5d951fb4
AC
886}
887
1da177e4
LT
888/*
889 * Exception handler that opens a serial port. Creates xmit_buf storage, fills in
890 * port's r_port struct. Initializes the port hardware.
891 */
892static int rp_open(struct tty_struct *tty, struct file *filp)
893{
894 struct r_port *info;
fba85e01 895 struct tty_port *port;
1da177e4
LT
896 int line = 0, retval;
897 CHANNEL_t *cp;
898 unsigned long page;
899
f6de0c98 900 line = tty->index;
fba85e01 901 if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL))
1da177e4 902 return -ENXIO;
fba85e01
AC
903 port = &info->port;
904
1da177e4
LT
905 page = __get_free_page(GFP_KERNEL);
906 if (!page)
907 return -ENOMEM;
908
fba85e01 909 if (port->flags & ASYNC_CLOSING) {
8cf5a8c5 910 retval = wait_for_completion_interruptible(&info->close_wait);
1da177e4 911 free_page(page);
8cf5a8c5
JS
912 if (retval)
913 return retval;
fba85e01 914 return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
1da177e4
LT
915 }
916
917 /*
918 * We must not sleep from here until the port is marked fully in use.
919 */
920 if (info->xmit_buf)
921 free_page(page);
922 else
923 info->xmit_buf = (unsigned char *) page;
924
925 tty->driver_data = info;
fba85e01 926 tty_port_tty_set(port, tty);
1da177e4 927
fba85e01 928 if (port->count++ == 0) {
1da177e4
LT
929 atomic_inc(&rp_num_ports_open);
930
931#ifdef ROCKET_DEBUG_OPEN
68562b79
JS
932 printk(KERN_INFO "rocket mod++ = %d...\n",
933 atomic_read(&rp_num_ports_open));
1da177e4
LT
934#endif
935 }
936#ifdef ROCKET_DEBUG_OPEN
e60a1084 937 printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
1da177e4
LT
938#endif
939
940 /*
941 * Info->count is now 1; so it's safe to sleep now.
942 */
a391ad0f 943 if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
1da177e4
LT
944 cp = &info->channel;
945 sSetRxTrigger(cp, TRIG_1);
946 if (sGetChanStatus(cp) & CD_ACT)
947 info->cd_status = 1;
948 else
949 info->cd_status = 0;
950 sDisRxStatusMode(cp);
951 sFlushRxFIFO(cp);
952 sFlushTxFIFO(cp);
953
954 sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
955 sSetRxTrigger(cp, TRIG_1);
956
957 sGetChanStatus(cp);
958 sDisRxStatusMode(cp);
959 sClrTxXOFF(cp);
960
961 sDisCTSFlowCtl(cp);
962 sDisTxSoftFlowCtl(cp);
963
964 sEnRxFIFO(cp);
965 sEnTransmit(cp);
966
a391ad0f 967 set_bit(ASYNCB_INITIALIZED, &info->port.flags);
1da177e4
LT
968
969 /*
970 * Set up the tty->alt_speed kludge
971 */
972 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
47b01b3a 973 tty->alt_speed = 57600;
1da177e4 974 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
47b01b3a 975 tty->alt_speed = 115200;
1da177e4 976 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
47b01b3a 977 tty->alt_speed = 230400;
1da177e4 978 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
47b01b3a 979 tty->alt_speed = 460800;
1da177e4 980
47b01b3a 981 configure_r_port(tty, info, NULL);
1da177e4
LT
982 if (tty->termios->c_cflag & CBAUD) {
983 sSetDTR(cp);
984 sSetRTS(cp);
985 }
986 }
987 /* Starts (or resets) the maint polling loop */
988 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
989
fba85e01 990 retval = tty_port_block_til_ready(port, tty, filp);
1da177e4
LT
991 if (retval) {
992#ifdef ROCKET_DEBUG_OPEN
993 printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
994#endif
995 return retval;
996 }
997 return 0;
998}
999
1000/*
e60a1084 1001 * Exception handler that closes a serial port. info->port.count is considered critical.
1da177e4
LT
1002 */
1003static void rp_close(struct tty_struct *tty, struct file *filp)
1004{
c9f19e96 1005 struct r_port *info = tty->driver_data;
c1314a49 1006 struct tty_port *port = &info->port;
1da177e4
LT
1007 int timeout;
1008 CHANNEL_t *cp;
1009
1010 if (rocket_paranoia_check(info, "rp_close"))
1011 return;
1012
1013#ifdef ROCKET_DEBUG_OPEN
e60a1084 1014 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
1da177e4
LT
1015#endif
1016
fba85e01 1017 if (tty_port_close_start(port, tty, filp) == 0)
1da177e4 1018 return;
1da177e4
LT
1019
1020 cp = &info->channel;
1da177e4
LT
1021 /*
1022 * Before we drop DTR, make sure the UART transmitter
1023 * has completely drained; this is especially
1024 * important if there is a transmit FIFO!
1025 */
1026 timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps;
1027 if (timeout == 0)
1028 timeout = 1;
1029 rp_wait_until_sent(tty, timeout);
1030 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1031
1032 sDisTransmit(cp);
1033 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1034 sDisCTSFlowCtl(cp);
1035 sDisTxSoftFlowCtl(cp);
1036 sClrTxXOFF(cp);
1037 sFlushRxFIFO(cp);
1038 sFlushTxFIFO(cp);
1039 sClrRTS(cp);
1040 if (C_HUPCL(tty))
1041 sClrDTR(cp);
1042
f6de0c98 1043 rp_flush_buffer(tty);
1da177e4
LT
1044
1045 tty_ldisc_flush(tty);
1046
1047 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1048
fba85e01
AC
1049 /* We can't yet use tty_port_close_end as the buffer handling in this
1050 driver is a bit different to the usual */
1051
c1314a49
AC
1052 if (port->blocked_open) {
1053 if (port->close_delay) {
1054 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1da177e4 1055 }
c1314a49 1056 wake_up_interruptible(&port->open_wait);
1da177e4
LT
1057 } else {
1058 if (info->xmit_buf) {
1059 free_page((unsigned long) info->xmit_buf);
1060 info->xmit_buf = NULL;
1061 }
1062 }
21bed701 1063 info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE);
1da177e4 1064 tty->closing = 0;
fba85e01
AC
1065 tty_port_tty_set(port, NULL);
1066 wake_up_interruptible(&port->close_wait);
8cf5a8c5 1067 complete_all(&info->close_wait);
1da177e4
LT
1068 atomic_dec(&rp_num_ports_open);
1069
1070#ifdef ROCKET_DEBUG_OPEN
68562b79
JS
1071 printk(KERN_INFO "rocket mod-- = %d...\n",
1072 atomic_read(&rp_num_ports_open));
1da177e4
LT
1073 printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line);
1074#endif
1075
1076}
1077
1078static void rp_set_termios(struct tty_struct *tty,
606d099c 1079 struct ktermios *old_termios)
1da177e4 1080{
c9f19e96 1081 struct r_port *info = tty->driver_data;
1da177e4
LT
1082 CHANNEL_t *cp;
1083 unsigned cflag;
1084
1085 if (rocket_paranoia_check(info, "rp_set_termios"))
1086 return;
1087
1088 cflag = tty->termios->c_cflag;
1089
1da177e4
LT
1090 /*
1091 * This driver doesn't support CS5 or CS6
1092 */
1093 if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
1094 tty->termios->c_cflag =
1095 ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
6df3526b
AC
1096 /* Or CMSPAR */
1097 tty->termios->c_cflag &= ~CMSPAR;
1da177e4 1098
47b01b3a 1099 configure_r_port(tty, info, old_termios);
1da177e4
LT
1100
1101 cp = &info->channel;
1102
1103 /* Handle transition to B0 status */
1104 if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) {
1105 sClrDTR(cp);
1106 sClrRTS(cp);
1107 }
1108
1109 /* Handle transition away from B0 status */
1110 if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) {
1111 if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS))
1112 sSetRTS(cp);
1113 sSetDTR(cp);
1114 }
1115
1116 if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
1117 tty->hw_stopped = 0;
1118 rp_start(tty);
1119 }
1120}
1121
9e98966c 1122static int rp_break(struct tty_struct *tty, int break_state)
1da177e4 1123{
c9f19e96 1124 struct r_port *info = tty->driver_data;
1da177e4
LT
1125 unsigned long flags;
1126
1127 if (rocket_paranoia_check(info, "rp_break"))
9e98966c 1128 return -EINVAL;
1da177e4
LT
1129
1130 spin_lock_irqsave(&info->slock, flags);
1131 if (break_state == -1)
1132 sSendBreak(&info->channel);
1133 else
1134 sClrBreak(&info->channel);
1135 spin_unlock_irqrestore(&info->slock, flags);
9e98966c 1136 return 0;
1da177e4
LT
1137}
1138
1139/*
1140 * sGetChanRI used to be a macro in rocket_int.h. When the functionality for
1141 * the UPCI boards was added, it was decided to make this a function because
1142 * the macro was getting too complicated. All cases except the first one
1143 * (UPCIRingInd) are taken directly from the original macro.
1144 */
1145static int sGetChanRI(CHANNEL_T * ChP)
1146{
1147 CONTROLLER_t *CtlP = ChP->CtlP;
1148 int ChanNum = ChP->ChanNum;
1149 int RingInd = 0;
1150
1151 if (CtlP->UPCIRingInd)
1152 RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]);
1153 else if (CtlP->AltChanRingIndicator)
1154 RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT;
1155 else if (CtlP->boardType == ROCKET_TYPE_PC104)
1156 RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]);
1157
1158 return RingInd;
1159}
1160
1161/********************************************************************************************/
1162/* Here are the routines used by rp_ioctl. These are all called from exception handlers. */
1163
1164/*
1165 * Returns the state of the serial modem control lines. These next 2 functions
1166 * are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs.
1167 */
1168static int rp_tiocmget(struct tty_struct *tty, struct file *file)
1169{
c9f19e96 1170 struct r_port *info = tty->driver_data;
1da177e4
LT
1171 unsigned int control, result, ChanStatus;
1172
1173 ChanStatus = sGetChanStatusLo(&info->channel);
1174 control = info->channel.TxControl[3];
1175 result = ((control & SET_RTS) ? TIOCM_RTS : 0) |
1176 ((control & SET_DTR) ? TIOCM_DTR : 0) |
1177 ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
1178 (sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
1179 ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
1180 ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);
1181
1182 return result;
1183}
1184
1185/*
1186 * Sets the modem control lines
1187 */
1188static int rp_tiocmset(struct tty_struct *tty, struct file *file,
1189 unsigned int set, unsigned int clear)
1190{
c9f19e96 1191 struct r_port *info = tty->driver_data;
1da177e4
LT
1192
1193 if (set & TIOCM_RTS)
1194 info->channel.TxControl[3] |= SET_RTS;
1195 if (set & TIOCM_DTR)
1196 info->channel.TxControl[3] |= SET_DTR;
1197 if (clear & TIOCM_RTS)
1198 info->channel.TxControl[3] &= ~SET_RTS;
1199 if (clear & TIOCM_DTR)
1200 info->channel.TxControl[3] &= ~SET_DTR;
1201
457fb605 1202 out32(info->channel.IndexAddr, info->channel.TxControl);
1da177e4
LT
1203 return 0;
1204}
1205
1206static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1207{
1208 struct rocket_config tmp;
1209
1210 if (!retinfo)
1211 return -EFAULT;
1212 memset(&tmp, 0, sizeof (tmp));
1213 tmp.line = info->line;
1214 tmp.flags = info->flags;
44b7d1b3
AC
1215 tmp.close_delay = info->port.close_delay;
1216 tmp.closing_wait = info->port.closing_wait;
1da177e4
LT
1217 tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
1218
1219 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
1220 return -EFAULT;
1221 return 0;
1222}
1223
47b01b3a
AC
1224static int set_config(struct tty_struct *tty, struct r_port *info,
1225 struct rocket_config __user *new_info)
1da177e4
LT
1226{
1227 struct rocket_config new_serial;
1228
1229 if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
1230 return -EFAULT;
1231
1232 if (!capable(CAP_SYS_ADMIN))
1233 {
1234 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
1235 return -EPERM;
1236 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
47b01b3a 1237 configure_r_port(tty, info, NULL);
1da177e4
LT
1238 return 0;
1239 }
1240
1241 info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
44b7d1b3
AC
1242 info->port.close_delay = new_serial.close_delay;
1243 info->port.closing_wait = new_serial.closing_wait;
1da177e4
LT
1244
1245 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
47b01b3a 1246 tty->alt_speed = 57600;
1da177e4 1247 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
47b01b3a 1248 tty->alt_speed = 115200;
1da177e4 1249 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
47b01b3a 1250 tty->alt_speed = 230400;
1da177e4 1251 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
47b01b3a 1252 tty->alt_speed = 460800;
1da177e4 1253
47b01b3a 1254 configure_r_port(tty, info, NULL);
1da177e4
LT
1255 return 0;
1256}
1257
1258/*
1259 * This function fills in a rocket_ports struct with information
1260 * about what boards/ports are in the system. This info is passed
1261 * to user space. See setrocket.c where the info is used to create
1262 * the /dev/ttyRx ports.
1263 */
1264static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
1265{
1266 struct rocket_ports tmp;
1267 int board;
1268
1269 if (!retports)
1270 return -EFAULT;
1271 memset(&tmp, 0, sizeof (tmp));
1272 tmp.tty_major = rocket_driver->major;
1273
1274 for (board = 0; board < 4; board++) {
1275 tmp.rocketModel[board].model = rocketModel[board].model;
1276 strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString);
1277 tmp.rocketModel[board].numPorts = rocketModel[board].numPorts;
1278 tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
1279 tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber;
1280 }
1281 if (copy_to_user(retports, &tmp, sizeof (*retports)))
1282 return -EFAULT;
1283 return 0;
1284}
1285
1286static int reset_rm2(struct r_port *info, void __user *arg)
1287{
1288 int reset;
1289
4129a645
AC
1290 if (!capable(CAP_SYS_ADMIN))
1291 return -EPERM;
1292
1da177e4
LT
1293 if (copy_from_user(&reset, arg, sizeof (int)))
1294 return -EFAULT;
1295 if (reset)
1296 reset = 1;
1297
1298 if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII &&
1299 rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII)
1300 return -EINVAL;
1301
1302 if (info->ctlp->BusType == isISA)
1303 sModemReset(info->ctlp, info->chan, reset);
1304 else
1305 sPCIModemReset(info->ctlp, info->chan, reset);
1306
1307 return 0;
1308}
1309
1310static int get_version(struct r_port *info, struct rocket_version __user *retvers)
1311{
1312 if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
1313 return -EFAULT;
1314 return 0;
1315}
1316
1317/* IOCTL call handler into the driver */
1318static int rp_ioctl(struct tty_struct *tty, struct file *file,
1319 unsigned int cmd, unsigned long arg)
1320{
c9f19e96 1321 struct r_port *info = tty->driver_data;
1da177e4 1322 void __user *argp = (void __user *)arg;
bdf183aa 1323 int ret = 0;
1da177e4
LT
1324
1325 if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
1326 return -ENXIO;
1327
bdf183aa
AC
1328 lock_kernel();
1329
1da177e4
LT
1330 switch (cmd) {
1331 case RCKP_GET_STRUCT:
1332 if (copy_to_user(argp, info, sizeof (struct r_port)))
bdf183aa
AC
1333 ret = -EFAULT;
1334 break;
1da177e4 1335 case RCKP_GET_CONFIG:
bdf183aa
AC
1336 ret = get_config(info, argp);
1337 break;
1da177e4 1338 case RCKP_SET_CONFIG:
47b01b3a 1339 ret = set_config(tty, info, argp);
bdf183aa 1340 break;
1da177e4 1341 case RCKP_GET_PORTS:
bdf183aa
AC
1342 ret = get_ports(info, argp);
1343 break;
1da177e4 1344 case RCKP_RESET_RM2:
bdf183aa
AC
1345 ret = reset_rm2(info, argp);
1346 break;
1da177e4 1347 case RCKP_GET_VERSION:
bdf183aa
AC
1348 ret = get_version(info, argp);
1349 break;
1da177e4 1350 default:
bdf183aa 1351 ret = -ENOIOCTLCMD;
1da177e4 1352 }
bdf183aa
AC
1353 unlock_kernel();
1354 return ret;
1da177e4
LT
1355}
1356
1357static void rp_send_xchar(struct tty_struct *tty, char ch)
1358{
c9f19e96 1359 struct r_port *info = tty->driver_data;
1da177e4
LT
1360 CHANNEL_t *cp;
1361
1362 if (rocket_paranoia_check(info, "rp_send_xchar"))
1363 return;
1364
1365 cp = &info->channel;
1366 if (sGetTxCnt(cp))
1367 sWriteTxPrioByte(cp, ch);
1368 else
1369 sWriteTxByte(sGetTxRxDataIO(cp), ch);
1370}
1371
1372static void rp_throttle(struct tty_struct *tty)
1373{
c9f19e96 1374 struct r_port *info = tty->driver_data;
1da177e4
LT
1375 CHANNEL_t *cp;
1376
1377#ifdef ROCKET_DEBUG_THROTTLE
1378 printk(KERN_INFO "throttle %s: %d....\n", tty->name,
1379 tty->ldisc.chars_in_buffer(tty));
1380#endif
1381
1382 if (rocket_paranoia_check(info, "rp_throttle"))
1383 return;
1384
1385 cp = &info->channel;
1386 if (I_IXOFF(tty))
1387 rp_send_xchar(tty, STOP_CHAR(tty));
1388
1389 sClrRTS(&info->channel);
1390}
1391
1392static void rp_unthrottle(struct tty_struct *tty)
1393{
c9f19e96 1394 struct r_port *info = tty->driver_data;
1da177e4
LT
1395 CHANNEL_t *cp;
1396#ifdef ROCKET_DEBUG_THROTTLE
1397 printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
1398 tty->ldisc.chars_in_buffer(tty));
1399#endif
1400
1401 if (rocket_paranoia_check(info, "rp_throttle"))
1402 return;
1403
1404 cp = &info->channel;
1405 if (I_IXOFF(tty))
1406 rp_send_xchar(tty, START_CHAR(tty));
1407
1408 sSetRTS(&info->channel);
1409}
1410
1411/*
1412 * ------------------------------------------------------------
1413 * rp_stop() and rp_start()
1414 *
1415 * This routines are called before setting or resetting tty->stopped.
1416 * They enable or disable transmitter interrupts, as necessary.
1417 * ------------------------------------------------------------
1418 */
1419static void rp_stop(struct tty_struct *tty)
1420{
c9f19e96 1421 struct r_port *info = tty->driver_data;
1da177e4
LT
1422
1423#ifdef ROCKET_DEBUG_FLOW
1424 printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
1425 info->xmit_cnt, info->xmit_fifo_room);
1426#endif
1427
1428 if (rocket_paranoia_check(info, "rp_stop"))
1429 return;
1430
1431 if (sGetTxCnt(&info->channel))
1432 sDisTransmit(&info->channel);
1433}
1434
1435static void rp_start(struct tty_struct *tty)
1436{
c9f19e96 1437 struct r_port *info = tty->driver_data;
1da177e4
LT
1438
1439#ifdef ROCKET_DEBUG_FLOW
1440 printk(KERN_INFO "start %s: %d %d....\n", tty->name,
1441 info->xmit_cnt, info->xmit_fifo_room);
1442#endif
1443
1444 if (rocket_paranoia_check(info, "rp_stop"))
1445 return;
1446
1447 sEnTransmit(&info->channel);
1448 set_bit((info->aiop * 8) + info->chan,
1449 (void *) &xmit_flags[info->board]);
1450}
1451
1452/*
1453 * rp_wait_until_sent() --- wait until the transmitter is empty
1454 */
1455static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1456{
c9f19e96 1457 struct r_port *info = tty->driver_data;
1da177e4
LT
1458 CHANNEL_t *cp;
1459 unsigned long orig_jiffies;
1460 int check_time, exit_time;
1461 int txcnt;
1462
1463 if (rocket_paranoia_check(info, "rp_wait_until_sent"))
1464 return;
1465
1466 cp = &info->channel;
1467
1468 orig_jiffies = jiffies;
1469#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
68562b79 1470 printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...\n", timeout,
1da177e4 1471 jiffies);
68562b79 1472 printk(KERN_INFO "cps=%d...\n", info->cps);
1da177e4 1473#endif
978e595f 1474 lock_kernel();
1da177e4
LT
1475 while (1) {
1476 txcnt = sGetTxCnt(cp);
1477 if (!txcnt) {
1478 if (sGetChanStatusLo(cp) & TXSHRMT)
1479 break;
1480 check_time = (HZ / info->cps) / 5;
1481 } else {
1482 check_time = HZ * txcnt / info->cps;
1483 }
1484 if (timeout) {
1485 exit_time = orig_jiffies + timeout - jiffies;
1486 if (exit_time <= 0)
1487 break;
1488 if (exit_time < check_time)
1489 check_time = exit_time;
1490 }
1491 if (check_time == 0)
1492 check_time = 1;
1493#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
68562b79
JS
1494 printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...\n", txcnt,
1495 jiffies, check_time);
1da177e4
LT
1496#endif
1497 msleep_interruptible(jiffies_to_msecs(check_time));
1498 if (signal_pending(current))
1499 break;
1500 }
cc0a8fbb 1501 __set_current_state(TASK_RUNNING);
978e595f 1502 unlock_kernel();
1da177e4
LT
1503#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1504 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
1505#endif
1506}
1507
1508/*
1509 * rp_hangup() --- called by tty_hangup() when a hangup is signaled.
1510 */
1511static void rp_hangup(struct tty_struct *tty)
1512{
1513 CHANNEL_t *cp;
c9f19e96 1514 struct r_port *info = tty->driver_data;
1da177e4
LT
1515
1516 if (rocket_paranoia_check(info, "rp_hangup"))
1517 return;
1518
1519#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
68562b79 1520 printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line);
1da177e4
LT
1521#endif
1522 rp_flush_buffer(tty);
21bed701 1523 if (info->port.flags & ASYNC_CLOSING)
1da177e4 1524 return;
e60a1084 1525 if (info->port.count)
1da177e4
LT
1526 atomic_dec(&rp_num_ports_open);
1527 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1528
fba85e01 1529 tty_port_hangup(&info->port);
1da177e4
LT
1530
1531 cp = &info->channel;
1532 sDisRxFIFO(cp);
1533 sDisTransmit(cp);
1534 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1535 sDisCTSFlowCtl(cp);
1536 sDisTxSoftFlowCtl(cp);
1537 sClrTxXOFF(cp);
21bed701 1538 info->port.flags &= ~ASYNC_INITIALIZED;
1da177e4 1539
e60a1084 1540 wake_up_interruptible(&info->port.open_wait);
1da177e4
LT
1541}
1542
1543/*
1544 * Exception handler - write char routine. The RocketPort driver uses a
1545 * double-buffering strategy, with the twist that if the in-memory CPU
1546 * buffer is empty, and there's space in the transmit FIFO, the
1547 * writing routines will write directly to transmit FIFO.
1548 * Write buffer and counters protected by spinlocks
1549 */
bbbbb96f 1550static int rp_put_char(struct tty_struct *tty, unsigned char ch)
1da177e4 1551{
c9f19e96 1552 struct r_port *info = tty->driver_data;
1da177e4
LT
1553 CHANNEL_t *cp;
1554 unsigned long flags;
1555
1556 if (rocket_paranoia_check(info, "rp_put_char"))
bbbbb96f 1557 return 0;
1da177e4 1558
69f545ea
MK
1559 /*
1560 * Grab the port write mutex, locking out other processes that try to
1561 * write to this port
1562 */
1563 mutex_lock(&info->write_mtx);
1da177e4
LT
1564
1565#ifdef ROCKET_DEBUG_WRITE
68562b79 1566 printk(KERN_INFO "rp_put_char %c...\n", ch);
1da177e4
LT
1567#endif
1568
1569 spin_lock_irqsave(&info->slock, flags);
1570 cp = &info->channel;
1571
1572 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
1573 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1574
1575 if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) {
1576 info->xmit_buf[info->xmit_head++] = ch;
1577 info->xmit_head &= XMIT_BUF_SIZE - 1;
1578 info->xmit_cnt++;
1579 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1580 } else {
1581 sOutB(sGetTxRxDataIO(cp), ch);
1582 info->xmit_fifo_room--;
1583 }
1584 spin_unlock_irqrestore(&info->slock, flags);
69f545ea 1585 mutex_unlock(&info->write_mtx);
bbbbb96f 1586 return 1;
1da177e4
LT
1587}
1588
1589/*
1590 * Exception handler - write routine, called when user app writes to the device.
69f545ea 1591 * A per port write mutex is used to protect from another process writing to
1da177e4
LT
1592 * this port at the same time. This other process could be running on the other CPU
1593 * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out).
1594 * Spinlocks protect the info xmit members.
1595 */
1596static int rp_write(struct tty_struct *tty,
1597 const unsigned char *buf, int count)
1598{
c9f19e96 1599 struct r_port *info = tty->driver_data;
1da177e4
LT
1600 CHANNEL_t *cp;
1601 const unsigned char *b;
1602 int c, retval = 0;
1603 unsigned long flags;
1604
1605 if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
1606 return 0;
1607
1e3e8d91
SS
1608 if (mutex_lock_interruptible(&info->write_mtx))
1609 return -ERESTARTSYS;
1da177e4
LT
1610
1611#ifdef ROCKET_DEBUG_WRITE
68562b79 1612 printk(KERN_INFO "rp_write %d chars...\n", count);
1da177e4
LT
1613#endif
1614 cp = &info->channel;
1615
1616 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count)
1617 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1618
1619 /*
1620 * If the write queue for the port is empty, and there is FIFO space, stuff bytes
1621 * into FIFO. Use the write queue for temp storage.
1622 */
1623 if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
1624 c = min(count, info->xmit_fifo_room);
1625 b = buf;
1626
1627 /* Push data into FIFO, 2 bytes at a time */
1628 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2);
1629
1630 /* If there is a byte remaining, write it */
1631 if (c & 1)
1632 sOutB(sGetTxRxDataIO(cp), b[c - 1]);
1633
1634 retval += c;
1635 buf += c;
1636 count -= c;
1637
1638 spin_lock_irqsave(&info->slock, flags);
1639 info->xmit_fifo_room -= c;
1640 spin_unlock_irqrestore(&info->slock, flags);
1641 }
1642
1643 /* If count is zero, we wrote it all and are done */
1644 if (!count)
1645 goto end;
1646
1647 /* Write remaining data into the port's xmit_buf */
1648 while (1) {
47b01b3a 1649 /* Hung up ? */
a391ad0f 1650 if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
1da177e4 1651 goto end;
709107fc
HH
1652 c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
1653 c = min(c, XMIT_BUF_SIZE - info->xmit_head);
1da177e4
LT
1654 if (c <= 0)
1655 break;
1656
1657 b = buf;
1658 memcpy(info->xmit_buf + info->xmit_head, b, c);
1659
1660 spin_lock_irqsave(&info->slock, flags);
1661 info->xmit_head =
1662 (info->xmit_head + c) & (XMIT_BUF_SIZE - 1);
1663 info->xmit_cnt += c;
1664 spin_unlock_irqrestore(&info->slock, flags);
1665
1666 buf += c;
1667 count -= c;
1668 retval += c;
1669 }
1670
1671 if ((retval > 0) && !tty->stopped && !tty->hw_stopped)
1672 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1673
1674end:
1675 if (info->xmit_cnt < WAKEUP_CHARS) {
1676 tty_wakeup(tty);
1da177e4
LT
1677#ifdef ROCKETPORT_HAVE_POLL_WAIT
1678 wake_up_interruptible(&tty->poll_wait);
1679#endif
1680 }
69f545ea 1681 mutex_unlock(&info->write_mtx);
1da177e4
LT
1682 return retval;
1683}
1684
1685/*
1686 * Return the number of characters that can be sent. We estimate
1687 * only using the in-memory transmit buffer only, and ignore the
1688 * potential space in the transmit FIFO.
1689 */
1690static int rp_write_room(struct tty_struct *tty)
1691{
c9f19e96 1692 struct r_port *info = tty->driver_data;
1da177e4
LT
1693 int ret;
1694
1695 if (rocket_paranoia_check(info, "rp_write_room"))
1696 return 0;
1697
1698 ret = XMIT_BUF_SIZE - info->xmit_cnt - 1;
1699 if (ret < 0)
1700 ret = 0;
1701#ifdef ROCKET_DEBUG_WRITE
68562b79 1702 printk(KERN_INFO "rp_write_room returns %d...\n", ret);
1da177e4
LT
1703#endif
1704 return ret;
1705}
1706
1707/*
1708 * Return the number of characters in the buffer. Again, this only
1709 * counts those characters in the in-memory transmit buffer.
1710 */
1711static int rp_chars_in_buffer(struct tty_struct *tty)
1712{
c9f19e96 1713 struct r_port *info = tty->driver_data;
1da177e4
LT
1714 CHANNEL_t *cp;
1715
1716 if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
1717 return 0;
1718
1719 cp = &info->channel;
1720
1721#ifdef ROCKET_DEBUG_WRITE
68562b79 1722 printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt);
1da177e4
LT
1723#endif
1724 return info->xmit_cnt;
1725}
1726
1727/*
1728 * Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the
1729 * r_port struct for the port. Note that spinlock are used to protect info members,
1730 * do not call this function if the spinlock is already held.
1731 */
1732static void rp_flush_buffer(struct tty_struct *tty)
1733{
c9f19e96 1734 struct r_port *info = tty->driver_data;
1da177e4
LT
1735 CHANNEL_t *cp;
1736 unsigned long flags;
1737
1738 if (rocket_paranoia_check(info, "rp_flush_buffer"))
1739 return;
1740
1741 spin_lock_irqsave(&info->slock, flags);
1742 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1743 spin_unlock_irqrestore(&info->slock, flags);
1744
1da177e4
LT
1745#ifdef ROCKETPORT_HAVE_POLL_WAIT
1746 wake_up_interruptible(&tty->poll_wait);
1747#endif
1748 tty_wakeup(tty);
1749
1750 cp = &info->channel;
1751 sFlushTxFIFO(cp);
1752}
1753
1754#ifdef CONFIG_PCI
1755
8d5916d3
JS
1756static struct pci_device_id __devinitdata rocket_pci_ids[] = {
1757 { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
1758 { }
1759};
1760MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
1761
1da177e4
LT
1762/*
1763 * Called when a PCI card is found. Retrieves and stores model information,
1764 * init's aiopic and serial port hardware.
1765 * Inputs: i is the board number (0-n)
1766 */
f15313bf 1767static __init int register_PCI(int i, struct pci_dev *dev)
1da177e4
LT
1768{
1769 int num_aiops, aiop, max_num_aiops, num_chan, chan;
1770 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
1771 char *str, *board_type;
1772 CONTROLLER_t *ctlp;
1773
1774 int fast_clock = 0;
1775 int altChanRingIndicator = 0;
1776 int ports_per_aiop = 8;
1da177e4
LT
1777 WordIO_t ConfigIO = 0;
1778 ByteIO_t UPCIRingInd = 0;
1779
1780 if (!dev || pci_enable_device(dev))
1781 return 0;
1782
1783 rcktpt_io_addr[i] = pci_resource_start(dev, 0);
1da177e4
LT
1784
1785 rcktpt_type[i] = ROCKET_TYPE_NORMAL;
1786 rocketModel[i].loadrm2 = 0;
1787 rocketModel[i].startingPortNumber = nextLineNumber;
1788
1789 /* Depending on the model, set up some config variables */
1790 switch (dev->device) {
1791 case PCI_DEVICE_ID_RP4QUAD:
1792 str = "Quadcable";
1793 max_num_aiops = 1;
1794 ports_per_aiop = 4;
1795 rocketModel[i].model = MODEL_RP4QUAD;
1796 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable");
1797 rocketModel[i].numPorts = 4;
1798 break;
1799 case PCI_DEVICE_ID_RP8OCTA:
1800 str = "Octacable";
1801 max_num_aiops = 1;
1802 rocketModel[i].model = MODEL_RP8OCTA;
1803 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
1804 rocketModel[i].numPorts = 8;
1805 break;
1806 case PCI_DEVICE_ID_URP8OCTA:
1807 str = "Octacable";
1808 max_num_aiops = 1;
1809 rocketModel[i].model = MODEL_UPCI_RP8OCTA;
1810 strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
1811 rocketModel[i].numPorts = 8;
1812 break;
1813 case PCI_DEVICE_ID_RP8INTF:
1814 str = "8";
1815 max_num_aiops = 1;
1816 rocketModel[i].model = MODEL_RP8INTF;
1817 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
1818 rocketModel[i].numPorts = 8;
1819 break;
1820 case PCI_DEVICE_ID_URP8INTF:
1821 str = "8";
1822 max_num_aiops = 1;
1823 rocketModel[i].model = MODEL_UPCI_RP8INTF;
1824 strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
1825 rocketModel[i].numPorts = 8;
1826 break;
1827 case PCI_DEVICE_ID_RP8J:
1828 str = "8J";
1829 max_num_aiops = 1;
1830 rocketModel[i].model = MODEL_RP8J;
1831 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
1832 rocketModel[i].numPorts = 8;
1833 break;
1834 case PCI_DEVICE_ID_RP4J:
1835 str = "4J";
1836 max_num_aiops = 1;
1837 ports_per_aiop = 4;
1838 rocketModel[i].model = MODEL_RP4J;
1839 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors");
1840 rocketModel[i].numPorts = 4;
1841 break;
1842 case PCI_DEVICE_ID_RP8SNI:
1843 str = "8 (DB78 Custom)";
1844 max_num_aiops = 1;
1845 rocketModel[i].model = MODEL_RP8SNI;
1846 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
1847 rocketModel[i].numPorts = 8;
1848 break;
1849 case PCI_DEVICE_ID_RP16SNI:
1850 str = "16 (DB78 Custom)";
1851 max_num_aiops = 2;
1852 rocketModel[i].model = MODEL_RP16SNI;
1853 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
1854 rocketModel[i].numPorts = 16;
1855 break;
1856 case PCI_DEVICE_ID_RP16INTF:
1857 str = "16";
1858 max_num_aiops = 2;
1859 rocketModel[i].model = MODEL_RP16INTF;
1860 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
1861 rocketModel[i].numPorts = 16;
1862 break;
1863 case PCI_DEVICE_ID_URP16INTF:
1864 str = "16";
1865 max_num_aiops = 2;
1866 rocketModel[i].model = MODEL_UPCI_RP16INTF;
1867 strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
1868 rocketModel[i].numPorts = 16;
1869 break;
1870 case PCI_DEVICE_ID_CRP16INTF:
1871 str = "16";
1872 max_num_aiops = 2;
1873 rocketModel[i].model = MODEL_CPCI_RP16INTF;
1874 strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
1875 rocketModel[i].numPorts = 16;
1876 break;
1877 case PCI_DEVICE_ID_RP32INTF:
1878 str = "32";
1879 max_num_aiops = 4;
1880 rocketModel[i].model = MODEL_RP32INTF;
1881 strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
1882 rocketModel[i].numPorts = 32;
1883 break;
1884 case PCI_DEVICE_ID_URP32INTF:
1885 str = "32";
1886 max_num_aiops = 4;
1887 rocketModel[i].model = MODEL_UPCI_RP32INTF;
1888 strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
1889 rocketModel[i].numPorts = 32;
1890 break;
1891 case PCI_DEVICE_ID_RPP4:
1892 str = "Plus Quadcable";
1893 max_num_aiops = 1;
1894 ports_per_aiop = 4;
1895 altChanRingIndicator++;
1896 fast_clock++;
1897 rocketModel[i].model = MODEL_RPP4;
1898 strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port");
1899 rocketModel[i].numPorts = 4;
1900 break;
1901 case PCI_DEVICE_ID_RPP8:
1902 str = "Plus Octacable";
1903 max_num_aiops = 2;
1904 ports_per_aiop = 4;
1905 altChanRingIndicator++;
1906 fast_clock++;
1907 rocketModel[i].model = MODEL_RPP8;
1908 strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port");
1909 rocketModel[i].numPorts = 8;
1910 break;
1911 case PCI_DEVICE_ID_RP2_232:
1912 str = "Plus 2 (RS-232)";
1913 max_num_aiops = 1;
1914 ports_per_aiop = 2;
1915 altChanRingIndicator++;
1916 fast_clock++;
1917 rocketModel[i].model = MODEL_RP2_232;
1918 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232");
1919 rocketModel[i].numPorts = 2;
1920 break;
1921 case PCI_DEVICE_ID_RP2_422:
1922 str = "Plus 2 (RS-422)";
1923 max_num_aiops = 1;
1924 ports_per_aiop = 2;
1925 altChanRingIndicator++;
1926 fast_clock++;
1927 rocketModel[i].model = MODEL_RP2_422;
1928 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422");
1929 rocketModel[i].numPorts = 2;
1930 break;
1931 case PCI_DEVICE_ID_RP6M:
1932
1933 max_num_aiops = 1;
1934 ports_per_aiop = 6;
1935 str = "6-port";
1936
57fedc7a
JS
1937 /* If revision is 1, the rocketmodem flash must be loaded.
1938 * If it is 2 it is a "socketed" version. */
1939 if (dev->revision == 1) {
1da177e4
LT
1940 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
1941 rocketModel[i].loadrm2 = 1;
1942 } else {
1943 rcktpt_type[i] = ROCKET_TYPE_MODEM;
1944 }
1945
1946 rocketModel[i].model = MODEL_RP6M;
1947 strcpy(rocketModel[i].modelString, "RocketModem 6 port");
1948 rocketModel[i].numPorts = 6;
1949 break;
1950 case PCI_DEVICE_ID_RP4M:
1951 max_num_aiops = 1;
1952 ports_per_aiop = 4;
1953 str = "4-port";
57fedc7a 1954 if (dev->revision == 1) {
1da177e4
LT
1955 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
1956 rocketModel[i].loadrm2 = 1;
1957 } else {
1958 rcktpt_type[i] = ROCKET_TYPE_MODEM;
1959 }
1960
1961 rocketModel[i].model = MODEL_RP4M;
1962 strcpy(rocketModel[i].modelString, "RocketModem 4 port");
1963 rocketModel[i].numPorts = 4;
1964 break;
1965 default:
1966 str = "(unknown/unsupported)";
1967 max_num_aiops = 0;
1968 break;
1969 }
1970
1971 /*
1972 * Check for UPCI boards.
1973 */
1974
1975 switch (dev->device) {
1976 case PCI_DEVICE_ID_URP32INTF:
1977 case PCI_DEVICE_ID_URP8INTF:
1978 case PCI_DEVICE_ID_URP16INTF:
1979 case PCI_DEVICE_ID_CRP16INTF:
1980 case PCI_DEVICE_ID_URP8OCTA:
1981 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
1982 ConfigIO = pci_resource_start(dev, 1);
1983 if (dev->device == PCI_DEVICE_ID_URP8OCTA) {
1984 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
1985
1986 /*
1987 * Check for octa or quad cable.
1988 */
1989 if (!
1990 (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
1991 PCI_GPIO_CTRL_8PORT)) {
1992 str = "Quadcable";
1993 ports_per_aiop = 4;
1994 rocketModel[i].numPorts = 4;
1995 }
1996 }
1997 break;
1998 case PCI_DEVICE_ID_UPCI_RM3_8PORT:
1999 str = "8 ports";
2000 max_num_aiops = 1;
2001 rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
2002 strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
2003 rocketModel[i].numPorts = 8;
2004 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2005 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2006 ConfigIO = pci_resource_start(dev, 1);
2007 rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2008 break;
2009 case PCI_DEVICE_ID_UPCI_RM3_4PORT:
2010 str = "4 ports";
2011 max_num_aiops = 1;
2012 rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
2013 strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
2014 rocketModel[i].numPorts = 4;
2015 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2016 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2017 ConfigIO = pci_resource_start(dev, 1);
2018 rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2019 break;
2020 default:
2021 break;
2022 }
2023
2024 switch (rcktpt_type[i]) {
2025 case ROCKET_TYPE_MODEM:
2026 board_type = "RocketModem";
2027 break;
2028 case ROCKET_TYPE_MODEMII:
2029 board_type = "RocketModem II";
2030 break;
2031 case ROCKET_TYPE_MODEMIII:
2032 board_type = "RocketModem III";
2033 break;
2034 default:
2035 board_type = "RocketPort";
2036 break;
2037 }
2038
2039 if (fast_clock) {
2040 sClockPrescale = 0x12; /* mod 2 (divide by 3) */
2041 rp_baud_base[i] = 921600;
2042 } else {
2043 /*
2044 * If support_low_speed is set, use the slow clock
2045 * prescale, which supports 50 bps
2046 */
2047 if (support_low_speed) {
2048 /* mod 9 (divide by 10) prescale */
2049 sClockPrescale = 0x19;
2050 rp_baud_base[i] = 230400;
2051 } else {
2052 /* mod 4 (devide by 5) prescale */
2053 sClockPrescale = 0x14;
2054 rp_baud_base[i] = 460800;
2055 }
2056 }
2057
2058 for (aiop = 0; aiop < max_num_aiops; aiop++)
2059 aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40);
2060 ctlp = sCtlNumToCtlPtr(i);
2061 num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd);
2062 for (aiop = 0; aiop < max_num_aiops; aiop++)
2063 ctlp->AiopNumChan[aiop] = ports_per_aiop;
2064
68562b79
JS
2065 dev_info(&dev->dev, "comtrol PCI controller #%d found at "
2066 "address %04lx, %d AIOP(s) (%s), creating ttyR%d - %ld\n",
2067 i, rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString,
2068 rocketModel[i].startingPortNumber,
2069 rocketModel[i].startingPortNumber + rocketModel[i].numPorts-1);
1da177e4
LT
2070
2071 if (num_aiops <= 0) {
2072 rcktpt_io_addr[i] = 0;
2073 return (0);
2074 }
2075 is_PCI[i] = 1;
2076
2077 /* Reset the AIOPIC, init the serial ports */
2078 for (aiop = 0; aiop < num_aiops; aiop++) {
2079 sResetAiopByNum(ctlp, aiop);
2080 num_chan = ports_per_aiop;
2081 for (chan = 0; chan < num_chan; chan++)
2082 init_r_port(i, aiop, chan, dev);
2083 }
2084
2085 /* Rocket modems must be reset */
2086 if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) ||
2087 (rcktpt_type[i] == ROCKET_TYPE_MODEMII) ||
2088 (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) {
2089 num_chan = ports_per_aiop;
2090 for (chan = 0; chan < num_chan; chan++)
2091 sPCIModemReset(ctlp, chan, 1);
48a67f5d 2092 msleep(500);
1da177e4
LT
2093 for (chan = 0; chan < num_chan; chan++)
2094 sPCIModemReset(ctlp, chan, 0);
48a67f5d 2095 msleep(500);
1da177e4
LT
2096 rmSpeakerReset(ctlp, rocketModel[i].model);
2097 }
2098 return (1);
2099}
2100
2101/*
2102 * Probes for PCI cards, inits them if found
2103 * Input: board_found = number of ISA boards already found, or the
2104 * starting board number
2105 * Returns: Number of PCI boards found
2106 */
2107static int __init init_PCI(int boards_found)
2108{
2109 struct pci_dev *dev = NULL;
2110 int count = 0;
2111
2112 /* Work through the PCI device list, pulling out ours */
606d099c 2113 while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
1da177e4
LT
2114 if (register_PCI(count + boards_found, dev))
2115 count++;
2116 }
2117 return (count);
2118}
2119
2120#endif /* CONFIG_PCI */
2121
2122/*
2123 * Probes for ISA cards
2124 * Input: i = the board number to look for
2125 * Returns: 1 if board found, 0 else
2126 */
2127static int __init init_ISA(int i)
2128{
2129 int num_aiops, num_chan = 0, total_num_chan = 0;
2130 int aiop, chan;
2131 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
2132 CONTROLLER_t *ctlp;
2133 char *type_string;
2134
2135 /* If io_addr is zero, no board configured */
2136 if (rcktpt_io_addr[i] == 0)
2137 return (0);
2138
2139 /* Reserve the IO region */
2140 if (!request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort")) {
68562b79
JS
2141 printk(KERN_ERR "Unable to reserve IO region for configured "
2142 "ISA RocketPort at address 0x%lx, board not "
2143 "installed...\n", rcktpt_io_addr[i]);
1da177e4
LT
2144 rcktpt_io_addr[i] = 0;
2145 return (0);
2146 }
2147
2148 ctlp = sCtlNumToCtlPtr(i);
2149
2150 ctlp->boardType = rcktpt_type[i];
2151
2152 switch (rcktpt_type[i]) {
2153 case ROCKET_TYPE_PC104:
2154 type_string = "(PC104)";
2155 break;
2156 case ROCKET_TYPE_MODEM:
2157 type_string = "(RocketModem)";
2158 break;
2159 case ROCKET_TYPE_MODEMII:
2160 type_string = "(RocketModem II)";
2161 break;
2162 default:
2163 type_string = "";
2164 break;
2165 }
2166
2167 /*
2168 * If support_low_speed is set, use the slow clock prescale,
2169 * which supports 50 bps
2170 */
2171 if (support_low_speed) {
2172 sClockPrescale = 0x19; /* mod 9 (divide by 10) prescale */
2173 rp_baud_base[i] = 230400;
2174 } else {
2175 sClockPrescale = 0x14; /* mod 4 (devide by 5) prescale */
2176 rp_baud_base[i] = 460800;
2177 }
2178
2179 for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
2180 aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400);
2181
2182 num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0);
2183
2184 if (ctlp->boardType == ROCKET_TYPE_PC104) {
2185 sEnAiop(ctlp, 2); /* only one AIOPIC, but these */
2186 sEnAiop(ctlp, 3); /* CSels used for other stuff */
2187 }
2188
2189 /* If something went wrong initing the AIOP's release the ISA IO memory */
2190 if (num_aiops <= 0) {
2191 release_region(rcktpt_io_addr[i], 64);
2192 rcktpt_io_addr[i] = 0;
2193 return (0);
2194 }
2195
2196 rocketModel[i].startingPortNumber = nextLineNumber;
2197
2198 for (aiop = 0; aiop < num_aiops; aiop++) {
2199 sResetAiopByNum(ctlp, aiop);
2200 sEnAiop(ctlp, aiop);
2201 num_chan = sGetAiopNumChan(ctlp, aiop);
2202 total_num_chan += num_chan;
2203 for (chan = 0; chan < num_chan; chan++)
2204 init_r_port(i, aiop, chan, NULL);
2205 }
2206 is_PCI[i] = 0;
2207 if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) {
2208 num_chan = sGetAiopNumChan(ctlp, 0);
2209 total_num_chan = num_chan;
2210 for (chan = 0; chan < num_chan; chan++)
2211 sModemReset(ctlp, chan, 1);
48a67f5d 2212 msleep(500);
1da177e4
LT
2213 for (chan = 0; chan < num_chan; chan++)
2214 sModemReset(ctlp, chan, 0);
48a67f5d 2215 msleep(500);
1da177e4
LT
2216 strcpy(rocketModel[i].modelString, "RocketModem ISA");
2217 } else {
2218 strcpy(rocketModel[i].modelString, "RocketPort ISA");
2219 }
2220 rocketModel[i].numPorts = total_num_chan;
2221 rocketModel[i].model = MODEL_ISA;
2222
2223 printk(KERN_INFO "RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n",
2224 i, rcktpt_io_addr[i], num_aiops, type_string);
2225
2226 printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
2227 rocketModel[i].modelString,
2228 rocketModel[i].startingPortNumber,
2229 rocketModel[i].startingPortNumber +
2230 rocketModel[i].numPorts - 1);
2231
2232 return (1);
2233}
2234
b68e31d0 2235static const struct tty_operations rocket_ops = {
1da177e4
LT
2236 .open = rp_open,
2237 .close = rp_close,
2238 .write = rp_write,
2239 .put_char = rp_put_char,
2240 .write_room = rp_write_room,
2241 .chars_in_buffer = rp_chars_in_buffer,
2242 .flush_buffer = rp_flush_buffer,
2243 .ioctl = rp_ioctl,
2244 .throttle = rp_throttle,
2245 .unthrottle = rp_unthrottle,
2246 .set_termios = rp_set_termios,
2247 .stop = rp_stop,
2248 .start = rp_start,
2249 .hangup = rp_hangup,
2250 .break_ctl = rp_break,
2251 .send_xchar = rp_send_xchar,
2252 .wait_until_sent = rp_wait_until_sent,
2253 .tiocmget = rp_tiocmget,
2254 .tiocmset = rp_tiocmset,
2255};
2256
31f35939
AC
2257static const struct tty_port_operations rocket_port_ops = {
2258 .carrier_raised = carrier_raised,
fcc8ac18 2259 .dtr_rts = dtr_rts,
31f35939
AC
2260};
2261
1da177e4
LT
2262/*
2263 * The module "startup" routine; it's run when the module is loaded.
2264 */
d269cdd0 2265static int __init rp_init(void)
1da177e4 2266{
4384a3fa 2267 int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
1da177e4
LT
2268
2269 printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
2270 ROCKET_VERSION, ROCKET_DATE);
2271
2272 rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
2273 if (!rocket_driver)
4384a3fa 2274 goto err;
1da177e4 2275
1da177e4
LT
2276 /*
2277 * If board 1 is non-zero, there is at least one ISA configured. If controller is
2278 * zero, use the default controller IO address of board1 + 0x40.
2279 */
2280 if (board1) {
2281 if (controller == 0)
2282 controller = board1 + 0x40;
2283 } else {
2284 controller = 0; /* Used as a flag, meaning no ISA boards */
2285 }
2286
2287 /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
2288 if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
4384a3fa
JS
2289 printk(KERN_ERR "Unable to reserve IO region for first "
2290 "configured ISA RocketPort controller 0x%lx. "
2291 "Driver exiting\n", controller);
2292 ret = -EBUSY;
2293 goto err_tty;
1da177e4
LT
2294 }
2295
2296 /* Store ISA variable retrieved from command line or .conf file. */
2297 rcktpt_io_addr[0] = board1;
2298 rcktpt_io_addr[1] = board2;
2299 rcktpt_io_addr[2] = board3;
2300 rcktpt_io_addr[3] = board4;
2301
2302 rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2303 rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0];
2304 rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2305 rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1];
2306 rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2307 rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2];
2308 rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2309 rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3];
2310
2311 /*
2312 * Set up the tty driver structure and then register this
2313 * driver with the tty layer.
2314 */
2315
2316 rocket_driver->owner = THIS_MODULE;
331b8319 2317 rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV;
1da177e4
LT
2318 rocket_driver->name = "ttyR";
2319 rocket_driver->driver_name = "Comtrol RocketPort";
2320 rocket_driver->major = TTY_ROCKET_MAJOR;
2321 rocket_driver->minor_start = 0;
2322 rocket_driver->type = TTY_DRIVER_TYPE_SERIAL;
2323 rocket_driver->subtype = SERIAL_TYPE_NORMAL;
2324 rocket_driver->init_termios = tty_std_termios;
2325 rocket_driver->init_termios.c_cflag =
2326 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
606d099c
AC
2327 rocket_driver->init_termios.c_ispeed = 9600;
2328 rocket_driver->init_termios.c_ospeed = 9600;
1da177e4 2329#ifdef ROCKET_SOFT_FLOW
ac6aec2f 2330 rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
1da177e4
LT
2331#endif
2332 tty_set_operations(rocket_driver, &rocket_ops);
2333
4384a3fa
JS
2334 ret = tty_register_driver(rocket_driver);
2335 if (ret < 0) {
2336 printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
2337 goto err_tty;
1da177e4
LT
2338 }
2339
2340#ifdef ROCKET_DEBUG_OPEN
2341 printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major);
2342#endif
2343
2344 /*
2345 * OK, let's probe each of the controllers looking for boards. Any boards found
2346 * will be initialized here.
2347 */
2348 isa_boards_found = 0;
2349 pci_boards_found = 0;
2350
2351 for (i = 0; i < NUM_BOARDS; i++) {
2352 if (init_ISA(i))
2353 isa_boards_found++;
2354 }
2355
2356#ifdef CONFIG_PCI
2357 if (isa_boards_found < NUM_BOARDS)
2358 pci_boards_found = init_PCI(isa_boards_found);
2359#endif
2360
2361 max_board = pci_boards_found + isa_boards_found;
2362
2363 if (max_board == 0) {
4384a3fa
JS
2364 printk(KERN_ERR "No rocketport ports found; unloading driver\n");
2365 ret = -ENXIO;
2366 goto err_ttyu;
1da177e4
LT
2367 }
2368
2369 return 0;
4384a3fa
JS
2370err_ttyu:
2371 tty_unregister_driver(rocket_driver);
2372err_tty:
2373 put_tty_driver(rocket_driver);
2374err:
2375 return ret;
1da177e4
LT
2376}
2377
1da177e4
LT
2378
2379static void rp_cleanup_module(void)
2380{
2381 int retval;
2382 int i;
2383
2384 del_timer_sync(&rocket_timer);
2385
2386 retval = tty_unregister_driver(rocket_driver);
2387 if (retval)
68562b79 2388 printk(KERN_ERR "Error %d while trying to unregister "
1da177e4 2389 "rocketport driver\n", -retval);
1da177e4 2390
735d5661 2391 for (i = 0; i < MAX_RP_PORTS; i++)
ac6aec2f
JS
2392 if (rp_table[i]) {
2393 tty_unregister_device(rocket_driver, i);
2394 kfree(rp_table[i]);
2395 }
2396
2397 put_tty_driver(rocket_driver);
1da177e4
LT
2398
2399 for (i = 0; i < NUM_BOARDS; i++) {
2400 if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
2401 continue;
2402 release_region(rcktpt_io_addr[i], 64);
2403 }
2404 if (controller)
2405 release_region(controller, 4);
2406}
1da177e4 2407
1da177e4
LT
2408/***************************************************************************
2409Function: sInitController
2410Purpose: Initialization of controller global registers and controller
2411 structure.
2412Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
2413 IRQNum,Frequency,PeriodicOnly)
2414 CONTROLLER_T *CtlP; Ptr to controller structure
2415 int CtlNum; Controller number
2416 ByteIO_t MudbacIO; Mudbac base I/O address.
2417 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2418 This list must be in the order the AIOPs will be found on the
2419 controller. Once an AIOP in the list is not found, it is
2420 assumed that there are no more AIOPs on the controller.
2421 int AiopIOListSize; Number of addresses in AiopIOList
2422 int IRQNum; Interrupt Request number. Can be any of the following:
2423 0: Disable global interrupts
2424 3: IRQ 3
2425 4: IRQ 4
2426 5: IRQ 5
2427 9: IRQ 9
2428 10: IRQ 10
2429 11: IRQ 11
2430 12: IRQ 12
2431 15: IRQ 15
2432 Byte_t Frequency: A flag identifying the frequency
2433 of the periodic interrupt, can be any one of the following:
2434 FREQ_DIS - periodic interrupt disabled
2435 FREQ_137HZ - 137 Hertz
2436 FREQ_69HZ - 69 Hertz
2437 FREQ_34HZ - 34 Hertz
2438 FREQ_17HZ - 17 Hertz
2439 FREQ_9HZ - 9 Hertz
2440 FREQ_4HZ - 4 Hertz
2441 If IRQNum is set to 0 the Frequency parameter is
2442 overidden, it is forced to a value of FREQ_DIS.
f15313bf 2443 int PeriodicOnly: 1 if all interrupts except the periodic
1da177e4 2444 interrupt are to be blocked.
f15313bf 2445 0 is both the periodic interrupt and
1da177e4
LT
2446 other channel interrupts are allowed.
2447 If IRQNum is set to 0 the PeriodicOnly parameter is
f15313bf 2448 overidden, it is forced to a value of 0.
1da177e4
LT
2449Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2450 initialization failed.
2451
2452Comments:
2453 If periodic interrupts are to be disabled but AIOP interrupts
f15313bf 2454 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
1da177e4
LT
2455
2456 If interrupts are to be completely disabled set IRQNum to 0.
2457
f15313bf 2458 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
1da177e4
LT
2459 invalid combination.
2460
2461 This function performs initialization of global interrupt modes,
2462 but it does not actually enable global interrupts. To enable
2463 and disable global interrupts use functions sEnGlobalInt() and
2464 sDisGlobalInt(). Enabling of global interrupts is normally not
2465 done until all other initializations are complete.
2466
2467 Even if interrupts are globally enabled, they must also be
2468 individually enabled for each channel that is to generate
2469 interrupts.
2470
2471Warnings: No range checking on any of the parameters is done.
2472
2473 No context switches are allowed while executing this function.
2474
2475 After this function all AIOPs on the controller are disabled,
2476 they can be enabled with sEnAiop().
2477*/
f15313bf
AB
2478static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
2479 ByteIO_t * AiopIOList, int AiopIOListSize,
2480 int IRQNum, Byte_t Frequency, int PeriodicOnly)
1da177e4
LT
2481{
2482 int i;
2483 ByteIO_t io;
2484 int done;
2485
2486 CtlP->AiopIntrBits = aiop_intr_bits;
2487 CtlP->AltChanRingIndicator = 0;
2488 CtlP->CtlNum = CtlNum;
2489 CtlP->CtlID = CTLID_0001; /* controller release 1 */
2490 CtlP->BusType = isISA;
2491 CtlP->MBaseIO = MudbacIO;
2492 CtlP->MReg1IO = MudbacIO + 1;
2493 CtlP->MReg2IO = MudbacIO + 2;
2494 CtlP->MReg3IO = MudbacIO + 3;
2495#if 1
2496 CtlP->MReg2 = 0; /* interrupt disable */
2497 CtlP->MReg3 = 0; /* no periodic interrupts */
2498#else
2499 if (sIRQMap[IRQNum] == 0) { /* interrupts globally disabled */
2500 CtlP->MReg2 = 0; /* interrupt disable */
2501 CtlP->MReg3 = 0; /* no periodic interrupts */
2502 } else {
2503 CtlP->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */
2504 CtlP->MReg3 = Frequency; /* set frequency */
2505 if (PeriodicOnly) { /* periodic interrupt only */
2506 CtlP->MReg3 |= PERIODIC_ONLY;
2507 }
2508 }
2509#endif
2510 sOutB(CtlP->MReg2IO, CtlP->MReg2);
2511 sOutB(CtlP->MReg3IO, CtlP->MReg3);
2512 sControllerEOI(CtlP); /* clear EOI if warm init */
2513 /* Init AIOPs */
2514 CtlP->NumAiop = 0;
2515 for (i = done = 0; i < AiopIOListSize; i++) {
2516 io = AiopIOList[i];
2517 CtlP->AiopIO[i] = (WordIO_t) io;
2518 CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2519 sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03)); /* AIOP index */
2520 sOutB(MudbacIO, (Byte_t) (io >> 6)); /* set up AIOP I/O in MUDBAC */
2521 if (done)
2522 continue;
2523 sEnAiop(CtlP, i); /* enable the AIOP */
2524 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
2525 if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
2526 done = 1; /* done looking for AIOPs */
2527 else {
2528 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
2529 sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */
2530 sOutB(io + _INDX_DATA, sClockPrescale);
2531 CtlP->NumAiop++; /* bump count of AIOPs */
2532 }
2533 sDisAiop(CtlP, i); /* disable AIOP */
2534 }
2535
2536 if (CtlP->NumAiop == 0)
2537 return (-1);
2538 else
2539 return (CtlP->NumAiop);
2540}
2541
2542/***************************************************************************
2543Function: sPCIInitController
2544Purpose: Initialization of controller global registers and controller
2545 structure.
2546Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
2547 IRQNum,Frequency,PeriodicOnly)
2548 CONTROLLER_T *CtlP; Ptr to controller structure
2549 int CtlNum; Controller number
2550 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2551 This list must be in the order the AIOPs will be found on the
2552 controller. Once an AIOP in the list is not found, it is
2553 assumed that there are no more AIOPs on the controller.
2554 int AiopIOListSize; Number of addresses in AiopIOList
2555 int IRQNum; Interrupt Request number. Can be any of the following:
2556 0: Disable global interrupts
2557 3: IRQ 3
2558 4: IRQ 4
2559 5: IRQ 5
2560 9: IRQ 9
2561 10: IRQ 10
2562 11: IRQ 11
2563 12: IRQ 12
2564 15: IRQ 15
2565 Byte_t Frequency: A flag identifying the frequency
2566 of the periodic interrupt, can be any one of the following:
2567 FREQ_DIS - periodic interrupt disabled
2568 FREQ_137HZ - 137 Hertz
2569 FREQ_69HZ - 69 Hertz
2570 FREQ_34HZ - 34 Hertz
2571 FREQ_17HZ - 17 Hertz
2572 FREQ_9HZ - 9 Hertz
2573 FREQ_4HZ - 4 Hertz
2574 If IRQNum is set to 0 the Frequency parameter is
2575 overidden, it is forced to a value of FREQ_DIS.
f15313bf 2576 int PeriodicOnly: 1 if all interrupts except the periodic
1da177e4 2577 interrupt are to be blocked.
f15313bf 2578 0 is both the periodic interrupt and
1da177e4
LT
2579 other channel interrupts are allowed.
2580 If IRQNum is set to 0 the PeriodicOnly parameter is
f15313bf 2581 overidden, it is forced to a value of 0.
1da177e4
LT
2582Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2583 initialization failed.
2584
2585Comments:
2586 If periodic interrupts are to be disabled but AIOP interrupts
f15313bf 2587 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
1da177e4
LT
2588
2589 If interrupts are to be completely disabled set IRQNum to 0.
2590
f15313bf 2591 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
1da177e4
LT
2592 invalid combination.
2593
2594 This function performs initialization of global interrupt modes,
2595 but it does not actually enable global interrupts. To enable
2596 and disable global interrupts use functions sEnGlobalInt() and
2597 sDisGlobalInt(). Enabling of global interrupts is normally not
2598 done until all other initializations are complete.
2599
2600 Even if interrupts are globally enabled, they must also be
2601 individually enabled for each channel that is to generate
2602 interrupts.
2603
2604Warnings: No range checking on any of the parameters is done.
2605
2606 No context switches are allowed while executing this function.
2607
2608 After this function all AIOPs on the controller are disabled,
2609 they can be enabled with sEnAiop().
2610*/
f15313bf
AB
2611static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
2612 ByteIO_t * AiopIOList, int AiopIOListSize,
2613 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
2614 int PeriodicOnly, int altChanRingIndicator,
2615 int UPCIRingInd)
1da177e4
LT
2616{
2617 int i;
2618 ByteIO_t io;
2619
2620 CtlP->AltChanRingIndicator = altChanRingIndicator;
2621 CtlP->UPCIRingInd = UPCIRingInd;
2622 CtlP->CtlNum = CtlNum;
2623 CtlP->CtlID = CTLID_0001; /* controller release 1 */
2624 CtlP->BusType = isPCI; /* controller release 1 */
2625
2626 if (ConfigIO) {
2627 CtlP->isUPCI = 1;
2628 CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
2629 CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
2630 CtlP->AiopIntrBits = upci_aiop_intr_bits;
2631 } else {
2632 CtlP->isUPCI = 0;
2633 CtlP->PCIIO =
2634 (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
2635 CtlP->AiopIntrBits = aiop_intr_bits;
2636 }
2637
2638 sPCIControllerEOI(CtlP); /* clear EOI if warm init */
2639 /* Init AIOPs */
2640 CtlP->NumAiop = 0;
2641 for (i = 0; i < AiopIOListSize; i++) {
2642 io = AiopIOList[i];
2643 CtlP->AiopIO[i] = (WordIO_t) io;
2644 CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2645
2646 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
2647 if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
2648 break; /* done looking for AIOPs */
2649
2650 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
2651 sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */
2652 sOutB(io + _INDX_DATA, sClockPrescale);
2653 CtlP->NumAiop++; /* bump count of AIOPs */
2654 }
2655
2656 if (CtlP->NumAiop == 0)
2657 return (-1);
2658 else
2659 return (CtlP->NumAiop);
2660}
2661
2662/***************************************************************************
2663Function: sReadAiopID
2664Purpose: Read the AIOP idenfication number directly from an AIOP.
2665Call: sReadAiopID(io)
2666 ByteIO_t io: AIOP base I/O address
2667Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
2668 is replace by an identifying number.
2669 Flag AIOPID_NULL if no valid AIOP is found
2670Warnings: No context switches are allowed while executing this function.
2671
2672*/
f15313bf 2673static int sReadAiopID(ByteIO_t io)
1da177e4
LT
2674{
2675 Byte_t AiopID; /* ID byte from AIOP */
2676
2677 sOutB(io + _CMD_REG, RESET_ALL); /* reset AIOP */
2678 sOutB(io + _CMD_REG, 0x0);
2679 AiopID = sInW(io + _CHN_STAT0) & 0x07;
2680 if (AiopID == 0x06)
2681 return (1);
2682 else /* AIOP does not exist */
2683 return (-1);
2684}
2685
2686/***************************************************************************
2687Function: sReadAiopNumChan
2688Purpose: Read the number of channels available in an AIOP directly from
2689 an AIOP.
2690Call: sReadAiopNumChan(io)
2691 WordIO_t io: AIOP base I/O address
2692Return: int: The number of channels available
2693Comments: The number of channels is determined by write/reads from identical
2694 offsets within the SRAM address spaces for channels 0 and 4.
2695 If the channel 4 space is mirrored to channel 0 it is a 4 channel
2696 AIOP, otherwise it is an 8 channel.
2697Warnings: No context switches are allowed while executing this function.
2698*/
f15313bf 2699static int sReadAiopNumChan(WordIO_t io)
1da177e4
LT
2700{
2701 Word_t x;
2702 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
2703
2704 /* write to chan 0 SRAM */
457fb605 2705 out32((DWordIO_t) io + _INDX_ADDR, R);
1da177e4
LT
2706 sOutW(io + _INDX_ADDR, 0); /* read from SRAM, chan 0 */
2707 x = sInW(io + _INDX_DATA);
2708 sOutW(io + _INDX_ADDR, 0x4000); /* read from SRAM, chan 4 */
2709 if (x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */
2710 return (8);
2711 else
2712 return (4);
2713}
2714
2715/***************************************************************************
2716Function: sInitChan
2717Purpose: Initialization of a channel and channel structure
2718Call: sInitChan(CtlP,ChP,AiopNum,ChanNum)
2719 CONTROLLER_T *CtlP; Ptr to controller structure
2720 CHANNEL_T *ChP; Ptr to channel structure
2721 int AiopNum; AIOP number within controller
2722 int ChanNum; Channel number within AIOP
f15313bf 2723Return: int: 1 if initialization succeeded, 0 if it fails because channel
1da177e4
LT
2724 number exceeds number of channels available in AIOP.
2725Comments: This function must be called before a channel can be used.
2726Warnings: No range checking on any of the parameters is done.
2727
2728 No context switches are allowed while executing this function.
2729*/
f15313bf
AB
2730static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2731 int ChanNum)
1da177e4
LT
2732{
2733 int i;
2734 WordIO_t AiopIO;
2735 WordIO_t ChIOOff;
2736 Byte_t *ChR;
2737 Word_t ChOff;
2738 static Byte_t R[4];
2739 int brd9600;
2740
2741 if (ChanNum >= CtlP->AiopNumChan[AiopNum])
f15313bf 2742 return 0; /* exceeds num chans in AIOP */
1da177e4
LT
2743
2744 /* Channel, AIOP, and controller identifiers */
2745 ChP->CtlP = CtlP;
2746 ChP->ChanID = CtlP->AiopID[AiopNum];
2747 ChP->AiopNum = AiopNum;
2748 ChP->ChanNum = ChanNum;
2749
2750 /* Global direct addresses */
2751 AiopIO = CtlP->AiopIO[AiopNum];
2752 ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG;
2753 ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN;
2754 ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK;
2755 ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR;
2756 ChP->IndexData = AiopIO + _INDX_DATA;
2757
2758 /* Channel direct addresses */
2759 ChIOOff = AiopIO + ChP->ChanNum * 2;
2760 ChP->TxRxData = ChIOOff + _TD0;
2761 ChP->ChanStat = ChIOOff + _CHN_STAT0;
2762 ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
2763 ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0;
2764
2765 /* Initialize the channel from the RData array */
2766 for (i = 0; i < RDATASIZE; i += 4) {
2767 R[0] = RData[i];
2768 R[1] = RData[i + 1] + 0x10 * ChanNum;
2769 R[2] = RData[i + 2];
2770 R[3] = RData[i + 3];
457fb605 2771 out32(ChP->IndexAddr, R);
1da177e4
LT
2772 }
2773
2774 ChR = ChP->R;
2775 for (i = 0; i < RREGDATASIZE; i += 4) {
2776 ChR[i] = RRegData[i];
2777 ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum;
2778 ChR[i + 2] = RRegData[i + 2];
2779 ChR[i + 3] = RRegData[i + 3];
2780 }
2781
2782 /* Indexed registers */
2783 ChOff = (Word_t) ChanNum *0x1000;
2784
2785 if (sClockPrescale == 0x14)
2786 brd9600 = 47;
2787 else
2788 brd9600 = 23;
2789
2790 ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD);
2791 ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8);
2792 ChP->BaudDiv[2] = (Byte_t) brd9600;
2793 ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8);
457fb605 2794 out32(ChP->IndexAddr, ChP->BaudDiv);
1da177e4
LT
2795
2796 ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL);
2797 ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8);
2798 ChP->TxControl[2] = 0;
2799 ChP->TxControl[3] = 0;
457fb605 2800 out32(ChP->IndexAddr, ChP->TxControl);
1da177e4
LT
2801
2802 ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL);
2803 ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8);
2804 ChP->RxControl[2] = 0;
2805 ChP->RxControl[3] = 0;
457fb605 2806 out32(ChP->IndexAddr, ChP->RxControl);
1da177e4
LT
2807
2808 ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS);
2809 ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8);
2810 ChP->TxEnables[2] = 0;
2811 ChP->TxEnables[3] = 0;
457fb605 2812 out32(ChP->IndexAddr, ChP->TxEnables);
1da177e4
LT
2813
2814 ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1);
2815 ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8);
2816 ChP->TxCompare[2] = 0;
2817 ChP->TxCompare[3] = 0;
457fb605 2818 out32(ChP->IndexAddr, ChP->TxCompare);
1da177e4
LT
2819
2820 ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1);
2821 ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8);
2822 ChP->TxReplace1[2] = 0;
2823 ChP->TxReplace1[3] = 0;
457fb605 2824 out32(ChP->IndexAddr, ChP->TxReplace1);
1da177e4
LT
2825
2826 ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2);
2827 ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8);
2828 ChP->TxReplace2[2] = 0;
2829 ChP->TxReplace2[3] = 0;
457fb605 2830 out32(ChP->IndexAddr, ChP->TxReplace2);
1da177e4
LT
2831
2832 ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
2833 ChP->TxFIFO = ChOff + _TX_FIFO;
2834
2835 sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
2836 sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Tx FIFO count */
2837 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
2838 sOutW(ChP->IndexData, 0);
2839 ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
2840 ChP->RxFIFO = ChOff + _RX_FIFO;
2841
2842 sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
2843 sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Rx FIFO count */
2844 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */
2845 sOutW(ChP->IndexData, 0);
2846 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
2847 sOutW(ChP->IndexData, 0);
2848 ChP->TxPrioCnt = ChOff + _TXP_CNT;
2849 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt);
2850 sOutB(ChP->IndexData, 0);
2851 ChP->TxPrioPtr = ChOff + _TXP_PNTR;
2852 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr);
2853 sOutB(ChP->IndexData, 0);
2854 ChP->TxPrioBuf = ChOff + _TXP_BUF;
2855 sEnRxProcessor(ChP); /* start the Rx processor */
2856
f15313bf 2857 return 1;
1da177e4
LT
2858}
2859
2860/***************************************************************************
2861Function: sStopRxProcessor
2862Purpose: Stop the receive processor from processing a channel.
2863Call: sStopRxProcessor(ChP)
2864 CHANNEL_T *ChP; Ptr to channel structure
2865
2866Comments: The receive processor can be started again with sStartRxProcessor().
2867 This function causes the receive processor to skip over the
2868 stopped channel. It does not stop it from processing other channels.
2869
2870Warnings: No context switches are allowed while executing this function.
2871
2872 Do not leave the receive processor stopped for more than one
2873 character time.
2874
2875 After calling this function a delay of 4 uS is required to ensure
2876 that the receive processor is no longer processing this channel.
2877*/
f15313bf 2878static void sStopRxProcessor(CHANNEL_T * ChP)
1da177e4
LT
2879{
2880 Byte_t R[4];
2881
2882 R[0] = ChP->R[0];
2883 R[1] = ChP->R[1];
2884 R[2] = 0x0a;
2885 R[3] = ChP->R[3];
457fb605 2886 out32(ChP->IndexAddr, R);
1da177e4
LT
2887}
2888
2889/***************************************************************************
2890Function: sFlushRxFIFO
2891Purpose: Flush the Rx FIFO
2892Call: sFlushRxFIFO(ChP)
2893 CHANNEL_T *ChP; Ptr to channel structure
2894Return: void
2895Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
2896 while it is being flushed the receive processor is stopped
2897 and the transmitter is disabled. After these operations a
2898 4 uS delay is done before clearing the pointers to allow
2899 the receive processor to stop. These items are handled inside
2900 this function.
2901Warnings: No context switches are allowed while executing this function.
2902*/
f15313bf 2903static void sFlushRxFIFO(CHANNEL_T * ChP)
1da177e4
LT
2904{
2905 int i;
2906 Byte_t Ch; /* channel number within AIOP */
f15313bf 2907 int RxFIFOEnabled; /* 1 if Rx FIFO enabled */
1da177e4
LT
2908
2909 if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */
2910 return; /* don't need to flush */
2911
f15313bf 2912 RxFIFOEnabled = 0;
1da177e4 2913 if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */
f15313bf 2914 RxFIFOEnabled = 1;
1da177e4
LT
2915 sDisRxFIFO(ChP); /* disable it */
2916 for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */
2917 sInB(ChP->IntChan); /* depends on bus i/o timing */
2918 }
2919 sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */
2920 Ch = (Byte_t) sGetChanNum(ChP);
2921 sOutB(ChP->Cmd, Ch | RESRXFCNT); /* apply reset Rx FIFO count */
2922 sOutB(ChP->Cmd, Ch); /* remove reset Rx FIFO count */
2923 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */
2924 sOutW(ChP->IndexData, 0);
2925 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
2926 sOutW(ChP->IndexData, 0);
2927 if (RxFIFOEnabled)
2928 sEnRxFIFO(ChP); /* enable Rx FIFO */
2929}
2930
2931/***************************************************************************
2932Function: sFlushTxFIFO
2933Purpose: Flush the Tx FIFO
2934Call: sFlushTxFIFO(ChP)
2935 CHANNEL_T *ChP; Ptr to channel structure
2936Return: void
2937Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
2938 while it is being flushed the receive processor is stopped
2939 and the transmitter is disabled. After these operations a
2940 4 uS delay is done before clearing the pointers to allow
2941 the receive processor to stop. These items are handled inside
2942 this function.
2943Warnings: No context switches are allowed while executing this function.
2944*/
f15313bf 2945static void sFlushTxFIFO(CHANNEL_T * ChP)
1da177e4
LT
2946{
2947 int i;
2948 Byte_t Ch; /* channel number within AIOP */
f15313bf 2949 int TxEnabled; /* 1 if transmitter enabled */
1da177e4
LT
2950
2951 if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */
2952 return; /* don't need to flush */
2953
f15313bf 2954 TxEnabled = 0;
1da177e4 2955 if (ChP->TxControl[3] & TX_ENABLE) {
f15313bf 2956 TxEnabled = 1;
1da177e4
LT
2957 sDisTransmit(ChP); /* disable transmitter */
2958 }
2959 sStopRxProcessor(ChP); /* stop Rx processor */
2960 for (i = 0; i < 4000 / 200; i++) /* delay 4 uS to allow proc to stop */
2961 sInB(ChP->IntChan); /* depends on bus i/o timing */
2962 Ch = (Byte_t) sGetChanNum(ChP);
2963 sOutB(ChP->Cmd, Ch | RESTXFCNT); /* apply reset Tx FIFO count */
2964 sOutB(ChP->Cmd, Ch); /* remove reset Tx FIFO count */
2965 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
2966 sOutW(ChP->IndexData, 0);
2967 if (TxEnabled)
2968 sEnTransmit(ChP); /* enable transmitter */
2969 sStartRxProcessor(ChP); /* restart Rx processor */
2970}
2971
2972/***************************************************************************
2973Function: sWriteTxPrioByte
2974Purpose: Write a byte of priority transmit data to a channel
2975Call: sWriteTxPrioByte(ChP,Data)
2976 CHANNEL_T *ChP; Ptr to channel structure
2977 Byte_t Data; The transmit data byte
2978
2979Return: int: 1 if the bytes is successfully written, otherwise 0.
2980
2981Comments: The priority byte is transmitted before any data in the Tx FIFO.
2982
2983Warnings: No context switches are allowed while executing this function.
2984*/
f15313bf 2985static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
1da177e4
LT
2986{
2987 Byte_t DWBuf[4]; /* buffer for double word writes */
2988 Word_t *WordPtr; /* must be far because Win SS != DS */
2989 register DWordIO_t IndexAddr;
2990
2991 if (sGetTxCnt(ChP) > 1) { /* write it to Tx priority buffer */
2992 IndexAddr = ChP->IndexAddr;
2993 sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt); /* get priority buffer status */
2994 if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND) /* priority buffer busy */
2995 return (0); /* nothing sent */
2996
2997 WordPtr = (Word_t *) (&DWBuf[0]);
2998 *WordPtr = ChP->TxPrioBuf; /* data byte address */
2999
3000 DWBuf[2] = Data; /* data byte value */
457fb605 3001 out32(IndexAddr, DWBuf); /* write it out */
1da177e4
LT
3002
3003 *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */
3004
3005 DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */
3006 DWBuf[3] = 0; /* priority buffer pointer */
457fb605 3007 out32(IndexAddr, DWBuf); /* write it out */
1da177e4
LT
3008 } else { /* write it to Tx FIFO */
3009
3010 sWriteTxByte(sGetTxRxDataIO(ChP), Data);
3011 }
3012 return (1); /* 1 byte sent */
3013}
3014
3015/***************************************************************************
3016Function: sEnInterrupts
3017Purpose: Enable one or more interrupts for a channel
3018Call: sEnInterrupts(ChP,Flags)
3019 CHANNEL_T *ChP; Ptr to channel structure
3020 Word_t Flags: Interrupt enable flags, can be any combination
3021 of the following flags:
3022 TXINT_EN: Interrupt on Tx FIFO empty
3023 RXINT_EN: Interrupt on Rx FIFO at trigger level (see
3024 sSetRxTrigger())
3025 SRCINT_EN: Interrupt on SRC (Special Rx Condition)
3026 MCINT_EN: Interrupt on modem input change
3027 CHANINT_EN: Allow channel interrupt signal to the AIOP's
3028 Interrupt Channel Register.
3029Return: void
3030Comments: If an interrupt enable flag is set in Flags, that interrupt will be
3031 enabled. If an interrupt enable flag is not set in Flags, that
3032 interrupt will not be changed. Interrupts can be disabled with
3033 function sDisInterrupts().
3034
3035 This function sets the appropriate bit for the channel in the AIOP's
3036 Interrupt Mask Register if the CHANINT_EN flag is set. This allows
3037 this channel's bit to be set in the AIOP's Interrupt Channel Register.
3038
3039 Interrupts must also be globally enabled before channel interrupts
3040 will be passed on to the host. This is done with function
3041 sEnGlobalInt().
3042
3043 In some cases it may be desirable to disable interrupts globally but
3044 enable channel interrupts. This would allow the global interrupt
3045 status register to be used to determine which AIOPs need service.
3046*/
f15313bf 3047static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
1da177e4
LT
3048{
3049 Byte_t Mask; /* Interrupt Mask Register */
3050
3051 ChP->RxControl[2] |=
3052 ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3053
457fb605 3054 out32(ChP->IndexAddr, ChP->RxControl);
1da177e4
LT
3055
3056 ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);
3057
457fb605 3058 out32(ChP->IndexAddr, ChP->TxControl);
1da177e4
LT
3059
3060 if (Flags & CHANINT_EN) {
3061 Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
3062 sOutB(ChP->IntMask, Mask);
3063 }
3064}
3065
3066/***************************************************************************
3067Function: sDisInterrupts
3068Purpose: Disable one or more interrupts for a channel
3069Call: sDisInterrupts(ChP,Flags)
3070 CHANNEL_T *ChP; Ptr to channel structure
3071 Word_t Flags: Interrupt flags, can be any combination
3072 of the following flags:
3073 TXINT_EN: Interrupt on Tx FIFO empty
3074 RXINT_EN: Interrupt on Rx FIFO at trigger level (see
3075 sSetRxTrigger())
3076 SRCINT_EN: Interrupt on SRC (Special Rx Condition)
3077 MCINT_EN: Interrupt on modem input change
3078 CHANINT_EN: Disable channel interrupt signal to the
3079 AIOP's Interrupt Channel Register.
3080Return: void
3081Comments: If an interrupt flag is set in Flags, that interrupt will be
3082 disabled. If an interrupt flag is not set in Flags, that
3083 interrupt will not be changed. Interrupts can be enabled with
3084 function sEnInterrupts().
3085
3086 This function clears the appropriate bit for the channel in the AIOP's
3087 Interrupt Mask Register if the CHANINT_EN flag is set. This blocks
3088 this channel's bit from being set in the AIOP's Interrupt Channel
3089 Register.
3090*/
f15313bf 3091static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
1da177e4
LT
3092{
3093 Byte_t Mask; /* Interrupt Mask Register */
3094
3095 ChP->RxControl[2] &=
3096 ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
457fb605 3097 out32(ChP->IndexAddr, ChP->RxControl);
1da177e4 3098 ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN);
457fb605 3099 out32(ChP->IndexAddr, ChP->TxControl);
1da177e4
LT
3100
3101 if (Flags & CHANINT_EN) {
3102 Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
3103 sOutB(ChP->IntMask, Mask);
3104 }
3105}
3106
f15313bf 3107static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
1da177e4
LT
3108{
3109 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
3110}
3111
3112/*
3113 * Not an official SSCI function, but how to reset RocketModems.
3114 * ISA bus version
3115 */
f15313bf 3116static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
1da177e4
LT
3117{
3118 ByteIO_t addr;
3119 Byte_t val;
3120
3121 addr = CtlP->AiopIO[0] + 0x400;
3122 val = sInB(CtlP->MReg3IO);
3123 /* if AIOP[1] is not enabled, enable it */
3124 if ((val & 2) == 0) {
3125 val = sInB(CtlP->MReg2IO);
3126 sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03));
3127 sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6));
3128 }
3129
3130 sEnAiop(CtlP, 1);
3131 if (!on)
3132 addr += 8;
3133 sOutB(addr + chan, 0); /* apply or remove reset */
3134 sDisAiop(CtlP, 1);
3135}
3136
3137/*
3138 * Not an official SSCI function, but how to reset RocketModems.
3139 * PCI bus version
3140 */
f15313bf 3141static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
1da177e4
LT
3142{
3143 ByteIO_t addr;
3144
3145 addr = CtlP->AiopIO[0] + 0x40; /* 2nd AIOP */
3146 if (!on)
3147 addr += 8;
3148 sOutB(addr + chan, 0); /* apply or remove reset */
3149}
3150
3151/* Resets the speaker controller on RocketModem II and III devices */
3152static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
3153{
3154 ByteIO_t addr;
3155
3156 /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
3157 if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
3158 addr = CtlP->AiopIO[0] + 0x4F;
3159 sOutB(addr, 0);
3160 }
3161
3162 /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
3163 if ((model == MODEL_UPCI_RM3_8PORT)
3164 || (model == MODEL_UPCI_RM3_4PORT)) {
3165 addr = CtlP->AiopIO[0] + 0x88;
3166 sOutB(addr, 0);
3167 }
3168}
3169
3170/* Returns the line number given the controller (board), aiop and channel number */
3171static unsigned char GetLineNumber(int ctrl, int aiop, int ch)
3172{
3173 return lineNumbers[(ctrl << 5) | (aiop << 3) | ch];
3174}
3175
3176/*
3177 * Stores the line number associated with a given controller (board), aiop
3178 * and channel number.
3179 * Returns: The line number assigned
3180 */
3181static unsigned char SetLineNumber(int ctrl, int aiop, int ch)
3182{
3183 lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++;
3184 return (nextLineNumber - 1);
3185}