diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2006-12-08 05:38:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 11:28:53 -0500 |
commit | 3306ce3d0554e2e59cc429b7133e17e1513307cb (patch) | |
tree | ecd4ea2522b6afdcf9e263fc36aef4f3e5327f7a /drivers/char/mxser_new.c | |
parent | 771f2d1af80b6b8f3b23203d7d6b93bbe93435a8 (diff) |
[PATCH] Char: mxser_new, upgrade to 1.9.1
Change cloned experimental driver according to original 1.9.1 moxa driver.
Some int->ulong conversions, outb ~UART_IER_THRI constant. Remove commented
stuff.
I also added printk line with info, if somebody wants to test it, he may
contact me as I can potentially debug the driver with him or just to confirm
it works properly.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/mxser_new.c')
-rw-r--r-- | drivers/char/mxser_new.c | 396 |
1 files changed, 192 insertions, 204 deletions
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 993e3a26c406..befff0548da3 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxser.c -- MOXA Smartio/Industio family multiport serial driver. | 2 | * mxser.c -- MOXA Smartio/Industio family multiport serial driver. |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2001 Moxa Technologies (support@moxa.com.tw). | 4 | * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). |
5 | * | 5 | * |
6 | * This code is loosely based on the Linux serial driver, written by | 6 | * This code is loosely based on the Linux serial driver, written by |
7 | * Linus Torvalds, Theodore T'so and others. | 7 | * Linus Torvalds, Theodore T'so and others. |
@@ -20,15 +20,6 @@ | |||
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | * | 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 | 23 | * 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. | 24 | * <alan@redhat.com>. The original 1.8 code is available on www.moxa.com. |
34 | * - Fixed x86_64 cleanness | 25 | * - Fixed x86_64 cleanness |
@@ -66,7 +57,7 @@ | |||
66 | 57 | ||
67 | #include "mxser_new.h" | 58 | #include "mxser_new.h" |
68 | 59 | ||
69 | #define MXSER_VERSION "1.8" | 60 | #define MXSER_VERSION "1.9.1" |
70 | #define MXSERMAJOR 174 | 61 | #define MXSERMAJOR 174 |
71 | #define MXSERCUMAJOR 175 | 62 | #define MXSERCUMAJOR 175 |
72 | 63 | ||
@@ -76,7 +67,7 @@ | |||
76 | #define MXSER_BOARDS 4 /* Max. boards */ | 67 | #define MXSER_BOARDS 4 /* Max. boards */ |
77 | #define MXSER_PORTS 32 /* Max. ports */ | 68 | #define MXSER_PORTS 32 /* Max. ports */ |
78 | #define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ | 69 | #define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ |
79 | #define MXSER_ISR_PASS_LIMIT 256 | 70 | #define MXSER_ISR_PASS_LIMIT 99999L |
80 | 71 | ||
81 | #define MXSER_ERR_IOADDR -1 | 72 | #define MXSER_ERR_IOADDR -1 |
82 | #define MXSER_ERR_IRQ -2 | 73 | #define MXSER_ERR_IRQ -2 |
@@ -125,6 +116,9 @@ enum { | |||
125 | MXSER_BOARD_CP118U, | 116 | MXSER_BOARD_CP118U, |
126 | MXSER_BOARD_CP102UL, | 117 | MXSER_BOARD_CP102UL, |
127 | MXSER_BOARD_CP102U, | 118 | MXSER_BOARD_CP102U, |
119 | MXSER_BOARD_CP118EL, | ||
120 | MXSER_BOARD_CP168EL, | ||
121 | MXSER_BOARD_CP104EL | ||
128 | }; | 122 | }; |
129 | 123 | ||
130 | static char *mxser_brdname[] = { | 124 | static char *mxser_brdname[] = { |
@@ -149,6 +143,9 @@ static char *mxser_brdname[] = { | |||
149 | "CP-118U series", | 143 | "CP-118U series", |
150 | "CP-102UL series", | 144 | "CP-102UL series", |
151 | "CP-102U series", | 145 | "CP-102U series", |
146 | "CP-118EL series", | ||
147 | "CP-168EL series", | ||
148 | "CP-104EL series" | ||
152 | }; | 149 | }; |
153 | 150 | ||
154 | static int mxser_numports[] = { | 151 | static int mxser_numports[] = { |
@@ -173,6 +170,9 @@ static int mxser_numports[] = { | |||
173 | 8, /* CP118U */ | 170 | 8, /* CP118U */ |
174 | 2, /* CP102UL */ | 171 | 2, /* CP102UL */ |
175 | 2, /* CP102U */ | 172 | 2, /* CP102U */ |
173 | 8, /* CP118EL */ | ||
174 | 8, /* CP168EL */ | ||
175 | 4 /* CP104EL */ | ||
176 | }; | 176 | }; |
177 | 177 | ||
178 | #define UART_TYPE_NUM 2 | 178 | #define UART_TYPE_NUM 2 |
@@ -205,22 +205,43 @@ static const struct mxpciuart_info Gpci_uart_info[UART_INFO_NUM] = { | |||
205 | #ifdef CONFIG_PCI | 205 | #ifdef CONFIG_PCI |
206 | 206 | ||
207 | static struct pci_device_id mxser_pcibrds[] = { | 207 | static struct pci_device_id mxser_pcibrds[] = { |
208 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_C168_PCI}, | 208 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168), |
209 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_C104_PCI}, | 209 | .driver_data = MXSER_BOARD_C168_PCI }, |
210 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP132}, | 210 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104), |
211 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP114}, | 211 | .driver_data = MXSER_BOARD_C104_PCI }, |
212 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CT114}, | 212 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132), |
213 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102}, | 213 | .driver_data = MXSER_BOARD_CP132 }, |
214 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP104U}, | 214 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114), |
215 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP168U}, | 215 | .driver_data = MXSER_BOARD_CP114 }, |
216 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP132U}, | 216 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114), |
217 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP134U}, | 217 | .driver_data = MXSER_BOARD_CT114 }, |
218 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP104JU}, | 218 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102), |
219 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_RC7000}, | 219 | .driver_data = MXSER_BOARD_CP102 }, |
220 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP118U}, | 220 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U), |
221 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102UL}, | 221 | .driver_data = MXSER_BOARD_CP104U }, |
222 | {PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102U}, | 222 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U), |
223 | {0} | 223 | .driver_data = MXSER_BOARD_CP168U }, |
224 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U), | ||
225 | .driver_data = MXSER_BOARD_CP132U }, | ||
226 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U), | ||
227 | .driver_data = MXSER_BOARD_CP134U }, | ||
228 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU), | ||
229 | .driver_data = MXSER_BOARD_CP104JU }, | ||
230 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000), | ||
231 | .driver_data = MXSER_BOARD_RC7000 }, | ||
232 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U), | ||
233 | .driver_data = MXSER_BOARD_CP118U }, | ||
234 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL), | ||
235 | .driver_data = MXSER_BOARD_CP102UL }, | ||
236 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U), | ||
237 | .driver_data = MXSER_BOARD_CP102U }, | ||
238 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL), | ||
239 | .driver_data = MXSER_BOARD_CP118EL }, | ||
240 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL), | ||
241 | .driver_data = MXSER_BOARD_CP168EL }, | ||
242 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL), | ||
243 | .driver_data = MXSER_BOARD_CP104EL }, | ||
244 | { } | ||
224 | }; | 245 | }; |
225 | 246 | ||
226 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); | 247 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); |
@@ -245,7 +266,6 @@ MODULE_AUTHOR("Casper Yang"); | |||
245 | MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); | 266 | MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); |
246 | module_param_array(ioaddr, int, NULL, 0); | 267 | module_param_array(ioaddr, int, NULL, 0); |
247 | module_param(ttymajor, int, 0); | 268 | module_param(ttymajor, int, 0); |
248 | module_param(calloutmajor, int, 0); | ||
249 | module_param(verbose, bool, 0); | 269 | module_param(verbose, bool, 0); |
250 | MODULE_LICENSE("GPL"); | 270 | MODULE_LICENSE("GPL"); |
251 | 271 | ||
@@ -285,23 +305,23 @@ struct mxser_hwconf { | |||
285 | int board_type; | 305 | int board_type; |
286 | int ports; | 306 | int ports; |
287 | int irq; | 307 | int irq; |
288 | int vector; | 308 | unsigned long vector; |
289 | int vector_mask; | 309 | unsigned long vector_mask; |
290 | int uart_type; | 310 | int uart_type; |
291 | int ioaddr[MXSER_PORTS_PER_BOARD]; | 311 | unsigned long ioaddr[MXSER_PORTS_PER_BOARD]; |
292 | int baud_base[MXSER_PORTS_PER_BOARD]; | 312 | int baud_base[MXSER_PORTS_PER_BOARD]; |
293 | moxa_pci_info pciInfo; | 313 | moxa_pci_info pciInfo; |
294 | int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */ | 314 | int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */ |
295 | int MaxCanSetBaudRate[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 09-04-2002 */ | 315 | int MaxCanSetBaudRate[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 09-04-2002 */ |
296 | int opmode_ioaddr[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 01-05-2004 */ | 316 | unsigned long opmode_ioaddr[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 01-05-2004 */ |
297 | }; | 317 | }; |
298 | 318 | ||
299 | struct mxser_struct { | 319 | struct mxser_struct { |
300 | int port; | 320 | int port; |
301 | int base; /* port base address */ | 321 | unsigned long base; /* port base address */ |
302 | int irq; /* port using irq no. */ | 322 | int irq; /* port using irq no. */ |
303 | int vector; /* port irq vector */ | 323 | unsigned long vector; /* port irq vector */ |
304 | int vectormask; /* port vector mask */ | 324 | unsigned long vectormask; /* port vector mask */ |
305 | int rx_high_water; | 325 | int rx_high_water; |
306 | int rx_trigger; /* Rx fifo trigger level */ | 326 | int rx_trigger; /* Rx fifo trigger level */ |
307 | int rx_low_water; | 327 | int rx_low_water; |
@@ -337,7 +357,7 @@ struct mxser_struct { | |||
337 | int timeout; | 357 | int timeout; |
338 | int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */ | 358 | int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */ |
339 | int MaxCanSetBaudRate; /* add by Victor Yu. 09-04-2002 */ | 359 | int MaxCanSetBaudRate; /* add by Victor Yu. 09-04-2002 */ |
340 | int opmode_ioaddr; /* add by Victor Yu. 01-05-2004 */ | 360 | unsigned long opmode_ioaddr; /* add by Victor Yu. 01-05-2004 */ |
341 | unsigned char stop_rx; | 361 | unsigned char stop_rx; |
342 | unsigned char ldisc_stop_rx; | 362 | unsigned char ldisc_stop_rx; |
343 | long realbaud; | 363 | long realbaud; |
@@ -485,6 +505,9 @@ static int __init mxser_module_init(void) | |||
485 | 505 | ||
486 | if (verbose) | 506 | if (verbose) |
487 | printk(KERN_DEBUG "Loading module mxser ...\n"); | 507 | printk(KERN_DEBUG "Loading module mxser ...\n"); |
508 | printk(KERN_INFO "This is mxser driver version 1.9.1 and needs TESTING." | ||
509 | "If your are willing to test this driver, please report to " | ||
510 | "jirislaby@gmail.com. Thanks.\n"); | ||
488 | ret = mxser_init(); | 511 | ret = mxser_init(); |
489 | if (verbose) | 512 | if (verbose) |
490 | printk(KERN_DEBUG "Done.\n"); | 513 | printk(KERN_DEBUG "Done.\n"); |
@@ -636,7 +659,7 @@ static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxs | |||
636 | { | 659 | { |
637 | int i, j; | 660 | int i, j; |
638 | /* unsigned int val; */ | 661 | /* unsigned int val; */ |
639 | unsigned int ioaddress; | 662 | unsigned long ioaddress; |
640 | struct pci_dev *pdev = hwconf->pciInfo.pdev; | 663 | struct pci_dev *pdev = hwconf->pciInfo.pdev; |
641 | 664 | ||
642 | /* io address */ | 665 | /* io address */ |
@@ -790,7 +813,7 @@ static int mxser_init(void) | |||
790 | 813 | ||
791 | /* Start finding ISA boards from module arg */ | 814 | /* Start finding ISA boards from module arg */ |
792 | for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) { | 815 | for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) { |
793 | int cap; | 816 | unsigned long cap; |
794 | 817 | ||
795 | if (!(cap = ioaddr[b])) | 818 | if (!(cap = ioaddr[b])) |
796 | continue; | 819 | continue; |
@@ -928,12 +951,10 @@ static void mxser_do_softint(void *private_) | |||
928 | 951 | ||
929 | tty = info->tty; | 952 | tty = info->tty; |
930 | 953 | ||
931 | if (tty) { | 954 | if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) |
932 | if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) | 955 | tty_wakeup(tty); |
933 | tty_wakeup(tty); | 956 | if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event)) |
934 | if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event)) | 957 | tty_hangup(tty); |
935 | tty_hangup(tty); | ||
936 | } | ||
937 | } | 958 | } |
938 | 959 | ||
939 | static unsigned char mxser_get_msr(int baseaddr, int mode, int port, struct mxser_struct *info) | 960 | static unsigned char mxser_get_msr(int baseaddr, int mode, int port, struct mxser_struct *info) |
@@ -979,6 +1000,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
979 | /* | 1000 | /* |
980 | * Start up serial port | 1001 | * Start up serial port |
981 | */ | 1002 | */ |
1003 | info->count++; | ||
982 | retval = mxser_startup(info); | 1004 | retval = mxser_startup(info); |
983 | if (retval) | 1005 | if (retval) |
984 | return retval; | 1006 | return retval; |
@@ -987,8 +1009,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
987 | if (retval) | 1009 | if (retval) |
988 | return retval; | 1010 | return retval; |
989 | 1011 | ||
990 | info->count++; | ||
991 | |||
992 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { | 1012 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { |
993 | if (tty->driver->subtype == SERIAL_TYPE_NORMAL) | 1013 | if (tty->driver->subtype == SERIAL_TYPE_NORMAL) |
994 | *tty->termios = info->normal_termios; | 1014 | *tty->termios = info->normal_termios; |
@@ -1150,11 +1170,13 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou | |||
1150 | total += c; | 1170 | total += c; |
1151 | } | 1171 | } |
1152 | 1172 | ||
1153 | if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) { | 1173 | if (info->xmit_cnt && !tty->stopped |
1174 | /*&& !(info->IER & UART_IER_THRI)*/) { | ||
1154 | if (!tty->hw_stopped || | 1175 | if (!tty->hw_stopped || |
1155 | (info->type == PORT_16550A) || | 1176 | (info->type == PORT_16550A) || |
1156 | (info->IsMoxaMustChipFlag)) { | 1177 | (info->IsMoxaMustChipFlag)) { |
1157 | spin_lock_irqsave(&info->slock, flags); | 1178 | spin_lock_irqsave(&info->slock, flags); |
1179 | outb(info->IER & ~UART_IER_THRI, info->base + UART_IER); | ||
1158 | info->IER |= UART_IER_THRI; | 1180 | info->IER |= UART_IER_THRI; |
1159 | outb(info->IER, info->base + UART_IER); | 1181 | outb(info->IER, info->base + UART_IER); |
1160 | spin_unlock_irqrestore(&info->slock, flags); | 1182 | spin_unlock_irqrestore(&info->slock, flags); |
@@ -1179,11 +1201,12 @@ static void mxser_put_char(struct tty_struct *tty, unsigned char ch) | |||
1179 | info->xmit_head &= SERIAL_XMIT_SIZE - 1; | 1201 | info->xmit_head &= SERIAL_XMIT_SIZE - 1; |
1180 | info->xmit_cnt++; | 1202 | info->xmit_cnt++; |
1181 | spin_unlock_irqrestore(&info->slock, flags); | 1203 | spin_unlock_irqrestore(&info->slock, flags); |
1182 | if (!tty->stopped && !(info->IER & UART_IER_THRI)) { | 1204 | if (!tty->stopped /*&& !(info->IER & UART_IER_THRI)*/) { |
1183 | if (!tty->hw_stopped || | 1205 | if (!tty->hw_stopped || |
1184 | (info->type == PORT_16550A) || | 1206 | (info->type == PORT_16550A) || |
1185 | info->IsMoxaMustChipFlag) { | 1207 | info->IsMoxaMustChipFlag) { |
1186 | spin_lock_irqsave(&info->slock, flags); | 1208 | spin_lock_irqsave(&info->slock, flags); |
1209 | outb(info->IER & ~UART_IER_THRI, info->base + UART_IER); | ||
1187 | info->IER |= UART_IER_THRI; | 1210 | info->IER |= UART_IER_THRI; |
1188 | outb(info->IER, info->base + UART_IER); | 1211 | outb(info->IER, info->base + UART_IER); |
1189 | spin_unlock_irqrestore(&info->slock, flags); | 1212 | spin_unlock_irqrestore(&info->slock, flags); |
@@ -1208,6 +1231,7 @@ static void mxser_flush_chars(struct tty_struct *tty) | |||
1208 | 1231 | ||
1209 | spin_lock_irqsave(&info->slock, flags); | 1232 | spin_lock_irqsave(&info->slock, flags); |
1210 | 1233 | ||
1234 | outb(info->IER & ~UART_IER_THRI, info->base + UART_IER); | ||
1211 | info->IER |= UART_IER_THRI; | 1235 | info->IER |= UART_IER_THRI; |
1212 | outb(info->IER, info->base + UART_IER); | 1236 | outb(info->IER, info->base + UART_IER); |
1213 | 1237 | ||
@@ -1228,7 +1252,12 @@ static int mxser_write_room(struct tty_struct *tty) | |||
1228 | static int mxser_chars_in_buffer(struct tty_struct *tty) | 1252 | static int mxser_chars_in_buffer(struct tty_struct *tty) |
1229 | { | 1253 | { |
1230 | struct mxser_struct *info = tty->driver_data; | 1254 | struct mxser_struct *info = tty->driver_data; |
1231 | return info->xmit_cnt; | 1255 | int len = info->xmit_cnt; |
1256 | |||
1257 | if (!(inb(info->base + UART_LSR) & UART_LSR_THRE)) | ||
1258 | len++; | ||
1259 | |||
1260 | return len; | ||
1232 | } | 1261 | } |
1233 | 1262 | ||
1234 | static void mxser_flush_buffer(struct tty_struct *tty) | 1263 | static void mxser_flush_buffer(struct tty_struct *tty) |
@@ -1270,7 +1299,8 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c | |||
1270 | 1299 | ||
1271 | /* following add by Victor Yu. 01-05-2004 */ | 1300 | /* following add by Victor Yu. 01-05-2004 */ |
1272 | if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { | 1301 | if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { |
1273 | int opmode, p; | 1302 | int p; |
1303 | unsigned long opmode; | ||
1274 | static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; | 1304 | static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; |
1275 | int shiftbit; | 1305 | int shiftbit; |
1276 | unsigned char val, mask; | 1306 | unsigned char val, mask; |
@@ -1572,9 +1602,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1572 | return -EFAULT; | 1602 | return -EFAULT; |
1573 | return 0; | 1603 | return 0; |
1574 | case MOXA_ASPP_MON_EXT: { | 1604 | case MOXA_ASPP_MON_EXT: { |
1575 | int status; | 1605 | int status, p, shiftbit; |
1576 | int opmode, p; | 1606 | unsigned long opmode; |
1577 | int shiftbit; | ||
1578 | unsigned cflag, iflag; | 1607 | unsigned cflag, iflag; |
1579 | 1608 | ||
1580 | for (i = 0; i < MXSER_PORTS; i++) { | 1609 | for (i = 0; i < MXSER_PORTS; i++) { |
@@ -1654,73 +1683,52 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1654 | static void mxser_stoprx(struct tty_struct *tty) | 1683 | static void mxser_stoprx(struct tty_struct *tty) |
1655 | { | 1684 | { |
1656 | struct mxser_struct *info = tty->driver_data; | 1685 | struct mxser_struct *info = tty->driver_data; |
1657 | /* unsigned long flags; */ | ||
1658 | 1686 | ||
1659 | info->ldisc_stop_rx = 1; | 1687 | info->ldisc_stop_rx = 1; |
1660 | if (I_IXOFF(tty)) { | 1688 | if (I_IXOFF(tty)) { |
1661 | /* MX_LOCK(&info->slock); */ | ||
1662 | /* following add by Victor Yu. 09-02-2002 */ | 1689 | /* following add by Victor Yu. 09-02-2002 */ |
1663 | if (info->IsMoxaMustChipFlag) { | 1690 | if (info->IsMoxaMustChipFlag) { |
1664 | info->IER &= ~MOXA_MUST_RECV_ISR; | 1691 | info->IER &= ~MOXA_MUST_RECV_ISR; |
1665 | outb(info->IER, info->base + UART_IER); | 1692 | outb(info->IER, info->base + UART_IER); |
1666 | } else { | 1693 | } else if (!(info->flags & ASYNC_CLOSING)) { |
1667 | /* above add by Victor Yu. 09-02-2002 */ | ||
1668 | info->x_char = STOP_CHAR(tty); | 1694 | info->x_char = STOP_CHAR(tty); |
1669 | /* mask by Victor Yu. 09-02-2002 */ | ||
1670 | /* outb(info->IER, 0); */ | ||
1671 | outb(0, info->base + UART_IER); | 1695 | outb(0, info->base + UART_IER); |
1672 | info->IER |= UART_IER_THRI; | 1696 | info->IER |= UART_IER_THRI; |
1673 | /* force Tx interrupt */ | ||
1674 | outb(info->IER, info->base + UART_IER); | 1697 | outb(info->IER, info->base + UART_IER); |
1675 | } /* add by Victor Yu. 09-02-2002 */ | 1698 | } |
1676 | /* MX_UNLOCK(&info->slock); */ | ||
1677 | } | 1699 | } |
1678 | 1700 | ||
1679 | if (info->tty->termios->c_cflag & CRTSCTS) { | 1701 | if (info->tty->termios->c_cflag & CRTSCTS) { |
1680 | /* MX_LOCK(&info->slock); */ | ||
1681 | info->MCR &= ~UART_MCR_RTS; | 1702 | info->MCR &= ~UART_MCR_RTS; |
1682 | outb(info->MCR, info->base + UART_MCR); | 1703 | outb(info->MCR, info->base + UART_MCR); |
1683 | /* MX_UNLOCK(&info->slock); */ | ||
1684 | } | 1704 | } |
1685 | } | 1705 | } |
1686 | 1706 | ||
1687 | static void mxser_startrx(struct tty_struct *tty) | 1707 | static void mxser_startrx(struct tty_struct *tty) |
1688 | { | 1708 | { |
1689 | struct mxser_struct *info = tty->driver_data; | 1709 | struct mxser_struct *info = tty->driver_data; |
1690 | /* unsigned long flags; */ | ||
1691 | 1710 | ||
1692 | info->ldisc_stop_rx = 0; | 1711 | info->ldisc_stop_rx = 0; |
1693 | if (I_IXOFF(tty)) { | 1712 | if (I_IXOFF(tty)) { |
1694 | if (info->x_char) | 1713 | if (info->x_char) |
1695 | info->x_char = 0; | 1714 | info->x_char = 0; |
1696 | else { | 1715 | else { |
1697 | /* MX_LOCK(&info->slock); */ | ||
1698 | |||
1699 | /* following add by Victor Yu. 09-02-2002 */ | 1716 | /* following add by Victor Yu. 09-02-2002 */ |
1700 | if (info->IsMoxaMustChipFlag) { | 1717 | if (info->IsMoxaMustChipFlag) { |
1701 | info->IER |= MOXA_MUST_RECV_ISR; | 1718 | info->IER |= MOXA_MUST_RECV_ISR; |
1702 | outb(info->IER, info->base + UART_IER); | 1719 | outb(info->IER, info->base + UART_IER); |
1703 | } else { | 1720 | } else if (!(info->flags & ASYNC_CLOSING)) { |
1704 | /* above add by Victor Yu. 09-02-2002 */ | ||
1705 | |||
1706 | info->x_char = START_CHAR(tty); | 1721 | info->x_char = START_CHAR(tty); |
1707 | /* mask by Victor Yu. 09-02-2002 */ | ||
1708 | /* outb(info->IER, 0); */ | ||
1709 | /* add by Victor Yu. 09-02-2002 */ | ||
1710 | outb(0, info->base + UART_IER); | 1722 | outb(0, info->base + UART_IER); |
1711 | /* force Tx interrupt */ | ||
1712 | info->IER |= UART_IER_THRI; | 1723 | info->IER |= UART_IER_THRI; |
1713 | outb(info->IER, info->base + UART_IER); | 1724 | outb(info->IER, info->base + UART_IER); |
1714 | } /* add by Victor Yu. 09-02-2002 */ | 1725 | } |
1715 | /* MX_UNLOCK(&info->slock); */ | ||
1716 | } | 1726 | } |
1717 | } | 1727 | } |
1718 | 1728 | ||
1719 | if (info->tty->termios->c_cflag & CRTSCTS) { | 1729 | if (info->tty->termios->c_cflag & CRTSCTS) { |
1720 | /* MX_LOCK(&info->slock); */ | ||
1721 | info->MCR |= UART_MCR_RTS; | 1730 | info->MCR |= UART_MCR_RTS; |
1722 | outb(info->MCR, info->base + UART_MCR); | 1731 | outb(info->MCR, info->base + UART_MCR); |
1723 | /* MX_UNLOCK(&info->slock); */ | ||
1724 | } | 1732 | } |
1725 | } | 1733 | } |
1726 | 1734 | ||
@@ -1730,22 +1738,22 @@ static void mxser_startrx(struct tty_struct *tty) | |||
1730 | */ | 1738 | */ |
1731 | static void mxser_throttle(struct tty_struct *tty) | 1739 | static void mxser_throttle(struct tty_struct *tty) |
1732 | { | 1740 | { |
1733 | /* struct mxser_struct *info = tty->driver_data; */ | 1741 | struct mxser_struct *info = tty->driver_data; |
1734 | /* unsigned long flags; */ | 1742 | unsigned long flags; |
1735 | 1743 | ||
1736 | /* MX_LOCK(&info->slock); */ | 1744 | spin_lock_irqsave(&info->slock, flags); |
1737 | mxser_stoprx(tty); | 1745 | mxser_stoprx(tty); |
1738 | /* MX_UNLOCK(&info->slock); */ | 1746 | spin_unlock_irqrestore(&info->slock, flags); |
1739 | } | 1747 | } |
1740 | 1748 | ||
1741 | static void mxser_unthrottle(struct tty_struct *tty) | 1749 | static void mxser_unthrottle(struct tty_struct *tty) |
1742 | { | 1750 | { |
1743 | /* struct mxser_struct *info = tty->driver_data; */ | 1751 | struct mxser_struct *info = tty->driver_data; |
1744 | /* unsigned long flags; */ | 1752 | unsigned long flags; |
1745 | 1753 | ||
1746 | /* MX_LOCK(&info->slock); */ | 1754 | spin_lock_irqsave(&info->slock, flags); |
1747 | mxser_startrx(tty); | 1755 | mxser_startrx(tty); |
1748 | /* MX_UNLOCK(&info->slock); */ | 1756 | spin_unlock_irqrestore(&info->slock, flags); |
1749 | } | 1757 | } |
1750 | 1758 | ||
1751 | static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termios) | 1759 | static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termios) |
@@ -1807,7 +1815,9 @@ static void mxser_start(struct tty_struct *tty) | |||
1807 | unsigned long flags; | 1815 | unsigned long flags; |
1808 | 1816 | ||
1809 | spin_lock_irqsave(&info->slock, flags); | 1817 | spin_lock_irqsave(&info->slock, flags); |
1810 | if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) { | 1818 | if (info->xmit_cnt && info->xmit_buf |
1819 | /* && !(info->IER & UART_IER_THRI) */) { | ||
1820 | outb(info->IER & ~UART_IER_THRI, info->base + UART_IER); | ||
1811 | info->IER |= UART_IER_THRI; | 1821 | info->IER |= UART_IER_THRI; |
1812 | outb(info->IER, info->base + UART_IER); | 1822 | outb(info->IER, info->base + UART_IER); |
1813 | } | 1823 | } |
@@ -1927,6 +1937,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1927 | struct mxser_struct *port; | 1937 | struct mxser_struct *port; |
1928 | int max, irqbits, bits, msr; | 1938 | int max, irqbits, bits, msr; |
1929 | int pass_counter = 0; | 1939 | int pass_counter = 0; |
1940 | unsigned int int_cnt; | ||
1930 | int handled = IRQ_NONE; | 1941 | int handled = IRQ_NONE; |
1931 | 1942 | ||
1932 | port = NULL; | 1943 | port = NULL; |
@@ -1957,90 +1968,77 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1957 | continue; | 1968 | continue; |
1958 | info = port + i; | 1969 | info = port + i; |
1959 | 1970 | ||
1960 | /* following add by Victor Yu. 09-13-2002 */ | 1971 | int_cnt = 0; |
1961 | iir = inb(info->base + UART_IIR); | 1972 | do { |
1962 | if (iir & UART_IIR_NO_INT) | 1973 | /* following add by Victor Yu. 09-13-2002 */ |
1963 | continue; | 1974 | iir = inb(info->base + UART_IIR); |
1964 | iir &= MOXA_MUST_IIR_MASK; | 1975 | if (iir & UART_IIR_NO_INT) |
1965 | if (!info->tty) { | 1976 | break; |
1966 | status = inb(info->base + UART_LSR); | 1977 | iir &= MOXA_MUST_IIR_MASK; |
1967 | outb(0x27, info->base + UART_FCR); | 1978 | if (!info->tty) { |
1968 | inb(info->base + UART_MSR); | 1979 | status = inb(info->base + UART_LSR); |
1969 | continue; | 1980 | outb(0x27, info->base + UART_FCR); |
1970 | } | 1981 | inb(info->base + UART_MSR); |
1971 | /* above add by Victor Yu. 09-13-2002 */ | 1982 | break; |
1972 | /* | 1983 | } |
1973 | if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) { | 1984 | /* above add by Victor Yu. 09-13-2002 */ |
1974 | info->IER |= MOXA_MUST_RECV_ISR; | ||
1975 | outb(info->IER, info->base + UART_IER); | ||
1976 | } | ||
1977 | */ | ||
1978 | |||
1979 | |||
1980 | /* mask by Victor Yu. 09-13-2002 | ||
1981 | if ( !info->tty || | ||
1982 | (inb(info->base + UART_IIR) & UART_IIR_NO_INT) ) | ||
1983 | continue; | ||
1984 | */ | ||
1985 | /* mask by Victor Yu. 09-02-2002 | ||
1986 | status = inb(info->base + UART_LSR) & info->read_status_mask; | ||
1987 | */ | ||
1988 | |||
1989 | /* following add by Victor Yu. 09-02-2002 */ | ||
1990 | status = inb(info->base + UART_LSR); | ||
1991 | 1985 | ||
1992 | if (status & UART_LSR_PE) | 1986 | spin_lock(&info->slock); |
1993 | info->err_shadow |= NPPI_NOTIFY_PARITY; | 1987 | /* following add by Victor Yu. 09-02-2002 */ |
1994 | if (status & UART_LSR_FE) | 1988 | status = inb(info->base + UART_LSR); |
1995 | info->err_shadow |= NPPI_NOTIFY_FRAMING; | ||
1996 | if (status & UART_LSR_OE) | ||
1997 | info->err_shadow |= NPPI_NOTIFY_HW_OVERRUN; | ||
1998 | if (status & UART_LSR_BI) | ||
1999 | info->err_shadow |= NPPI_NOTIFY_BREAK; | ||
2000 | 1989 | ||
2001 | if (info->IsMoxaMustChipFlag) { | 1990 | if (status & UART_LSR_PE) |
2002 | /* | 1991 | info->err_shadow |= NPPI_NOTIFY_PARITY; |
2003 | if ( (status & 0x02) && !(status & 0x01) ) { | 1992 | if (status & UART_LSR_FE) |
2004 | outb(info->base+UART_FCR, 0x23); | 1993 | info->err_shadow |= NPPI_NOTIFY_FRAMING; |
2005 | continue; | 1994 | if (status & UART_LSR_OE) |
2006 | } | 1995 | info->err_shadow |= |
2007 | */ | 1996 | NPPI_NOTIFY_HW_OVERRUN; |
2008 | if (iir == MOXA_MUST_IIR_GDA || | 1997 | if (status & UART_LSR_BI) |
2009 | iir == MOXA_MUST_IIR_RDA || | 1998 | info->err_shadow |= NPPI_NOTIFY_BREAK; |
2010 | iir == MOXA_MUST_IIR_RTO || | 1999 | |
2011 | iir == MOXA_MUST_IIR_LSR) | 2000 | if (info->IsMoxaMustChipFlag) { |
2012 | mxser_receive_chars(info, &status); | 2001 | /* |
2002 | if ( (status & 0x02) && !(status & 0x01) ) { | ||
2003 | outb(info->base+UART_FCR, 0x23); | ||
2004 | continue; | ||
2005 | } | ||
2006 | */ | ||
2007 | if (iir == MOXA_MUST_IIR_GDA || | ||
2008 | iir == MOXA_MUST_IIR_RDA || | ||
2009 | iir == MOXA_MUST_IIR_RTO || | ||
2010 | iir == MOXA_MUST_IIR_LSR) | ||
2011 | mxser_receive_chars(info, | ||
2012 | &status); | ||
2013 | 2013 | ||
2014 | } else { | 2014 | } else { |
2015 | /* above add by Victor Yu. 09-02-2002 */ | 2015 | /* above add by Victor Yu. 09-02-2002 */ |
2016 | 2016 | ||
2017 | status &= info->read_status_mask; | 2017 | status &= info->read_status_mask; |
2018 | if (status & UART_LSR_DR) | 2018 | if (status & UART_LSR_DR) |
2019 | mxser_receive_chars(info, &status); | 2019 | mxser_receive_chars(info, |
2020 | } | 2020 | &status); |
2021 | msr = inb(info->base + UART_MSR); | ||
2022 | if (msr & UART_MSR_ANY_DELTA) { | ||
2023 | mxser_check_modem_status(info, msr); | ||
2024 | } | ||
2025 | /* following add by Victor Yu. 09-13-2002 */ | ||
2026 | if (info->IsMoxaMustChipFlag) { | ||
2027 | if ((iir == 0x02) && (status & UART_LSR_THRE)) { | ||
2028 | mxser_transmit_chars(info); | ||
2029 | } | 2021 | } |
2030 | } else { | 2022 | msr = inb(info->base + UART_MSR); |
2031 | /* above add by Victor Yu. 09-13-2002 */ | 2023 | if (msr & UART_MSR_ANY_DELTA) |
2024 | mxser_check_modem_status(info, msr); | ||
2025 | |||
2026 | /* following add by Victor Yu. 09-13-2002 */ | ||
2027 | if (info->IsMoxaMustChipFlag) { | ||
2028 | if (iir == 0x02 && (status & | ||
2029 | UART_LSR_THRE)) | ||
2030 | mxser_transmit_chars(info); | ||
2031 | } else { | ||
2032 | /* above add by Victor Yu. 09-13-2002 */ | ||
2032 | 2033 | ||
2033 | if (status & UART_LSR_THRE) { | 2034 | if (status & UART_LSR_THRE) |
2034 | /* 8-2-99 by William | 2035 | mxser_transmit_chars(info); |
2035 | if ( info->x_char || (info->xmit_cnt > 0) ) | ||
2036 | */ | ||
2037 | mxser_transmit_chars(info); | ||
2038 | } | 2036 | } |
2039 | } | 2037 | spin_unlock(&info->slock); |
2038 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); | ||
2040 | } | 2039 | } |
2041 | if (pass_counter++ > MXSER_ISR_PASS_LIMIT) { | 2040 | if (pass_counter++ > MXSER_ISR_PASS_LIMIT) |
2042 | break; /* Prevent infinite loops */ | 2041 | break; /* Prevent infinite loops */ |
2043 | } | ||
2044 | } | 2042 | } |
2045 | 2043 | ||
2046 | irq_stop: | 2044 | irq_stop: |
@@ -2070,9 +2068,8 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
2070 | /* following add by Victor Yu. 09-02-2002 */ | 2068 | /* following add by Victor Yu. 09-02-2002 */ |
2071 | if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { | 2069 | if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { |
2072 | 2070 | ||
2073 | if (*status & UART_LSR_SPECIAL) { | 2071 | if (*status & UART_LSR_SPECIAL) |
2074 | goto intr_old; | 2072 | goto intr_old; |
2075 | } | ||
2076 | /* following add by Victor Yu. 02-11-2004 */ | 2073 | /* following add by Victor Yu. 02-11-2004 */ |
2077 | if (info->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID && | 2074 | if (info->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID && |
2078 | (*status & MOXA_MUST_LSR_RERR)) | 2075 | (*status & MOXA_MUST_LSR_RERR)) |
@@ -2097,12 +2094,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
2097 | ch = inb(info->base + UART_RX); | 2094 | ch = inb(info->base + UART_RX); |
2098 | tty_insert_flip_char(tty, ch, 0); | 2095 | tty_insert_flip_char(tty, ch, 0); |
2099 | cnt++; | 2096 | cnt++; |
2100 | /* | ||
2101 | if ((cnt >= HI_WATER) && (info->stop_rx == 0)) { | ||
2102 | mxser_stoprx(tty); | ||
2103 | info->stop_rx = 1; | ||
2104 | break; | ||
2105 | } */ | ||
2106 | } | 2097 | } |
2107 | goto end_intr; | 2098 | goto end_intr; |
2108 | } | 2099 | } |
@@ -2112,17 +2103,11 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
2112 | do { | 2103 | do { |
2113 | if (max-- < 0) | 2104 | if (max-- < 0) |
2114 | break; | 2105 | break; |
2115 | /* | ||
2116 | if ((cnt >= HI_WATER) && (info->stop_rx == 0)) { | ||
2117 | mxser_stoprx(tty); | ||
2118 | info->stop_rx=1; | ||
2119 | break; | ||
2120 | } | ||
2121 | */ | ||
2122 | 2106 | ||
2123 | ch = inb(info->base + UART_RX); | 2107 | ch = inb(info->base + UART_RX); |
2124 | /* following add by Victor Yu. 09-02-2002 */ | 2108 | /* following add by Victor Yu. 09-02-2002 */ |
2125 | if (info->IsMoxaMustChipFlag && (*status & UART_LSR_OE) /*&& !(*status&UART_LSR_DR) */ ) | 2109 | if (info->IsMoxaMustChipFlag && (*status & UART_LSR_OE) |
2110 | /*&& !(*status&UART_LSR_DR) */) | ||
2126 | outb(0x23, info->base + UART_FCR); | 2111 | outb(0x23, info->base + UART_FCR); |
2127 | *status &= info->read_status_mask; | 2112 | *status &= info->read_status_mask; |
2128 | /* above add by Victor Yu. 09-02-2002 */ | 2113 | /* above add by Victor Yu. 09-02-2002 */ |
@@ -2136,26 +2121,25 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
2136 | flag = TTY_BREAK; | 2121 | flag = TTY_BREAK; |
2137 | /* added by casper 1/11/2000 */ | 2122 | /* added by casper 1/11/2000 */ |
2138 | info->icount.brk++; | 2123 | info->icount.brk++; |
2139 | /* */ | 2124 | |
2140 | if (info->flags & ASYNC_SAK) | 2125 | if (info->flags & ASYNC_SAK) |
2141 | do_SAK(tty); | 2126 | do_SAK(tty); |
2142 | } else if (*status & UART_LSR_PE) { | 2127 | } else if (*status & UART_LSR_PE) { |
2143 | flag = TTY_PARITY; | 2128 | flag = TTY_PARITY; |
2144 | /* added by casper 1/11/2000 */ | 2129 | /* added by casper 1/11/2000 */ |
2145 | info->icount.parity++; | 2130 | info->icount.parity++; |
2146 | /* */ | ||
2147 | } else if (*status & UART_LSR_FE) { | 2131 | } else if (*status & UART_LSR_FE) { |
2148 | flag = TTY_FRAME; | 2132 | flag = TTY_FRAME; |
2149 | /* added by casper 1/11/2000 */ | 2133 | /* added by casper 1/11/2000 */ |
2150 | info->icount.frame++; | 2134 | info->icount.frame++; |
2151 | /* */ | ||
2152 | } else if (*status & UART_LSR_OE) { | 2135 | } else if (*status & UART_LSR_OE) { |
2153 | flag = TTY_OVERRUN; | 2136 | flag = TTY_OVERRUN; |
2154 | /* added by casper 1/11/2000 */ | 2137 | /* added by casper 1/11/2000 */ |
2155 | info->icount.overrun++; | 2138 | info->icount.overrun++; |
2156 | /* */ | 2139 | } else |
2157 | } | 2140 | flags = TTY_BREAK; |
2158 | } | 2141 | } else |
2142 | flags = 0; | ||
2159 | tty_insert_flip_char(tty, ch, flag); | 2143 | tty_insert_flip_char(tty, ch, flag); |
2160 | cnt++; | 2144 | cnt++; |
2161 | if (cnt >= recv_room) { | 2145 | if (cnt >= recv_room) { |
@@ -2171,7 +2155,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
2171 | /* following add by Victor Yu. 09-02-2002 */ | 2155 | /* following add by Victor Yu. 09-02-2002 */ |
2172 | if (info->IsMoxaMustChipFlag) | 2156 | if (info->IsMoxaMustChipFlag) |
2173 | break; | 2157 | break; |
2174 | /* above add by Victor Yu. 09-02-2002 */ | ||
2175 | 2158 | ||
2176 | /* mask by Victor Yu. 09-02-2002 | 2159 | /* mask by Victor Yu. 09-02-2002 |
2177 | *status = inb(info->base + UART_LSR) & info->read_status_mask; | 2160 | *status = inb(info->base + UART_LSR) & info->read_status_mask; |
@@ -2206,24 +2189,25 @@ static void mxser_transmit_chars(struct mxser_struct *info) | |||
2206 | 2189 | ||
2207 | /* added by casper 1/11/2000 */ | 2190 | /* added by casper 1/11/2000 */ |
2208 | info->icount.tx++; | 2191 | info->icount.tx++; |
2209 | /* */ | 2192 | goto unlock; |
2210 | spin_unlock_irqrestore(&info->slock, flags); | ||
2211 | return; | ||
2212 | } | 2193 | } |
2213 | 2194 | ||
2214 | if (info->xmit_buf == 0) { | 2195 | if (info->xmit_buf == 0) |
2215 | spin_unlock_irqrestore(&info->slock, flags); | 2196 | goto unlock; |
2216 | return; | ||
2217 | } | ||
2218 | 2197 | ||
2219 | if ((info->xmit_cnt <= 0) || info->tty->stopped || | 2198 | if (info->xmit_cnt == 0) { |
2220 | (info->tty->hw_stopped && | 2199 | if (info->xmit_cnt < WAKEUP_CHARS) { /* XXX what's this for?? */ |
2200 | set_bit(MXSER_EVENT_TXLOW, &info->event); | ||
2201 | schedule_work(&info->tqueue); | ||
2202 | } | ||
2203 | goto unlock; | ||
2204 | } | ||
2205 | if (info->tty->stopped || (info->tty->hw_stopped && | ||
2221 | (info->type != PORT_16550A) && | 2206 | (info->type != PORT_16550A) && |
2222 | (!info->IsMoxaMustChipFlag))) { | 2207 | (!info->IsMoxaMustChipFlag))) { |
2223 | info->IER &= ~UART_IER_THRI; | 2208 | info->IER &= ~UART_IER_THRI; |
2224 | outb(info->IER, info->base + UART_IER); | 2209 | outb(info->IER, info->base + UART_IER); |
2225 | spin_unlock_irqrestore(&info->slock, flags); | 2210 | goto unlock; |
2226 | return; | ||
2227 | } | 2211 | } |
2228 | 2212 | ||
2229 | cnt = info->xmit_cnt; | 2213 | cnt = info->xmit_cnt; |
@@ -2240,11 +2224,9 @@ static void mxser_transmit_chars(struct mxser_struct *info) | |||
2240 | /* added by James 03-12-2004. */ | 2224 | /* added by James 03-12-2004. */ |
2241 | info->mon_data.txcnt += (cnt - info->xmit_cnt); | 2225 | info->mon_data.txcnt += (cnt - info->xmit_cnt); |
2242 | info->mon_data.up_txcnt += (cnt - info->xmit_cnt); | 2226 | info->mon_data.up_txcnt += (cnt - info->xmit_cnt); |
2243 | /* (above) added by James. */ | ||
2244 | 2227 | ||
2245 | /* added by casper 1/11/2000 */ | 2228 | /* added by casper 1/11/2000 */ |
2246 | info->icount.tx += (cnt - info->xmit_cnt); | 2229 | info->icount.tx += (cnt - info->xmit_cnt); |
2247 | /* */ | ||
2248 | 2230 | ||
2249 | if (info->xmit_cnt < WAKEUP_CHARS) { | 2231 | if (info->xmit_cnt < WAKEUP_CHARS) { |
2250 | set_bit(MXSER_EVENT_TXLOW, &info->event); | 2232 | set_bit(MXSER_EVENT_TXLOW, &info->event); |
@@ -2254,6 +2236,7 @@ static void mxser_transmit_chars(struct mxser_struct *info) | |||
2254 | info->IER &= ~UART_IER_THRI; | 2236 | info->IER &= ~UART_IER_THRI; |
2255 | outb(info->IER, info->base + UART_IER); | 2237 | outb(info->IER, info->base + UART_IER); |
2256 | } | 2238 | } |
2239 | unlock: | ||
2257 | spin_unlock_irqrestore(&info->slock, flags); | 2240 | spin_unlock_irqrestore(&info->slock, flags); |
2258 | } | 2241 | } |
2259 | 2242 | ||
@@ -2284,16 +2267,19 @@ static void mxser_check_modem_status(struct mxser_struct *info, int status) | |||
2284 | 2267 | ||
2285 | if ((info->type != PORT_16550A) && | 2268 | if ((info->type != PORT_16550A) && |
2286 | (!info->IsMoxaMustChipFlag)) { | 2269 | (!info->IsMoxaMustChipFlag)) { |
2270 | outb(info->IER & ~UART_IER_THRI, | ||
2271 | info->base + UART_IER); | ||
2287 | info->IER |= UART_IER_THRI; | 2272 | info->IER |= UART_IER_THRI; |
2288 | outb(info->IER, info->base + UART_IER); | 2273 | outb(info->IER, info->base + UART_IER); |
2289 | } | 2274 | } |
2290 | set_bit(MXSER_EVENT_TXLOW, &info->event); | 2275 | set_bit(MXSER_EVENT_TXLOW, &info->event); |
2291 | schedule_work(&info->tqueue); } | 2276 | schedule_work(&info->tqueue); |
2277 | } | ||
2292 | } else { | 2278 | } else { |
2293 | if (!(status & UART_MSR_CTS)) { | 2279 | if (!(status & UART_MSR_CTS)) { |
2294 | info->tty->hw_stopped = 1; | 2280 | info->tty->hw_stopped = 1; |
2295 | if ((info->type != PORT_16550A) && | 2281 | if (info->type != PORT_16550A && |
2296 | (!info->IsMoxaMustChipFlag)) { | 2282 | !info->IsMoxaMustChipFlag) { |
2297 | info->IER &= ~UART_IER_THRI; | 2283 | info->IER &= ~UART_IER_THRI; |
2298 | outb(info->IER, info->base + UART_IER); | 2284 | outb(info->IER, info->base + UART_IER); |
2299 | } | 2285 | } |
@@ -2645,8 +2631,10 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter | |||
2645 | if (info->tty->hw_stopped) { | 2631 | if (info->tty->hw_stopped) { |
2646 | if (status & UART_MSR_CTS) { | 2632 | if (status & UART_MSR_CTS) { |
2647 | info->tty->hw_stopped = 0; | 2633 | info->tty->hw_stopped = 0; |
2648 | if ((info->type != PORT_16550A) && | 2634 | if (info->type != PORT_16550A && |
2649 | (!info->IsMoxaMustChipFlag)) { | 2635 | !info->IsMoxaMustChipFlag) { |
2636 | outb(info->IER & ~UART_IER_THRI, | ||
2637 | info->base + UART_IER); | ||
2650 | info->IER |= UART_IER_THRI; | 2638 | info->IER |= UART_IER_THRI; |
2651 | outb(info->IER, info->base + UART_IER); | 2639 | outb(info->IER, info->base + UART_IER); |
2652 | } | 2640 | } |