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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [char/] [mxser.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *          mxser.c  -- MOXA Smartio/Industio family multiport serial driver.
3
 *
4
 *      Copyright (C) 1999-2001  Moxa Technologies (support@moxa.com.tw).
5
 *
6
 *      This code is loosely based on the Linux serial driver, written by
7
 *      Linus Torvalds, Theodore T'so and others.
8
 *
9
 *      This program is free software; you can redistribute it and/or modify
10
 *      it under the terms of the GNU General Public License as published by
11
 *      the Free Software Foundation; either version 2 of the License, or
12
 *      (at your option) any later version.
13
 *
14
 *      This program is distributed in the hope that it will be useful,
15
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *      GNU General Public License for more details.
18
 *
19
 *      You should have received a copy of the GNU General Public License
20
 *      along with this program; if not, write to the Free Software
21
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
 *
23
 *      Original release        10/26/00
24
 *
25
 *      02/06/01        Support MOXA Industio family boards.
26
 *      02/06/01        Support TIOCGICOUNT.
27
 *      02/06/01        Fix the problem for connecting to serial mouse.
28
 *      02/06/01        Fix the problem for H/W flow control.
29
 *      02/06/01        Fix the compling warning when CONFIG_PCI
30
 *                      don't be defined.
31
 *
32
 *      Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox
33
 *      <alan@redhat.com>. The original 1.8 code is available on www.moxa.com.
34
 *      - Fixed x86_64 cleanness
35
 *      - Fixed sleep with spinlock held in mxser_send_break
36
 */
37
 
38
 
39
#include <linux/module.h>
40
#include <linux/autoconf.h>
41
#include <linux/errno.h>
42
#include <linux/signal.h>
43
#include <linux/sched.h>
44
#include <linux/timer.h>
45
#include <linux/interrupt.h>
46
#include <linux/tty.h>
47
#include <linux/tty_flip.h>
48
#include <linux/serial.h>
49
#include <linux/serial_reg.h>
50
#include <linux/major.h>
51
#include <linux/string.h>
52
#include <linux/fcntl.h>
53
#include <linux/ptrace.h>
54
#include <linux/gfp.h>
55
#include <linux/ioport.h>
56
#include <linux/mm.h>
57
#include <linux/delay.h>
58
#include <linux/pci.h>
59
#include <linux/bitops.h>
60
 
61
#include <asm/system.h>
62
#include <asm/io.h>
63
#include <asm/irq.h>
64
#include <asm/uaccess.h>
65
 
66
#include "mxser.h"
67
 
68
#define MXSER_VERSION   "1.8"
69
#define MXSERMAJOR       174
70
#define MXSERCUMAJOR     175
71
 
72
#define MXSER_EVENT_TXLOW       1
73
#define MXSER_EVENT_HANGUP      2
74
 
75
#define MXSER_BOARDS            4       /* Max. boards */
76
#define MXSER_PORTS             32      /* Max. ports */
77
#define MXSER_PORTS_PER_BOARD   8       /* Max. ports per board */
78
#define MXSER_ISR_PASS_LIMIT    256
79
 
80
#define MXSER_ERR_IOADDR        -1
81
#define MXSER_ERR_IRQ           -2
82
#define MXSER_ERR_IRQ_CONFLIT   -3
83
#define MXSER_ERR_VECTOR        -4
84
 
85
#define SERIAL_TYPE_NORMAL      1
86
#define SERIAL_TYPE_CALLOUT     2
87
 
88
#define WAKEUP_CHARS            256
89
 
90
#define UART_MCR_AFE            0x20
91
#define UART_LSR_SPECIAL        0x1E
92
 
93
 
94
#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED)
95
 
96
#define C168_ASIC_ID    1
97
#define C104_ASIC_ID    2
98
#define C102_ASIC_ID    0xB
99
#define CI132_ASIC_ID   4
100
#define CI134_ASIC_ID   3
101
#define CI104J_ASIC_ID  5
102
 
103
enum {
104
        MXSER_BOARD_C168_ISA = 1,
105
        MXSER_BOARD_C104_ISA,
106
        MXSER_BOARD_CI104J,
107
        MXSER_BOARD_C168_PCI,
108
        MXSER_BOARD_C104_PCI,
109
        MXSER_BOARD_C102_ISA,
110
        MXSER_BOARD_CI132,
111
        MXSER_BOARD_CI134,
112
        MXSER_BOARD_CP132,
113
        MXSER_BOARD_CP114,
114
        MXSER_BOARD_CT114,
115
        MXSER_BOARD_CP102,
116
        MXSER_BOARD_CP104U,
117
        MXSER_BOARD_CP168U,
118
        MXSER_BOARD_CP132U,
119
        MXSER_BOARD_CP134U,
120
        MXSER_BOARD_CP104JU,
121
        MXSER_BOARD_RC7000,
122
        MXSER_BOARD_CP118U,
123
        MXSER_BOARD_CP102UL,
124
        MXSER_BOARD_CP102U,
125
};
126
 
127
static char *mxser_brdname[] = {
128
        "C168 series",
129
        "C104 series",
130
        "CI-104J series",
131
        "C168H/PCI series",
132
        "C104H/PCI series",
133
        "C102 series",
134
        "CI-132 series",
135
        "CI-134 series",
136
        "CP-132 series",
137
        "CP-114 series",
138
        "CT-114 series",
139
        "CP-102 series",
140
        "CP-104U series",
141
        "CP-168U series",
142
        "CP-132U series",
143
        "CP-134U series",
144
        "CP-104JU series",
145
        "Moxa UC7000 Serial",
146
        "CP-118U series",
147
        "CP-102UL series",
148
        "CP-102U series",
149
};
150
 
151
static int mxser_numports[] = {
152
        8,                      /* C168-ISA */
153
        4,                      /* C104-ISA */
154
        4,                      /* CI104J */
155
        8,                      /* C168-PCI */
156
        4,                      /* C104-PCI */
157
        2,                      /* C102-ISA */
158
        2,                      /* CI132 */
159
        4,                      /* CI134 */
160
        2,                      /* CP132 */
161
        4,                      /* CP114 */
162
        4,                      /* CT114 */
163
        2,                      /* CP102 */
164
        4,                      /* CP104U */
165
        8,                      /* CP168U */
166
        2,                      /* CP132U */
167
        4,                      /* CP134U */
168
        4,                      /* CP104JU */
169
        8,                      /* RC7000 */
170
        8,                      /* CP118U */
171
        2,                      /* CP102UL */
172
        2,                      /* CP102U */
173
};
174
 
175
#define UART_TYPE_NUM   2
176
 
177
static const unsigned int Gmoxa_uart_id[UART_TYPE_NUM] = {
178
        MOXA_MUST_MU150_HWID,
179
        MOXA_MUST_MU860_HWID
180
};
181
 
182
/* This is only for PCI */
183
#define UART_INFO_NUM   3
184
struct mxpciuart_info {
185
        int type;
186
        int tx_fifo;
187
        int rx_fifo;
188
        int xmit_fifo_size;
189
        int rx_high_water;
190
        int rx_trigger;
191
        int rx_low_water;
192
        long max_baud;
193
};
194
 
195
static const struct mxpciuart_info Gpci_uart_info[UART_INFO_NUM] = {
196
        {MOXA_OTHER_UART, 16, 16, 16, 14, 14, 1, 921600L},
197
        {MOXA_MUST_MU150_HWID, 64, 64, 64, 48, 48, 16, 230400L},
198
        {MOXA_MUST_MU860_HWID, 128, 128, 128, 96, 96, 32, 921600L}
199
};
200
 
201
 
202
#ifdef CONFIG_PCI
203
 
204
static struct pci_device_id mxser_pcibrds[] = {
205
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_C168_PCI},
206
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_C104_PCI},
207
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP132},
208
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP114},
209
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CT114},
210
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102},
211
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP104U},
212
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP168U},
213
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP132U},
214
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP134U},
215
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP104JU},
216
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_RC7000},
217
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP118U},
218
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102UL},
219
        {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102U},
220
        {0}
221
};
222
 
223
MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
224
 
225
 
226
#endif
227
 
228
typedef struct _moxa_pci_info {
229
        unsigned short busNum;
230
        unsigned short devNum;
231
        struct pci_dev *pdev;   /* add by Victor Yu. 06-23-2003 */
232
} moxa_pci_info;
233
 
234
static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
235
static int ttymajor = MXSERMAJOR;
236
static int calloutmajor = MXSERCUMAJOR;
237
static int verbose = 0;
238
 
239
/* Variables for insmod */
240
 
241
MODULE_AUTHOR("Casper Yang");
242
MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver");
243
module_param_array(ioaddr, int, NULL, 0);
244
module_param(ttymajor, int, 0);
245
module_param(calloutmajor, int, 0);
246
module_param(verbose, bool, 0);
247
MODULE_LICENSE("GPL");
248
 
249
struct mxser_log {
250
        int tick;
251
        unsigned long rxcnt[MXSER_PORTS];
252
        unsigned long txcnt[MXSER_PORTS];
253
};
254
 
255
 
256
struct mxser_mon {
257
        unsigned long rxcnt;
258
        unsigned long txcnt;
259
        unsigned long up_rxcnt;
260
        unsigned long up_txcnt;
261
        int modem_status;
262
        unsigned char hold_reason;
263
};
264
 
265
struct mxser_mon_ext {
266
        unsigned long rx_cnt[32];
267
        unsigned long tx_cnt[32];
268
        unsigned long up_rxcnt[32];
269
        unsigned long up_txcnt[32];
270
        int modem_status[32];
271
 
272
        long baudrate[32];
273
        int databits[32];
274
        int stopbits[32];
275
        int parity[32];
276
        int flowctrl[32];
277
        int fifo[32];
278
        int iftype[32];
279
};
280
 
281
struct mxser_hwconf {
282
        int board_type;
283
        int ports;
284
        int irq;
285
        int vector;
286
        int vector_mask;
287
        int uart_type;
288
        int ioaddr[MXSER_PORTS_PER_BOARD];
289
        int baud_base[MXSER_PORTS_PER_BOARD];
290
        moxa_pci_info pciInfo;
291
        int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */
292
        int MaxCanSetBaudRate[MXSER_PORTS_PER_BOARD];   /* add by Victor Yu. 09-04-2002 */
293
        int opmode_ioaddr[MXSER_PORTS_PER_BOARD];       /* add by Victor Yu. 01-05-2004 */
294
};
295
 
296
struct mxser_struct {
297
        int port;
298
        int base;               /* port base address */
299
        int irq;                /* port using irq no. */
300
        int vector;             /* port irq vector */
301
        int vectormask;         /* port vector mask */
302
        int rx_high_water;
303
        int rx_trigger;         /* Rx fifo trigger level */
304
        int rx_low_water;
305
        int baud_base;          /* max. speed */
306
        int flags;              /* defined in tty.h */
307
        int type;               /* UART type */
308
        struct tty_struct *tty;
309
        int read_status_mask;
310
        int ignore_status_mask;
311
        int xmit_fifo_size;
312
        int custom_divisor;
313
        int x_char;             /* xon/xoff character */
314
        int close_delay;
315
        unsigned short closing_wait;
316
        int IER;                /* Interrupt Enable Register */
317
        int MCR;                /* Modem control register */
318
        unsigned long event;
319
        int count;              /* # of fd on device */
320
        int blocked_open;       /* # of blocked opens */
321
        unsigned char *xmit_buf;
322
        int xmit_head;
323
        int xmit_tail;
324
        int xmit_cnt;
325
        struct work_struct tqueue;
326
        struct ktermios normal_termios;
327
        struct ktermios callout_termios;
328
        wait_queue_head_t open_wait;
329
        wait_queue_head_t close_wait;
330
        wait_queue_head_t delta_msr_wait;
331
        struct async_icount icount;     /* kernel counters for the 4 input interrupts */
332
        int timeout;
333
        int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */
334
        int MaxCanSetBaudRate;  /* add by Victor Yu. 09-04-2002 */
335
        int opmode_ioaddr;      /* add by Victor Yu. 01-05-2004 */
336
        unsigned char stop_rx;
337
        unsigned char ldisc_stop_rx;
338
        long realbaud;
339
        struct mxser_mon mon_data;
340
        unsigned char err_shadow;
341
        spinlock_t slock;
342
};
343
 
344
struct mxser_mstatus {
345
        tcflag_t cflag;
346
        int cts;
347
        int dsr;
348
        int ri;
349
        int dcd;
350
};
351
 
352
static struct mxser_mstatus GMStatus[MXSER_PORTS];
353
 
354
static int mxserBoardCAP[MXSER_BOARDS] = {
355
        0, 0, 0, 0
356
        /*  0x180, 0x280, 0x200, 0x320 */
357
};
358
 
359
static struct tty_driver *mxvar_sdriver;
360
static struct mxser_struct mxvar_table[MXSER_PORTS];
361
static struct tty_struct *mxvar_tty[MXSER_PORTS + 1];
362
static struct ktermios *mxvar_termios[MXSER_PORTS + 1];
363
static struct ktermios *mxvar_termios_locked[MXSER_PORTS + 1];
364
static struct mxser_log mxvar_log;
365
static int mxvar_diagflag;
366
static unsigned char mxser_msr[MXSER_PORTS + 1];
367
static struct mxser_mon_ext mon_data_ext;
368
static int mxser_set_baud_method[MXSER_PORTS + 1];
369
static spinlock_t gm_lock;
370
 
371
/*
372
 * This is used to figure out the divisor speeds and the timeouts
373
 */
374
 
375
static struct mxser_hwconf mxsercfg[MXSER_BOARDS];
376
 
377
/*
378
 * static functions:
379
 */
380
 
381
static void mxser_getcfg(int board, struct mxser_hwconf *hwconf);
382
static int mxser_init(void);
383
 
384
/* static void   mxser_poll(unsigned long); */
385
static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
386
static void mxser_do_softint(struct work_struct *);
387
static int mxser_open(struct tty_struct *, struct file *);
388
static void mxser_close(struct tty_struct *, struct file *);
389
static int mxser_write(struct tty_struct *, const unsigned char *, int);
390
static int mxser_write_room(struct tty_struct *);
391
static void mxser_flush_buffer(struct tty_struct *);
392
static int mxser_chars_in_buffer(struct tty_struct *);
393
static void mxser_flush_chars(struct tty_struct *);
394
static void mxser_put_char(struct tty_struct *, unsigned char);
395
static int mxser_ioctl(struct tty_struct *, struct file *, uint, ulong);
396
static int mxser_ioctl_special(unsigned int, void __user *);
397
static void mxser_throttle(struct tty_struct *);
398
static void mxser_unthrottle(struct tty_struct *);
399
static void mxser_set_termios(struct tty_struct *, struct ktermios *);
400
static void mxser_stop(struct tty_struct *);
401
static void mxser_start(struct tty_struct *);
402
static void mxser_hangup(struct tty_struct *);
403
static void mxser_rs_break(struct tty_struct *, int);
404
static irqreturn_t mxser_interrupt(int, void *);
405
static void mxser_receive_chars(struct mxser_struct *, int *);
406
static void mxser_transmit_chars(struct mxser_struct *);
407
static void mxser_check_modem_status(struct mxser_struct *, int);
408
static int mxser_block_til_ready(struct tty_struct *, struct file *, struct mxser_struct *);
409
static int mxser_startup(struct mxser_struct *);
410
static void mxser_shutdown(struct mxser_struct *);
411
static int mxser_change_speed(struct mxser_struct *, struct ktermios *old_termios);
412
static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *);
413
static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *);
414
static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *);
415
static void mxser_send_break(struct mxser_struct *, int);
416
static int mxser_tiocmget(struct tty_struct *, struct file *);
417
static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int);
418
static int mxser_set_baud(struct mxser_struct *info, long newspd);
419
static void mxser_wait_until_sent(struct tty_struct *tty, int timeout);
420
 
421
static void mxser_startrx(struct tty_struct *tty);
422
static void mxser_stoprx(struct tty_struct *tty);
423
 
424
#ifdef CONFIG_PCI
425
static int CheckIsMoxaMust(int io)
426
{
427
        u8 oldmcr, hwid;
428
        int i;
429
 
430
        outb(0, io + UART_LCR);
431
        DISABLE_MOXA_MUST_ENCHANCE_MODE(io);
432
        oldmcr = inb(io + UART_MCR);
433
        outb(0, io + UART_MCR);
434
        SET_MOXA_MUST_XON1_VALUE(io, 0x11);
435
        if ((hwid = inb(io + UART_MCR)) != 0) {
436
                outb(oldmcr, io + UART_MCR);
437
                return MOXA_OTHER_UART;
438
        }
439
 
440
        GET_MOXA_MUST_HARDWARE_ID(io, &hwid);
441
        for (i = 0; i < UART_TYPE_NUM; i++) {
442
                if (hwid == Gmoxa_uart_id[i])
443
                        return (int)hwid;
444
        }
445
        return MOXA_OTHER_UART;
446
}
447
#endif
448
 
449
/* above is modified by Victor Yu. 08-15-2002 */
450
 
451
static const struct tty_operations mxser_ops = {
452
        .open = mxser_open,
453
        .close = mxser_close,
454
        .write = mxser_write,
455
        .put_char = mxser_put_char,
456
        .flush_chars = mxser_flush_chars,
457
        .write_room = mxser_write_room,
458
        .chars_in_buffer = mxser_chars_in_buffer,
459
        .flush_buffer = mxser_flush_buffer,
460
        .ioctl = mxser_ioctl,
461
        .throttle = mxser_throttle,
462
        .unthrottle = mxser_unthrottle,
463
        .set_termios = mxser_set_termios,
464
        .stop = mxser_stop,
465
        .start = mxser_start,
466
        .hangup = mxser_hangup,
467
        .break_ctl = mxser_rs_break,
468
        .wait_until_sent = mxser_wait_until_sent,
469
        .tiocmget = mxser_tiocmget,
470
        .tiocmset = mxser_tiocmset,
471
};
472
 
473
/*
474
 * The MOXA Smartio/Industio serial driver boot-time initialization code!
475
 */
476
 
477
static int __init mxser_module_init(void)
478
{
479
        int ret;
480
 
481
        if (verbose)
482
                printk(KERN_DEBUG "Loading module mxser ...\n");
483
        ret = mxser_init();
484
        if (verbose)
485
                printk(KERN_DEBUG "Done.\n");
486
        return ret;
487
}
488
 
489
static void __exit mxser_module_exit(void)
490
{
491
        int i, err;
492
 
493
        if (verbose)
494
                printk(KERN_DEBUG "Unloading module mxser ...\n");
495
 
496
        err = tty_unregister_driver(mxvar_sdriver);
497
        if (!err)
498
                put_tty_driver(mxvar_sdriver);
499
        else
500
                printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n");
501
 
502
        for (i = 0; i < MXSER_BOARDS; i++) {
503
                struct pci_dev *pdev;
504
 
505
                if (mxsercfg[i].board_type == -1)
506
                        continue;
507
                else {
508
                        pdev = mxsercfg[i].pciInfo.pdev;
509
                        free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
510
                        if (pdev != NULL) {     /* PCI */
511
                                release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
512
                                release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
513
                                pci_dev_put(pdev);
514
                        } else {
515
                                release_region(mxsercfg[i].ioaddr[0], 8 * mxsercfg[i].ports);
516
                                release_region(mxsercfg[i].vector, 1);
517
                        }
518
                }
519
        }
520
        if (verbose)
521
                printk(KERN_DEBUG "Done.\n");
522
}
523
 
524
static void process_txrx_fifo(struct mxser_struct *info)
525
{
526
        int i;
527
 
528
        if ((info->type == PORT_16450) || (info->type == PORT_8250)) {
529
                info->rx_trigger = 1;
530
                info->rx_high_water = 1;
531
                info->rx_low_water = 1;
532
                info->xmit_fifo_size = 1;
533
        } else {
534
                for (i = 0; i < UART_INFO_NUM; i++) {
535
                        if (info->IsMoxaMustChipFlag == Gpci_uart_info[i].type) {
536
                                info->rx_trigger = Gpci_uart_info[i].rx_trigger;
537
                                info->rx_low_water = Gpci_uart_info[i].rx_low_water;
538
                                info->rx_high_water = Gpci_uart_info[i].rx_high_water;
539
                                info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size;
540
                                break;
541
                        }
542
                }
543
        }
544
}
545
 
546
static int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
547
{
548
        struct mxser_struct *info;
549
        int retval;
550
        int i, n;
551
 
552
        n = board * MXSER_PORTS_PER_BOARD;
553
        info = &mxvar_table[n];
554
        /*if (verbose) */  {
555
                printk(KERN_DEBUG "        ttyMI%d - ttyMI%d ",
556
                        n, n + hwconf->ports - 1);
557
                printk(" max. baud rate = %d bps.\n",
558
                        hwconf->MaxCanSetBaudRate[0]);
559
        }
560
 
561
        for (i = 0; i < hwconf->ports; i++, n++, info++) {
562
                info->port = n;
563
                info->base = hwconf->ioaddr[i];
564
                info->irq = hwconf->irq;
565
                info->vector = hwconf->vector;
566
                info->vectormask = hwconf->vector_mask;
567
                info->opmode_ioaddr = hwconf->opmode_ioaddr[i]; /* add by Victor Yu. 01-05-2004 */
568
                info->stop_rx = 0;
569
                info->ldisc_stop_rx = 0;
570
 
571
                info->IsMoxaMustChipFlag = hwconf->IsMoxaMustChipFlag;
572
                /* Enhance mode enabled here */
573
                if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
574
                        ENABLE_MOXA_MUST_ENCHANCE_MODE(info->base);
575
                }
576
 
577
                info->flags = ASYNC_SHARE_IRQ;
578
                info->type = hwconf->uart_type;
579
                info->baud_base = hwconf->baud_base[i];
580
 
581
                info->MaxCanSetBaudRate = hwconf->MaxCanSetBaudRate[i];
582
 
583
                process_txrx_fifo(info);
584
 
585
 
586
                info->custom_divisor = hwconf->baud_base[i] * 16;
587
                info->close_delay = 5 * HZ / 10;
588
                info->closing_wait = 30 * HZ;
589
                INIT_WORK(&info->tqueue, mxser_do_softint);
590
                info->normal_termios = mxvar_sdriver->init_termios;
591
                init_waitqueue_head(&info->open_wait);
592
                init_waitqueue_head(&info->close_wait);
593
                init_waitqueue_head(&info->delta_msr_wait);
594
                memset(&info->mon_data, 0, sizeof(struct mxser_mon));
595
                info->err_shadow = 0;
596
                spin_lock_init(&info->slock);
597
        }
598
        /*
599
         * Allocate the IRQ if necessary
600
         */
601
 
602
 
603
        /* before set INT ISR, disable all int */
604
        for (i = 0; i < hwconf->ports; i++) {
605
                outb(inb(hwconf->ioaddr[i] + UART_IER) & 0xf0,
606
                        hwconf->ioaddr[i] + UART_IER);
607
        }
608
 
609
        n = board * MXSER_PORTS_PER_BOARD;
610
        info = &mxvar_table[n];
611
 
612
        retval = request_irq(hwconf->irq, mxser_interrupt, IRQ_T(info),
613
                                "mxser", info);
614
        if (retval) {
615
                printk(KERN_ERR "Board %d: %s",
616
                        board, mxser_brdname[hwconf->board_type - 1]);
617
                printk("  Request irq failed, IRQ (%d) may conflict with"
618
                        " another device.\n", info->irq);
619
                return retval;
620
        }
621
        return 0;
622
}
623
 
624
static void mxser_getcfg(int board, struct mxser_hwconf *hwconf)
625
{
626
        mxsercfg[board] = *hwconf;
627
}
628
 
629
#ifdef CONFIG_PCI
630
static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxser_hwconf *hwconf)
631
{
632
        int i, j;
633
        /* unsigned int val; */
634
        unsigned int ioaddress;
635
        struct pci_dev *pdev = hwconf->pciInfo.pdev;
636
 
637
        /* io address */
638
        hwconf->board_type = board_type;
639
        hwconf->ports = mxser_numports[board_type - 1];
640
        ioaddress = pci_resource_start(pdev, 2);
641
        request_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2),
642
                        "mxser(IO)");
643
 
644
        for (i = 0; i < hwconf->ports; i++)
645
                hwconf->ioaddr[i] = ioaddress + 8 * i;
646
 
647
        /* vector */
648
        ioaddress = pci_resource_start(pdev, 3);
649
        request_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3),
650
                        "mxser(vector)");
651
        hwconf->vector = ioaddress;
652
 
653
        /* irq */
654
        hwconf->irq = hwconf->pciInfo.pdev->irq;
655
 
656
        hwconf->IsMoxaMustChipFlag = CheckIsMoxaMust(hwconf->ioaddr[0]);
657
        hwconf->uart_type = PORT_16550A;
658
        hwconf->vector_mask = 0;
659
 
660
 
661
        for (i = 0; i < hwconf->ports; i++) {
662
                for (j = 0; j < UART_INFO_NUM; j++) {
663
                        if (Gpci_uart_info[j].type == hwconf->IsMoxaMustChipFlag) {
664
                                hwconf->MaxCanSetBaudRate[i] = Gpci_uart_info[j].max_baud;
665
 
666
                                /* exception....CP-102 */
667
                                if (board_type == MXSER_BOARD_CP102)
668
                                        hwconf->MaxCanSetBaudRate[i] = 921600;
669
                                break;
670
                        }
671
                }
672
        }
673
 
674
        if (hwconf->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID) {
675
                for (i = 0; i < hwconf->ports; i++) {
676
                        if (i < 4)
677
                                hwconf->opmode_ioaddr[i] = ioaddress + 4;
678
                        else
679
                                hwconf->opmode_ioaddr[i] = ioaddress + 0x0c;
680
                }
681
                outb(0, ioaddress + 4);  /* default set to RS232 mode */
682
                outb(0, ioaddress + 0x0c);       /* default set to RS232 mode */
683
        }
684
 
685
        for (i = 0; i < hwconf->ports; i++) {
686
                hwconf->vector_mask |= (1 << i);
687
                hwconf->baud_base[i] = 921600;
688
        }
689
        return 0;
690
}
691
#endif
692
 
693
static int mxser_init(void)
694
{
695
        int i, m, retval, b, n;
696
        struct pci_dev *pdev = NULL;
697
        int index;
698
        unsigned char busnum, devnum;
699
        struct mxser_hwconf hwconf;
700
 
701
        mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1);
702
        if (!mxvar_sdriver)
703
                return -ENOMEM;
704
        spin_lock_init(&gm_lock);
705
 
706
        for (i = 0; i < MXSER_BOARDS; i++) {
707
                mxsercfg[i].board_type = -1;
708
        }
709
 
710
        printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n",
711
                MXSER_VERSION);
712
 
713
        /* Initialize the tty_driver structure */
714
        memset(mxvar_sdriver, 0, sizeof(struct tty_driver));
715
        mxvar_sdriver->owner = THIS_MODULE;
716
        mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
717
        mxvar_sdriver->name = "ttyMI";
718
        mxvar_sdriver->major = ttymajor;
719
        mxvar_sdriver->minor_start = 0;
720
        mxvar_sdriver->num = MXSER_PORTS + 1;
721
        mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL;
722
        mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL;
723
        mxvar_sdriver->init_termios = tty_std_termios;
724
        mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
725
        mxvar_sdriver->init_termios.c_ispeed = 9600;
726
        mxvar_sdriver->init_termios.c_ospeed = 9600;
727
        mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW;
728
        tty_set_operations(mxvar_sdriver, &mxser_ops);
729
        mxvar_sdriver->ttys = mxvar_tty;
730
        mxvar_sdriver->termios = mxvar_termios;
731
        mxvar_sdriver->termios_locked = mxvar_termios_locked;
732
 
733
        mxvar_diagflag = 0;
734
        memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
735
        memset(&mxvar_log, 0, sizeof(struct mxser_log));
736
 
737
        memset(&mxser_msr, 0, sizeof(unsigned char) * (MXSER_PORTS + 1));
738
        memset(&mon_data_ext, 0, sizeof(struct mxser_mon_ext));
739
        memset(&mxser_set_baud_method, 0, sizeof(int) * (MXSER_PORTS + 1));
740
        memset(&hwconf, 0, sizeof(struct mxser_hwconf));
741
 
742
        m = 0;
743
        /* Start finding ISA boards here */
744
        for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) {
745
                int cap;
746
 
747
                if (!(cap = mxserBoardCAP[b]))
748
                        continue;
749
 
750
                retval = mxser_get_ISA_conf(cap, &hwconf);
751
 
752
                if (retval != 0)
753
                        printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n",
754
                                mxser_brdname[hwconf.board_type - 1], ioaddr[b]);
755
 
756
                if (retval <= 0) {
757
                        if (retval == MXSER_ERR_IRQ)
758
                                printk(KERN_ERR "Invalid interrupt number, "
759
                                        "board not configured\n");
760
                        else if (retval == MXSER_ERR_IRQ_CONFLIT)
761
                                printk(KERN_ERR "Invalid interrupt number, "
762
                                        "board not configured\n");
763
                        else if (retval == MXSER_ERR_VECTOR)
764
                                printk(KERN_ERR "Invalid interrupt vector, "
765
                                        "board not configured\n");
766
                        else if (retval == MXSER_ERR_IOADDR)
767
                                printk(KERN_ERR "Invalid I/O address, "
768
                                        "board not configured\n");
769
 
770
                        continue;
771
                }
772
 
773
                hwconf.pciInfo.busNum = 0;
774
                hwconf.pciInfo.devNum = 0;
775
                hwconf.pciInfo.pdev = NULL;
776
 
777
                mxser_getcfg(m, &hwconf);
778
                /*
779
                 * init mxsercfg first,
780
                 * or mxsercfg data is not correct on ISR.
781
                 */
782
                /* mxser_initbrd will hook ISR. */
783
                if (mxser_initbrd(m, &hwconf) < 0)
784
                        continue;
785
 
786
                m++;
787
        }
788
 
789
        /* Start finding ISA boards from module arg */
790
        for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) {
791
                int cap;
792
 
793
                if (!(cap = ioaddr[b]))
794
                        continue;
795
 
796
                retval = mxser_get_ISA_conf(cap, &hwconf);
797
 
798
                if (retval != 0)
799
                        printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n",
800
                                mxser_brdname[hwconf.board_type - 1], ioaddr[b]);
801
 
802
                if (retval <= 0) {
803
                        if (retval == MXSER_ERR_IRQ)
804
                                printk(KERN_ERR "Invalid interrupt number, "
805
                                        "board not configured\n");
806
                        else if (retval == MXSER_ERR_IRQ_CONFLIT)
807
                                printk(KERN_ERR "Invalid interrupt number, "
808
                                        "board not configured\n");
809
                        else if (retval == MXSER_ERR_VECTOR)
810
                                printk(KERN_ERR "Invalid interrupt vector, "
811
                                        "board not configured\n");
812
                        else if (retval == MXSER_ERR_IOADDR)
813
                                printk(KERN_ERR "Invalid I/O address, "
814
                                        "board not configured\n");
815
 
816
                        continue;
817
                }
818
 
819
                hwconf.pciInfo.busNum = 0;
820
                hwconf.pciInfo.devNum = 0;
821
                hwconf.pciInfo.pdev = NULL;
822
 
823
                mxser_getcfg(m, &hwconf);
824
                /*
825
                 * init mxsercfg first,
826
                 * or mxsercfg data is not correct on ISR.
827
                 */
828
                /* mxser_initbrd will hook ISR. */
829
                if (mxser_initbrd(m, &hwconf) < 0)
830
                        continue;
831
 
832
                m++;
833
        }
834
 
835
        /* start finding PCI board here */
836
#ifdef CONFIG_PCI
837
        n = ARRAY_SIZE(mxser_pcibrds) - 1;
838
        index = 0;
839
        b = 0;
840
        while (b < n) {
841
                pdev = pci_get_device(mxser_pcibrds[b].vendor,
842
                                mxser_pcibrds[b].device, pdev);
843
                if (pdev == NULL) {
844
                        b++;
845
                        continue;
846
                }
847
                hwconf.pciInfo.busNum = busnum = pdev->bus->number;
848
                hwconf.pciInfo.devNum = devnum = PCI_SLOT(pdev->devfn) << 3;
849
                hwconf.pciInfo.pdev = pdev;
850
                printk(KERN_INFO "Found MOXA %s board(BusNo=%d,DevNo=%d)\n",
851
                        mxser_brdname[(int) (mxser_pcibrds[b].driver_data) - 1],
852
                        busnum, devnum >> 3);
853
                index++;
854
                if (m >= MXSER_BOARDS)
855
                        printk(KERN_ERR
856
                                "Too many Smartio/Industio family boards find "
857
                                "(maximum %d), board not configured\n",
858
                                MXSER_BOARDS);
859
                else {
860
                        if (pci_enable_device(pdev)) {
861
                                printk(KERN_ERR "Moxa SmartI/O PCI enable "
862
                                        "fail !\n");
863
                                continue;
864
                        }
865
                        retval = mxser_get_PCI_conf(busnum, devnum,
866
                                        (int)mxser_pcibrds[b].driver_data,
867
                                        &hwconf);
868
                        if (retval < 0) {
869
                                if (retval == MXSER_ERR_IRQ)
870
                                        printk(KERN_ERR
871
                                                "Invalid interrupt number, "
872
                                                "board not configured\n");
873
                                else if (retval == MXSER_ERR_IRQ_CONFLIT)
874
                                        printk(KERN_ERR
875
                                                "Invalid interrupt number, "
876
                                                "board not configured\n");
877
                                else if (retval == MXSER_ERR_VECTOR)
878
                                        printk(KERN_ERR
879
                                                "Invalid interrupt vector, "
880
                                                "board not configured\n");
881
                                else if (retval == MXSER_ERR_IOADDR)
882
                                        printk(KERN_ERR
883
                                                "Invalid I/O address, "
884
                                                "board not configured\n");
885
                                continue;
886
                        }
887
                        mxser_getcfg(m, &hwconf);
888
                        /* init mxsercfg first,
889
                         * or mxsercfg data is not correct on ISR.
890
                         */
891
                        /* mxser_initbrd will hook ISR. */
892
                        if (mxser_initbrd(m, &hwconf) < 0)
893
                                continue;
894
                        m++;
895
                        /* Keep an extra reference if we succeeded. It will
896
                           be returned at unload time */
897
                        pci_dev_get(pdev);
898
                }
899
        }
900
#endif
901
 
902
        retval = tty_register_driver(mxvar_sdriver);
903
        if (retval) {
904
                printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family"
905
                                " driver !\n");
906
                put_tty_driver(mxvar_sdriver);
907
 
908
                for (i = 0; i < MXSER_BOARDS; i++) {
909
                        if (mxsercfg[i].board_type == -1)
910
                                continue;
911
                        else {
912
                                free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
913
                                /* todo: release io, vector */
914
                        }
915
                }
916
                return retval;
917
        }
918
 
919
        return 0;
920
}
921
 
922
static void mxser_do_softint(struct work_struct *work)
923
{
924
        struct mxser_struct *info =
925
                container_of(work, struct mxser_struct, tqueue);
926
        struct tty_struct *tty;
927
 
928
        tty = info->tty;
929
 
930
        if (tty) {
931
                if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event))
932
                        tty_wakeup(tty);
933
                if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event))
934
                        tty_hangup(tty);
935
        }
936
}
937
 
938
static unsigned char mxser_get_msr(int baseaddr, int mode, int port, struct mxser_struct *info)
939
{
940
        unsigned char status = 0;
941
 
942
        status = inb(baseaddr + UART_MSR);
943
 
944
        mxser_msr[port] &= 0x0F;
945
        mxser_msr[port] |= status;
946
        status = mxser_msr[port];
947
        if (mode)
948
                mxser_msr[port] = 0;
949
 
950
        return status;
951
}
952
 
953
/*
954
 * This routine is called whenever a serial port is opened.  It
955
 * enables interrupts for a serial port, linking in its async structure into
956
 * the IRQ chain.   It also performs the serial-specific
957
 * initialization for the tty structure.
958
 */
959
static int mxser_open(struct tty_struct *tty, struct file *filp)
960
{
961
        struct mxser_struct *info;
962
        int retval, line;
963
 
964
        /* initialize driver_data in case something fails */
965
        tty->driver_data = NULL;
966
 
967
        line = tty->index;
968
        if (line == MXSER_PORTS)
969
                return 0;
970
        if (line < 0 || line > MXSER_PORTS)
971
                return -ENODEV;
972
        info = mxvar_table + line;
973
        if (!info->base)
974
                return -ENODEV;
975
 
976
        tty->driver_data = info;
977
        info->tty = tty;
978
        /*
979
         * Start up serial port
980
         */
981
        retval = mxser_startup(info);
982
        if (retval)
983
                return retval;
984
 
985
        retval = mxser_block_til_ready(tty, filp, info);
986
        if (retval)
987
                return retval;
988
 
989
        info->count++;
990
 
991
        if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
992
                if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
993
                        *tty->termios = info->normal_termios;
994
                else
995
                        *tty->termios = info->callout_termios;
996
                mxser_change_speed(info, NULL);
997
        }
998
 
999
        /*
1000
        status = mxser_get_msr(info->base, 0, info->port);
1001
        mxser_check_modem_status(info, status);
1002
        */
1003
 
1004
        /* unmark here for very high baud rate (ex. 921600 bps) used */
1005
        tty->low_latency = 1;
1006
        return 0;
1007
}
1008
 
1009
/*
1010
 * This routine is called when the serial port gets closed.  First, we
1011
 * wait for the last remaining data to be sent.  Then, we unlink its
1012
 * async structure from the interrupt chain if necessary, and we free
1013
 * that IRQ if nothing is left in the chain.
1014
 */
1015
static void mxser_close(struct tty_struct *tty, struct file *filp)
1016
{
1017
        struct mxser_struct *info = tty->driver_data;
1018
 
1019
        unsigned long timeout;
1020
        unsigned long flags;
1021
        struct tty_ldisc *ld;
1022
 
1023
        if (tty->index == MXSER_PORTS)
1024
                return;
1025
        if (!info)
1026
                return;
1027
 
1028
        spin_lock_irqsave(&info->slock, flags);
1029
 
1030
        if (tty_hung_up_p(filp)) {
1031
                spin_unlock_irqrestore(&info->slock, flags);
1032
                return;
1033
        }
1034
        if ((tty->count == 1) && (info->count != 1)) {
1035
                /*
1036
                 * Uh, oh.  tty->count is 1, which means that the tty
1037
                 * structure will be freed.  Info->count should always
1038
                 * be one in these conditions.  If it's greater than
1039
                 * one, we've got real problems, since it means the
1040
                 * serial port won't be shutdown.
1041
                 */
1042
                printk(KERN_ERR "mxser_close: bad serial port count; "
1043
                        "tty->count is 1, info->count is %d\n", info->count);
1044
                info->count = 1;
1045
        }
1046
        if (--info->count < 0) {
1047
                printk(KERN_ERR "mxser_close: bad serial port count for "
1048
                        "ttys%d: %d\n", info->port, info->count);
1049
                info->count = 0;
1050
        }
1051
        if (info->count) {
1052
                spin_unlock_irqrestore(&info->slock, flags);
1053
                return;
1054
        }
1055
        info->flags |= ASYNC_CLOSING;
1056
        spin_unlock_irqrestore(&info->slock, flags);
1057
        /*
1058
         * Save the termios structure, since this port may have
1059
         * separate termios for callout and dialin.
1060
         */
1061
        if (info->flags & ASYNC_NORMAL_ACTIVE)
1062
                info->normal_termios = *tty->termios;
1063
        /*
1064
         * Now we wait for the transmit buffer to clear; and we notify
1065
         * the line discipline to only process XON/XOFF characters.
1066
         */
1067
        tty->closing = 1;
1068
        if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1069
                tty_wait_until_sent(tty, info->closing_wait);
1070
        /*
1071
         * At this point we stop accepting input.  To do this, we
1072
         * disable the receive line status interrupts, and tell the
1073
         * interrupt driver to stop checking the data ready bit in the
1074
         * line status register.
1075
         */
1076
        info->IER &= ~UART_IER_RLSI;
1077
        if (info->IsMoxaMustChipFlag)
1078
                info->IER &= ~MOXA_MUST_RECV_ISR;
1079
/* by William
1080
        info->read_status_mask &= ~UART_LSR_DR;
1081
*/
1082
        if (info->flags & ASYNC_INITIALIZED) {
1083
                outb(info->IER, info->base + UART_IER);
1084
                /*
1085
                 * Before we drop DTR, make sure the UART transmitter
1086
                 * has completely drained; this is especially
1087
                 * important if there is a transmit FIFO!
1088
                 */
1089
                timeout = jiffies + HZ;
1090
                while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) {
1091
                        schedule_timeout_interruptible(5);
1092
                        if (time_after(jiffies, timeout))
1093
                                break;
1094
                }
1095
        }
1096
        mxser_shutdown(info);
1097
 
1098
        if (tty->driver->flush_buffer)
1099
                tty->driver->flush_buffer(tty);
1100
 
1101
        ld = tty_ldisc_ref(tty);
1102
        if (ld) {
1103
                if (ld->flush_buffer)
1104
                        ld->flush_buffer(tty);
1105
                tty_ldisc_deref(ld);
1106
        }
1107
 
1108
        tty->closing = 0;
1109
        info->event = 0;
1110
        info->tty = NULL;
1111
        if (info->blocked_open) {
1112
                if (info->close_delay)
1113
                        schedule_timeout_interruptible(info->close_delay);
1114
                wake_up_interruptible(&info->open_wait);
1115
        }
1116
 
1117
        info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1118
        wake_up_interruptible(&info->close_wait);
1119
 
1120
}
1121
 
1122
static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
1123
{
1124
        int c, total = 0;
1125
        struct mxser_struct *info = tty->driver_data;
1126
        unsigned long flags;
1127
 
1128
        if (!info->xmit_buf)
1129
                return 0;
1130
 
1131
        while (1) {
1132
                c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1133
                                          SERIAL_XMIT_SIZE - info->xmit_head));
1134
                if (c <= 0)
1135
                        break;
1136
 
1137
                memcpy(info->xmit_buf + info->xmit_head, buf, c);
1138
                spin_lock_irqsave(&info->slock, flags);
1139
                info->xmit_head = (info->xmit_head + c) &
1140
                                  (SERIAL_XMIT_SIZE - 1);
1141
                info->xmit_cnt += c;
1142
                spin_unlock_irqrestore(&info->slock, flags);
1143
 
1144
                buf += c;
1145
                count -= c;
1146
                total += c;
1147
        }
1148
 
1149
        if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) {
1150
                if (!tty->hw_stopped ||
1151
                                (info->type == PORT_16550A) ||
1152
                                (info->IsMoxaMustChipFlag)) {
1153
                        spin_lock_irqsave(&info->slock, flags);
1154
                        info->IER |= UART_IER_THRI;
1155
                        outb(info->IER, info->base + UART_IER);
1156
                        spin_unlock_irqrestore(&info->slock, flags);
1157
                }
1158
        }
1159
        return total;
1160
}
1161
 
1162
static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
1163
{
1164
        struct mxser_struct *info = tty->driver_data;
1165
        unsigned long flags;
1166
 
1167
        if (!info->xmit_buf)
1168
                return;
1169
 
1170
        if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1171
                return;
1172
 
1173
        spin_lock_irqsave(&info->slock, flags);
1174
        info->xmit_buf[info->xmit_head++] = ch;
1175
        info->xmit_head &= SERIAL_XMIT_SIZE - 1;
1176
        info->xmit_cnt++;
1177
        spin_unlock_irqrestore(&info->slock, flags);
1178
        if (!tty->stopped && !(info->IER & UART_IER_THRI)) {
1179
                if (!tty->hw_stopped ||
1180
                                (info->type == PORT_16550A) ||
1181
                                info->IsMoxaMustChipFlag) {
1182
                        spin_lock_irqsave(&info->slock, flags);
1183
                        info->IER |= UART_IER_THRI;
1184
                        outb(info->IER, info->base + UART_IER);
1185
                        spin_unlock_irqrestore(&info->slock, flags);
1186
                }
1187
        }
1188
}
1189
 
1190
 
1191
static void mxser_flush_chars(struct tty_struct *tty)
1192
{
1193
        struct mxser_struct *info = tty->driver_data;
1194
        unsigned long flags;
1195
 
1196
        if (info->xmit_cnt <= 0 ||
1197
                        tty->stopped ||
1198
                        !info->xmit_buf ||
1199
                        (tty->hw_stopped &&
1200
                         (info->type != PORT_16550A) &&
1201
                         (!info->IsMoxaMustChipFlag)
1202
                        ))
1203
                return;
1204
 
1205
        spin_lock_irqsave(&info->slock, flags);
1206
 
1207
        info->IER |= UART_IER_THRI;
1208
        outb(info->IER, info->base + UART_IER);
1209
 
1210
        spin_unlock_irqrestore(&info->slock, flags);
1211
}
1212
 
1213
static int mxser_write_room(struct tty_struct *tty)
1214
{
1215
        struct mxser_struct *info = tty->driver_data;
1216
        int ret;
1217
 
1218
        ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
1219
        if (ret < 0)
1220
                ret = 0;
1221
        return ret;
1222
}
1223
 
1224
static int mxser_chars_in_buffer(struct tty_struct *tty)
1225
{
1226
        struct mxser_struct *info = tty->driver_data;
1227
        return info->xmit_cnt;
1228
}
1229
 
1230
static void mxser_flush_buffer(struct tty_struct *tty)
1231
{
1232
        struct mxser_struct *info = tty->driver_data;
1233
        char fcr;
1234
        unsigned long flags;
1235
 
1236
 
1237
        spin_lock_irqsave(&info->slock, flags);
1238
        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1239
 
1240
        /* below added by shinhay */
1241
        fcr = inb(info->base + UART_FCR);
1242
        outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
1243
                info->base + UART_FCR);
1244
        outb(fcr, info->base + UART_FCR);
1245
 
1246
        spin_unlock_irqrestore(&info->slock, flags);
1247
        /* above added by shinhay */
1248
 
1249
        tty_wakeup(tty);
1250
}
1251
 
1252
static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1253
{
1254
        struct mxser_struct *info = tty->driver_data;
1255
        int retval;
1256
        struct async_icount cprev, cnow;        /* kernel counter temps */
1257
        struct serial_icounter_struct __user *p_cuser;
1258
        unsigned long templ;
1259
        unsigned long flags;
1260
        void __user *argp = (void __user *)arg;
1261
 
1262
        if (tty->index == MXSER_PORTS)
1263
                return mxser_ioctl_special(cmd, argp);
1264
 
1265
        /* following add by Victor Yu. 01-05-2004 */
1266
        if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) {
1267
                int opmode, p;
1268
                static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f };
1269
                int shiftbit;
1270
                unsigned char val, mask;
1271
 
1272
                p = info->port % 4;
1273
                if (cmd == MOXA_SET_OP_MODE) {
1274
                        if (get_user(opmode, (int __user *) argp))
1275
                                return -EFAULT;
1276
                        if (opmode != RS232_MODE &&
1277
                                        opmode != RS485_2WIRE_MODE &&
1278
                                        opmode != RS422_MODE &&
1279
                                        opmode != RS485_4WIRE_MODE)
1280
                                return -EFAULT;
1281
                        mask = ModeMask[p];
1282
                        shiftbit = p * 2;
1283
                        val = inb(info->opmode_ioaddr);
1284
                        val &= mask;
1285
                        val |= (opmode << shiftbit);
1286
                        outb(val, info->opmode_ioaddr);
1287
                } else {
1288
                        shiftbit = p * 2;
1289
                        opmode = inb(info->opmode_ioaddr) >> shiftbit;
1290
                        opmode &= OP_MODE_MASK;
1291
                        if (copy_to_user(argp, &opmode, sizeof(int)))
1292
                                return -EFAULT;
1293
                }
1294
                return 0;
1295
        }
1296
        /* above add by Victor Yu. 01-05-2004 */
1297
 
1298
        if ((cmd != TIOCGSERIAL) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
1299
                if (tty->flags & (1 << TTY_IO_ERROR))
1300
                        return -EIO;
1301
        }
1302
        switch (cmd) {
1303
        case TCSBRK:            /* SVID version: non-zero arg --> no break */
1304
                retval = tty_check_change(tty);
1305
                if (retval)
1306
                        return retval;
1307
                tty_wait_until_sent(tty, 0);
1308
                if (!arg)
1309
                        mxser_send_break(info, HZ / 4); /* 1/4 second */
1310
                return 0;
1311
        case TCSBRKP:           /* support for POSIX tcsendbreak() */
1312
                retval = tty_check_change(tty);
1313
                if (retval)
1314
                        return retval;
1315
                tty_wait_until_sent(tty, 0);
1316
                mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
1317
                return 0;
1318
        case TIOCGSOFTCAR:
1319
                return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
1320
        case TIOCSSOFTCAR:
1321
                if (get_user(templ, (unsigned long __user *) argp))
1322
                        return -EFAULT;
1323
                arg = templ;
1324
                tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
1325
                return 0;
1326
        case TIOCGSERIAL:
1327
                return mxser_get_serial_info(info, argp);
1328
        case TIOCSSERIAL:
1329
                return mxser_set_serial_info(info, argp);
1330
        case TIOCSERGETLSR:     /* Get line status register */
1331
                return mxser_get_lsr_info(info, argp);
1332
                /*
1333
                 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
1334
                 * - mask passed in arg for lines of interest
1335
                 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
1336
                 * Caller should use TIOCGICOUNT to see which one it was
1337
                 */
1338
        case TIOCMIWAIT:
1339
                spin_lock_irqsave(&info->slock, flags);
1340
                cnow = info->icount;    /* note the counters on entry */
1341
                spin_unlock_irqrestore(&info->slock, flags);
1342
 
1343
                wait_event_interruptible(info->delta_msr_wait, ({
1344
                        cprev = cnow;
1345
                        spin_lock_irqsave(&info->slock, flags);
1346
                        cnow = info->icount;    /* atomic copy */
1347
                        spin_unlock_irqrestore(&info->slock, flags);
1348
 
1349
                        ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
1350
                        ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
1351
                        ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
1352
                        ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
1353
                }));
1354
                break;
1355
                /*
1356
                 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
1357
                 * Return: write counters to the user passed counter struct
1358
                 * NB: both 1->0 and 0->1 transitions are counted except for
1359
                 *     RI where only 0->1 is counted.
1360
                 */
1361
        case TIOCGICOUNT:
1362
                spin_lock_irqsave(&info->slock, flags);
1363
                cnow = info->icount;
1364
                spin_unlock_irqrestore(&info->slock, flags);
1365
                p_cuser = argp;
1366
                /* modified by casper 1/11/2000 */
1367
                if (put_user(cnow.frame, &p_cuser->frame))
1368
                        return -EFAULT;
1369
                if (put_user(cnow.brk, &p_cuser->brk))
1370
                        return -EFAULT;
1371
                if (put_user(cnow.overrun, &p_cuser->overrun))
1372
                        return -EFAULT;
1373
                if (put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
1374
                        return -EFAULT;
1375
                if (put_user(cnow.parity, &p_cuser->parity))
1376
                        return -EFAULT;
1377
                if (put_user(cnow.rx, &p_cuser->rx))
1378
                        return -EFAULT;
1379
                if (put_user(cnow.tx, &p_cuser->tx))
1380
                        return -EFAULT;
1381
                put_user(cnow.cts, &p_cuser->cts);
1382
                put_user(cnow.dsr, &p_cuser->dsr);
1383
                put_user(cnow.rng, &p_cuser->rng);
1384
                put_user(cnow.dcd, &p_cuser->dcd);
1385
                return 0;
1386
        case MOXA_HighSpeedOn:
1387
                return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
1388
        case MOXA_SDS_RSTICOUNTER: {
1389
                        info->mon_data.rxcnt = 0;
1390
                        info->mon_data.txcnt = 0;
1391
                        return 0;
1392
                }
1393
/* (above) added by James. */
1394
        case MOXA_ASPP_SETBAUD:{
1395
                        long baud;
1396
                        if (get_user(baud, (long __user *)argp))
1397
                                return -EFAULT;
1398
                        mxser_set_baud(info, baud);
1399
                        return 0;
1400
                }
1401
        case MOXA_ASPP_GETBAUD:
1402
                if (copy_to_user(argp, &info->realbaud, sizeof(long)))
1403
                        return -EFAULT;
1404
 
1405
                return 0;
1406
 
1407
        case MOXA_ASPP_OQUEUE:{
1408
                        int len, lsr;
1409
 
1410
                        len = mxser_chars_in_buffer(tty);
1411
 
1412
                        lsr = inb(info->base + UART_LSR) & UART_LSR_TEMT;
1413
 
1414
                        len += (lsr ? 0 : 1);
1415
 
1416
                        if (copy_to_user(argp, &len, sizeof(int)))
1417
                                return -EFAULT;
1418
 
1419
                        return 0;
1420
                }
1421
        case MOXA_ASPP_MON: {
1422
                        int mcr, status;
1423
 
1424
                        /* info->mon_data.ser_param = tty->termios->c_cflag; */
1425
 
1426
                        status = mxser_get_msr(info->base, 1, info->port, info);
1427
                        mxser_check_modem_status(info, status);
1428
 
1429
                        mcr = inb(info->base + UART_MCR);
1430
                        if (mcr & MOXA_MUST_MCR_XON_FLAG)
1431
                                info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
1432
                        else
1433
                                info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD;
1434
 
1435
                        if (mcr & MOXA_MUST_MCR_TX_XON)
1436
                                info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT;
1437
                        else
1438
                                info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
1439
 
1440
                        if (info->tty->hw_stopped)
1441
                                info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
1442
                        else
1443
                                info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
1444
 
1445
                        if (copy_to_user(argp, &info->mon_data,
1446
                                        sizeof(struct mxser_mon)))
1447
                                return -EFAULT;
1448
 
1449
                        return 0;
1450
                }
1451
 
1452
        case MOXA_ASPP_LSTATUS: {
1453
                        if (copy_to_user(argp, &info->err_shadow,
1454
                                        sizeof(unsigned char)))
1455
                                return -EFAULT;
1456
 
1457
                        info->err_shadow = 0;
1458
                        return 0;
1459
                }
1460
        case MOXA_SET_BAUD_METHOD: {
1461
                        int method;
1462
 
1463
                        if (get_user(method, (int __user *)argp))
1464
                                return -EFAULT;
1465
                        mxser_set_baud_method[info->port] = method;
1466
                        if (copy_to_user(argp, &method, sizeof(int)))
1467
                                return -EFAULT;
1468
 
1469
                        return 0;
1470
                }
1471
        default:
1472
                return -ENOIOCTLCMD;
1473
        }
1474
        return 0;
1475
}
1476
 
1477
#ifndef CMSPAR
1478
#define CMSPAR 010000000000
1479
#endif
1480
 
1481
static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1482
{
1483
        int i, result, status;
1484
 
1485
        switch (cmd) {
1486
        case MOXA_GET_CONF:
1487
                if (copy_to_user(argp, mxsercfg,
1488
                                sizeof(struct mxser_hwconf) * 4))
1489
                        return -EFAULT;
1490
                return 0;
1491
        case MOXA_GET_MAJOR:
1492
                if (copy_to_user(argp, &ttymajor, sizeof(int)))
1493
                        return -EFAULT;
1494
                return 0;
1495
 
1496
        case MOXA_GET_CUMAJOR:
1497
                if (copy_to_user(argp, &calloutmajor, sizeof(int)))
1498
                        return -EFAULT;
1499
                return 0;
1500
 
1501
        case MOXA_CHKPORTENABLE:
1502
                result = 0;
1503
                for (i = 0; i < MXSER_PORTS; i++) {
1504
                        if (mxvar_table[i].base)
1505
                                result |= (1 << i);
1506
                }
1507
                return put_user(result, (unsigned long __user *)argp);
1508
        case MOXA_GETDATACOUNT:
1509
                if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
1510
                        return -EFAULT;
1511
                return 0;
1512
        case MOXA_GETMSTATUS:
1513
                for (i = 0; i < MXSER_PORTS; i++) {
1514
                        GMStatus[i].ri = 0;
1515
                        if (!mxvar_table[i].base) {
1516
                                GMStatus[i].dcd = 0;
1517
                                GMStatus[i].dsr = 0;
1518
                                GMStatus[i].cts = 0;
1519
                                continue;
1520
                        }
1521
 
1522
                        if (!mxvar_table[i].tty || !mxvar_table[i].tty->termios)
1523
                                GMStatus[i].cflag = mxvar_table[i].normal_termios.c_cflag;
1524
                        else
1525
                                GMStatus[i].cflag = mxvar_table[i].tty->termios->c_cflag;
1526
 
1527
                        status = inb(mxvar_table[i].base + UART_MSR);
1528
                        if (status & 0x80 /*UART_MSR_DCD */ )
1529
                                GMStatus[i].dcd = 1;
1530
                        else
1531
                                GMStatus[i].dcd = 0;
1532
 
1533
                        if (status & 0x20 /*UART_MSR_DSR */ )
1534
                                GMStatus[i].dsr = 1;
1535
                        else
1536
                                GMStatus[i].dsr = 0;
1537
 
1538
 
1539
                        if (status & 0x10 /*UART_MSR_CTS */ )
1540
                                GMStatus[i].cts = 1;
1541
                        else
1542
                                GMStatus[i].cts = 0;
1543
                }
1544
                if (copy_to_user(argp, GMStatus,
1545
                                sizeof(struct mxser_mstatus) * MXSER_PORTS))
1546
                        return -EFAULT;
1547
                return 0;
1548
        case MOXA_ASPP_MON_EXT: {
1549
                        int status;
1550
                        int opmode, p;
1551
                        int shiftbit;
1552
                        unsigned cflag, iflag;
1553
 
1554
                        for (i = 0; i < MXSER_PORTS; i++) {
1555
                                if (!mxvar_table[i].base)
1556
                                        continue;
1557
 
1558
                                status = mxser_get_msr(mxvar_table[i].base, 0,
1559
                                                        i, &(mxvar_table[i]));
1560
                                /*
1561
                                mxser_check_modem_status(&mxvar_table[i],
1562
                                                                status);
1563
                                */
1564
                                if (status & UART_MSR_TERI)
1565
                                        mxvar_table[i].icount.rng++;
1566
                                if (status & UART_MSR_DDSR)
1567
                                        mxvar_table[i].icount.dsr++;
1568
                                if (status & UART_MSR_DDCD)
1569
                                        mxvar_table[i].icount.dcd++;
1570
                                if (status & UART_MSR_DCTS)
1571
                                        mxvar_table[i].icount.cts++;
1572
 
1573
                                mxvar_table[i].mon_data.modem_status = status;
1574
                                mon_data_ext.rx_cnt[i] = mxvar_table[i].mon_data.rxcnt;
1575
                                mon_data_ext.tx_cnt[i] = mxvar_table[i].mon_data.txcnt;
1576
                                mon_data_ext.up_rxcnt[i] = mxvar_table[i].mon_data.up_rxcnt;
1577
                                mon_data_ext.up_txcnt[i] = mxvar_table[i].mon_data.up_txcnt;
1578
                                mon_data_ext.modem_status[i] = mxvar_table[i].mon_data.modem_status;
1579
                                mon_data_ext.baudrate[i] = mxvar_table[i].realbaud;
1580
 
1581
                                if (!mxvar_table[i].tty || !mxvar_table[i].tty->termios) {
1582
                                        cflag = mxvar_table[i].normal_termios.c_cflag;
1583
                                        iflag = mxvar_table[i].normal_termios.c_iflag;
1584
                                } else {
1585
                                        cflag = mxvar_table[i].tty->termios->c_cflag;
1586
                                        iflag = mxvar_table[i].tty->termios->c_iflag;
1587
                                }
1588
 
1589
                                mon_data_ext.databits[i] = cflag & CSIZE;
1590
 
1591
                                mon_data_ext.stopbits[i] = cflag & CSTOPB;
1592
 
1593
                                mon_data_ext.parity[i] = cflag & (PARENB | PARODD | CMSPAR);
1594
 
1595
                                mon_data_ext.flowctrl[i] = 0x00;
1596
 
1597
                                if (cflag & CRTSCTS)
1598
                                        mon_data_ext.flowctrl[i] |= 0x03;
1599
 
1600
                                if (iflag & (IXON | IXOFF))
1601
                                        mon_data_ext.flowctrl[i] |= 0x0C;
1602
 
1603
                                if (mxvar_table[i].type == PORT_16550A)
1604
                                        mon_data_ext.fifo[i] = 1;
1605
                                else
1606
                                        mon_data_ext.fifo[i] = 0;
1607
 
1608
                                p = i % 4;
1609
                                shiftbit = p * 2;
1610
                                opmode = inb(mxvar_table[i].opmode_ioaddr) >> shiftbit;
1611
                                opmode &= OP_MODE_MASK;
1612
 
1613
                                mon_data_ext.iftype[i] = opmode;
1614
 
1615
                        }
1616
                        if (copy_to_user(argp, &mon_data_ext, sizeof(struct mxser_mon_ext)))
1617
                                return -EFAULT;
1618
 
1619
                        return 0;
1620
 
1621
                }
1622
        default:
1623
                return -ENOIOCTLCMD;
1624
        }
1625
        return 0;
1626
}
1627
 
1628
static void mxser_stoprx(struct tty_struct *tty)
1629
{
1630
        struct mxser_struct *info = tty->driver_data;
1631
        /* unsigned long flags; */
1632
 
1633
        info->ldisc_stop_rx = 1;
1634
        if (I_IXOFF(tty)) {
1635
                /* MX_LOCK(&info->slock); */
1636
                /* following add by Victor Yu. 09-02-2002 */
1637
                if (info->IsMoxaMustChipFlag) {
1638
                        info->IER &= ~MOXA_MUST_RECV_ISR;
1639
                        outb(info->IER, info->base + UART_IER);
1640
                } else {
1641
                        /* above add by Victor Yu. 09-02-2002 */
1642
                        info->x_char = STOP_CHAR(tty);
1643
                        /* mask by Victor Yu. 09-02-2002 */
1644
                        /* outb(info->IER, 0); */
1645
                        outb(0, info->base + UART_IER);
1646
                        info->IER |= UART_IER_THRI;
1647
                        /* force Tx interrupt */
1648
                        outb(info->IER, info->base + UART_IER);
1649
                }               /* add by Victor Yu. 09-02-2002 */
1650
                /* MX_UNLOCK(&info->slock); */
1651
        }
1652
 
1653
        if (info->tty->termios->c_cflag & CRTSCTS) {
1654
                /* MX_LOCK(&info->slock); */
1655
                info->MCR &= ~UART_MCR_RTS;
1656
                outb(info->MCR, info->base + UART_MCR);
1657
                /* MX_UNLOCK(&info->slock); */
1658
        }
1659
}
1660
 
1661
static void mxser_startrx(struct tty_struct *tty)
1662
{
1663
        struct mxser_struct *info = tty->driver_data;
1664
        /* unsigned long flags; */
1665
 
1666
        info->ldisc_stop_rx = 0;
1667
        if (I_IXOFF(tty)) {
1668
                if (info->x_char)
1669
                        info->x_char = 0;
1670
                else {
1671
                        /* MX_LOCK(&info->slock); */
1672
 
1673
                        /* following add by Victor Yu. 09-02-2002 */
1674
                        if (info->IsMoxaMustChipFlag) {
1675
                                info->IER |= MOXA_MUST_RECV_ISR;
1676
                                outb(info->IER, info->base + UART_IER);
1677
                        } else {
1678
                                /* above add by Victor Yu. 09-02-2002 */
1679
 
1680
                                info->x_char = START_CHAR(tty);
1681
                                /* mask by Victor Yu. 09-02-2002 */
1682
                                /* outb(info->IER, 0); */
1683
                                /* add by Victor Yu. 09-02-2002 */
1684
                                outb(0, info->base + UART_IER);
1685
                                /* force Tx interrupt */
1686
                                info->IER |= UART_IER_THRI;
1687
                                outb(info->IER, info->base + UART_IER);
1688
                        }       /* add by Victor Yu. 09-02-2002 */
1689
                        /* MX_UNLOCK(&info->slock); */
1690
                }
1691
        }
1692
 
1693
        if (info->tty->termios->c_cflag & CRTSCTS) {
1694
                /* MX_LOCK(&info->slock); */
1695
                info->MCR |= UART_MCR_RTS;
1696
                outb(info->MCR, info->base + UART_MCR);
1697
                /* MX_UNLOCK(&info->slock); */
1698
        }
1699
}
1700
 
1701
/*
1702
 * This routine is called by the upper-layer tty layer to signal that
1703
 * incoming characters should be throttled.
1704
 */
1705
static void mxser_throttle(struct tty_struct *tty)
1706
{
1707
        /* struct mxser_struct *info = tty->driver_data; */
1708
        /* unsigned long flags; */
1709
 
1710
        /* MX_LOCK(&info->slock); */
1711
        mxser_stoprx(tty);
1712
        /* MX_UNLOCK(&info->slock); */
1713
}
1714
 
1715
static void mxser_unthrottle(struct tty_struct *tty)
1716
{
1717
        /* struct mxser_struct *info = tty->driver_data; */
1718
        /* unsigned long flags; */
1719
 
1720
        /* MX_LOCK(&info->slock); */
1721
        mxser_startrx(tty);
1722
        /* MX_UNLOCK(&info->slock); */
1723
}
1724
 
1725
static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1726
{
1727
        struct mxser_struct *info = tty->driver_data;
1728
        unsigned long flags;
1729
 
1730
        mxser_change_speed(info, old_termios);
1731
 
1732
        if ((old_termios->c_cflag & CRTSCTS) &&
1733
                        !(tty->termios->c_cflag & CRTSCTS)) {
1734
                tty->hw_stopped = 0;
1735
                mxser_start(tty);
1736
        }
1737
 
1738
/* Handle sw stopped */
1739
        if ((old_termios->c_iflag & IXON) &&
1740
                        !(tty->termios->c_iflag & IXON)) {
1741
                tty->stopped = 0;
1742
 
1743
                /* following add by Victor Yu. 09-02-2002 */
1744
                if (info->IsMoxaMustChipFlag) {
1745
                        spin_lock_irqsave(&info->slock, flags);
1746
                        DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->base);
1747
                        spin_unlock_irqrestore(&info->slock, flags);
1748
                }
1749
                /* above add by Victor Yu. 09-02-2002 */
1750
 
1751
                mxser_start(tty);
1752
        }
1753
}
1754
 
1755
/*
1756
 * mxser_stop() and mxser_start()
1757
 *
1758
 * This routines are called before setting or resetting tty->stopped.
1759
 * They enable or disable transmitter interrupts, as necessary.
1760
 */
1761
static void mxser_stop(struct tty_struct *tty)
1762
{
1763
        struct mxser_struct *info = tty->driver_data;
1764
        unsigned long flags;
1765
 
1766
        spin_lock_irqsave(&info->slock, flags);
1767
        if (info->IER & UART_IER_THRI) {
1768
                info->IER &= ~UART_IER_THRI;
1769
                outb(info->IER, info->base + UART_IER);
1770
        }
1771
        spin_unlock_irqrestore(&info->slock, flags);
1772
}
1773
 
1774
static void mxser_start(struct tty_struct *tty)
1775
{
1776
        struct mxser_struct *info = tty->driver_data;
1777
        unsigned long flags;
1778
 
1779
        spin_lock_irqsave(&info->slock, flags);
1780
        if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
1781
                info->IER |= UART_IER_THRI;
1782
                outb(info->IER, info->base + UART_IER);
1783
        }
1784
        spin_unlock_irqrestore(&info->slock, flags);
1785
}
1786
 
1787
/*
1788
 * mxser_wait_until_sent() --- wait until the transmitter is empty
1789
 */
1790
static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
1791
{
1792
        struct mxser_struct *info = tty->driver_data;
1793
        unsigned long orig_jiffies, char_time;
1794
        int lsr;
1795
 
1796
        if (info->type == PORT_UNKNOWN)
1797
                return;
1798
 
1799
        if (info->xmit_fifo_size == 0)
1800
                return;         /* Just in case.... */
1801
 
1802
        orig_jiffies = jiffies;
1803
        /*
1804
         * Set the check interval to be 1/5 of the estimated time to
1805
         * send a single character, and make it at least 1.  The check
1806
         * interval should also be less than the timeout.
1807
         *
1808
         * Note: we have to use pretty tight timings here to satisfy
1809
         * the NIST-PCTS.
1810
         */
1811
        char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size;
1812
        char_time = char_time / 5;
1813
        if (char_time == 0)
1814
                char_time = 1;
1815
        if (timeout && timeout < char_time)
1816
                char_time = timeout;
1817
        /*
1818
         * If the transmitter hasn't cleared in twice the approximate
1819
         * amount of time to send the entire FIFO, it probably won't
1820
         * ever clear.  This assumes the UART isn't doing flow
1821
         * control, which is currently the case.  Hence, if it ever
1822
         * takes longer than info->timeout, this is probably due to a
1823
         * UART bug of some kind.  So, we clamp the timeout parameter at
1824
         * 2*info->timeout.
1825
         */
1826
        if (!timeout || timeout > 2 * info->timeout)
1827
                timeout = 2 * info->timeout;
1828
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1829
        printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...",
1830
                timeout, char_time);
1831
        printk("jiff=%lu...", jiffies);
1832
#endif
1833
        while (!((lsr = inb(info->base + UART_LSR)) & UART_LSR_TEMT)) {
1834
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1835
                printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
1836
#endif
1837
                schedule_timeout_interruptible(char_time);
1838
                if (signal_pending(current))
1839
                        break;
1840
                if (timeout && time_after(jiffies, orig_jiffies + timeout))
1841
                        break;
1842
        }
1843
        set_current_state(TASK_RUNNING);
1844
 
1845
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1846
        printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
1847
#endif
1848
}
1849
 
1850
 
1851
/*
1852
 * This routine is called by tty_hangup() when a hangup is signaled.
1853
 */
1854
void mxser_hangup(struct tty_struct *tty)
1855
{
1856
        struct mxser_struct *info = tty->driver_data;
1857
 
1858
        mxser_flush_buffer(tty);
1859
        mxser_shutdown(info);
1860
        info->event = 0;
1861
        info->count = 0;
1862
        info->flags &= ~ASYNC_NORMAL_ACTIVE;
1863
        info->tty = NULL;
1864
        wake_up_interruptible(&info->open_wait);
1865
}
1866
 
1867
 
1868
/* added by James 03-12-2004. */
1869
/*
1870
 * mxser_rs_break() --- routine which turns the break handling on or off
1871
 */
1872
static void mxser_rs_break(struct tty_struct *tty, int break_state)
1873
{
1874
        struct mxser_struct *info = tty->driver_data;
1875
        unsigned long flags;
1876
 
1877
        spin_lock_irqsave(&info->slock, flags);
1878
        if (break_state == -1)
1879
                outb(inb(info->base + UART_LCR) | UART_LCR_SBC,
1880
                        info->base + UART_LCR);
1881
        else
1882
                outb(inb(info->base + UART_LCR) & ~UART_LCR_SBC,
1883
                        info->base + UART_LCR);
1884
        spin_unlock_irqrestore(&info->slock, flags);
1885
}
1886
 
1887
/* (above) added by James. */
1888
 
1889
 
1890
/*
1891
 * This is the serial driver's generic interrupt routine
1892
 */
1893
static irqreturn_t mxser_interrupt(int irq, void *dev_id)
1894
{
1895
        int status, iir, i;
1896
        struct mxser_struct *info;
1897
        struct mxser_struct *port;
1898
        int max, irqbits, bits, msr;
1899
        int pass_counter = 0;
1900
        int handled = IRQ_NONE;
1901
 
1902
        port = NULL;
1903
        /* spin_lock(&gm_lock); */
1904
 
1905
        for (i = 0; i < MXSER_BOARDS; i++) {
1906
                if (dev_id == &(mxvar_table[i * MXSER_PORTS_PER_BOARD])) {
1907
                        port = dev_id;
1908
                        break;
1909
                }
1910
        }
1911
 
1912
        if (i == MXSER_BOARDS)
1913
                goto irq_stop;
1914
        if (port == 0)
1915
                goto irq_stop;
1916
        max = mxser_numports[mxsercfg[i].board_type - 1];
1917
        while (1) {
1918
                irqbits = inb(port->vector) & port->vectormask;
1919
                if (irqbits == port->vectormask)
1920
                        break;
1921
 
1922
                handled = IRQ_HANDLED;
1923
                for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) {
1924
                        if (irqbits == port->vectormask)
1925
                                break;
1926
                        if (bits & irqbits)
1927
                                continue;
1928
                        info = port + i;
1929
 
1930
                        /* following add by Victor Yu. 09-13-2002 */
1931
                        iir = inb(info->base + UART_IIR);
1932
                        if (iir & UART_IIR_NO_INT)
1933
                                continue;
1934
                        iir &= MOXA_MUST_IIR_MASK;
1935
                        if (!info->tty) {
1936
                                status = inb(info->base + UART_LSR);
1937
                                outb(0x27, info->base + UART_FCR);
1938
                                inb(info->base + UART_MSR);
1939
                                continue;
1940
                        }
1941
 
1942
                        /* mask by Victor Yu. 09-13-2002
1943
                           if ( !info->tty ||
1944
                           (inb(info->base + UART_IIR) & UART_IIR_NO_INT) )
1945
                           continue;
1946
                         */
1947
                        /* mask by Victor Yu. 09-02-2002
1948
                           status = inb(info->base + UART_LSR) & info->read_status_mask;
1949
                         */
1950
 
1951
                        /* following add by Victor Yu. 09-02-2002 */
1952
                        status = inb(info->base + UART_LSR);
1953
 
1954
                        if (status & UART_LSR_PE)
1955
                                info->err_shadow |= NPPI_NOTIFY_PARITY;
1956
                        if (status & UART_LSR_FE)
1957
                                info->err_shadow |= NPPI_NOTIFY_FRAMING;
1958
                        if (status & UART_LSR_OE)
1959
                                info->err_shadow |= NPPI_NOTIFY_HW_OVERRUN;
1960
                        if (status & UART_LSR_BI)
1961
                                info->err_shadow |= NPPI_NOTIFY_BREAK;
1962
 
1963
                        if (info->IsMoxaMustChipFlag) {
1964
                                /*
1965
                                   if ( (status & 0x02) && !(status & 0x01) ) {
1966
                                   outb(info->base+UART_FCR,  0x23);
1967
                                   continue;
1968
                                   }
1969
                                 */
1970
                                if (iir == MOXA_MUST_IIR_GDA ||
1971
                                                iir == MOXA_MUST_IIR_RDA ||
1972
                                                iir == MOXA_MUST_IIR_RTO ||
1973
                                                iir == MOXA_MUST_IIR_LSR)
1974
                                        mxser_receive_chars(info, &status);
1975
 
1976
                        } else {
1977
                                /* above add by Victor Yu. 09-02-2002 */
1978
 
1979
                                status &= info->read_status_mask;
1980
                                if (status & UART_LSR_DR)
1981
                                        mxser_receive_chars(info, &status);
1982
                        }
1983
                        msr = inb(info->base + UART_MSR);
1984
                        if (msr & UART_MSR_ANY_DELTA) {
1985
                                mxser_check_modem_status(info, msr);
1986
                        }
1987
                        /* following add by Victor Yu. 09-13-2002 */
1988
                        if (info->IsMoxaMustChipFlag) {
1989
                                if ((iir == 0x02) && (status & UART_LSR_THRE)) {
1990
                                        mxser_transmit_chars(info);
1991
                                }
1992
                        } else {
1993
                                /* above add by Victor Yu. 09-13-2002 */
1994
 
1995
                                if (status & UART_LSR_THRE) {
1996
/* 8-2-99 by William
1997
                            if ( info->x_char || (info->xmit_cnt > 0) )
1998
*/
1999
                                        mxser_transmit_chars(info);
2000
                                }
2001
                        }
2002
                }
2003
                if (pass_counter++ > MXSER_ISR_PASS_LIMIT) {
2004
                        break;  /* Prevent infinite loops */
2005
                }
2006
        }
2007
 
2008
      irq_stop:
2009
        /* spin_unlock(&gm_lock); */
2010
        return handled;
2011
}
2012
 
2013
static void mxser_receive_chars(struct mxser_struct *info, int *status)
2014
{
2015
        struct tty_struct *tty = info->tty;
2016
        unsigned char ch, gdl;
2017
        int ignored = 0;
2018
        int cnt = 0;
2019
        int recv_room;
2020
        int max = 256;
2021
        unsigned long flags;
2022
 
2023
        spin_lock_irqsave(&info->slock, flags);
2024
 
2025
        recv_room = tty->receive_room;
2026
        if ((recv_room == 0) && (!info->ldisc_stop_rx)) {
2027
                /* mxser_throttle(tty); */
2028
                mxser_stoprx(tty);
2029
                /* return; */
2030
        }
2031
 
2032
        /* following add by Victor Yu. 09-02-2002 */
2033
        if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
2034
 
2035
                if (*status & UART_LSR_SPECIAL) {
2036
                        goto intr_old;
2037
                }
2038
                /* following add by Victor Yu. 02-11-2004 */
2039
                if (info->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID &&
2040
                                (*status & MOXA_MUST_LSR_RERR))
2041
                        goto intr_old;
2042
                /* above add by Victor Yu. 02-14-2004 */
2043
                if (*status & MOXA_MUST_LSR_RERR)
2044
                        goto intr_old;
2045
 
2046
                gdl = inb(info->base + MOXA_MUST_GDL_REGISTER);
2047
 
2048
                /* add by Victor Yu. 02-11-2004 */
2049
                if (info->IsMoxaMustChipFlag == MOXA_MUST_MU150_HWID)
2050
                        gdl &= MOXA_MUST_GDL_MASK;
2051
                if (gdl >= recv_room) {
2052
                        if (!info->ldisc_stop_rx) {
2053
                                /* mxser_throttle(tty); */
2054
                                mxser_stoprx(tty);
2055
                        }
2056
                        /* return; */
2057
                }
2058
                while (gdl--) {
2059
                        ch = inb(info->base + UART_RX);
2060
                        tty_insert_flip_char(tty, ch, 0);
2061
                        cnt++;
2062
                        /*
2063
                           if ((cnt >= HI_WATER) && (info->stop_rx == 0)) {
2064
                           mxser_stoprx(tty);
2065
                           info->stop_rx = 1;
2066
                           break;
2067
                           } */
2068
                }
2069
                goto end_intr;
2070
        }
2071
 intr_old:
2072
        /* above add by Victor Yu. 09-02-2002 */
2073
 
2074
        do {
2075
                if (max-- < 0)
2076
                        break;
2077
                /*
2078
                   if ((cnt >= HI_WATER) && (info->stop_rx == 0)) {
2079
                   mxser_stoprx(tty);
2080
                   info->stop_rx=1;
2081
                   break;
2082
                   }
2083
                 */
2084
 
2085
                ch = inb(info->base + UART_RX);
2086
                /* following add by Victor Yu. 09-02-2002 */
2087
                if (info->IsMoxaMustChipFlag && (*status & UART_LSR_OE) /*&& !(*status&UART_LSR_DR) */ )
2088
                        outb(0x23, info->base + UART_FCR);
2089
                *status &= info->read_status_mask;
2090
                /* above add by Victor Yu. 09-02-2002 */
2091
                if (*status & info->ignore_status_mask) {
2092
                        if (++ignored > 100)
2093
                                break;
2094
                } else {
2095
                        char flag = 0;
2096
                        if (*status & UART_LSR_SPECIAL) {
2097
                                if (*status & UART_LSR_BI) {
2098
                                        flag = TTY_BREAK;
2099
/* added by casper 1/11/2000 */
2100
                                        info->icount.brk++;
2101
/* */
2102
                                        if (info->flags & ASYNC_SAK)
2103
                                                do_SAK(tty);
2104
                                } else if (*status & UART_LSR_PE) {
2105
                                        flag = TTY_PARITY;
2106
/* added by casper 1/11/2000 */
2107
                                        info->icount.parity++;
2108
/* */
2109
                                } else if (*status & UART_LSR_FE) {
2110
                                        flag = TTY_FRAME;
2111
/* added by casper 1/11/2000 */
2112
                                        info->icount.frame++;
2113
/* */
2114
                                } else if (*status & UART_LSR_OE) {
2115
                                        flag = TTY_OVERRUN;
2116
/* added by casper 1/11/2000 */
2117
                                        info->icount.overrun++;
2118
/* */
2119
                                }
2120
                        }
2121
                        tty_insert_flip_char(tty, ch, flag);
2122
                        cnt++;
2123
                        if (cnt >= recv_room) {
2124
                                if (!info->ldisc_stop_rx) {
2125
                                        /* mxser_throttle(tty); */
2126
                                        mxser_stoprx(tty);
2127
                                }
2128
                                break;
2129
                        }
2130
 
2131
                }
2132
 
2133
                /* following add by Victor Yu. 09-02-2002 */
2134
                if (info->IsMoxaMustChipFlag)
2135
                        break;
2136
                /* above add by Victor Yu. 09-02-2002 */
2137
 
2138
                /* mask by Victor Yu. 09-02-2002
2139
                 *status = inb(info->base + UART_LSR) & info->read_status_mask;
2140
                 */
2141
                /* following add by Victor Yu. 09-02-2002 */
2142
                *status = inb(info->base + UART_LSR);
2143
                /* above add by Victor Yu. 09-02-2002 */
2144
        } while (*status & UART_LSR_DR);
2145
 
2146
end_intr:               /* add by Victor Yu. 09-02-2002 */
2147
        mxvar_log.rxcnt[info->port] += cnt;
2148
        info->mon_data.rxcnt += cnt;
2149
        info->mon_data.up_rxcnt += cnt;
2150
        spin_unlock_irqrestore(&info->slock, flags);
2151
 
2152
        tty_flip_buffer_push(tty);
2153
}
2154
 
2155
static void mxser_transmit_chars(struct mxser_struct *info)
2156
{
2157
        int count, cnt;
2158
        unsigned long flags;
2159
 
2160
        spin_lock_irqsave(&info->slock, flags);
2161
 
2162
        if (info->x_char) {
2163
                outb(info->x_char, info->base + UART_TX);
2164
                info->x_char = 0;
2165
                mxvar_log.txcnt[info->port]++;
2166
                info->mon_data.txcnt++;
2167
                info->mon_data.up_txcnt++;
2168
 
2169
/* added by casper 1/11/2000 */
2170
                info->icount.tx++;
2171
/* */
2172
                spin_unlock_irqrestore(&info->slock, flags);
2173
                return;
2174
        }
2175
 
2176
        if (info->xmit_buf == 0) {
2177
                spin_unlock_irqrestore(&info->slock, flags);
2178
                return;
2179
        }
2180
 
2181
        if ((info->xmit_cnt <= 0) || info->tty->stopped ||
2182
                        (info->tty->hw_stopped &&
2183
                        (info->type != PORT_16550A) &&
2184
                        (!info->IsMoxaMustChipFlag))) {
2185
                info->IER &= ~UART_IER_THRI;
2186
                outb(info->IER, info->base + UART_IER);
2187
                spin_unlock_irqrestore(&info->slock, flags);
2188
                return;
2189
        }
2190
 
2191
        cnt = info->xmit_cnt;
2192
        count = info->xmit_fifo_size;
2193
        do {
2194
                outb(info->xmit_buf[info->xmit_tail++],
2195
                        info->base + UART_TX);
2196
                info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
2197
                if (--info->xmit_cnt <= 0)
2198
                        break;
2199
        } while (--count > 0);
2200
        mxvar_log.txcnt[info->port] += (cnt - info->xmit_cnt);
2201
 
2202
/* added by James 03-12-2004. */
2203
        info->mon_data.txcnt += (cnt - info->xmit_cnt);
2204
        info->mon_data.up_txcnt += (cnt - info->xmit_cnt);
2205
/* (above) added by James. */
2206
 
2207
/* added by casper 1/11/2000 */
2208
        info->icount.tx += (cnt - info->xmit_cnt);
2209
/* */
2210
 
2211
        if (info->xmit_cnt < WAKEUP_CHARS) {
2212
                set_bit(MXSER_EVENT_TXLOW, &info->event);
2213
                schedule_work(&info->tqueue);
2214
        }
2215
        if (info->xmit_cnt <= 0) {
2216
                info->IER &= ~UART_IER_THRI;
2217
                outb(info->IER, info->base + UART_IER);
2218
        }
2219
        spin_unlock_irqrestore(&info->slock, flags);
2220
}
2221
 
2222
static void mxser_check_modem_status(struct mxser_struct *info, int status)
2223
{
2224
        /* update input line counters */
2225
        if (status & UART_MSR_TERI)
2226
                info->icount.rng++;
2227
        if (status & UART_MSR_DDSR)
2228
                info->icount.dsr++;
2229
        if (status & UART_MSR_DDCD)
2230
                info->icount.dcd++;
2231
        if (status & UART_MSR_DCTS)
2232
                info->icount.cts++;
2233
        info->mon_data.modem_status = status;
2234
        wake_up_interruptible(&info->delta_msr_wait);
2235
 
2236
        if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
2237
                if (status & UART_MSR_DCD)
2238
                        wake_up_interruptible(&info->open_wait);
2239
                schedule_work(&info->tqueue);
2240
        }
2241
 
2242
        if (info->flags & ASYNC_CTS_FLOW) {
2243
                if (info->tty->hw_stopped) {
2244
                        if (status & UART_MSR_CTS) {
2245
                                info->tty->hw_stopped = 0;
2246
 
2247
                                if ((info->type != PORT_16550A) &&
2248
                                                (!info->IsMoxaMustChipFlag)) {
2249
                                        info->IER |= UART_IER_THRI;
2250
                                        outb(info->IER, info->base + UART_IER);
2251
                                }
2252
                                set_bit(MXSER_EVENT_TXLOW, &info->event);
2253
                                schedule_work(&info->tqueue);                   }
2254
                } else {
2255
                        if (!(status & UART_MSR_CTS)) {
2256
                                info->tty->hw_stopped = 1;
2257
                                if ((info->type != PORT_16550A) &&
2258
                                                (!info->IsMoxaMustChipFlag)) {
2259
                                        info->IER &= ~UART_IER_THRI;
2260
                                        outb(info->IER, info->base + UART_IER);
2261
                                }
2262
                        }
2263
                }
2264
        }
2265
}
2266
 
2267
static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, struct mxser_struct *info)
2268
{
2269
        DECLARE_WAITQUEUE(wait, current);
2270
        int retval;
2271
        int do_clocal = 0;
2272
        unsigned long flags;
2273
 
2274
        /*
2275
         * If non-blocking mode is set, or the port is not enabled,
2276
         * then make the check up front and then exit.
2277
         */
2278
        if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
2279
                info->flags |= ASYNC_NORMAL_ACTIVE;
2280
                return 0;
2281
        }
2282
 
2283
        if (tty->termios->c_cflag & CLOCAL)
2284
                do_clocal = 1;
2285
 
2286
        /*
2287
         * Block waiting for the carrier detect and the line to become
2288
         * free (i.e., not in use by the callout).  While we are in
2289
         * this loop, info->count is dropped by one, so that
2290
         * mxser_close() knows when to free things.  We restore it upon
2291
         * exit, either normal or abnormal.
2292
         */
2293
        retval = 0;
2294
        add_wait_queue(&info->open_wait, &wait);
2295
 
2296
        spin_lock_irqsave(&info->slock, flags);
2297
        if (!tty_hung_up_p(filp))
2298
                info->count--;
2299
        spin_unlock_irqrestore(&info->slock, flags);
2300
        info->blocked_open++;
2301
        while (1) {
2302
                spin_lock_irqsave(&info->slock, flags);
2303
                outb(inb(info->base + UART_MCR) |
2304
                        UART_MCR_DTR | UART_MCR_RTS, info->base + UART_MCR);
2305
                spin_unlock_irqrestore(&info->slock, flags);
2306
                set_current_state(TASK_INTERRUPTIBLE);
2307
                if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)) {
2308
                        if (info->flags & ASYNC_HUP_NOTIFY)
2309
                                retval = -EAGAIN;
2310
                        else
2311
                                retval = -ERESTARTSYS;
2312
                        break;
2313
                }
2314
                if (!(info->flags & ASYNC_CLOSING) &&
2315
                                (do_clocal ||
2316
                                (inb(info->base + UART_MSR) & UART_MSR_DCD)))
2317
                        break;
2318
                if (signal_pending(current)) {
2319
                        retval = -ERESTARTSYS;
2320
                        break;
2321
                }
2322
                schedule();
2323
        }
2324
        set_current_state(TASK_RUNNING);
2325
        remove_wait_queue(&info->open_wait, &wait);
2326
        if (!tty_hung_up_p(filp))
2327
                info->count++;
2328
        info->blocked_open--;
2329
        if (retval)
2330
                return retval;
2331
        info->flags |= ASYNC_NORMAL_ACTIVE;
2332
        return 0;
2333
}
2334
 
2335
static int mxser_startup(struct mxser_struct *info)
2336
{
2337
        unsigned long page;
2338
        unsigned long flags;
2339
 
2340
        page = __get_free_page(GFP_KERNEL);
2341
        if (!page)
2342
                return -ENOMEM;
2343
 
2344
        spin_lock_irqsave(&info->slock, flags);
2345
 
2346
        if (info->flags & ASYNC_INITIALIZED) {
2347
                free_page(page);
2348
                spin_unlock_irqrestore(&info->slock, flags);
2349
                return 0;
2350
        }
2351
 
2352
        if (!info->base || !info->type) {
2353
                if (info->tty)
2354
                        set_bit(TTY_IO_ERROR, &info->tty->flags);
2355
                free_page(page);
2356
                spin_unlock_irqrestore(&info->slock, flags);
2357
                return 0;
2358
        }
2359
        if (info->xmit_buf)
2360
                free_page(page);
2361
        else
2362
                info->xmit_buf = (unsigned char *) page;
2363
 
2364
        /*
2365
         * Clear the FIFO buffers and disable them
2366
         * (they will be reenabled in mxser_change_speed())
2367
         */
2368
        if (info->IsMoxaMustChipFlag)
2369
                outb((UART_FCR_CLEAR_RCVR |
2370
                        UART_FCR_CLEAR_XMIT |
2371
                        MOXA_MUST_FCR_GDA_MODE_ENABLE), info->base + UART_FCR);
2372
        else
2373
                outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
2374
                        info->base + UART_FCR);
2375
 
2376
        /*
2377
         * At this point there's no way the LSR could still be 0xFF;
2378
         * if it is, then bail out, because there's likely no UART
2379
         * here.
2380
         */
2381
        if (inb(info->base + UART_LSR) == 0xff) {
2382
                spin_unlock_irqrestore(&info->slock, flags);
2383
                if (capable(CAP_SYS_ADMIN)) {
2384
                        if (info->tty)
2385
                                set_bit(TTY_IO_ERROR, &info->tty->flags);
2386
                        return 0;
2387
                } else
2388
                        return -ENODEV;
2389
        }
2390
 
2391
        /*
2392
         * Clear the interrupt registers.
2393
         */
2394
        (void) inb(info->base + UART_LSR);
2395
        (void) inb(info->base + UART_RX);
2396
        (void) inb(info->base + UART_IIR);
2397
        (void) inb(info->base + UART_MSR);
2398
 
2399
        /*
2400
         * Now, initialize the UART
2401
         */
2402
        outb(UART_LCR_WLEN8, info->base + UART_LCR);    /* reset DLAB */
2403
        info->MCR = UART_MCR_DTR | UART_MCR_RTS;
2404
        outb(info->MCR, info->base + UART_MCR);
2405
 
2406
        /*
2407
         * Finally, enable interrupts
2408
         */
2409
        info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
2410
        /* info->IER = UART_IER_RLSI | UART_IER_RDI; */
2411
 
2412
        /* following add by Victor Yu. 08-30-2002 */
2413
        if (info->IsMoxaMustChipFlag)
2414
                info->IER |= MOXA_MUST_IER_EGDAI;
2415
        /* above add by Victor Yu. 08-30-2002 */
2416
        outb(info->IER, info->base + UART_IER); /* enable interrupts */
2417
 
2418
        /*
2419
         * And clear the interrupt registers again for luck.
2420
         */
2421
        (void) inb(info->base + UART_LSR);
2422
        (void) inb(info->base + UART_RX);
2423
        (void) inb(info->base + UART_IIR);
2424
        (void) inb(info->base + UART_MSR);
2425
 
2426
        if (info->tty)
2427
                clear_bit(TTY_IO_ERROR, &info->tty->flags);
2428
        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2429
 
2430
        /*
2431
         * and set the speed of the serial port
2432
         */
2433
        spin_unlock_irqrestore(&info->slock, flags);
2434
        mxser_change_speed(info, NULL);
2435
 
2436
        info->flags |= ASYNC_INITIALIZED;
2437
        return 0;
2438
}
2439
 
2440
/*
2441
 * This routine will shutdown a serial port; interrupts maybe disabled, and
2442
 * DTR is dropped if the hangup on close termio flag is on.
2443
 */
2444
static void mxser_shutdown(struct mxser_struct *info)
2445
{
2446
        unsigned long flags;
2447
 
2448
        if (!(info->flags & ASYNC_INITIALIZED))
2449
                return;
2450
 
2451
        spin_lock_irqsave(&info->slock, flags);
2452
 
2453
        /*
2454
         * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
2455
         * here so the queue might never be waken up
2456
         */
2457
        wake_up_interruptible(&info->delta_msr_wait);
2458
 
2459
        /*
2460
         * Free the IRQ, if necessary
2461
         */
2462
        if (info->xmit_buf) {
2463
                free_page((unsigned long) info->xmit_buf);
2464
                info->xmit_buf = NULL;
2465
        }
2466
 
2467
        info->IER = 0;
2468
        outb(0x00, info->base + UART_IER);
2469
 
2470
        if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
2471
                info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
2472
        outb(info->MCR, info->base + UART_MCR);
2473
 
2474
        /* clear Rx/Tx FIFO's */
2475
        /* following add by Victor Yu. 08-30-2002 */
2476
        if (info->IsMoxaMustChipFlag)
2477
                outb((UART_FCR_CLEAR_RCVR |
2478
                        UART_FCR_CLEAR_XMIT |
2479
                        MOXA_MUST_FCR_GDA_MODE_ENABLE), info->base + UART_FCR);
2480
        else
2481
                /* above add by Victor Yu. 08-30-2002 */
2482
                outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
2483
                        info->base + UART_FCR);
2484
 
2485
        /* read data port to reset things */
2486
        (void) inb(info->base + UART_RX);
2487
 
2488
        if (info->tty)
2489
                set_bit(TTY_IO_ERROR, &info->tty->flags);
2490
 
2491
        info->flags &= ~ASYNC_INITIALIZED;
2492
 
2493
        /* following add by Victor Yu. 09-23-2002 */
2494
        if (info->IsMoxaMustChipFlag)
2495
                SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->base);
2496
        /* above add by Victor Yu. 09-23-2002 */
2497
 
2498
        spin_unlock_irqrestore(&info->slock, flags);
2499
}
2500
 
2501
/*
2502
 * This routine is called to set the UART divisor registers to match
2503
 * the specified baud rate for a serial port.
2504
 */
2505
static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_termios)
2506
{
2507
        unsigned cflag, cval, fcr;
2508
        int ret = 0;
2509
        unsigned char status;
2510
        long baud;
2511
        unsigned long flags;
2512
 
2513
        if (!info->tty || !info->tty->termios)
2514
                return ret;
2515
        cflag = info->tty->termios->c_cflag;
2516
        if (!(info->base))
2517
                return ret;
2518
 
2519
#ifndef B921600
2520
#define B921600 (B460800 +1)
2521
#endif
2522
        if (mxser_set_baud_method[info->port] == 0) {
2523
                baud = tty_get_baud_rate(info->tty);
2524
                mxser_set_baud(info, baud);
2525
        }
2526
 
2527
        /* byte size and parity */
2528
        switch (cflag & CSIZE) {
2529
        case CS5:
2530
                cval = 0x00;
2531
                break;
2532
        case CS6:
2533
                cval = 0x01;
2534
                break;
2535
        case CS7:
2536
                cval = 0x02;
2537
                break;
2538
        case CS8:
2539
                cval = 0x03;
2540
                break;
2541
        default:
2542
                cval = 0x00;
2543
                break;          /* too keep GCC shut... */
2544
        }
2545
        if (cflag & CSTOPB)
2546
                cval |= 0x04;
2547
        if (cflag & PARENB)
2548
                cval |= UART_LCR_PARITY;
2549
        if (!(cflag & PARODD))
2550
                cval |= UART_LCR_EPAR;
2551
        if (cflag & CMSPAR)
2552
                cval |= UART_LCR_SPAR;
2553
 
2554
        if ((info->type == PORT_8250) || (info->type == PORT_16450)) {
2555
                if (info->IsMoxaMustChipFlag) {
2556
                        fcr = UART_FCR_ENABLE_FIFO;
2557
                        fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE;
2558
                        SET_MOXA_MUST_FIFO_VALUE(info);
2559
                } else
2560
                        fcr = 0;
2561
        } else {
2562
                fcr = UART_FCR_ENABLE_FIFO;
2563
                /* following add by Victor Yu. 08-30-2002 */
2564
                if (info->IsMoxaMustChipFlag) {
2565
                        fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE;
2566
                        SET_MOXA_MUST_FIFO_VALUE(info);
2567
                } else {
2568
                        /* above add by Victor Yu. 08-30-2002 */
2569
                        switch (info->rx_trigger) {
2570
                        case 1:
2571
                                fcr |= UART_FCR_TRIGGER_1;
2572
                                break;
2573
                        case 4:
2574
                                fcr |= UART_FCR_TRIGGER_4;
2575
                                break;
2576
                        case 8:
2577
                                fcr |= UART_FCR_TRIGGER_8;
2578
                                break;
2579
                        default:
2580
                                fcr |= UART_FCR_TRIGGER_14;
2581
                                break;
2582
                        }
2583
                }
2584
        }
2585
 
2586
        /* CTS flow control flag and modem status interrupts */
2587
        info->IER &= ~UART_IER_MSI;
2588
        info->MCR &= ~UART_MCR_AFE;
2589
        if (cflag & CRTSCTS) {
2590
                info->flags |= ASYNC_CTS_FLOW;
2591
                info->IER |= UART_IER_MSI;
2592
                if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) {
2593
                        info->MCR |= UART_MCR_AFE;
2594
                } else {
2595
                        status = inb(info->base + UART_MSR);
2596
                        if (info->tty->hw_stopped) {
2597
                                if (status & UART_MSR_CTS) {
2598
                                        info->tty->hw_stopped = 0;
2599
                                        if ((info->type != PORT_16550A) &&
2600
                                                        (!info->IsMoxaMustChipFlag)) {
2601
                                                info->IER |= UART_IER_THRI;
2602
                                                outb(info->IER, info->base + UART_IER);
2603
                                        }
2604
                                        set_bit(MXSER_EVENT_TXLOW, &info->event);
2605
                                        schedule_work(&info->tqueue);                           }
2606
                        } else {
2607
                                if (!(status & UART_MSR_CTS)) {
2608
                                        info->tty->hw_stopped = 1;
2609
                                        if ((info->type != PORT_16550A) &&
2610
                                                        (!info->IsMoxaMustChipFlag)) {
2611
                                                info->IER &= ~UART_IER_THRI;
2612
                                                outb(info->IER, info->base + UART_IER);
2613
                                        }
2614
                                }
2615
                        }
2616
                }
2617
        } else {
2618
                info->flags &= ~ASYNC_CTS_FLOW;
2619
        }
2620
        outb(info->MCR, info->base + UART_MCR);
2621
        if (cflag & CLOCAL) {
2622
                info->flags &= ~ASYNC_CHECK_CD;
2623
        } else {
2624
                info->flags |= ASYNC_CHECK_CD;
2625
                info->IER |= UART_IER_MSI;
2626
        }
2627
        outb(info->IER, info->base + UART_IER);
2628
 
2629
        /*
2630
         * Set up parity check flag
2631
         */
2632
        info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
2633
        if (I_INPCK(info->tty))
2634
                info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
2635
        if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
2636
                info->read_status_mask |= UART_LSR_BI;
2637
 
2638
        info->ignore_status_mask = 0;
2639
 
2640
        if (I_IGNBRK(info->tty)) {
2641
                info->ignore_status_mask |= UART_LSR_BI;
2642
                info->read_status_mask |= UART_LSR_BI;
2643
                /*
2644
                 * If we're ignore parity and break indicators, ignore
2645
                 * overruns too.  (For real raw support).
2646
                 */
2647
                if (I_IGNPAR(info->tty)) {
2648
                        info->ignore_status_mask |=
2649
                                                UART_LSR_OE |
2650
                                                UART_LSR_PE |
2651
                                                UART_LSR_FE;
2652
                        info->read_status_mask |=
2653
                                                UART_LSR_OE |
2654
                                                UART_LSR_PE |
2655
                                                UART_LSR_FE;
2656
                }
2657
        }
2658
        /* following add by Victor Yu. 09-02-2002 */
2659
        if (info->IsMoxaMustChipFlag) {
2660
                spin_lock_irqsave(&info->slock, flags);
2661
                SET_MOXA_MUST_XON1_VALUE(info->base, START_CHAR(info->tty));
2662
                SET_MOXA_MUST_XOFF1_VALUE(info->base, STOP_CHAR(info->tty));
2663
                if (I_IXON(info->tty)) {
2664
                        ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->base);
2665
                } else {
2666
                        DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->base);
2667
                }
2668
                if (I_IXOFF(info->tty)) {
2669
                        ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->base);
2670
                } else {
2671
                        DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->base);
2672
                }
2673
                /*
2674
                   if ( I_IXANY(info->tty) ) {
2675
                   info->MCR |= MOXA_MUST_MCR_XON_ANY;
2676
                   ENABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(info->base);
2677
                   } else {
2678
                   info->MCR &= ~MOXA_MUST_MCR_XON_ANY;
2679
                   DISABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(info->base);
2680
                   }
2681
                 */
2682
                spin_unlock_irqrestore(&info->slock, flags);
2683
        }
2684
        /* above add by Victor Yu. 09-02-2002 */
2685
 
2686
 
2687
        outb(fcr, info->base + UART_FCR);       /* set fcr */
2688
        outb(cval, info->base + UART_LCR);
2689
 
2690
        return ret;
2691
}
2692
 
2693
 
2694
static int mxser_set_baud(struct mxser_struct *info, long newspd)
2695
{
2696
        int quot = 0;
2697
        unsigned char cval;
2698
        int ret = 0;
2699
        unsigned long flags;
2700
 
2701
        if (!info->tty || !info->tty->termios)
2702
                return ret;
2703
 
2704
        if (!(info->base))
2705
                return ret;
2706
 
2707
        if (newspd > info->MaxCanSetBaudRate)
2708
                return 0;
2709
 
2710
        info->realbaud = newspd;
2711
        if (newspd == 134) {
2712
                quot = (2 * info->baud_base / 269);
2713
        } else if (newspd) {
2714
                quot = info->baud_base / newspd;
2715
                if (quot == 0)
2716
                        quot = 1;
2717
        } else {
2718
                quot = 0;
2719
        }
2720
 
2721
        info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base);
2722
        info->timeout += HZ / 50;       /* Add .02 seconds of slop */
2723
 
2724
        if (quot) {
2725
                spin_lock_irqsave(&info->slock, flags);
2726
                info->MCR |= UART_MCR_DTR;
2727
                outb(info->MCR, info->base + UART_MCR);
2728
                spin_unlock_irqrestore(&info->slock, flags);
2729
        } else {
2730
                spin_lock_irqsave(&info->slock, flags);
2731
                info->MCR &= ~UART_MCR_DTR;
2732
                outb(info->MCR, info->base + UART_MCR);
2733
                spin_unlock_irqrestore(&info->slock, flags);
2734
                return ret;
2735
        }
2736
 
2737
        cval = inb(info->base + UART_LCR);
2738
 
2739
        outb(cval | UART_LCR_DLAB, info->base + UART_LCR);      /* set DLAB */
2740
 
2741
        outb(quot & 0xff, info->base + UART_DLL);       /* LS of divisor */
2742
        outb(quot >> 8, info->base + UART_DLM); /* MS of divisor */
2743
        outb(cval, info->base + UART_LCR);      /* reset DLAB */
2744
 
2745
 
2746
        return ret;
2747
}
2748
 
2749
/*
2750
 * ------------------------------------------------------------
2751
 * friends of mxser_ioctl()
2752
 * ------------------------------------------------------------
2753
 */
2754
static int mxser_get_serial_info(struct mxser_struct *info, struct serial_struct __user *retinfo)
2755
{
2756
        struct serial_struct tmp;
2757
 
2758
        if (!retinfo)
2759
                return -EFAULT;
2760
        memset(&tmp, 0, sizeof(tmp));
2761
        tmp.type = info->type;
2762
        tmp.line = info->port;
2763
        tmp.port = info->base;
2764
        tmp.irq = info->irq;
2765
        tmp.flags = info->flags;
2766
        tmp.baud_base = info->baud_base;
2767
        tmp.close_delay = info->close_delay;
2768
        tmp.closing_wait = info->closing_wait;
2769
        tmp.custom_divisor = info->custom_divisor;
2770
        tmp.hub6 = 0;
2771
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2772
                return -EFAULT;
2773
        return 0;
2774
}
2775
 
2776
static int mxser_set_serial_info(struct mxser_struct *info, struct serial_struct __user *new_info)
2777
{
2778
        struct serial_struct new_serial;
2779
        unsigned int flags;
2780
        int retval = 0;
2781
 
2782
        if (!new_info || !info->base)
2783
                return -EFAULT;
2784
        if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
2785
                return -EFAULT;
2786
 
2787
        if ((new_serial.irq != info->irq) ||
2788
                        (new_serial.port != info->base) ||
2789
                        (new_serial.custom_divisor != info->custom_divisor) ||
2790
                        (new_serial.baud_base != info->baud_base))
2791
                return -EPERM;
2792
 
2793
        flags = info->flags & ASYNC_SPD_MASK;
2794
 
2795
        if (!capable(CAP_SYS_ADMIN)) {
2796
                if ((new_serial.baud_base != info->baud_base) ||
2797
                                (new_serial.close_delay != info->close_delay) ||
2798
                                ((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK)))
2799
                        return -EPERM;
2800
                info->flags = ((info->flags & ~ASYNC_USR_MASK) |
2801
                                (new_serial.flags & ASYNC_USR_MASK));
2802
        } else {
2803
                /*
2804
                 * OK, past this point, all the error checking has been done.
2805
                 * At this point, we start making changes.....
2806
                 */
2807
                info->flags = ((info->flags & ~ASYNC_FLAGS) |
2808
                                (new_serial.flags & ASYNC_FLAGS));
2809
                info->close_delay = new_serial.close_delay * HZ / 100;
2810
                info->closing_wait = new_serial.closing_wait * HZ / 100;
2811
                info->tty->low_latency =
2812
                                (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
2813
                info->tty->low_latency = 0;      /* (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; */
2814
        }
2815
 
2816
        /* added by casper, 3/17/2000, for mouse */
2817
        info->type = new_serial.type;
2818
 
2819
        process_txrx_fifo(info);
2820
 
2821
        if (info->flags & ASYNC_INITIALIZED) {
2822
                if (flags != (info->flags & ASYNC_SPD_MASK)) {
2823
                        mxser_change_speed(info, NULL);
2824
                }
2825
        } else {
2826
                retval = mxser_startup(info);
2827
        }
2828
        return retval;
2829
}
2830
 
2831
/*
2832
 * mxser_get_lsr_info - get line status register info
2833
 *
2834
 * Purpose: Let user call ioctl() to get info when the UART physically
2835
 *          is emptied.  On bus types like RS485, the transmitter must
2836
 *          release the bus after transmitting. This must be done when
2837
 *          the transmit shift register is empty, not be done when the
2838
 *          transmit holding register is empty.  This functionality
2839
 *          allows an RS485 driver to be written in user space.
2840
 */
2841
static int mxser_get_lsr_info(struct mxser_struct *info, unsigned int __user *value)
2842
{
2843
        unsigned char status;
2844
        unsigned int result;
2845
        unsigned long flags;
2846
 
2847
        spin_lock_irqsave(&info->slock, flags);
2848
        status = inb(info->base + UART_LSR);
2849
        spin_unlock_irqrestore(&info->slock, flags);
2850
        result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
2851
        return put_user(result, value);
2852
}
2853
 
2854
/*
2855
 * This routine sends a break character out the serial port.
2856
 */
2857
static void mxser_send_break(struct mxser_struct *info, int duration)
2858
{
2859
        unsigned long flags;
2860
 
2861
        if (!info->base)
2862
                return;
2863
        set_current_state(TASK_INTERRUPTIBLE);
2864
        spin_lock_irqsave(&info->slock, flags);
2865
        outb(inb(info->base + UART_LCR) | UART_LCR_SBC,
2866
                info->base + UART_LCR);
2867
        spin_unlock_irqrestore(&info->slock, flags);
2868
        schedule_timeout(duration);
2869
        spin_lock_irqsave(&info->slock, flags);
2870
        outb(inb(info->base + UART_LCR) & ~UART_LCR_SBC,
2871
                info->base + UART_LCR);
2872
        spin_unlock_irqrestore(&info->slock, flags);
2873
}
2874
 
2875
static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
2876
{
2877
        struct mxser_struct *info = tty->driver_data;
2878
        unsigned char control, status;
2879
        unsigned long flags;
2880
 
2881
 
2882
        if (tty->index == MXSER_PORTS)
2883
                return -ENOIOCTLCMD;
2884
        if (tty->flags & (1 << TTY_IO_ERROR))
2885
                return -EIO;
2886
 
2887
        control = info->MCR;
2888
 
2889
        spin_lock_irqsave(&info->slock, flags);
2890
        status = inb(info->base + UART_MSR);
2891
        if (status & UART_MSR_ANY_DELTA)
2892
                mxser_check_modem_status(info, status);
2893
        spin_unlock_irqrestore(&info->slock, flags);
2894
        return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
2895
                    ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
2896
                    ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) |
2897
                    ((status & UART_MSR_RI) ? TIOCM_RNG : 0) |
2898
                    ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) |
2899
                    ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
2900
}
2901
 
2902
static int mxser_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear)
2903
{
2904
        struct mxser_struct *info = tty->driver_data;
2905
        unsigned long flags;
2906
 
2907
 
2908
        if (tty->index == MXSER_PORTS)
2909
                return -ENOIOCTLCMD;
2910
        if (tty->flags & (1 << TTY_IO_ERROR))
2911
                return -EIO;
2912
 
2913
        spin_lock_irqsave(&info->slock, flags);
2914
 
2915
        if (set & TIOCM_RTS)
2916
                info->MCR |= UART_MCR_RTS;
2917
        if (set & TIOCM_DTR)
2918
                info->MCR |= UART_MCR_DTR;
2919
 
2920
        if (clear & TIOCM_RTS)
2921
                info->MCR &= ~UART_MCR_RTS;
2922
        if (clear & TIOCM_DTR)
2923
                info->MCR &= ~UART_MCR_DTR;
2924
 
2925
        outb(info->MCR, info->base + UART_MCR);
2926
        spin_unlock_irqrestore(&info->slock, flags);
2927
        return 0;
2928
}
2929
 
2930
 
2931
static int mxser_read_register(int, unsigned short *);
2932
static int mxser_program_mode(int);
2933
static void mxser_normal_mode(int);
2934
 
2935
static int mxser_get_ISA_conf(int cap, struct mxser_hwconf *hwconf)
2936
{
2937
        int id, i, bits;
2938
        unsigned short regs[16], irq;
2939
        unsigned char scratch, scratch2;
2940
 
2941
        hwconf->IsMoxaMustChipFlag = MOXA_OTHER_UART;
2942
 
2943
        id = mxser_read_register(cap, regs);
2944
        if (id == C168_ASIC_ID) {
2945
                hwconf->board_type = MXSER_BOARD_C168_ISA;
2946
                hwconf->ports = 8;
2947
        } else if (id == C104_ASIC_ID) {
2948
                hwconf->board_type = MXSER_BOARD_C104_ISA;
2949
                hwconf->ports = 4;
2950
        } else if (id == C102_ASIC_ID) {
2951
                hwconf->board_type = MXSER_BOARD_C102_ISA;
2952
                hwconf->ports = 2;
2953
        } else if (id == CI132_ASIC_ID) {
2954
                hwconf->board_type = MXSER_BOARD_CI132;
2955
                hwconf->ports = 2;
2956
        } else if (id == CI134_ASIC_ID) {
2957
                hwconf->board_type = MXSER_BOARD_CI134;
2958
                hwconf->ports = 4;
2959
        } else if (id == CI104J_ASIC_ID) {
2960
                hwconf->board_type = MXSER_BOARD_CI104J;
2961
                hwconf->ports = 4;
2962
        } else
2963
                return 0;
2964
 
2965
        irq = 0;
2966
        if (hwconf->ports == 2) {
2967
                irq = regs[9] & 0xF000;
2968
                irq = irq | (irq >> 4);
2969
                if (irq != (regs[9] & 0xFF00))
2970
                        return MXSER_ERR_IRQ_CONFLIT;
2971
        } else if (hwconf->ports == 4) {
2972
                irq = regs[9] & 0xF000;
2973
                irq = irq | (irq >> 4);
2974
                irq = irq | (irq >> 8);
2975
                if (irq != regs[9])
2976
                        return MXSER_ERR_IRQ_CONFLIT;
2977
        } else if (hwconf->ports == 8) {
2978
                irq = regs[9] & 0xF000;
2979
                irq = irq | (irq >> 4);
2980
                irq = irq | (irq >> 8);
2981
                if ((irq != regs[9]) || (irq != regs[10]))
2982
                        return MXSER_ERR_IRQ_CONFLIT;
2983
        }
2984
 
2985
        if (!irq)
2986
                return MXSER_ERR_IRQ;
2987
        hwconf->irq = ((int)(irq & 0xF000) >> 12);
2988
        for (i = 0; i < 8; i++)
2989
                hwconf->ioaddr[i] = (int) regs[i + 1] & 0xFFF8;
2990
        if ((regs[12] & 0x80) == 0)
2991
                return MXSER_ERR_VECTOR;
2992
        hwconf->vector = (int)regs[11]; /* interrupt vector */
2993
        if (id == 1)
2994
                hwconf->vector_mask = 0x00FF;
2995
        else
2996
                hwconf->vector_mask = 0x000F;
2997
        for (i = 7, bits = 0x0100; i >= 0; i--, bits <<= 1) {
2998
                if (regs[12] & bits) {
2999
                        hwconf->baud_base[i] = 921600;
3000
                        hwconf->MaxCanSetBaudRate[i] = 921600;  /* add by Victor Yu. 09-04-2002 */
3001
                } else {
3002
                        hwconf->baud_base[i] = 115200;
3003
                        hwconf->MaxCanSetBaudRate[i] = 115200;  /* add by Victor Yu. 09-04-2002 */
3004
                }
3005
        }
3006
        scratch2 = inb(cap + UART_LCR) & (~UART_LCR_DLAB);
3007
        outb(scratch2 | UART_LCR_DLAB, cap + UART_LCR);
3008
        outb(0, cap + UART_EFR); /* EFR is the same as FCR */
3009
        outb(scratch2, cap + UART_LCR);
3010
        outb(UART_FCR_ENABLE_FIFO, cap + UART_FCR);
3011
        scratch = inb(cap + UART_IIR);
3012
 
3013
        if (scratch & 0xC0)
3014
                hwconf->uart_type = PORT_16550A;
3015
        else
3016
                hwconf->uart_type = PORT_16450;
3017
        if (id == 1)
3018
                hwconf->ports = 8;
3019
        else
3020
                hwconf->ports = 4;
3021
        request_region(hwconf->ioaddr[0], 8 * hwconf->ports, "mxser(IO)");
3022
        request_region(hwconf->vector, 1, "mxser(vector)");
3023
        return hwconf->ports;
3024
}
3025
 
3026
#define CHIP_SK         0x01    /* Serial Data Clock  in Eprom */
3027
#define CHIP_DO         0x02    /* Serial Data Output in Eprom */
3028
#define CHIP_CS         0x04    /* Serial Chip Select in Eprom */
3029
#define CHIP_DI         0x08    /* Serial Data Input  in Eprom */
3030
#define EN_CCMD         0x000   /* Chip's command register     */
3031
#define EN0_RSARLO      0x008   /* Remote start address reg 0  */
3032
#define EN0_RSARHI      0x009   /* Remote start address reg 1  */
3033
#define EN0_RCNTLO      0x00A   /* Remote byte count reg WR    */
3034
#define EN0_RCNTHI      0x00B   /* Remote byte count reg WR    */
3035
#define EN0_DCFG        0x00E   /* Data configuration reg WR   */
3036
#define EN0_PORT        0x010   /* Rcv missed frame error counter RD */
3037
#define ENC_PAGE0       0x000   /* Select page 0 of chip registers   */
3038
#define ENC_PAGE3       0x0C0   /* Select page 3 of chip registers   */
3039
static int mxser_read_register(int port, unsigned short *regs)
3040
{
3041
        int i, k, value, id;
3042
        unsigned int j;
3043
 
3044
        id = mxser_program_mode(port);
3045
        if (id < 0)
3046
                return id;
3047
        for (i = 0; i < 14; i++) {
3048
                k = (i & 0x3F) | 0x180;
3049
                for (j = 0x100; j > 0; j >>= 1) {
3050
                        outb(CHIP_CS, port);
3051
                        if (k & j) {
3052
                                outb(CHIP_CS | CHIP_DO, port);
3053
                                outb(CHIP_CS | CHIP_DO | CHIP_SK, port);        /* A? bit of read */
3054
                        } else {
3055
                                outb(CHIP_CS, port);
3056
                                outb(CHIP_CS | CHIP_SK, port);  /* A? bit of read */
3057
                        }
3058
                }
3059
                (void)inb(port);
3060
                value = 0;
3061
                for (k = 0, j = 0x8000; k < 16; k++, j >>= 1) {
3062
                        outb(CHIP_CS, port);
3063
                        outb(CHIP_CS | CHIP_SK, port);
3064
                        if (inb(port) & CHIP_DI)
3065
                                value |= j;
3066
                }
3067
                regs[i] = value;
3068
                outb(0, port);
3069
        }
3070
        mxser_normal_mode(port);
3071
        return id;
3072
}
3073
 
3074
static int mxser_program_mode(int port)
3075
{
3076
        int id, i, j, n;
3077
        /* unsigned long flags; */
3078
 
3079
        spin_lock(&gm_lock);
3080
        outb(0, port);
3081
        outb(0, port);
3082
        outb(0, port);
3083
        (void)inb(port);
3084
        (void)inb(port);
3085
        outb(0, port);
3086
        (void)inb(port);
3087
        /* restore_flags(flags); */
3088
        spin_unlock(&gm_lock);
3089
 
3090
        id = inb(port + 1) & 0x1F;
3091
        if ((id != C168_ASIC_ID) &&
3092
                        (id != C104_ASIC_ID) &&
3093
                        (id != C102_ASIC_ID) &&
3094
                        (id != CI132_ASIC_ID) &&
3095
                        (id != CI134_ASIC_ID) &&
3096
                        (id != CI104J_ASIC_ID))
3097
                return -1;
3098
        for (i = 0, j = 0; i < 4; i++) {
3099
                n = inb(port + 2);
3100
                if (n == 'M') {
3101
                        j = 1;
3102
                } else if ((j == 1) && (n == 1)) {
3103
                        j = 2;
3104
                        break;
3105
                } else
3106
                        j = 0;
3107
        }
3108
        if (j != 2)
3109
                id = -2;
3110
        return id;
3111
}
3112
 
3113
static void mxser_normal_mode(int port)
3114
{
3115
        int i, n;
3116
 
3117
        outb(0xA5, port + 1);
3118
        outb(0x80, port + 3);
3119
        outb(12, port + 0);      /* 9600 bps */
3120
        outb(0, port + 1);
3121
        outb(0x03, port + 3);   /* 8 data bits */
3122
        outb(0x13, port + 4);   /* loop back mode */
3123
        for (i = 0; i < 16; i++) {
3124
                n = inb(port + 5);
3125
                if ((n & 0x61) == 0x60)
3126
                        break;
3127
                if ((n & 1) == 1)
3128
                        (void)inb(port);
3129
        }
3130
        outb(0x00, port + 4);
3131
}
3132
 
3133
module_init(mxser_module_init);
3134
module_exit(mxser_module_exit);

powered by: WebSVN 2.1.0

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