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