aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/moxa.c421
-rw-r--r--drivers/char/moxa.h10
2 files changed, 141 insertions, 290 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index f737fbb8598c..a64707623e47 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -129,25 +129,22 @@ struct moxaq_str {
129 129
130struct moxa_port { 130struct moxa_port {
131 struct moxa_board_conf *board; 131 struct moxa_board_conf *board;
132 struct tty_struct *tty;
133 void __iomem *tableAddr;
134
132 int type; 135 int type;
133 int close_delay; 136 int close_delay;
134 int count; 137 int count;
135 int blocked_open; 138 int blocked_open;
136 int asyncflags; 139 int asyncflags;
137 unsigned long statusflags;
138 struct tty_struct *tty;
139 int cflag; 140 int cflag;
141 unsigned long statusflags;
140 wait_queue_head_t open_wait; 142 wait_queue_head_t open_wait;
141 struct completion close_wait; 143 struct completion close_wait;
142 144
143 struct timer_list emptyTimer; 145 u8 DCDState;
144 146 u8 lineCtrl;
145 char lineCtrl; 147 u8 lowChkFlag;
146 void __iomem *tableAddr;
147 char DCDState;
148 char lowChkFlag;
149
150 ushort breakCnt;
151}; 148};
152 149
153struct mon_str { 150struct mon_str {
@@ -169,6 +166,7 @@ struct mon_str {
169static int ttymajor = MOXAMAJOR; 166static int ttymajor = MOXAMAJOR;
170static struct mon_str moxaLog; 167static struct mon_str moxaLog;
171static unsigned int moxaFuncTout = HZ / 2; 168static unsigned int moxaFuncTout = HZ / 2;
169static unsigned int moxaLowWaterChk;
172/* Variables for insmod */ 170/* Variables for insmod */
173#ifdef MODULE 171#ifdef MODULE
174static unsigned long baseaddr[MAX_BOARDS]; 172static unsigned long baseaddr[MAX_BOARDS];
@@ -214,13 +212,10 @@ static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
214static int moxa_block_till_ready(struct tty_struct *, struct file *, 212static int moxa_block_till_ready(struct tty_struct *, struct file *,
215 struct moxa_port *); 213 struct moxa_port *);
216static void moxa_setup_empty_event(struct tty_struct *); 214static void moxa_setup_empty_event(struct tty_struct *);
217static void moxa_check_xmit_empty(unsigned long);
218static void moxa_shut_down(struct moxa_port *); 215static void moxa_shut_down(struct moxa_port *);
219static void moxa_receive_data(struct moxa_port *);
220/* 216/*
221 * moxa board interface functions: 217 * moxa board interface functions:
222 */ 218 */
223static int MoxaDriverPoll(void);
224static void MoxaPortEnable(struct moxa_port *); 219static void MoxaPortEnable(struct moxa_port *);
225static void MoxaPortDisable(struct moxa_port *); 220static void MoxaPortDisable(struct moxa_port *);
226static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t); 221static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t);
@@ -228,17 +223,14 @@ static int MoxaPortGetLineOut(struct moxa_port *, int *, int *);
228static void MoxaPortLineCtrl(struct moxa_port *, int, int); 223static void MoxaPortLineCtrl(struct moxa_port *, int, int);
229static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); 224static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
230static int MoxaPortLineStatus(struct moxa_port *); 225static int MoxaPortLineStatus(struct moxa_port *);
231static int MoxaPortDCDChange(struct moxa_port *);
232static int MoxaPortDCDON(struct moxa_port *);
233static void MoxaPortFlushData(struct moxa_port *, int); 226static void MoxaPortFlushData(struct moxa_port *, int);
234static int MoxaPortWriteData(struct moxa_port *, unsigned char *, int); 227static int MoxaPortWriteData(struct moxa_port *, unsigned char *, int);
235static int MoxaPortReadData(struct moxa_port *, struct tty_struct *tty); 228static int MoxaPortReadData(struct moxa_port *);
236static int MoxaPortTxQueue(struct moxa_port *); 229static int MoxaPortTxQueue(struct moxa_port *);
237static int MoxaPortRxQueue(struct moxa_port *); 230static int MoxaPortRxQueue(struct moxa_port *);
238static int MoxaPortTxFree(struct moxa_port *); 231static int MoxaPortTxFree(struct moxa_port *);
239static void MoxaPortTxDisable(struct moxa_port *); 232static void MoxaPortTxDisable(struct moxa_port *);
240static void MoxaPortTxEnable(struct moxa_port *); 233static void MoxaPortTxEnable(struct moxa_port *);
241static int MoxaPortResetBrkCnt(struct moxa_port *);
242static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); 234static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *);
243static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); 235static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *);
244static void MoxaSetFifo(struct moxa_port *port, int enable); 236static void MoxaSetFifo(struct moxa_port *port, int enable);
@@ -265,6 +257,20 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
265 moxa_wait_finish(ofsAddr); 257 moxa_wait_finish(ofsAddr);
266} 258}
267 259
260static void moxa_low_water_check(void __iomem *ofsAddr)
261{
262 u16 rptr, wptr, mask, len;
263
264 if (readb(ofsAddr + FlagStat) & Xoff_state) {
265 rptr = readw(ofsAddr + RXrptr);
266 wptr = readw(ofsAddr + RXwptr);
267 mask = readw(ofsAddr + RX_mask);
268 len = (wptr - rptr) & mask;
269 if (len <= Low_water)
270 moxafunc(ofsAddr, FC_SendXon, 0);
271 }
272}
273
268/* 274/*
269 * TTY operations 275 * TTY operations
270 */ 276 */
@@ -812,9 +818,6 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
812 p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; 818 p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
813 init_waitqueue_head(&p->open_wait); 819 init_waitqueue_head(&p->open_wait);
814 init_completion(&p->close_wait); 820 init_completion(&p->close_wait);
815
816 setup_timer(&p->emptyTimer, moxa_check_xmit_empty,
817 (unsigned long)p);
818 } 821 }
819 822
820 switch (brd->boardType) { 823 switch (brd->boardType) {
@@ -857,12 +860,9 @@ err:
857 860
858static void moxa_board_deinit(struct moxa_board_conf *brd) 861static void moxa_board_deinit(struct moxa_board_conf *brd)
859{ 862{
860 unsigned int i; 863 spin_lock_bh(&moxa_lock);
861
862 brd->ready = 0; 864 brd->ready = 0;
863 for (i = 0; i < MAX_PORTS_PER_BOARD; i++) 865 spin_unlock_bh(&moxa_lock);
864 del_timer_sync(&brd->ports[i].emptyTimer);
865
866 iounmap(brd->basemem); 866 iounmap(brd->basemem);
867 brd->basemem = NULL; 867 brd->basemem = NULL;
868 kfree(brd->ports); 868 kfree(brd->ports);
@@ -1135,7 +1135,6 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
1135 if (ch->asyncflags & ASYNC_INITIALIZED) { 1135 if (ch->asyncflags & ASYNC_INITIALIZED) {
1136 moxa_setup_empty_event(tty); 1136 moxa_setup_empty_event(tty);
1137 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ 1137 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
1138 del_timer_sync(&ch->emptyTimer);
1139 } 1138 }
1140 moxa_shut_down(ch); 1139 moxa_shut_down(ch);
1141 MoxaPortFlushData(ch, 2); 1140 MoxaPortFlushData(ch, 2);
@@ -1160,15 +1159,14 @@ static int moxa_write(struct tty_struct *tty,
1160 const unsigned char *buf, int count) 1159 const unsigned char *buf, int count)
1161{ 1160{
1162 struct moxa_port *ch = tty->driver_data; 1161 struct moxa_port *ch = tty->driver_data;
1163 unsigned long flags;
1164 int len; 1162 int len;
1165 1163
1166 if (ch == NULL) 1164 if (ch == NULL)
1167 return 0; 1165 return 0;
1168 1166
1169 spin_lock_irqsave(&moxa_lock, flags); 1167 spin_lock_bh(&moxa_lock);
1170 len = MoxaPortWriteData(ch, (unsigned char *) buf, count); 1168 len = MoxaPortWriteData(ch, (unsigned char *) buf, count);
1171 spin_unlock_irqrestore(&moxa_lock, flags); 1169 spin_unlock_bh(&moxa_lock);
1172 1170
1173 /********************************************* 1171 /*********************************************
1174 if ( !(ch->statusflags & LOWWAIT) && 1172 if ( !(ch->statusflags & LOWWAIT) &&
@@ -1236,13 +1234,12 @@ static void moxa_flush_chars(struct tty_struct *tty)
1236static void moxa_put_char(struct tty_struct *tty, unsigned char c) 1234static void moxa_put_char(struct tty_struct *tty, unsigned char c)
1237{ 1235{
1238 struct moxa_port *ch = tty->driver_data; 1236 struct moxa_port *ch = tty->driver_data;
1239 unsigned long flags;
1240 1237
1241 if (ch == NULL) 1238 if (ch == NULL)
1242 return; 1239 return;
1243 spin_lock_irqsave(&moxa_lock, flags); 1240 spin_lock_bh(&moxa_lock);
1244 MoxaPortWriteData(ch, &c, 1); 1241 MoxaPortWriteData(ch, &c, 1);
1245 spin_unlock_irqrestore(&moxa_lock, flags); 1242 spin_unlock_bh(&moxa_lock);
1246 /************************************************ 1243 /************************************************
1247 if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) 1244 if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
1248 *************************************************/ 1245 *************************************************/
@@ -1360,58 +1357,110 @@ static void moxa_hangup(struct tty_struct *tty)
1360 wake_up_interruptible(&ch->open_wait); 1357 wake_up_interruptible(&ch->open_wait);
1361} 1358}
1362 1359
1363static void moxa_poll(unsigned long ignored) 1360static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1364{ 1361{
1365 struct moxa_port *ch; 1362 dcd = !!dcd;
1366 struct tty_struct *tty;
1367 unsigned int card;
1368 int i;
1369 1363
1370 del_timer(&moxaTimer); 1364 if ((dcd != p->DCDState) && p->tty && C_CLOCAL(p->tty)) {
1365 if (!dcd) {
1366 tty_hangup(p->tty);
1367 p->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
1368 }
1369 wake_up_interruptible(&p->open_wait);
1370 }
1371 p->DCDState = dcd;
1372}
1371 1373
1372 if (MoxaDriverPoll() < 0) { 1374static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
1373 mod_timer(&moxaTimer, jiffies + HZ / 50); 1375 u16 __iomem *ip)
1374 return; 1376{
1377 struct tty_struct *tty = p->tty;
1378 void __iomem *ofsAddr;
1379 unsigned int inited = p->asyncflags & ASYNC_INITIALIZED;
1380 u16 intr;
1381
1382 if (tty) {
1383 if ((p->statusflags & EMPTYWAIT) &&
1384 MoxaPortTxQueue(p) == 0) {
1385 p->statusflags &= ~EMPTYWAIT;
1386 tty_wakeup(tty);
1387 }
1388 if ((p->statusflags & LOWWAIT) && !tty->stopped &&
1389 MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
1390 p->statusflags &= ~LOWWAIT;
1391 tty_wakeup(tty);
1392 }
1393
1394 if (inited && !(p->statusflags & THROTTLE) &&
1395 MoxaPortRxQueue(p) > 0) { /* RX */
1396 MoxaPortReadData(p);
1397 tty_schedule_flip(tty);
1398 }
1399 } else {
1400 p->statusflags &= ~EMPTYWAIT;
1401 MoxaPortFlushData(p, 0); /* flush RX */
1375 } 1402 }
1376 1403
1404 if (!handle) /* nothing else to do */
1405 return 0;
1406
1407 intr = readw(ip); /* port irq status */
1408 if (intr == 0)
1409 return 0;
1410
1411 writew(0, ip); /* ACK port */
1412 ofsAddr = p->tableAddr;
1413 if (intr & IntrTx) /* disable tx intr */
1414 writew(readw(ofsAddr + HostStat) & ~WakeupTx,
1415 ofsAddr + HostStat);
1416
1417 if (!inited)
1418 return 0;
1419
1420 if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
1421 tty_insert_flip_char(tty, 0, TTY_BREAK);
1422 tty_schedule_flip(tty);
1423 }
1424
1425 if (intr & IntrLine)
1426 moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
1427
1428 return 0;
1429}
1430
1431static void moxa_poll(unsigned long ignored)
1432{
1433 struct moxa_board_conf *brd;
1434 u16 __iomem *ip;
1435 unsigned int card, port;
1436
1437 spin_lock(&moxa_lock);
1377 for (card = 0; card < MAX_BOARDS; card++) { 1438 for (card = 0; card < MAX_BOARDS; card++) {
1378 if (!moxa_boards[card].ready) 1439 brd = &moxa_boards[card];
1440 if (!brd->ready)
1379 continue; 1441 continue;
1380 ch = moxa_boards[card].ports; 1442
1381 for (i = 0; i < moxa_boards[card].numPorts; i++, ch++) { 1443 ip = NULL;
1382 if ((ch->asyncflags & ASYNC_INITIALIZED) == 0) 1444 if (readb(brd->intPend) == 0xff)
1383 continue; 1445 ip = brd->intTable + readb(brd->intNdx);
1384 if (!(ch->statusflags & THROTTLE) && 1446
1385 (MoxaPortRxQueue(ch) > 0)) 1447 for (port = 0; port < brd->numPorts; port++)
1386 moxa_receive_data(ch); 1448 moxa_poll_port(&brd->ports[port], !!ip, ip + port);
1387 tty = ch->tty; 1449
1388 if (tty == NULL) 1450 if (ip)
1389 continue; 1451 writeb(0, brd->intPend); /* ACK */
1390 if (ch->statusflags & LOWWAIT) { 1452
1391 if (MoxaPortTxQueue(ch) <= WAKEUP_CHARS) { 1453 if (moxaLowWaterChk) {
1392 if (!tty->stopped) { 1454 struct moxa_port *p = brd->ports;
1393 ch->statusflags &= ~LOWWAIT; 1455 for (port = 0; port < brd->numPorts; port++, p++)
1394 tty_wakeup(tty); 1456 if (p->lowChkFlag) {
1395 } 1457 p->lowChkFlag = 0;
1396 } 1458 moxa_low_water_check(p->tableAddr);
1397 }
1398 if (!I_IGNBRK(tty) && (MoxaPortResetBrkCnt(ch) > 0)) {
1399 tty_insert_flip_char(tty, 0, TTY_BREAK);
1400 tty_schedule_flip(tty);
1401 }
1402 if (MoxaPortDCDChange(ch)) {
1403 if (ch->asyncflags & ASYNC_CHECK_CD) {
1404 if (MoxaPortDCDON(ch))
1405 wake_up_interruptible(&ch->open_wait);
1406 else {
1407 tty_hangup(tty);
1408 wake_up_interruptible(&ch->open_wait);
1409 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
1410 }
1411 } 1459 }
1412 }
1413 } 1460 }
1414 } 1461 }
1462 moxaLowWaterChk = 0;
1463 spin_unlock(&moxa_lock);
1415 1464
1416 mod_timer(&moxaTimer, jiffies + HZ / 50); 1465 mod_timer(&moxaTimer, jiffies + HZ / 50);
1417} 1466}
@@ -1426,10 +1475,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
1426 1475
1427 ch = (struct moxa_port *) tty->driver_data; 1476 ch = (struct moxa_port *) tty->driver_data;
1428 ts = tty->termios; 1477 ts = tty->termios;
1429 if (ts->c_cflag & CLOCAL)
1430 ch->asyncflags &= ~ASYNC_CHECK_CD;
1431 else
1432 ch->asyncflags |= ASYNC_CHECK_CD;
1433 rts = cts = txflow = rxflow = xany = 0; 1478 rts = cts = txflow = rxflow = xany = 0;
1434 if (ts->c_cflag & CRTSCTS) 1479 if (ts->c_cflag & CRTSCTS)
1435 rts = cts = 1; 1480 rts = cts = 1;
@@ -1454,7 +1499,6 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1454 struct moxa_port *ch) 1499 struct moxa_port *ch)
1455{ 1500{
1456 DECLARE_WAITQUEUE(wait,current); 1501 DECLARE_WAITQUEUE(wait,current);
1457 unsigned long flags;
1458 int retval; 1502 int retval;
1459 int do_clocal = C_CLOCAL(tty); 1503 int do_clocal = C_CLOCAL(tty);
1460 1504
@@ -1489,11 +1533,11 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1489 add_wait_queue(&ch->open_wait, &wait); 1533 add_wait_queue(&ch->open_wait, &wait);
1490 pr_debug("block_til_ready before block: ttys%d, count = %d\n", 1534 pr_debug("block_til_ready before block: ttys%d, count = %d\n",
1491 tty->index, ch->count); 1535 tty->index, ch->count);
1492 spin_lock_irqsave(&moxa_lock, flags); 1536 spin_lock_bh(&moxa_lock);
1493 if (!tty_hung_up_p(filp)) 1537 if (!tty_hung_up_p(filp))
1494 ch->count--; 1538 ch->count--;
1495 ch->blocked_open++; 1539 ch->blocked_open++;
1496 spin_unlock_irqrestore(&moxa_lock, flags); 1540 spin_unlock_bh(&moxa_lock);
1497 1541
1498 while (1) { 1542 while (1) {
1499 set_current_state(TASK_INTERRUPTIBLE); 1543 set_current_state(TASK_INTERRUPTIBLE);
@@ -1510,7 +1554,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1510 break; 1554 break;
1511 } 1555 }
1512 if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal || 1556 if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
1513 MoxaPortDCDON(ch))) 1557 ch->DCDState))
1514 break; 1558 break;
1515 1559
1516 if (signal_pending(current)) { 1560 if (signal_pending(current)) {
@@ -1522,11 +1566,11 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1522 set_current_state(TASK_RUNNING); 1566 set_current_state(TASK_RUNNING);
1523 remove_wait_queue(&ch->open_wait, &wait); 1567 remove_wait_queue(&ch->open_wait, &wait);
1524 1568
1525 spin_lock_irqsave(&moxa_lock, flags); 1569 spin_lock_bh(&moxa_lock);
1526 if (!tty_hung_up_p(filp)) 1570 if (!tty_hung_up_p(filp))
1527 ch->count++; 1571 ch->count++;
1528 ch->blocked_open--; 1572 ch->blocked_open--;
1529 spin_unlock_irqrestore(&moxa_lock, flags); 1573 spin_unlock_bh(&moxa_lock);
1530 pr_debug("block_til_ready after blocking: ttys%d, count = %d\n", 1574 pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
1531 tty->index, ch->count); 1575 tty->index, ch->count);
1532 if (retval) 1576 if (retval)
@@ -1539,28 +1583,10 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1539static void moxa_setup_empty_event(struct tty_struct *tty) 1583static void moxa_setup_empty_event(struct tty_struct *tty)
1540{ 1584{
1541 struct moxa_port *ch = tty->driver_data; 1585 struct moxa_port *ch = tty->driver_data;
1542 unsigned long flags;
1543 1586
1544 spin_lock_irqsave(&moxa_lock, flags); 1587 spin_lock_bh(&moxa_lock);
1545 ch->statusflags |= EMPTYWAIT; 1588 ch->statusflags |= EMPTYWAIT;
1546 mod_timer(&ch->emptyTimer, jiffies + HZ); 1589 spin_unlock_bh(&moxa_lock);
1547 spin_unlock_irqrestore(&moxa_lock, flags);
1548}
1549
1550static void moxa_check_xmit_empty(unsigned long data)
1551{
1552 struct moxa_port *ch;
1553
1554 ch = (struct moxa_port *) data;
1555 if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
1556 if (MoxaPortTxQueue(ch) == 0) {
1557 ch->statusflags &= ~EMPTYWAIT;
1558 tty_wakeup(ch->tty);
1559 return;
1560 }
1561 mod_timer(&ch->emptyTimer, round_jiffies(jiffies + HZ));
1562 } else
1563 ch->statusflags &= ~EMPTYWAIT;
1564} 1590}
1565 1591
1566static void moxa_shut_down(struct moxa_port *ch) 1592static void moxa_shut_down(struct moxa_port *ch)
@@ -1583,43 +1609,8 @@ static void moxa_shut_down(struct moxa_port *ch)
1583 ch->asyncflags &= ~ASYNC_INITIALIZED; 1609 ch->asyncflags &= ~ASYNC_INITIALIZED;
1584} 1610}
1585 1611
1586static void moxa_receive_data(struct moxa_port *ch)
1587{
1588 struct tty_struct *tp;
1589 struct ktermios *ts;
1590 unsigned long flags;
1591
1592 ts = NULL;
1593 tp = ch->tty;
1594 if (tp)
1595 ts = tp->termios;
1596 /**************************************************
1597 if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
1598 *****************************************************/
1599 if (!tp || !ts) {
1600 MoxaPortFlushData(ch, 0);
1601 return;
1602 }
1603 spin_lock_irqsave(&moxa_lock, flags);
1604 MoxaPortReadData(ch, tp);
1605 spin_unlock_irqrestore(&moxa_lock, flags);
1606 tty_schedule_flip(tp);
1607}
1608
1609/*
1610 * Query
1611 */
1612
1613#define DCD_changed 0x01
1614#define DCD_oldstate 0x80
1615
1616static int moxaLowWaterChk;
1617
1618static void moxa_low_water_check(void __iomem *);
1619
1620/***************************************************************************** 1612/*****************************************************************************
1621 * Driver level functions: * 1613 * Driver level functions: *
1622 * 3. MoxaDriverPoll(void); *
1623 *****************************************************************************/ 1614 *****************************************************************************/
1624 1615
1625static void MoxaPortFlushData(struct moxa_port *port, int mode) 1616static void MoxaPortFlushData(struct moxa_port *port, int mode)
@@ -1635,67 +1626,6 @@ static void MoxaPortFlushData(struct moxa_port *port, int mode)
1635 } 1626 }
1636} 1627}
1637 1628
1638static int MoxaDriverPoll(void)
1639{
1640 struct moxa_board_conf *brd;
1641 struct moxa_port *p;
1642 void __iomem *ofsAddr;
1643 void __iomem *ip;
1644 unsigned int port, ports, card;
1645 ushort temp;
1646
1647 for (card = 0; card < MAX_BOARDS; card++) {
1648 brd = &moxa_boards[card];
1649 if (brd->ready == 0)
1650 continue;
1651 if ((ports = brd->numPorts) == 0)
1652 continue;
1653 if (readb(brd->intPend) == 0xff) {
1654 ip = brd->intTable + readb(brd->intNdx);
1655 p = brd->ports;
1656 ports <<= 1;
1657 for (port = 0; port < ports; port += 2, p++) {
1658 temp = readw(ip + port);
1659 if (temp == 0)
1660 continue;
1661
1662 writew(0, ip + port);
1663 ofsAddr = p->tableAddr;
1664 if (temp & IntrTx)
1665 writew(readw(ofsAddr + HostStat) &
1666 ~WakeupTx, ofsAddr + HostStat);
1667 if (temp & IntrBreak)
1668 p->breakCnt++;
1669
1670 if (temp & IntrLine) {
1671 if (readb(ofsAddr + FlagStat) & DCD_state) {
1672 if ((p->DCDState & DCD_oldstate) == 0)
1673 p->DCDState = (DCD_oldstate |
1674 DCD_changed);
1675 } else {
1676 if (p->DCDState & DCD_oldstate)
1677 p->DCDState = DCD_changed;
1678 }
1679 }
1680 }
1681 writeb(0, brd->intPend);
1682 }
1683 if (moxaLowWaterChk) {
1684 p = brd->ports;
1685 for (port = 0; port < ports; port++, p++) {
1686 if (p->lowChkFlag) {
1687 p->lowChkFlag = 0;
1688 ofsAddr = p->tableAddr;
1689 moxa_low_water_check(ofsAddr);
1690 }
1691 }
1692 }
1693 }
1694 moxaLowWaterChk = 0;
1695
1696 return 0;
1697}
1698
1699/***************************************************************************** 1629/*****************************************************************************
1700 * Port level functions: * 1630 * Port level functions: *
1701 * 2. MoxaPortEnable(int port); * 1631 * 2. MoxaPortEnable(int port); *
@@ -1707,8 +1637,6 @@ static int MoxaDriverPoll(void)
1707 * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); * 1637 * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); *
1708 * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); * 1638 * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); *
1709 * 12. MoxaPortLineStatus(int port); * 1639 * 12. MoxaPortLineStatus(int port); *
1710 * 13. MoxaPortDCDChange(int port); *
1711 * 14. MoxaPortDCDON(int port); *
1712 * 15. MoxaPortFlushData(int port, int mode); * 1640 * 15. MoxaPortFlushData(int port, int mode); *
1713 * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * 1641 * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
1714 * 17. MoxaPortReadData(int port, struct tty_struct *tty); * 1642 * 17. MoxaPortReadData(int port, struct tty_struct *tty); *
@@ -1755,14 +1683,6 @@ static int MoxaDriverPoll(void)
1755 * -ENOIOCTLCMD 1683 * -ENOIOCTLCMD
1756 * 1684 *
1757 * 1685 *
1758 * Function 3: Moxa driver polling process routine.
1759 * Syntax:
1760 * int MoxaDriverPoll(void);
1761 *
1762 * return: 0 ; polling O.K.
1763 * -1 : no any Moxa card.
1764 *
1765 *
1766 * Function 6: Enable this port to start Tx/Rx data. 1686 * Function 6: Enable this port to start Tx/Rx data.
1767 * Syntax: 1687 * Syntax:
1768 * void MoxaPortEnable(int port); 1688 * void MoxaPortEnable(int port);
@@ -1853,25 +1773,6 @@ static int MoxaDriverPoll(void)
1853 * Bit 2 - DCD state (0: off, 1: on) 1773 * Bit 2 - DCD state (0: off, 1: on)
1854 * 1774 *
1855 * 1775 *
1856 * Function 17: Check the DCD state has changed since the last read
1857 * of this function.
1858 * Syntax:
1859 * int MoxaPortDCDChange(int port);
1860 * int port : port number (0 - 127)
1861 *
1862 * return: 0 : no changed
1863 * 1 : DCD has changed
1864 *
1865 *
1866 * Function 18: Check ths current DCD state is ON or not.
1867 * Syntax:
1868 * int MoxaPortDCDON(int port);
1869 * int port : port number (0 - 127)
1870 *
1871 * return: 0 : DCD off
1872 * 1 : DCD on
1873 *
1874 *
1875 * Function 19: Flush the Rx/Tx buffer data of this port. 1776 * Function 19: Flush the Rx/Tx buffer data of this port.
1876 * Syntax: 1777 * Syntax:
1877 * void MoxaPortFlushData(int port, int mode); 1778 * void MoxaPortFlushData(int port, int mode);
@@ -1954,7 +1855,6 @@ static void MoxaPortEnable(struct moxa_port *port)
1954 1855
1955 ofsAddr = port->tableAddr; 1856 ofsAddr = port->tableAddr;
1956 writew(lowwater, ofsAddr + Low_water); 1857 writew(lowwater, ofsAddr + Low_water);
1957 port->breakCnt = 0;
1958 if (port->board->boardType == MOXA_BOARD_C320_ISA || 1858 if (port->board->boardType == MOXA_BOARD_C320_ISA ||
1959 port->board->boardType == MOXA_BOARD_C320_PCI) { 1859 port->board->boardType == MOXA_BOARD_C320_PCI) {
1960 moxafunc(ofsAddr, FC_SetBreakIrq, 0); 1860 moxafunc(ofsAddr, FC_SetBreakIrq, 0);
@@ -2123,37 +2023,11 @@ static int MoxaPortLineStatus(struct moxa_port *port)
2123 val = readw(ofsAddr + FlagStat) >> 4; 2023 val = readw(ofsAddr + FlagStat) >> 4;
2124 } 2024 }
2125 val &= 0x0B; 2025 val &= 0x0B;
2126 if (val & 8) { 2026 if (val & 8)
2127 val |= 4; 2027 val |= 4;
2128 if ((port->DCDState & DCD_oldstate) == 0) 2028 moxa_new_dcdstate(port, val & 8);
2129 port->DCDState = (DCD_oldstate | DCD_changed);
2130 } else {
2131 if (port->DCDState & DCD_oldstate)
2132 port->DCDState = DCD_changed;
2133 }
2134 val &= 7; 2029 val &= 7;
2135 return (val); 2030 return val;
2136}
2137
2138static int MoxaPortDCDChange(struct moxa_port *port)
2139{
2140 int n;
2141
2142 n = port->DCDState;
2143 port->DCDState &= ~DCD_changed;
2144 n &= DCD_changed;
2145 return (n);
2146}
2147
2148static int MoxaPortDCDON(struct moxa_port *port)
2149{
2150 int n;
2151
2152 if (port->DCDState & DCD_oldstate)
2153 n = 1;
2154 else
2155 n = 0;
2156 return (n);
2157} 2031}
2158 2032
2159static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer, 2033static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
@@ -2221,8 +2095,9 @@ static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
2221 return (total); 2095 return (total);
2222} 2096}
2223 2097
2224static int MoxaPortReadData(struct moxa_port *port, struct tty_struct *tty) 2098static int MoxaPortReadData(struct moxa_port *port)
2225{ 2099{
2100 struct tty_struct *tty = port->tty;
2226 register ushort head, pageofs; 2101 register ushort head, pageofs;
2227 int i, count, cnt, len, total, remain; 2102 int i, count, cnt, len, total, remain;
2228 ushort tail, rx_mask, spage, epage; 2103 ushort tail, rx_mask, spage, epage;
@@ -2243,7 +2118,7 @@ static int MoxaPortReadData(struct moxa_port *port, struct tty_struct *tty)
2243 2118
2244 total = count; 2119 total = count;
2245 remain = count - total; 2120 remain = count - total;
2246 moxaLog.rxcnt[port->tty->index] += total; 2121 moxaLog.rxcnt[tty->index] += total;
2247 count = total; 2122 count = total;
2248 if (spage == epage) { 2123 if (spage == epage) {
2249 bufhead = readw(ofsAddr + Ofs_rxb); 2124 bufhead = readw(ofsAddr + Ofs_rxb);
@@ -2341,15 +2216,6 @@ static void MoxaPortTxEnable(struct moxa_port *port)
2341 moxafunc(port->tableAddr, FC_SetXonState, Magic_code); 2216 moxafunc(port->tableAddr, FC_SetXonState, Magic_code);
2342} 2217}
2343 2218
2344
2345static int MoxaPortResetBrkCnt(struct moxa_port *port)
2346{
2347 ushort cnt;
2348 cnt = port->breakCnt;
2349 port->breakCnt = 0;
2350 return (cnt);
2351}
2352
2353static int moxa_get_serial_info(struct moxa_port *info, 2219static int moxa_get_serial_info(struct moxa_port *info,
2354 struct serial_struct __user *retinfo) 2220 struct serial_struct __user *retinfo)
2355{ 2221{
@@ -2413,21 +2279,6 @@ static int moxa_set_serial_info(struct moxa_port *info,
2413 * Static local functions: * 2279 * Static local functions: *
2414 *****************************************************************************/ 2280 *****************************************************************************/
2415 2281
2416static void moxa_low_water_check(void __iomem *ofsAddr)
2417{
2418 int len;
2419 ushort rptr, wptr, mask;
2420
2421 if (readb(ofsAddr + FlagStat) & Xoff_state) {
2422 rptr = readw(ofsAddr + RXrptr);
2423 wptr = readw(ofsAddr + RXwptr);
2424 mask = readw(ofsAddr + RX_mask);
2425 len = (wptr - rptr) & mask;
2426 if (len <= Low_water)
2427 moxafunc(ofsAddr, FC_SendXon, 0);
2428 }
2429}
2430
2431static void MoxaSetFifo(struct moxa_port *port, int enable) 2282static void MoxaSetFifo(struct moxa_port *port, int enable)
2432{ 2283{
2433 void __iomem *ofsAddr = port->tableAddr; 2284 void __iomem *ofsAddr = port->tableAddr;
diff --git a/drivers/char/moxa.h b/drivers/char/moxa.h
index 49e926dea195..0b1650621a04 100644
--- a/drivers/char/moxa.h
+++ b/drivers/char/moxa.h
@@ -165,11 +165,11 @@
165#define HostStat 0x08 /* IRQ flag and general flag */ 165#define HostStat 0x08 /* IRQ flag and general flag */
166#define FlagStat 0x0A 166#define FlagStat 0x0A
167#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ 167#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */
168 /* x x x x | | | | */ 168 /* x x x x | | | | */
169 /* | | | + CTS flow */ 169 /* | | | + CTS flow */
170 /* | | +--- RTS flow */ 170 /* | | +--- RTS flow */
171 /* | +------ TX Xon/Xoff */ 171 /* | +------ TX Xon/Xoff */
172 /* +--------- RX Xon/Xoff */ 172 /* +--------- RX Xon/Xoff */
173#define Break_cnt 0x0E /* received break count */ 173#define Break_cnt 0x0E /* received break count */
174#define CD180TXirq 0x10 /* if non-0: enable TX irq */ 174#define CD180TXirq 0x10 /* if non-0: enable TX irq */
175#define RX_mask 0x12 175#define RX_mask 0x12