aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/moxa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/moxa.c')
-rw-r--r--drivers/char/moxa.c73
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);
269static int MoxaPortDCDON(int); 269static int MoxaPortDCDON(int);
270static void MoxaPortFlushData(int, int); 270static void MoxaPortFlushData(int, int);
271static int MoxaPortWriteData(int, unsigned char *, int); 271static int MoxaPortWriteData(int, unsigned char *, int);
272static int MoxaPortReadData(int, unsigned char *, int); 272static int MoxaPortReadData(int, struct tty_struct *tty);
273static int MoxaPortTxQueue(int); 273static int MoxaPortTxQueue(int);
274static int MoxaPortRxQueue(int); 274static int MoxaPortRxQueue(int);
275static int MoxaPortTxFree(int); 275static 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
304static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED;
305
304#ifdef CONFIG_PCI 306#ifdef CONFIG_PCI
305static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) 307static 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
1078static void setup_empty_event(struct tty_struct *tty) 1083static 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
1094static void check_xmit_empty(unsigned long data) 1098static 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
2507int MoxaPortReadData(int port, unsigned char * buffer, int space) 2494int 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;