|
@@ -129,25 +129,22 @@ struct moxaq_str {
|
|
|
|
|
|
struct moxa_port {
|
|
|
struct moxa_board_conf *board;
|
|
|
+ struct tty_struct *tty;
|
|
|
+ void __iomem *tableAddr;
|
|
|
+
|
|
|
int type;
|
|
|
int close_delay;
|
|
|
int count;
|
|
|
int blocked_open;
|
|
|
int asyncflags;
|
|
|
- unsigned long statusflags;
|
|
|
- struct tty_struct *tty;
|
|
|
int cflag;
|
|
|
+ unsigned long statusflags;
|
|
|
wait_queue_head_t open_wait;
|
|
|
struct completion close_wait;
|
|
|
|
|
|
- struct timer_list emptyTimer;
|
|
|
-
|
|
|
- char lineCtrl;
|
|
|
- void __iomem *tableAddr;
|
|
|
- char DCDState;
|
|
|
- char lowChkFlag;
|
|
|
-
|
|
|
- ushort breakCnt;
|
|
|
+ u8 DCDState;
|
|
|
+ u8 lineCtrl;
|
|
|
+ u8 lowChkFlag;
|
|
|
};
|
|
|
|
|
|
struct mon_str {
|
|
@@ -169,6 +166,7 @@ struct mon_str {
|
|
|
static int ttymajor = MOXAMAJOR;
|
|
|
static struct mon_str moxaLog;
|
|
|
static unsigned int moxaFuncTout = HZ / 2;
|
|
|
+static unsigned int moxaLowWaterChk;
|
|
|
/* Variables for insmod */
|
|
|
#ifdef MODULE
|
|
|
static unsigned long baseaddr[MAX_BOARDS];
|
|
@@ -214,13 +212,10 @@ static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
|
|
|
static int moxa_block_till_ready(struct tty_struct *, struct file *,
|
|
|
struct moxa_port *);
|
|
|
static void moxa_setup_empty_event(struct tty_struct *);
|
|
|
-static void moxa_check_xmit_empty(unsigned long);
|
|
|
static void moxa_shut_down(struct moxa_port *);
|
|
|
-static void moxa_receive_data(struct moxa_port *);
|
|
|
/*
|
|
|
* moxa board interface functions:
|
|
|
*/
|
|
|
-static int MoxaDriverPoll(void);
|
|
|
static void MoxaPortEnable(struct moxa_port *);
|
|
|
static void MoxaPortDisable(struct moxa_port *);
|
|
|
static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t);
|
|
@@ -228,17 +223,14 @@ static int MoxaPortGetLineOut(struct moxa_port *, int *, int *);
|
|
|
static void MoxaPortLineCtrl(struct moxa_port *, int, int);
|
|
|
static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
|
|
|
static int MoxaPortLineStatus(struct moxa_port *);
|
|
|
-static int MoxaPortDCDChange(struct moxa_port *);
|
|
|
-static int MoxaPortDCDON(struct moxa_port *);
|
|
|
static void MoxaPortFlushData(struct moxa_port *, int);
|
|
|
static int MoxaPortWriteData(struct moxa_port *, unsigned char *, int);
|
|
|
-static int MoxaPortReadData(struct moxa_port *, struct tty_struct *tty);
|
|
|
+static int MoxaPortReadData(struct moxa_port *);
|
|
|
static int MoxaPortTxQueue(struct moxa_port *);
|
|
|
static int MoxaPortRxQueue(struct moxa_port *);
|
|
|
static int MoxaPortTxFree(struct moxa_port *);
|
|
|
static void MoxaPortTxDisable(struct moxa_port *);
|
|
|
static void MoxaPortTxEnable(struct moxa_port *);
|
|
|
-static int MoxaPortResetBrkCnt(struct moxa_port *);
|
|
|
static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *);
|
|
|
static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *);
|
|
|
static void MoxaSetFifo(struct moxa_port *port, int enable);
|
|
@@ -265,6 +257,20 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
|
|
|
moxa_wait_finish(ofsAddr);
|
|
|
}
|
|
|
|
|
|
+static void moxa_low_water_check(void __iomem *ofsAddr)
|
|
|
+{
|
|
|
+ u16 rptr, wptr, mask, len;
|
|
|
+
|
|
|
+ if (readb(ofsAddr + FlagStat) & Xoff_state) {
|
|
|
+ rptr = readw(ofsAddr + RXrptr);
|
|
|
+ wptr = readw(ofsAddr + RXwptr);
|
|
|
+ mask = readw(ofsAddr + RX_mask);
|
|
|
+ len = (wptr - rptr) & mask;
|
|
|
+ if (len <= Low_water)
|
|
|
+ moxafunc(ofsAddr, FC_SendXon, 0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* TTY operations
|
|
|
*/
|
|
@@ -812,9 +818,6 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
|
|
|
p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
|
|
|
init_waitqueue_head(&p->open_wait);
|
|
|
init_completion(&p->close_wait);
|
|
|
-
|
|
|
- setup_timer(&p->emptyTimer, moxa_check_xmit_empty,
|
|
|
- (unsigned long)p);
|
|
|
}
|
|
|
|
|
|
switch (brd->boardType) {
|
|
@@ -857,12 +860,9 @@ err:
|
|
|
|
|
|
static void moxa_board_deinit(struct moxa_board_conf *brd)
|
|
|
{
|
|
|
- unsigned int i;
|
|
|
-
|
|
|
+ spin_lock_bh(&moxa_lock);
|
|
|
brd->ready = 0;
|
|
|
- for (i = 0; i < MAX_PORTS_PER_BOARD; i++)
|
|
|
- del_timer_sync(&brd->ports[i].emptyTimer);
|
|
|
-
|
|
|
+ spin_unlock_bh(&moxa_lock);
|
|
|
iounmap(brd->basemem);
|
|
|
brd->basemem = NULL;
|
|
|
kfree(brd->ports);
|
|
@@ -1135,7 +1135,6 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
|
|
|
if (ch->asyncflags & ASYNC_INITIALIZED) {
|
|
|
moxa_setup_empty_event(tty);
|
|
|
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
|
|
|
- del_timer_sync(&ch->emptyTimer);
|
|
|
}
|
|
|
moxa_shut_down(ch);
|
|
|
MoxaPortFlushData(ch, 2);
|
|
@@ -1160,15 +1159,14 @@ static int moxa_write(struct tty_struct *tty,
|
|
|
const unsigned char *buf, int count)
|
|
|
{
|
|
|
struct moxa_port *ch = tty->driver_data;
|
|
|
- unsigned long flags;
|
|
|
int len;
|
|
|
|
|
|
if (ch == NULL)
|
|
|
return 0;
|
|
|
|
|
|
- spin_lock_irqsave(&moxa_lock, flags);
|
|
|
+ spin_lock_bh(&moxa_lock);
|
|
|
len = MoxaPortWriteData(ch, (unsigned char *) buf, count);
|
|
|
- spin_unlock_irqrestore(&moxa_lock, flags);
|
|
|
+ spin_unlock_bh(&moxa_lock);
|
|
|
|
|
|
/*********************************************
|
|
|
if ( !(ch->statusflags & LOWWAIT) &&
|
|
@@ -1236,13 +1234,12 @@ static void moxa_flush_chars(struct tty_struct *tty)
|
|
|
static void moxa_put_char(struct tty_struct *tty, unsigned char c)
|
|
|
{
|
|
|
struct moxa_port *ch = tty->driver_data;
|
|
|
- unsigned long flags;
|
|
|
|
|
|
if (ch == NULL)
|
|
|
return;
|
|
|
- spin_lock_irqsave(&moxa_lock, flags);
|
|
|
+ spin_lock_bh(&moxa_lock);
|
|
|
MoxaPortWriteData(ch, &c, 1);
|
|
|
- spin_unlock_irqrestore(&moxa_lock, flags);
|
|
|
+ spin_unlock_bh(&moxa_lock);
|
|
|
/************************************************
|
|
|
if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
|
|
|
*************************************************/
|
|
@@ -1360,58 +1357,110 @@ static void moxa_hangup(struct tty_struct *tty)
|
|
|
wake_up_interruptible(&ch->open_wait);
|
|
|
}
|
|
|
|
|
|
-static void moxa_poll(unsigned long ignored)
|
|
|
+static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
|
|
|
{
|
|
|
- struct moxa_port *ch;
|
|
|
- struct tty_struct *tty;
|
|
|
- unsigned int card;
|
|
|
- int i;
|
|
|
+ dcd = !!dcd;
|
|
|
|
|
|
- del_timer(&moxaTimer);
|
|
|
+ if ((dcd != p->DCDState) && p->tty && C_CLOCAL(p->tty)) {
|
|
|
+ if (!dcd) {
|
|
|
+ tty_hangup(p->tty);
|
|
|
+ p->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
|
|
|
+ }
|
|
|
+ wake_up_interruptible(&p->open_wait);
|
|
|
+ }
|
|
|
+ p->DCDState = dcd;
|
|
|
+}
|
|
|
|
|
|
- if (MoxaDriverPoll() < 0) {
|
|
|
- mod_timer(&moxaTimer, jiffies + HZ / 50);
|
|
|
- return;
|
|
|
+static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
|
|
|
+ u16 __iomem *ip)
|
|
|
+{
|
|
|
+ struct tty_struct *tty = p->tty;
|
|
|
+ void __iomem *ofsAddr;
|
|
|
+ unsigned int inited = p->asyncflags & ASYNC_INITIALIZED;
|
|
|
+ u16 intr;
|
|
|
+
|
|
|
+ if (tty) {
|
|
|
+ if ((p->statusflags & EMPTYWAIT) &&
|
|
|
+ MoxaPortTxQueue(p) == 0) {
|
|
|
+ p->statusflags &= ~EMPTYWAIT;
|
|
|
+ tty_wakeup(tty);
|
|
|
+ }
|
|
|
+ if ((p->statusflags & LOWWAIT) && !tty->stopped &&
|
|
|
+ MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
|
|
|
+ p->statusflags &= ~LOWWAIT;
|
|
|
+ tty_wakeup(tty);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (inited && !(p->statusflags & THROTTLE) &&
|
|
|
+ MoxaPortRxQueue(p) > 0) { /* RX */
|
|
|
+ MoxaPortReadData(p);
|
|
|
+ tty_schedule_flip(tty);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ p->statusflags &= ~EMPTYWAIT;
|
|
|
+ MoxaPortFlushData(p, 0); /* flush RX */
|
|
|
}
|
|
|
|
|
|
+ if (!handle) /* nothing else to do */
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ intr = readw(ip); /* port irq status */
|
|
|
+ if (intr == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ writew(0, ip); /* ACK port */
|
|
|
+ ofsAddr = p->tableAddr;
|
|
|
+ if (intr & IntrTx) /* disable tx intr */
|
|
|
+ writew(readw(ofsAddr + HostStat) & ~WakeupTx,
|
|
|
+ ofsAddr + HostStat);
|
|
|
+
|
|
|
+ if (!inited)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
|
|
|
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
|
|
|
+ tty_schedule_flip(tty);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (intr & IntrLine)
|
|
|
+ moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void moxa_poll(unsigned long ignored)
|
|
|
+{
|
|
|
+ struct moxa_board_conf *brd;
|
|
|
+ u16 __iomem *ip;
|
|
|
+ unsigned int card, port;
|
|
|
+
|
|
|
+ spin_lock(&moxa_lock);
|
|
|
for (card = 0; card < MAX_BOARDS; card++) {
|
|
|
- if (!moxa_boards[card].ready)
|
|
|
+ brd = &moxa_boards[card];
|
|
|
+ if (!brd->ready)
|
|
|
continue;
|
|
|
- ch = moxa_boards[card].ports;
|
|
|
- for (i = 0; i < moxa_boards[card].numPorts; i++, ch++) {
|
|
|
- if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
|
|
|
- continue;
|
|
|
- if (!(ch->statusflags & THROTTLE) &&
|
|
|
- (MoxaPortRxQueue(ch) > 0))
|
|
|
- moxa_receive_data(ch);
|
|
|
- tty = ch->tty;
|
|
|
- if (tty == NULL)
|
|
|
- continue;
|
|
|
- if (ch->statusflags & LOWWAIT) {
|
|
|
- if (MoxaPortTxQueue(ch) <= WAKEUP_CHARS) {
|
|
|
- if (!tty->stopped) {
|
|
|
- ch->statusflags &= ~LOWWAIT;
|
|
|
- tty_wakeup(tty);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (!I_IGNBRK(tty) && (MoxaPortResetBrkCnt(ch) > 0)) {
|
|
|
- tty_insert_flip_char(tty, 0, TTY_BREAK);
|
|
|
- tty_schedule_flip(tty);
|
|
|
- }
|
|
|
- if (MoxaPortDCDChange(ch)) {
|
|
|
- if (ch->asyncflags & ASYNC_CHECK_CD) {
|
|
|
- if (MoxaPortDCDON(ch))
|
|
|
- wake_up_interruptible(&ch->open_wait);
|
|
|
- else {
|
|
|
- tty_hangup(tty);
|
|
|
- wake_up_interruptible(&ch->open_wait);
|
|
|
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
|
|
|
- }
|
|
|
+
|
|
|
+ ip = NULL;
|
|
|
+ if (readb(brd->intPend) == 0xff)
|
|
|
+ ip = brd->intTable + readb(brd->intNdx);
|
|
|
+
|
|
|
+ for (port = 0; port < brd->numPorts; port++)
|
|
|
+ moxa_poll_port(&brd->ports[port], !!ip, ip + port);
|
|
|
+
|
|
|
+ if (ip)
|
|
|
+ writeb(0, brd->intPend); /* ACK */
|
|
|
+
|
|
|
+ if (moxaLowWaterChk) {
|
|
|
+ struct moxa_port *p = brd->ports;
|
|
|
+ for (port = 0; port < brd->numPorts; port++, p++)
|
|
|
+ if (p->lowChkFlag) {
|
|
|
+ p->lowChkFlag = 0;
|
|
|
+ moxa_low_water_check(p->tableAddr);
|
|
|
}
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
+ moxaLowWaterChk = 0;
|
|
|
+ spin_unlock(&moxa_lock);
|
|
|
|
|
|
mod_timer(&moxaTimer, jiffies + HZ / 50);
|
|
|
}
|
|
@@ -1426,10 +1475,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
|
|
|
|
|
|
ch = (struct moxa_port *) tty->driver_data;
|
|
|
ts = tty->termios;
|
|
|
- if (ts->c_cflag & CLOCAL)
|
|
|
- ch->asyncflags &= ~ASYNC_CHECK_CD;
|
|
|
- else
|
|
|
- ch->asyncflags |= ASYNC_CHECK_CD;
|
|
|
rts = cts = txflow = rxflow = xany = 0;
|
|
|
if (ts->c_cflag & CRTSCTS)
|
|
|
rts = cts = 1;
|
|
@@ -1454,7 +1499,6 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
|
|
|
struct moxa_port *ch)
|
|
|
{
|
|
|
DECLARE_WAITQUEUE(wait,current);
|
|
|
- unsigned long flags;
|
|
|
int retval;
|
|
|
int do_clocal = C_CLOCAL(tty);
|
|
|
|
|
@@ -1489,11 +1533,11 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
|
|
|
add_wait_queue(&ch->open_wait, &wait);
|
|
|
pr_debug("block_til_ready before block: ttys%d, count = %d\n",
|
|
|
tty->index, ch->count);
|
|
|
- spin_lock_irqsave(&moxa_lock, flags);
|
|
|
+ spin_lock_bh(&moxa_lock);
|
|
|
if (!tty_hung_up_p(filp))
|
|
|
ch->count--;
|
|
|
ch->blocked_open++;
|
|
|
- spin_unlock_irqrestore(&moxa_lock, flags);
|
|
|
+ spin_unlock_bh(&moxa_lock);
|
|
|
|
|
|
while (1) {
|
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
@@ -1510,7 +1554,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
|
|
|
break;
|
|
|
}
|
|
|
if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
|
|
|
- MoxaPortDCDON(ch)))
|
|
|
+ ch->DCDState))
|
|
|
break;
|
|
|
|
|
|
if (signal_pending(current)) {
|
|
@@ -1522,11 +1566,11 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
|
|
|
set_current_state(TASK_RUNNING);
|
|
|
remove_wait_queue(&ch->open_wait, &wait);
|
|
|
|
|
|
- spin_lock_irqsave(&moxa_lock, flags);
|
|
|
+ spin_lock_bh(&moxa_lock);
|
|
|
if (!tty_hung_up_p(filp))
|
|
|
ch->count++;
|
|
|
ch->blocked_open--;
|
|
|
- spin_unlock_irqrestore(&moxa_lock, flags);
|
|
|
+ spin_unlock_bh(&moxa_lock);
|
|
|
pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
|
|
|
tty->index, ch->count);
|
|
|
if (retval)
|
|
@@ -1539,28 +1583,10 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
|
|
|
static void moxa_setup_empty_event(struct tty_struct *tty)
|
|
|
{
|
|
|
struct moxa_port *ch = tty->driver_data;
|
|
|
- unsigned long flags;
|
|
|
|
|
|
- spin_lock_irqsave(&moxa_lock, flags);
|
|
|
+ spin_lock_bh(&moxa_lock);
|
|
|
ch->statusflags |= EMPTYWAIT;
|
|
|
- mod_timer(&ch->emptyTimer, jiffies + HZ);
|
|
|
- spin_unlock_irqrestore(&moxa_lock, flags);
|
|
|
-}
|
|
|
-
|
|
|
-static void moxa_check_xmit_empty(unsigned long data)
|
|
|
-{
|
|
|
- struct moxa_port *ch;
|
|
|
-
|
|
|
- ch = (struct moxa_port *) data;
|
|
|
- if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
|
|
|
- if (MoxaPortTxQueue(ch) == 0) {
|
|
|
- ch->statusflags &= ~EMPTYWAIT;
|
|
|
- tty_wakeup(ch->tty);
|
|
|
- return;
|
|
|
- }
|
|
|
- mod_timer(&ch->emptyTimer, round_jiffies(jiffies + HZ));
|
|
|
- } else
|
|
|
- ch->statusflags &= ~EMPTYWAIT;
|
|
|
+ spin_unlock_bh(&moxa_lock);
|
|
|
}
|
|
|
|
|
|
static void moxa_shut_down(struct moxa_port *ch)
|
|
@@ -1583,43 +1609,8 @@ static void moxa_shut_down(struct moxa_port *ch)
|
|
|
ch->asyncflags &= ~ASYNC_INITIALIZED;
|
|
|
}
|
|
|
|
|
|
-static void moxa_receive_data(struct moxa_port *ch)
|
|
|
-{
|
|
|
- struct tty_struct *tp;
|
|
|
- struct ktermios *ts;
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- ts = NULL;
|
|
|
- tp = ch->tty;
|
|
|
- if (tp)
|
|
|
- ts = tp->termios;
|
|
|
- /**************************************************
|
|
|
- if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
|
|
|
- *****************************************************/
|
|
|
- if (!tp || !ts) {
|
|
|
- MoxaPortFlushData(ch, 0);
|
|
|
- return;
|
|
|
- }
|
|
|
- spin_lock_irqsave(&moxa_lock, flags);
|
|
|
- MoxaPortReadData(ch, tp);
|
|
|
- spin_unlock_irqrestore(&moxa_lock, flags);
|
|
|
- tty_schedule_flip(tp);
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Query
|
|
|
- */
|
|
|
-
|
|
|
-#define DCD_changed 0x01
|
|
|
-#define DCD_oldstate 0x80
|
|
|
-
|
|
|
-static int moxaLowWaterChk;
|
|
|
-
|
|
|
-static void moxa_low_water_check(void __iomem *);
|
|
|
-
|
|
|
/*****************************************************************************
|
|
|
* Driver level functions: *
|
|
|
- * 3. MoxaDriverPoll(void); *
|
|
|
*****************************************************************************/
|
|
|
|
|
|
static void MoxaPortFlushData(struct moxa_port *port, int mode)
|
|
@@ -1635,67 +1626,6 @@ static void MoxaPortFlushData(struct moxa_port *port, int mode)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int MoxaDriverPoll(void)
|
|
|
-{
|
|
|
- struct moxa_board_conf *brd;
|
|
|
- struct moxa_port *p;
|
|
|
- void __iomem *ofsAddr;
|
|
|
- void __iomem *ip;
|
|
|
- unsigned int port, ports, card;
|
|
|
- ushort temp;
|
|
|
-
|
|
|
- for (card = 0; card < MAX_BOARDS; card++) {
|
|
|
- brd = &moxa_boards[card];
|
|
|
- if (brd->ready == 0)
|
|
|
- continue;
|
|
|
- if ((ports = brd->numPorts) == 0)
|
|
|
- continue;
|
|
|
- if (readb(brd->intPend) == 0xff) {
|
|
|
- ip = brd->intTable + readb(brd->intNdx);
|
|
|
- p = brd->ports;
|
|
|
- ports <<= 1;
|
|
|
- for (port = 0; port < ports; port += 2, p++) {
|
|
|
- temp = readw(ip + port);
|
|
|
- if (temp == 0)
|
|
|
- continue;
|
|
|
-
|
|
|
- writew(0, ip + port);
|
|
|
- ofsAddr = p->tableAddr;
|
|
|
- if (temp & IntrTx)
|
|
|
- writew(readw(ofsAddr + HostStat) &
|
|
|
- ~WakeupTx, ofsAddr + HostStat);
|
|
|
- if (temp & IntrBreak)
|
|
|
- p->breakCnt++;
|
|
|
-
|
|
|
- if (temp & IntrLine) {
|
|
|
- if (readb(ofsAddr + FlagStat) & DCD_state) {
|
|
|
- if ((p->DCDState & DCD_oldstate) == 0)
|
|
|
- p->DCDState = (DCD_oldstate |
|
|
|
- DCD_changed);
|
|
|
- } else {
|
|
|
- if (p->DCDState & DCD_oldstate)
|
|
|
- p->DCDState = DCD_changed;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- writeb(0, brd->intPend);
|
|
|
- }
|
|
|
- if (moxaLowWaterChk) {
|
|
|
- p = brd->ports;
|
|
|
- for (port = 0; port < ports; port++, p++) {
|
|
|
- if (p->lowChkFlag) {
|
|
|
- p->lowChkFlag = 0;
|
|
|
- ofsAddr = p->tableAddr;
|
|
|
- moxa_low_water_check(ofsAddr);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- moxaLowWaterChk = 0;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/*****************************************************************************
|
|
|
* Port level functions: *
|
|
|
* 2. MoxaPortEnable(int port); *
|
|
@@ -1707,8 +1637,6 @@ static int MoxaDriverPoll(void)
|
|
|
* 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); *
|
|
|
* 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); *
|
|
|
* 12. MoxaPortLineStatus(int port); *
|
|
|
- * 13. MoxaPortDCDChange(int port); *
|
|
|
- * 14. MoxaPortDCDON(int port); *
|
|
|
* 15. MoxaPortFlushData(int port, int mode); *
|
|
|
* 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
|
|
|
* 17. MoxaPortReadData(int port, struct tty_struct *tty); *
|
|
@@ -1755,14 +1683,6 @@ static int MoxaDriverPoll(void)
|
|
|
* -ENOIOCTLCMD
|
|
|
*
|
|
|
*
|
|
|
- * Function 3: Moxa driver polling process routine.
|
|
|
- * Syntax:
|
|
|
- * int MoxaDriverPoll(void);
|
|
|
- *
|
|
|
- * return: 0 ; polling O.K.
|
|
|
- * -1 : no any Moxa card.
|
|
|
- *
|
|
|
- *
|
|
|
* Function 6: Enable this port to start Tx/Rx data.
|
|
|
* Syntax:
|
|
|
* void MoxaPortEnable(int port);
|
|
@@ -1853,25 +1773,6 @@ static int MoxaDriverPoll(void)
|
|
|
* Bit 2 - DCD state (0: off, 1: on)
|
|
|
*
|
|
|
*
|
|
|
- * Function 17: Check the DCD state has changed since the last read
|
|
|
- * of this function.
|
|
|
- * Syntax:
|
|
|
- * int MoxaPortDCDChange(int port);
|
|
|
- * int port : port number (0 - 127)
|
|
|
- *
|
|
|
- * return: 0 : no changed
|
|
|
- * 1 : DCD has changed
|
|
|
- *
|
|
|
- *
|
|
|
- * Function 18: Check ths current DCD state is ON or not.
|
|
|
- * Syntax:
|
|
|
- * int MoxaPortDCDON(int port);
|
|
|
- * int port : port number (0 - 127)
|
|
|
- *
|
|
|
- * return: 0 : DCD off
|
|
|
- * 1 : DCD on
|
|
|
- *
|
|
|
- *
|
|
|
* Function 19: Flush the Rx/Tx buffer data of this port.
|
|
|
* Syntax:
|
|
|
* void MoxaPortFlushData(int port, int mode);
|
|
@@ -1954,7 +1855,6 @@ static void MoxaPortEnable(struct moxa_port *port)
|
|
|
|
|
|
ofsAddr = port->tableAddr;
|
|
|
writew(lowwater, ofsAddr + Low_water);
|
|
|
- port->breakCnt = 0;
|
|
|
if (port->board->boardType == MOXA_BOARD_C320_ISA ||
|
|
|
port->board->boardType == MOXA_BOARD_C320_PCI) {
|
|
|
moxafunc(ofsAddr, FC_SetBreakIrq, 0);
|
|
@@ -2123,37 +2023,11 @@ static int MoxaPortLineStatus(struct moxa_port *port)
|
|
|
val = readw(ofsAddr + FlagStat) >> 4;
|
|
|
}
|
|
|
val &= 0x0B;
|
|
|
- if (val & 8) {
|
|
|
+ if (val & 8)
|
|
|
val |= 4;
|
|
|
- if ((port->DCDState & DCD_oldstate) == 0)
|
|
|
- port->DCDState = (DCD_oldstate | DCD_changed);
|
|
|
- } else {
|
|
|
- if (port->DCDState & DCD_oldstate)
|
|
|
- port->DCDState = DCD_changed;
|
|
|
- }
|
|
|
+ moxa_new_dcdstate(port, val & 8);
|
|
|
val &= 7;
|
|
|
- return (val);
|
|
|
-}
|
|
|
-
|
|
|
-static int MoxaPortDCDChange(struct moxa_port *port)
|
|
|
-{
|
|
|
- int n;
|
|
|
-
|
|
|
- n = port->DCDState;
|
|
|
- port->DCDState &= ~DCD_changed;
|
|
|
- n &= DCD_changed;
|
|
|
- return (n);
|
|
|
-}
|
|
|
-
|
|
|
-static int MoxaPortDCDON(struct moxa_port *port)
|
|
|
-{
|
|
|
- int n;
|
|
|
-
|
|
|
- if (port->DCDState & DCD_oldstate)
|
|
|
- n = 1;
|
|
|
- else
|
|
|
- n = 0;
|
|
|
- return (n);
|
|
|
+ return val;
|
|
|
}
|
|
|
|
|
|
static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
|
|
@@ -2221,8 +2095,9 @@ static int MoxaPortWriteData(struct moxa_port *port, unsigned char *buffer,
|
|
|
return (total);
|
|
|
}
|
|
|
|
|
|
-static int MoxaPortReadData(struct moxa_port *port, struct tty_struct *tty)
|
|
|
+static int MoxaPortReadData(struct moxa_port *port)
|
|
|
{
|
|
|
+ struct tty_struct *tty = port->tty;
|
|
|
register ushort head, pageofs;
|
|
|
int i, count, cnt, len, total, remain;
|
|
|
ushort tail, rx_mask, spage, epage;
|
|
@@ -2243,7 +2118,7 @@ static int MoxaPortReadData(struct moxa_port *port, struct tty_struct *tty)
|
|
|
|
|
|
total = count;
|
|
|
remain = count - total;
|
|
|
- moxaLog.rxcnt[port->tty->index] += total;
|
|
|
+ moxaLog.rxcnt[tty->index] += total;
|
|
|
count = total;
|
|
|
if (spage == epage) {
|
|
|
bufhead = readw(ofsAddr + Ofs_rxb);
|
|
@@ -2341,15 +2216,6 @@ static void MoxaPortTxEnable(struct moxa_port *port)
|
|
|
moxafunc(port->tableAddr, FC_SetXonState, Magic_code);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int MoxaPortResetBrkCnt(struct moxa_port *port)
|
|
|
-{
|
|
|
- ushort cnt;
|
|
|
- cnt = port->breakCnt;
|
|
|
- port->breakCnt = 0;
|
|
|
- return (cnt);
|
|
|
-}
|
|
|
-
|
|
|
static int moxa_get_serial_info(struct moxa_port *info,
|
|
|
struct serial_struct __user *retinfo)
|
|
|
{
|
|
@@ -2413,21 +2279,6 @@ static int moxa_set_serial_info(struct moxa_port *info,
|
|
|
* Static local functions: *
|
|
|
*****************************************************************************/
|
|
|
|
|
|
-static void moxa_low_water_check(void __iomem *ofsAddr)
|
|
|
-{
|
|
|
- int len;
|
|
|
- ushort rptr, wptr, mask;
|
|
|
-
|
|
|
- if (readb(ofsAddr + FlagStat) & Xoff_state) {
|
|
|
- rptr = readw(ofsAddr + RXrptr);
|
|
|
- wptr = readw(ofsAddr + RXwptr);
|
|
|
- mask = readw(ofsAddr + RX_mask);
|
|
|
- len = (wptr - rptr) & mask;
|
|
|
- if (len <= Low_water)
|
|
|
- moxafunc(ofsAddr, FC_SendXon, 0);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void MoxaSetFifo(struct moxa_port *port, int enable)
|
|
|
{
|
|
|
void __iomem *ofsAddr = port->tableAddr;
|