blob: 80a2bdf7b92c8df7f587b78521732f18337806ca [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*****************************************************************************/
2/*
3 * moxa.c -- MOXA Intellio family multiport serial driver.
4 *
5 * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com.tw).
6 *
7 * This code is loosely based on the Linux serial driver, written by
8 * Linus Torvalds, Theodore T'so and others.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25/*
26 * MOXA Intellio Series Driver
27 * for : LINUX
28 * date : 1999/1/7
29 * version : 5.1
30 */
31
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/mm.h>
35#include <linux/ioport.h>
36#include <linux/errno.h>
37#include <linux/signal.h>
38#include <linux/sched.h>
39#include <linux/timer.h>
40#include <linux/interrupt.h>
41#include <linux/tty.h>
42#include <linux/tty_flip.h>
43#include <linux/major.h>
44#include <linux/string.h>
45#include <linux/fcntl.h>
46#include <linux/ptrace.h>
47#include <linux/serial.h>
48#include <linux/tty_driver.h>
49#include <linux/delay.h>
50#include <linux/pci.h>
51#include <linux/init.h>
52#include <linux/bitops.h>
53
54#include <asm/system.h>
55#include <asm/io.h>
56#include <asm/uaccess.h>
57
58#define MOXA_VERSION "5.1k"
59
60#define MOXAMAJOR 172
61#define MOXACUMAJOR 173
62
63#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2)
64#define get_from_user(arg1, arg2) get_user(arg1, (unsigned int *)arg2)
65
66#define MAX_BOARDS 4 /* Don't change this value */
67#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */
68#define MAX_PORTS 128 /* Don't change this value */
69
70/*
71 * Define the Moxa PCI vendor and device IDs.
72 */
73#define MOXA_BUS_TYPE_ISA 0
74#define MOXA_BUS_TYPE_PCI 1
75
76#ifndef PCI_VENDOR_ID_MOXA
77#define PCI_VENDOR_ID_MOXA 0x1393
78#endif
79#ifndef PCI_DEVICE_ID_CP204J
80#define PCI_DEVICE_ID_CP204J 0x2040
81#endif
82#ifndef PCI_DEVICE_ID_C218
83#define PCI_DEVICE_ID_C218 0x2180
84#endif
85#ifndef PCI_DEVICE_ID_C320
86#define PCI_DEVICE_ID_C320 0x3200
87#endif
88
89enum {
90 MOXA_BOARD_C218_PCI = 1,
91 MOXA_BOARD_C218_ISA,
92 MOXA_BOARD_C320_PCI,
93 MOXA_BOARD_C320_ISA,
94 MOXA_BOARD_CP204J,
95};
96
97static char *moxa_brdname[] =
98{
99 "C218 Turbo PCI series",
100 "C218 Turbo ISA series",
101 "C320 Turbo PCI series",
102 "C320 Turbo ISA series",
103 "CP-204J series",
104};
105
106#ifdef CONFIG_PCI
107static struct pci_device_id moxa_pcibrds[] = {
108 { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID,
109 0, 0, MOXA_BOARD_C218_PCI },
110 { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C320, PCI_ANY_ID, PCI_ANY_ID,
111 0, 0, MOXA_BOARD_C320_PCI },
112 { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP204J, PCI_ANY_ID, PCI_ANY_ID,
113 0, 0, MOXA_BOARD_CP204J },
114 { 0 }
115};
116MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
117#endif /* CONFIG_PCI */
118
119typedef struct _moxa_isa_board_conf {
120 int boardType;
121 int numPorts;
122 unsigned long baseAddr;
123} moxa_isa_board_conf;
124
125static moxa_isa_board_conf moxa_isa_boards[] =
126{
127/* {MOXA_BOARD_C218_ISA,8,0xDC000}, */
128};
129
130typedef struct _moxa_pci_devinfo {
131 ushort busNum;
132 ushort devNum;
Jiri Slaby86fbf142006-10-21 10:24:01 -0700133 struct pci_dev *pdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134} moxa_pci_devinfo;
135
136typedef struct _moxa_board_conf {
137 int boardType;
138 int numPorts;
139 unsigned long baseAddr;
140 int busType;
141 moxa_pci_devinfo pciInfo;
142} moxa_board_conf;
143
144static moxa_board_conf moxa_boards[MAX_BOARDS];
145static void __iomem *moxaBaseAddr[MAX_BOARDS];
Dirk Eibach01cfaf02006-08-27 01:23:36 -0700146static int loadstat[MAX_BOARDS];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
148struct moxa_str {
149 int type;
150 int port;
151 int close_delay;
152 unsigned short closing_wait;
153 int count;
154 int blocked_open;
155 long event; /* long req'd for set_bit --RR */
156 int asyncflags;
157 unsigned long statusflags;
158 struct tty_struct *tty;
159 int cflag;
160 wait_queue_head_t open_wait;
161 wait_queue_head_t close_wait;
162 struct work_struct tqueue;
163};
164
165struct mxser_mstatus {
166 tcflag_t cflag;
167 int cts;
168 int dsr;
169 int ri;
170 int dcd;
171};
172
173static struct mxser_mstatus GMStatus[MAX_PORTS];
174
175/* statusflags */
176#define TXSTOPPED 0x1
177#define LOWWAIT 0x2
178#define EMPTYWAIT 0x4
179#define THROTTLE 0x8
180
181/* event */
182#define MOXA_EVENT_HANGUP 1
183
184#define SERIAL_DO_RESTART
185
186
187#define SERIAL_TYPE_NORMAL 1
188
189#define WAKEUP_CHARS 256
190
191#define PORTNO(x) ((x)->index)
192
193static int verbose = 0;
194static int ttymajor = MOXAMAJOR;
195/* Variables for insmod */
196#ifdef MODULE
Jiri Slaby9fa372a2007-02-10 01:45:26 -0800197static int baseaddr[4];
198static int type[4];
199static int numports[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200#endif
201
202MODULE_AUTHOR("William Chen");
203MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
204MODULE_LICENSE("GPL");
205#ifdef MODULE
206module_param_array(type, int, NULL, 0);
207module_param_array(baseaddr, int, NULL, 0);
208module_param_array(numports, int, NULL, 0);
209#endif
210module_param(ttymajor, int, 0);
211module_param(verbose, bool, 0644);
212
213static struct tty_driver *moxaDriver;
214static struct moxa_str moxaChannels[MAX_PORTS];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215static int moxaTimer_on;
216static struct timer_list moxaTimer;
217static int moxaEmptyTimer_on[MAX_PORTS];
218static struct timer_list moxaEmptyTimer[MAX_PORTS];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
220/*
221 * static functions:
222 */
David Howellsc4028952006-11-22 14:57:56 +0000223static void do_moxa_softint(struct work_struct *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224static int moxa_open(struct tty_struct *, struct file *);
225static void moxa_close(struct tty_struct *, struct file *);
226static int moxa_write(struct tty_struct *, const unsigned char *, int);
227static int moxa_write_room(struct tty_struct *);
228static void moxa_flush_buffer(struct tty_struct *);
229static int moxa_chars_in_buffer(struct tty_struct *);
230static void moxa_flush_chars(struct tty_struct *);
231static void moxa_put_char(struct tty_struct *, unsigned char);
232static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
233static void moxa_throttle(struct tty_struct *);
234static void moxa_unthrottle(struct tty_struct *);
Alan Cox606d0992006-12-08 02:38:45 -0800235static void moxa_set_termios(struct tty_struct *, struct ktermios *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236static void moxa_stop(struct tty_struct *);
237static void moxa_start(struct tty_struct *);
238static void moxa_hangup(struct tty_struct *);
239static int moxa_tiocmget(struct tty_struct *tty, struct file *file);
240static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
241 unsigned int set, unsigned int clear);
242static void moxa_poll(unsigned long);
243static void set_tty_param(struct tty_struct *);
244static int block_till_ready(struct tty_struct *, struct file *,
245 struct moxa_str *);
246static void setup_empty_event(struct tty_struct *);
247static void check_xmit_empty(unsigned long);
248static void shut_down(struct moxa_str *);
249static void receive_data(struct moxa_str *);
250/*
251 * moxa board interface functions:
252 */
253static void MoxaDriverInit(void);
254static int MoxaDriverIoctl(unsigned int, unsigned long, int);
255static int MoxaDriverPoll(void);
256static int MoxaPortsOfCard(int);
257static int MoxaPortIsValid(int);
258static void MoxaPortEnable(int);
259static void MoxaPortDisable(int);
260static long MoxaPortGetMaxBaud(int);
261static long MoxaPortSetBaud(int, long);
Alan Cox606d0992006-12-08 02:38:45 -0800262static int MoxaPortSetTermio(int, struct ktermios *, speed_t);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263static int MoxaPortGetLineOut(int, int *, int *);
264static void MoxaPortLineCtrl(int, int, int);
265static void MoxaPortFlowCtrl(int, int, int, int, int, int);
266static int MoxaPortLineStatus(int);
267static int MoxaPortDCDChange(int);
268static int MoxaPortDCDON(int);
269static void MoxaPortFlushData(int, int);
270static int MoxaPortWriteData(int, unsigned char *, int);
Alan Cox33f0f882006-01-09 20:54:13 -0800271static int MoxaPortReadData(int, struct tty_struct *tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272static int MoxaPortTxQueue(int);
273static int MoxaPortRxQueue(int);
274static int MoxaPortTxFree(int);
275static void MoxaPortTxDisable(int);
276static void MoxaPortTxEnable(int);
277static int MoxaPortResetBrkCnt(int);
278static void MoxaPortSendBreak(int, int);
279static int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *);
280static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);
281static void MoxaSetFifo(int port, int enable);
282
Jeff Dikeb68e31d2006-10-02 02:17:18 -0700283static const struct tty_operations moxa_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 .open = moxa_open,
285 .close = moxa_close,
286 .write = moxa_write,
287 .write_room = moxa_write_room,
288 .flush_buffer = moxa_flush_buffer,
289 .chars_in_buffer = moxa_chars_in_buffer,
290 .flush_chars = moxa_flush_chars,
291 .put_char = moxa_put_char,
292 .ioctl = moxa_ioctl,
293 .throttle = moxa_throttle,
294 .unthrottle = moxa_unthrottle,
295 .set_termios = moxa_set_termios,
296 .stop = moxa_stop,
297 .start = moxa_start,
298 .hangup = moxa_hangup,
299 .tiocmget = moxa_tiocmget,
300 .tiocmset = moxa_tiocmset,
301};
302
Ingo Molnar34af9462006-06-27 02:53:55 -0700303static DEFINE_SPINLOCK(moxa_lock);
Alan Cox33f0f882006-01-09 20:54:13 -0800304
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305#ifdef CONFIG_PCI
306static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board)
307{
308 board->baseAddr = pci_resource_start (p, 2);
309 board->boardType = board_type;
310 switch (board_type) {
311 case MOXA_BOARD_C218_ISA:
312 case MOXA_BOARD_C218_PCI:
313 board->numPorts = 8;
314 break;
315
316 case MOXA_BOARD_CP204J:
317 board->numPorts = 4;
318 break;
319 default:
320 board->numPorts = 0;
321 break;
322 }
323 board->busType = MOXA_BUS_TYPE_PCI;
324 board->pciInfo.busNum = p->bus->number;
325 board->pciInfo.devNum = p->devfn >> 3;
Jiri Slaby86fbf142006-10-21 10:24:01 -0700326 board->pciInfo.pdev = p;
327 /* don't lose the reference in the next pci_get_device iteration */
328 pci_dev_get(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329
330 return (0);
331}
332#endif /* CONFIG_PCI */
333
334static int __init moxa_init(void)
335{
336 int i, numBoards;
337 struct moxa_str *ch;
338
339 printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
340 moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
341 if (!moxaDriver)
342 return -ENOMEM;
343
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 moxaDriver->owner = THIS_MODULE;
Sergey Vlasov9b4e3b12005-09-03 16:26:49 +0100345 moxaDriver->name = "ttyMX";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 moxaDriver->major = ttymajor;
347 moxaDriver->minor_start = 0;
348 moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;
349 moxaDriver->subtype = SERIAL_TYPE_NORMAL;
350 moxaDriver->init_termios = tty_std_termios;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
Alan Cox606d0992006-12-08 02:38:45 -0800352 moxaDriver->init_termios.c_ispeed = 9600;
353 moxaDriver->init_termios.c_ospeed = 9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 moxaDriver->flags = TTY_DRIVER_REAL_RAW;
355 tty_set_operations(moxaDriver, &moxa_ops);
356
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {
358 ch->type = PORT_16550A;
359 ch->port = i;
David Howellsc4028952006-11-22 14:57:56 +0000360 INIT_WORK(&ch->tqueue, do_moxa_softint);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 ch->close_delay = 5 * HZ / 10;
362 ch->closing_wait = 30 * HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
364 init_waitqueue_head(&ch->open_wait);
365 init_waitqueue_head(&ch->close_wait);
366 }
367
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 printk("Tty devices major number = %d\n", ttymajor);
369
370 if (tty_register_driver(moxaDriver)) {
371 printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
372 put_tty_driver(moxaDriver);
373 return -1;
374 }
375 for (i = 0; i < MAX_PORTS; i++) {
376 init_timer(&moxaEmptyTimer[i]);
377 moxaEmptyTimer[i].function = check_xmit_empty;
378 moxaEmptyTimer[i].data = (unsigned long) & moxaChannels[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 }
380
381 init_timer(&moxaTimer);
382 moxaTimer.function = moxa_poll;
383 moxaTimer.expires = jiffies + (HZ / 50);
384 moxaTimer_on = 1;
385 add_timer(&moxaTimer);
386
387 /* Find the boards defined in source code */
388 numBoards = 0;
389 for (i = 0; i < MAX_BOARDS; i++) {
390 if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) ||
391 (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) {
392 moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType;
393 if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
394 moxa_boards[numBoards].numPorts = 8;
395 else
396 moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;
397 moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
398 moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;
399 if (verbose)
400 printk("Board %2d: %s board(baseAddr=%lx)\n",
401 numBoards + 1,
402 moxa_brdname[moxa_boards[numBoards].boardType - 1],
403 moxa_boards[numBoards].baseAddr);
404 numBoards++;
405 }
406 }
407 /* Find the boards defined form module args. */
408#ifdef MODULE
409 for (i = 0; i < MAX_BOARDS; i++) {
410 if ((type[i] == MOXA_BOARD_C218_ISA) ||
411 (type[i] == MOXA_BOARD_C320_ISA)) {
412 if (verbose)
413 printk("Board %2d: %s board(baseAddr=%lx)\n",
414 numBoards + 1,
415 moxa_brdname[type[i] - 1],
416 (unsigned long) baseaddr[i]);
417 if (numBoards >= MAX_BOARDS) {
418 if (verbose)
419 printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
420 continue;
421 }
422 moxa_boards[numBoards].boardType = type[i];
423 if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
424 moxa_boards[numBoards].numPorts = 8;
425 else
426 moxa_boards[numBoards].numPorts = numports[i];
427 moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
428 moxa_boards[numBoards].baseAddr = baseaddr[i];
429 numBoards++;
430 }
431 }
432#endif
433 /* Find PCI boards here */
434#ifdef CONFIG_PCI
435 {
436 struct pci_dev *p = NULL;
Tobias Klauserfe971072006-01-09 20:54:02 -0800437 int n = ARRAY_SIZE(moxa_pcibrds) - 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 i = 0;
439 while (i < n) {
Amit Gud881a8c12005-04-12 19:03:33 +0530440 while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 {
442 if (pci_enable_device(p))
443 continue;
444 if (numBoards >= MAX_BOARDS) {
445 if (verbose)
446 printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
447 } else {
448 moxa_get_PCI_conf(p, moxa_pcibrds[i].driver_data,
449 &moxa_boards[numBoards]);
450 numBoards++;
451 }
452 }
453 i++;
454 }
455 }
456#endif
457 for (i = 0; i < numBoards; i++) {
458 moxaBaseAddr[i] = ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000);
459 }
460
461 return (0);
462}
463
464static void __exit moxa_exit(void)
465{
466 int i;
467
468 if (verbose)
469 printk("Unloading module moxa ...\n");
470
471 if (moxaTimer_on)
472 del_timer(&moxaTimer);
473
474 for (i = 0; i < MAX_PORTS; i++)
475 if (moxaEmptyTimer_on[i])
476 del_timer(&moxaEmptyTimer[i]);
477
478 if (tty_unregister_driver(moxaDriver))
479 printk("Couldn't unregister MOXA Intellio family serial driver\n");
480 put_tty_driver(moxaDriver);
Jiri Slaby86fbf142006-10-21 10:24:01 -0700481
Amol Lad41bdabb2006-12-06 20:35:21 -0800482 for (i = 0; i < MAX_BOARDS; i++) {
483 if (moxaBaseAddr[i])
484 iounmap(moxaBaseAddr[i]);
Jiri Slaby86fbf142006-10-21 10:24:01 -0700485 if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
486 pci_dev_put(moxa_boards[i].pciInfo.pdev);
Amol Lad41bdabb2006-12-06 20:35:21 -0800487 }
Jiri Slaby86fbf142006-10-21 10:24:01 -0700488
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 if (verbose)
490 printk("Done\n");
491}
492
493module_init(moxa_init);
494module_exit(moxa_exit);
495
David Howellsc4028952006-11-22 14:57:56 +0000496static void do_moxa_softint(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497{
David Howellsc4028952006-11-22 14:57:56 +0000498 struct moxa_str *ch = container_of(work, struct moxa_str, tqueue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 struct tty_struct *tty;
500
501 if (ch && (tty = ch->tty)) {
502 if (test_and_clear_bit(MOXA_EVENT_HANGUP, &ch->event)) {
503 tty_hangup(tty); /* FIXME: module removal race here - AKPM */
504 wake_up_interruptible(&ch->open_wait);
505 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
506 }
507 }
508}
509
510static int moxa_open(struct tty_struct *tty, struct file *filp)
511{
512 struct moxa_str *ch;
513 int port;
514 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515
516 port = PORTNO(tty);
517 if (port == MAX_PORTS) {
518 return (0);
519 }
520 if (!MoxaPortIsValid(port)) {
521 tty->driver_data = NULL;
522 return (-ENODEV);
523 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
525 ch = &moxaChannels[port];
526 ch->count++;
527 tty->driver_data = ch;
528 ch->tty = tty;
529 if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
530 ch->statusflags = 0;
531 set_tty_param(tty);
532 MoxaPortLineCtrl(ch->port, 1, 1);
533 MoxaPortEnable(ch->port);
534 ch->asyncflags |= ASYNC_INITIALIZED;
535 }
536 retval = block_till_ready(tty, filp, ch);
537
538 moxa_unthrottle(tty);
539
540 if (ch->type == PORT_16550A) {
541 MoxaSetFifo(ch->port, 1);
542 } else {
543 MoxaSetFifo(ch->port, 0);
544 }
545
546 return (retval);
547}
548
549static void moxa_close(struct tty_struct *tty, struct file *filp)
550{
551 struct moxa_str *ch;
552 int port;
553
554 port = PORTNO(tty);
555 if (port == MAX_PORTS) {
556 return;
557 }
558 if (!MoxaPortIsValid(port)) {
559#ifdef SERIAL_DEBUG_CLOSE
560 printk("Invalid portno in moxa_close\n");
561#endif
562 tty->driver_data = NULL;
563 return;
564 }
565 if (tty->driver_data == NULL) {
566 return;
567 }
568 if (tty_hung_up_p(filp)) {
569 return;
570 }
571 ch = (struct moxa_str *) tty->driver_data;
572
573 if ((tty->count == 1) && (ch->count != 1)) {
574 printk("moxa_close: bad serial port count; tty->count is 1, "
575 "ch->count is %d\n", ch->count);
576 ch->count = 1;
577 }
578 if (--ch->count < 0) {
579 printk("moxa_close: bad serial port count, device=%s\n",
580 tty->name);
581 ch->count = 0;
582 }
583 if (ch->count) {
584 return;
585 }
586 ch->asyncflags |= ASYNC_CLOSING;
587
588 ch->cflag = tty->termios->c_cflag;
589 if (ch->asyncflags & ASYNC_INITIALIZED) {
590 setup_empty_event(tty);
591 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
592 moxaEmptyTimer_on[ch->port] = 0;
593 del_timer(&moxaEmptyTimer[ch->port]);
594 }
595 shut_down(ch);
596 MoxaPortFlushData(port, 2);
597
598 if (tty->driver->flush_buffer)
599 tty->driver->flush_buffer(tty);
600 tty_ldisc_flush(tty);
601
602 tty->closing = 0;
603 ch->event = 0;
604 ch->tty = NULL;
605 if (ch->blocked_open) {
606 if (ch->close_delay) {
607 msleep_interruptible(jiffies_to_msecs(ch->close_delay));
608 }
609 wake_up_interruptible(&ch->open_wait);
610 }
611 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
612 wake_up_interruptible(&ch->close_wait);
613}
614
615static int moxa_write(struct tty_struct *tty,
616 const unsigned char *buf, int count)
617{
618 struct moxa_str *ch;
619 int len, port;
620 unsigned long flags;
621
622 ch = (struct moxa_str *) tty->driver_data;
623 if (ch == NULL)
624 return (0);
625 port = ch->port;
Alan Cox33f0f882006-01-09 20:54:13 -0800626
627 spin_lock_irqsave(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 len = MoxaPortWriteData(port, (unsigned char *) buf, count);
Alan Cox33f0f882006-01-09 20:54:13 -0800629 spin_unlock_irqrestore(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
631 /*********************************************
632 if ( !(ch->statusflags & LOWWAIT) &&
633 ((len != count) || (MoxaPortTxFree(port) <= 100)) )
634 ************************************************/
635 ch->statusflags |= LOWWAIT;
636 return (len);
637}
638
639static int moxa_write_room(struct tty_struct *tty)
640{
641 struct moxa_str *ch;
642
643 if (tty->stopped)
644 return (0);
645 ch = (struct moxa_str *) tty->driver_data;
646 if (ch == NULL)
647 return (0);
648 return (MoxaPortTxFree(ch->port));
649}
650
651static void moxa_flush_buffer(struct tty_struct *tty)
652{
653 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
654
655 if (ch == NULL)
656 return;
657 MoxaPortFlushData(ch->port, 1);
658 tty_wakeup(tty);
659}
660
661static int moxa_chars_in_buffer(struct tty_struct *tty)
662{
663 int chars;
664 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
665
666 /*
667 * Sigh...I have to check if driver_data is NULL here, because
668 * if an open() fails, the TTY subsystem eventually calls
669 * tty_wait_until_sent(), which calls the driver's chars_in_buffer()
670 * routine. And since the open() failed, we return 0 here. TDJ
671 */
672 if (ch == NULL)
673 return (0);
674 chars = MoxaPortTxQueue(ch->port);
675 if (chars) {
676 /*
677 * Make it possible to wakeup anything waiting for output
678 * in tty_ioctl.c, etc.
679 */
680 if (!(ch->statusflags & EMPTYWAIT))
681 setup_empty_event(tty);
682 }
683 return (chars);
684}
685
686static void moxa_flush_chars(struct tty_struct *tty)
687{
688 /*
689 * Don't think I need this, because this is called to empty the TX
690 * buffer for the 16450, 16550, etc.
691 */
692}
693
694static void moxa_put_char(struct tty_struct *tty, unsigned char c)
695{
696 struct moxa_str *ch;
697 int port;
698 unsigned long flags;
699
700 ch = (struct moxa_str *) tty->driver_data;
701 if (ch == NULL)
702 return;
703 port = ch->port;
Alan Cox33f0f882006-01-09 20:54:13 -0800704 spin_lock_irqsave(&moxa_lock, flags);
Jiri Slabyf204d262007-02-10 01:45:25 -0800705 MoxaPortWriteData(port, &c, 1);
Alan Cox33f0f882006-01-09 20:54:13 -0800706 spin_unlock_irqrestore(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 /************************************************
708 if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
709 *************************************************/
710 ch->statusflags |= LOWWAIT;
711}
712
713static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
714{
715 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
716 int port;
717 int flag = 0, dtr, rts;
718
719 port = PORTNO(tty);
720 if ((port != MAX_PORTS) && (!ch))
721 return (-EINVAL);
722
723 MoxaPortGetLineOut(ch->port, &dtr, &rts);
724 if (dtr)
725 flag |= TIOCM_DTR;
726 if (rts)
727 flag |= TIOCM_RTS;
728 dtr = MoxaPortLineStatus(ch->port);
729 if (dtr & 1)
730 flag |= TIOCM_CTS;
731 if (dtr & 2)
732 flag |= TIOCM_DSR;
733 if (dtr & 4)
734 flag |= TIOCM_CD;
735 return flag;
736}
737
738static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
739 unsigned int set, unsigned int clear)
740{
741 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
742 int port;
743 int dtr, rts;
744
745 port = PORTNO(tty);
746 if ((port != MAX_PORTS) && (!ch))
747 return (-EINVAL);
748
749 MoxaPortGetLineOut(ch->port, &dtr, &rts);
750 if (set & TIOCM_RTS)
751 rts = 1;
752 if (set & TIOCM_DTR)
753 dtr = 1;
754 if (clear & TIOCM_RTS)
755 rts = 0;
756 if (clear & TIOCM_DTR)
757 dtr = 0;
758 MoxaPortLineCtrl(ch->port, dtr, rts);
759 return 0;
760}
761
762static int moxa_ioctl(struct tty_struct *tty, struct file *file,
763 unsigned int cmd, unsigned long arg)
764{
765 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
766 register int port;
767 void __user *argp = (void __user *)arg;
768 int retval;
769
770 port = PORTNO(tty);
771 if ((port != MAX_PORTS) && (!ch))
772 return (-EINVAL);
773
774 switch (cmd) {
775 case TCSBRK: /* SVID version: non-zero arg --> no break */
776 retval = tty_check_change(tty);
777 if (retval)
778 return (retval);
779 setup_empty_event(tty);
780 tty_wait_until_sent(tty, 0);
781 if (!arg)
782 MoxaPortSendBreak(ch->port, 0);
783 return (0);
784 case TCSBRKP: /* support for POSIX tcsendbreak() */
785 retval = tty_check_change(tty);
786 if (retval)
787 return (retval);
788 setup_empty_event(tty);
789 tty_wait_until_sent(tty, 0);
790 MoxaPortSendBreak(ch->port, arg);
791 return (0);
792 case TIOCGSOFTCAR:
793 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
794 case TIOCSSOFTCAR:
795 if(get_user(retval, (unsigned long __user *) argp))
796 return -EFAULT;
797 arg = retval;
798 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
799 (arg ? CLOCAL : 0));
800 if (C_CLOCAL(tty))
801 ch->asyncflags &= ~ASYNC_CHECK_CD;
802 else
803 ch->asyncflags |= ASYNC_CHECK_CD;
804 return (0);
805 case TIOCGSERIAL:
806 return moxa_get_serial_info(ch, argp);
807
808 case TIOCSSERIAL:
809 return moxa_set_serial_info(ch, argp);
810 default:
811 retval = MoxaDriverIoctl(cmd, arg, port);
812 }
813 return (retval);
814}
815
816static void moxa_throttle(struct tty_struct *tty)
817{
818 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
819
820 ch->statusflags |= THROTTLE;
821}
822
823static void moxa_unthrottle(struct tty_struct *tty)
824{
825 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
826
827 ch->statusflags &= ~THROTTLE;
828}
829
830static void moxa_set_termios(struct tty_struct *tty,
Alan Cox606d0992006-12-08 02:38:45 -0800831 struct ktermios *old_termios)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832{
833 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
834
835 if (ch == NULL)
836 return;
837 set_tty_param(tty);
838 if (!(old_termios->c_cflag & CLOCAL) &&
839 (tty->termios->c_cflag & CLOCAL))
840 wake_up_interruptible(&ch->open_wait);
841}
842
843static void moxa_stop(struct tty_struct *tty)
844{
845 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
846
847 if (ch == NULL)
848 return;
849 MoxaPortTxDisable(ch->port);
850 ch->statusflags |= TXSTOPPED;
851}
852
853
854static void moxa_start(struct tty_struct *tty)
855{
856 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
857
858 if (ch == NULL)
859 return;
860
861 if (!(ch->statusflags & TXSTOPPED))
862 return;
863
864 MoxaPortTxEnable(ch->port);
865 ch->statusflags &= ~TXSTOPPED;
866}
867
868static void moxa_hangup(struct tty_struct *tty)
869{
870 struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
871
872 moxa_flush_buffer(tty);
873 shut_down(ch);
874 ch->event = 0;
875 ch->count = 0;
876 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
877 ch->tty = NULL;
878 wake_up_interruptible(&ch->open_wait);
879}
880
881static void moxa_poll(unsigned long ignored)
882{
883 register int card;
884 struct moxa_str *ch;
885 struct tty_struct *tp;
886 int i, ports;
887
888 moxaTimer_on = 0;
889 del_timer(&moxaTimer);
890
891 if (MoxaDriverPoll() < 0) {
892 moxaTimer.function = moxa_poll;
893 moxaTimer.expires = jiffies + (HZ / 50);
894 moxaTimer_on = 1;
895 add_timer(&moxaTimer);
896 return;
897 }
898 for (card = 0; card < MAX_BOARDS; card++) {
899 if ((ports = MoxaPortsOfCard(card)) <= 0)
900 continue;
901 ch = &moxaChannels[card * MAX_PORTS_PER_BOARD];
902 for (i = 0; i < ports; i++, ch++) {
903 if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
904 continue;
905 if (!(ch->statusflags & THROTTLE) &&
906 (MoxaPortRxQueue(ch->port) > 0))
907 receive_data(ch);
908 if ((tp = ch->tty) == 0)
909 continue;
910 if (ch->statusflags & LOWWAIT) {
911 if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {
912 if (!tp->stopped) {
913 ch->statusflags &= ~LOWWAIT;
914 tty_wakeup(tp);
915 }
916 }
917 }
918 if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) {
919 tty_insert_flip_char(tp, 0, TTY_BREAK);
920 tty_schedule_flip(tp);
921 }
922 if (MoxaPortDCDChange(ch->port)) {
923 if (ch->asyncflags & ASYNC_CHECK_CD) {
924 if (MoxaPortDCDON(ch->port))
925 wake_up_interruptible(&ch->open_wait);
926 else {
927 set_bit(MOXA_EVENT_HANGUP, &ch->event);
928 schedule_work(&ch->tqueue);
929 }
930 }
931 }
932 }
933 }
934
935 moxaTimer.function = moxa_poll;
936 moxaTimer.expires = jiffies + (HZ / 50);
937 moxaTimer_on = 1;
938 add_timer(&moxaTimer);
939}
940
941/******************************************************************************/
942
943static void set_tty_param(struct tty_struct *tty)
944{
Alan Cox606d0992006-12-08 02:38:45 -0800945 register struct ktermios *ts;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 struct moxa_str *ch;
947 int rts, cts, txflow, rxflow, xany;
948
949 ch = (struct moxa_str *) tty->driver_data;
950 ts = tty->termios;
951 if (ts->c_cflag & CLOCAL)
952 ch->asyncflags &= ~ASYNC_CHECK_CD;
953 else
954 ch->asyncflags |= ASYNC_CHECK_CD;
955 rts = cts = txflow = rxflow = xany = 0;
956 if (ts->c_cflag & CRTSCTS)
957 rts = cts = 1;
958 if (ts->c_iflag & IXON)
959 txflow = 1;
960 if (ts->c_iflag & IXOFF)
961 rxflow = 1;
962 if (ts->c_iflag & IXANY)
963 xany = 1;
964 MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany);
Alan Coxc7bce302006-09-30 23:27:24 -0700965 MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966}
967
968static int block_till_ready(struct tty_struct *tty, struct file *filp,
969 struct moxa_str *ch)
970{
971 DECLARE_WAITQUEUE(wait,current);
972 unsigned long flags;
973 int retval;
974 int do_clocal = C_CLOCAL(tty);
975
976 /*
977 * If the device is in the middle of being closed, then block
978 * until it's done, and then try again.
979 */
980 if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
981 if (ch->asyncflags & ASYNC_CLOSING)
982 interruptible_sleep_on(&ch->close_wait);
983#ifdef SERIAL_DO_RESTART
984 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
985 return (-EAGAIN);
986 else
987 return (-ERESTARTSYS);
988#else
989 return (-EAGAIN);
990#endif
991 }
992 /*
993 * If non-blocking mode is set, then make the check up front
994 * and then exit.
995 */
996 if (filp->f_flags & O_NONBLOCK) {
997 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
998 return (0);
999 }
1000 /*
1001 * Block waiting for the carrier detect and the line to become free
1002 */
1003 retval = 0;
1004 add_wait_queue(&ch->open_wait, &wait);
1005#ifdef SERIAL_DEBUG_OPEN
1006 printk("block_til_ready before block: ttys%d, count = %d\n",
1007 ch->line, ch->count);
1008#endif
Alan Cox33f0f882006-01-09 20:54:13 -08001009 spin_lock_irqsave(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 if (!tty_hung_up_p(filp))
1011 ch->count--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 ch->blocked_open++;
Alan Cox33f0f882006-01-09 20:54:13 -08001013 spin_unlock_irqrestore(&moxa_lock, flags);
1014
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 while (1) {
1016 set_current_state(TASK_INTERRUPTIBLE);
1017 if (tty_hung_up_p(filp) ||
1018 !(ch->asyncflags & ASYNC_INITIALIZED)) {
1019#ifdef SERIAL_DO_RESTART
1020 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1021 retval = -EAGAIN;
1022 else
1023 retval = -ERESTARTSYS;
1024#else
1025 retval = -EAGAIN;
1026#endif
1027 break;
1028 }
1029 if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
1030 MoxaPortDCDON(ch->port)))
1031 break;
1032
1033 if (signal_pending(current)) {
1034 retval = -ERESTARTSYS;
1035 break;
1036 }
1037 schedule();
1038 }
1039 set_current_state(TASK_RUNNING);
1040 remove_wait_queue(&ch->open_wait, &wait);
Alan Cox33f0f882006-01-09 20:54:13 -08001041
1042 spin_lock_irqsave(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043 if (!tty_hung_up_p(filp))
1044 ch->count++;
1045 ch->blocked_open--;
Alan Cox33f0f882006-01-09 20:54:13 -08001046 spin_unlock_irqrestore(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047#ifdef SERIAL_DEBUG_OPEN
1048 printk("block_til_ready after blocking: ttys%d, count = %d\n",
1049 ch->line, ch->count);
1050#endif
1051 if (retval)
1052 return (retval);
Alan Cox33f0f882006-01-09 20:54:13 -08001053 /* FIXME: review to see if we need to use set_bit on these */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
Alan Cox33f0f882006-01-09 20:54:13 -08001055 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056}
1057
1058static void setup_empty_event(struct tty_struct *tty)
1059{
1060 struct moxa_str *ch = tty->driver_data;
1061 unsigned long flags;
1062
Alan Cox33f0f882006-01-09 20:54:13 -08001063 spin_lock_irqsave(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 ch->statusflags |= EMPTYWAIT;
1065 moxaEmptyTimer_on[ch->port] = 0;
1066 del_timer(&moxaEmptyTimer[ch->port]);
1067 moxaEmptyTimer[ch->port].expires = jiffies + HZ;
1068 moxaEmptyTimer_on[ch->port] = 1;
1069 add_timer(&moxaEmptyTimer[ch->port]);
Alan Cox33f0f882006-01-09 20:54:13 -08001070 spin_unlock_irqrestore(&moxa_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071}
1072
1073static void check_xmit_empty(unsigned long data)
1074{
1075 struct moxa_str *ch;
1076
1077 ch = (struct moxa_str *) data;
1078 moxaEmptyTimer_on[ch->port] = 0;
1079 del_timer(&moxaEmptyTimer[ch->port]);
1080 if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
1081 if (MoxaPortTxQueue(ch->port) == 0) {
1082 ch->statusflags &= ~EMPTYWAIT;
1083 tty_wakeup(ch->tty);
1084 return;
1085 }
1086 moxaEmptyTimer[ch->port].expires = jiffies + HZ;
1087 moxaEmptyTimer_on[ch->port] = 1;
1088 add_timer(&moxaEmptyTimer[ch->port]);
1089 } else
1090 ch->statusflags &= ~EMPTYWAIT;
1091}
1092
1093static void shut_down(struct moxa_str *ch)
1094{
1095 struct tty_struct *tp;
1096
1097 if (!(ch->asyncflags & ASYNC_INITIALIZED))
1098 return;
1099
1100 tp = ch->tty;
1101
1102 MoxaPortDisable(ch->port);
1103
1104 /*
1105 * If we're a modem control device and HUPCL is on, drop RTS & DTR.
1106 */
1107 if (tp->termios->c_cflag & HUPCL)
1108 MoxaPortLineCtrl(ch->port, 0, 0);
1109
1110 ch->asyncflags &= ~ASYNC_INITIALIZED;
1111}
1112
1113static void receive_data(struct moxa_str *ch)
1114{
1115 struct tty_struct *tp;
Alan Cox606d0992006-12-08 02:38:45 -08001116 struct ktermios *ts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 unsigned long flags;
1118
1119 ts = NULL;
1120 tp = ch->tty;
1121 if (tp)
1122 ts = tp->termios;
1123 /**************************************************
1124 if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
1125 *****************************************************/
1126 if (!tp || !ts) {
1127 MoxaPortFlushData(ch->port, 0);
1128 return;
1129 }
Alan Cox33f0f882006-01-09 20:54:13 -08001130 spin_lock_irqsave(&moxa_lock, flags);
1131 MoxaPortReadData(ch->port, tp);
1132 spin_unlock_irqrestore(&moxa_lock, flags);
1133 tty_schedule_flip(tp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134}
1135
1136#define Magic_code 0x404
1137
1138/*
1139 * System Configuration
1140 */
1141/*
1142 * for C218 BIOS initialization
1143 */
1144#define C218_ConfBase 0x800
1145#define C218_status (C218_ConfBase + 0) /* BIOS running status */
1146#define C218_diag (C218_ConfBase + 2) /* diagnostic status */
1147#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */
1148#define C218DLoad_len (C218_ConfBase + 6) /* WORD */
1149#define C218check_sum (C218_ConfBase + 8) /* BYTE */
1150#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */
1151#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */
1152#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */
1153#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */
1154#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */
1155
1156#define C218_LoadBuf 0x0F00
1157#define C218_KeyCode 0x218
1158#define CP204J_KeyCode 0x204
1159
1160/*
1161 * for C320 BIOS initialization
1162 */
1163#define C320_ConfBase 0x800
1164#define C320_LoadBuf 0x0f00
1165#define STS_init 0x05 /* for C320_status */
1166
1167#define C320_status C320_ConfBase + 0 /* BIOS running status */
1168#define C320_diag C320_ConfBase + 2 /* diagnostic status */
1169#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */
1170#define C320DLoad_len C320_ConfBase + 6 /* WORD */
1171#define C320check_sum C320_ConfBase + 8 /* WORD */
1172#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */
1173#define C320bapi_len C320_ConfBase + 0x0c /* WORD */
1174#define C320UART_no C320_ConfBase + 0x0e /* WORD */
1175
1176#define C320_KeyCode 0x320
1177
1178#define FixPage_addr 0x0000 /* starting addr of static page */
1179#define DynPage_addr 0x2000 /* starting addr of dynamic page */
1180#define C218_start 0x3000 /* starting addr of C218 BIOS prg */
1181#define Control_reg 0x1ff0 /* select page and reset control */
1182#define HW_reset 0x80
1183
1184/*
1185 * Function Codes
1186 */
1187#define FC_CardReset 0x80
1188#define FC_ChannelReset 1 /* C320 firmware not supported */
1189#define FC_EnableCH 2
1190#define FC_DisableCH 3
1191#define FC_SetParam 4
1192#define FC_SetMode 5
1193#define FC_SetRate 6
1194#define FC_LineControl 7
1195#define FC_LineStatus 8
1196#define FC_XmitControl 9
1197#define FC_FlushQueue 10
1198#define FC_SendBreak 11
1199#define FC_StopBreak 12
1200#define FC_LoopbackON 13
1201#define FC_LoopbackOFF 14
1202#define FC_ClrIrqTable 15
1203#define FC_SendXon 16
1204#define FC_SetTermIrq 17 /* C320 firmware not supported */
1205#define FC_SetCntIrq 18 /* C320 firmware not supported */
1206#define FC_SetBreakIrq 19
1207#define FC_SetLineIrq 20
1208#define FC_SetFlowCtl 21
1209#define FC_GenIrq 22
1210#define FC_InCD180 23
1211#define FC_OutCD180 24
1212#define FC_InUARTreg 23
1213#define FC_OutUARTreg 24
1214#define FC_SetXonXoff 25
1215#define FC_OutCD180CCR 26
1216#define FC_ExtIQueue 27
1217#define FC_ExtOQueue 28
1218#define FC_ClrLineIrq 29
1219#define FC_HWFlowCtl 30
1220#define FC_GetClockRate 35
1221#define FC_SetBaud 36
1222#define FC_SetDataMode 41
1223#define FC_GetCCSR 43
1224#define FC_GetDataError 45
1225#define FC_RxControl 50
1226#define FC_ImmSend 51
1227#define FC_SetXonState 52
1228#define FC_SetXoffState 53
1229#define FC_SetRxFIFOTrig 54
1230#define FC_SetTxFIFOCnt 55
1231#define FC_UnixRate 56
1232#define FC_UnixResetTimer 57
1233
1234#define RxFIFOTrig1 0
1235#define RxFIFOTrig4 1
1236#define RxFIFOTrig8 2
1237#define RxFIFOTrig14 3
1238
1239/*
1240 * Dual-Ported RAM
1241 */
1242#define DRAM_global 0
1243#define INT_data (DRAM_global + 0)
1244#define Config_base (DRAM_global + 0x108)
1245
1246#define IRQindex (INT_data + 0)
1247#define IRQpending (INT_data + 4)
1248#define IRQtable (INT_data + 8)
1249
1250/*
1251 * Interrupt Status
1252 */
1253#define IntrRx 0x01 /* receiver data O.K. */
1254#define IntrTx 0x02 /* transmit buffer empty */
1255#define IntrFunc 0x04 /* function complete */
1256#define IntrBreak 0x08 /* received break */
1257#define IntrLine 0x10 /* line status change
1258 for transmitter */
1259#define IntrIntr 0x20 /* received INTR code */
1260#define IntrQuit 0x40 /* received QUIT code */
1261#define IntrEOF 0x80 /* received EOF code */
1262
1263#define IntrRxTrigger 0x100 /* rx data count reach tigger value */
1264#define IntrTxTrigger 0x200 /* tx data count below trigger value */
1265
1266#define Magic_no (Config_base + 0)
1267#define Card_model_no (Config_base + 2)
1268#define Total_ports (Config_base + 4)
1269#define Module_cnt (Config_base + 8)
1270#define Module_no (Config_base + 10)
1271#define Timer_10ms (Config_base + 14)
1272#define Disable_IRQ (Config_base + 20)
1273#define TMS320_PORT1 (Config_base + 22)
1274#define TMS320_PORT2 (Config_base + 24)
1275#define TMS320_CLOCK (Config_base + 26)
1276
1277/*
1278 * DATA BUFFER in DRAM
1279 */
1280#define Extern_table 0x400 /* Base address of the external table
1281 (24 words * 64) total 3K bytes
1282 (24 words * 128) total 6K bytes */
1283#define Extern_size 0x60 /* 96 bytes */
1284#define RXrptr 0x00 /* read pointer for RX buffer */
1285#define RXwptr 0x02 /* write pointer for RX buffer */
1286#define TXrptr 0x04 /* read pointer for TX buffer */
1287#define TXwptr 0x06 /* write pointer for TX buffer */
1288#define HostStat 0x08 /* IRQ flag and general flag */
1289#define FlagStat 0x0A
1290#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */
1291 /* x x x x | | | | */
1292 /* | | | + CTS flow */
1293 /* | | +--- RTS flow */
1294 /* | +------ TX Xon/Xoff */
1295 /* +--------- RX Xon/Xoff */
1296#define Break_cnt 0x0E /* received break count */
1297#define CD180TXirq 0x10 /* if non-0: enable TX irq */
1298#define RX_mask 0x12
1299#define TX_mask 0x14
1300#define Ofs_rxb 0x16
1301#define Ofs_txb 0x18
1302#define Page_rxb 0x1A
1303#define Page_txb 0x1C
1304#define EndPage_rxb 0x1E
1305#define EndPage_txb 0x20
1306#define Data_error 0x22
1307#define RxTrigger 0x28
1308#define TxTrigger 0x2a
1309
1310#define rRXwptr 0x34
1311#define Low_water 0x36
1312
1313#define FuncCode 0x40
1314#define FuncArg 0x42
1315#define FuncArg1 0x44
1316
1317#define C218rx_size 0x2000 /* 8K bytes */
1318#define C218tx_size 0x8000 /* 32K bytes */
1319
1320#define C218rx_mask (C218rx_size - 1)
1321#define C218tx_mask (C218tx_size - 1)
1322
1323#define C320p8rx_size 0x2000
1324#define C320p8tx_size 0x8000
1325#define C320p8rx_mask (C320p8rx_size - 1)
1326#define C320p8tx_mask (C320p8tx_size - 1)
1327
1328#define C320p16rx_size 0x2000
1329#define C320p16tx_size 0x4000
1330#define C320p16rx_mask (C320p16rx_size - 1)
1331#define C320p16tx_mask (C320p16tx_size - 1)
1332
1333#define C320p24rx_size 0x2000
1334#define C320p24tx_size 0x2000
1335#define C320p24rx_mask (C320p24rx_size - 1)
1336#define C320p24tx_mask (C320p24tx_size - 1)
1337
1338#define C320p32rx_size 0x1000
1339#define C320p32tx_size 0x1000
1340#define C320p32rx_mask (C320p32rx_size - 1)
1341#define C320p32tx_mask (C320p32tx_size - 1)
1342
1343#define Page_size 0x2000
1344#define Page_mask (Page_size - 1)
1345#define C218rx_spage 3
1346#define C218tx_spage 4
1347#define C218rx_pageno 1
1348#define C218tx_pageno 4
1349#define C218buf_pageno 5
1350
1351#define C320p8rx_spage 3
1352#define C320p8tx_spage 4
1353#define C320p8rx_pgno 1
1354#define C320p8tx_pgno 4
1355#define C320p8buf_pgno 5
1356
1357#define C320p16rx_spage 3
1358#define C320p16tx_spage 4
1359#define C320p16rx_pgno 1
1360#define C320p16tx_pgno 2
1361#define C320p16buf_pgno 3
1362
1363#define C320p24rx_spage 3
1364#define C320p24tx_spage 4
1365#define C320p24rx_pgno 1
1366#define C320p24tx_pgno 1
1367#define C320p24buf_pgno 2
1368
1369#define C320p32rx_spage 3
1370#define C320p32tx_ofs C320p32rx_size
1371#define C320p32tx_spage 3
1372#define C320p32buf_pgno 1
1373
1374/*
1375 * Host Status
1376 */
1377#define WakeupRx 0x01
1378#define WakeupTx 0x02
1379#define WakeupBreak 0x08
1380#define WakeupLine 0x10
1381#define WakeupIntr 0x20
1382#define WakeupQuit 0x40
1383#define WakeupEOF 0x80 /* used in VTIME control */
1384#define WakeupRxTrigger 0x100
1385#define WakeupTxTrigger 0x200
1386/*
1387 * Flag status
1388 */
1389#define Rx_over 0x01
1390#define Xoff_state 0x02
1391#define Tx_flowOff 0x04
1392#define Tx_enable 0x08
1393#define CTS_state 0x10
1394#define DSR_state 0x20
1395#define DCD_state 0x80
1396/*
1397 * FlowControl
1398 */
1399#define CTS_FlowCtl 1
1400#define RTS_FlowCtl 2
1401#define Tx_FlowCtl 4
1402#define Rx_FlowCtl 8
1403#define IXM_IXANY 0x10
1404
1405#define LowWater 128
1406
1407#define DTR_ON 1
1408#define RTS_ON 2
1409#define CTS_ON 1
1410#define DSR_ON 2
1411#define DCD_ON 8
1412
1413/* mode definition */
1414#define MX_CS8 0x03
1415#define MX_CS7 0x02
1416#define MX_CS6 0x01
1417#define MX_CS5 0x00
1418
1419#define MX_STOP1 0x00
1420#define MX_STOP15 0x04
1421#define MX_STOP2 0x08
1422
1423#define MX_PARNONE 0x00
1424#define MX_PAREVEN 0x40
1425#define MX_PARODD 0xC0
1426
1427/*
1428 * Query
1429 */
1430#define QueryPort MAX_PORTS
1431
1432
1433
1434struct mon_str {
1435 int tick;
1436 int rxcnt[MAX_PORTS];
1437 int txcnt[MAX_PORTS];
1438};
1439typedef struct mon_str mon_st;
1440
1441#define DCD_changed 0x01
1442#define DCD_oldstate 0x80
1443
1444static unsigned char moxaBuff[10240];
1445static void __iomem *moxaIntNdx[MAX_BOARDS];
1446static void __iomem *moxaIntPend[MAX_BOARDS];
1447static void __iomem *moxaIntTable[MAX_BOARDS];
1448static char moxaChkPort[MAX_PORTS];
1449static char moxaLineCtrl[MAX_PORTS];
1450static void __iomem *moxaTableAddr[MAX_PORTS];
1451static long moxaCurBaud[MAX_PORTS];
1452static char moxaDCDState[MAX_PORTS];
1453static char moxaLowChkFlag[MAX_PORTS];
1454static int moxaLowWaterChk;
1455static int moxaCard;
1456static mon_st moxaLog;
Jiri Slaby9fa372a2007-02-10 01:45:26 -08001457static int moxaFuncTout = HZ / 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458static ushort moxaBreakCnt[MAX_PORTS];
1459
1460static void moxadelay(int);
1461static void moxafunc(void __iomem *, int, ushort);
1462static void wait_finish(void __iomem *);
1463static void low_water_check(void __iomem *);
1464static int moxaloadbios(int, unsigned char __user *, int);
1465static int moxafindcard(int);
1466static int moxaload320b(int, unsigned char __user *, int);
1467static int moxaloadcode(int, unsigned char __user *, int);
1468static int moxaloadc218(int, void __iomem *, int);
1469static int moxaloadc320(int, void __iomem *, int, int *);
1470
1471/*****************************************************************************
1472 * Driver level functions: *
1473 * 1. MoxaDriverInit(void); *
1474 * 2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); *
1475 * 3. MoxaDriverPoll(void); *
1476 *****************************************************************************/
1477void MoxaDriverInit(void)
1478{
1479 int i;
1480
1481 moxaFuncTout = HZ / 2; /* 500 mini-seconds */
1482 moxaCard = 0;
1483 moxaLog.tick = 0;
1484 moxaLowWaterChk = 0;
1485 for (i = 0; i < MAX_PORTS; i++) {
1486 moxaChkPort[i] = 0;
1487 moxaLowChkFlag[i] = 0;
1488 moxaLineCtrl[i] = 0;
1489 moxaLog.rxcnt[i] = 0;
1490 moxaLog.txcnt[i] = 0;
1491 }
1492}
1493
1494#define MOXA 0x400
1495#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */
1496#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */
1497#define MOXA_INIT_DRIVER (MOXA + 6) /* moxaCard=0 */
1498#define MOXA_LOAD_BIOS (MOXA + 9) /* download BIOS */
1499#define MOXA_FIND_BOARD (MOXA + 10) /* Check if MOXA card exist? */
1500#define MOXA_LOAD_C320B (MOXA + 11) /* download 320B firmware */
1501#define MOXA_LOAD_CODE (MOXA + 12) /* download firmware */
1502#define MOXA_GETDATACOUNT (MOXA + 23)
1503#define MOXA_GET_IOQUEUE (MOXA + 27)
1504#define MOXA_FLUSH_QUEUE (MOXA + 28)
1505#define MOXA_GET_CONF (MOXA + 35) /* configuration */
1506#define MOXA_GET_MAJOR (MOXA + 63)
1507#define MOXA_GET_CUMAJOR (MOXA + 64)
1508#define MOXA_GETMSTATUS (MOXA + 65)
1509
1510
1511struct moxaq_str {
1512 int inq;
1513 int outq;
1514};
1515
1516struct dl_str {
1517 char __user *buf;
1518 int len;
1519 int cardno;
1520};
1521
1522static struct moxaq_str temp_queue[MAX_PORTS];
1523static struct dl_str dltmp;
1524
1525void MoxaPortFlushData(int port, int mode)
1526{
1527 void __iomem *ofsAddr;
1528 if ((mode < 0) || (mode > 2))
1529 return;
1530 ofsAddr = moxaTableAddr[port];
1531 moxafunc(ofsAddr, FC_FlushQueue, mode);
1532 if (mode != 1) {
1533 moxaLowChkFlag[port] = 0;
1534 low_water_check(ofsAddr);
1535 }
1536}
1537
1538int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
1539{
1540 int i;
1541 int status;
1542 int MoxaPortTxQueue(int), MoxaPortRxQueue(int);
1543 void __user *argp = (void __user *)arg;
1544
1545 if (port == QueryPort) {
1546 if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) &&
1547 (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) &&
1548 (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) &&
1549 (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) &&
1550 (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS))
1551 return (-EINVAL);
1552 }
1553 switch (cmd) {
1554 case MOXA_GET_CONF:
1555 if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf)))
1556 return -EFAULT;
1557 return (0);
1558 case MOXA_INIT_DRIVER:
1559 if ((int) arg == 0x404)
1560 MoxaDriverInit();
1561 return (0);
1562 case MOXA_GETDATACOUNT:
1563 moxaLog.tick = jiffies;
1564 if(copy_to_user(argp, &moxaLog, sizeof(mon_st)))
1565 return -EFAULT;
1566 return (0);
1567 case MOXA_FLUSH_QUEUE:
1568 MoxaPortFlushData(port, arg);
1569 return (0);
1570 case MOXA_GET_IOQUEUE:
1571 for (i = 0; i < MAX_PORTS; i++) {
1572 if (moxaChkPort[i]) {
1573 temp_queue[i].inq = MoxaPortRxQueue(i);
1574 temp_queue[i].outq = MoxaPortTxQueue(i);
1575 }
1576 }
1577 if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS))
1578 return -EFAULT;
1579 return (0);
1580 case MOXA_GET_OQUEUE:
1581 i = MoxaPortTxQueue(port);
1582 return put_user(i, (unsigned long __user *)argp);
1583 case MOXA_GET_IQUEUE:
1584 i = MoxaPortRxQueue(port);
1585 return put_user(i, (unsigned long __user *)argp);
1586 case MOXA_GET_MAJOR:
1587 if(copy_to_user(argp, &ttymajor, sizeof(int)))
1588 return -EFAULT;
1589 return 0;
1590 case MOXA_GET_CUMAJOR:
1591 i = 0;
1592 if(copy_to_user(argp, &i, sizeof(int)))
1593 return -EFAULT;
1594 return 0;
1595 case MOXA_GETMSTATUS:
1596 for (i = 0; i < MAX_PORTS; i++) {
1597 GMStatus[i].ri = 0;
1598 GMStatus[i].dcd = 0;
1599 GMStatus[i].dsr = 0;
1600 GMStatus[i].cts = 0;
1601 if (!moxaChkPort[i]) {
1602 continue;
1603 } else {
1604 status = MoxaPortLineStatus(moxaChannels[i].port);
1605 if (status & 1)
1606 GMStatus[i].cts = 1;
1607 if (status & 2)
1608 GMStatus[i].dsr = 1;
1609 if (status & 4)
1610 GMStatus[i].dcd = 1;
1611 }
1612
1613 if (!moxaChannels[i].tty || !moxaChannels[i].tty->termios)
1614 GMStatus[i].cflag = moxaChannels[i].cflag;
1615 else
1616 GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag;
1617 }
1618 if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS))
1619 return -EFAULT;
1620 return 0;
1621 default:
1622 return (-ENOIOCTLCMD);
1623 case MOXA_LOAD_BIOS:
1624 case MOXA_FIND_BOARD:
1625 case MOXA_LOAD_C320B:
1626 case MOXA_LOAD_CODE:
Alan Cox49cd6192006-01-09 09:35:28 -05001627 if (!capable(CAP_SYS_RAWIO))
1628 return -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 break;
1630 }
1631
1632 if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
1633 return -EFAULT;
1634 if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS)
1635 return -EINVAL;
1636
1637 switch(cmd)
1638 {
1639 case MOXA_LOAD_BIOS:
1640 i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len);
1641 return (i);
1642 case MOXA_FIND_BOARD:
1643 return moxafindcard(dltmp.cardno);
1644 case MOXA_LOAD_C320B:
1645 moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len);
1646 default: /* to keep gcc happy */
1647 return (0);
1648 case MOXA_LOAD_CODE:
1649 i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len);
1650 if (i == -1)
1651 return (-EFAULT);
1652 return (i);
1653
1654 }
1655}
1656
1657int MoxaDriverPoll(void)
1658{
1659 register ushort temp;
1660 register int card;
1661 void __iomem *ofsAddr;
1662 void __iomem *ip;
1663 int port, p, ports;
1664
1665 if (moxaCard == 0)
1666 return (-1);
1667 for (card = 0; card < MAX_BOARDS; card++) {
Dirk Eibach01cfaf02006-08-27 01:23:36 -07001668 if (loadstat[card] == 0)
1669 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 if ((ports = moxa_boards[card].numPorts) == 0)
1671 continue;
1672 if (readb(moxaIntPend[card]) == 0xff) {
1673 ip = moxaIntTable[card] + readb(moxaIntNdx[card]);
1674 p = card * MAX_PORTS_PER_BOARD;
1675 ports <<= 1;
1676 for (port = 0; port < ports; port += 2, p++) {
1677 if ((temp = readw(ip + port)) != 0) {
1678 writew(0, ip + port);
1679 ofsAddr = moxaTableAddr[p];
1680 if (temp & IntrTx)
1681 writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat);
1682 if (temp & IntrBreak) {
1683 moxaBreakCnt[p]++;
1684 }
1685 if (temp & IntrLine) {
1686 if (readb(ofsAddr + FlagStat) & DCD_state) {
1687 if ((moxaDCDState[p] & DCD_oldstate) == 0)
1688 moxaDCDState[p] = (DCD_oldstate |
1689 DCD_changed);
1690 } else {
1691 if (moxaDCDState[p] & DCD_oldstate)
1692 moxaDCDState[p] = DCD_changed;
1693 }
1694 }
1695 }
1696 }
1697 writeb(0, moxaIntPend[card]);
1698 }
1699 if (moxaLowWaterChk) {
1700 p = card * MAX_PORTS_PER_BOARD;
1701 for (port = 0; port < ports; port++, p++) {
1702 if (moxaLowChkFlag[p]) {
1703 moxaLowChkFlag[p] = 0;
1704 ofsAddr = moxaTableAddr[p];
1705 low_water_check(ofsAddr);
1706 }
1707 }
1708 }
1709 }
1710 moxaLowWaterChk = 0;
1711 return (0);
1712}
1713
1714/*****************************************************************************
1715 * Card level function: *
1716 * 1. MoxaPortsOfCard(int cardno); *
1717 *****************************************************************************/
1718int MoxaPortsOfCard(int cardno)
1719{
1720
1721 if (moxa_boards[cardno].boardType == 0)
1722 return (0);
1723 return (moxa_boards[cardno].numPorts);
1724}
1725
1726/*****************************************************************************
1727 * Port level functions: *
1728 * 1. MoxaPortIsValid(int port); *
1729 * 2. MoxaPortEnable(int port); *
1730 * 3. MoxaPortDisable(int port); *
1731 * 4. MoxaPortGetMaxBaud(int port); *
1732 * 5. MoxaPortGetCurBaud(int port); *
1733 * 6. MoxaPortSetBaud(int port, long baud); *
1734 * 7. MoxaPortSetMode(int port, int databit, int stopbit, int parity); *
1735 * 8. MoxaPortSetTermio(int port, unsigned char *termio); *
1736 * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); *
1737 * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); *
1738 * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); *
1739 * 12. MoxaPortLineStatus(int port); *
1740 * 13. MoxaPortDCDChange(int port); *
1741 * 14. MoxaPortDCDON(int port); *
1742 * 15. MoxaPortFlushData(int port, int mode); *
1743 * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
Alan Cox33f0f882006-01-09 20:54:13 -08001744 * 17. MoxaPortReadData(int port, struct tty_struct *tty); *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 * 18. MoxaPortTxBufSize(int port); *
1746 * 19. MoxaPortRxBufSize(int port); *
1747 * 20. MoxaPortTxQueue(int port); *
1748 * 21. MoxaPortTxFree(int port); *
1749 * 22. MoxaPortRxQueue(int port); *
1750 * 23. MoxaPortRxFree(int port); *
1751 * 24. MoxaPortTxDisable(int port); *
1752 * 25. MoxaPortTxEnable(int port); *
1753 * 26. MoxaPortGetBrkCnt(int port); *
1754 * 27. MoxaPortResetBrkCnt(int port); *
1755 * 28. MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); *
1756 * 29. MoxaPortIsTxHold(int port); *
1757 * 30. MoxaPortSendBreak(int port, int ticks); *
1758 *****************************************************************************/
1759/*
1760 * Moxa Port Number Description:
1761 *
1762 * MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And,
1763 * the port number using in MOXA driver functions will be 0 to 31 for
1764 * first MOXA board, 32 to 63 for second, 64 to 95 for third and 96
1765 * to 127 for fourth. For example, if you setup three MOXA boards,
1766 * first board is C218, second board is C320-16 and third board is
1767 * C320-32. The port number of first board (C218 - 8 ports) is from
1768 * 0 to 7. The port number of second board (C320 - 16 ports) is form
1769 * 32 to 47. The port number of third board (C320 - 32 ports) is from
1770 * 64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to
1771 * 127 will be invalid.
1772 *
1773 *
1774 * Moxa Functions Description:
1775 *
1776 * Function 1: Driver initialization routine, this routine must be
1777 * called when initialized driver.
1778 * Syntax:
1779 * void MoxaDriverInit();
1780 *
1781 *
1782 * Function 2: Moxa driver private IOCTL command processing.
1783 * Syntax:
1784 * int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port);
1785 *
1786 * unsigned int cmd : IOCTL command
1787 * unsigned long arg : IOCTL argument
1788 * int port : port number (0 - 127)
1789 *
1790 * return: 0 (OK)
1791 * -EINVAL
1792 * -ENOIOCTLCMD
1793 *
1794 *
1795 * Function 3: Moxa driver polling process routine.
1796 * Syntax:
1797 * int MoxaDriverPoll(void);
1798 *
1799 * return: 0 ; polling O.K.
1800 * -1 : no any Moxa card.
1801 *
1802 *
1803 * Function 4: Get the ports of this card.
1804 * Syntax:
1805 * int MoxaPortsOfCard(int cardno);
1806 *
1807 * int cardno : card number (0 - 3)
1808 *
1809 * return: 0 : this card is invalid
1810 * 8/16/24/32
1811 *
1812 *
1813 * Function 5: Check this port is valid or invalid
1814 * Syntax:
1815 * int MoxaPortIsValid(int port);
1816 * int port : port number (0 - 127, ref port description)
1817 *
1818 * return: 0 : this port is invalid
1819 * 1 : this port is valid
1820 *
1821 *
1822 * Function 6: Enable this port to start Tx/Rx data.
1823 * Syntax:
1824 * void MoxaPortEnable(int port);
1825 * int port : port number (0 - 127)
1826 *
1827 *
1828 * Function 7: Disable this port
1829 * Syntax:
1830 * void MoxaPortDisable(int port);
1831 * int port : port number (0 - 127)
1832 *
1833 *
1834 * Function 8: Get the maximun available baud rate of this port.
1835 * Syntax:
1836 * long MoxaPortGetMaxBaud(int port);
1837 * int port : port number (0 - 127)
1838 *
1839 * return: 0 : this port is invalid
1840 * 38400/57600/115200 bps
1841 *
1842 *
1843 * Function 9: Get the current baud rate of this port.
1844 * Syntax:
1845 * long MoxaPortGetCurBaud(int port);
1846 * int port : port number (0 - 127)
1847 *
1848 * return: 0 : this port is invalid
1849 * 50 - 115200 bps
1850 *
1851 *
1852 * Function 10: Setting baud rate of this port.
1853 * Syntax:
1854 * long MoxaPortSetBaud(int port, long baud);
1855 * int port : port number (0 - 127)
1856 * long baud : baud rate (50 - 115200)
1857 *
1858 * return: 0 : this port is invalid or baud < 50
1859 * 50 - 115200 : the real baud rate set to the port, if
1860 * the argument baud is large than maximun
1861 * available baud rate, the real setting
1862 * baud rate will be the maximun baud rate.
1863 *
1864 *
1865 * Function 11: Setting the data-bits/stop-bits/parity of this port
1866 * Syntax:
1867 * int MoxaPortSetMode(int port, int databits, int stopbits, int parity);
1868 * int port : port number (0 - 127)
1869 * int databits : data bits (8/7/6/5)
1870 * int stopbits : stop bits (2/1/0, 0 show 1.5 stop bits)
1871 int parity : parity (0:None,1:Odd,2:Even,3:Mark,4:Space)
1872 *
1873 * return: -1 : invalid parameter
1874 * 0 : setting O.K.
1875 *
1876 *
1877 * Function 12: Configure the port.
1878 * Syntax:
Alan Cox606d0992006-12-08 02:38:45 -08001879 * int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 * int port : port number (0 - 127)
Alan Cox606d0992006-12-08 02:38:45 -08001881 * struct ktermios * termio : termio structure pointer
Alan Coxc7bce302006-09-30 23:27:24 -07001882 * speed_t baud : baud rate
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 *
1884 * return: -1 : this port is invalid or termio == NULL
1885 * 0 : setting O.K.
1886 *
1887 *
1888 * Function 13: Get the DTR/RTS state of this port.
1889 * Syntax:
1890 * int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState);
1891 * int port : port number (0 - 127)
1892 * int * dtrState : pointer to INT to receive the current DTR
1893 * state. (if NULL, this function will not
1894 * write to this address)
1895 * int * rtsState : pointer to INT to receive the current RTS
1896 * state. (if NULL, this function will not
1897 * write to this address)
1898 *
1899 * return: -1 : this port is invalid
1900 * 0 : O.K.
1901 *
1902 *
1903 * Function 14: Setting the DTR/RTS output state of this port.
1904 * Syntax:
1905 * void MoxaPortLineCtrl(int port, int dtrState, int rtsState);
1906 * int port : port number (0 - 127)
1907 * int dtrState : DTR output state (0: off, 1: on)
1908 * int rtsState : RTS output state (0: off, 1: on)
1909 *
1910 *
1911 * Function 15: Setting the flow control of this port.
1912 * Syntax:
1913 * void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow,
1914 * int txFlow,int xany);
1915 * int port : port number (0 - 127)
1916 * int rtsFlow : H/W RTS flow control (0: no, 1: yes)
1917 * int ctsFlow : H/W CTS flow control (0: no, 1: yes)
1918 * int rxFlow : S/W Rx XON/XOFF flow control (0: no, 1: yes)
1919 * int txFlow : S/W Tx XON/XOFF flow control (0: no, 1: yes)
1920 * int xany : S/W XANY flow control (0: no, 1: yes)
1921 *
1922 *
1923 * Function 16: Get ths line status of this port
1924 * Syntax:
1925 * int MoxaPortLineStatus(int port);
1926 * int port : port number (0 - 127)
1927 *
1928 * return: Bit 0 - CTS state (0: off, 1: on)
1929 * Bit 1 - DSR state (0: off, 1: on)
1930 * Bit 2 - DCD state (0: off, 1: on)
1931 *
1932 *
1933 * Function 17: Check the DCD state has changed since the last read
1934 * of this function.
1935 * Syntax:
1936 * int MoxaPortDCDChange(int port);
1937 * int port : port number (0 - 127)
1938 *
1939 * return: 0 : no changed
1940 * 1 : DCD has changed
1941 *
1942 *
1943 * Function 18: Check ths current DCD state is ON or not.
1944 * Syntax:
1945 * int MoxaPortDCDON(int port);
1946 * int port : port number (0 - 127)
1947 *
1948 * return: 0 : DCD off
1949 * 1 : DCD on
1950 *
1951 *
1952 * Function 19: Flush the Rx/Tx buffer data of this port.
1953 * Syntax:
1954 * void MoxaPortFlushData(int port, int mode);
1955 * int port : port number (0 - 127)
1956 * int mode
1957 * 0 : flush the Rx buffer
1958 * 1 : flush the Tx buffer
1959 * 2 : flush the Rx and Tx buffer
1960 *
1961 *
1962 * Function 20: Write data.
1963 * Syntax:
1964 * int MoxaPortWriteData(int port, unsigned char * buffer, int length);
1965 * int port : port number (0 - 127)
1966 * unsigned char * buffer : pointer to write data buffer.
1967 * int length : write data length
1968 *
1969 * return: 0 - length : real write data length
1970 *
1971 *
1972 * Function 21: Read data.
1973 * Syntax:
Alan Cox33f0f882006-01-09 20:54:13 -08001974 * int MoxaPortReadData(int port, struct tty_struct *tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 * int port : port number (0 - 127)
Alan Cox33f0f882006-01-09 20:54:13 -08001976 * struct tty_struct *tty : tty for data
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 *
1978 * return: 0 - length : real read data length
1979 *
1980 *
1981 * Function 22: Get the Tx buffer size of this port
1982 * Syntax:
1983 * int MoxaPortTxBufSize(int port);
1984 * int port : port number (0 - 127)
1985 *
1986 * return: .. : Tx buffer size
1987 *
1988 *
1989 * Function 23: Get the Rx buffer size of this port
1990 * Syntax:
1991 * int MoxaPortRxBufSize(int port);
1992 * int port : port number (0 - 127)
1993 *
1994 * return: .. : Rx buffer size
1995 *
1996 *
1997 * Function 24: Get the Tx buffer current queued data bytes
1998 * Syntax:
1999 * int MoxaPortTxQueue(int port);
2000 * int port : port number (0 - 127)
2001 *
2002 * return: .. : Tx buffer current queued data bytes
2003 *
2004 *
2005 * Function 25: Get the Tx buffer current free space
2006 * Syntax:
2007 * int MoxaPortTxFree(int port);
2008 * int port : port number (0 - 127)
2009 *
2010 * return: .. : Tx buffer current free space
2011 *
2012 *
2013 * Function 26: Get the Rx buffer current queued data bytes
2014 * Syntax:
2015 * int MoxaPortRxQueue(int port);
2016 * int port : port number (0 - 127)
2017 *
2018 * return: .. : Rx buffer current queued data bytes
2019 *
2020 *
2021 * Function 27: Get the Rx buffer current free space
2022 * Syntax:
2023 * int MoxaPortRxFree(int port);
2024 * int port : port number (0 - 127)
2025 *
2026 * return: .. : Rx buffer current free space
2027 *
2028 *
2029 * Function 28: Disable port data transmission.
2030 * Syntax:
2031 * void MoxaPortTxDisable(int port);
2032 * int port : port number (0 - 127)
2033 *
2034 *
2035 * Function 29: Enable port data transmission.
2036 * Syntax:
2037 * void MoxaPortTxEnable(int port);
2038 * int port : port number (0 - 127)
2039 *
2040 *
2041 * Function 30: Get the received BREAK signal count.
2042 * Syntax:
2043 * int MoxaPortGetBrkCnt(int port);
2044 * int port : port number (0 - 127)
2045 *
2046 * return: 0 - .. : BREAK signal count
2047 *
2048 *
2049 * Function 31: Get the received BREAK signal count and reset it.
2050 * Syntax:
2051 * int MoxaPortResetBrkCnt(int port);
2052 * int port : port number (0 - 127)
2053 *
2054 * return: 0 - .. : BREAK signal count
2055 *
2056 *
2057 * Function 32: Set the S/W flow control new XON/XOFF value, default
2058 * XON is 0x11 & XOFF is 0x13.
2059 * Syntax:
2060 * void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue);
2061 * int port : port number (0 - 127)
2062 * int xonValue : new XON value (0 - 255)
2063 * int xoffValue : new XOFF value (0 - 255)
2064 *
2065 *
2066 * Function 33: Check this port's transmission is hold by remote site
2067 * because the flow control.
2068 * Syntax:
2069 * int MoxaPortIsTxHold(int port);
2070 * int port : port number (0 - 127)
2071 *
2072 * return: 0 : normal
2073 * 1 : hold by remote site
2074 *
2075 *
2076 * Function 34: Send out a BREAK signal.
2077 * Syntax:
2078 * void MoxaPortSendBreak(int port, int ms100);
2079 * int port : port number (0 - 127)
2080 * int ms100 : break signal time interval.
2081 * unit: 100 mini-second. if ms100 == 0, it will
2082 * send out a about 250 ms BREAK signal.
2083 *
2084 */
2085int MoxaPortIsValid(int port)
2086{
2087
2088 if (moxaCard == 0)
2089 return (0);
2090 if (moxaChkPort[port] == 0)
2091 return (0);
2092 return (1);
2093}
2094
2095void MoxaPortEnable(int port)
2096{
2097 void __iomem *ofsAddr;
2098 int MoxaPortLineStatus(int);
2099 short lowwater = 512;
2100
2101 ofsAddr = moxaTableAddr[port];
2102 writew(lowwater, ofsAddr + Low_water);
2103 moxaBreakCnt[port] = 0;
2104 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2105 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
2106 moxafunc(ofsAddr, FC_SetBreakIrq, 0);
2107 } else {
2108 writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat);
2109 }
2110
2111 moxafunc(ofsAddr, FC_SetLineIrq, Magic_code);
2112 moxafunc(ofsAddr, FC_FlushQueue, 2);
2113
2114 moxafunc(ofsAddr, FC_EnableCH, Magic_code);
2115 MoxaPortLineStatus(port);
2116}
2117
2118void MoxaPortDisable(int port)
2119{
2120 void __iomem *ofsAddr = moxaTableAddr[port];
2121
2122 moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */
2123 moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);
2124 writew(0, ofsAddr + HostStat);
2125 moxafunc(ofsAddr, FC_DisableCH, Magic_code);
2126}
2127
2128long MoxaPortGetMaxBaud(int port)
2129{
2130 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2131 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI))
2132 return (460800L);
2133 else
2134 return (921600L);
2135}
2136
2137
2138long MoxaPortSetBaud(int port, long baud)
2139{
2140 void __iomem *ofsAddr;
2141 long max, clock;
2142 unsigned int val;
2143
2144 if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0))
2145 return (0);
2146 ofsAddr = moxaTableAddr[port];
2147 if (baud > max)
2148 baud = max;
2149 if (max == 38400L)
2150 clock = 614400L; /* for 9.8304 Mhz : max. 38400 bps */
2151 else if (max == 57600L)
2152 clock = 691200L; /* for 11.0592 Mhz : max. 57600 bps */
2153 else
2154 clock = 921600L; /* for 14.7456 Mhz : max. 115200 bps */
2155 val = clock / baud;
2156 moxafunc(ofsAddr, FC_SetBaud, val);
2157 baud = clock / val;
2158 moxaCurBaud[port] = baud;
2159 return (baud);
2160}
2161
Alan Cox606d0992006-12-08 02:38:45 -08002162int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163{
2164 void __iomem *ofsAddr;
2165 tcflag_t cflag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166 tcflag_t mode = 0;
2167
2168 if (moxaChkPort[port] == 0 || termio == 0)
2169 return (-1);
2170 ofsAddr = moxaTableAddr[port];
2171 cflag = termio->c_cflag; /* termio->c_cflag */
2172
2173 mode = termio->c_cflag & CSIZE;
2174 if (mode == CS5)
2175 mode = MX_CS5;
2176 else if (mode == CS6)
2177 mode = MX_CS6;
2178 else if (mode == CS7)
2179 mode = MX_CS7;
2180 else if (mode == CS8)
2181 mode = MX_CS8;
2182
2183 if (termio->c_cflag & CSTOPB) {
2184 if (mode == MX_CS5)
2185 mode |= MX_STOP15;
2186 else
2187 mode |= MX_STOP2;
2188 } else
2189 mode |= MX_STOP1;
2190
2191 if (termio->c_cflag & PARENB) {
2192 if (termio->c_cflag & PARODD)
2193 mode |= MX_PARODD;
2194 else
2195 mode |= MX_PAREVEN;
2196 } else
2197 mode |= MX_PARNONE;
2198
2199 moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);
2200
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2202 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
Alan Coxc7bce302006-09-30 23:27:24 -07002203 if (baud >= 921600L)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204 return (-1);
2205 }
2206 MoxaPortSetBaud(port, baud);
2207
2208 if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
2209 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
2210 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
2211 writeb(FC_SetXonXoff, ofsAddr + FuncCode);
2212 wait_finish(ofsAddr);
2213
2214 }
2215 return (0);
2216}
2217
2218int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState)
2219{
2220
2221 if (!MoxaPortIsValid(port))
2222 return (-1);
2223 if (dtrState) {
2224 if (moxaLineCtrl[port] & DTR_ON)
2225 *dtrState = 1;
2226 else
2227 *dtrState = 0;
2228 }
2229 if (rtsState) {
2230 if (moxaLineCtrl[port] & RTS_ON)
2231 *rtsState = 1;
2232 else
2233 *rtsState = 0;
2234 }
2235 return (0);
2236}
2237
2238void MoxaPortLineCtrl(int port, int dtr, int rts)
2239{
2240 void __iomem *ofsAddr;
2241 int mode;
2242
2243 ofsAddr = moxaTableAddr[port];
2244 mode = 0;
2245 if (dtr)
2246 mode |= DTR_ON;
2247 if (rts)
2248 mode |= RTS_ON;
2249 moxaLineCtrl[port] = mode;
2250 moxafunc(ofsAddr, FC_LineControl, mode);
2251}
2252
2253void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany)
2254{
2255 void __iomem *ofsAddr;
2256 int mode;
2257
2258 ofsAddr = moxaTableAddr[port];
2259 mode = 0;
2260 if (rts)
2261 mode |= RTS_FlowCtl;
2262 if (cts)
2263 mode |= CTS_FlowCtl;
2264 if (txflow)
2265 mode |= Tx_FlowCtl;
2266 if (rxflow)
2267 mode |= Rx_FlowCtl;
2268 if (txany)
2269 mode |= IXM_IXANY;
2270 moxafunc(ofsAddr, FC_SetFlowCtl, mode);
2271}
2272
2273int MoxaPortLineStatus(int port)
2274{
2275 void __iomem *ofsAddr;
2276 int val;
2277
2278 ofsAddr = moxaTableAddr[port];
2279 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2280 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
2281 moxafunc(ofsAddr, FC_LineStatus, 0);
2282 val = readw(ofsAddr + FuncArg);
2283 } else {
2284 val = readw(ofsAddr + FlagStat) >> 4;
2285 }
2286 val &= 0x0B;
2287 if (val & 8) {
2288 val |= 4;
2289 if ((moxaDCDState[port] & DCD_oldstate) == 0)
2290 moxaDCDState[port] = (DCD_oldstate | DCD_changed);
2291 } else {
2292 if (moxaDCDState[port] & DCD_oldstate)
2293 moxaDCDState[port] = DCD_changed;
2294 }
2295 val &= 7;
2296 return (val);
2297}
2298
2299int MoxaPortDCDChange(int port)
2300{
2301 int n;
2302
2303 if (moxaChkPort[port] == 0)
2304 return (0);
2305 n = moxaDCDState[port];
2306 moxaDCDState[port] &= ~DCD_changed;
2307 n &= DCD_changed;
2308 return (n);
2309}
2310
2311int MoxaPortDCDON(int port)
2312{
2313 int n;
2314
2315 if (moxaChkPort[port] == 0)
2316 return (0);
2317 if (moxaDCDState[port] & DCD_oldstate)
2318 n = 1;
2319 else
2320 n = 0;
2321 return (n);
2322}
2323
2324
2325/*
2326 int MoxaDumpMem(int port, unsigned char * buffer, int len)
2327 {
2328 int i;
2329 unsigned long baseAddr,ofsAddr,ofs;
2330
2331 baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
2332 ofs = baseAddr + DynPage_addr + pageofs;
2333 if (len > 0x2000L)
2334 len = 0x2000L;
2335 for (i = 0; i < len; i++)
2336 buffer[i] = readb(ofs+i);
2337 }
2338 */
2339
2340
2341int MoxaPortWriteData(int port, unsigned char * buffer, int len)
2342{
2343 int c, total, i;
2344 ushort tail;
2345 int cnt;
2346 ushort head, tx_mask, spage, epage;
2347 ushort pageno, pageofs, bufhead;
2348 void __iomem *baseAddr, *ofsAddr, *ofs;
2349
2350 ofsAddr = moxaTableAddr[port];
2351 baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
2352 tx_mask = readw(ofsAddr + TX_mask);
2353 spage = readw(ofsAddr + Page_txb);
2354 epage = readw(ofsAddr + EndPage_txb);
2355 tail = readw(ofsAddr + TXwptr);
2356 head = readw(ofsAddr + TXrptr);
2357 c = (head > tail) ? (head - tail - 1)
2358 : (head - tail + tx_mask);
2359 if (c > len)
2360 c = len;
2361 moxaLog.txcnt[port] += c;
2362 total = c;
2363 if (spage == epage) {
2364 bufhead = readw(ofsAddr + Ofs_txb);
2365 writew(spage, baseAddr + Control_reg);
2366 while (c > 0) {
2367 if (head > tail)
2368 len = head - tail - 1;
2369 else
2370 len = tx_mask + 1 - tail;
2371 len = (c > len) ? len : c;
2372 ofs = baseAddr + DynPage_addr + bufhead + tail;
2373 for (i = 0; i < len; i++)
2374 writeb(*buffer++, ofs + i);
2375 tail = (tail + len) & tx_mask;
2376 c -= len;
2377 }
2378 writew(tail, ofsAddr + TXwptr);
2379 } else {
2380 len = c;
2381 pageno = spage + (tail >> 13);
2382 pageofs = tail & Page_mask;
2383 do {
2384 cnt = Page_size - pageofs;
2385 if (cnt > c)
2386 cnt = c;
2387 c -= cnt;
2388 writeb(pageno, baseAddr + Control_reg);
2389 ofs = baseAddr + DynPage_addr + pageofs;
2390 for (i = 0; i < cnt; i++)
2391 writeb(*buffer++, ofs + i);
2392 if (c == 0) {
2393 writew((tail + len) & tx_mask, ofsAddr + TXwptr);
2394 break;
2395 }
2396 if (++pageno == epage)
2397 pageno = spage;
2398 pageofs = 0;
2399 } while (1);
2400 }
2401 writeb(1, ofsAddr + CD180TXirq); /* start to send */
2402 return (total);
2403}
2404
Alan Cox33f0f882006-01-09 20:54:13 -08002405int MoxaPortReadData(int port, struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406{
2407 register ushort head, pageofs;
2408 int i, count, cnt, len, total, remain;
2409 ushort tail, rx_mask, spage, epage;
2410 ushort pageno, bufhead;
2411 void __iomem *baseAddr, *ofsAddr, *ofs;
2412
2413 ofsAddr = moxaTableAddr[port];
2414 baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
2415 head = readw(ofsAddr + RXrptr);
2416 tail = readw(ofsAddr + RXwptr);
2417 rx_mask = readw(ofsAddr + RX_mask);
2418 spage = readw(ofsAddr + Page_rxb);
2419 epage = readw(ofsAddr + EndPage_rxb);
2420 count = (tail >= head) ? (tail - head)
2421 : (tail - head + rx_mask + 1);
2422 if (count == 0)
Alan Cox33f0f882006-01-09 20:54:13 -08002423 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424
Alan Cox33f0f882006-01-09 20:54:13 -08002425 total = count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426 remain = count - total;
2427 moxaLog.rxcnt[port] += total;
2428 count = total;
2429 if (spage == epage) {
2430 bufhead = readw(ofsAddr + Ofs_rxb);
2431 writew(spage, baseAddr + Control_reg);
2432 while (count > 0) {
2433 if (tail >= head)
2434 len = tail - head;
2435 else
2436 len = rx_mask + 1 - head;
2437 len = (count > len) ? len : count;
2438 ofs = baseAddr + DynPage_addr + bufhead + head;
2439 for (i = 0; i < len; i++)
Alan Cox33f0f882006-01-09 20:54:13 -08002440 tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 head = (head + len) & rx_mask;
2442 count -= len;
2443 }
2444 writew(head, ofsAddr + RXrptr);
2445 } else {
2446 len = count;
2447 pageno = spage + (head >> 13);
2448 pageofs = head & Page_mask;
2449 do {
2450 cnt = Page_size - pageofs;
2451 if (cnt > count)
2452 cnt = count;
2453 count -= cnt;
2454 writew(pageno, baseAddr + Control_reg);
2455 ofs = baseAddr + DynPage_addr + pageofs;
2456 for (i = 0; i < cnt; i++)
Alan Cox33f0f882006-01-09 20:54:13 -08002457 tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458 if (count == 0) {
2459 writew((head + len) & rx_mask, ofsAddr + RXrptr);
2460 break;
2461 }
2462 if (++pageno == epage)
2463 pageno = spage;
2464 pageofs = 0;
2465 } while (1);
2466 }
2467 if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) {
2468 moxaLowWaterChk = 1;
2469 moxaLowChkFlag[port] = 1;
2470 }
2471 return (total);
2472}
2473
2474
2475int MoxaPortTxQueue(int port)
2476{
2477 void __iomem *ofsAddr;
2478 ushort rptr, wptr, mask;
2479 int len;
2480
2481 ofsAddr = moxaTableAddr[port];
2482 rptr = readw(ofsAddr + TXrptr);
2483 wptr = readw(ofsAddr + TXwptr);
2484 mask = readw(ofsAddr + TX_mask);
2485 len = (wptr - rptr) & mask;
2486 return (len);
2487}
2488
2489int MoxaPortTxFree(int port)
2490{
2491 void __iomem *ofsAddr;
2492 ushort rptr, wptr, mask;
2493 int len;
2494
2495 ofsAddr = moxaTableAddr[port];
2496 rptr = readw(ofsAddr + TXrptr);
2497 wptr = readw(ofsAddr + TXwptr);
2498 mask = readw(ofsAddr + TX_mask);
2499 len = mask - ((wptr - rptr) & mask);
2500 return (len);
2501}
2502
2503int MoxaPortRxQueue(int port)
2504{
2505 void __iomem *ofsAddr;
2506 ushort rptr, wptr, mask;
2507 int len;
2508
2509 ofsAddr = moxaTableAddr[port];
2510 rptr = readw(ofsAddr + RXrptr);
2511 wptr = readw(ofsAddr + RXwptr);
2512 mask = readw(ofsAddr + RX_mask);
2513 len = (wptr - rptr) & mask;
2514 return (len);
2515}
2516
2517
2518void MoxaPortTxDisable(int port)
2519{
2520 void __iomem *ofsAddr;
2521
2522 ofsAddr = moxaTableAddr[port];
2523 moxafunc(ofsAddr, FC_SetXoffState, Magic_code);
2524}
2525
2526void MoxaPortTxEnable(int port)
2527{
2528 void __iomem *ofsAddr;
2529
2530 ofsAddr = moxaTableAddr[port];
2531 moxafunc(ofsAddr, FC_SetXonState, Magic_code);
2532}
2533
2534
2535int MoxaPortResetBrkCnt(int port)
2536{
2537 ushort cnt;
2538 cnt = moxaBreakCnt[port];
2539 moxaBreakCnt[port] = 0;
2540 return (cnt);
2541}
2542
2543
2544void MoxaPortSendBreak(int port, int ms100)
2545{
2546 void __iomem *ofsAddr;
2547
2548 ofsAddr = moxaTableAddr[port];
2549 if (ms100) {
2550 moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2551 moxadelay(ms100 * (HZ / 10));
2552 } else {
2553 moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2554 moxadelay(HZ / 4); /* 250 ms */
2555 }
2556 moxafunc(ofsAddr, FC_StopBreak, Magic_code);
2557}
2558
2559static int moxa_get_serial_info(struct moxa_str *info,
2560 struct serial_struct __user *retinfo)
2561{
2562 struct serial_struct tmp;
2563
2564 memset(&tmp, 0, sizeof(tmp));
2565 tmp.type = info->type;
2566 tmp.line = info->port;
2567 tmp.port = 0;
2568 tmp.irq = 0;
2569 tmp.flags = info->asyncflags;
2570 tmp.baud_base = 921600;
2571 tmp.close_delay = info->close_delay;
2572 tmp.closing_wait = info->closing_wait;
2573 tmp.custom_divisor = 0;
2574 tmp.hub6 = 0;
2575 if(copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2576 return -EFAULT;
2577 return (0);
2578}
2579
2580
2581static int moxa_set_serial_info(struct moxa_str *info,
2582 struct serial_struct __user *new_info)
2583{
2584 struct serial_struct new_serial;
2585
2586 if(copy_from_user(&new_serial, new_info, sizeof(new_serial)))
2587 return -EFAULT;
2588
2589 if ((new_serial.irq != 0) ||
2590 (new_serial.port != 0) ||
2591// (new_serial.type != info->type) ||
2592 (new_serial.custom_divisor != 0) ||
2593 (new_serial.baud_base != 921600))
2594 return (-EPERM);
2595
2596 if (!capable(CAP_SYS_ADMIN)) {
2597 if (((new_serial.flags & ~ASYNC_USR_MASK) !=
2598 (info->asyncflags & ~ASYNC_USR_MASK)))
2599 return (-EPERM);
2600 } else {
2601 info->close_delay = new_serial.close_delay * HZ / 100;
2602 info->closing_wait = new_serial.closing_wait * HZ / 100;
2603 }
2604
2605 new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
2606 new_serial.flags |= (info->asyncflags & ASYNC_FLAGS);
2607
2608 if (new_serial.type == PORT_16550A) {
2609 MoxaSetFifo(info->port, 1);
2610 } else {
2611 MoxaSetFifo(info->port, 0);
2612 }
2613
2614 info->type = new_serial.type;
2615 return (0);
2616}
2617
2618
2619
2620/*****************************************************************************
2621 * Static local functions: *
2622 *****************************************************************************/
2623/*
2624 * moxadelay - delays a specified number ticks
2625 */
2626static void moxadelay(int tick)
2627{
2628 unsigned long st, et;
2629
2630 st = jiffies;
2631 et = st + tick;
2632 while (time_before(jiffies, et));
2633}
2634
2635static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
2636{
2637
2638 writew(arg, ofsAddr + FuncArg);
2639 writew(cmd, ofsAddr + FuncCode);
2640 wait_finish(ofsAddr);
2641}
2642
2643static void wait_finish(void __iomem *ofsAddr)
2644{
2645 unsigned long i, j;
2646
2647 i = jiffies;
2648 while (readw(ofsAddr + FuncCode) != 0) {
2649 j = jiffies;
2650 if ((j - i) > moxaFuncTout) {
2651 return;
2652 }
2653 }
2654}
2655
2656static void low_water_check(void __iomem *ofsAddr)
2657{
2658 int len;
2659 ushort rptr, wptr, mask;
2660
2661 if (readb(ofsAddr + FlagStat) & Xoff_state) {
2662 rptr = readw(ofsAddr + RXrptr);
2663 wptr = readw(ofsAddr + RXwptr);
2664 mask = readw(ofsAddr + RX_mask);
2665 len = (wptr - rptr) & mask;
2666 if (len <= Low_water)
2667 moxafunc(ofsAddr, FC_SendXon, 0);
2668 }
2669}
2670
2671static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
2672{
2673 void __iomem *baseAddr;
2674 int i;
2675
2676 if(copy_from_user(moxaBuff, tmp, len))
2677 return -EFAULT;
2678 baseAddr = moxaBaseAddr[cardno];
2679 writeb(HW_reset, baseAddr + Control_reg); /* reset */
2680 moxadelay(1); /* delay 10 ms */
2681 for (i = 0; i < 4096; i++)
2682 writeb(0, baseAddr + i); /* clear fix page */
2683 for (i = 0; i < len; i++)
2684 writeb(moxaBuff[i], baseAddr + i); /* download BIOS */
2685 writeb(0, baseAddr + Control_reg); /* restart */
2686 return (0);
2687}
2688
2689static int moxafindcard(int cardno)
2690{
2691 void __iomem *baseAddr;
2692 ushort tmp;
2693
2694 baseAddr = moxaBaseAddr[cardno];
2695 switch (moxa_boards[cardno].boardType) {
2696 case MOXA_BOARD_C218_ISA:
2697 case MOXA_BOARD_C218_PCI:
2698 if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) {
2699 return (-1);
2700 }
2701 break;
2702 case MOXA_BOARD_CP204J:
2703 if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) {
2704 return (-1);
2705 }
2706 break;
2707 default:
2708 if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) {
2709 return (-1);
2710 }
2711 if ((tmp = readw(baseAddr + C320_status)) != STS_init) {
2712 return (-2);
2713 }
2714 }
2715 return (0);
2716}
2717
2718static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
2719{
2720 void __iomem *baseAddr;
2721 int i;
2722
2723 if(len > sizeof(moxaBuff))
2724 return -EINVAL;
2725 if(copy_from_user(moxaBuff, tmp, len))
2726 return -EFAULT;
2727 baseAddr = moxaBaseAddr[cardno];
2728 writew(len - 7168 - 2, baseAddr + C320bapi_len);
2729 writeb(1, baseAddr + Control_reg); /* Select Page 1 */
2730 for (i = 0; i < 7168; i++)
2731 writeb(moxaBuff[i], baseAddr + DynPage_addr + i);
2732 writeb(2, baseAddr + Control_reg); /* Select Page 2 */
2733 for (i = 0; i < (len - 7168); i++)
2734 writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i);
2735 return (0);
2736}
2737
2738static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
2739{
2740 void __iomem *baseAddr, *ofsAddr;
2741 int retval, port, i;
2742
2743 if(copy_from_user(moxaBuff, tmp, len))
2744 return -EFAULT;
2745 baseAddr = moxaBaseAddr[cardno];
2746 switch (moxa_boards[cardno].boardType) {
2747 case MOXA_BOARD_C218_ISA:
2748 case MOXA_BOARD_C218_PCI:
2749 case MOXA_BOARD_CP204J:
2750 retval = moxaloadc218(cardno, baseAddr, len);
2751 if (retval)
2752 return (retval);
2753 port = cardno * MAX_PORTS_PER_BOARD;
2754 for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
2755 moxaChkPort[port] = 1;
2756 moxaCurBaud[port] = 9600L;
2757 moxaDCDState[port] = 0;
2758 moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i;
2759 ofsAddr = moxaTableAddr[port];
2760 writew(C218rx_mask, ofsAddr + RX_mask);
2761 writew(C218tx_mask, ofsAddr + TX_mask);
2762 writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);
2763 writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);
2764
2765 writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);
2766 writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);
2767
2768 }
2769 break;
2770 default:
2771 retval = moxaloadc320(cardno, baseAddr, len,
2772 &moxa_boards[cardno].numPorts);
2773 if (retval)
2774 return (retval);
2775 port = cardno * MAX_PORTS_PER_BOARD;
2776 for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
2777 moxaChkPort[port] = 1;
2778 moxaCurBaud[port] = 9600L;
2779 moxaDCDState[port] = 0;
2780 moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i;
2781 ofsAddr = moxaTableAddr[port];
2782 if (moxa_boards[cardno].numPorts == 8) {
2783 writew(C320p8rx_mask, ofsAddr + RX_mask);
2784 writew(C320p8tx_mask, ofsAddr + TX_mask);
2785 writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);
2786 writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);
2787 writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);
2788 writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);
2789
2790 } else if (moxa_boards[cardno].numPorts == 16) {
2791 writew(C320p16rx_mask, ofsAddr + RX_mask);
2792 writew(C320p16tx_mask, ofsAddr + TX_mask);
2793 writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);
2794 writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);
2795 writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);
2796 writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);
2797
2798 } else if (moxa_boards[cardno].numPorts == 24) {
2799 writew(C320p24rx_mask, ofsAddr + RX_mask);
2800 writew(C320p24tx_mask, ofsAddr + TX_mask);
2801 writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);
2802 writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);
2803 writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);
2804 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
2805 } else if (moxa_boards[cardno].numPorts == 32) {
2806 writew(C320p32rx_mask, ofsAddr + RX_mask);
2807 writew(C320p32tx_mask, ofsAddr + TX_mask);
2808 writew(C320p32tx_ofs, ofsAddr + Ofs_txb);
2809 writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);
2810 writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);
2811 writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);
2812 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
2813 }
2814 }
2815 break;
2816 }
Dirk Eibach01cfaf02006-08-27 01:23:36 -07002817 loadstat[cardno] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818 return (0);
2819}
2820
2821static int moxaloadc218(int cardno, void __iomem *baseAddr, int len)
2822{
2823 char retry;
2824 int i, j, len1, len2;
2825 ushort usum, *ptr, keycode;
2826
2827 if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J)
2828 keycode = CP204J_KeyCode;
2829 else
2830 keycode = C218_KeyCode;
2831 usum = 0;
2832 len1 = len >> 1;
2833 ptr = (ushort *) moxaBuff;
2834 for (i = 0; i < len1; i++)
Dirk Eibach01cfaf02006-08-27 01:23:36 -07002835 usum += le16_to_cpu(*(ptr + i));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 retry = 0;
2837 do {
2838 len1 = len >> 1;
2839 j = 0;
2840 while (len1) {
2841 len2 = (len1 > 2048) ? 2048 : len1;
2842 len1 -= len2;
2843 for (i = 0; i < len2 << 1; i++)
2844 writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i);
2845 j += i;
2846
2847 writew(len2, baseAddr + C218DLoad_len);
2848 writew(0, baseAddr + C218_key);
2849 for (i = 0; i < 100; i++) {
2850 if (readw(baseAddr + C218_key) == keycode)
2851 break;
2852 moxadelay(1); /* delay 10 ms */
2853 }
2854 if (readw(baseAddr + C218_key) != keycode) {
2855 return (-1);
2856 }
2857 }
2858 writew(0, baseAddr + C218DLoad_len);
2859 writew(usum, baseAddr + C218check_sum);
2860 writew(0, baseAddr + C218_key);
2861 for (i = 0; i < 100; i++) {
2862 if (readw(baseAddr + C218_key) == keycode)
2863 break;
2864 moxadelay(1); /* delay 10 ms */
2865 }
2866 retry++;
2867 } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3));
2868 if (readb(baseAddr + C218chksum_ok) != 1) {
2869 return (-1);
2870 }
2871 writew(0, baseAddr + C218_key);
2872 for (i = 0; i < 100; i++) {
2873 if (readw(baseAddr + Magic_no) == Magic_code)
2874 break;
2875 moxadelay(1); /* delay 10 ms */
2876 }
2877 if (readw(baseAddr + Magic_no) != Magic_code) {
2878 return (-1);
2879 }
2880 writew(1, baseAddr + Disable_IRQ);
2881 writew(0, baseAddr + Magic_no);
2882 for (i = 0; i < 100; i++) {
2883 if (readw(baseAddr + Magic_no) == Magic_code)
2884 break;
2885 moxadelay(1); /* delay 10 ms */
2886 }
2887 if (readw(baseAddr + Magic_no) != Magic_code) {
2888 return (-1);
2889 }
2890 moxaCard = 1;
2891 moxaIntNdx[cardno] = baseAddr + IRQindex;
2892 moxaIntPend[cardno] = baseAddr + IRQpending;
2893 moxaIntTable[cardno] = baseAddr + IRQtable;
2894 return (0);
2895}
2896
2897static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts)
2898{
2899 ushort usum;
2900 int i, j, wlen, len2, retry;
2901 ushort *uptr;
2902
2903 usum = 0;
2904 wlen = len >> 1;
2905 uptr = (ushort *) moxaBuff;
2906 for (i = 0; i < wlen; i++)
Dirk Eibach01cfaf02006-08-27 01:23:36 -07002907 usum += le16_to_cpu(uptr[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 retry = 0;
2909 j = 0;
2910 do {
2911 while (wlen) {
2912 if (wlen > 2048)
2913 len2 = 2048;
2914 else
2915 len2 = wlen;
2916 wlen -= len2;
2917 len2 <<= 1;
2918 for (i = 0; i < len2; i++)
2919 writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i);
2920 len2 >>= 1;
2921 j += i;
2922 writew(len2, baseAddr + C320DLoad_len);
2923 writew(0, baseAddr + C320_key);
2924 for (i = 0; i < 10; i++) {
2925 if (readw(baseAddr + C320_key) == C320_KeyCode)
2926 break;
2927 moxadelay(1);
2928 }
2929 if (readw(baseAddr + C320_key) != C320_KeyCode)
2930 return (-1);
2931 }
2932 writew(0, baseAddr + C320DLoad_len);
2933 writew(usum, baseAddr + C320check_sum);
2934 writew(0, baseAddr + C320_key);
2935 for (i = 0; i < 10; i++) {
2936 if (readw(baseAddr + C320_key) == C320_KeyCode)
2937 break;
2938 moxadelay(1);
2939 }
2940 retry++;
2941 } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3));
2942 if (readb(baseAddr + C320chksum_ok) != 1)
2943 return (-1);
2944 writew(0, baseAddr + C320_key);
2945 for (i = 0; i < 600; i++) {
2946 if (readw(baseAddr + Magic_no) == Magic_code)
2947 break;
2948 moxadelay(1);
2949 }
2950 if (readw(baseAddr + Magic_no) != Magic_code)
2951 return (-100);
2952
2953 if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */
2954 writew(0x3800, baseAddr + TMS320_PORT1);
2955 writew(0x3900, baseAddr + TMS320_PORT2);
2956 writew(28499, baseAddr + TMS320_CLOCK);
2957 } else {
2958 writew(0x3200, baseAddr + TMS320_PORT1);
2959 writew(0x3400, baseAddr + TMS320_PORT2);
2960 writew(19999, baseAddr + TMS320_CLOCK);
2961 }
2962 writew(1, baseAddr + Disable_IRQ);
2963 writew(0, baseAddr + Magic_no);
2964 for (i = 0; i < 500; i++) {
2965 if (readw(baseAddr + Magic_no) == Magic_code)
2966 break;
2967 moxadelay(1);
2968 }
2969 if (readw(baseAddr + Magic_no) != Magic_code)
2970 return (-102);
2971
2972 j = readw(baseAddr + Module_cnt);
2973 if (j <= 0)
2974 return (-101);
2975 *numPorts = j * 8;
2976 writew(j, baseAddr + Module_no);
2977 writew(0, baseAddr + Magic_no);
2978 for (i = 0; i < 600; i++) {
2979 if (readw(baseAddr + Magic_no) == Magic_code)
2980 break;
2981 moxadelay(1);
2982 }
2983 if (readw(baseAddr + Magic_no) != Magic_code)
2984 return (-102);
2985 moxaCard = 1;
2986 moxaIntNdx[cardno] = baseAddr + IRQindex;
2987 moxaIntPend[cardno] = baseAddr + IRQpending;
2988 moxaIntTable[cardno] = baseAddr + IRQtable;
2989 return (0);
2990}
2991
2992#if 0
2993long MoxaPortGetCurBaud(int port)
2994{
2995
2996 if (moxaChkPort[port] == 0)
2997 return (0);
2998 return (moxaCurBaud[port]);
2999}
3000#endif /* 0 */
3001
3002static void MoxaSetFifo(int port, int enable)
3003{
3004 void __iomem *ofsAddr = moxaTableAddr[port];
3005
3006 if (!enable) {
3007 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0);
3008 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1);
3009 } else {
3010 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3);
3011 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16);
3012 }
3013}
3014
3015#if 0
3016int MoxaPortSetMode(int port, int databits, int stopbits, int parity)
3017{
3018 void __iomem *ofsAddr;
3019 int val;
3020
3021 val = 0;
3022 switch (databits) {
3023 case 5:
3024 val |= 0;
3025 break;
3026 case 6:
3027 val |= 1;
3028 break;
3029 case 7:
3030 val |= 2;
3031 break;
3032 case 8:
3033 val |= 3;
3034 break;
3035 default:
3036 return (-1);
3037 }
3038 switch (stopbits) {
3039 case 0:
3040 val |= 0;
3041 break; /* stop bits 1.5 */
3042 case 1:
3043 val |= 0;
3044 break;
3045 case 2:
3046 val |= 4;
3047 break;
3048 default:
3049 return (-1);
3050 }
3051 switch (parity) {
3052 case 0:
3053 val |= 0x00;
3054 break; /* None */
3055 case 1:
3056 val |= 0x08;
3057 break; /* Odd */
3058 case 2:
3059 val |= 0x18;
3060 break; /* Even */
3061 case 3:
3062 val |= 0x28;
3063 break; /* Mark */
3064 case 4:
3065 val |= 0x38;
3066 break; /* Space */
3067 default:
3068 return (-1);
3069 }
3070 ofsAddr = moxaTableAddr[port];
3071 moxafunc(ofsAddr, FC_SetMode, val);
3072 return (0);
3073}
3074
3075int MoxaPortTxBufSize(int port)
3076{
3077 void __iomem *ofsAddr;
3078 int size;
3079
3080 ofsAddr = moxaTableAddr[port];
3081 size = readw(ofsAddr + TX_mask);
3082 return (size);
3083}
3084
3085int MoxaPortRxBufSize(int port)
3086{
3087 void __iomem *ofsAddr;
3088 int size;
3089
3090 ofsAddr = moxaTableAddr[port];
3091 size = readw(ofsAddr + RX_mask);
3092 return (size);
3093}
3094
3095int MoxaPortRxFree(int port)
3096{
3097 void __iomem *ofsAddr;
3098 ushort rptr, wptr, mask;
3099 int len;
3100
3101 ofsAddr = moxaTableAddr[port];
3102 rptr = readw(ofsAddr + RXrptr);
3103 wptr = readw(ofsAddr + RXwptr);
3104 mask = readw(ofsAddr + RX_mask);
3105 len = mask - ((wptr - rptr) & mask);
3106 return (len);
3107}
3108int MoxaPortGetBrkCnt(int port)
3109{
3110 return (moxaBreakCnt[port]);
3111}
3112
3113void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue)
3114{
3115 void __iomem *ofsAddr;
3116
3117 ofsAddr = moxaTableAddr[port];
3118 writew(xonValue, ofsAddr + FuncArg);
3119 writew(xoffValue, ofsAddr + FuncArg1);
3120 writew(FC_SetXonXoff, ofsAddr + FuncCode);
3121 wait_finish(ofsAddr);
3122}
3123
3124int MoxaPortIsTxHold(int port)
3125{
3126 void __iomem *ofsAddr;
3127 int val;
3128
3129 ofsAddr = moxaTableAddr[port];
3130 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
3131 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
3132 moxafunc(ofsAddr, FC_GetCCSR, 0);
3133 val = readw(ofsAddr + FuncArg);
3134 if (val & 0x04)
3135 return (1);
3136 } else {
3137 if (readw(ofsAddr + FlagStat) & Tx_flowOff)
3138 return (1);
3139 }
3140 return (0);
3141}
3142#endif