OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [moxa.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.