aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/moxa.c
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-04-30 03:53:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:42 -0400
commit74d7d97b9e2a090a4b1812b5074ac6c539234ebb (patch)
tree912c68a877a5004f1d2926934837dbb512ce606e /drivers/char/moxa.c
parent0bcc4caadc8f5396b52950ee03c67b76875602df (diff)
Char: moxa, ioctl cleanup
- allow stats only for sys_admin - move TCSBRK* processing to .break_ctl tty op - let TIOCGSOFTCAR and TIOCSSOFTCAR be processed by ldisc - remove MOXA_GET_MAJOR, MOXA_GET_CUMAJOR - fix jiffies subtraction by time_after - move moxa ioctl numbers into the header; still not exported to userspace, needs _IOC and 32/64 compat cleanup anyways Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Tested-by: Oyvind Aabling <Oyvind.Aabling@uni-c.dk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/moxa.c')
-rw-r--r--drivers/char/moxa.c360
1 files changed, 139 insertions, 221 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index fdfa7783e992..f737fbb8598c 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -150,6 +150,12 @@ struct moxa_port {
150 ushort breakCnt; 150 ushort breakCnt;
151}; 151};
152 152
153struct mon_str {
154 int tick;
155 int rxcnt[MAX_PORTS];
156 int txcnt[MAX_PORTS];
157};
158
153/* statusflags */ 159/* statusflags */
154#define TXSTOPPED 0x1 160#define TXSTOPPED 0x1
155#define LOWWAIT 0x2 161#define LOWWAIT 0x2
@@ -161,6 +167,8 @@ struct moxa_port {
161#define WAKEUP_CHARS 256 167#define WAKEUP_CHARS 256
162 168
163static int ttymajor = MOXAMAJOR; 169static int ttymajor = MOXAMAJOR;
170static struct mon_str moxaLog;
171static unsigned int moxaFuncTout = HZ / 2;
164/* Variables for insmod */ 172/* Variables for insmod */
165#ifdef MODULE 173#ifdef MODULE
166static unsigned long baseaddr[MAX_BOARDS]; 174static unsigned long baseaddr[MAX_BOARDS];
@@ -192,7 +200,6 @@ static void moxa_flush_buffer(struct tty_struct *);
192static int moxa_chars_in_buffer(struct tty_struct *); 200static int moxa_chars_in_buffer(struct tty_struct *);
193static void moxa_flush_chars(struct tty_struct *); 201static void moxa_flush_chars(struct tty_struct *);
194static void moxa_put_char(struct tty_struct *, unsigned char); 202static void moxa_put_char(struct tty_struct *, unsigned char);
195static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
196static void moxa_throttle(struct tty_struct *); 203static void moxa_throttle(struct tty_struct *);
197static void moxa_unthrottle(struct tty_struct *); 204static void moxa_unthrottle(struct tty_struct *);
198static void moxa_set_termios(struct tty_struct *, struct ktermios *); 205static void moxa_set_termios(struct tty_struct *, struct ktermios *);
@@ -213,7 +220,6 @@ static void moxa_receive_data(struct moxa_port *);
213/* 220/*
214 * moxa board interface functions: 221 * moxa board interface functions:
215 */ 222 */
216static int MoxaDriverIoctl(struct tty_struct *, unsigned int, unsigned long);
217static int MoxaDriverPoll(void); 223static int MoxaDriverPoll(void);
218static void MoxaPortEnable(struct moxa_port *); 224static void MoxaPortEnable(struct moxa_port *);
219static void MoxaPortDisable(struct moxa_port *); 225static void MoxaPortDisable(struct moxa_port *);
@@ -233,11 +239,131 @@ static int MoxaPortTxFree(struct moxa_port *);
233static void MoxaPortTxDisable(struct moxa_port *); 239static void MoxaPortTxDisable(struct moxa_port *);
234static void MoxaPortTxEnable(struct moxa_port *); 240static void MoxaPortTxEnable(struct moxa_port *);
235static int MoxaPortResetBrkCnt(struct moxa_port *); 241static int MoxaPortResetBrkCnt(struct moxa_port *);
236static void MoxaPortSendBreak(struct moxa_port *, int);
237static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); 242static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *);
238static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); 243static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *);
239static void MoxaSetFifo(struct moxa_port *port, int enable); 244static void MoxaSetFifo(struct moxa_port *port, int enable);
240 245
246/*
247 * I/O functions
248 */
249
250static void moxa_wait_finish(void __iomem *ofsAddr)
251{
252 unsigned long end = jiffies + moxaFuncTout;
253
254 while (readw(ofsAddr + FuncCode) != 0)
255 if (time_after(jiffies, end))
256 return;
257 if (readw(ofsAddr + FuncCode) != 0 && printk_ratelimit())
258 printk(KERN_WARNING "moxa function expired\n");
259}
260
261static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
262{
263 writew(arg, ofsAddr + FuncArg);
264 writew(cmd, ofsAddr + FuncCode);
265 moxa_wait_finish(ofsAddr);
266}
267
268/*
269 * TTY operations
270 */
271
272static int moxa_ioctl(struct tty_struct *tty, struct file *file,
273 unsigned int cmd, unsigned long arg)
274{
275 struct moxa_port *ch = tty->driver_data;
276 void __user *argp = (void __user *)arg;
277 int status;
278
279 if (tty->index == MAX_PORTS) {
280 if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE &&
281 cmd != MOXA_GETMSTATUS)
282 return -EINVAL;
283 } else if (!ch)
284 return -ENODEV;
285
286 switch (cmd) {
287 case MOXA_GETDATACOUNT:
288 moxaLog.tick = jiffies;
289 return copy_to_user(argp, &moxaLog, sizeof(moxaLog)) ?
290 -EFAULT : 0;
291 case MOXA_FLUSH_QUEUE:
292 MoxaPortFlushData(ch, arg);
293 return 0;
294 case MOXA_GET_IOQUEUE: {
295 struct moxaq_str __user *argm = argp;
296 struct moxaq_str tmp;
297 struct moxa_port *p;
298 unsigned int i, j;
299
300 for (i = 0; i < MAX_BOARDS; i++) {
301 p = moxa_boards[i].ports;
302 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
303 memset(&tmp, 0, sizeof(tmp));
304 if (moxa_boards[i].ready) {
305 tmp.inq = MoxaPortRxQueue(p);
306 tmp.outq = MoxaPortTxQueue(p);
307 }
308 if (copy_to_user(argm, &tmp, sizeof(tmp)))
309 return -EFAULT;
310 }
311 }
312 return 0;
313 } case MOXA_GET_OQUEUE:
314 status = MoxaPortTxQueue(ch);
315 return put_user(status, (unsigned long __user *)argp);
316 case MOXA_GET_IQUEUE:
317 status = MoxaPortRxQueue(ch);
318 return put_user(status, (unsigned long __user *)argp);
319 case MOXA_GETMSTATUS: {
320 struct mxser_mstatus __user *argm = argp;
321 struct mxser_mstatus tmp;
322 struct moxa_port *p;
323 unsigned int i, j;
324
325 for (i = 0; i < MAX_BOARDS; i++) {
326 p = moxa_boards[i].ports;
327 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
328 memset(&tmp, 0, sizeof(tmp));
329 if (!moxa_boards[i].ready)
330 goto copy;
331
332 status = MoxaPortLineStatus(p);
333 if (status & 1)
334 tmp.cts = 1;
335 if (status & 2)
336 tmp.dsr = 1;
337 if (status & 4)
338 tmp.dcd = 1;
339
340 if (!p->tty || !p->tty->termios)
341 tmp.cflag = p->cflag;
342 else
343 tmp.cflag = p->tty->termios->c_cflag;
344copy:
345 if (copy_to_user(argm, &tmp, sizeof(tmp)))
346 return -EFAULT;
347 }
348 }
349 return 0;
350 }
351 case TIOCGSERIAL:
352 return moxa_get_serial_info(ch, argp);
353 case TIOCSSERIAL:
354 return moxa_set_serial_info(ch, argp);
355 }
356 return -ENOIOCTLCMD;
357}
358
359static void moxa_break_ctl(struct tty_struct *tty, int state)
360{
361 struct moxa_port *port = tty->driver_data;
362
363 moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,
364 Magic_code);
365}
366
241static const struct tty_operations moxa_ops = { 367static const struct tty_operations moxa_ops = {
242 .open = moxa_open, 368 .open = moxa_open,
243 .close = moxa_close, 369 .close = moxa_close,
@@ -254,6 +380,7 @@ static const struct tty_operations moxa_ops = {
254 .stop = moxa_stop, 380 .stop = moxa_stop,
255 .start = moxa_start, 381 .start = moxa_start,
256 .hangup = moxa_hangup, 382 .hangup = moxa_hangup,
383 .break_ctl = moxa_break_ctl,
257 .tiocmget = moxa_tiocmget, 384 .tiocmget = moxa_tiocmget,
258 .tiocmset = moxa_tiocmset, 385 .tiocmset = moxa_tiocmset,
259}; 386};
@@ -262,6 +389,10 @@ static struct tty_driver *moxaDriver;
262static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); 389static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
263static DEFINE_SPINLOCK(moxa_lock); 390static DEFINE_SPINLOCK(moxa_lock);
264 391
392/*
393 * HW init
394 */
395
265static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model) 396static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model)
266{ 397{
267 switch (brd->boardType) { 398 switch (brd->boardType) {
@@ -938,7 +1069,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
938 1069
939 port = tty->index; 1070 port = tty->index;
940 if (port == MAX_PORTS) { 1071 if (port == MAX_PORTS) {
941 return (0); 1072 return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
942 } 1073 }
943 brd = &moxa_boards[port / MAX_PORTS_PER_BOARD]; 1074 brd = &moxa_boards[port / MAX_PORTS_PER_BOARD];
944 if (!brd->ready) 1075 if (!brd->ready)
@@ -1123,8 +1254,8 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
1123 struct moxa_port *ch = tty->driver_data; 1254 struct moxa_port *ch = tty->driver_data;
1124 int flag = 0, dtr, rts; 1255 int flag = 0, dtr, rts;
1125 1256
1126 if ((tty->index != MAX_PORTS) && (!ch)) 1257 if (!ch)
1127 return (-EINVAL); 1258 return -EINVAL;
1128 1259
1129 MoxaPortGetLineOut(ch, &dtr, &rts); 1260 MoxaPortGetLineOut(ch, &dtr, &rts);
1130 if (dtr) 1261 if (dtr)
@@ -1149,8 +1280,8 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
1149 int dtr, rts; 1280 int dtr, rts;
1150 1281
1151 port = tty->index; 1282 port = tty->index;
1152 if ((port != MAX_PORTS) && (!ch)) 1283 if (!ch)
1153 return (-EINVAL); 1284 return -EINVAL;
1154 1285
1155 MoxaPortGetLineOut(ch, &dtr, &rts); 1286 MoxaPortGetLineOut(ch, &dtr, &rts);
1156 if (set & TIOCM_RTS) 1287 if (set & TIOCM_RTS)
@@ -1165,60 +1296,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
1165 return 0; 1296 return 0;
1166} 1297}
1167 1298
1168static int moxa_ioctl(struct tty_struct *tty, struct file *file,
1169 unsigned int cmd, unsigned long arg)
1170{
1171 struct moxa_port *ch = tty->driver_data;
1172 register int port;
1173 void __user *argp = (void __user *)arg;
1174 int retval;
1175
1176 port = tty->index;
1177 if ((port != MAX_PORTS) && (!ch))
1178 return (-EINVAL);
1179
1180 switch (cmd) {
1181 case TCSBRK: /* SVID version: non-zero arg --> no break */
1182 retval = tty_check_change(tty);
1183 if (retval)
1184 return (retval);
1185 moxa_setup_empty_event(tty);
1186 tty_wait_until_sent(tty, 0);
1187 if (!arg)
1188 MoxaPortSendBreak(ch, 0);
1189 return (0);
1190 case TCSBRKP: /* support for POSIX tcsendbreak() */
1191 retval = tty_check_change(tty);
1192 if (retval)
1193 return (retval);
1194 moxa_setup_empty_event(tty);
1195 tty_wait_until_sent(tty, 0);
1196 MoxaPortSendBreak(ch, arg);
1197 return (0);
1198 case TIOCGSOFTCAR:
1199 return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)argp);
1200 case TIOCSSOFTCAR:
1201 if (get_user(retval, (int __user *)argp))
1202 return -EFAULT;
1203 arg = retval;
1204 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
1205 (arg ? CLOCAL : 0));
1206 if (C_CLOCAL(tty))
1207 ch->asyncflags &= ~ASYNC_CHECK_CD;
1208 else
1209 ch->asyncflags |= ASYNC_CHECK_CD;
1210 return (0);
1211 case TIOCGSERIAL:
1212 return moxa_get_serial_info(ch, argp);
1213
1214 case TIOCSSERIAL:
1215 return moxa_set_serial_info(ch, argp);
1216 default:
1217 retval = MoxaDriverIoctl(tty, cmd, arg);
1218 }
1219 return (retval);
1220}
1221
1222static void moxa_throttle(struct tty_struct *tty) 1299static void moxa_throttle(struct tty_struct *tty)
1223{ 1300{
1224 struct moxa_port *ch = (struct moxa_port *) tty->driver_data; 1301 struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
@@ -1533,38 +1610,17 @@ static void moxa_receive_data(struct moxa_port *ch)
1533 * Query 1610 * Query
1534 */ 1611 */
1535 1612
1536struct mon_str {
1537 int tick;
1538 int rxcnt[MAX_PORTS];
1539 int txcnt[MAX_PORTS];
1540};
1541
1542#define DCD_changed 0x01 1613#define DCD_changed 0x01
1543#define DCD_oldstate 0x80 1614#define DCD_oldstate 0x80
1544 1615
1545static int moxaLowWaterChk; 1616static int moxaLowWaterChk;
1546static struct mon_str moxaLog;
1547static int moxaFuncTout = HZ / 2;
1548 1617
1549static void moxafunc(void __iomem *, int, ushort);
1550static void moxa_wait_finish(void __iomem *);
1551static void moxa_low_water_check(void __iomem *); 1618static void moxa_low_water_check(void __iomem *);
1552 1619
1553/***************************************************************************** 1620/*****************************************************************************
1554 * Driver level functions: * 1621 * Driver level functions: *
1555 * 2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); *
1556 * 3. MoxaDriverPoll(void); * 1622 * 3. MoxaDriverPoll(void); *
1557 *****************************************************************************/ 1623 *****************************************************************************/
1558#define MOXA 0x400
1559#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */
1560#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */
1561#define MOXA_GETDATACOUNT (MOXA + 23)
1562#define MOXA_GET_IOQUEUE (MOXA + 27)
1563#define MOXA_FLUSH_QUEUE (MOXA + 28)
1564#define MOXA_GET_CONF (MOXA + 35) /* configuration */
1565#define MOXA_GET_MAJOR (MOXA + 63)
1566#define MOXA_GET_CUMAJOR (MOXA + 64)
1567#define MOXA_GETMSTATUS (MOXA + 65)
1568 1624
1569static void MoxaPortFlushData(struct moxa_port *port, int mode) 1625static void MoxaPortFlushData(struct moxa_port *port, int mode)
1570{ 1626{
@@ -1579,100 +1635,6 @@ static void MoxaPortFlushData(struct moxa_port *port, int mode)
1579 } 1635 }
1580} 1636}
1581 1637
1582static int MoxaDriverIoctl(struct tty_struct *tty, unsigned int cmd,
1583 unsigned long arg)
1584{
1585 struct moxa_port *port = tty->driver_data;
1586 int i;
1587 int status;
1588 void __user *argp = (void __user *)arg;
1589
1590 if (tty->index == MAX_PORTS) {
1591 if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_GETDATACOUNT) &&
1592 (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) &&
1593 (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS))
1594 return (-EINVAL);
1595 }
1596 switch (cmd) {
1597 case MOXA_GETDATACOUNT:
1598 moxaLog.tick = jiffies;
1599 if(copy_to_user(argp, &moxaLog, sizeof(struct mon_str)))
1600 return -EFAULT;
1601 return (0);
1602 case MOXA_FLUSH_QUEUE:
1603 MoxaPortFlushData(port, arg);
1604 return (0);
1605 case MOXA_GET_IOQUEUE: {
1606 struct moxaq_str __user *argm = argp;
1607 struct moxaq_str tmp;
1608 struct moxa_port *p;
1609 unsigned int j;
1610
1611 for (i = 0; i < MAX_BOARDS; i++) {
1612 p = moxa_boards[i].ports;
1613 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
1614 memset(&tmp, 0, sizeof(tmp));
1615 if (moxa_boards[i].ready) {
1616 tmp.inq = MoxaPortRxQueue(p);
1617 tmp.outq = MoxaPortTxQueue(p);
1618 }
1619 if (copy_to_user(argm, &tmp, sizeof(tmp)))
1620 return -EFAULT;
1621 }
1622 }
1623 return 0;
1624 } case MOXA_GET_OQUEUE:
1625 i = MoxaPortTxQueue(port);
1626 return put_user(i, (unsigned long __user *)argp);
1627 case MOXA_GET_IQUEUE:
1628 i = MoxaPortRxQueue(port);
1629 return put_user(i, (unsigned long __user *)argp);
1630 case MOXA_GET_MAJOR:
1631 if(copy_to_user(argp, &ttymajor, sizeof(int)))
1632 return -EFAULT;
1633 return 0;
1634 case MOXA_GET_CUMAJOR:
1635 i = 0;
1636 if(copy_to_user(argp, &i, sizeof(int)))
1637 return -EFAULT;
1638 return 0;
1639 case MOXA_GETMSTATUS: {
1640 struct mxser_mstatus __user *argm = argp;
1641 struct mxser_mstatus tmp;
1642 struct moxa_port *p;
1643 unsigned int j;
1644
1645 for (i = 0; i < MAX_BOARDS; i++) {
1646 p = moxa_boards[i].ports;
1647 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
1648 memset(&tmp, 0, sizeof(tmp));
1649 if (!moxa_boards[i].ready)
1650 goto copy;
1651
1652 status = MoxaPortLineStatus(p);
1653 if (status & 1)
1654 tmp.cts = 1;
1655 if (status & 2)
1656 tmp.dsr = 1;
1657 if (status & 4)
1658 tmp.dcd = 1;
1659
1660 if (!p->tty || !p->tty->termios)
1661 tmp.cflag = p->cflag;
1662 else
1663 tmp.cflag = p->tty->termios->c_cflag;
1664copy:
1665 if (copy_to_user(argm, &tmp, sizeof(tmp)))
1666 return -EFAULT;
1667 }
1668 }
1669 return 0;
1670 }
1671 }
1672
1673 return -ENOIOCTLCMD;
1674}
1675
1676static int MoxaDriverPoll(void) 1638static int MoxaDriverPoll(void)
1677{ 1639{
1678 struct moxa_board_conf *brd; 1640 struct moxa_board_conf *brd;
@@ -1756,7 +1718,6 @@ static int MoxaDriverPoll(void)
1756 * 24. MoxaPortTxDisable(int port); * 1718 * 24. MoxaPortTxDisable(int port); *
1757 * 25. MoxaPortTxEnable(int port); * 1719 * 25. MoxaPortTxEnable(int port); *
1758 * 27. MoxaPortResetBrkCnt(int port); * 1720 * 27. MoxaPortResetBrkCnt(int port); *
1759 * 30. MoxaPortSendBreak(int port, int ticks); *
1760 *****************************************************************************/ 1721 *****************************************************************************/
1761/* 1722/*
1762 * Moxa Port Number Description: 1723 * Moxa Port Number Description:
@@ -1984,14 +1945,6 @@ static int MoxaDriverPoll(void)
1984 * return: 0 - .. : BREAK signal count 1945 * return: 0 - .. : BREAK signal count
1985 * 1946 *
1986 * 1947 *
1987 * Function 34: Send out a BREAK signal.
1988 * Syntax:
1989 * void MoxaPortSendBreak(int port, int ms100);
1990 * int port : port number (0 - 127)
1991 * int ms100 : break signal time interval.
1992 * unit: 100 mini-second. if ms100 == 0, it will
1993 * send out a about 250 ms BREAK signal.
1994 *
1995 */ 1948 */
1996 1949
1997static void MoxaPortEnable(struct moxa_port *port) 1950static void MoxaPortEnable(struct moxa_port *port)
@@ -2397,21 +2350,6 @@ static int MoxaPortResetBrkCnt(struct moxa_port *port)
2397 return (cnt); 2350 return (cnt);
2398} 2351}
2399 2352
2400
2401static void MoxaPortSendBreak(struct moxa_port *port, int ms100)
2402{
2403 void __iomem *ofsAddr = port->tableAddr;
2404
2405 if (ms100) {
2406 moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2407 msleep(ms100 * 10);
2408 } else {
2409 moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2410 msleep(250);
2411 }
2412 moxafunc(ofsAddr, FC_StopBreak, Magic_code);
2413}
2414
2415static int moxa_get_serial_info(struct moxa_port *info, 2353static int moxa_get_serial_info(struct moxa_port *info,
2416 struct serial_struct __user *retinfo) 2354 struct serial_struct __user *retinfo)
2417{ 2355{
@@ -2474,26 +2412,6 @@ static int moxa_set_serial_info(struct moxa_port *info,
2474/***************************************************************************** 2412/*****************************************************************************
2475 * Static local functions: * 2413 * Static local functions: *
2476 *****************************************************************************/ 2414 *****************************************************************************/
2477static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
2478{
2479
2480 writew(arg, ofsAddr + FuncArg);
2481 writew(cmd, ofsAddr + FuncCode);
2482 moxa_wait_finish(ofsAddr);
2483}
2484
2485static void moxa_wait_finish(void __iomem *ofsAddr)
2486{
2487 unsigned long i, j;
2488
2489 i = jiffies;
2490 while (readw(ofsAddr + FuncCode) != 0) {
2491 j = jiffies;
2492 if ((j - i) > moxaFuncTout) {
2493 return;
2494 }
2495 }
2496}
2497 2415
2498static void moxa_low_water_check(void __iomem *ofsAddr) 2416static void moxa_low_water_check(void __iomem *ofsAddr)
2499{ 2417{