~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/char/moxa.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.