diff options
-rw-r--r-- | drivers/char/moxa.c | 421 | ||||
-rw-r--r-- | drivers/char/moxa.h | 10 |
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 | ||
130 | struct moxa_port { | 130 | struct 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 | ||
153 | struct mon_str { | 150 | struct mon_str { |
@@ -169,6 +166,7 @@ struct mon_str { | |||
169 | static int ttymajor = MOXAMAJOR; | 166 | static int ttymajor = MOXAMAJOR; |
170 | static struct mon_str moxaLog; | 167 | static struct mon_str moxaLog; |
171 | static unsigned int moxaFuncTout = HZ / 2; | 168 | static unsigned int moxaFuncTout = HZ / 2; |
169 | static unsigned int moxaLowWaterChk; | ||
172 | /* Variables for insmod */ | 170 | /* Variables for insmod */ |
173 | #ifdef MODULE | 171 | #ifdef MODULE |
174 | static unsigned long baseaddr[MAX_BOARDS]; | 172 | static unsigned long baseaddr[MAX_BOARDS]; |
@@ -214,13 +212,10 @@ static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); | |||
214 | static int moxa_block_till_ready(struct tty_struct *, struct file *, | 212 | static int moxa_block_till_ready(struct tty_struct *, struct file *, |
215 | struct moxa_port *); | 213 | struct moxa_port *); |
216 | static void moxa_setup_empty_event(struct tty_struct *); | 214 | static void moxa_setup_empty_event(struct tty_struct *); |
217 | static void moxa_check_xmit_empty(unsigned long); | ||
218 | static void moxa_shut_down(struct moxa_port *); | 215 | static void moxa_shut_down(struct moxa_port *); |
219 | static void moxa_receive_data(struct moxa_port *); | ||
220 | /* | 216 | /* |
221 | * moxa board interface functions: | 217 | * moxa board interface functions: |
222 | */ | 218 | */ |
223 | static int MoxaDriverPoll(void); | ||
224 | static void MoxaPortEnable(struct moxa_port *); | 219 | static void MoxaPortEnable(struct moxa_port *); |
225 | static void MoxaPortDisable(struct moxa_port *); | 220 | static void MoxaPortDisable(struct moxa_port *); |
226 | static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t); | 221 | static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t); |
@@ -228,17 +223,14 @@ static int MoxaPortGetLineOut(struct moxa_port *, int *, int *); | |||
228 | static void MoxaPortLineCtrl(struct moxa_port *, int, int); | 223 | static void MoxaPortLineCtrl(struct moxa_port *, int, int); |
229 | static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); | 224 | static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); |
230 | static int MoxaPortLineStatus(struct moxa_port *); | 225 | static int MoxaPortLineStatus(struct moxa_port *); |
231 | static int MoxaPortDCDChange(struct moxa_port *); | ||
232 | static int MoxaPortDCDON(struct moxa_port *); | ||
233 | static void MoxaPortFlushData(struct moxa_port *, int); | 226 | static void MoxaPortFlushData(struct moxa_port *, int); |
234 | static int MoxaPortWriteData(struct moxa_port *, unsigned char *, int); | 227 | static int MoxaPortWriteData(struct moxa_port *, unsigned char *, int); |
235 | static int MoxaPortReadData(struct moxa_port *, struct tty_struct *tty); | 228 | static int MoxaPortReadData(struct moxa_port *); |
236 | static int MoxaPortTxQueue(struct moxa_port *); | 229 | static int MoxaPortTxQueue(struct moxa_port *); |
237 | static int MoxaPortRxQueue(struct moxa_port *); | 230 | static int MoxaPortRxQueue(struct moxa_port *); |
238 | static int MoxaPortTxFree(struct moxa_port *); | 231 | static int MoxaPortTxFree(struct moxa_port *); |
239 | static void MoxaPortTxDisable(struct moxa_port *); | 232 | static void MoxaPortTxDisable(struct moxa_port *); |
240 | static void MoxaPortTxEnable(struct moxa_port *); | 233 | static void MoxaPortTxEnable(struct moxa_port *); |
241 | static int MoxaPortResetBrkCnt(struct moxa_port *); | ||
242 | static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); | 234 | static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); |
243 | static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); | 235 | static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); |
244 | static void MoxaSetFifo(struct moxa_port *port, int enable); | 236 | static 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 | ||
260 | static 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 | ||
858 | static void moxa_board_deinit(struct moxa_board_conf *brd) | 861 | static 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) | |||
1236 | static void moxa_put_char(struct tty_struct *tty, unsigned char c) | 1234 | static 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 | ||
1363 | static void moxa_poll(unsigned long ignored) | 1360 | static 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) { | 1374 | static 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 | |||
1431 | static 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, | |||
1539 | static void moxa_setup_empty_event(struct tty_struct *tty) | 1583 | static 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 | |||
1550 | static 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 | ||
1566 | static void moxa_shut_down(struct moxa_port *ch) | 1592 | static 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 | ||
1586 | static 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 | |||
1616 | static int moxaLowWaterChk; | ||
1617 | |||
1618 | static 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 | ||
1625 | static void MoxaPortFlushData(struct moxa_port *port, int mode) | 1616 | static 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 | ||
1638 | static 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 | |||
2138 | static 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 | |||
2148 | static 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 | ||
2159 | static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer, | 2033 | static 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 | ||
2224 | static int MoxaPortReadData(struct moxa_port *port, struct tty_struct *tty) | 2098 | static 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 | |||
2345 | static int MoxaPortResetBrkCnt(struct moxa_port *port) | ||
2346 | { | ||
2347 | ushort cnt; | ||
2348 | cnt = port->breakCnt; | ||
2349 | port->breakCnt = 0; | ||
2350 | return (cnt); | ||
2351 | } | ||
2352 | |||
2353 | static int moxa_get_serial_info(struct moxa_port *info, | 2219 | static 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 | ||
2416 | static 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 | |||
2431 | static void MoxaSetFifo(struct moxa_port *port, int enable) | 2282 | static 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 |