Commit d450b5a0 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

tty: kref usage for isicom and moxa

Rather than blindly keep taking krefs we reorder the code in a few places
to pass the tty down to the right place (which is important as from the user
side it is not the case that tty == port->tty in all situations). For the irq
and related paths use the krefs to stop the tty being freed under us.
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4a90f09b
...@@ -421,17 +421,16 @@ static void isicom_tx(unsigned long _data) ...@@ -421,17 +421,16 @@ static void isicom_tx(unsigned long _data)
if (retries >= 100) if (retries >= 100)
goto unlock; goto unlock;
tty = tty_port_tty_get(&port->port);
if (tty == NULL)
goto put_unlock;
for (; count > 0; count--, port++) { for (; count > 0; count--, port++) {
/* port not active or tx disabled to force flow control */ /* port not active or tx disabled to force flow control */
if (!(port->port.flags & ASYNC_INITIALIZED) || if (!(port->port.flags & ASYNC_INITIALIZED) ||
!(port->status & ISI_TXOK)) !(port->status & ISI_TXOK))
continue; continue;
tty = port->port.tty;
if (tty == NULL)
continue;
txcount = min_t(short, TX_SIZE, port->xmit_cnt); txcount = min_t(short, TX_SIZE, port->xmit_cnt);
if (txcount <= 0 || tty->stopped || tty->hw_stopped) if (txcount <= 0 || tty->stopped || tty->hw_stopped)
continue; continue;
...@@ -489,6 +488,8 @@ static void isicom_tx(unsigned long _data) ...@@ -489,6 +488,8 @@ static void isicom_tx(unsigned long _data)
tty_wakeup(tty); tty_wakeup(tty);
} }
put_unlock:
tty_kref_put(tty);
unlock: unlock:
spin_unlock_irqrestore(&isi_card[card].card_lock, flags); spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
/* schedule another tx for hopefully in about 10ms */ /* schedule another tx for hopefully in about 10ms */
...@@ -547,7 +548,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) ...@@ -547,7 +548,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
tty = port->port.tty; tty = tty_port_tty_get(&port->port);
if (tty == NULL) { if (tty == NULL) {
word_count = byte_count >> 1; word_count = byte_count >> 1;
while (byte_count > 1) { while (byte_count > 1) {
...@@ -588,7 +589,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) ...@@ -588,7 +589,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
} }
if (port->port.flags & ASYNC_CTS_FLOW) { if (port->port.flags & ASYNC_CTS_FLOW) {
if (port->port.tty->hw_stopped) { if (tty->hw_stopped) {
if (header & ISI_CTS) { if (header & ISI_CTS) {
port->port.tty->hw_stopped = 0; port->port.tty->hw_stopped = 0;
/* start tx ing */ /* start tx ing */
...@@ -597,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) ...@@ -597,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
tty_wakeup(tty); tty_wakeup(tty);
} }
} else if (!(header & ISI_CTS)) { } else if (!(header & ISI_CTS)) {
port->port.tty->hw_stopped = 1; tty->hw_stopped = 1;
/* stop tx ing */ /* stop tx ing */
port->status &= ~(ISI_TXOK | ISI_CTS); port->status &= ~(ISI_TXOK | ISI_CTS);
} }
...@@ -660,24 +661,21 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) ...@@ -660,24 +661,21 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
} }
outw(0x0000, base+0x04); /* enable interrupts */ outw(0x0000, base+0x04); /* enable interrupts */
spin_unlock(&card->card_lock); spin_unlock(&card->card_lock);
tty_kref_put(tty);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void isicom_config_port(struct isi_port *port) static void isicom_config_port(struct tty_struct *tty)
{ {
struct isi_port *port = tty->driver_data;
struct isi_board *card = port->card; struct isi_board *card = port->card;
struct tty_struct *tty;
unsigned long baud; unsigned long baud;
unsigned long base = card->base; unsigned long base = card->base;
u16 channel_setup, channel = port->channel, u16 channel_setup, channel = port->channel,
shift_count = card->shift_count; shift_count = card->shift_count;
unsigned char flow_ctrl; unsigned char flow_ctrl;
tty = port->port.tty;
if (tty == NULL)
return;
/* FIXME: Switch to new tty baud API */ /* FIXME: Switch to new tty baud API */
baud = C_BAUD(tty); baud = C_BAUD(tty);
if (baud & CBAUDEX) { if (baud & CBAUDEX) {
...@@ -690,7 +688,7 @@ static void isicom_config_port(struct isi_port *port) ...@@ -690,7 +688,7 @@ static void isicom_config_port(struct isi_port *port)
/* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
if (baud < 1 || baud > 4) if (baud < 1 || baud > 4)
port->port.tty->termios->c_cflag &= ~CBAUDEX; tty->termios->c_cflag &= ~CBAUDEX;
else else
baud += 15; baud += 15;
} }
...@@ -797,8 +795,9 @@ static inline void isicom_setup_board(struct isi_board *bp) ...@@ -797,8 +795,9 @@ static inline void isicom_setup_board(struct isi_board *bp)
spin_unlock_irqrestore(&bp->card_lock, flags); spin_unlock_irqrestore(&bp->card_lock, flags);
} }
static int isicom_setup_port(struct isi_port *port) static int isicom_setup_port(struct tty_struct *tty)
{ {
struct isi_port *port = tty->driver_data;
struct isi_board *card = port->card; struct isi_board *card = port->card;
unsigned long flags; unsigned long flags;
...@@ -808,8 +807,7 @@ static int isicom_setup_port(struct isi_port *port) ...@@ -808,8 +807,7 @@ static int isicom_setup_port(struct isi_port *port)
return -ENOMEM; return -ENOMEM;
spin_lock_irqsave(&card->card_lock, flags); spin_lock_irqsave(&card->card_lock, flags);
if (port->port.tty) clear_bit(TTY_IO_ERROR, &tty->flags);
clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
if (port->port.count == 1) if (port->port.count == 1)
card->count++; card->count++;
...@@ -823,7 +821,7 @@ static int isicom_setup_port(struct isi_port *port) ...@@ -823,7 +821,7 @@ static int isicom_setup_port(struct isi_port *port)
InterruptTheCard(card->base); InterruptTheCard(card->base);
} }
isicom_config_port(port); isicom_config_port(tty);
port->port.flags |= ASYNC_INITIALIZED; port->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&card->card_lock, flags); spin_unlock_irqrestore(&card->card_lock, flags);
...@@ -934,8 +932,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) ...@@ -934,8 +932,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
port->port.count++; port->port.count++;
tty->driver_data = port; tty->driver_data = port;
port->port.tty = tty; tty_port_tty_set(&port->port, tty);
error = isicom_setup_port(port); error = isicom_setup_port(tty);
if (error == 0) if (error == 0)
error = block_til_ready(tty, filp, port); error = block_til_ready(tty, filp, port);
return error; return error;
...@@ -955,15 +953,17 @@ static void isicom_shutdown_port(struct isi_port *port) ...@@ -955,15 +953,17 @@ static void isicom_shutdown_port(struct isi_port *port)
struct isi_board *card = port->card; struct isi_board *card = port->card;
struct tty_struct *tty; struct tty_struct *tty;
tty = port->port.tty; tty = tty_port_tty_get(&port->port);
if (!(port->port.flags & ASYNC_INITIALIZED)) if (!(port->port.flags & ASYNC_INITIALIZED)) {
tty_kref_put(tty);
return; return;
}
tty_port_free_xmit_buf(&port->port); tty_port_free_xmit_buf(&port->port);
port->port.flags &= ~ASYNC_INITIALIZED; port->port.flags &= ~ASYNC_INITIALIZED;
/* 3rd October 2000 : Vinayak P Risbud */ /* 3rd October 2000 : Vinayak P Risbud */
port->port.tty = NULL; tty_port_tty_set(&port->port, NULL);
/*Fix done by Anil .S on 30-04-2001 /*Fix done by Anil .S on 30-04-2001
remote login through isi port has dtr toggle problem remote login through isi port has dtr toggle problem
...@@ -1243,9 +1243,10 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file, ...@@ -1243,9 +1243,10 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
return 0; return 0;
} }
static int isicom_set_serial_info(struct isi_port *port, static int isicom_set_serial_info(struct tty_struct *tty,
struct serial_struct __user *info) struct serial_struct __user *info)
{ {
struct isi_port *port = tty->driver_data;
struct serial_struct newinfo; struct serial_struct newinfo;
int reconfig_port; int reconfig_port;
...@@ -1276,7 +1277,7 @@ static int isicom_set_serial_info(struct isi_port *port, ...@@ -1276,7 +1277,7 @@ static int isicom_set_serial_info(struct isi_port *port,
if (reconfig_port) { if (reconfig_port) {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&port->card->card_lock, flags); spin_lock_irqsave(&port->card->card_lock, flags);
isicom_config_port(port); isicom_config_port(tty);
spin_unlock_irqrestore(&port->card->card_lock, flags); spin_unlock_irqrestore(&port->card->card_lock, flags);
} }
unlock_kernel(); unlock_kernel();
...@@ -1318,7 +1319,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp, ...@@ -1318,7 +1319,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
return isicom_get_serial_info(port, argp); return isicom_get_serial_info(port, argp);
case TIOCSSERIAL: case TIOCSSERIAL:
return isicom_set_serial_info(port, argp); return isicom_set_serial_info(tty, argp);
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
...@@ -1341,7 +1342,7 @@ static void isicom_set_termios(struct tty_struct *tty, ...@@ -1341,7 +1342,7 @@ static void isicom_set_termios(struct tty_struct *tty,
return; return;
spin_lock_irqsave(&port->card->card_lock, flags); spin_lock_irqsave(&port->card->card_lock, flags);
isicom_config_port(port); isicom_config_port(tty);
spin_unlock_irqrestore(&port->card->card_lock, flags); spin_unlock_irqrestore(&port->card->card_lock, flags);
if ((old_termios->c_cflag & CRTSCTS) && if ((old_termios->c_cflag & CRTSCTS) &&
...@@ -1419,7 +1420,7 @@ static void isicom_hangup(struct tty_struct *tty) ...@@ -1419,7 +1420,7 @@ static void isicom_hangup(struct tty_struct *tty)
port->port.count = 0; port->port.count = 0;
port->port.flags &= ~ASYNC_NORMAL_ACTIVE; port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
port->port.tty = NULL; tty_port_tty_set(&port->port, NULL);
wake_up_interruptible(&port->port.open_wait); wake_up_interruptible(&port->port.open_wait);
} }
......
...@@ -205,7 +205,7 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, ...@@ -205,7 +205,7 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
static void moxa_poll(unsigned long); static void moxa_poll(unsigned long);
static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
static void moxa_setup_empty_event(struct tty_struct *); static void moxa_setup_empty_event(struct tty_struct *);
static void moxa_shut_down(struct moxa_port *); static void moxa_shut_down(struct tty_struct *);
/* /*
* moxa board interface functions: * moxa board interface functions:
*/ */
...@@ -217,7 +217,7 @@ static void MoxaPortLineCtrl(struct moxa_port *, int, int); ...@@ -217,7 +217,7 @@ static void MoxaPortLineCtrl(struct moxa_port *, int, int);
static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
static int MoxaPortLineStatus(struct moxa_port *); static int MoxaPortLineStatus(struct moxa_port *);
static void MoxaPortFlushData(struct moxa_port *, int); static void MoxaPortFlushData(struct moxa_port *, int);
static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int); static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int);
static int MoxaPortReadData(struct moxa_port *); static int MoxaPortReadData(struct moxa_port *);
static int MoxaPortTxQueue(struct moxa_port *); static int MoxaPortTxQueue(struct moxa_port *);
static int MoxaPortRxQueue(struct moxa_port *); static int MoxaPortRxQueue(struct moxa_port *);
...@@ -332,6 +332,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, ...@@ -332,6 +332,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
for (i = 0; i < MAX_BOARDS; i++) { for (i = 0; i < MAX_BOARDS; i++) {
p = moxa_boards[i].ports; p = moxa_boards[i].ports;
for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
struct tty_struct *ttyp;
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
if (!moxa_boards[i].ready) if (!moxa_boards[i].ready)
goto copy; goto copy;
...@@ -344,10 +345,12 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, ...@@ -344,10 +345,12 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
if (status & 4) if (status & 4)
tmp.dcd = 1; tmp.dcd = 1;
if (!p->port.tty || !p->port.tty->termios) ttyp = tty_port_tty_get(&p->port);
if (!ttyp || !ttyp->termios)
tmp.cflag = p->cflag; tmp.cflag = p->cflag;
else else
tmp.cflag = p->port.tty->termios->c_cflag; tmp.cflag = ttyp->termios->c_cflag;
tty_kref_put(tty);
copy: copy:
if (copy_to_user(argm, &tmp, sizeof(tmp))) { if (copy_to_user(argm, &tmp, sizeof(tmp))) {
mutex_unlock(&moxa_openlock); mutex_unlock(&moxa_openlock);
...@@ -880,8 +883,14 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) ...@@ -880,8 +883,14 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
/* pci hot-un-plug support */ /* pci hot-un-plug support */
for (a = 0; a < brd->numPorts; a++) for (a = 0; a < brd->numPorts; a++)
if (brd->ports[a].port.flags & ASYNC_INITIALIZED) if (brd->ports[a].port.flags & ASYNC_INITIALIZED) {
tty_hangup(brd->ports[a].port.tty); struct tty_struct *tty = tty_port_tty_get(
&brd->ports[a].port);
if (tty) {
tty_hangup(tty);
tty_kref_put(tty);
}
}
while (1) { while (1) {
opened = 0; opened = 0;
for (a = 0; a < brd->numPorts; a++) for (a = 0; a < brd->numPorts; a++)
...@@ -1096,13 +1105,14 @@ static void __exit moxa_exit(void) ...@@ -1096,13 +1105,14 @@ static void __exit moxa_exit(void)
module_init(moxa_init); module_init(moxa_init);
module_exit(moxa_exit); module_exit(moxa_exit);
static void moxa_close_port(struct moxa_port *ch) static void moxa_close_port(struct tty_struct *tty)
{ {
moxa_shut_down(ch); struct moxa_port *ch = tty->driver_data;
moxa_shut_down(tty);
MoxaPortFlushData(ch, 2); MoxaPortFlushData(ch, 2);
ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
ch->port.tty->driver_data = NULL; tty->driver_data = NULL;
ch->port.tty = NULL; tty_port_tty_set(&ch->port, NULL);
} }
static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
...@@ -1161,7 +1171,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) ...@@ -1161,7 +1171,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
ch->port.count++; ch->port.count++;
tty->driver_data = ch; tty->driver_data = ch;
ch->port.tty = tty; tty_port_tty_set(&ch->port, tty);
if (!(ch->port.flags & ASYNC_INITIALIZED)) { if (!(ch->port.flags & ASYNC_INITIALIZED)) {
ch->statusflags = 0; ch->statusflags = 0;
moxa_set_tty_param(tty, tty->termios); moxa_set_tty_param(tty, tty->termios);
...@@ -1179,7 +1189,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) ...@@ -1179,7 +1189,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
if (retval) { if (retval) {
if (ch->port.count) /* 0 means already hung up... */ if (ch->port.count) /* 0 means already hung up... */
if (--ch->port.count == 0) if (--ch->port.count == 0)
moxa_close_port(ch); moxa_close_port(tty);
} else } else
ch->port.flags |= ASYNC_NORMAL_ACTIVE; ch->port.flags |= ASYNC_NORMAL_ACTIVE;
mutex_unlock(&moxa_openlock); mutex_unlock(&moxa_openlock);
...@@ -1219,7 +1229,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) ...@@ -1219,7 +1229,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
} }
moxa_close_port(ch); moxa_close_port(tty);
unlock: unlock:
mutex_unlock(&moxa_openlock); mutex_unlock(&moxa_openlock);
} }
...@@ -1234,7 +1244,7 @@ static int moxa_write(struct tty_struct *tty, ...@@ -1234,7 +1244,7 @@ static int moxa_write(struct tty_struct *tty,
return 0; return 0;
spin_lock_bh(&moxa_lock); spin_lock_bh(&moxa_lock);
len = MoxaPortWriteData(ch, buf, count); len = MoxaPortWriteData(tty, buf, count);
spin_unlock_bh(&moxa_lock); spin_unlock_bh(&moxa_lock);
ch->statusflags |= LOWWAIT; ch->statusflags |= LOWWAIT;
...@@ -1409,7 +1419,7 @@ static void moxa_hangup(struct tty_struct *tty) ...@@ -1409,7 +1419,7 @@ static void moxa_hangup(struct tty_struct *tty)
return; return;
} }
ch->port.count = 0; ch->port.count = 0;
moxa_close_port(ch); moxa_close_port(tty);
mutex_unlock(&moxa_openlock); mutex_unlock(&moxa_openlock);
wake_up_interruptible(&ch->port.open_wait); wake_up_interruptible(&ch->port.open_wait);
...@@ -1417,11 +1427,14 @@ static void moxa_hangup(struct tty_struct *tty) ...@@ -1417,11 +1427,14 @@ static void moxa_hangup(struct tty_struct *tty)
static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
{ {
struct tty_struct *tty;
dcd = !!dcd; dcd = !!dcd;
if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) { if (dcd != p->DCDState) {
if (!dcd) tty = tty_port_tty_get(&p->port);
tty_hangup(p->port.tty); if (tty && C_CLOCAL(tty) && !dcd)
tty_hangup(tty);
tty_kref_put(tty);
} }
p->DCDState = dcd; p->DCDState = dcd;
} }
...@@ -1429,7 +1442,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) ...@@ -1429,7 +1442,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
static int moxa_poll_port(struct moxa_port *p, unsigned int handle, static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
u16 __iomem *ip) u16 __iomem *ip)
{ {
struct tty_struct *tty = p->port.tty; struct tty_struct *tty = tty_port_tty_get(&p->port);
void __iomem *ofsAddr; void __iomem *ofsAddr;
unsigned int inited = p->port.flags & ASYNC_INITIALIZED; unsigned int inited = p->port.flags & ASYNC_INITIALIZED;
u16 intr; u16 intr;
...@@ -1476,6 +1489,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, ...@@ -1476,6 +1489,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
tty_insert_flip_char(tty, 0, TTY_BREAK); tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty); tty_schedule_flip(tty);
} }
tty_kref_put(tty);
if (intr & IntrLine) if (intr & IntrLine)
moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
...@@ -1560,9 +1574,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty) ...@@ -1560,9 +1574,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty)
spin_unlock_bh(&moxa_lock); spin_unlock_bh(&moxa_lock);
} }
static void moxa_shut_down(struct moxa_port *ch) static void moxa_shut_down(struct tty_struct *tty)
{ {
struct tty_struct *tp = ch->port.tty; struct moxa_port *ch = tty->driver_data;
if (!(ch->port.flags & ASYNC_INITIALIZED)) if (!(ch->port.flags & ASYNC_INITIALIZED))
return; return;
...@@ -1572,7 +1586,7 @@ static void moxa_shut_down(struct moxa_port *ch) ...@@ -1572,7 +1586,7 @@ static void moxa_shut_down(struct moxa_port *ch)
/* /*
* If we're a modem control device and HUPCL is on, drop RTS & DTR. * If we're a modem control device and HUPCL is on, drop RTS & DTR.
*/ */
if (C_HUPCL(tp)) if (C_HUPCL(tty))
MoxaPortLineCtrl(ch, 0, 0); MoxaPortLineCtrl(ch, 0, 0);
spin_lock_bh(&moxa_lock); spin_lock_bh(&moxa_lock);
...@@ -1953,9 +1967,10 @@ static int MoxaPortLineStatus(struct moxa_port *port) ...@@ -1953,9 +1967,10 @@ static int MoxaPortLineStatus(struct moxa_port *port)
return val; return val;
} }
static int MoxaPortWriteData(struct moxa_port *port, static int MoxaPortWriteData(struct tty_struct *tty,
const unsigned char *buffer, int len) const unsigned char *buffer, int len)
{ {
struct moxa_port *port = tty->driver_data;
void __iomem *baseAddr, *ofsAddr, *ofs; void __iomem *baseAddr, *ofsAddr, *ofs;
unsigned int c, total; unsigned int c, total;
u16 head, tail, tx_mask, spage, epage; u16 head, tail, tx_mask, spage, epage;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment