diff options
Diffstat (limited to 'drivers/char/moxa.c')
-rw-r--r-- | drivers/char/moxa.c | 73 |
1 files changed, 30 insertions, 43 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 46a3a8ccd65f..5e3ef5522194 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -269,7 +269,7 @@ static int MoxaPortDCDChange(int); | |||
269 | static int MoxaPortDCDON(int); | 269 | static int MoxaPortDCDON(int); |
270 | static void MoxaPortFlushData(int, int); | 270 | static void MoxaPortFlushData(int, int); |
271 | static int MoxaPortWriteData(int, unsigned char *, int); | 271 | static int MoxaPortWriteData(int, unsigned char *, int); |
272 | static int MoxaPortReadData(int, unsigned char *, int); | 272 | static int MoxaPortReadData(int, struct tty_struct *tty); |
273 | static int MoxaPortTxQueue(int); | 273 | static int MoxaPortTxQueue(int); |
274 | static int MoxaPortRxQueue(int); | 274 | static int MoxaPortRxQueue(int); |
275 | static int MoxaPortTxFree(int); | 275 | static int MoxaPortTxFree(int); |
@@ -301,6 +301,8 @@ static struct tty_operations moxa_ops = { | |||
301 | .tiocmset = moxa_tiocmset, | 301 | .tiocmset = moxa_tiocmset, |
302 | }; | 302 | }; |
303 | 303 | ||
304 | static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; | ||
305 | |||
304 | #ifdef CONFIG_PCI | 306 | #ifdef CONFIG_PCI |
305 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) | 307 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) |
306 | { | 308 | { |
@@ -645,10 +647,10 @@ static int moxa_write(struct tty_struct *tty, | |||
645 | if (ch == NULL) | 647 | if (ch == NULL) |
646 | return (0); | 648 | return (0); |
647 | port = ch->port; | 649 | port = ch->port; |
648 | save_flags(flags); | 650 | |
649 | cli(); | 651 | spin_lock_irqsave(&moxa_lock, flags); |
650 | len = MoxaPortWriteData(port, (unsigned char *) buf, count); | 652 | len = MoxaPortWriteData(port, (unsigned char *) buf, count); |
651 | restore_flags(flags); | 653 | spin_unlock_irqrestore(&moxa_lock, flags); |
652 | 654 | ||
653 | /********************************************* | 655 | /********************************************* |
654 | if ( !(ch->statusflags & LOWWAIT) && | 656 | if ( !(ch->statusflags & LOWWAIT) && |
@@ -723,11 +725,10 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c) | |||
723 | if (ch == NULL) | 725 | if (ch == NULL) |
724 | return; | 726 | return; |
725 | port = ch->port; | 727 | port = ch->port; |
726 | save_flags(flags); | 728 | spin_lock_irqsave(&moxa_lock, flags); |
727 | cli(); | ||
728 | moxaXmitBuff[0] = c; | 729 | moxaXmitBuff[0] = c; |
729 | MoxaPortWriteData(port, moxaXmitBuff, 1); | 730 | MoxaPortWriteData(port, moxaXmitBuff, 1); |
730 | restore_flags(flags); | 731 | spin_unlock_irqrestore(&moxa_lock, flags); |
731 | /************************************************ | 732 | /************************************************ |
732 | if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) | 733 | if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) |
733 | *************************************************/ | 734 | *************************************************/ |
@@ -1030,12 +1031,12 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1030 | printk("block_til_ready before block: ttys%d, count = %d\n", | 1031 | printk("block_til_ready before block: ttys%d, count = %d\n", |
1031 | ch->line, ch->count); | 1032 | ch->line, ch->count); |
1032 | #endif | 1033 | #endif |
1033 | save_flags(flags); | 1034 | spin_lock_irqsave(&moxa_lock, flags); |
1034 | cli(); | ||
1035 | if (!tty_hung_up_p(filp)) | 1035 | if (!tty_hung_up_p(filp)) |
1036 | ch->count--; | 1036 | ch->count--; |
1037 | restore_flags(flags); | ||
1038 | ch->blocked_open++; | 1037 | ch->blocked_open++; |
1038 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1039 | |||
1039 | while (1) { | 1040 | while (1) { |
1040 | set_current_state(TASK_INTERRUPTIBLE); | 1041 | set_current_state(TASK_INTERRUPTIBLE); |
1041 | if (tty_hung_up_p(filp) || | 1042 | if (tty_hung_up_p(filp) || |
@@ -1062,17 +1063,21 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1062 | } | 1063 | } |
1063 | set_current_state(TASK_RUNNING); | 1064 | set_current_state(TASK_RUNNING); |
1064 | remove_wait_queue(&ch->open_wait, &wait); | 1065 | remove_wait_queue(&ch->open_wait, &wait); |
1066 | |||
1067 | spin_lock_irqsave(&moxa_lock, flags); | ||
1065 | if (!tty_hung_up_p(filp)) | 1068 | if (!tty_hung_up_p(filp)) |
1066 | ch->count++; | 1069 | ch->count++; |
1067 | ch->blocked_open--; | 1070 | ch->blocked_open--; |
1071 | spin_unlock_irqrestore(&moxa_lock, flags); | ||
1068 | #ifdef SERIAL_DEBUG_OPEN | 1072 | #ifdef SERIAL_DEBUG_OPEN |
1069 | printk("block_til_ready after blocking: ttys%d, count = %d\n", | 1073 | printk("block_til_ready after blocking: ttys%d, count = %d\n", |
1070 | ch->line, ch->count); | 1074 | ch->line, ch->count); |
1071 | #endif | 1075 | #endif |
1072 | if (retval) | 1076 | if (retval) |
1073 | return (retval); | 1077 | return (retval); |
1078 | /* FIXME: review to see if we need to use set_bit on these */ | ||
1074 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; | 1079 | ch->asyncflags |= ASYNC_NORMAL_ACTIVE; |
1075 | return (0); | 1080 | return 0; |
1076 | } | 1081 | } |
1077 | 1082 | ||
1078 | static void setup_empty_event(struct tty_struct *tty) | 1083 | static void setup_empty_event(struct tty_struct *tty) |
@@ -1080,15 +1085,14 @@ static void setup_empty_event(struct tty_struct *tty) | |||
1080 | struct moxa_str *ch = tty->driver_data; | 1085 | struct moxa_str *ch = tty->driver_data; |
1081 | unsigned long flags; | 1086 | unsigned long flags; |
1082 | 1087 | ||
1083 | save_flags(flags); | 1088 | spin_lock_irqsave(&moxa_lock, flags); |
1084 | cli(); | ||
1085 | ch->statusflags |= EMPTYWAIT; | 1089 | ch->statusflags |= EMPTYWAIT; |
1086 | moxaEmptyTimer_on[ch->port] = 0; | 1090 | moxaEmptyTimer_on[ch->port] = 0; |
1087 | del_timer(&moxaEmptyTimer[ch->port]); | 1091 | del_timer(&moxaEmptyTimer[ch->port]); |
1088 | moxaEmptyTimer[ch->port].expires = jiffies + HZ; | 1092 | moxaEmptyTimer[ch->port].expires = jiffies + HZ; |
1089 | moxaEmptyTimer_on[ch->port] = 1; | 1093 | moxaEmptyTimer_on[ch->port] = 1; |
1090 | add_timer(&moxaEmptyTimer[ch->port]); | 1094 | add_timer(&moxaEmptyTimer[ch->port]); |
1091 | restore_flags(flags); | 1095 | spin_unlock_irqrestore(&moxa_lock, flags); |
1092 | } | 1096 | } |
1093 | 1097 | ||
1094 | static void check_xmit_empty(unsigned long data) | 1098 | static void check_xmit_empty(unsigned long data) |
@@ -1135,8 +1139,6 @@ static void receive_data(struct moxa_str *ch) | |||
1135 | { | 1139 | { |
1136 | struct tty_struct *tp; | 1140 | struct tty_struct *tp; |
1137 | struct termios *ts; | 1141 | struct termios *ts; |
1138 | int i, count, rc, space; | ||
1139 | unsigned char *charptr, *flagptr; | ||
1140 | unsigned long flags; | 1142 | unsigned long flags; |
1141 | 1143 | ||
1142 | ts = NULL; | 1144 | ts = NULL; |
@@ -1150,24 +1152,10 @@ static void receive_data(struct moxa_str *ch) | |||
1150 | MoxaPortFlushData(ch->port, 0); | 1152 | MoxaPortFlushData(ch->port, 0); |
1151 | return; | 1153 | return; |
1152 | } | 1154 | } |
1153 | space = TTY_FLIPBUF_SIZE - tp->flip.count; | 1155 | spin_lock_irqsave(&moxa_lock, flags); |
1154 | if (space <= 0) | 1156 | MoxaPortReadData(ch->port, tp); |
1155 | return; | 1157 | spin_unlock_irqrestore(&moxa_lock, flags); |
1156 | charptr = tp->flip.char_buf_ptr; | 1158 | tty_schedule_flip(tp); |
1157 | flagptr = tp->flip.flag_buf_ptr; | ||
1158 | rc = tp->flip.count; | ||
1159 | save_flags(flags); | ||
1160 | cli(); | ||
1161 | count = MoxaPortReadData(ch->port, charptr, space); | ||
1162 | restore_flags(flags); | ||
1163 | for (i = 0; i < count; i++) | ||
1164 | *flagptr++ = 0; | ||
1165 | charptr += count; | ||
1166 | rc += count; | ||
1167 | tp->flip.count = rc; | ||
1168 | tp->flip.char_buf_ptr = charptr; | ||
1169 | tp->flip.flag_buf_ptr = flagptr; | ||
1170 | tty_schedule_flip(ch->tty); | ||
1171 | } | 1159 | } |
1172 | 1160 | ||
1173 | #define Magic_code 0x404 | 1161 | #define Magic_code 0x404 |
@@ -1774,7 +1762,7 @@ int MoxaPortsOfCard(int cardno) | |||
1774 | * 14. MoxaPortDCDON(int port); * | 1762 | * 14. MoxaPortDCDON(int port); * |
1775 | * 15. MoxaPortFlushData(int port, int mode); * | 1763 | * 15. MoxaPortFlushData(int port, int mode); * |
1776 | * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * | 1764 | * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * |
1777 | * 17. MoxaPortReadData(int port, unsigned char * buffer, int length); * | 1765 | * 17. MoxaPortReadData(int port, struct tty_struct *tty); * |
1778 | * 18. MoxaPortTxBufSize(int port); * | 1766 | * 18. MoxaPortTxBufSize(int port); * |
1779 | * 19. MoxaPortRxBufSize(int port); * | 1767 | * 19. MoxaPortRxBufSize(int port); * |
1780 | * 20. MoxaPortTxQueue(int port); * | 1768 | * 20. MoxaPortTxQueue(int port); * |
@@ -2003,10 +1991,9 @@ int MoxaPortsOfCard(int cardno) | |||
2003 | * | 1991 | * |
2004 | * Function 21: Read data. | 1992 | * Function 21: Read data. |
2005 | * Syntax: | 1993 | * Syntax: |
2006 | * int MoxaPortReadData(int port, unsigned char * buffer, int length); | 1994 | * int MoxaPortReadData(int port, struct tty_struct *tty); |
2007 | * int port : port number (0 - 127) | 1995 | * int port : port number (0 - 127) |
2008 | * unsigned char * buffer : pointer to read data buffer. | 1996 | * struct tty_struct *tty : tty for data |
2009 | * int length : read data buffer length | ||
2010 | * | 1997 | * |
2011 | * return: 0 - length : real read data length | 1998 | * return: 0 - length : real read data length |
2012 | * | 1999 | * |
@@ -2504,7 +2491,7 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len) | |||
2504 | return (total); | 2491 | return (total); |
2505 | } | 2492 | } |
2506 | 2493 | ||
2507 | int MoxaPortReadData(int port, unsigned char * buffer, int space) | 2494 | int MoxaPortReadData(int port, struct tty_struct *tty) |
2508 | { | 2495 | { |
2509 | register ushort head, pageofs; | 2496 | register ushort head, pageofs; |
2510 | int i, count, cnt, len, total, remain; | 2497 | int i, count, cnt, len, total, remain; |
@@ -2522,9 +2509,9 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2522 | count = (tail >= head) ? (tail - head) | 2509 | count = (tail >= head) ? (tail - head) |
2523 | : (tail - head + rx_mask + 1); | 2510 | : (tail - head + rx_mask + 1); |
2524 | if (count == 0) | 2511 | if (count == 0) |
2525 | return (0); | 2512 | return 0; |
2526 | 2513 | ||
2527 | total = (space > count) ? count : space; | 2514 | total = count; |
2528 | remain = count - total; | 2515 | remain = count - total; |
2529 | moxaLog.rxcnt[port] += total; | 2516 | moxaLog.rxcnt[port] += total; |
2530 | count = total; | 2517 | count = total; |
@@ -2539,7 +2526,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2539 | len = (count > len) ? len : count; | 2526 | len = (count > len) ? len : count; |
2540 | ofs = baseAddr + DynPage_addr + bufhead + head; | 2527 | ofs = baseAddr + DynPage_addr + bufhead + head; |
2541 | for (i = 0; i < len; i++) | 2528 | for (i = 0; i < len; i++) |
2542 | *buffer++ = readb(ofs + i); | 2529 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); |
2543 | head = (head + len) & rx_mask; | 2530 | head = (head + len) & rx_mask; |
2544 | count -= len; | 2531 | count -= len; |
2545 | } | 2532 | } |
@@ -2556,7 +2543,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space) | |||
2556 | writew(pageno, baseAddr + Control_reg); | 2543 | writew(pageno, baseAddr + Control_reg); |
2557 | ofs = baseAddr + DynPage_addr + pageofs; | 2544 | ofs = baseAddr + DynPage_addr + pageofs; |
2558 | for (i = 0; i < cnt; i++) | 2545 | for (i = 0; i < cnt; i++) |
2559 | *buffer++ = readb(ofs + i); | 2546 | tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); |
2560 | if (count == 0) { | 2547 | if (count == 0) { |
2561 | writew((head + len) & rx_mask, ofsAddr + RXrptr); | 2548 | writew((head + len) & rx_mask, ofsAddr + RXrptr); |
2562 | break; | 2549 | break; |