aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mxser_new.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/mxser_new.c')
-rw-r--r--drivers/char/mxser_new.c236
1 files changed, 131 insertions, 105 deletions
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index 1bb030b3a51..9af07e4999d 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -49,22 +49,25 @@
49 49
50#include "mxser_new.h" 50#include "mxser_new.h"
51 51
52#define MXSER_VERSION "2.0" 52#define MXSER_VERSION "2.0.1" /* 1.9.15 */
53#define MXSERMAJOR 174 53#define MXSERMAJOR 174
54#define MXSERCUMAJOR 175 54#define MXSERCUMAJOR 175
55 55
56#define MXSER_EVENT_TXLOW 1
57
58#define MXSER_BOARDS 4 /* Max. boards */ 56#define MXSER_BOARDS 4 /* Max. boards */
59#define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ 57#define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */
60#define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) 58#define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD)
61#define MXSER_ISR_PASS_LIMIT 99999L 59#define MXSER_ISR_PASS_LIMIT 100
62 60
63#define MXSER_ERR_IOADDR -1 61#define MXSER_ERR_IOADDR -1
64#define MXSER_ERR_IRQ -2 62#define MXSER_ERR_IRQ -2
65#define MXSER_ERR_IRQ_CONFLIT -3 63#define MXSER_ERR_IRQ_CONFLIT -3
66#define MXSER_ERR_VECTOR -4 64#define MXSER_ERR_VECTOR -4
67 65
66/*CheckIsMoxaMust return value*/
67#define MOXA_OTHER_UART 0x00
68#define MOXA_MUST_MU150_HWID 0x01
69#define MOXA_MUST_MU860_HWID 0x02
70
68#define WAKEUP_CHARS 256 71#define WAKEUP_CHARS 256
69 72
70#define UART_MCR_AFE 0x20 73#define UART_MCR_AFE 0x20
@@ -176,6 +179,18 @@ static struct pci_device_id mxser_pcibrds[] = {
176}; 179};
177MODULE_DEVICE_TABLE(pci, mxser_pcibrds); 180MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
178 181
182static int mxvar_baud_table[] = {
183 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
184 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
185};
186static unsigned int mxvar_baud_table1[] = {
187 0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400,
188 B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B921600
189};
190#define BAUD_TABLE_NO ARRAY_SIZE(mxvar_baud_table)
191
192#define B_SPEC B2000000
193
179static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 }; 194static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
180static int ttymajor = MXSERMAJOR; 195static int ttymajor = MXSERMAJOR;
181static int calloutmajor = MXSERCUMAJOR; 196static int calloutmajor = MXSERCUMAJOR;
@@ -237,8 +252,7 @@ struct mxser_port {
237 long realbaud; 252 long realbaud;
238 int type; /* UART type */ 253 int type; /* UART type */
239 int flags; /* defined in tty.h */ 254 int flags; /* defined in tty.h */
240 long session; /* Session of opening process */ 255 int speed;
241 long pgrp; /* pgrp of opening process */
242 256
243 int x_char; /* xon/xoff character */ 257 int x_char; /* xon/xoff character */
244 int IER; /* Interrupt Enable Register */ 258 int IER; /* Interrupt Enable Register */
@@ -267,14 +281,11 @@ struct mxser_port {
267 int xmit_cnt; 281 int xmit_cnt;
268 282
269 struct ktermios normal_termios; 283 struct ktermios normal_termios;
270 struct ktermios callout_termios;
271 284
272 struct mxser_mon mon_data; 285 struct mxser_mon mon_data;
273 286
274 spinlock_t slock; 287 spinlock_t slock;
275 struct work_struct tqueue;
276 wait_queue_head_t open_wait; 288 wait_queue_head_t open_wait;
277 wait_queue_head_t close_wait;
278 wait_queue_head_t delta_msr_wait; 289 wait_queue_head_t delta_msr_wait;
279}; 290};
280 291
@@ -313,10 +324,9 @@ static int mxvar_diagflag;
313static unsigned char mxser_msr[MXSER_PORTS + 1]; 324static unsigned char mxser_msr[MXSER_PORTS + 1];
314static struct mxser_mon_ext mon_data_ext; 325static struct mxser_mon_ext mon_data_ext;
315static int mxser_set_baud_method[MXSER_PORTS + 1]; 326static int mxser_set_baud_method[MXSER_PORTS + 1];
316static spinlock_t gm_lock;
317 327
318#ifdef CONFIG_PCI 328#ifdef CONFIG_PCI
319static int CheckIsMoxaMust(int io) 329static int __devinit CheckIsMoxaMust(int io)
320{ 330{
321 u8 oldmcr, hwid; 331 u8 oldmcr, hwid;
322 int i; 332 int i;
@@ -360,15 +370,6 @@ static void process_txrx_fifo(struct mxser_port *info)
360 } 370 }
361} 371}
362 372
363static void mxser_do_softint(struct work_struct *work)
364{
365 struct mxser_port *info = container_of(work, struct mxser_port, tqueue);
366 struct tty_struct *tty = info->tty;
367
368 if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event))
369 tty_wakeup(tty);
370}
371
372static unsigned char mxser_get_msr(int baseaddr, int mode, int port) 373static unsigned char mxser_get_msr(int baseaddr, int mode, int port)
373{ 374{
374 unsigned char status = 0; 375 unsigned char status = 0;
@@ -456,10 +457,10 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
456 457
457static int mxser_set_baud(struct mxser_port *info, long newspd) 458static int mxser_set_baud(struct mxser_port *info, long newspd)
458{ 459{
460 unsigned int i;
459 int quot = 0; 461 int quot = 0;
460 unsigned char cval; 462 unsigned char cval;
461 int ret = 0; 463 int ret = 0;
462 unsigned long flags;
463 464
464 if (!info->tty || !info->tty->termios) 465 if (!info->tty || !info->tty->termios)
465 return ret; 466 return ret;
@@ -471,29 +472,34 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
471 return 0; 472 return 0;
472 473
473 info->realbaud = newspd; 474 info->realbaud = newspd;
474 if (newspd == 134) { 475 for (i = 0; i < BAUD_TABLE_NO; i++)
475 quot = (2 * info->baud_base / 269); 476 if (newspd == mxvar_baud_table[i])
476 } else if (newspd) { 477 break;
477 quot = info->baud_base / newspd; 478 if (i == BAUD_TABLE_NO) {
478 if (quot == 0) 479 quot = info->baud_base / info->speed;
479 quot = 1; 480 if (info->speed <= 0 || info->speed > info->max_baud)
481 quot = 0;
480 } else { 482 } else {
481 quot = 0; 483 if (newspd == 134) {
484 quot = (2 * info->baud_base / 269);
485 } else if (newspd) {
486 quot = info->baud_base / newspd;
487 if (quot == 0)
488 quot = 1;
489 } else {
490 quot = 0;
491 }
482 } 492 }
483 493
484 info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); 494 info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base);
485 info->timeout += HZ / 50; /* Add .02 seconds of slop */ 495 info->timeout += HZ / 50; /* Add .02 seconds of slop */
486 496
487 if (quot) { 497 if (quot) {
488 spin_lock_irqsave(&info->slock, flags);
489 info->MCR |= UART_MCR_DTR; 498 info->MCR |= UART_MCR_DTR;
490 outb(info->MCR, info->ioaddr + UART_MCR); 499 outb(info->MCR, info->ioaddr + UART_MCR);
491 spin_unlock_irqrestore(&info->slock, flags);
492 } else { 500 } else {
493 spin_lock_irqsave(&info->slock, flags);
494 info->MCR &= ~UART_MCR_DTR; 501 info->MCR &= ~UART_MCR_DTR;
495 outb(info->MCR, info->ioaddr + UART_MCR); 502 outb(info->MCR, info->ioaddr + UART_MCR);
496 spin_unlock_irqrestore(&info->slock, flags);
497 return ret; 503 return ret;
498 } 504 }
499 505
@@ -505,6 +511,18 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
505 outb(quot >> 8, info->ioaddr + UART_DLM); /* MS of divisor */ 511 outb(quot >> 8, info->ioaddr + UART_DLM); /* MS of divisor */
506 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ 512 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */
507 513
514 if (i == BAUD_TABLE_NO) {
515 quot = info->baud_base % info->speed;
516 quot *= 8;
517 if ((quot % info->speed) > (info->speed / 2)) {
518 quot /= info->speed;
519 quot++;
520 } else {
521 quot /= info->speed;
522 }
523 SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, quot);
524 } else
525 SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, 0);
508 526
509 return ret; 527 return ret;
510} 528}
@@ -520,7 +538,6 @@ static int mxser_change_speed(struct mxser_port *info,
520 int ret = 0; 538 int ret = 0;
521 unsigned char status; 539 unsigned char status;
522 long baud; 540 long baud;
523 unsigned long flags;
524 541
525 if (!info->tty || !info->tty->termios) 542 if (!info->tty || !info->tty->termios)
526 return ret; 543 return ret;
@@ -529,7 +546,10 @@ static int mxser_change_speed(struct mxser_port *info,
529 return ret; 546 return ret;
530 547
531 if (mxser_set_baud_method[info->tty->index] == 0) { 548 if (mxser_set_baud_method[info->tty->index] == 0) {
532 baud = tty_get_baud_rate(info->tty); 549 if ((cflag & CBAUD) == B_SPEC)
550 baud = info->speed;
551 else
552 baud = tty_get_baud_rate(info->tty);
533 mxser_set_baud(info, baud); 553 mxser_set_baud(info, baud);
534 } 554 }
535 555
@@ -612,8 +632,8 @@ static int mxser_change_speed(struct mxser_port *info,
612 outb(info->IER, info->ioaddr + 632 outb(info->IER, info->ioaddr +
613 UART_IER); 633 UART_IER);
614 } 634 }
615 set_bit(MXSER_EVENT_TXLOW, &info->event); 635 tty_wakeup(info->tty);
616 schedule_work(&info->tqueue); } 636 }
617 } else { 637 } else {
618 if (!(status & UART_MSR_CTS)) { 638 if (!(status & UART_MSR_CTS)) {
619 info->tty->hw_stopped = 1; 639 info->tty->hw_stopped = 1;
@@ -668,7 +688,6 @@ static int mxser_change_speed(struct mxser_port *info,
668 } 688 }
669 } 689 }
670 if (info->board->chip_flag) { 690 if (info->board->chip_flag) {
671 spin_lock_irqsave(&info->slock, flags);
672 SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty)); 691 SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty));
673 SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty)); 692 SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty));
674 if (I_IXON(info->tty)) { 693 if (I_IXON(info->tty)) {
@@ -681,7 +700,6 @@ static int mxser_change_speed(struct mxser_port *info,
681 } else { 700 } else {
682 DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr); 701 DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
683 } 702 }
684 spin_unlock_irqrestore(&info->slock, flags);
685 } 703 }
686 704
687 705
@@ -708,7 +726,6 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
708 if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { 726 if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
709 if (status & UART_MSR_DCD) 727 if (status & UART_MSR_DCD)
710 wake_up_interruptible(&port->open_wait); 728 wake_up_interruptible(&port->open_wait);
711 schedule_work(&port->tqueue);
712 } 729 }
713 730
714 if (port->flags & ASYNC_CTS_FLOW) { 731 if (port->flags & ASYNC_CTS_FLOW) {
@@ -724,8 +741,7 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
724 outb(port->IER, port->ioaddr + 741 outb(port->IER, port->ioaddr +
725 UART_IER); 742 UART_IER);
726 } 743 }
727 set_bit(MXSER_EVENT_TXLOW, &port->event); 744 tty_wakeup(port->tty);
728 schedule_work(&port->tqueue);
729 } 745 }
730 } else { 746 } else {
731 if (!(status & UART_MSR_CTS)) { 747 if (!(status & UART_MSR_CTS)) {
@@ -836,10 +852,10 @@ static int mxser_startup(struct mxser_port *info)
836 /* 852 /*
837 * and set the speed of the serial port 853 * and set the speed of the serial port
838 */ 854 */
839 spin_unlock_irqrestore(&info->slock, flags);
840 mxser_change_speed(info, NULL); 855 mxser_change_speed(info, NULL);
841
842 info->flags |= ASYNC_INITIALIZED; 856 info->flags |= ASYNC_INITIALIZED;
857 spin_unlock_irqrestore(&info->slock, flags);
858
843 return 0; 859 return 0;
844} 860}
845 861
@@ -909,11 +925,9 @@ static void mxser_shutdown(struct mxser_port *info)
909static int mxser_open(struct tty_struct *tty, struct file *filp) 925static int mxser_open(struct tty_struct *tty, struct file *filp)
910{ 926{
911 struct mxser_port *info; 927 struct mxser_port *info;
928 unsigned long flags;
912 int retval, line; 929 int retval, line;
913 930
914 /* initialize driver_data in case something fails */
915 tty->driver_data = NULL;
916
917 line = tty->index; 931 line = tty->index;
918 if (line == MXSER_PORTS) 932 if (line == MXSER_PORTS)
919 return 0; 933 return 0;
@@ -928,7 +942,9 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
928 /* 942 /*
929 * Start up serial port 943 * Start up serial port
930 */ 944 */
945 spin_lock_irqsave(&info->slock, flags);
931 info->count++; 946 info->count++;
947 spin_unlock_irqrestore(&info->slock, flags);
932 retval = mxser_startup(info); 948 retval = mxser_startup(info);
933 if (retval) 949 if (retval)
934 return retval; 950 return retval;
@@ -937,17 +953,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
937 if (retval) 953 if (retval)
938 return retval; 954 return retval;
939 955
940 if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
941 if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
942 *tty->termios = info->normal_termios;
943 else
944 *tty->termios = info->callout_termios;
945 mxser_change_speed(info, NULL);
946 }
947
948 info->session = process_session(current);
949 info->pgrp = process_group(current);
950
951 /* unmark here for very high baud rate (ex. 921600 bps) used */ 956 /* unmark here for very high baud rate (ex. 921600 bps) used */
952 tty->low_latency = 1; 957 tty->low_latency = 1;
953 return 0; 958 return 0;
@@ -1054,8 +1059,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1054 } 1059 }
1055 1060
1056 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 1061 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1057 wake_up_interruptible(&info->close_wait);
1058
1059} 1062}
1060 1063
1061static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) 1064static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1222,6 +1225,7 @@ static int mxser_set_serial_info(struct mxser_port *info,
1222 struct serial_struct __user *new_info) 1225 struct serial_struct __user *new_info)
1223{ 1226{
1224 struct serial_struct new_serial; 1227 struct serial_struct new_serial;
1228 unsigned long sl_flags;
1225 unsigned int flags; 1229 unsigned int flags;
1226 int retval = 0; 1230 int retval = 0;
1227 1231
@@ -1264,8 +1268,11 @@ static int mxser_set_serial_info(struct mxser_port *info,
1264 process_txrx_fifo(info); 1268 process_txrx_fifo(info);
1265 1269
1266 if (info->flags & ASYNC_INITIALIZED) { 1270 if (info->flags & ASYNC_INITIALIZED) {
1267 if (flags != (info->flags & ASYNC_SPD_MASK)) 1271 if (flags != (info->flags & ASYNC_SPD_MASK)) {
1272 spin_lock_irqsave(&info->slock, sl_flags);
1268 mxser_change_speed(info, NULL); 1273 mxser_change_speed(info, NULL);
1274 spin_unlock_irqrestore(&info->slock, sl_flags);
1275 }
1269 } else 1276 } else
1270 retval = mxser_startup(info); 1277 retval = mxser_startup(info);
1271 1278
@@ -1373,11 +1380,10 @@ static int mxser_tiocmset(struct tty_struct *tty, struct file *file,
1373 return 0; 1380 return 0;
1374} 1381}
1375 1382
1376static int mxser_program_mode(int port) 1383static int __init mxser_program_mode(int port)
1377{ 1384{
1378 int id, i, j, n; 1385 int id, i, j, n;
1379 1386
1380 spin_lock(&gm_lock);
1381 outb(0, port); 1387 outb(0, port);
1382 outb(0, port); 1388 outb(0, port);
1383 outb(0, port); 1389 outb(0, port);
@@ -1385,7 +1391,6 @@ static int mxser_program_mode(int port)
1385 (void)inb(port); 1391 (void)inb(port);
1386 outb(0, port); 1392 outb(0, port);
1387 (void)inb(port); 1393 (void)inb(port);
1388 spin_unlock(&gm_lock);
1389 1394
1390 id = inb(port + 1) & 0x1F; 1395 id = inb(port + 1) & 0x1F;
1391 if ((id != C168_ASIC_ID) && 1396 if ((id != C168_ASIC_ID) &&
@@ -1410,7 +1415,7 @@ static int mxser_program_mode(int port)
1410 return id; 1415 return id;
1411} 1416}
1412 1417
1413static void mxser_normal_mode(int port) 1418static void __init mxser_normal_mode(int port)
1414{ 1419{
1415 int i, n; 1420 int i, n;
1416 1421
@@ -1443,7 +1448,7 @@ static void mxser_normal_mode(int port)
1443#define EN0_PORT 0x010 /* Rcv missed frame error counter RD */ 1448#define EN0_PORT 0x010 /* Rcv missed frame error counter RD */
1444#define ENC_PAGE0 0x000 /* Select page 0 of chip registers */ 1449#define ENC_PAGE0 0x000 /* Select page 0 of chip registers */
1445#define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */ 1450#define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */
1446static int mxser_read_register(int port, unsigned short *regs) 1451static int __init mxser_read_register(int port, unsigned short *regs)
1447{ 1452{
1448 int i, k, value, id; 1453 int i, k, value, id;
1449 unsigned int j; 1454 unsigned int j;
@@ -1644,6 +1649,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1644 struct serial_icounter_struct __user *p_cuser; 1649 struct serial_icounter_struct __user *p_cuser;
1645 unsigned long templ; 1650 unsigned long templ;
1646 unsigned long flags; 1651 unsigned long flags;
1652 unsigned int i;
1647 void __user *argp = (void __user *)arg; 1653 void __user *argp = (void __user *)arg;
1648 int retval; 1654 int retval;
1649 1655
@@ -1682,6 +1688,36 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1682 return 0; 1688 return 0;
1683 } 1689 }
1684 1690
1691 if (cmd == MOXA_SET_SPECIAL_BAUD_RATE) {
1692 int speed;
1693
1694 if (get_user(speed, (int __user *)argp))
1695 return -EFAULT;
1696 if (speed <= 0 || speed > info->max_baud)
1697 return -EFAULT;
1698 if (!info->tty || !info->tty->termios || !info->ioaddr)
1699 return 0;
1700 info->tty->termios->c_cflag &= ~(CBAUD | CBAUDEX);
1701 for (i = 0; i < BAUD_TABLE_NO; i++)
1702 if (speed == mxvar_baud_table[i])
1703 break;
1704 if (i == BAUD_TABLE_NO) {
1705 info->tty->termios->c_cflag |= B_SPEC;
1706 } else if (speed != 0)
1707 info->tty->termios->c_cflag |= mxvar_baud_table1[i];
1708
1709 info->speed = speed;
1710 spin_lock_irqsave(&info->slock, flags);
1711 mxser_change_speed(info, NULL);
1712 spin_unlock_irqrestore(&info->slock, flags);
1713
1714 return 0;
1715 } else if (cmd == MOXA_GET_SPECIAL_BAUD_RATE) {
1716 if (copy_to_user(argp, &info->speed, sizeof(int)))
1717 return -EFAULT;
1718 return 0;
1719 }
1720
1685 if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT && 1721 if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT &&
1686 test_bit(TTY_IO_ERROR, &tty->flags)) 1722 test_bit(TTY_IO_ERROR, &tty->flags))
1687 return -EIO; 1723 return -EIO;
@@ -1799,7 +1835,9 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1799 long baud; 1835 long baud;
1800 if (get_user(baud, (long __user *)argp)) 1836 if (get_user(baud, (long __user *)argp))
1801 return -EFAULT; 1837 return -EFAULT;
1838 spin_lock_irqsave(&info->slock, flags);
1802 mxser_set_baud(info, baud); 1839 mxser_set_baud(info, baud);
1840 spin_unlock_irqrestore(&info->slock, flags);
1803 return 0; 1841 return 0;
1804 } 1842 }
1805 case MOXA_ASPP_GETBAUD: 1843 case MOXA_ASPP_GETBAUD:
@@ -1976,7 +2014,9 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
1976 if ((tty->termios->c_cflag != old_termios->c_cflag) || 2014 if ((tty->termios->c_cflag != old_termios->c_cflag) ||
1977 (RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) { 2015 (RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) {
1978 2016
2017 spin_lock_irqsave(&info->slock, flags);
1979 mxser_change_speed(info, old_termios); 2018 mxser_change_speed(info, old_termios);
2019 spin_unlock_irqrestore(&info->slock, flags);
1980 2020
1981 if ((old_termios->c_cflag & CRTSCTS) && 2021 if ((old_termios->c_cflag & CRTSCTS) &&
1982 !(tty->termios->c_cflag & CRTSCTS)) { 2022 !(tty->termios->c_cflag & CRTSCTS)) {
@@ -2066,7 +2106,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
2066/* 2106/*
2067 * This routine is called by tty_hangup() when a hangup is signaled. 2107 * This routine is called by tty_hangup() when a hangup is signaled.
2068 */ 2108 */
2069void mxser_hangup(struct tty_struct *tty) 2109static void mxser_hangup(struct tty_struct *tty)
2070{ 2110{
2071 struct mxser_port *info = tty->driver_data; 2111 struct mxser_port *info = tty->driver_data;
2072 2112
@@ -2105,9 +2145,6 @@ static void mxser_receive_chars(struct mxser_port *port, int *status)
2105 int cnt = 0; 2145 int cnt = 0;
2106 int recv_room; 2146 int recv_room;
2107 int max = 256; 2147 int max = 256;
2108 unsigned long flags;
2109
2110 spin_lock_irqsave(&port->slock, flags);
2111 2148
2112 recv_room = tty->receive_room; 2149 recv_room = tty->receive_room;
2113 if ((recv_room == 0) && (!port->ldisc_stop_rx)) 2150 if ((recv_room == 0) && (!port->ldisc_stop_rx))
@@ -2169,7 +2206,8 @@ intr_old:
2169 } else if (*status & UART_LSR_OE) { 2206 } else if (*status & UART_LSR_OE) {
2170 flag = TTY_OVERRUN; 2207 flag = TTY_OVERRUN;
2171 port->icount.overrun++; 2208 port->icount.overrun++;
2172 } 2209 } else
2210 flag = TTY_BREAK;
2173 } 2211 }
2174 tty_insert_flip_char(tty, ch, flag); 2212 tty_insert_flip_char(tty, ch, flag);
2175 cnt++; 2213 cnt++;
@@ -2191,7 +2229,6 @@ end_intr:
2191 mxvar_log.rxcnt[port->tty->index] += cnt; 2229 mxvar_log.rxcnt[port->tty->index] += cnt;
2192 port->mon_data.rxcnt += cnt; 2230 port->mon_data.rxcnt += cnt;
2193 port->mon_data.up_rxcnt += cnt; 2231 port->mon_data.up_rxcnt += cnt;
2194 spin_unlock_irqrestore(&port->slock, flags);
2195 2232
2196 tty_flip_buffer_push(tty); 2233 tty_flip_buffer_push(tty);
2197} 2234}
@@ -2199,9 +2236,6 @@ end_intr:
2199static void mxser_transmit_chars(struct mxser_port *port) 2236static void mxser_transmit_chars(struct mxser_port *port)
2200{ 2237{
2201 int count, cnt; 2238 int count, cnt;
2202 unsigned long flags;
2203
2204 spin_lock_irqsave(&port->slock, flags);
2205 2239
2206 if (port->x_char) { 2240 if (port->x_char) {
2207 outb(port->x_char, port->ioaddr + UART_TX); 2241 outb(port->x_char, port->ioaddr + UART_TX);
@@ -2210,11 +2244,11 @@ static void mxser_transmit_chars(struct mxser_port *port)
2210 port->mon_data.txcnt++; 2244 port->mon_data.txcnt++;
2211 port->mon_data.up_txcnt++; 2245 port->mon_data.up_txcnt++;
2212 port->icount.tx++; 2246 port->icount.tx++;
2213 goto unlock; 2247 return;
2214 } 2248 }
2215 2249
2216 if (port->xmit_buf == 0) 2250 if (port->xmit_buf == 0)
2217 goto unlock; 2251 return;
2218 2252
2219 if ((port->xmit_cnt <= 0) || port->tty->stopped || 2253 if ((port->xmit_cnt <= 0) || port->tty->stopped ||
2220 (port->tty->hw_stopped && 2254 (port->tty->hw_stopped &&
@@ -2222,7 +2256,7 @@ static void mxser_transmit_chars(struct mxser_port *port)
2222 (!port->board->chip_flag))) { 2256 (!port->board->chip_flag))) {
2223 port->IER &= ~UART_IER_THRI; 2257 port->IER &= ~UART_IER_THRI;
2224 outb(port->IER, port->ioaddr + UART_IER); 2258 outb(port->IER, port->ioaddr + UART_IER);
2225 goto unlock; 2259 return;
2226 } 2260 }
2227 2261
2228 cnt = port->xmit_cnt; 2262 cnt = port->xmit_cnt;
@@ -2240,16 +2274,13 @@ static void mxser_transmit_chars(struct mxser_port *port)
2240 port->mon_data.up_txcnt += (cnt - port->xmit_cnt); 2274 port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
2241 port->icount.tx += (cnt - port->xmit_cnt); 2275 port->icount.tx += (cnt - port->xmit_cnt);
2242 2276
2243 if (port->xmit_cnt < WAKEUP_CHARS) { 2277 if (port->xmit_cnt < WAKEUP_CHARS)
2244 set_bit(MXSER_EVENT_TXLOW, &port->event); 2278 tty_wakeup(port->tty);
2245 schedule_work(&port->tqueue); 2279
2246 }
2247 if (port->xmit_cnt <= 0) { 2280 if (port->xmit_cnt <= 0) {
2248 port->IER &= ~UART_IER_THRI; 2281 port->IER &= ~UART_IER_THRI;
2249 outb(port->IER, port->ioaddr + UART_IER); 2282 outb(port->IER, port->ioaddr + UART_IER);
2250 } 2283 }
2251unlock:
2252 spin_unlock_irqrestore(&port->slock, flags);
2253} 2284}
2254 2285
2255/* 2286/*
@@ -2261,8 +2292,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2261 struct mxser_board *brd = NULL; 2292 struct mxser_board *brd = NULL;
2262 struct mxser_port *port; 2293 struct mxser_port *port;
2263 int max, irqbits, bits, msr; 2294 int max, irqbits, bits, msr;
2264 int pass_counter = 0; 2295 unsigned int int_cnt, pass_counter = 0;
2265 unsigned int int_cnt;
2266 int handled = IRQ_NONE; 2296 int handled = IRQ_NONE;
2267 2297
2268 for (i = 0; i < MXSER_BOARDS; i++) 2298 for (i = 0; i < MXSER_BOARDS; i++)
@@ -2276,7 +2306,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2276 if (brd == NULL) 2306 if (brd == NULL)
2277 goto irq_stop; 2307 goto irq_stop;
2278 max = brd->info->nports; 2308 max = brd->info->nports;
2279 while (1) { 2309 while (pass_counter++ < MXSER_ISR_PASS_LIMIT) {
2280 irqbits = inb(brd->vector) & brd->vector_mask; 2310 irqbits = inb(brd->vector) & brd->vector_mask;
2281 if (irqbits == brd->vector_mask) 2311 if (irqbits == brd->vector_mask)
2282 break; 2312 break;
@@ -2290,12 +2320,16 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2290 port = &brd->ports[i]; 2320 port = &brd->ports[i];
2291 2321
2292 int_cnt = 0; 2322 int_cnt = 0;
2323 spin_lock(&port->slock);
2293 do { 2324 do {
2294 iir = inb(port->ioaddr + UART_IIR); 2325 iir = inb(port->ioaddr + UART_IIR);
2295 if (iir & UART_IIR_NO_INT) 2326 if (iir & UART_IIR_NO_INT)
2296 break; 2327 break;
2297 iir &= MOXA_MUST_IIR_MASK; 2328 iir &= MOXA_MUST_IIR_MASK;
2298 if (!port->tty) { 2329 if (!port->tty ||
2330 (port->flags & ASYNC_CLOSING) ||
2331 !(port->flags &
2332 ASYNC_INITIALIZED)) {
2299 status = inb(port->ioaddr + UART_LSR); 2333 status = inb(port->ioaddr + UART_LSR);
2300 outb(0x27, port->ioaddr + UART_FCR); 2334 outb(0x27, port->ioaddr + UART_FCR);
2301 inb(port->ioaddr + UART_MSR); 2335 inb(port->ioaddr + UART_MSR);
@@ -2341,9 +2375,8 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2341 mxser_transmit_chars(port); 2375 mxser_transmit_chars(port);
2342 } 2376 }
2343 } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); 2377 } while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
2378 spin_unlock(&port->slock);
2344 } 2379 }
2345 if (pass_counter++ > MXSER_ISR_PASS_LIMIT)
2346 break; /* Prevent infinite loops */
2347 } 2380 }
2348 2381
2349irq_stop: 2382irq_stop:
@@ -2385,7 +2418,6 @@ static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev,
2385#ifdef CONFIG_PCI 2418#ifdef CONFIG_PCI
2386 pci_release_region(pdev, 2); 2419 pci_release_region(pdev, 2);
2387 pci_release_region(pdev, 3); 2420 pci_release_region(pdev, 3);
2388 pci_dev_put(pdev);
2389#endif 2421#endif
2390 } else { 2422 } else {
2391 release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); 2423 release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
@@ -2420,11 +2452,10 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
2420 info->custom_divisor = info->baud_base * 16; 2452 info->custom_divisor = info->baud_base * 16;
2421 info->close_delay = 5 * HZ / 10; 2453 info->close_delay = 5 * HZ / 10;
2422 info->closing_wait = 30 * HZ; 2454 info->closing_wait = 30 * HZ;
2423 INIT_WORK(&info->tqueue, mxser_do_softint);
2424 info->normal_termios = mxvar_sdriver->init_termios; 2455 info->normal_termios = mxvar_sdriver->init_termios;
2425 init_waitqueue_head(&info->open_wait); 2456 init_waitqueue_head(&info->open_wait);
2426 init_waitqueue_head(&info->close_wait);
2427 init_waitqueue_head(&info->delta_msr_wait); 2457 init_waitqueue_head(&info->delta_msr_wait);
2458 info->speed = 9600;
2428 memset(&info->mon_data, 0, sizeof(struct mxser_mon)); 2459 memset(&info->mon_data, 0, sizeof(struct mxser_mon));
2429 info->err_shadow = 0; 2460 info->err_shadow = 0;
2430 spin_lock_init(&info->slock); 2461 spin_lock_init(&info->slock);
@@ -2433,22 +2464,17 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
2433 outb(inb(info->ioaddr + UART_IER) & 0xf0, 2464 outb(inb(info->ioaddr + UART_IER) & 0xf0,
2434 info->ioaddr + UART_IER); 2465 info->ioaddr + UART_IER);
2435 } 2466 }
2436 /*
2437 * Allocate the IRQ if necessary
2438 */
2439 2467
2440 retval = request_irq(brd->irq, mxser_interrupt, 2468 retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser",
2441 (brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : 2469 brd);
2442 IRQF_DISABLED, "mxser", brd);
2443 if (retval) { 2470 if (retval) {
2444 printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " 2471 printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
2445 "conflict with another device.\n", 2472 "conflict with another device.\n",
2446 brd->info->name, brd->irq); 2473 brd->info->name, brd->irq);
2447 /* We hold resources, we need to release them. */ 2474 /* We hold resources, we need to release them. */
2448 mxser_release_res(brd, pdev, 0); 2475 mxser_release_res(brd, pdev, 0);
2449 return retval;
2450 } 2476 }
2451 return 0; 2477 return retval;
2452} 2478}
2453 2479
2454static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) 2480static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
@@ -2633,8 +2659,9 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
2633 } 2659 }
2634 2660
2635 /* mxser_initbrd will hook ISR. */ 2661 /* mxser_initbrd will hook ISR. */
2636 if (mxser_initbrd(brd, pdev) < 0) 2662 retval = mxser_initbrd(brd, pdev);
2637 goto err_relvec; 2663 if (retval)
2664 goto err_null;
2638 2665
2639 for (i = 0; i < brd->info->nports; i++) 2666 for (i = 0; i < brd->info->nports; i++)
2640 tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); 2667 tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev);
@@ -2642,10 +2669,9 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
2642 pci_set_drvdata(pdev, brd); 2669 pci_set_drvdata(pdev, brd);
2643 2670
2644 return 0; 2671 return 0;
2645err_relvec:
2646 pci_release_region(pdev, 3);
2647err_relio: 2672err_relio:
2648 pci_release_region(pdev, 2); 2673 pci_release_region(pdev, 2);
2674err_null:
2649 brd->info = NULL; 2675 brd->info = NULL;
2650err: 2676err:
2651 return retval; 2677 return retval;
@@ -2663,6 +2689,7 @@ static void __devexit mxser_remove(struct pci_dev *pdev)
2663 tty_unregister_device(mxvar_sdriver, brd->idx + i); 2689 tty_unregister_device(mxvar_sdriver, brd->idx + i);
2664 2690
2665 mxser_release_res(brd, pdev, 1); 2691 mxser_release_res(brd, pdev, 1);
2692 brd->info = NULL;
2666} 2693}
2667 2694
2668static struct pci_driver mxser_driver = { 2695static struct pci_driver mxser_driver = {
@@ -2684,7 +2711,6 @@ static int __init mxser_module_init(void)
2684 mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); 2711 mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1);
2685 if (!mxvar_sdriver) 2712 if (!mxvar_sdriver)
2686 return -ENOMEM; 2713 return -ENOMEM;
2687 spin_lock_init(&gm_lock);
2688 2714
2689 printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", 2715 printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n",
2690 MXSER_VERSION); 2716 MXSER_VERSION);