tty/serial: lay the foundations for the next set of reworks
- Stop drivers calling their own flush method indirectly, it obfuscates code and it will change soon anyway - A few more lock_kernel paths temporarily needed in some driver internal waiting code - Remove private put_char method that does a write call for one char - we have that anyway - Most but not yet all of the termios copy under lock fixing (some has other dependencies to follow) - Note a few locking bugs in drivers found in the process - Kill remaining [ab]users of TIOCG/SSOFTCAR in the driver, these must go to fix the termios locking Signed-off-by: Alan Cox <alan@redhat.com> Cc: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
ac0e4b7d31
commit
978e595f88
@ -1505,8 +1505,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
||||
rs_wait_until_sent(tty, info->timeout);
|
||||
}
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
rs_flush_buffer(tty);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
@ -1539,6 +1538,8 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
return; /* Just in case.... */
|
||||
|
||||
orig_jiffies = jiffies;
|
||||
|
||||
lock_kernel();
|
||||
/*
|
||||
* Set the check interval to be 1/5 of the estimated time to
|
||||
* send a single character, and make it at least 1. The check
|
||||
@ -1579,6 +1580,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
break;
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
unlock_kernel();
|
||||
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
|
||||
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
|
||||
#endif
|
||||
|
@ -2522,6 +2522,7 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
return; /* Just in case.... */
|
||||
|
||||
orig_jiffies = jiffies;
|
||||
lock_kernel();
|
||||
/*
|
||||
* Set the check interval to be 1/5 of the estimated time to
|
||||
* send a single character, and make it at least 1. The check
|
||||
@ -2573,11 +2574,47 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
}
|
||||
/* Run one more char cycle */
|
||||
msleep_interruptible(jiffies_to_msecs(char_time * 5));
|
||||
unlock_kernel();
|
||||
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
|
||||
printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cy_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct cyclades_port *info = tty->driver_data;
|
||||
struct cyclades_card *card;
|
||||
int channel, retval;
|
||||
unsigned long flags;
|
||||
|
||||
#ifdef CY_DEBUG_IO
|
||||
printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
|
||||
#endif
|
||||
|
||||
if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
|
||||
return;
|
||||
|
||||
card = info->card;
|
||||
channel = info->line - card->first_line;
|
||||
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
|
||||
if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
|
||||
buffers as well */
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
|
||||
if (retval != 0) {
|
||||
printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
|
||||
"was %x\n", info->line, retval);
|
||||
}
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
}
|
||||
tty_wakeup(tty);
|
||||
} /* cy_flush_buffer */
|
||||
|
||||
|
||||
/*
|
||||
* This routine is called when a particular tty device is closed.
|
||||
*/
|
||||
@ -2689,8 +2726,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
|
||||
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
cy_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
|
||||
@ -2881,6 +2917,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
|
||||
int char_count;
|
||||
__u32 tx_put, tx_get, tx_bufsize;
|
||||
|
||||
lock_kernel();
|
||||
firm_id = card->base_addr + ID_ADDRESS;
|
||||
zfw_ctrl = card->base_addr +
|
||||
(readl(&firm_id->zfwctrl_addr) & 0xfffff);
|
||||
@ -2898,6 +2935,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
|
||||
printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
|
||||
info->line, info->xmit_cnt + char_count);
|
||||
#endif
|
||||
unlock_kernel();
|
||||
return info->xmit_cnt + char_count;
|
||||
}
|
||||
#endif /* Z_EXT_CHARS_IN_BUFFER */
|
||||
@ -4271,40 +4309,6 @@ static void cy_start(struct tty_struct *tty)
|
||||
}
|
||||
} /* cy_start */
|
||||
|
||||
static void cy_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct cyclades_port *info = tty->driver_data;
|
||||
struct cyclades_card *card;
|
||||
int channel, retval;
|
||||
unsigned long flags;
|
||||
|
||||
#ifdef CY_DEBUG_IO
|
||||
printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
|
||||
#endif
|
||||
|
||||
if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
|
||||
return;
|
||||
|
||||
card = info->card;
|
||||
channel = info->line - card->first_line;
|
||||
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
|
||||
if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
|
||||
buffers as well */
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
|
||||
if (retval != 0) {
|
||||
printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
|
||||
"was %x\n", info->line, retval);
|
||||
}
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
}
|
||||
tty_wakeup(tty);
|
||||
} /* cy_flush_buffer */
|
||||
|
||||
/*
|
||||
* cy_hangup() --- called by tty_hangup() when a hangup is signaled.
|
||||
*/
|
||||
|
@ -157,7 +157,6 @@ static void epca_error(int, char *);
|
||||
static void pc_close(struct tty_struct *, struct file *);
|
||||
static void shutdown(struct channel *);
|
||||
static void pc_hangup(struct tty_struct *);
|
||||
static void pc_put_char(struct tty_struct *, unsigned char);
|
||||
static int pc_write_room(struct tty_struct *);
|
||||
static int pc_chars_in_buffer(struct tty_struct *);
|
||||
static void pc_flush_buffer(struct tty_struct *);
|
||||
@ -459,8 +458,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
|
||||
setup_empty_event(tty, ch);
|
||||
tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
|
||||
}
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
pc_flush_buffer(tty);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
shutdown(ch);
|
||||
@ -532,8 +530,7 @@ static void pc_hangup(struct tty_struct *tty)
|
||||
if ((ch = verifyChannel(tty)) != NULL) {
|
||||
unsigned long flags;
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
pc_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
shutdown(ch);
|
||||
|
||||
@ -645,11 +642,6 @@ static int pc_write(struct tty_struct *tty,
|
||||
return amountCopied;
|
||||
}
|
||||
|
||||
static void pc_put_char(struct tty_struct *tty, unsigned char c)
|
||||
{
|
||||
pc_write(tty, &c, 1);
|
||||
}
|
||||
|
||||
static int pc_write_room(struct tty_struct *tty)
|
||||
{
|
||||
int remain;
|
||||
@ -1035,7 +1027,6 @@ static const struct tty_operations pc_ops = {
|
||||
.flush_buffer = pc_flush_buffer,
|
||||
.chars_in_buffer = pc_chars_in_buffer,
|
||||
.flush_chars = pc_flush_chars,
|
||||
.put_char = pc_put_char,
|
||||
.ioctl = pc_ioctl,
|
||||
.set_termios = pc_set_termios,
|
||||
.stop = pc_stop,
|
||||
|
@ -1994,8 +1994,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
||||
rs_wait_until_sent(tty, info->timeout);
|
||||
}
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
rs_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
info->tty = NULL;
|
||||
|
@ -586,8 +586,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
|
||||
|
||||
port->flags &= ~GS_ACTIVE;
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
gs_flush_buffer(tty);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
|
@ -1012,6 +1012,22 @@ static void isicom_shutdown_port(struct isi_port *port)
|
||||
}
|
||||
}
|
||||
|
||||
static void isicom_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct isi_port *port = tty->driver_data;
|
||||
struct isi_board *card = port->card;
|
||||
unsigned long flags;
|
||||
|
||||
if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
static void isicom_close(struct tty_struct *tty, struct file *filp)
|
||||
{
|
||||
struct isi_port *port = tty->driver_data;
|
||||
@ -1065,8 +1081,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
|
||||
isicom_shutdown_port(port);
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
isicom_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
@ -1447,22 +1462,6 @@ static void isicom_hangup(struct tty_struct *tty)
|
||||
wake_up_interruptible(&port->open_wait);
|
||||
}
|
||||
|
||||
/* flush_buffer et all */
|
||||
static void isicom_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct isi_port *port = tty->driver_data;
|
||||
struct isi_board *card = port->card;
|
||||
unsigned long flags;
|
||||
|
||||
if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
/*
|
||||
* Driver init and deinit functions
|
||||
|
@ -1280,6 +1280,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
|
||||
*/
|
||||
if (ch == NULL)
|
||||
return 0;
|
||||
lock_kernel();
|
||||
chars = MoxaPortTxQueue(ch);
|
||||
if (chars) {
|
||||
/*
|
||||
@ -1289,6 +1290,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
|
||||
if (!(ch->statusflags & EMPTYWAIT))
|
||||
moxa_setup_empty_event(tty);
|
||||
}
|
||||
unlock_kernel();
|
||||
return chars;
|
||||
}
|
||||
|
||||
|
@ -927,6 +927,27 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mxser_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct mxser_port *info = tty->driver_data;
|
||||
char fcr;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
spin_lock_irqsave(&info->slock, flags);
|
||||
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
|
||||
|
||||
fcr = inb(info->ioaddr + UART_FCR);
|
||||
outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
|
||||
info->ioaddr + UART_FCR);
|
||||
outb(fcr, info->ioaddr + UART_FCR);
|
||||
|
||||
spin_unlock_irqrestore(&info->slock, flags);
|
||||
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine is called when the serial port gets closed. First, we
|
||||
* wait for the last remaining data to be sent. Then, we unlink its
|
||||
@ -1013,9 +1034,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
|
||||
}
|
||||
mxser_shutdown(info);
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
|
||||
mxser_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
tty->closing = 0;
|
||||
@ -1142,26 +1161,6 @@ static int mxser_chars_in_buffer(struct tty_struct *tty)
|
||||
return info->xmit_cnt;
|
||||
}
|
||||
|
||||
static void mxser_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct mxser_port *info = tty->driver_data;
|
||||
char fcr;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
spin_lock_irqsave(&info->slock, flags);
|
||||
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
|
||||
|
||||
fcr = inb(info->ioaddr + UART_FCR);
|
||||
outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
|
||||
info->ioaddr + UART_FCR);
|
||||
outb(fcr, info->ioaddr + UART_FCR);
|
||||
|
||||
spin_unlock_irqrestore(&info->slock, flags);
|
||||
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------------
|
||||
* friends of mxser_ioctl()
|
||||
@ -1992,6 +1991,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
timeout, char_time);
|
||||
printk("jiff=%lu...", jiffies);
|
||||
#endif
|
||||
lock_kernel();
|
||||
while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) {
|
||||
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
|
||||
printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
|
||||
@ -2003,6 +2003,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
break;
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
unlock_kernel();
|
||||
|
||||
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
|
||||
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
|
||||
|
@ -1724,6 +1724,8 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file)
|
||||
const struct ctrl_dl *ctrl_dl = &port->ctrl_dl;
|
||||
const struct ctrl_ul *ctrl_ul = &port->ctrl_ul;
|
||||
|
||||
/* Note: these could change under us but it is not clear this
|
||||
matters if so */
|
||||
return (ctrl_ul->RTS ? TIOCM_RTS : 0) |
|
||||
(ctrl_ul->DTR ? TIOCM_DTR : 0) |
|
||||
(ctrl_dl->DCD ? TIOCM_CAR : 0) |
|
||||
@ -1849,16 +1851,6 @@ static void ntty_throttle(struct tty_struct *tty)
|
||||
spin_unlock_irqrestore(&dc->spin_mutex, flags);
|
||||
}
|
||||
|
||||
/* just to discard single character writes */
|
||||
static void ntty_put_char(struct tty_struct *tty, unsigned char c)
|
||||
{
|
||||
/*
|
||||
* card does not react correct when we write single chars
|
||||
* to the card, so we discard them
|
||||
*/
|
||||
DBG2("PUT CHAR Function: %c", c);
|
||||
}
|
||||
|
||||
/* Returns number of chars in buffer, called by tty layer */
|
||||
static s32 ntty_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
@ -1892,7 +1884,6 @@ static const struct tty_operations tty_ops = {
|
||||
.unthrottle = ntty_unthrottle,
|
||||
.throttle = ntty_throttle,
|
||||
.chars_in_buffer = ntty_chars_in_buffer,
|
||||
.put_char = ntty_put_char,
|
||||
.tiocmget = ntty_tiocmget,
|
||||
.tiocmset = ntty_tiocmset,
|
||||
};
|
||||
|
@ -503,20 +503,9 @@ static void* mgslpc_get_text_ptr(void)
|
||||
* The wrappers maintain line discipline references
|
||||
* while calling into the line discipline.
|
||||
*
|
||||
* ldisc_flush_buffer - flush line discipline receive buffers
|
||||
* ldisc_receive_buf - pass receive data to line discipline
|
||||
*/
|
||||
|
||||
static void ldisc_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct tty_ldisc *ld = tty_ldisc_ref(tty);
|
||||
if (ld) {
|
||||
if (ld->flush_buffer)
|
||||
ld->flush_buffer(tty);
|
||||
tty_ldisc_deref(ld);
|
||||
}
|
||||
}
|
||||
|
||||
static void ldisc_receive_buf(struct tty_struct *tty,
|
||||
const __u8 *data, char *flags, int count)
|
||||
{
|
||||
@ -2467,10 +2456,9 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp)
|
||||
if (info->flags & ASYNC_INITIALIZED)
|
||||
mgslpc_wait_until_sent(tty, info->timeout);
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
mgslpc_flush_buffer(tty);
|
||||
|
||||
ldisc_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
shutdown(info);
|
||||
|
||||
|
@ -1015,6 +1015,24 @@ static int rc_open(struct tty_struct * tty, struct file * filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rc_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&riscom_lock, flags);
|
||||
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
|
||||
spin_unlock_irqrestore(&riscom_lock, flags);
|
||||
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
|
||||
static void rc_close(struct tty_struct * tty, struct file * filp)
|
||||
{
|
||||
struct riscom_port *port = (struct riscom_port *) tty->driver_data;
|
||||
@ -1078,8 +1096,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
|
||||
}
|
||||
}
|
||||
rc_shutdown_port(bp, port);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
rc_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
tty->closing = 0;
|
||||
@ -1213,23 +1230,6 @@ static int rc_chars_in_buffer(struct tty_struct *tty)
|
||||
return port->xmit_cnt;
|
||||
}
|
||||
|
||||
static void rc_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&riscom_lock, flags);
|
||||
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
|
||||
spin_unlock_irqrestore(&riscom_lock, flags);
|
||||
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
static int rc_tiocmget(struct tty_struct *tty, struct file *file)
|
||||
{
|
||||
struct riscom_port *port = (struct riscom_port *)tty->driver_data;
|
||||
|
@ -1585,6 +1585,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
jiffies);
|
||||
printk(KERN_INFO "cps=%d...\n", info->cps);
|
||||
#endif
|
||||
lock_kernel();
|
||||
while (1) {
|
||||
txcnt = sGetTxCnt(cp);
|
||||
if (!txcnt) {
|
||||
@ -1612,6 +1613,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
break;
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
unlock_kernel();
|
||||
#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
|
||||
printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
|
||||
#endif
|
||||
|
@ -1674,8 +1674,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
|
||||
if (info->flags & ASYNC_INITIALIZED)
|
||||
tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
cy_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
info->tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
|
@ -1504,6 +1504,27 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sx_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
|
||||
unsigned long flags;
|
||||
struct specialix_board * bp;
|
||||
|
||||
func_enter();
|
||||
|
||||
if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
|
||||
func_exit();
|
||||
return;
|
||||
}
|
||||
|
||||
bp = port_Board(port);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
tty_wakeup(tty);
|
||||
|
||||
func_exit();
|
||||
}
|
||||
|
||||
static void sx_close(struct tty_struct * tty, struct file * filp)
|
||||
{
|
||||
@ -1597,8 +1618,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
|
||||
}
|
||||
|
||||
sx_shutdown_port(bp, port);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
sx_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
tty->closing = 0;
|
||||
@ -1770,28 +1790,6 @@ static int sx_chars_in_buffer(struct tty_struct *tty)
|
||||
}
|
||||
|
||||
|
||||
static void sx_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
|
||||
unsigned long flags;
|
||||
struct specialix_board * bp;
|
||||
|
||||
func_enter();
|
||||
|
||||
if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
|
||||
func_exit();
|
||||
return;
|
||||
}
|
||||
|
||||
bp = port_Board(port);
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
tty_wakeup(tty);
|
||||
|
||||
func_exit();
|
||||
}
|
||||
|
||||
|
||||
static int sx_tiocmget(struct tty_struct *tty, struct file *file)
|
||||
{
|
||||
|
@ -875,6 +875,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
|
||||
timeout = HZ;
|
||||
tend = jiffies + timeout;
|
||||
|
||||
lock_kernel();
|
||||
while (stl_datastate(portp)) {
|
||||
if (signal_pending(current))
|
||||
break;
|
||||
@ -882,6 +883,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
|
||||
if (time_after_eq(jiffies, tend))
|
||||
break;
|
||||
}
|
||||
unlock_kernel();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -3157,8 +3157,7 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
|
||||
if (info->flags & ASYNC_INITIALIZED)
|
||||
mgsl_wait_until_sent(tty, info->timeout);
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
mgsl_flush_buffer(tty);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
@ -3221,7 +3220,8 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
* interval should also be less than the timeout.
|
||||
* Note: use tight timings here to satisfy the NIST-PCTS.
|
||||
*/
|
||||
|
||||
|
||||
lock_kernel();
|
||||
if ( info->params.data_rate ) {
|
||||
char_time = info->timeout/(32 * 5);
|
||||
if (!char_time)
|
||||
@ -3251,6 +3251,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlock_kernel();
|
||||
|
||||
exit:
|
||||
if (debug_level >= DEBUG_LEVEL_INFO)
|
||||
|
@ -771,8 +771,7 @@ static void close(struct tty_struct *tty, struct file *filp)
|
||||
|
||||
if (info->flags & ASYNC_INITIALIZED)
|
||||
wait_until_sent(tty, info->timeout);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
shutdown(info);
|
||||
@ -967,6 +966,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
* Note: use tight timings here to satisfy the NIST-PCTS.
|
||||
*/
|
||||
|
||||
lock_kernel();
|
||||
|
||||
if (info->params.data_rate) {
|
||||
char_time = info->timeout/(32 * 5);
|
||||
if (!char_time)
|
||||
@ -984,6 +985,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
if (timeout && time_after(jiffies, orig_jiffies + timeout))
|
||||
break;
|
||||
}
|
||||
unlock_kernel();
|
||||
|
||||
exit:
|
||||
DBGINFO(("%s wait_until_sent exit\n", info->device_name));
|
||||
|
@ -862,8 +862,7 @@ static void close(struct tty_struct *tty, struct file *filp)
|
||||
if (info->flags & ASYNC_INITIALIZED)
|
||||
wait_until_sent(tty, info->timeout);
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
flush_buffer(tty);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
@ -1119,6 +1118,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
if (sanity_check(info, tty->name, "wait_until_sent"))
|
||||
return;
|
||||
|
||||
lock_kernel();
|
||||
|
||||
if (!(info->flags & ASYNC_INITIALIZED))
|
||||
goto exit;
|
||||
|
||||
@ -1161,6 +1162,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
}
|
||||
|
||||
exit:
|
||||
unlock_kernel();
|
||||
if (debug_level >= DEBUG_LEVEL_INFO)
|
||||
printk("%s(%d):%s wait_until_sent() exit\n",
|
||||
__FILE__,__LINE__, info->device_name );
|
||||
@ -1176,6 +1178,7 @@ static int write_room(struct tty_struct *tty)
|
||||
if (sanity_check(info, tty->name, "write_room"))
|
||||
return 0;
|
||||
|
||||
lock_kernel();
|
||||
if (info->params.mode == MGSL_MODE_HDLC) {
|
||||
ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE;
|
||||
} else {
|
||||
@ -1183,6 +1186,7 @@ static int write_room(struct tty_struct *tty)
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
}
|
||||
unlock_kernel();
|
||||
|
||||
if (debug_level >= DEBUG_LEVEL_INFO)
|
||||
printk("%s(%d):%s write_room()=%d\n",
|
||||
|
@ -1204,7 +1204,7 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver);
|
||||
* not in the foreground, send a SIGTTOU. If the signal is blocked or
|
||||
* ignored, go ahead and perform the operation. (POSIX 7.2)
|
||||
*
|
||||
* Locking: ctrl_lock - FIXME: review this
|
||||
* Locking: ctrl_lock
|
||||
*/
|
||||
|
||||
int tty_check_change(struct tty_struct *tty)
|
||||
|
@ -396,7 +396,7 @@ EXPORT_SYMBOL(tty_termios_hw_change);
|
||||
static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
|
||||
{
|
||||
int canon_change;
|
||||
struct ktermios old_termios = *tty->termios;
|
||||
struct ktermios old_termios;
|
||||
struct tty_ldisc *ld;
|
||||
unsigned long flags;
|
||||
|
||||
@ -408,7 +408,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
|
||||
/* FIXME: we need to decide on some locking/ordering semantics
|
||||
for the set_termios notification eventually */
|
||||
mutex_lock(&tty->termios_mutex);
|
||||
|
||||
old_termios = *tty->termios;
|
||||
*tty->termios = *new_termios;
|
||||
unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
|
||||
canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
|
||||
@ -480,7 +480,9 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
mutex_lock(&tty->termios_mutex);
|
||||
memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
|
||||
mutex_unlock(&tty->termios_mutex);
|
||||
|
||||
if (opt & TERMIOS_TERMIO) {
|
||||
if (user_termio_to_kernel_termios(&tmp_termios,
|
||||
@ -666,12 +668,14 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
|
||||
{
|
||||
struct tchars tmp;
|
||||
|
||||
mutex_lock(&tty->termios_mutex);
|
||||
tmp.t_intrc = tty->termios->c_cc[VINTR];
|
||||
tmp.t_quitc = tty->termios->c_cc[VQUIT];
|
||||
tmp.t_startc = tty->termios->c_cc[VSTART];
|
||||
tmp.t_stopc = tty->termios->c_cc[VSTOP];
|
||||
tmp.t_eofc = tty->termios->c_cc[VEOF];
|
||||
tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
|
||||
mutex_unlock(&tty->termios_mutex);
|
||||
return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
@ -681,12 +685,14 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
|
||||
|
||||
if (copy_from_user(&tmp, tchars, sizeof(tmp)))
|
||||
return -EFAULT;
|
||||
mutex_lock(&tty->termios_mutex);
|
||||
tty->termios->c_cc[VINTR] = tmp.t_intrc;
|
||||
tty->termios->c_cc[VQUIT] = tmp.t_quitc;
|
||||
tty->termios->c_cc[VSTART] = tmp.t_startc;
|
||||
tty->termios->c_cc[VSTOP] = tmp.t_stopc;
|
||||
tty->termios->c_cc[VEOF] = tmp.t_eofc;
|
||||
tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
|
||||
mutex_unlock(&tty->termios_mutex);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -696,6 +702,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
|
||||
{
|
||||
struct ltchars tmp;
|
||||
|
||||
mutex_lock(&tty->termios_mutex);
|
||||
tmp.t_suspc = tty->termios->c_cc[VSUSP];
|
||||
/* what is dsuspc anyway? */
|
||||
tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
|
||||
@ -704,6 +711,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
|
||||
tmp.t_flushc = tty->termios->c_cc[VEOL2];
|
||||
tmp.t_werasc = tty->termios->c_cc[VWERASE];
|
||||
tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
|
||||
mutex_unlock(&tty->termios_mutex);
|
||||
return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
@ -714,6 +722,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
|
||||
if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&tty->termios_mutex);
|
||||
tty->termios->c_cc[VSUSP] = tmp.t_suspc;
|
||||
/* what is dsuspc anyway? */
|
||||
tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
|
||||
@ -722,6 +731,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
|
||||
tty->termios->c_cc[VEOL2] = tmp.t_flushc;
|
||||
tty->termios->c_cc[VWERASE] = tmp.t_werasc;
|
||||
tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
|
||||
mutex_unlock(&tty->termios_mutex);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1708,9 +1708,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
|
||||
}
|
||||
dev->modempoll--;
|
||||
isdn_tty_shutdown(info);
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
isdn_tty_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
info->tty = NULL;
|
||||
info->ncarrier = 0;
|
||||
|
@ -1017,18 +1017,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
||||
tty_wait_until_sent(tty, 0);
|
||||
send_break(info, arg ? arg*(100) : 250);
|
||||
return 0;
|
||||
case TIOCGSOFTCAR:
|
||||
error = put_user(C_CLOCAL(tty) ? 1 : 0,
|
||||
(unsigned long *) arg);
|
||||
if (error)
|
||||
return error;
|
||||
return 0;
|
||||
case TIOCSSOFTCAR:
|
||||
get_user(arg, (unsigned long *) arg);
|
||||
tty->termios->c_cflag =
|
||||
((tty->termios->c_cflag & ~CLOCAL) |
|
||||
(arg ? CLOCAL : 0));
|
||||
return 0;
|
||||
case TIOCGSERIAL:
|
||||
if (access_ok(VERIFY_WRITE, (void *) arg,
|
||||
sizeof(struct serial_struct)))
|
||||
@ -1061,9 +1049,6 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
||||
{
|
||||
struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
|
||||
|
||||
if (tty->termios->c_cflag == old_termios->c_cflag)
|
||||
return;
|
||||
|
||||
change_speed(info);
|
||||
|
||||
if ((old_termios->c_cflag & CRTSCTS) &&
|
||||
@ -1140,8 +1125,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
||||
uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK);
|
||||
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
rs_flush_buffer(tty);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
|
@ -1436,18 +1436,6 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
|
||||
return retval;
|
||||
end_break(info);
|
||||
return 0;
|
||||
case TIOCGSOFTCAR:
|
||||
/* return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); */
|
||||
put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
|
||||
return 0;
|
||||
case TIOCSSOFTCAR:
|
||||
error = get_user(arg, (unsigned int *) arg);
|
||||
if (error)
|
||||
return error;
|
||||
tty->termios->c_cflag =
|
||||
((tty->termios->c_cflag & ~CLOCAL) |
|
||||
(arg ? CLOCAL : 0));
|
||||
return 0;
|
||||
#ifdef maybe
|
||||
case TIOCSERGETLSR: /* Get line status register */
|
||||
return get_lsr_info(info, (unsigned int *) arg);
|
||||
@ -1665,8 +1653,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp)
|
||||
rs_360_wait_until_sent(tty, info->timeout);
|
||||
}
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
rs_360_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
tty->closing = 0;
|
||||
info->event = 0;
|
||||
@ -1717,6 +1704,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
printk("jiff=%lu...", jiffies);
|
||||
#endif
|
||||
|
||||
lock_kernel();
|
||||
/* We go through the loop at least once because we can't tell
|
||||
* exactly when the last character exits the shifter. There can
|
||||
* be at least two characters waiting to be sent after the buffers
|
||||
@ -1745,6 +1733,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
bdp--;
|
||||
} while (bdp->status & BD_SC_READY);
|
||||
current->state = TASK_RUNNING;
|
||||
unlock_kernel();
|
||||
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
|
||||
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
|
||||
#endif
|
||||
|
@ -3581,8 +3581,9 @@ rs_tiocmset(struct tty_struct *tty, struct file *file,
|
||||
unsigned int set, unsigned int clear)
|
||||
{
|
||||
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
lock_kernel();
|
||||
local_irq_save(flags);
|
||||
|
||||
if (clear & TIOCM_RTS)
|
||||
e100_rts(info, 0);
|
||||
@ -3604,7 +3605,7 @@ rs_tiocmset(struct tty_struct *tty, struct file *file,
|
||||
if (set & TIOCM_CD)
|
||||
e100_cd_out(info, 1);
|
||||
|
||||
unlock_kernel();
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3613,8 +3614,10 @@ rs_tiocmget(struct tty_struct *tty, struct file *file)
|
||||
{
|
||||
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
|
||||
unsigned int result;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
lock_kernel();
|
||||
result =
|
||||
(!E100_RTS_GET(info) ? TIOCM_RTS : 0)
|
||||
| (!E100_DTR_GET(info) ? TIOCM_DTR : 0)
|
||||
@ -3623,7 +3626,7 @@ rs_tiocmget(struct tty_struct *tty, struct file *file)
|
||||
| (!E100_CD_GET(info) ? TIOCM_CAR : 0)
|
||||
| (!E100_CTS_GET(info) ? TIOCM_CTS : 0);
|
||||
|
||||
unlock_kernel();
|
||||
local_irq_restore(flags);
|
||||
|
||||
#ifdef SERIAL_DEBUG_IO
|
||||
printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n",
|
||||
@ -3702,10 +3705,6 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
||||
{
|
||||
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
|
||||
|
||||
if (tty->termios->c_cflag == old_termios->c_cflag &&
|
||||
tty->termios->c_iflag == old_termios->c_iflag)
|
||||
return;
|
||||
|
||||
change_speed(info);
|
||||
|
||||
/* Handle turning off CRTSCTS */
|
||||
@ -3808,10 +3807,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
|
||||
#endif
|
||||
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
if (tty->ldisc.flush_buffer)
|
||||
tty->ldisc.flush_buffer(tty);
|
||||
rs_flush_buffer(tty);
|
||||
tty_ldisc_flush_buffer(tty);
|
||||
tty->closing = 0;
|
||||
info->event = 0;
|
||||
info->tty = 0;
|
||||
@ -3885,6 +3882,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
* Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO
|
||||
* R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k)
|
||||
*/
|
||||
lock_kernel();
|
||||
orig_jiffies = jiffies;
|
||||
while (info->xmit.head != info->xmit.tail || /* More in send queue */
|
||||
(*info->ostatusadr & 0x007f) || /* more in FIFO */
|
||||
@ -3901,6 +3899,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
curr_time_usec - info->last_tx_active_usec;
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
unlock_kernel();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1072,18 +1072,6 @@ static int mcfrs_ioctl(struct tty_struct *tty, struct file * file,
|
||||
tty_wait_until_sent(tty, 0);
|
||||
send_break(info, arg ? arg*(HZ/10) : HZ/4);
|
||||
return 0;
|
||||
case TIOCGSOFTCAR:
|
||||
error = put_user(C_CLOCAL(tty) ? 1 : 0,
|
||||
(unsigned long *) arg);
|
||||
if (error)
|
||||
return error;
|
||||
return 0;
|
||||
case TIOCSSOFTCAR:
|
||||
get_user(arg, (unsigned long *) arg);
|
||||
tty->termios->c_cflag =
|
||||
((tty->termios->c_cflag & ~CLOCAL) |
|
||||
(arg ? CLOCAL : 0));
|
||||
return 0;
|
||||
case TIOCGSERIAL:
|
||||
if (access_ok(VERIFY_WRITE, (void *) arg,
|
||||
sizeof(struct serial_struct)))
|
||||
@ -1222,8 +1210,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp)
|
||||
} else
|
||||
#endif
|
||||
shutdown(info);
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
mcfrs_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
tty->closing = 0;
|
||||
@ -1276,6 +1263,8 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
* Note: we have to use pretty tight timings here to satisfy
|
||||
* the NIST-PCTS.
|
||||
*/
|
||||
lock_kernel();
|
||||
|
||||
fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud;
|
||||
char_time = fifo_time / 5;
|
||||
if (char_time == 0)
|
||||
@ -1312,6 +1301,7 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
if (timeout && time_after(jiffies, orig_jiffies + timeout))
|
||||
break;
|
||||
}
|
||||
unlock_kernel();
|
||||
#else
|
||||
/*
|
||||
* For the other coldfire models, assume all data has been sent
|
||||
|
@ -287,6 +287,7 @@ static void netx_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
/* FIXME: Locking needed ? */
|
||||
if (mctrl & TIOCM_RTS) {
|
||||
val = readl(port->membase + UART_RTS_CR);
|
||||
writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR);
|
||||
|
Loading…
x
Reference in New Issue
Block a user