diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 16:12:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 16:12:24 -0700 |
commit | 94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch) | |
tree | 39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers | |
parent | 5d4e2d08e7fdf7339f84a1c670d296a77e02f881 (diff) | |
parent | 59bd234b72fc29887839d792b7d6c7e8d2a577a6 (diff) |
Merge tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY updates from Greg Kroah-Hartman:
"Here's the big TTY/serial driver pull request for the 3.5-rc1 merge
window.
Nothing major in here, just lots of incremental changes from Alan and
Jiri reworking some tty core things to behave better and to get a more
solid grasp on some of the nasty tty locking issues.
There are a few tty and serial driver updates in here as well.
All of this has been in the linux-next releases for a while with no
problems.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
* tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (115 commits)
serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller.
serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width.
serial: bfin_uart: narrow the reboot condition in DMA tx interrupt
serial: bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller.
Revert "serial_core: Update buffer overrun statistics."
tty: hvc_xen: NULL dereference on allocation failure
tty: Fix LED error return
tty: Allow uart_register/unregister/register
tty: move global ldisc idle waitqueue to the individual ldisc
serial8250-em: Add DT support
serial8250-em: clk_get() IS_ERR() error handling fix
serial_core: Update buffer overrun statistics.
tty: drop the pty lock during hangup
cris: fix missing tty arg in wait_event_interruptible_tty call
tty/amiserial: Add missing argument for tty_unlock()
tty_lock: Localise the lock
pty: Lock the devpts bits privately
tty_lock: undo the old tty_lock use on the ctty
serial8250-em: Emma Mobile UART driver V2
Add missing call to uart_update_timeout()
...
Diffstat (limited to 'drivers')
52 files changed, 1759 insertions, 1778 deletions
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index d9f5524593f..8c610fa6782 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -46,7 +46,6 @@ static DEFINE_MUTEX(isdn_mutex); static char *isdn_revision = "$Revision: 1.1.2.3 $"; extern char *isdn_net_revision; -extern char *isdn_tty_revision; #ifdef CONFIG_ISDN_PPP extern char *isdn_ppp_revision; #else @@ -2327,8 +2326,6 @@ static int __init isdn_init(void) dev->chanmap[i] = -1; dev->m_idx[i] = -1; strcpy(dev->num[i], "???"); - init_waitqueue_head(&dev->mdm.info[i].open_wait); - init_waitqueue_head(&dev->mdm.info[i].close_wait); } if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) { printk(KERN_WARNING "isdn: Could not register control devices\n"); @@ -2353,8 +2350,6 @@ static int __init isdn_init(void) strcpy(tmprev, isdn_revision); printk(KERN_NOTICE "ISDN subsystem Rev: %s/", isdn_getrev(tmprev)); - strcpy(tmprev, isdn_tty_revision); - printk("%s/", isdn_getrev(tmprev)); strcpy(tmprev, isdn_net_revision); printk("%s/", isdn_getrev(tmprev)); strcpy(tmprev, isdn_ppp_revision); diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 3831abdbc66..7bc50670d7d 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1,5 +1,4 @@ -/* $Id: isdn_tty.c,v 1.1.2.3 2004/02/10 01:07:13 keil Exp $ - * +/* * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel). * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) @@ -12,6 +11,7 @@ #undef ISDN_TTY_STAT_DEBUG #include <linux/isdn.h> +#include <linux/serial.h> /* ASYNC_* flags */ #include <linux/slab.h> #include <linux/delay.h> #include <linux/mutex.h> @@ -48,9 +48,6 @@ static int bit2si[8] = static int si2bit[8] = {4, 1, 4, 4, 4, 4, 4, 4}; -char *isdn_tty_revision = "$Revision: 1.1.2.3 $"; - - /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb() * to stuff incoming data directly into a tty's flip-buffer. This * is done to speed up tty-receiving if the receive-queue is empty. @@ -68,49 +65,54 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb) struct tty_struct *tty; char last; - if (info->online) { - if ((tty = info->tty)) { - if (info->mcr & UART_MCR_RTS) { - len = skb->len + if (!info->online) + return 0; + + tty = info->port.tty; + if (!tty) + return 0; + + if (!(info->mcr & UART_MCR_RTS)) + return 0; + + len = skb->len #ifdef CONFIG_ISDN_AUDIO - + ISDN_AUDIO_SKB_DLECOUNT(skb) + + ISDN_AUDIO_SKB_DLECOUNT(skb) #endif - ; + ; + + c = tty_buffer_request_room(tty, len); + if (c < len) + return 0; - c = tty_buffer_request_room(tty, len); - if (c >= len) { -#ifdef CONFIG_ISDN_AUDIO - if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { - int l = skb->len; - unsigned char *dp = skb->data; - while (--l) { - if (*dp == DLE) - tty_insert_flip_char(tty, DLE, 0); - tty_insert_flip_char(tty, *dp++, 0); - } - if (*dp == DLE) - tty_insert_flip_char(tty, DLE, 0); - last = *dp; - } else { -#endif - if (len > 1) - tty_insert_flip_string(tty, skb->data, len - 1); - last = skb->data[len - 1]; #ifdef CONFIG_ISDN_AUDIO - } + if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { + int l = skb->len; + unsigned char *dp = skb->data; + while (--l) { + if (*dp == DLE) + tty_insert_flip_char(tty, DLE, 0); + tty_insert_flip_char(tty, *dp++, 0); + } + if (*dp == DLE) + tty_insert_flip_char(tty, DLE, 0); + last = *dp; + } else { #endif - if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) - tty_insert_flip_char(tty, last, 0xFF); - else - tty_insert_flip_char(tty, last, TTY_NORMAL); - tty_flip_buffer_push(tty); - kfree_skb(skb); - return 1; - } - } - } + if (len > 1) + tty_insert_flip_string(tty, skb->data, len - 1); + last = skb->data[len - 1]; +#ifdef CONFIG_ISDN_AUDIO } - return 0; +#endif + if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) + tty_insert_flip_char(tty, last, 0xFF); + else + tty_insert_flip_char(tty, last, TTY_NORMAL); + tty_flip_buffer_push(tty); + kfree_skb(skb); + + return 1; } /* isdn_tty_readmodem() is called periodically from within timer-interrupt. @@ -128,35 +130,39 @@ isdn_tty_readmodem(void) modem_info *info; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - if ((midx = dev->m_idx[i]) >= 0) { - info = &dev->mdm.info[midx]; - if (info->online) { - r = 0; + midx = dev->m_idx[i]; + if (midx < 0) + continue; + + info = &dev->mdm.info[midx]; + if (!info->online) + continue; + + r = 0; #ifdef CONFIG_ISDN_AUDIO - isdn_audio_eval_dtmf(info); - if ((info->vonline & 1) && (info->emu.vpar[1])) - isdn_audio_eval_silence(info); -#endif - if ((tty = info->tty)) { - if (info->mcr & UART_MCR_RTS) { - /* CISCO AsyncPPP Hack */ - if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) - r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); - else - r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); - if (r) - tty_flip_buffer_push(tty); - } else - r = 1; - } else - r = 1; - if (r) { - info->rcvsched = 0; - resched = 1; - } else - info->rcvsched = 1; - } - } + isdn_audio_eval_dtmf(info); + if ((info->vonline & 1) && (info->emu.vpar[1])) + isdn_audio_eval_silence(info); +#endif + tty = info->port.tty; + if (tty) { + if (info->mcr & UART_MCR_RTS) { + /* CISCO AsyncPPP Hack */ + if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) + r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); + else + r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); + if (r) + tty_flip_buffer_push(tty); + } else + r = 1; + } else + r = 1; + if (r) { + info->rcvsched = 0; + resched = 1; + } else + info->rcvsched = 1; } if (!resched) isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 0); @@ -294,7 +300,7 @@ isdn_tty_tint(modem_info *info) len = skb->len; if ((slen = isdn_writebuf_skb_stub(info->isdn_driver, info->isdn_channel, 1, skb)) == len) { - struct tty_struct *tty = info->tty; + struct tty_struct *tty = info->port.tty; info->send_outstanding++; info->msr &= ~UART_MSR_CTS; info->lsr &= ~UART_LSR_TEMT; @@ -327,7 +333,7 @@ isdn_tty_countDLE(unsigned char *buf, int len) static int isdn_tty_handleDLEdown(modem_info *info, atemu *m, int len) { - unsigned char *p = &info->xmit_buf[info->xmit_count]; + unsigned char *p = &info->port.xmit_buf[info->xmit_count]; int count = 0; while (len > 0) { @@ -471,7 +477,7 @@ isdn_tty_senddown(modem_info *info) return; } skb_reserve(skb, skb_res); - memcpy(skb_put(skb, buflen), info->xmit_buf, buflen); + memcpy(skb_put(skb, buflen), info->port.xmit_buf, buflen); info->xmit_count = 0; #ifdef CONFIG_ISDN_AUDIO if (info->vonline & 2) { @@ -699,7 +705,7 @@ isdn_tty_modem_hup(modem_info *info, int local) printk(KERN_DEBUG "Mhup ttyI%d\n", info->line); #endif info->rcvsched = 0; - isdn_tty_flush_buffer(info->tty); + isdn_tty_flush_buffer(info->port.tty); if (info->online) { info->last_lhup = local; info->online = 0; @@ -997,20 +1003,21 @@ isdn_tty_paranoia_check(modem_info *info, char *name, const char *routine) static void isdn_tty_change_speed(modem_info *info) { + struct tty_port *port = &info->port; uint cflag, cval, quot; int i; - if (!info->tty || !info->tty->termios) + if (!port->tty || !port->tty->termios) return; - cflag = info->tty->termios->c_cflag; + cflag = port->tty->termios->c_cflag; quot = i = cflag & CBAUD; if (i & CBAUDEX) { i &= ~CBAUDEX; if (i < 1 || i > 2) - info->tty->termios->c_cflag &= ~CBAUDEX; + port->tty->termios->c_cflag &= ~CBAUDEX; else i += 15; } @@ -1040,20 +1047,20 @@ isdn_tty_change_speed(modem_info *info) /* CTS flow control flag and modem status interrupts */ if (cflag & CRTSCTS) { - info->flags |= ISDN_ASYNC_CTS_FLOW; + port->flags |= ASYNC_CTS_FLOW; } else - info->flags &= ~ISDN_ASYNC_CTS_FLOW; + port->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) - info->flags &= ~ISDN_ASYNC_CHECK_CD; + port->flags &= ~ASYNC_CHECK_CD; else { - info->flags |= ISDN_ASYNC_CHECK_CD; + port->flags |= ASYNC_CHECK_CD; } } static int isdn_tty_startup(modem_info *info) { - if (info->flags & ISDN_ASYNC_INITIALIZED) + if (info->port.flags & ASYNC_INITIALIZED) return 0; isdn_lock_drivers(); #ifdef ISDN_DEBUG_MODEM_OPEN @@ -1063,14 +1070,14 @@ isdn_tty_startup(modem_info *info) * Now, initialize the UART */ info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->port.tty) + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); /* * and set the speed of the serial port */ isdn_tty_change_speed(info); - info->flags |= ISDN_ASYNC_INITIALIZED; + info->port.flags |= ASYNC_INITIALIZED; info->msr |= (UART_MSR_DSR | UART_MSR_CTS); info->send_outstanding = 0; return 0; @@ -1083,14 +1090,14 @@ isdn_tty_startup(modem_info *info) static void isdn_tty_shutdown(modem_info *info) { - if (!(info->flags & ISDN_ASYNC_INITIALIZED)) + if (!(info->port.flags & ASYNC_INITIALIZED)) return; #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line); #endif isdn_unlock_drivers(); info->msr &= ~UART_MSR_RI; - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { + if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { isdn_tty_modem_reset_regs(info, 0); @@ -1100,10 +1107,10 @@ isdn_tty_shutdown(modem_info *info) isdn_tty_modem_hup(info, 1); } } - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->flags &= ~ISDN_ASYNC_INITIALIZED; + info->port.flags &= ~ASYNC_INITIALIZED; } /* isdn_tty_write() is the main send-routine. It is called from the upper @@ -1146,7 +1153,7 @@ isdn_tty_write(struct tty_struct *tty, const u_char *buf, int count) isdn_tty_check_esc(buf, m->mdmreg[REG_ESC], c, &(m->pluscount), &(m->lastplus)); - memcpy(&(info->xmit_buf[info->xmit_count]), buf, c); + memcpy(&info->port.xmit_buf[info->xmit_count], buf, c); #ifdef CONFIG_ISDN_AUDIO if (info->vonline) { int cc = isdn_tty_handleDLEdown(info, m, c); @@ -1478,107 +1485,6 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) * isdn_tty_open() and friends * ------------------------------------------------------------ */ -static int -isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *info) -{ - DECLARE_WAITQUEUE(wait, NULL); - int do_clocal = 0; - int retval; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ISDN_ASYNC_CLOSING)) { - if (info->flags & ISDN_ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef MODEM_DO_RESTART - if (info->flags & ISDN_ASYNC_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; -#else - return -EAGAIN; -#endif - } - /* - * If non-blocking mode is set, then make the check up front - * and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) - return -EBUSY; - info->flags |= ISDN_ASYNC_NORMAL_ACTIVE; - return 0; - } - if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) { - if (info->normal_termios.c_cflag & CLOCAL) - do_clocal = 1; - } else { - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - } - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * isdn_tty_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef ISDN_DEBUG_MODEM_OPEN - printk(KERN_DEBUG "isdn_tty_block_til_ready before block: ttyi%d, count = %d\n", - info->line, info->count); -#endif - if (!(tty_hung_up_p(filp))) - info->count--; - info->blocked_open++; - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ISDN_ASYNC_INITIALIZED)) { -#ifdef MODEM_DO_RESTART - if (info->flags & ISDN_ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) && - !(info->flags & ISDN_ASYNC_CLOSING) && - (do_clocal || (info->msr & UART_MSR_DCD))) { - break; - } - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef ISDN_DEBUG_MODEM_OPEN - printk(KERN_DEBUG "isdn_tty_block_til_ready blocking: ttyi%d, count = %d\n", - info->line, info->count); -#endif - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) - info->count++; - info->blocked_open--; -#ifdef ISDN_DEBUG_MODEM_OPEN - printk(KERN_DEBUG "isdn_tty_block_til_ready after blocking: ttyi%d, count = %d\n", - info->line, info->count); -#endif - if (retval) - return retval; - info->flags |= ISDN_ASYNC_NORMAL_ACTIVE; - return 0; -} /* * This routine is called whenever a serial port is opened. It @@ -1589,23 +1495,22 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info * static int isdn_tty_open(struct tty_struct *tty, struct file *filp) { + struct tty_port *port; modem_info *info; int retval; info = &dev->mdm.info[tty->index]; if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) return -ENODEV; - if (!try_module_get(info->owner)) { - printk(KERN_WARNING "%s: cannot reserve module\n", __func__); - return -ENODEV; - } + port = &info->port; #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, - info->count); + port->count); #endif - info->count++; + port->count++; tty->driver_data = info; - info->tty = tty; + port->tty = tty; + tty->port = port; /* * Start up serial port */ @@ -1614,15 +1519,13 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp) #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_open return after startup\n"); #endif - module_put(info->owner); return retval; } - retval = isdn_tty_block_til_ready(tty, filp, info); + retval = tty_port_block_til_ready(port, tty, filp); if (retval) { #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n"); #endif - module_put(info->owner); return retval; } #ifdef ISDN_DEBUG_MODEM_OPEN @@ -1639,6 +1542,7 @@ static void isdn_tty_close(struct tty_struct *tty, struct file *filp) { modem_info *info = (modem_info *) tty->driver_data; + struct tty_port *port = &info->port; ulong timeout; if (!info || isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close")) @@ -1649,7 +1553,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) #endif return; } - if ((tty->count == 1) && (info->count != 1)) { + if ((tty->count == 1) && (port->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. Info->count should always @@ -1658,30 +1562,21 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) * serial port won't be shutdown. */ printk(KERN_ERR "isdn_tty_close: bad port count; tty->count is 1, " - "info->count is %d\n", info->count); - info->count = 1; + "info->count is %d\n", port->count); + port->count = 1; } - if (--info->count < 0) { + if (--port->count < 0) { printk(KERN_ERR "isdn_tty_close: bad port count for ttyi%d: %d\n", - info->line, info->count); - info->count = 0; + info->line, port->count); + port->count = 0; } - if (info->count) { + if (port->count) { #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); #endif - module_put(info->owner); return; } - info->flags |= ISDN_ASYNC_CLOSING; - /* - * Save the termios structure, since this port may have - * separate termios for callout and dialin. - */ - if (info->flags & ISDN_ASYNC_NORMAL_ACTIVE) - info->normal_termios = *tty->termios; - if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) - info->callout_termios = *tty->termios; + port->flags |= ASYNC_CLOSING; tty->closing = 1; /* @@ -1690,7 +1585,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) * interrupt driver to stop checking the data ready bit in the * line status register. */ - if (info->flags & ISDN_ASYNC_INITIALIZED) { + if (port->flags & ASYNC_INITIALIZED) { tty_wait_until_sent_from_close(tty, 3000); /* 30 seconds timeout */ /* * Before we drop DTR, make sure the UART transmitter @@ -1708,16 +1603,10 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) isdn_tty_shutdown(info); isdn_tty_flush_buffer(tty); tty_ldisc_flush(tty); - info->tty = NULL; + port->tty = NULL; info->ncarrier = 0; - tty->closing = 0; - module_put(info->owner); - if (info->blocked_open) { - msleep_interruptible(500); - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); + + tty_port_close_end(port, tty); #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_close normal exit\n"); #endif @@ -1730,14 +1619,15 @@ static void isdn_tty_hangup(struct tty_struct *tty) { modem_info *info = (modem_info *) tty->driver_data; + struct tty_port *port = &info->port; if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_hangup")) return; isdn_tty_shutdown(info); - info->count = 0; - info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE); - info->tty = NULL; - wake_up_interruptible(&info->open_wait); + port->count = 0; + port->flags &= ~ASYNC_NORMAL_ACTIVE; + port->tty = NULL; + wake_up_interruptible(&port->open_wait); } /* This routine initializes all emulator-data. @@ -1864,6 +1754,16 @@ static const struct tty_operations modem_ops = { .tiocmset = isdn_tty_tiocmset, }; +static int isdn_tty_carrier_raised(struct tty_port *port) +{ + modem_info *info = container_of(port, modem_info, port); + return info->msr & UART_MSR_DCD; +} + +static const struct tty_port_operations isdn_tty_port_ops = { + .carrier_raised = isdn_tty_carrier_raised, +}; + int isdn_tty_modem_init(void) { @@ -1899,9 +1799,8 @@ isdn_tty_modem_init(void) goto err_unregister; } #endif -#ifdef MODULE - info->owner = THIS_MODULE; -#endif + tty_port_init(&info->port); + info->port.ops = &isdn_tty_port_ops; spin_lock_init(&info->readlock); sprintf(info->last_cause, "0000"); sprintf(info->last_num, "none"); @@ -1913,12 +1812,7 @@ isdn_tty_modem_init(void) isdn_tty_modem_reset_regs(info, 1); info->magic = ISDN_ASYNC_MAGIC; info->line = i; - info->tty = NULL; info->x_char = 0; - info->count = 0; - info->blocked_open = 0; - init_waitqueue_h |