#define MXSERMAJOR 174
#define MXSERCUMAJOR 175
-#define MXSER_EVENT_TXLOW 1
-
#define MXSER_BOARDS 4 /* Max. boards */
#define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */
#define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD)
#define MXSER_ERR_IRQ_CONFLIT -3
#define MXSER_ERR_VECTOR -4
+/*CheckIsMoxaMust return value*/
+#define MOXA_OTHER_UART 0x00
+#define MOXA_MUST_MU150_HWID 0x01
+#define MOXA_MUST_MU860_HWID 0x02
+
#define WAKEUP_CHARS 256
#define UART_MCR_AFE 0x20
struct mxser_mon mon_data;
spinlock_t slock;
- struct work_struct tqueue;
wait_queue_head_t open_wait;
wait_queue_head_t delta_msr_wait;
};
}
}
-static void mxser_do_softint(struct work_struct *work)
-{
- struct mxser_port *info = container_of(work, struct mxser_port, tqueue);
- struct tty_struct *tty = info->tty;
-
- if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event))
- tty_wakeup(tty);
-}
-
static unsigned char mxser_get_msr(int baseaddr, int mode, int port)
{
unsigned char status = 0;
outb(info->IER, info->ioaddr +
UART_IER);
}
- set_bit(MXSER_EVENT_TXLOW, &info->event);
- schedule_work(&info->tqueue); }
+ tty_wakeup(info->tty);
+ }
} else {
if (!(status & UART_MSR_CTS)) {
info->tty->hw_stopped = 1;
if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
if (status & UART_MSR_DCD)
wake_up_interruptible(&port->open_wait);
- schedule_work(&port->tqueue);
}
if (port->flags & ASYNC_CTS_FLOW) {
outb(port->IER, port->ioaddr +
UART_IER);
}
- set_bit(MXSER_EVENT_TXLOW, &port->event);
- schedule_work(&port->tqueue);
+ tty_wakeup(port->tty);
}
} else {
if (!(status & UART_MSR_CTS)) {
int cnt = 0;
int recv_room;
int max = 256;
- unsigned long flags;
-
- spin_lock_irqsave(&port->slock, flags);
recv_room = tty->receive_room;
if ((recv_room == 0) && (!port->ldisc_stop_rx))
mxvar_log.rxcnt[port->tty->index] += cnt;
port->mon_data.rxcnt += cnt;
port->mon_data.up_rxcnt += cnt;
- spin_unlock_irqrestore(&port->slock, flags);
tty_flip_buffer_push(tty);
}
static void mxser_transmit_chars(struct mxser_port *port)
{
int count, cnt;
- unsigned long flags;
-
- spin_lock_irqsave(&port->slock, flags);
if (port->x_char) {
outb(port->x_char, port->ioaddr + UART_TX);
port->mon_data.txcnt++;
port->mon_data.up_txcnt++;
port->icount.tx++;
- goto unlock;
+ return;
}
if (port->xmit_buf == 0)
- goto unlock;
+ return;
if ((port->xmit_cnt <= 0) || port->tty->stopped ||
(port->tty->hw_stopped &&
(!port->board->chip_flag))) {
port->IER &= ~UART_IER_THRI;
outb(port->IER, port->ioaddr + UART_IER);
- goto unlock;
+ return;
}
cnt = port->xmit_cnt;
port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
port->icount.tx += (cnt - port->xmit_cnt);
- if (port->xmit_cnt < WAKEUP_CHARS) {
- set_bit(MXSER_EVENT_TXLOW, &port->event);
- schedule_work(&port->tqueue);
- }
+ if (port->xmit_cnt < WAKEUP_CHARS)
+ tty_wakeup(port->tty);
+
if (port->xmit_cnt <= 0) {
port->IER &= ~UART_IER_THRI;
outb(port->IER, port->ioaddr + UART_IER);
}
-unlock:
- spin_unlock_irqrestore(&port->slock, flags);
}
/*
port = &brd->ports[i];
int_cnt = 0;
+ spin_lock(&port->slock);
do {
iir = inb(port->ioaddr + UART_IIR);
if (iir & UART_IIR_NO_INT)
break;
iir &= MOXA_MUST_IIR_MASK;
- if (!port->tty) {
+ if (!port->tty ||
+ (port->flags & ASYNC_CLOSING) ||
+ !(port->flags &
+ ASYNC_INITIALIZED)) {
status = inb(port->ioaddr + UART_LSR);
outb(0x27, port->ioaddr + UART_FCR);
inb(port->ioaddr + UART_MSR);
mxser_transmit_chars(port);
}
} while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
+ spin_unlock(&port->slock);
}
if (pass_counter++ > MXSER_ISR_PASS_LIMIT)
break; /* Prevent infinite loops */
info->custom_divisor = info->baud_base * 16;
info->close_delay = 5 * HZ / 10;
info->closing_wait = 30 * HZ;
- INIT_WORK(&info->tqueue, mxser_do_softint);
info->normal_termios = mxvar_sdriver->init_termios;
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->delta_msr_wait);
outb(inb(info->ioaddr + UART_IER) & 0xf0,
info->ioaddr + UART_IER);
}
- /*
- * Allocate the IRQ if necessary
- */
- retval = request_irq(brd->irq, mxser_interrupt,
- (brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED :
- IRQF_DISABLED, "mxser", brd);
+ retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser",
+ brd);
if (retval) {
printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
"conflict with another device.\n",