1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/module.h>
24#include <linux/types.h>
25#include <linux/mm.h>
26#include <linux/ioport.h>
27#include <linux/errno.h>
28#include <linux/signal.h>
29#include <linux/sched.h>
30#include <linux/timer.h>
31#include <linux/interrupt.h>
32#include <linux/tty.h>
33#include <linux/tty_flip.h>
34#include <linux/major.h>
35#include <linux/string.h>
36#include <linux/fcntl.h>
37#include <linux/ptrace.h>
38#include <linux/serial.h>
39#include <linux/tty_driver.h>
40#include <linux/delay.h>
41#include <linux/pci.h>
42#include <linux/init.h>
43#include <linux/bitops.h>
44#include <linux/completion.h>
45
46#include <asm/system.h>
47#include <asm/io.h>
48#include <asm/uaccess.h>
49
50#define MOXA_VERSION "5.1k"
51
52#define MOXAMAJOR 172
53#define MOXACUMAJOR 173
54
55#define MAX_BOARDS 4
56#define MAX_PORTS_PER_BOARD 32
57#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD)
58
59
60
61
62#define MOXA_BUS_TYPE_ISA 0
63#define MOXA_BUS_TYPE_PCI 1
64
65enum {
66 MOXA_BOARD_C218_PCI = 1,
67 MOXA_BOARD_C218_ISA,
68 MOXA_BOARD_C320_PCI,
69 MOXA_BOARD_C320_ISA,
70 MOXA_BOARD_CP204J,
71};
72
73static char *moxa_brdname[] =
74{
75 "C218 Turbo PCI series",
76 "C218 Turbo ISA series",
77 "C320 Turbo PCI series",
78 "C320 Turbo ISA series",
79 "CP-204J series",
80};
81
82#ifdef CONFIG_PCI
83static struct pci_device_id moxa_pcibrds[] = {
84 { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218),
85 .driver_data = MOXA_BOARD_C218_PCI },
86 { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320),
87 .driver_data = MOXA_BOARD_C320_PCI },
88 { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP204J),
89 .driver_data = MOXA_BOARD_CP204J },
90 { 0 }
91};
92MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
93#endif
94
95struct moxa_isa_board_conf {
96 int boardType;
97 int numPorts;
98 unsigned long baseAddr;
99};
100
101static struct moxa_isa_board_conf moxa_isa_boards[] =
102{
103
104};
105
106static struct moxa_board_conf {
107 int boardType;
108 int numPorts;
109 unsigned long baseAddr;
110 int busType;
111
112 int loadstat;
113
114 void __iomem *basemem;
115 void __iomem *intNdx;
116 void __iomem *intPend;
117 void __iomem *intTable;
118} moxa_boards[MAX_BOARDS];
119
120struct mxser_mstatus {
121 tcflag_t cflag;
122 int cts;
123 int dsr;
124 int ri;
125 int dcd;
126};
127
128struct moxaq_str {
129 int inq;
130 int outq;
131};
132
133struct moxa_port {
134 int type;
135 int port;
136 int close_delay;
137 unsigned short closing_wait;
138 int count;
139 int blocked_open;
140 long event;
141 int asyncflags;
142 unsigned long statusflags;
143 struct tty_struct *tty;
144 int cflag;
145 wait_queue_head_t open_wait;
146 struct completion close_wait;
147
148 struct timer_list emptyTimer;
149
150 char chkPort;
151 char lineCtrl;
152 void __iomem *tableAddr;
153 long curBaud;
154 char DCDState;
155 char lowChkFlag;
156
157 ushort breakCnt;
158};
159
160
161#define TXSTOPPED 0x1
162#define LOWWAIT 0x2
163#define EMPTYWAIT 0x4
164#define THROTTLE 0x8
165
166#define SERIAL_DO_RESTART
167
168#define WAKEUP_CHARS 256
169
170static int ttymajor = MOXAMAJOR;
171
172#ifdef MODULE
173static int baseaddr[4];
174static int type[4];
175static int numports[4];
176#endif
177
178MODULE_AUTHOR("William Chen");
179MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
180MODULE_LICENSE("GPL");
181#ifdef MODULE
182module_param_array(type, int, NULL, 0);
183module_param_array(baseaddr, int, NULL, 0);
184module_param_array(numports, int, NULL, 0);
185#endif
186module_param(ttymajor, int, 0);
187
188
189
190
191static int moxa_open(struct tty_struct *, struct file *);
192static void moxa_close(struct tty_struct *, struct file *);
193static int moxa_write(struct tty_struct *, const unsigned char *, int);
194static int moxa_write_room(struct tty_struct *);
195static void moxa_flush_buffer(struct tty_struct *);
196static int moxa_chars_in_buffer(struct tty_struct *);
197static void moxa_flush_chars(struct tty_struct *);
198static void moxa_put_char(struct tty_struct *, unsigned char);
199static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
200static void moxa_throttle(struct tty_struct *);
201static void moxa_unthrottle(struct tty_struct *);
202static void moxa_set_termios(struct tty_struct *, struct ktermios *);
203static void moxa_stop(struct tty_struct *);
204static void moxa_start(struct tty_struct *);
205static void moxa_hangup(struct tty_struct *);
206static int moxa_tiocmget(struct tty_struct *tty, struct file *file);
207static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
208 unsigned int set, unsigned int clear);
209static void moxa_poll(unsigned long);
210static void moxa_set_tty_param(struct tty_struct *);
211static int moxa_block_till_ready(struct tty_struct *, struct file *,
212 struct moxa_port *);
213static void moxa_setup_empty_event(struct tty_struct *);
214static void moxa_check_xmit_empty(unsigned long);
215static void moxa_shut_down(struct moxa_port *);
216static void moxa_receive_data(struct moxa_port *);
217
218
219
220static void MoxaDriverInit(void);
221static int MoxaDriverIoctl(unsigned int, unsigned long, int);
222static int MoxaDriverPoll(void);
223static int MoxaPortsOfCard(int);
224static int MoxaPortIsValid(int);
225static void MoxaPortEnable(int);
226static void MoxaPortDisable(int);
227static long MoxaPortGetMaxBaud(int);
228static long MoxaPortSetBaud(int, long);
229static int MoxaPortSetTermio(int, struct ktermios *, speed_t);
230static int MoxaPortGetLineOut(int, int *, int *);
231static void MoxaPortLineCtrl(int, int, int);
232static void MoxaPortFlowCtrl(int, int, int, int, int, int);
233static int MoxaPortLineStatus(int);
234static int MoxaPortDCDChange(int);
235static int MoxaPortDCDON(int);
236static void MoxaPortFlushData(int, int);
237static int MoxaPortWriteData(int, unsigned char *, int);
238static int MoxaPortReadData(int, struct tty_struct *tty);
239static int MoxaPortTxQueue(int);
240static int MoxaPortRxQueue(int);
241static int MoxaPortTxFree(int);
242static void MoxaPortTxDisable(int);
243static void MoxaPortTxEnable(int);
244static int MoxaPortResetBrkCnt(int);
245static void MoxaPortSendBreak(int, int);
246static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *);
247static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *);
248static void MoxaSetFifo(int port, int enable);
249
250static const struct tty_operations moxa_ops = {
251 .open = moxa_open,
252 .close = moxa_close,
253 .write = moxa_write,
254 .write_room = moxa_write_room,
255 .flush_buffer = moxa_flush_buffer,
256 .chars_in_buffer = moxa_chars_in_buffer,
257 .flush_chars = moxa_flush_chars,
258 .put_char = moxa_put_char,
259 .ioctl = moxa_ioctl,
260 .throttle = moxa_throttle,
261 .unthrottle = moxa_unthrottle,
262 .set_termios = moxa_set_termios,
263 .stop = moxa_stop,
264 .start = moxa_start,
265 .hangup = moxa_hangup,
266 .tiocmget = moxa_tiocmget,
267 .tiocmset = moxa_tiocmset,
268};
269
270static struct tty_driver *moxaDriver;
271static struct moxa_port moxa_ports[MAX_PORTS];
272static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
273static DEFINE_SPINLOCK(moxa_lock);
274
275#ifdef CONFIG_PCI
276static int __devinit moxa_pci_probe(struct pci_dev *pdev,
277 const struct pci_device_id *ent)
278{
279 struct moxa_board_conf *board;
280 unsigned int i;
281 int board_type = ent->driver_data;
282 int retval;
283
284 retval = pci_enable_device(pdev);
285 if (retval) {
286 dev_err(&pdev->dev, "can't enable pci device\n");
287 goto err;
288 }
289
290 for (i = 0; i < MAX_BOARDS; i++)
291 if (moxa_boards[i].basemem == NULL)
292 break;
293
294 retval = -ENODEV;
295 if (i >= MAX_BOARDS) {
296 dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards "
297 "found. Board is ignored.\n", MAX_BOARDS);
298 goto err;
299 }
300
301 board = &moxa_boards[i];
302 board->basemem = pci_iomap(pdev, 2, 0x4000);
303 if (board->basemem == NULL) {
304 dev_err(&pdev->dev, "can't remap io space 2\n");
305 goto err;
306 }
307
308 board->boardType = board_type;
309 switch (board_type) {
310 case MOXA_BOARD_C218_ISA:
311 case MOXA_BOARD_C218_PCI:
312 board->numPorts = 8;
313 break;
314
315 case MOXA_BOARD_CP204J:
316 board->numPorts = 4;
317 break;
318 default:
319 board->numPorts = 0;
320 break;
321 }
322 board->busType = MOXA_BUS_TYPE_PCI;
323
324 pci_set_drvdata(pdev, board);
325
326 return (0);
327err:
328 return retval;
329}
330
331static void __devexit moxa_pci_remove(struct pci_dev *pdev)
332{
333 struct moxa_board_conf *brd = pci_get_drvdata(pdev);
334
335 pci_iounmap(pdev, brd->basemem);
336 brd->basemem = NULL;
337}
338
339static struct pci_driver moxa_pci_driver = {
340 .name = "moxa",
341 .id_table = moxa_pcibrds,
342 .probe = moxa_pci_probe,
343 .remove = __devexit_p(moxa_pci_remove)
344};
345#endif
346
347static int __init moxa_init(void)
348{
349 int i, numBoards, retval = 0;
350 struct moxa_port *ch;
351
352 printk(KERN_INFO "MOXA Intellio family driver version %s\n",
353 MOXA_VERSION);
354 moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
355 if (!moxaDriver)
356 return -ENOMEM;
357
358 moxaDriver->owner = THIS_MODULE;
359 moxaDriver->name = "ttyMX";
360 moxaDriver->major = ttymajor;
361 moxaDriver->minor_start = 0;
362 moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;
363 moxaDriver->subtype = SERIAL_TYPE_NORMAL;
364 moxaDriver->init_termios = tty_std_termios;
365 moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
366 moxaDriver->init_termios.c_ispeed = 9600;
367 moxaDriver->init_termios.c_ospeed = 9600;
368 moxaDriver->flags = TTY_DRIVER_REAL_RAW;
369 tty_set_operations(moxaDriver, &moxa_ops);
370
371 for (i = 0, ch = moxa_ports; i < MAX_PORTS; i++, ch++) {
372 ch->type = PORT_16550A;
373 ch->port = i;
374 ch->close_delay = 5 * HZ / 10;
375 ch->closing_wait = 30 * HZ;
376 ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
377 init_waitqueue_head(&ch->open_wait);
378 init_completion(&ch->close_wait);
379
380 setup_timer(&ch->emptyTimer, moxa_check_xmit_empty,
381 (unsigned long)ch);
382 }
383
384 pr_debug("Moxa tty devices major number = %d\n", ttymajor);
385
386 if (tty_register_driver(moxaDriver)) {
387 printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
388 put_tty_driver(moxaDriver);
389 return -1;
390 }
391
392 mod_timer(&moxaTimer, jiffies + HZ / 50);
393
394
395 numBoards = 0;
396 for (i = 0; i < MAX_BOARDS; i++) {
397 if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) ||
398 (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) {
399 moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType;
400 if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
401 moxa_boards[numBoards].numPorts = 8;
402 else
403 moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;
404 moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
405 moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;
406 pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
407 numBoards + 1,
408 moxa_brdname[moxa_boards[numBoards].boardType-1],
409 moxa_boards[numBoards].baseAddr);
410 numBoards++;
411 }
412 }
413
414#ifdef MODULE
415 for (i = 0; i < MAX_BOARDS; i++) {
416 if ((type[i] == MOXA_BOARD_C218_ISA) ||
417 (type[i] == MOXA_BOARD_C320_ISA)) {
418 pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
419 numBoards + 1, moxa_brdname[type[i] - 1],
420 (unsigned long)baseaddr[i]);
421 if (numBoards >= MAX_BOARDS) {
422 printk(KERN_WARNING "More than %d MOXA "
423 "Intellio family boards found. Board "
424 "is ignored.\n", MAX_BOARDS);
425 continue;
426 }
427 moxa_boards[numBoards].boardType = type[i];
428 if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
429 moxa_boards[numBoards].numPorts = 8;
430 else
431 moxa_boards[numBoards].numPorts = numports[i];
432 moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
433 moxa_boards[numBoards].baseAddr = baseaddr[i];
434 numBoards++;
435 }
436 }
437#endif
438
439#ifdef CONFIG_PCI
440 retval = pci_register_driver(&moxa_pci_driver);
441 if (retval) {
442 printk(KERN_ERR "Can't register moxa pci driver!\n");
443 if (numBoards)
444 retval = 0;
445 }
446#endif
447
448 for (i = 0; i < numBoards; i++) {
449 moxa_boards[i].basemem = ioremap(moxa_boards[i].baseAddr,
450 0x4000);
451 }
452
453 return retval;
454}
455
456static void __exit moxa_exit(void)
457{
458 int i;
459
460 del_timer_sync(&moxaTimer);
461
462 for (i = 0; i < MAX_PORTS; i++)
463 del_timer_sync(&moxa_ports[i].emptyTimer);
464
465 if (tty_unregister_driver(moxaDriver))
466 printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
467 "serial driver\n");
468 put_tty_driver(moxaDriver);
469
470#ifdef CONFIG_PCI
471 pci_unregister_driver(&moxa_pci_driver);
472#endif
473
474 for (i = 0; i < MAX_BOARDS; i++)
475 if (moxa_boards[i].basemem)
476 iounmap(moxa_boards[i].basemem);
477}
478
479module_init(moxa_init);
480module_exit(moxa_exit);
481
482static int moxa_open(struct tty_struct *tty, struct file *filp)
483{
484 struct moxa_port *ch;
485 int port;
486 int retval;
487
488 port = tty->index;
489 if (port == MAX_PORTS) {
490 return (0);
491 }
492 if (!MoxaPortIsValid(port)) {
493 tty->driver_data = NULL;
494 return (-ENODEV);
495 }
496
497 ch = &moxa_ports[port];
498 ch->count++;
499 tty->driver_data = ch;
500 ch->tty = tty;
501 if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
502 ch->statusflags = 0;
503 moxa_set_tty_param(tty);
504 MoxaPortLineCtrl(ch->port, 1, 1);
505 MoxaPortEnable(ch->port);
506 ch->asyncflags |= ASYNC_INITIALIZED;
507 }
508 retval = moxa_block_till_ready(tty, filp, ch);
509
510 moxa_unthrottle(tty);
511
512 if (ch->type == PORT_16550A) {
513 MoxaSetFifo(ch->port, 1);
514 } else {
515 MoxaSetFifo(ch->port, 0);
516 }
517
518 return (retval);
519}
520
521static void moxa_close(struct tty_struct *tty, struct file *filp)
522{
523 struct moxa_port *ch;
524 int port;
525
526 port = tty->index;
527 if (port == MAX_PORTS) {
528 return;
529 }
530 if (!MoxaPortIsValid(port)) {
531 pr_debug("Invalid portno in moxa_close\n");
532 tty->driver_data = NULL;
533 return;
534 }
535 if (tty->driver_data == NULL) {
536 return;
537 }
538 if (tty_hung_up_p(filp)) {
539 return;
540 }
541 ch = (struct moxa_port *) tty->driver_data;
542
543 if ((tty->count == 1) && (ch->count != 1)) {
544 printk(KERN_WARNING "moxa_close: bad serial port count; "
545 "tty->count is 1, ch->count is %d\n", ch->count);
546 ch->count = 1;
547 }
548 if (--ch->count < 0) {
549 printk(KERN_WARNING "moxa_close: bad serial port count, "
550 "device=%s\n", tty->name);
551 ch->count = 0;
552 }
553 if (ch->count) {
554 return;
555 }
556 ch->asyncflags |= ASYNC_CLOSING;
557
558 ch->cflag = tty->termios->c_cflag;
559 if (ch->asyncflags & ASYNC_INITIALIZED) {
560 moxa_setup_empty_event(tty);
561 tty_wait_until_sent(tty, 30 * HZ);
562 del_timer_sync(&moxa_ports[ch->port].emptyTimer);
563 }
564 moxa_shut_down(ch);
565 MoxaPortFlushData(port, 2);
566
567 if (tty->driver->flush_buffer)
568 tty->driver->flush_buffer(tty);
569 tty_ldisc_flush(tty);
570
571 tty->closing = 0;
572 ch->event = 0;
573 ch->tty = NULL;
574 if (ch->blocked_open) {
575 if (ch->close_delay) {
576 msleep_interruptible(jiffies_to_msecs(ch->close_delay));
577 }
578 wake_up_interruptible(&ch->open_wait);
579 }
580 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
581 complete_all(&ch->close_wait);
582}
583
584static int moxa_write(struct tty_struct *tty,
585 const unsigned char *buf, int count)
586{
587 struct moxa_port *ch;
588 int len, port;
589 unsigned long flags;
590
591 ch = (struct moxa_port *) tty->driver_data;
592 if (ch == NULL)
593 return (0);
594 port = ch->port;
595
596 spin_lock_irqsave(&moxa_lock, flags);
597 len = MoxaPortWriteData(port, (unsigned char *) buf, count);
598 spin_unlock_irqrestore(&moxa_lock, flags);
599
600
601
602
603
604 ch->statusflags |= LOWWAIT;
605 return (len);
606}
607
608static int moxa_write_room(struct tty_struct *tty)
609{
610 struct moxa_port *ch;
611
612 if (tty->stopped)
613 return (0);
614 ch = (struct moxa_port *) tty->driver_data;
615 if (ch == NULL)
616 return (0);
617 return (MoxaPortTxFree(ch->port));
618}
619
620static void moxa_flush_buffer(struct tty_struct *tty)
621{
622 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
623
624 if (ch == NULL)
625 return;
626 MoxaPortFlushData(ch->port, 1);
627 tty_wakeup(tty);
628}
629
630static int moxa_chars_in_buffer(struct tty_struct *tty)
631{
632 int chars;
633 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
634
635
636
637
638
639
640
641 if (ch == NULL)
642 return (0);
643 chars = MoxaPortTxQueue(ch->port);
644 if (chars) {
645
646
647
648
649 if (!(ch->statusflags & EMPTYWAIT))
650 moxa_setup_empty_event(tty);
651 }
652 return (chars);
653}
654
655static void moxa_flush_chars(struct tty_struct *tty)
656{
657
658
659
660
661}
662
663static void moxa_put_char(struct tty_struct *tty, unsigned char c)
664{
665 struct moxa_port *ch;
666 int port;
667 unsigned long flags;
668
669 ch = (struct moxa_port *) tty->driver_data;
670 if (ch == NULL)
671 return;
672 port = ch->port;
673 spin_lock_irqsave(&moxa_lock, flags);
674 MoxaPortWriteData(port, &c, 1);
675 spin_unlock_irqrestore(&moxa_lock, flags);
676
677
678
679 ch->statusflags |= LOWWAIT;
680}
681
682static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
683{
684 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
685 int port;
686 int flag = 0, dtr, rts;
687
688 port = tty->index;
689 if ((port != MAX_PORTS) && (!ch))
690 return (-EINVAL);
691
692 MoxaPortGetLineOut(ch->port, &dtr, &rts);
693 if (dtr)
694 flag |= TIOCM_DTR;
695 if (rts)
696 flag |= TIOCM_RTS;
697 dtr = MoxaPortLineStatus(ch->port);
698 if (dtr & 1)
699 flag |= TIOCM_CTS;
700 if (dtr & 2)
701 flag |= TIOCM_DSR;
702 if (dtr & 4)
703 flag |= TIOCM_CD;
704 return flag;
705}
706
707static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
708 unsigned int set, unsigned int clear)
709{
710 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
711 int port;
712 int dtr, rts;
713
714 port = tty->index;
715 if ((port != MAX_PORTS) && (!ch))
716 return (-EINVAL);
717
718 MoxaPortGetLineOut(ch->port, &dtr, &rts);
719 if (set & TIOCM_RTS)
720 rts = 1;
721 if (set & TIOCM_DTR)
722 dtr = 1;
723 if (clear & TIOCM_RTS)
724 rts = 0;
725 if (clear & TIOCM_DTR)
726 dtr = 0;
727 MoxaPortLineCtrl(ch->port, dtr, rts);
728 return 0;
729}
730
731static int moxa_ioctl(struct tty_struct *tty, struct file *file,
732 unsigned int cmd, unsigned long arg)
733{
734 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
735 register int port;
736 void __user *argp = (void __user *)arg;
737 int retval;
738
739 port = tty->index;
740 if ((port != MAX_PORTS) && (!ch))
741 return (-EINVAL);
742
743 switch (cmd) {
744 case TCSBRK:
745 retval = tty_check_change(tty);
746 if (retval)
747 return (retval);
748 moxa_setup_empty_event(tty);
749 tty_wait_until_sent(tty, 0);
750 if (!arg)
751 MoxaPortSendBreak(ch->port, 0);
752 return (0);
753 case TCSBRKP:
754 retval = tty_check_change(tty);
755 if (retval)
756 return (retval);
757 moxa_setup_empty_event(tty);
758 tty_wait_until_sent(tty, 0);
759 MoxaPortSendBreak(ch->port, arg);
760 return (0);
761 case TIOCGSOFTCAR:
762 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
763 case TIOCSSOFTCAR:
764 if(get_user(retval, (unsigned long __user *) argp))
765 return -EFAULT;
766 arg = retval;
767 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
768 (arg ? CLOCAL : 0));
769 if (C_CLOCAL(tty))
770 ch->asyncflags &= ~ASYNC_CHECK_CD;
771 else
772 ch->asyncflags |= ASYNC_CHECK_CD;
773 return (0);
774 case TIOCGSERIAL:
775 return moxa_get_serial_info(ch, argp);
776
777 case TIOCSSERIAL:
778 return moxa_set_serial_info(ch, argp);
779 default:
780 retval = MoxaDriverIoctl(cmd, arg, port);
781 }
782 return (retval);
783}
784
785static void moxa_throttle(struct tty_struct *tty)
786{
787 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
788
789 ch->statusflags |= THROTTLE;
790}
791
792static void moxa_unthrottle(struct tty_struct *tty)
793{
794 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
795
796 ch->statusflags &= ~THROTTLE;
797}
798
799static void moxa_set_termios(struct tty_struct *tty,
800 struct ktermios *old_termios)
801{
802 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
803
804 if (ch == NULL)
805 return;
806 moxa_set_tty_param(tty);
807 if (!(old_termios->c_cflag & CLOCAL) &&
808 (tty->termios->c_cflag & CLOCAL))
809 wake_up_interruptible(&ch->open_wait);
810}
811
812static void moxa_stop(struct tty_struct *tty)
813{
814 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
815
816 if (ch == NULL)
817 return;
818 MoxaPortTxDisable(ch->port);
819 ch->statusflags |= TXSTOPPED;
820}
821
822
823static void moxa_start(struct tty_struct *tty)
824{
825 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
826
827 if (ch == NULL)
828 return;
829
830 if (!(ch->statusflags & TXSTOPPED))
831 return;
832
833 MoxaPortTxEnable(ch->port);
834 ch->statusflags &= ~TXSTOPPED;
835}
836
837static void moxa_hangup(struct tty_struct *tty)
838{
839 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
840
841 moxa_flush_buffer(tty);
842 moxa_shut_down(ch);
843 ch->event = 0;
844 ch->count = 0;
845 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
846 ch->tty = NULL;
847 wake_up_interruptible(&ch->open_wait);
848}
849
850static void moxa_poll(unsigned long ignored)
851{
852 register int card;
853 struct moxa_port *ch;
854 struct tty_struct *tp;
855 int i, ports;
856
857 del_timer(&moxaTimer);
858
859 if (MoxaDriverPoll() < 0) {
860 mod_timer(&moxaTimer, jiffies + HZ / 50);
861 return;
862 }
863 for (card = 0; card < MAX_BOARDS; card++) {
864 if ((ports = MoxaPortsOfCard(card)) <= 0)
865 continue;
866 ch = &moxa_ports[card * MAX_PORTS_PER_BOARD];
867 for (i = 0; i < ports; i++, ch++) {
868 if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
869 continue;
870 if (!(ch->statusflags & THROTTLE) &&
871 (MoxaPortRxQueue(ch->port) > 0))
872 moxa_receive_data(ch);
873 if ((tp = ch->tty) == 0)
874 continue;
875 if (ch->statusflags & LOWWAIT) {
876 if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {
877 if (!tp->stopped) {
878 ch->statusflags &= ~LOWWAIT;
879 tty_wakeup(tp);
880 }
881 }
882 }
883 if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) {
884 tty_insert_flip_char(tp, 0, TTY_BREAK);
885 tty_schedule_flip(tp);
886 }
887 if (MoxaPortDCDChange(ch->port)) {
888 if (ch->asyncflags & ASYNC_CHECK_CD) {
889 if (MoxaPortDCDON(ch->port))
890 wake_up_interruptible(&ch->open_wait);
891 else {
892 tty_hangup(tp);
893 wake_up_interruptible(&ch->open_wait);
894 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
895 }
896 }
897 }
898 }
899 }
900
901 mod_timer(&moxaTimer, jiffies + HZ / 50);
902}
903
904
905
906static void moxa_set_tty_param(struct tty_struct *tty)
907{
908 register struct ktermios *ts;
909 struct moxa_port *ch;
910 int rts, cts, txflow, rxflow, xany;
911
912 ch = (struct moxa_port *) tty->driver_data;
913 ts = tty->termios;
914 if (ts->c_cflag & CLOCAL)
915 ch->asyncflags &= ~ASYNC_CHECK_CD;
916 else
917 ch->asyncflags |= ASYNC_CHECK_CD;
918 rts = cts = txflow = rxflow = xany = 0;
919 if (ts->c_cflag & CRTSCTS)
920 rts = cts = 1;
921 if (ts->c_iflag & IXON)
922 txflow = 1;
923 if (ts->c_iflag & IXOFF)
924 rxflow = 1;
925 if (ts->c_iflag & IXANY)
926 xany = 1;
927 MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany);
928 MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
929}
930
931static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
932 struct moxa_port *ch)
933{
934 DECLARE_WAITQUEUE(wait,current);
935 unsigned long flags;
936 int retval;
937 int do_clocal = C_CLOCAL(tty);
938
939
940
941
942
943 if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
944 if (ch->asyncflags & ASYNC_CLOSING)
945 wait_for_completion_interruptible(&ch->close_wait);
946#ifdef SERIAL_DO_RESTART
947 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
948 return (-EAGAIN);
949 else
950 return (-ERESTARTSYS);
951#else
952 return (-EAGAIN);
953#endif
954 }
955
956
957
958
959 if (filp->f_flags & O_NONBLOCK) {
960 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
961 return (0);
962 }
963
964
965
966 retval = 0;
967 add_wait_queue(&ch->open_wait, &wait);
968 pr_debug("block_til_ready before block: ttys%d, count = %d\n",
969 ch->port, ch->count);
970 spin_lock_irqsave(&moxa_lock, flags);
971 if (!tty_hung_up_p(filp))
972 ch->count--;
973 ch->blocked_open++;
974 spin_unlock_irqrestore(&moxa_lock, flags);
975
976 while (1) {
977 set_current_state(TASK_INTERRUPTIBLE);
978 if (tty_hung_up_p(filp) ||
979 !(ch->asyncflags & ASYNC_INITIALIZED)) {
980#ifdef SERIAL_DO_RESTART
981 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
982 retval = -EAGAIN;
983 else
984 retval = -ERESTARTSYS;
985#else
986 retval = -EAGAIN;
987#endif
988 break;
989 }
990 if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
991 MoxaPortDCDON(ch->port)))
992 break;
993
994 if (signal_pending(current)) {
995 retval = -ERESTARTSYS;
996 break;
997 }
998 schedule();
999 }
1000 set_current_state(TASK_RUNNING);
1001 remove_wait_queue(&ch->open_wait, &wait);
1002
1003 spin_lock_irqsave(&moxa_lock, flags);
1004 if (!tty_hung_up_p(filp))
1005 ch->count++;
1006 ch->blocked_open--;
1007 spin_unlock_irqrestore(&moxa_lock, flags);
1008 pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
1009 ch->port, ch->count);
1010 if (retval)
1011 return (retval);
1012
1013 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1014 return 0;
1015}
1016
1017static void moxa_setup_empty_event(struct tty_struct *tty)
1018{
1019 struct moxa_port *ch = tty->driver_data;
1020 unsigned long flags;
1021
1022 spin_lock_irqsave(&moxa_lock, flags);
1023 ch->statusflags |= EMPTYWAIT;
1024 mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ);
1025 spin_unlock_irqrestore(&moxa_lock, flags);
1026}
1027
1028static void moxa_check_xmit_empty(unsigned long data)
1029{
1030 struct moxa_port *ch;
1031
1032 ch = (struct moxa_port *) data;
1033 if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
1034 if (MoxaPortTxQueue(ch->port) == 0) {
1035 ch->statusflags &= ~EMPTYWAIT;
1036 tty_wakeup(ch->tty);
1037 return;
1038 }
1039 mod_timer(&moxa_ports[ch->port].emptyTimer,
1040 round_jiffies(jiffies + HZ));
1041 } else
1042 ch->statusflags &= ~EMPTYWAIT;
1043}
1044
1045static void moxa_shut_down(struct moxa_port *ch)
1046{
1047 struct tty_struct *tp;
1048
1049 if (!(ch->asyncflags & ASYNC_INITIALIZED))
1050 return;
1051
1052 tp = ch->tty;
1053
1054 MoxaPortDisable(ch->port);
1055
1056
1057
1058
1059 if (tp->termios->c_cflag & HUPCL)
1060 MoxaPortLineCtrl(ch->port, 0, 0);
1061
1062 ch->asyncflags &= ~ASYNC_INITIALIZED;
1063}
1064
1065static void moxa_receive_data(struct moxa_port *ch)
1066{
1067 struct tty_struct *tp;
1068 struct ktermios *ts;
1069 unsigned long flags;
1070
1071 ts = NULL;
1072 tp = ch->tty;
1073 if (tp)
1074 ts = tp->termios;
1075
1076
1077
1078 if (!tp || !ts) {
1079 MoxaPortFlushData(ch->port, 0);
1080 return;
1081 }
1082 spin_lock_irqsave(&moxa_lock, flags);
1083 MoxaPortReadData(ch->port, tp);
1084 spin_unlock_irqrestore(&moxa_lock, flags);
1085 tty_schedule_flip(tp);
1086}
1087
1088#define Magic_code 0x404
1089
1090
1091
1092
1093
1094
1095
1096#define C218_ConfBase 0x800
1097#define C218_status (C218_ConfBase + 0)
1098#define C218_diag (C218_ConfBase + 2)
1099#define C218_key (C218_ConfBase + 4)
1100#define C218DLoad_len (C218_ConfBase + 6)
1101#define C218check_sum (C218_ConfBase + 8)
1102#define C218chksum_ok (C218_ConfBase + 0x0a)
1103#define C218_TestRx (C218_ConfBase + 0x10)
1104#define C218_TestTx (C218_ConfBase + 0x18)
1105#define C218_RXerr (C218_ConfBase + 0x20)
1106#define C218_ErrFlag (C218_ConfBase + 0x28)
1107
1108#define C218_LoadBuf 0x0F00
1109#define C218_KeyCode 0x218
1110#define CP204J_KeyCode 0x204
1111
1112
1113
1114
1115#define C320_ConfBase 0x800
1116#define C320_LoadBuf 0x0f00
1117#define STS_init 0x05
1118
1119#define C320_status C320_ConfBase + 0
1120#define C320_diag C320_ConfBase + 2
1121#define C320_key C320_ConfBase + 4
1122#define C320DLoad_len C320_ConfBase + 6
1123#define C320check_sum C320_ConfBase + 8
1124#define C320chksum_ok C320_ConfBase + 0x0a
1125#define C320bapi_len C320_ConfBase + 0x0c
1126#define C320UART_no C320_ConfBase + 0x0e
1127
1128#define C320_KeyCode 0x320
1129
1130#define FixPage_addr 0x0000
1131#define DynPage_addr 0x2000
1132#define C218_start 0x3000
1133#define Control_reg 0x1ff0
1134#define HW_reset 0x80
1135
1136
1137
1138
1139#define FC_CardReset 0x80
1140#define FC_ChannelReset 1
1141#define FC_EnableCH 2
1142#define FC_DisableCH 3
1143#define FC_SetParam 4
1144#define FC_SetMode 5
1145#define FC_SetRate 6
1146#define FC_LineControl 7
1147#define FC_LineStatus 8
1148#define FC_XmitControl 9
1149#define FC_FlushQueue 10
1150#define FC_SendBreak 11
1151#define FC_StopBreak 12
1152#define FC_LoopbackON 13
1153#define FC_LoopbackOFF 14
1154#define FC_ClrIrqTable 15
1155#define FC_SendXon 16
1156#define FC_SetTermIrq 17
1157#define FC_SetCntIrq 18
1158#define FC_SetBreakIrq 19
1159#define FC_SetLineIrq 20
1160#define FC_SetFlowCtl 21
1161#define FC_GenIrq 22
1162#define FC_InCD180 23
1163#define FC_OutCD180 24
1164#define FC_InUARTreg 23
1165#define FC_OutUARTreg 24
1166#define FC_SetXonXoff 25
1167#define FC_OutCD180CCR 26
1168#define FC_ExtIQueue 27
1169#define FC_ExtOQueue 28
1170#define FC_ClrLineIrq 29
1171#define FC_HWFlowCtl 30
1172#define FC_GetClockRate 35
1173#define FC_SetBaud 36
1174#define FC_SetDataMode 41
1175#define FC_GetCCSR 43
1176#define FC_GetDataError 45
1177#define FC_RxControl 50
1178#define FC_ImmSend 51
1179#define FC_SetXonState 52
1180#define FC_SetXoffState 53
1181#define FC_SetRxFIFOTrig 54
1182#define FC_SetTxFIFOCnt 55
1183#define FC_UnixRate 56
1184#define FC_UnixResetTimer 57
1185
1186#define RxFIFOTrig1 0
1187#define RxFIFOTrig4 1
1188#define RxFIFOTrig8 2
1189#define RxFIFOTrig14 3
1190
1191
1192
1193
1194#define DRAM_global 0
1195#define INT_data (DRAM_global + 0)
1196#define Config_base (DRAM_global + 0x108)
1197
1198#define IRQindex (INT_data + 0)
1199#define IRQpending (INT_data + 4)
1200#define IRQtable (INT_data + 8)
1201
1202
1203
1204
1205#define IntrRx 0x01
1206#define IntrTx 0x02
1207#define IntrFunc 0x04
1208#define IntrBreak 0x08
1209#define IntrLine 0x10
1210
1211#define IntrIntr 0x20
1212#define IntrQuit 0x40
1213#define IntrEOF 0x80
1214
1215#define IntrRxTrigger 0x100
1216#define IntrTxTrigger 0x200
1217
1218#define Magic_no (Config_base + 0)
1219#define Card_model_no (Config_base + 2)
1220#define Total_ports (Config_base + 4)
1221#define Module_cnt (Config_base + 8)
1222#define Module_no (Config_base + 10)
1223#define Timer_10ms (Config_base + 14)
1224#define Disable_IRQ (Config_base + 20)
1225#define TMS320_PORT1 (Config_base + 22)
1226#define TMS320_PORT2 (Config_base + 24)
1227#define TMS320_CLOCK (Config_base + 26)
1228
1229
1230
1231
1232#define Extern_table 0x400
1233
1234
1235#define Extern_size 0x60
1236#define RXrptr 0x00
1237#define RXwptr 0x02
1238#define TXrptr 0x04
1239#define TXwptr 0x06
1240#define HostStat 0x08
1241#define FlagStat 0x0A
1242#define FlowControl 0x0C
1243
1244
1245
1246
1247
1248#define Break_cnt 0x0E
1249#define CD180TXirq 0x10
1250#define RX_mask 0x12
1251#define TX_mask 0x14
1252#define Ofs_rxb 0x16
1253#define Ofs_txb 0x18
1254#define Page_rxb 0x1A
1255#define Page_txb 0x1C
1256#define EndPage_rxb 0x1E
1257#define EndPage_txb 0x20
1258#define Data_error 0x22
1259#define RxTrigger 0x28
1260#define TxTrigger 0x2a
1261
1262#define rRXwptr 0x34
1263#define Low_water 0x36
1264
1265#define FuncCode 0x40
1266#define FuncArg 0x42
1267#define FuncArg1 0x44
1268
1269#define C218rx_size 0x2000
1270#define C218tx_size 0x8000
1271
1272#define C218rx_mask (C218rx_size - 1)
1273#define C218tx_mask (C218tx_size - 1)
1274
1275#define C320p8rx_size 0x2000
1276#define C320p8tx_size 0x8000
1277#define C320p8rx_mask (C320p8rx_size - 1)
1278#define C320p8tx_mask (C320p8tx_size - 1)
1279
1280#define C320p16rx_size 0x2000
1281#define C320p16tx_size 0x4000
1282#define C320p16rx_mask (C320p16rx_size - 1)
1283#define C320p16tx_mask (C320p16tx_size - 1)
1284
1285#define C320p24rx_size 0x2000
1286#define C320p24tx_size 0x2000
1287#define C320p24rx_mask (C320p24rx_size - 1)
1288#define C320p24tx_mask (C320p24tx_size - 1)
1289
1290#define C320p32rx_size 0x1000
1291#define C320p32tx_size 0x1000
1292#define C320p32rx_mask (C320p32rx_size - 1)
1293#define C320p32tx_mask (C320p32tx_size - 1)
1294
1295#define Page_size 0x2000
1296#define Page_mask (Page_size - 1)
1297#define C218rx_spage 3
1298#define C218tx_spage 4
1299#define C218rx_pageno 1
1300#define C218tx_pageno 4
1301#define C218buf_pageno 5
1302
1303#define C320p8rx_spage 3
1304#define C320p8tx_spage 4
1305#define C320p8rx_pgno 1
1306#define C320p8tx_pgno 4
1307#define C320p8buf_pgno 5
1308
1309#define C320p16rx_spage 3
1310#define C320p16tx_spage 4
1311#define C320p16rx_pgno 1
1312#define C320p16tx_pgno 2
1313#define C320p16buf_pgno 3
1314
1315#define C320p24rx_spage 3
1316#define C320p24tx_spage 4
1317#define C320p24rx_pgno 1
1318#define C320p24tx_pgno 1
1319#define C320p24buf_pgno 2
1320
1321#define C320p32rx_spage 3
1322#define C320p32tx_ofs C320p32rx_size
1323#define C320p32tx_spage 3
1324#define C320p32buf_pgno 1
1325
1326
1327
1328
1329#define WakeupRx 0x01
1330#define WakeupTx 0x02
1331#define WakeupBreak 0x08
1332#define WakeupLine 0x10
1333#define WakeupIntr 0x20
1334#define WakeupQuit 0x40
1335#define WakeupEOF 0x80
1336#define WakeupRxTrigger 0x100
1337#define WakeupTxTrigger 0x200
1338
1339
1340
1341#define Rx_over 0x01
1342#define Xoff_state 0x02
1343#define Tx_flowOff 0x04
1344#define Tx_enable 0x08
1345#define CTS_state 0x10
1346#define DSR_state 0x20
1347#define DCD_state 0x80
1348
1349
1350
1351#define CTS_FlowCtl 1
1352#define RTS_FlowCtl 2
1353#define Tx_FlowCtl 4
1354#define Rx_FlowCtl 8
1355#define IXM_IXANY 0x10
1356
1357#define LowWater 128
1358
1359#define DTR_ON 1
1360#define RTS_ON 2
1361#define CTS_ON 1
1362#define DSR_ON 2
1363#define DCD_ON 8
1364
1365
1366#define MX_CS8 0x03
1367#define MX_CS7 0x02
1368#define MX_CS6 0x01
1369#define MX_CS5 0x00
1370
1371#define MX_STOP1 0x00
1372#define MX_STOP15 0x04
1373#define MX_STOP2 0x08
1374
1375#define MX_PARNONE 0x00
1376#define MX_PAREVEN 0x40
1377#define MX_PARODD 0xC0
1378
1379
1380
1381
1382
1383struct mon_str {
1384 int tick;
1385 int rxcnt[MAX_PORTS];
1386 int txcnt[MAX_PORTS];
1387};
1388
1389#define DCD_changed 0x01
1390#define DCD_oldstate 0x80
1391
1392static unsigned char moxaBuff[10240];
1393static int moxaLowWaterChk;
1394static int moxaCard;
1395static struct mon_str moxaLog;
1396static int moxaFuncTout = HZ / 2;
1397
1398static void moxafunc(void __iomem *, int, ushort);
1399static void moxa_wait_finish(void __iomem *);
1400static void moxa_low_water_check(void __iomem *);
1401static int moxaloadbios(int, unsigned char __user *, int);
1402static int moxafindcard(int);
1403static int moxaload320b(int, unsigned char __user *, int);
1404static int moxaloadcode(int, unsigned char __user *, int);
1405static int moxaloadc218(int, void __iomem *, int);
1406static int moxaloadc320(int, void __iomem *, int, int *);
1407
1408
1409
1410
1411
1412
1413
1414void MoxaDriverInit(void)
1415{
1416 struct moxa_port *p;
1417 unsigned int i;
1418
1419 moxaFuncTout = HZ / 2;
1420 moxaCard = 0;
1421 moxaLog.tick = 0;
1422 moxaLowWaterChk = 0;
1423 for (i = 0; i < MAX_PORTS; i++) {
1424 p = &moxa_ports[i];
1425 p->chkPort = 0;
1426 p->lowChkFlag = 0;
1427 p->lineCtrl = 0;
1428 moxaLog.rxcnt[i] = 0;
1429 moxaLog.txcnt[i] = 0;
1430 }
1431}
1432
1433#define MOXA 0x400
1434#define MOXA_GET_IQUEUE (MOXA + 1)
1435#define MOXA_GET_OQUEUE (MOXA + 2)
1436#define MOXA_INIT_DRIVER (MOXA + 6)
1437#define MOXA_LOAD_BIOS (MOXA + 9)
1438#define MOXA_FIND_BOARD (MOXA + 10)
1439#define MOXA_LOAD_C320B (MOXA + 11)
1440#define MOXA_LOAD_CODE (MOXA + 12)
1441#define MOXA_GETDATACOUNT (MOXA + 23)
1442#define MOXA_GET_IOQUEUE (MOXA + 27)
1443#define MOXA_FLUSH_QUEUE (MOXA + 28)
1444#define MOXA_GET_CONF (MOXA + 35)
1445#define MOXA_GET_MAJOR (MOXA + 63)
1446#define MOXA_GET_CUMAJOR (MOXA + 64)
1447#define MOXA_GETMSTATUS (MOXA + 65)
1448
1449struct dl_str {
1450 char __user *buf;
1451 int len;
1452 int cardno;
1453};
1454
1455static struct dl_str dltmp;
1456
1457void MoxaPortFlushData(int port, int mode)
1458{
1459 void __iomem *ofsAddr;
1460 if ((mode < 0) || (mode > 2))
1461 return;
1462 ofsAddr = moxa_ports[port].tableAddr;
1463 moxafunc(ofsAddr, FC_FlushQueue, mode);
1464 if (mode != 1) {
1465 moxa_ports[port].lowChkFlag = 0;
1466 moxa_low_water_check(ofsAddr);
1467 }
1468}
1469
1470int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
1471{
1472 int i;
1473 int status;
1474 int MoxaPortTxQueue(int), MoxaPortRxQueue(int);
1475 void __user *argp = (void __user *)arg;
1476
1477 if (port == MAX_PORTS) {
1478 if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) &&
1479 (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) &&
1480 (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) &&
1481 (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) &&
1482 (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS))
1483 return (-EINVAL);
1484 }
1485 switch (cmd) {
1486 case MOXA_GET_CONF:
1487 if(copy_to_user(argp, &moxa_boards, MAX_BOARDS *
1488 sizeof(struct moxa_board_conf)))
1489 return -EFAULT;
1490 return (0);
1491 case MOXA_INIT_DRIVER:
1492 if ((int) arg == 0x404)
1493 MoxaDriverInit();
1494 return (0);
1495 case MOXA_GETDATACOUNT:
1496 moxaLog.tick = jiffies;
1497 if(copy_to_user(argp, &moxaLog, sizeof(struct mon_str)))
1498 return -EFAULT;
1499 return (0);
1500 case MOXA_FLUSH_QUEUE:
1501 MoxaPortFlushData(port, arg);
1502 return (0);
1503 case MOXA_GET_IOQUEUE: {
1504 struct moxaq_str __user *argm = argp;
1505 struct moxaq_str tmp;
1506
1507 for (i = 0; i < MAX_PORTS; i++, argm++) {
1508 memset(&tmp, 0, sizeof(tmp));
1509 if (moxa_ports[i].chkPort) {
1510 tmp.inq = MoxaPortRxQueue(i);
1511 tmp.outq = MoxaPortTxQueue(i);
1512 }
1513 if (copy_to_user(argm, &tmp, sizeof(tmp)))
1514 return -EFAULT;
1515 }
1516 return (0);
1517 } case MOXA_GET_OQUEUE:
1518 i = MoxaPortTxQueue(port);
1519 return put_user(i, (unsigned long __user *)argp);
1520 case MOXA_GET_IQUEUE:
1521 i = MoxaPortRxQueue(port);
1522 return put_user(i, (unsigned long __user *)argp);
1523 case MOXA_GET_MAJOR:
1524 if(copy_to_user(argp, &ttymajor, sizeof(int)))
1525 return -EFAULT;
1526 return 0;
1527 case MOXA_GET_CUMAJOR:
1528 i = 0;
1529 if(copy_to_user(argp, &i, sizeof(int)))
1530 return -EFAULT;
1531 return 0;
1532 case MOXA_GETMSTATUS: {
1533 struct mxser_mstatus __user *argm = argp;
1534 struct mxser_mstatus tmp;
1535 struct moxa_port *p;
1536
1537 for (i = 0; i < MAX_PORTS; i++, argm++) {
1538 p = &moxa_ports[i];
1539 memset(&tmp, 0, sizeof(tmp));
1540 if (!p->chkPort) {
1541 goto copy;
1542 } else {
1543 status = MoxaPortLineStatus(p->port);
1544 if (status & 1)
1545 tmp.cts = 1;
1546 if (status & 2)
1547 tmp.dsr = 1;
1548 if (status & 4)
1549 tmp.dcd = 1;
1550 }
1551
1552 if (!p->tty || !p->tty->termios)
1553 tmp.cflag = p->cflag;
1554 else
1555 tmp.cflag = p->tty->termios->c_cflag;
1556copy:
1557 if (copy_to_user(argm, &tmp, sizeof(tmp)))
1558 return -EFAULT;
1559 }
1560 return 0;
1561 } default:
1562 return (-ENOIOCTLCMD);
1563 case MOXA_LOAD_BIOS:
1564 case MOXA_FIND_BOARD:
1565 case MOXA_LOAD_C320B:
1566 case MOXA_LOAD_CODE:
1567 if (!capable(CAP_SYS_RAWIO))
1568 return -EPERM;
1569 break;
1570 }
1571
1572 if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
1573 return -EFAULT;
1574 if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0)
1575 return -EINVAL;
1576
1577 switch(cmd)
1578 {
1579 case MOXA_LOAD_BIOS:
1580 i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len);
1581 return (i);
1582 case MOXA_FIND_BOARD:
1583 return moxafindcard(dltmp.cardno);
1584 case MOXA_LOAD_C320B:
1585 moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len);
1586 default:
1587 return (0);
1588 case MOXA_LOAD_CODE:
1589 i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len);
1590 if (i == -1)
1591 return (-EFAULT);
1592 return (i);
1593
1594 }
1595}
1596
1597int MoxaDriverPoll(void)
1598{
1599 struct moxa_board_conf *brd;
1600 register ushort temp;
1601 register int card;
1602 void __iomem *ofsAddr;
1603 void __iomem *ip;
1604 int port, p, ports;
1605
1606 if (moxaCard == 0)
1607 return (-1);
1608 for (card = 0; card < MAX_BOARDS; card++) {
1609 brd = &moxa_boards[card];
1610 if (brd->loadstat == 0)
1611 continue;
1612 if ((ports = brd->numPorts) == 0)
1613 continue;
1614 if (readb(brd->intPend) == 0xff) {
1615 ip = brd->intTable + readb(brd->intNdx);
1616 p = card * MAX_PORTS_PER_BOARD;
1617 ports <<= 1;
1618 for (port = 0; port < ports; port += 2, p++) {
1619 if ((temp = readw(ip + port)) != 0) {
1620 writew(0, ip + port);
1621 ofsAddr = moxa_ports[p].tableAddr;
1622 if (temp & IntrTx)
1623 writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat);
1624 if (temp & IntrBreak) {
1625 moxa_ports[p].breakCnt++;
1626 }
1627 if (temp & IntrLine) {
1628 if (readb(ofsAddr + FlagStat) & DCD_state) {
1629 if ((moxa_ports[p].DCDState & DCD_oldstate) == 0)
1630 moxa_ports[p].DCDState = (DCD_oldstate |
1631 DCD_changed);
1632 } else {
1633 if (moxa_ports[p].DCDState & DCD_oldstate)
1634 moxa_ports[p].DCDState = DCD_changed;
1635 }
1636 }
1637 }
1638 }
1639 writeb(0, brd->intPend);
1640 }
1641 if (moxaLowWaterChk) {
1642 p = card * MAX_PORTS_PER_BOARD;
1643 for (port = 0; port < ports; port++, p++) {
1644 if (moxa_ports[p].lowChkFlag) {
1645 moxa_ports[p].lowChkFlag = 0;
1646 ofsAddr = moxa_ports[p].tableAddr;
1647 moxa_low_water_check(ofsAddr);
1648 }
1649 }
1650 }
1651 }
1652 moxaLowWaterChk = 0;
1653 return (0);
1654}
1655
1656
1657
1658
1659
1660int MoxaPortsOfCard(int cardno)
1661{
1662
1663 if (moxa_boards[cardno].boardType == 0)
1664 return (0);
1665 return (moxa_boards[cardno].numPorts);
1666}
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947int MoxaPortIsValid(int port)
1948{
1949
1950 if (moxaCard == 0)
1951 return (0);
1952 if (moxa_ports[port].chkPort == 0)
1953 return (0);
1954 return (1);
1955}
1956
1957void MoxaPortEnable(int port)
1958{
1959 void __iomem *ofsAddr;
1960 int MoxaPortLineStatus(int);
1961 short lowwater = 512;
1962
1963 ofsAddr = moxa_ports[port].tableAddr;
1964 writew(lowwater, ofsAddr + Low_water);
1965 moxa_ports[port].breakCnt = 0;
1966 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
1967 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
1968 moxafunc(ofsAddr, FC_SetBreakIrq, 0);
1969 } else {
1970 writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat);
1971 }
1972
1973 moxafunc(ofsAddr, FC_SetLineIrq, Magic_code);
1974 moxafunc(ofsAddr, FC_FlushQueue, 2);
1975
1976 moxafunc(ofsAddr, FC_EnableCH, Magic_code);
1977 MoxaPortLineStatus(port);
1978}
1979
1980void MoxaPortDisable(int port)
1981{
1982 void __iomem *ofsAddr = moxa_ports[port].tableAddr;
1983
1984 moxafunc(ofsAddr, FC_SetFlowCtl, 0);
1985 moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);
1986 writew(0, ofsAddr + HostStat);
1987 moxafunc(ofsAddr, FC_DisableCH, Magic_code);
1988}
1989
1990long MoxaPortGetMaxBaud(int port)
1991{
1992 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
1993 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI))
1994 return (460800L);
1995 else
1996 return (921600L);
1997}
1998
1999
2000long MoxaPortSetBaud(int port, long baud)
2001{
2002 void __iomem *ofsAddr;
2003 long max, clock;
2004 unsigned int val;
2005
2006 if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0))
2007 return (0);
2008 ofsAddr = moxa_ports[port].tableAddr;
2009 if (baud > max)
2010 baud = max;
2011 if (max == 38400L)
2012 clock = 614400L;
2013 else if (max == 57600L)
2014 clock = 691200L;
2015 else
2016 clock = 921600L;
2017 val = clock / baud;
2018 moxafunc(ofsAddr, FC_SetBaud, val);
2019 baud = clock / val;
2020 moxa_ports[port].curBaud = baud;
2021 return (baud);
2022}
2023
2024int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
2025{
2026 void __iomem *ofsAddr;
2027 tcflag_t cflag;
2028 tcflag_t mode = 0;
2029
2030 if (moxa_ports[port].chkPort == 0 || termio == 0)
2031 return (-1);
2032 ofsAddr = moxa_ports[port].tableAddr;
2033 cflag = termio->c_cflag;
2034
2035 mode = termio->c_cflag & CSIZE;
2036 if (mode == CS5)
2037 mode = MX_CS5;
2038 else if (mode == CS6)
2039 mode = MX_CS6;
2040 else if (mode == CS7)
2041 mode = MX_CS7;
2042 else if (mode == CS8)
2043 mode = MX_CS8;
2044
2045 if (termio->c_cflag & CSTOPB) {
2046 if (mode == MX_CS5)
2047 mode |= MX_STOP15;
2048 else
2049 mode |= MX_STOP2;
2050 } else
2051 mode |= MX_STOP1;
2052
2053 if (termio->c_cflag & PARENB) {
2054 if (termio->c_cflag & PARODD)
2055 mode |= MX_PARODD;
2056 else
2057 mode |= MX_PAREVEN;
2058 } else
2059 mode |= MX_PARNONE;
2060
2061 moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);
2062
2063 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2064 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
2065 if (baud >= 921600L)
2066 return (-1);
2067 }
2068 MoxaPortSetBaud(port, baud);
2069
2070 if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
2071 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
2072 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
2073 writeb(FC_SetXonXoff, ofsAddr + FuncCode);
2074 moxa_wait_finish(ofsAddr);
2075
2076 }
2077 return (0);
2078}
2079
2080int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState)
2081{
2082
2083 if (!MoxaPortIsValid(port))
2084 return (-1);
2085 if (dtrState) {
2086 if (moxa_ports[port].lineCtrl & DTR_ON)
2087 *dtrState = 1;
2088 else
2089 *dtrState = 0;
2090 }
2091 if (rtsState) {
2092 if (moxa_ports[port].lineCtrl & RTS_ON)
2093 *rtsState = 1;
2094 else
2095 *rtsState = 0;
2096 }
2097 return (0);
2098}
2099
2100void MoxaPortLineCtrl(int port, int dtr, int rts)
2101{
2102 void __iomem *ofsAddr;
2103 int mode;
2104
2105 ofsAddr = moxa_ports[port].tableAddr;
2106 mode = 0;
2107 if (dtr)
2108 mode |= DTR_ON;
2109 if (rts)
2110 mode |= RTS_ON;
2111 moxa_ports[port].lineCtrl = mode;
2112 moxafunc(ofsAddr, FC_LineControl, mode);
2113}
2114
2115void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany)
2116{
2117 void __iomem *ofsAddr;
2118 int mode;
2119
2120 ofsAddr = moxa_ports[port].tableAddr;
2121 mode = 0;
2122 if (rts)
2123 mode |= RTS_FlowCtl;
2124 if (cts)
2125 mode |= CTS_FlowCtl;
2126 if (txflow)
2127 mode |= Tx_FlowCtl;
2128 if (rxflow)
2129 mode |= Rx_FlowCtl;
2130 if (txany)
2131 mode |= IXM_IXANY;
2132 moxafunc(ofsAddr, FC_SetFlowCtl, mode);
2133}
2134
2135int MoxaPortLineStatus(int port)
2136{
2137 void __iomem *ofsAddr;
2138 int val;
2139
2140 ofsAddr = moxa_ports[port].tableAddr;
2141 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2142 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
2143 moxafunc(ofsAddr, FC_LineStatus, 0);
2144 val = readw(ofsAddr + FuncArg);
2145 } else {
2146 val = readw(ofsAddr + FlagStat) >> 4;
2147 }
2148 val &= 0x0B;
2149 if (val & 8) {
2150 val |= 4;
2151 if ((moxa_ports[port].DCDState & DCD_oldstate) == 0)
2152 moxa_ports[port].DCDState = (DCD_oldstate | DCD_changed);
2153 } else {
2154 if (moxa_ports[port].DCDState & DCD_oldstate)
2155 moxa_ports[port].DCDState = DCD_changed;
2156 }
2157 val &= 7;
2158 return (val);
2159}
2160
2161int MoxaPortDCDChange(int port)
2162{
2163 int n;
2164
2165 if (moxa_ports[port].chkPort == 0)
2166 return (0);
2167 n = moxa_ports[port].DCDState;
2168 moxa_ports[port].DCDState &= ~DCD_changed;
2169 n &= DCD_changed;
2170 return (n);
2171}
2172
2173int MoxaPortDCDON(int port)
2174{
2175 int n;
2176
2177 if (moxa_ports[port].chkPort == 0)
2178 return (0);
2179 if (moxa_ports[port].DCDState & DCD_oldstate)
2180 n = 1;
2181 else
2182 n = 0;
2183 return (n);
2184}
2185
2186int MoxaPortWriteData(int port, unsigned char * buffer, int len)
2187{
2188 int c, total, i;
2189 ushort tail;
2190 int cnt;
2191 ushort head, tx_mask, spage, epage;
2192 ushort pageno, pageofs, bufhead;
2193 void __iomem *baseAddr, *ofsAddr, *ofs;
2194
2195 ofsAddr = moxa_ports[port].tableAddr;
2196 baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;
2197 tx_mask = readw(ofsAddr + TX_mask);
2198 spage = readw(ofsAddr + Page_txb);
2199 epage = readw(ofsAddr + EndPage_txb);
2200 tail = readw(ofsAddr + TXwptr);
2201 head = readw(ofsAddr + TXrptr);
2202 c = (head > tail) ? (head - tail - 1)
2203 : (head - tail + tx_mask);
2204 if (c > len)
2205 c = len;
2206 moxaLog.txcnt[port] += c;
2207 total = c;
2208 if (spage == epage) {
2209 bufhead = readw(ofsAddr + Ofs_txb);
2210 writew(spage, baseAddr + Control_reg);
2211 while (c > 0) {
2212 if (head > tail)
2213 len = head - tail - 1;
2214 else
2215 len = tx_mask + 1 - tail;
2216 len = (c > len) ? len : c;
2217 ofs = baseAddr + DynPage_addr + bufhead + tail;
2218 for (i = 0; i < len; i++)
2219 writeb(*buffer++, ofs + i);
2220 tail = (tail + len) & tx_mask;
2221 c -= len;
2222 }
2223 writew(tail, ofsAddr + TXwptr);
2224 } else {
2225 len = c;
2226 pageno = spage + (tail >> 13);
2227 pageofs = tail & Page_mask;
2228 do {
2229 cnt = Page_size - pageofs;
2230 if (cnt > c)
2231 cnt = c;
2232 c -= cnt;
2233 writeb(pageno, baseAddr + Control_reg);
2234 ofs = baseAddr + DynPage_addr + pageofs;
2235 for (i = 0; i < cnt; i++)
2236 writeb(*buffer++, ofs + i);
2237 if (c == 0) {
2238 writew((tail + len) & tx_mask, ofsAddr + TXwptr);
2239 break;
2240 }
2241 if (++pageno == epage)
2242 pageno = spage;
2243 pageofs = 0;
2244 } while (1);
2245 }
2246 writeb(1, ofsAddr + CD180TXirq);
2247 return (total);
2248}
2249
2250int MoxaPortReadData(int port, struct tty_struct *tty)
2251{
2252 register ushort head, pageofs;
2253 int i, count, cnt, len, total, remain;
2254 ushort tail, rx_mask, spage, epage;
2255 ushort pageno, bufhead;
2256 void __iomem *baseAddr, *ofsAddr, *ofs;
2257
2258 ofsAddr = moxa_ports[port].tableAddr;
2259 baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;
2260 head = readw(ofsAddr + RXrptr);
2261 tail = readw(ofsAddr + RXwptr);
2262 rx_mask = readw(ofsAddr + RX_mask);
2263 spage = readw(ofsAddr + Page_rxb);
2264 epage = readw(ofsAddr + EndPage_rxb);
2265 count = (tail >= head) ? (tail - head)
2266 : (tail - head + rx_mask + 1);
2267 if (count == 0)
2268 return 0;
2269
2270 total = count;
2271 remain = count - total;
2272 moxaLog.rxcnt[port] += total;
2273 count = total;
2274 if (spage == epage) {
2275 bufhead = readw(ofsAddr + Ofs_rxb);
2276 writew(spage, baseAddr + Control_reg);
2277 while (count > 0) {
2278 if (tail >= head)
2279 len = tail - head;
2280 else
2281 len = rx_mask + 1 - head;
2282 len = (count > len) ? len : count;
2283 ofs = baseAddr + DynPage_addr + bufhead + head;
2284 for (i = 0; i < len; i++)
2285 tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
2286 head = (head + len) & rx_mask;
2287 count -= len;
2288 }
2289 writew(head, ofsAddr + RXrptr);
2290 } else {
2291 len = count;
2292 pageno = spage + (head >> 13);
2293 pageofs = head & Page_mask;
2294 do {
2295 cnt = Page_size - pageofs;
2296 if (cnt > count)
2297 cnt = count;
2298 count -= cnt;
2299 writew(pageno, baseAddr + Control_reg);
2300 ofs = baseAddr + DynPage_addr + pageofs;
2301 for (i = 0; i < cnt; i++)
2302 tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
2303 if (count == 0) {
2304 writew((head + len) & rx_mask, ofsAddr + RXrptr);
2305 break;
2306 }
2307 if (++pageno == epage)
2308 pageno = spage;
2309 pageofs = 0;
2310 } while (1);
2311 }
2312 if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) {
2313 moxaLowWaterChk = 1;
2314 moxa_ports[port].lowChkFlag = 1;
2315 }
2316 return (total);
2317}
2318
2319
2320int MoxaPortTxQueue(int port)
2321{
2322 void __iomem *ofsAddr;
2323 ushort rptr, wptr, mask;
2324 int len;
2325
2326 ofsAddr = moxa_ports[port].tableAddr;
2327 rptr = readw(ofsAddr + TXrptr);
2328 wptr = readw(ofsAddr + TXwptr);
2329 mask = readw(ofsAddr + TX_mask);
2330 len = (wptr - rptr) & mask;
2331 return (len);
2332}
2333
2334int MoxaPortTxFree(int port)
2335{
2336 void __iomem *ofsAddr;
2337 ushort rptr, wptr, mask;
2338 int len;
2339
2340 ofsAddr = moxa_ports[port].tableAddr;
2341 rptr = readw(ofsAddr + TXrptr);
2342 wptr = readw(ofsAddr + TXwptr);
2343 mask = readw(ofsAddr + TX_mask);
2344 len = mask - ((wptr - rptr) & mask);
2345 return (len);
2346}
2347
2348int MoxaPortRxQueue(int port)
2349{
2350 void __iomem *ofsAddr;
2351 ushort rptr, wptr, mask;
2352 int len;
2353
2354 ofsAddr = moxa_ports[port].tableAddr;
2355 rptr = readw(ofsAddr + RXrptr);
2356 wptr = readw(ofsAddr + RXwptr);
2357 mask = readw(ofsAddr + RX_mask);
2358 len = (wptr - rptr) & mask;
2359 return (len);
2360}
2361
2362
2363void MoxaPortTxDisable(int port)
2364{
2365 void __iomem *ofsAddr;
2366
2367 ofsAddr = moxa_ports[port].tableAddr;
2368 moxafunc(ofsAddr, FC_SetXoffState, Magic_code);
2369}
2370
2371void MoxaPortTxEnable(int port)
2372{
2373 void __iomem *ofsAddr;
2374
2375 ofsAddr = moxa_ports[port].tableAddr;
2376 moxafunc(ofsAddr, FC_SetXonState, Magic_code);
2377}
2378
2379
2380int MoxaPortResetBrkCnt(int port)
2381{
2382 ushort cnt;
2383 cnt = moxa_ports[port].breakCnt;
2384 moxa_ports[port].breakCnt = 0;
2385 return (cnt);
2386}
2387
2388
2389void MoxaPortSendBreak(int port, int ms100)
2390{
2391 void __iomem *ofsAddr;
2392
2393 ofsAddr = moxa_ports[port].tableAddr;
2394 if (ms100) {
2395 moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2396 msleep(ms100 * 10);
2397 } else {
2398 moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2399 msleep(250);
2400 }
2401 moxafunc(ofsAddr, FC_StopBreak, Magic_code);
2402}
2403
2404static int moxa_get_serial_info(struct moxa_port *info,
2405 struct serial_struct __user *retinfo)
2406{
2407 struct serial_struct tmp;
2408
2409 memset(&tmp, 0, sizeof(tmp));
2410 tmp.type = info->type;
2411 tmp.line = info->port;
2412 tmp.port = 0;
2413 tmp.irq = 0;
2414 tmp.flags = info->asyncflags;
2415 tmp.baud_base = 921600;
2416 tmp.close_delay = info->close_delay;
2417 tmp.closing_wait = info->closing_wait;
2418 tmp.custom_divisor = 0;
2419 tmp.hub6 = 0;
2420 if(copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2421 return -EFAULT;
2422 return (0);
2423}
2424
2425
2426static int moxa_set_serial_info(struct moxa_port *info,
2427 struct serial_struct __user *new_info)
2428{
2429 struct serial_struct new_serial;
2430
2431 if(copy_from_user(&new_serial, new_info, sizeof(new_serial)))
2432 return -EFAULT;
2433
2434 if ((new_serial.irq != 0) ||
2435 (new_serial.port != 0) ||
2436
2437 (new_serial.custom_divisor != 0) ||
2438 (new_serial.baud_base != 921600))
2439 return (-EPERM);
2440
2441 if (!capable(CAP_SYS_ADMIN)) {
2442 if (((new_serial.flags & ~ASYNC_USR_MASK) !=
2443 (info->asyncflags & ~ASYNC_USR_MASK)))
2444 return (-EPERM);
2445 } else {
2446 info->close_delay = new_serial.close_delay * HZ / 100;
2447 info->closing_wait = new_serial.closing_wait * HZ / 100;
2448 }
2449
2450 new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
2451 new_serial.flags |= (info->asyncflags & ASYNC_FLAGS);
2452
2453 if (new_serial.type == PORT_16550A) {
2454 MoxaSetFifo(info->port, 1);
2455 } else {
2456 MoxaSetFifo(info->port, 0);
2457 }
2458
2459 info->type = new_serial.type;
2460 return (0);
2461}
2462
2463
2464
2465
2466
2467
2468static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
2469{
2470
2471 writew(arg, ofsAddr + FuncArg);
2472 writew(cmd, ofsAddr + FuncCode);
2473 moxa_wait_finish(ofsAddr);
2474}
2475
2476static void moxa_wait_finish(void __iomem *ofsAddr)
2477{
2478 unsigned long i, j;
2479
2480 i = jiffies;
2481 while (readw(ofsAddr + FuncCode) != 0) {
2482 j = jiffies;
2483 if ((j - i) > moxaFuncTout) {
2484 return;
2485 }
2486 }
2487}
2488
2489static void moxa_low_water_check(void __iomem *ofsAddr)
2490{
2491 int len;
2492 ushort rptr, wptr, mask;
2493
2494 if (readb(ofsAddr + FlagStat) & Xoff_state) {
2495 rptr = readw(ofsAddr + RXrptr);
2496 wptr = readw(ofsAddr + RXwptr);
2497 mask = readw(ofsAddr + RX_mask);
2498 len = (wptr - rptr) & mask;
2499 if (len <= Low_water)
2500 moxafunc(ofsAddr, FC_SendXon, 0);
2501 }
2502}
2503
2504static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
2505{
2506 void __iomem *baseAddr;
2507 int i;
2508
2509 if(len < 0 || len > sizeof(moxaBuff))
2510 return -EINVAL;
2511 if(copy_from_user(moxaBuff, tmp, len))
2512 return -EFAULT;
2513 baseAddr = moxa_boards[cardno].basemem;
2514 writeb(HW_reset, baseAddr + Control_reg);
2515 msleep(10);
2516 for (i = 0; i < 4096; i++)
2517 writeb(0, baseAddr + i);
2518 for (i = 0; i < len; i++)
2519 writeb(moxaBuff[i], baseAddr + i);
2520 writeb(0, baseAddr + Control_reg);
2521 return (0);
2522}
2523
2524static int moxafindcard(int cardno)
2525{
2526 void __iomem *baseAddr;
2527 ushort tmp;
2528
2529 baseAddr = moxa_boards[cardno].basemem;
2530 switch (moxa_boards[cardno].boardType) {
2531 case MOXA_BOARD_C218_ISA:
2532 case MOXA_BOARD_C218_PCI:
2533 if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) {
2534 return (-1);
2535 }
2536 break;
2537 case MOXA_BOARD_CP204J:
2538 if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) {
2539 return (-1);
2540 }
2541 break;
2542 default:
2543 if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) {
2544 return (-1);
2545 }
2546 if ((tmp = readw(baseAddr + C320_status)) != STS_init) {
2547 return (-2);
2548 }
2549 }
2550 return (0);
2551}
2552
2553static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
2554{
2555 void __iomem *baseAddr;
2556 int i;
2557
2558 if(len < 0 || len > sizeof(moxaBuff))
2559 return -EINVAL;
2560 if(copy_from_user(moxaBuff, tmp, len))
2561 return -EFAULT;
2562 baseAddr = moxa_boards[cardno].basemem;
2563 writew(len - 7168 - 2, baseAddr + C320bapi_len);
2564 writeb(1, baseAddr + Control_reg);
2565 for (i = 0; i < 7168; i++)
2566 writeb(moxaBuff[i], baseAddr + DynPage_addr + i);
2567 writeb(2, baseAddr + Control_reg);
2568 for (i = 0; i < (len - 7168); i++)
2569 writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i);
2570 return (0);
2571}
2572
2573static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
2574{
2575 void __iomem *baseAddr, *ofsAddr;
2576 int retval, port, i;
2577
2578 if(len < 0 || len > sizeof(moxaBuff))
2579 return -EINVAL;
2580 if(copy_from_user(moxaBuff, tmp, len))
2581 return -EFAULT;
2582 baseAddr = moxa_boards[cardno].basemem;
2583 switch (moxa_boards[cardno].boardType) {
2584 case MOXA_BOARD_C218_ISA:
2585 case MOXA_BOARD_C218_PCI:
2586 case MOXA_BOARD_CP204J:
2587 retval = moxaloadc218(cardno, baseAddr, len);
2588 if (retval)
2589 return (retval);
2590 port = cardno * MAX_PORTS_PER_BOARD;
2591 for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
2592 struct moxa_port *p = &moxa_ports[port];
2593
2594 p->chkPort = 1;
2595 p->curBaud = 9600L;
2596 p->DCDState = 0;
2597 p->tableAddr = baseAddr + Extern_table + Extern_size * i;
2598 ofsAddr = p->tableAddr;
2599 writew(C218rx_mask, ofsAddr + RX_mask);
2600 writew(C218tx_mask, ofsAddr + TX_mask);
2601 writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);
2602 writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);
2603
2604 writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);
2605 writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);
2606
2607 }
2608 break;
2609 default:
2610 retval = moxaloadc320(cardno, baseAddr, len,
2611 &moxa_boards[cardno].numPorts);
2612 if (retval)
2613 return (retval);
2614 port = cardno * MAX_PORTS_PER_BOARD;
2615 for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
2616 struct moxa_port *p = &moxa_ports[port];
2617
2618 p->chkPort = 1;
2619 p->curBaud = 9600L;
2620 p->DCDState = 0;
2621 p->tableAddr = baseAddr + Extern_table + Extern_size * i;
2622 ofsAddr = p->tableAddr;
2623 if (moxa_boards[cardno].numPorts == 8) {
2624 writew(C320p8rx_mask, ofsAddr + RX_mask);
2625 writew(C320p8tx_mask, ofsAddr + TX_mask);
2626 writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);
2627 writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);
2628 writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);
2629 writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);
2630
2631 } else if (moxa_boards[cardno].numPorts == 16) {
2632 writew(C320p16rx_mask, ofsAddr + RX_mask);
2633 writew(C320p16tx_mask, ofsAddr + TX_mask);
2634 writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);
2635 writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);
2636 writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);
2637 writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);
2638
2639 } else if (moxa_boards[cardno].numPorts == 24) {
2640 writew(C320p24rx_mask, ofsAddr + RX_mask);
2641 writew(C320p24tx_mask, ofsAddr + TX_mask);
2642 writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);
2643 writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);
2644 writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);
2645 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
2646 } else if (moxa_boards[cardno].numPorts == 32) {
2647 writew(C320p32rx_mask, ofsAddr + RX_mask);
2648 writew(C320p32tx_mask, ofsAddr + TX_mask);
2649 writew(C320p32tx_ofs, ofsAddr + Ofs_txb);
2650 writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);
2651 writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);
2652 writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);
2653 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
2654 }
2655 }
2656 break;
2657 }
2658 moxa_boards[cardno].loadstat = 1;
2659 return (0);
2660}
2661
2662static int moxaloadc218(int cardno, void __iomem *baseAddr, int len)
2663{
2664 char retry;
2665 int i, j, len1, len2;
2666 ushort usum, *ptr, keycode;
2667
2668 if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J)
2669 keycode = CP204J_KeyCode;
2670 else
2671 keycode = C218_KeyCode;
2672 usum = 0;
2673 len1 = len >> 1;
2674 ptr = (ushort *) moxaBuff;
2675 for (i = 0; i < len1; i++)
2676 usum += le16_to_cpu(*(ptr + i));
2677 retry = 0;
2678 do {
2679 len1 = len >> 1;
2680 j = 0;
2681 while (len1) {
2682 len2 = (len1 > 2048) ? 2048 : len1;
2683 len1 -= len2;
2684 for (i = 0; i < len2 << 1; i++)
2685 writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i);
2686 j += i;
2687
2688 writew(len2, baseAddr + C218DLoad_len);
2689 writew(0, baseAddr + C218_key);
2690 for (i = 0; i < 100; i++) {
2691 if (readw(baseAddr + C218_key) == keycode)
2692 break;
2693 msleep(10);
2694 }
2695 if (readw(baseAddr + C218_key) != keycode) {
2696 return (-1);
2697 }
2698 }
2699 writew(0, baseAddr + C218DLoad_len);
2700 writew(usum, baseAddr + C218check_sum);
2701 writew(0, baseAddr + C218_key);
2702 for (i = 0; i < 100; i++) {
2703 if (readw(baseAddr + C218_key) == keycode)
2704 break;
2705 msleep(10);
2706 }
2707 retry++;
2708 } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3));
2709 if (readb(baseAddr + C218chksum_ok) != 1) {
2710 return (-1);
2711 }
2712 writew(0, baseAddr + C218_key);
2713 for (i = 0; i < 100; i++) {
2714 if (readw(baseAddr + Magic_no) == Magic_code)
2715 break;
2716 msleep(10);
2717 }
2718 if (readw(baseAddr + Magic_no) != Magic_code) {
2719 return (-1);
2720 }
2721 writew(1, baseAddr + Disable_IRQ);
2722 writew(0, baseAddr + Magic_no);
2723 for (i = 0; i < 100; i++) {
2724 if (readw(baseAddr + Magic_no) == Magic_code)
2725 break;
2726 msleep(10);
2727 }
2728 if (readw(baseAddr + Magic_no) != Magic_code) {
2729 return (-1);
2730 }
2731 moxaCard = 1;
2732 moxa_boards[cardno].intNdx = baseAddr + IRQindex;
2733 moxa_boards[cardno].intPend = baseAddr + IRQpending;
2734 moxa_boards[cardno].intTable = baseAddr + IRQtable;
2735 return (0);
2736}
2737
2738static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts)
2739{
2740 ushort usum;
2741 int i, j, wlen, len2, retry;
2742 ushort *uptr;
2743
2744 usum = 0;
2745 wlen = len >> 1;
2746 uptr = (ushort *) moxaBuff;
2747 for (i = 0; i < wlen; i++)
2748 usum += le16_to_cpu(uptr[i]);
2749 retry = 0;
2750 j = 0;
2751 do {
2752 while (wlen) {
2753 if (wlen > 2048)
2754 len2 = 2048;
2755 else
2756 len2 = wlen;
2757 wlen -= len2;
2758 len2 <<= 1;
2759 for (i = 0; i < len2; i++)
2760 writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i);
2761 len2 >>= 1;
2762 j += i;
2763 writew(len2, baseAddr + C320DLoad_len);
2764 writew(0, baseAddr + C320_key);
2765 for (i = 0; i < 10; i++) {
2766 if (readw(baseAddr + C320_key) == C320_KeyCode)
2767 break;
2768 msleep(10);
2769 }
2770 if (readw(baseAddr + C320_key) != C320_KeyCode)
2771 return (-1);
2772 }
2773 writew(0, baseAddr + C320DLoad_len);
2774 writew(usum, baseAddr + C320check_sum);
2775 writew(0, baseAddr + C320_key);
2776 for (i = 0; i < 10; i++) {
2777 if (readw(baseAddr + C320_key) == C320_KeyCode)
2778 break;
2779 msleep(10);
2780 }
2781 retry++;
2782 } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3));
2783 if (readb(baseAddr + C320chksum_ok) != 1)
2784 return (-1);
2785 writew(0, baseAddr + C320_key);
2786 for (i = 0; i < 600; i++) {
2787 if (readw(baseAddr + Magic_no) == Magic_code)
2788 break;
2789 msleep(10);
2790 }
2791 if (readw(baseAddr + Magic_no) != Magic_code)
2792 return (-100);
2793
2794 if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) {
2795 writew(0x3800, baseAddr + TMS320_PORT1);
2796 writew(0x3900, baseAddr + TMS320_PORT2);
2797 writew(28499, baseAddr + TMS320_CLOCK);
2798 } else {
2799 writew(0x3200, baseAddr + TMS320_PORT1);
2800 writew(0x3400, baseAddr + TMS320_PORT2);
2801 writew(19999, baseAddr + TMS320_CLOCK);
2802 }
2803 writew(1, baseAddr + Disable_IRQ);
2804 writew(0, baseAddr + Magic_no);
2805 for (i = 0; i < 500; i++) {
2806 if (readw(baseAddr + Magic_no) == Magic_code)
2807 break;
2808 msleep(10);
2809 }
2810 if (readw(baseAddr + Magic_no) != Magic_code)
2811 return (-102);
2812
2813 j = readw(baseAddr + Module_cnt);
2814 if (j <= 0)
2815 return (-101);
2816 *numPorts = j * 8;
2817 writew(j, baseAddr + Module_no);
2818 writew(0, baseAddr + Magic_no);
2819 for (i = 0; i < 600; i++) {
2820 if (readw(baseAddr + Magic_no) == Magic_code)
2821 break;
2822 msleep(10);
2823 }
2824 if (readw(baseAddr + Magic_no) != Magic_code)
2825 return (-102);
2826 moxaCard = 1;
2827 moxa_boards[cardno].intNdx = baseAddr + IRQindex;
2828 moxa_boards[cardno].intPend = baseAddr + IRQpending;
2829 moxa_boards[cardno].intTable = baseAddr + IRQtable;
2830 return (0);
2831}
2832
2833static void MoxaSetFifo(int port, int enable)
2834{
2835 void __iomem *ofsAddr = moxa_ports[port].tableAddr;
2836
2837 if (!enable) {
2838 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0);
2839 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1);
2840 } else {
2841 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3);
2842 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16);
2843 }
2844}
2845