diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:45:05 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:38 -0500 |
commit | 31f35939d1d9bcfb3099b32c67b896d2792603f9 (patch) | |
tree | 39b6ceaf0e7477e0357ff8235814f579adad3f28 | |
parent | c9b3976e3fec266be25c5001a70aa0a890b6c476 (diff) |
tty_port: Add a port level carrier detect operation
This is the first step to generalising the various pieces of waiting logic
duplicated in all sorts of serial drivers.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/esp.c | 61 | ||||
-rw-r--r-- | drivers/char/generic_serial.c | 43 | ||||
-rw-r--r-- | drivers/char/isicom.c | 51 | ||||
-rw-r--r-- | drivers/char/istallion.c | 28 | ||||
-rw-r--r-- | drivers/char/moxa.c | 26 | ||||
-rw-r--r-- | drivers/char/mxser.c | 54 | ||||
-rw-r--r-- | drivers/char/rio/rio_linux.c | 18 | ||||
-rw-r--r-- | drivers/char/riscom8.c | 65 | ||||
-rw-r--r-- | drivers/char/rocket.c | 40 | ||||
-rw-r--r-- | drivers/char/ser_a2232.c | 19 | ||||
-rw-r--r-- | drivers/char/stallion.c | 28 | ||||
-rw-r--r-- | drivers/char/sx.c | 27 | ||||
-rw-r--r-- | drivers/char/synclink.c | 61 | ||||
-rw-r--r-- | drivers/char/synclink_gt.c | 48 | ||||
-rw-r--r-- | drivers/char/synclinkmp.c | 55 | ||||
-rw-r--r-- | drivers/char/tty_port.c | 17 | ||||
-rw-r--r-- | drivers/char/vme_scc.c | 15 | ||||
-rw-r--r-- | include/linux/generic_serial.h | 1 | ||||
-rw-r--r-- | include/linux/tty.h | 9 |
19 files changed, 427 insertions, 239 deletions
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 7f077c0097f6..45ec263ec012 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -2054,6 +2054,15 @@ static void esp_hangup(struct tty_struct *tty) | |||
2054 | wake_up_interruptible(&info->port.open_wait); | 2054 | wake_up_interruptible(&info->port.open_wait); |
2055 | } | 2055 | } |
2056 | 2056 | ||
2057 | static int esp_carrier_raised(struct tty_port *port) | ||
2058 | { | ||
2059 | struct esp_struct *info = container_of(port, struct esp_struct, port); | ||
2060 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); | ||
2061 | if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD) | ||
2062 | return 1; | ||
2063 | return 0; | ||
2064 | } | ||
2065 | |||
2057 | /* | 2066 | /* |
2058 | * ------------------------------------------------------------ | 2067 | * ------------------------------------------------------------ |
2059 | * esp_open() and friends | 2068 | * esp_open() and friends |
@@ -2066,17 +2075,19 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2066 | int retval; | 2075 | int retval; |
2067 | int do_clocal = 0; | 2076 | int do_clocal = 0; |
2068 | unsigned long flags; | 2077 | unsigned long flags; |
2078 | int cd; | ||
2079 | struct tty_port *port = &info->port; | ||
2069 | 2080 | ||
2070 | /* | 2081 | /* |
2071 | * If the device is in the middle of being closed, then block | 2082 | * If the device is in the middle of being closed, then block |
2072 | * until it's done, and then try again. | 2083 | * until it's done, and then try again. |
2073 | */ | 2084 | */ |
2074 | if (tty_hung_up_p(filp) || | 2085 | if (tty_hung_up_p(filp) || |
2075 | (info->port.flags & ASYNC_CLOSING)) { | 2086 | (port->flags & ASYNC_CLOSING)) { |
2076 | if (info->port.flags & ASYNC_CLOSING) | 2087 | if (port->flags & ASYNC_CLOSING) |
2077 | interruptible_sleep_on(&info->port.close_wait); | 2088 | interruptible_sleep_on(&port->close_wait); |
2078 | #ifdef SERIAL_DO_RESTART | 2089 | #ifdef SERIAL_DO_RESTART |
2079 | if (info->port.flags & ASYNC_HUP_NOTIFY) | 2090 | if (port->flags & ASYNC_HUP_NOTIFY) |
2080 | return -EAGAIN; | 2091 | return -EAGAIN; |
2081 | else | 2092 | else |
2082 | return -ERESTARTSYS; | 2093 | return -ERESTARTSYS; |
@@ -2091,7 +2102,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2091 | */ | 2102 | */ |
2092 | if ((filp->f_flags & O_NONBLOCK) || | 2103 | if ((filp->f_flags & O_NONBLOCK) || |
2093 | (tty->flags & (1 << TTY_IO_ERROR))) { | 2104 | (tty->flags & (1 << TTY_IO_ERROR))) { |
2094 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 2105 | port->flags |= ASYNC_NORMAL_ACTIVE; |
2095 | return 0; | 2106 | return 0; |
2096 | } | 2107 | } |
2097 | 2108 | ||
@@ -2101,20 +2112,20 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2101 | /* | 2112 | /* |
2102 | * Block waiting for the carrier detect and the line to become | 2113 | * Block waiting for the carrier detect and the line to become |
2103 | * free (i.e., not in use by the callout). While we are in | 2114 | * free (i.e., not in use by the callout). While we are in |
2104 | * this loop, info->port.count is dropped by one, so that | 2115 | * this loop, port->count is dropped by one, so that |
2105 | * rs_close() knows when to free things. We restore it upon | 2116 | * rs_close() knows when to free things. We restore it upon |
2106 | * exit, either normal or abnormal. | 2117 | * exit, either normal or abnormal. |
2107 | */ | 2118 | */ |
2108 | retval = 0; | 2119 | retval = 0; |
2109 | add_wait_queue(&info->port.open_wait, &wait); | 2120 | add_wait_queue(&port->open_wait, &wait); |
2110 | #ifdef SERIAL_DEBUG_OPEN | 2121 | #ifdef SERIAL_DEBUG_OPEN |
2111 | printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n", | 2122 | printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n", |
2112 | info->line, info->port.count); | 2123 | info->line, port->count); |
2113 | #endif | 2124 | #endif |
2114 | spin_lock_irqsave(&info->lock, flags); | 2125 | spin_lock_irqsave(&info->lock, flags); |
2115 | if (!tty_hung_up_p(filp)) | 2126 | if (!tty_hung_up_p(filp)) |
2116 | info->port.count--; | 2127 | port->count--; |
2117 | info->port.blocked_open++; | 2128 | port->blocked_open++; |
2118 | while (1) { | 2129 | while (1) { |
2119 | if ((tty->termios->c_cflag & CBAUD)) { | 2130 | if ((tty->termios->c_cflag & CBAUD)) { |
2120 | unsigned int scratch; | 2131 | unsigned int scratch; |
@@ -2129,9 +2140,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2129 | } | 2140 | } |
2130 | set_current_state(TASK_INTERRUPTIBLE); | 2141 | set_current_state(TASK_INTERRUPTIBLE); |
2131 | if (tty_hung_up_p(filp) || | 2142 | if (tty_hung_up_p(filp) || |
2132 | !(info->port.flags & ASYNC_INITIALIZED)) { | 2143 | !(port->flags & ASYNC_INITIALIZED)) { |
2133 | #ifdef SERIAL_DO_RESTART | 2144 | #ifdef SERIAL_DO_RESTART |
2134 | if (info->port.flags & ASYNC_HUP_NOTIFY) | 2145 | if (port->flags & ASYNC_HUP_NOTIFY) |
2135 | retval = -EAGAIN; | 2146 | retval = -EAGAIN; |
2136 | else | 2147 | else |
2137 | retval = -ERESTARTSYS; | 2148 | retval = -ERESTARTSYS; |
@@ -2141,11 +2152,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2141 | break; | 2152 | break; |
2142 | } | 2153 | } |
2143 | 2154 | ||
2144 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); | 2155 | cd = tty_port_carrier_raised(port); |
2145 | if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD) | ||
2146 | do_clocal = 1; | ||
2147 | 2156 | ||
2148 | if (!(info->port.flags & ASYNC_CLOSING) && | 2157 | if (!(port->flags & ASYNC_CLOSING) && |
2149 | (do_clocal)) | 2158 | (do_clocal)) |
2150 | break; | 2159 | break; |
2151 | if (signal_pending(current)) { | 2160 | if (signal_pending(current)) { |
@@ -2154,25 +2163,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2154 | } | 2163 | } |
2155 | #ifdef SERIAL_DEBUG_OPEN | 2164 | #ifdef SERIAL_DEBUG_OPEN |
2156 | printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n", | 2165 | printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n", |
2157 | info->line, info->port.count); | 2166 | info->line, port->count); |
2158 | #endif | 2167 | #endif |
2159 | spin_unlock_irqrestore(&info->lock, flags); | 2168 | spin_unlock_irqrestore(&info->lock, flags); |
2160 | schedule(); | 2169 | schedule(); |
2161 | spin_lock_irqsave(&info->lock, flags); | 2170 | spin_lock_irqsave(&info->lock, flags); |
2162 | } | 2171 | } |
2163 | set_current_state(TASK_RUNNING); | 2172 | set_current_state(TASK_RUNNING); |
2164 | remove_wait_queue(&info->port.open_wait, &wait); | 2173 | remove_wait_queue(&port->open_wait, &wait); |
2165 | if (!tty_hung_up_p(filp)) | 2174 | if (!tty_hung_up_p(filp)) |
2166 | info->port.count++; | 2175 | port->count++; |
2167 | info->port.blocked_open--; | 2176 | port->blocked_open--; |
2168 | spin_unlock_irqrestore(&info->lock, flags); | 2177 | spin_unlock_irqrestore(&info->lock, flags); |
2169 | #ifdef SERIAL_DEBUG_OPEN | 2178 | #ifdef SERIAL_DEBUG_OPEN |
2170 | printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n", | 2179 | printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n", |
2171 | info->line, info->port.count); | 2180 | info->line, port->count); |
2172 | #endif | 2181 | #endif |
2173 | if (retval) | 2182 | if (retval) |
2174 | return retval; | 2183 | return retval; |
2175 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 2184 | port->flags |= ASYNC_NORMAL_ACTIVE; |
2176 | return 0; | 2185 | return 0; |
2177 | } | 2186 | } |
2178 | 2187 | ||
@@ -2329,6 +2338,10 @@ static const struct tty_operations esp_ops = { | |||
2329 | .tiocmset = esp_tiocmset, | 2338 | .tiocmset = esp_tiocmset, |
2330 | }; | 2339 | }; |
2331 | 2340 | ||
2341 | static const struct tty_port_operations esp_port_ops = { | ||
2342 | .esp_carrier_raised, | ||
2343 | }; | ||
2344 | |||
2332 | /* | 2345 | /* |
2333 | * The serial driver boot-time initialization code! | 2346 | * The serial driver boot-time initialization code! |
2334 | */ | 2347 | */ |
@@ -2415,6 +2428,8 @@ static int __init espserial_init(void) | |||
2415 | offset = 0; | 2428 | offset = 0; |
2416 | 2429 | ||
2417 | do { | 2430 | do { |
2431 | tty_port_init(&info->port); | ||
2432 | info->port.ops = &esp_port_ops; | ||
2418 | info->io_port = esp[i] + offset; | 2433 | info->io_port = esp[i] + offset; |
2419 | info->irq = irq[i]; | 2434 | info->irq = irq[i]; |
2420 | info->line = (i * 8) + (offset / 8); | 2435 | info->line = (i * 8) + (offset / 8); |
@@ -2437,8 +2452,6 @@ static int __init espserial_init(void) | |||
2437 | info->config.flow_off = flow_off; | 2452 | info->config.flow_off = flow_off; |
2438 | info->config.pio_threshold = pio_threshold; | 2453 | info->config.pio_threshold = pio_threshold; |
2439 | info->next_port = ports; | 2454 | info->next_port = ports; |
2440 | init_waitqueue_head(&info->port.open_wait); | ||
2441 | init_waitqueue_head(&info->port.close_wait); | ||
2442 | init_waitqueue_head(&info->delta_msr_wait); | 2455 | init_waitqueue_head(&info->delta_msr_wait); |
2443 | init_waitqueue_head(&info->break_wait); | 2456 | init_waitqueue_head(&info->break_wait); |
2444 | ports = info; | 2457 | ports = info; |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index c6090f84a2e4..2356994ee010 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c | |||
@@ -397,7 +397,8 @@ void gs_hangup(struct tty_struct *tty) | |||
397 | 397 | ||
398 | int gs_block_til_ready(void *port_, struct file * filp) | 398 | int gs_block_til_ready(void *port_, struct file * filp) |
399 | { | 399 | { |
400 | struct gs_port *port = port_; | 400 | struct gs_port *gp = port_; |
401 | struct tty_port *port = &gp->port; | ||
401 | DECLARE_WAITQUEUE(wait, current); | 402 | DECLARE_WAITQUEUE(wait, current); |
402 | int retval; | 403 | int retval; |
403 | int do_clocal = 0; | 404 | int do_clocal = 0; |
@@ -409,16 +410,16 @@ int gs_block_til_ready(void *port_, struct file * filp) | |||
409 | 410 | ||
410 | if (!port) return 0; | 411 | if (!port) return 0; |
411 | 412 | ||
412 | tty = port->port.tty; | 413 | tty = port->tty; |
413 | 414 | ||
414 | gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); | 415 | gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); |
415 | /* | 416 | /* |
416 | * If the device is in the middle of being closed, then block | 417 | * If the device is in the middle of being closed, then block |
417 | * until it's done, and then try again. | 418 | * until it's done, and then try again. |
418 | */ | 419 | */ |
419 | if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { | 420 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { |
420 | interruptible_sleep_on(&port->port.close_wait); | 421 | interruptible_sleep_on(&port->close_wait); |
421 | if (port->port.flags & ASYNC_HUP_NOTIFY) | 422 | if (port->flags & ASYNC_HUP_NOTIFY) |
422 | return -EAGAIN; | 423 | return -EAGAIN; |
423 | else | 424 | else |
424 | return -ERESTARTSYS; | 425 | return -ERESTARTSYS; |
@@ -432,7 +433,7 @@ int gs_block_til_ready(void *port_, struct file * filp) | |||
432 | */ | 433 | */ |
433 | if ((filp->f_flags & O_NONBLOCK) || | 434 | if ((filp->f_flags & O_NONBLOCK) || |
434 | (tty->flags & (1 << TTY_IO_ERROR))) { | 435 | (tty->flags & (1 << TTY_IO_ERROR))) { |
435 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 436 | port->flags |= ASYNC_NORMAL_ACTIVE; |
436 | return 0; | 437 | return 0; |
437 | } | 438 | } |
438 | 439 | ||
@@ -444,34 +445,34 @@ int gs_block_til_ready(void *port_, struct file * filp) | |||
444 | /* | 445 | /* |
445 | * Block waiting for the carrier detect and the line to become | 446 | * Block waiting for the carrier detect and the line to become |
446 | * free (i.e., not in use by the callout). While we are in | 447 | * free (i.e., not in use by the callout). While we are in |
447 | * this loop, port->port.count is dropped by one, so that | 448 | * this loop, port->count is dropped by one, so that |
448 | * rs_close() knows when to free things. We restore it upon | 449 | * rs_close() knows when to free things. We restore it upon |
449 | * exit, either normal or abnormal. | 450 | * exit, either normal or abnormal. |
450 | */ | 451 | */ |
451 | retval = 0; | 452 | retval = 0; |
452 | 453 | ||
453 | add_wait_queue(&port->port.open_wait, &wait); | 454 | add_wait_queue(&port->open_wait, &wait); |
454 | 455 | ||
455 | gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); | 456 | gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); |
456 | spin_lock_irqsave(&port->driver_lock, flags); | 457 | spin_lock_irqsave(&gp->driver_lock, flags); |
457 | if (!tty_hung_up_p(filp)) { | 458 | if (!tty_hung_up_p(filp)) { |
458 | port->port.count--; | 459 | port->count--; |
459 | } | 460 | } |
460 | spin_unlock_irqrestore(&port->driver_lock, flags); | 461 | spin_unlock_irqrestore(&gp->driver_lock, flags); |
461 | port->port.blocked_open++; | 462 | port->blocked_open++; |
462 | while (1) { | 463 | while (1) { |
463 | CD = port->rd->get_CD (port); | 464 | CD = tty_port_carrier_raised(port); |
464 | gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); | 465 | gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); |
465 | set_current_state (TASK_INTERRUPTIBLE); | 466 | set_current_state (TASK_INTERRUPTIBLE); |
466 | if (tty_hung_up_p(filp) || | 467 | if (tty_hung_up_p(filp) || |
467 | !(port->port.flags & ASYNC_INITIALIZED)) { | 468 | !(port->flags & ASYNC_INITIALIZED)) { |
468 | if (port->port.flags & ASYNC_HUP_NOTIFY) | 469 | if (port->flags & ASYNC_HUP_NOTIFY) |
469 | retval = -EAGAIN; | 470 | retval = -EAGAIN; |
470 | else | 471 | else |
471 | retval = -ERESTARTSYS; | 472 | retval = -ERESTARTSYS; |
472 | break; | 473 | break; |
473 | } | 474 | } |
474 | if (!(port->port.flags & ASYNC_CLOSING) && | 475 | if (!(port->flags & ASYNC_CLOSING) && |
475 | (do_clocal || CD)) | 476 | (do_clocal || CD)) |
476 | break; | 477 | break; |
477 | gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", | 478 | gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", |
@@ -483,17 +484,17 @@ int gs_block_til_ready(void *port_, struct file * filp) | |||
483 | schedule(); | 484 | schedule(); |
484 | } | 485 | } |
485 | gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", | 486 | gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", |
486 | port->port.blocked_open); | 487 | port->blocked_open); |
487 | set_current_state (TASK_RUNNING); | 488 | set_current_state (TASK_RUNNING); |
488 | remove_wait_queue(&port->port.open_wait, &wait); | 489 | remove_wait_queue(&port->open_wait, &wait); |
489 | if (!tty_hung_up_p(filp)) { | 490 | if (!tty_hung_up_p(filp)) { |
490 | port->port.count++; | 491 | port->count++; |
491 | } | 492 | } |
492 | port->port.blocked_open--; | 493 | port->blocked_open--; |
493 | if (retval) | 494 | if (retval) |
494 | return retval; | 495 | return retval; |
495 | 496 | ||
496 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 497 | port->flags |= ASYNC_NORMAL_ACTIVE; |
497 | func_exit (); | 498 | func_exit (); |
498 | return 0; | 499 | return 0; |
499 | } | 500 | } |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 04e4549299ba..b3da4858fd4a 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -830,20 +830,28 @@ static int isicom_setup_port(struct tty_struct *tty) | |||
830 | return 0; | 830 | return 0; |
831 | } | 831 | } |
832 | 832 | ||
833 | static int isicom_carrier_raised(struct tty_port *port) | ||
834 | { | ||
835 | struct isi_port *ip = container_of(port, struct isi_port, port); | ||
836 | return (ip->status & ISI_DCD)?1 : 0; | ||
837 | } | ||
838 | |||
833 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | 839 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
834 | struct isi_port *port) | 840 | struct isi_port *ip) |
835 | { | 841 | { |
836 | struct isi_board *card = port->card; | 842 | struct isi_board *card = ip->card; |
843 | struct tty_port *port = &ip->port; | ||
837 | int do_clocal = 0, retval; | 844 | int do_clocal = 0, retval; |
838 | unsigned long flags; | 845 | unsigned long flags; |
839 | DECLARE_WAITQUEUE(wait, current); | 846 | DECLARE_WAITQUEUE(wait, current); |
847 | int cd; | ||
840 | 848 | ||
841 | /* block if port is in the process of being closed */ | 849 | /* block if port is in the process of being closed */ |
842 | 850 | ||
843 | if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { | 851 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { |
844 | pr_dbg("block_til_ready: close in progress.\n"); | 852 | pr_dbg("block_til_ready: close in progress.\n"); |
845 | interruptible_sleep_on(&port->port.close_wait); | 853 | interruptible_sleep_on(&port->close_wait); |
846 | if (port->port.flags & ASYNC_HUP_NOTIFY) | 854 | if (port->flags & ASYNC_HUP_NOTIFY) |
847 | return -EAGAIN; | 855 | return -EAGAIN; |
848 | else | 856 | else |
849 | return -ERESTARTSYS; | 857 | return -ERESTARTSYS; |
@@ -854,7 +862,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
854 | if ((filp->f_flags & O_NONBLOCK) || | 862 | if ((filp->f_flags & O_NONBLOCK) || |
855 | (tty->flags & (1 << TTY_IO_ERROR))) { | 863 | (tty->flags & (1 << TTY_IO_ERROR))) { |
856 | pr_dbg("block_til_ready: non-block mode.\n"); | 864 | pr_dbg("block_til_ready: non-block mode.\n"); |
857 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 865 | port->flags |= ASYNC_NORMAL_ACTIVE; |
858 | return 0; | 866 | return 0; |
859 | } | 867 | } |
860 | 868 | ||
@@ -864,29 +872,29 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
864 | /* block waiting for DCD to be asserted, and while | 872 | /* block waiting for DCD to be asserted, and while |
865 | callout dev is busy */ | 873 | callout dev is busy */ |
866 | retval = 0; | 874 | retval = 0; |
867 | add_wait_queue(&port->port.open_wait, &wait); | 875 | add_wait_queue(&port->open_wait, &wait); |
868 | 876 | ||
869 | spin_lock_irqsave(&card->card_lock, flags); | 877 | spin_lock_irqsave(&card->card_lock, flags); |
870 | if (!tty_hung_up_p(filp)) | 878 | if (!tty_hung_up_p(filp)) |
871 | port->port.count--; | 879 | port->count--; |
872 | port->port.blocked_open++; | 880 | port->blocked_open++; |
873 | spin_unlock_irqrestore(&card->card_lock, flags); | 881 | spin_unlock_irqrestore(&card->card_lock, flags); |
874 | 882 | ||
875 | while (1) { | 883 | while (1) { |
876 | raise_dtr_rts(port); | 884 | raise_dtr_rts(ip); |
877 | 885 | ||
878 | set_current_state(TASK_INTERRUPTIBLE); | 886 | set_current_state(TASK_INTERRUPTIBLE); |
879 | if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) { | 887 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { |
880 | if (port->port.flags & ASYNC_HUP_NOTIFY) | 888 | if (port->flags & ASYNC_HUP_NOTIFY) |
881 | retval = -EAGAIN; | 889 | retval = -EAGAIN; |
882 | else | 890 | else |
883 | retval = -ERESTARTSYS; | 891 | retval = -ERESTARTSYS; |
884 | break; | 892 | break; |
885 | } | 893 | } |
886 | if (!(port->port.flags & ASYNC_CLOSING) && | 894 | cd = tty_port_carrier_raised(port); |
887 | (do_clocal || (port->status & ISI_DCD))) { | 895 | if (!(port->flags & ASYNC_CLOSING) && |
896 | (do_clocal || cd)) | ||
888 | break; | 897 | break; |
889 | } | ||
890 | if (signal_pending(current)) { | 898 | if (signal_pending(current)) { |
891 | retval = -ERESTARTSYS; | 899 | retval = -ERESTARTSYS; |
892 | break; | 900 | break; |
@@ -894,15 +902,15 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
894 | schedule(); | 902 | schedule(); |
895 | } | 903 | } |
896 | set_current_state(TASK_RUNNING); | 904 | set_current_state(TASK_RUNNING); |
897 | remove_wait_queue(&port->port.open_wait, &wait); | 905 | remove_wait_queue(&port->open_wait, &wait); |
898 | spin_lock_irqsave(&card->card_lock, flags); | 906 | spin_lock_irqsave(&card->card_lock, flags); |
899 | if (!tty_hung_up_p(filp)) | 907 | if (!tty_hung_up_p(filp)) |
900 | port->port.count++; | 908 | port->count++; |
901 | port->port.blocked_open--; | 909 | port->blocked_open--; |
902 | spin_unlock_irqrestore(&card->card_lock, flags); | 910 | spin_unlock_irqrestore(&card->card_lock, flags); |
903 | if (retval) | 911 | if (retval) |
904 | return retval; | 912 | return retval; |
905 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 913 | port->flags |= ASYNC_NORMAL_ACTIVE; |
906 | return 0; | 914 | return 0; |
907 | } | 915 | } |
908 | 916 | ||
@@ -1452,6 +1460,10 @@ static const struct tty_operations isicom_ops = { | |||
1452 | .break_ctl = isicom_send_break, | 1460 | .break_ctl = isicom_send_break, |
1453 | }; | 1461 | }; |
1454 | 1462 | ||
1463 | static const struct tty_port_operations isicom_port_ops = { | ||
1464 | .carrier_raised = isicom_carrier_raised, | ||
1465 | }; | ||
1466 | |||
1455 | static int __devinit reset_card(struct pci_dev *pdev, | 1467 | static int __devinit reset_card(struct pci_dev *pdev, |
1456 | const unsigned int card, unsigned int *signature) | 1468 | const unsigned int card, unsigned int *signature) |
1457 | { | 1469 | { |
@@ -1794,6 +1806,7 @@ static int __init isicom_init(void) | |||
1794 | spin_lock_init(&isi_card[idx].card_lock); | 1806 | spin_lock_init(&isi_card[idx].card_lock); |
1795 | for (channel = 0; channel < 16; channel++, port++) { | 1807 | for (channel = 0; channel < 16; channel++, port++) { |
1796 | tty_port_init(&port->port); | 1808 | tty_port_init(&port->port); |
1809 | port->port.ops = &isicom_port_ops; | ||
1797 | port->magic = ISICOM_MAGIC; | 1810 | port->magic = ISICOM_MAGIC; |
1798 | port->card = &isi_card[idx]; | 1811 | port->card = &isi_card[idx]; |
1799 | port->channel = channel; | 1812 | port->channel = channel; |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 4b10770fa937..c4682f9e34bb 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -151,7 +151,7 @@ static char *stli_drvversion = "5.6.0"; | |||
151 | static char *stli_serialname = "ttyE"; | 151 | static char *stli_serialname = "ttyE"; |
152 | 152 | ||
153 | static struct tty_driver *stli_serial; | 153 | static struct tty_driver *stli_serial; |
154 | 154 | static const struct tty_port_operations stli_port_ops; | |
155 | 155 | ||
156 | #define STLI_TXBUFSIZE 4096 | 156 | #define STLI_TXBUFSIZE 4096 |
157 | 157 | ||
@@ -1183,6 +1183,12 @@ static int stli_setport(struct tty_struct *tty) | |||
1183 | 1183 | ||
1184 | /*****************************************************************************/ | 1184 | /*****************************************************************************/ |
1185 | 1185 | ||
1186 | static int stli_carrier_raised(struct tty_port *port) | ||
1187 | { | ||
1188 | struct stliport *portp = container_of(port, struct stliport, port); | ||
1189 | return (portp->sigs & TIOCM_CD) ? 1 : 0; | ||
1190 | } | ||
1191 | |||
1186 | /* | 1192 | /* |
1187 | * Possibly need to wait for carrier (DCD signal) to come high. Say | 1193 | * Possibly need to wait for carrier (DCD signal) to come high. Say |
1188 | * maybe because if we are clocal then we don't need to wait... | 1194 | * maybe because if we are clocal then we don't need to wait... |
@@ -1193,6 +1199,7 @@ static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, | |||
1193 | { | 1199 | { |
1194 | unsigned long flags; | 1200 | unsigned long flags; |
1195 | int rc, doclocal; | 1201 | int rc, doclocal; |
1202 | struct tty_port *port = &portp->port; | ||
1196 | 1203 | ||
1197 | rc = 0; | 1204 | rc = 0; |
1198 | doclocal = 0; | 1205 | doclocal = 0; |
@@ -1203,7 +1210,7 @@ static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, | |||
1203 | spin_lock_irqsave(&stli_lock, flags); | 1210 | spin_lock_irqsave(&stli_lock, flags); |
1204 | portp->openwaitcnt++; | 1211 | portp->openwaitcnt++; |
1205 | if (! tty_hung_up_p(filp)) | 1212 | if (! tty_hung_up_p(filp)) |
1206 | portp->port.count--; | 1213 | port->count--; |
1207 | spin_unlock_irqrestore(&stli_lock, flags); | 1214 | spin_unlock_irqrestore(&stli_lock, flags); |
1208 | 1215 | ||
1209 | for (;;) { | 1216 | for (;;) { |
@@ -1212,27 +1219,27 @@ static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, | |||
1212 | &portp->asig, sizeof(asysigs_t), 0)) < 0) | 1219 | &portp->asig, sizeof(asysigs_t), 0)) < 0) |
1213 | break; | 1220 | break; |
1214 | if (tty_hung_up_p(filp) || | 1221 | if (tty_hung_up_p(filp) || |
1215 | ((portp->port.flags & ASYNC_INITIALIZED) == 0)) { | 1222 | ((port->flags & ASYNC_INITIALIZED) == 0)) { |
1216 | if (portp->port.flags & ASYNC_HUP_NOTIFY) | 1223 | if (port->flags & ASYNC_HUP_NOTIFY) |
1217 | rc = -EBUSY; | 1224 | rc = -EBUSY; |
1218 | else | 1225 | else |
1219 | rc = -ERESTARTSYS; | 1226 | rc = -ERESTARTSYS; |
1220 | break; | 1227 | break; |
1221 | } | 1228 | } |
1222 | if (((portp->port.flags & ASYNC_CLOSING) == 0) && | 1229 | if (((port->flags & ASYNC_CLOSING) == 0) && |
1223 | (doclocal || (portp->sigs & TIOCM_CD))) { | 1230 | (doclocal || tty_port_carrier_raised(port))) { |
1224 | break; | 1231 | break; |
1225 | } | 1232 | } |
1226 | if (signal_pending(current)) { | 1233 | if (signal_pending(current)) { |
1227 | rc = -ERESTARTSYS; | 1234 | rc = -ERESTARTSYS; |
1228 | break; | 1235 | break; |
1229 | } | 1236 | } |
1230 | interruptible_sleep_on(&portp->port.open_wait); | 1237 | interruptible_sleep_on(&port->open_wait); |
1231 | } | 1238 | } |
1232 | 1239 | ||
1233 | spin_lock_irqsave(&stli_lock, flags); | 1240 | spin_lock_irqsave(&stli_lock, flags); |
1234 | if (! tty_hung_up_p(filp)) | 1241 | if (! tty_hung_up_p(filp)) |
1235 | portp->port.count++; | 1242 | port->count++; |
1236 | portp->openwaitcnt--; | 1243 | portp->openwaitcnt--; |
1237 | spin_unlock_irqrestore(&stli_lock, flags); | 1244 | spin_unlock_irqrestore(&stli_lock, flags); |
1238 | 1245 | ||
@@ -2696,6 +2703,7 @@ static int stli_initports(struct stlibrd *brdp) | |||
2696 | continue; | 2703 | continue; |
2697 | } | 2704 | } |
2698 | tty_port_init(&portp->port); | 2705 | tty_port_init(&portp->port); |
2706 | portp->port.ops = &stli_port_ops; | ||
2699 | portp->magic = STLI_PORTMAGIC; | 2707 | portp->magic = STLI_PORTMAGIC; |
2700 | portp->portnr = i; | 2708 | portp->portnr = i; |
2701 | portp->brdnr = brdp->brdnr; | 2709 | portp->brdnr = brdp->brdnr; |
@@ -4518,6 +4526,10 @@ static const struct tty_operations stli_ops = { | |||
4518 | .tiocmset = stli_tiocmset, | 4526 | .tiocmset = stli_tiocmset, |
4519 | }; | 4527 | }; |
4520 | 4528 | ||
4529 | static const struct tty_port_operations stli_port_ops = { | ||
4530 | .carrier_raised = stli_carrier_raised, | ||
4531 | }; | ||
4532 | |||
4521 | /*****************************************************************************/ | 4533 | /*****************************************************************************/ |
4522 | /* | 4534 | /* |
4523 | * Loadable module initialization stuff. | 4535 | * Loadable module initialization stuff. |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 12d327a2c9ba..8b0da97d5293 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -206,6 +206,7 @@ static void moxa_poll(unsigned long); | |||
206 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); | 206 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); |
207 | static void moxa_setup_empty_event(struct tty_struct *); | 207 | static void moxa_setup_empty_event(struct tty_struct *); |
208 | static void moxa_shut_down(struct tty_struct *); | 208 | static void moxa_shut_down(struct tty_struct *); |
209 | static int moxa_carrier_raised(struct tty_port *); | ||
209 | /* | 210 | /* |
210 | * moxa board interface functions: | 211 | * moxa board interface functions: |
211 | */ | 212 | */ |
@@ -405,6 +406,10 @@ static const struct tty_operations moxa_ops = { | |||
405 | .tiocmset = moxa_tiocmset, | 406 | .tiocmset = moxa_tiocmset, |
406 | }; | 407 | }; |
407 | 408 | ||
409 | static const struct tty_port_operations moxa_port_ops = { | ||
410 | .carrier_raised = moxa_carrier_raised, | ||
411 | }; | ||
412 | |||
408 | static struct tty_driver *moxaDriver; | 413 | static struct tty_driver *moxaDriver; |
409 | static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); | 414 | static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); |
410 | static DEFINE_SPINLOCK(moxa_lock); | 415 | static DEFINE_SPINLOCK(moxa_lock); |
@@ -826,6 +831,7 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) | |||
826 | 831 | ||
827 | for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) { | 832 | for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) { |
828 | tty_port_init(&p->port); | 833 | tty_port_init(&p->port); |
834 | p->port.ops = &moxa_port_ops; | ||
829 | p->type = PORT_16550A; | 835 | p->type = PORT_16550A; |
830 | p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | 836 | p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; |
831 | } | 837 | } |
@@ -1115,15 +1121,27 @@ static void moxa_close_port(struct tty_struct *tty) | |||
1115 | tty_port_tty_set(&ch->port, NULL); | 1121 | tty_port_tty_set(&ch->port, NULL); |
1116 | } | 1122 | } |
1117 | 1123 | ||
1124 | static int moxa_carrier_raised(struct tty_port *port) | ||
1125 | { | ||
1126 | struct moxa_port *ch = container_of(port, struct moxa_port, port); | ||
1127 | int dcd; | ||
1128 | |||
1129 | spin_lock_bh(&moxa_lock); | ||
1130 | dcd = ch->DCDState; | ||
1131 | spin_unlock_bh(&moxa_lock); | ||
1132 | return dcd; | ||
1133 | } | ||
1134 | |||
1118 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | 1135 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, |
1119 | struct moxa_port *ch) | 1136 | struct moxa_port *ch) |
1120 | { | 1137 | { |
1138 | struct tty_port *port = &ch->port; | ||
1121 | DEFINE_WAIT(wait); | 1139 | DEFINE_WAIT(wait); |
1122 | int retval = 0; | 1140 | int retval = 0; |
1123 | u8 dcd; | 1141 | u8 dcd; |
1124 | 1142 | ||
1125 | while (1) { | 1143 | while (1) { |
1126 | prepare_to_wait(&ch->port.open_wait, &wait, TASK_INTERRUPTIBLE); | 1144 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); |
1127 | if (tty_hung_up_p(filp)) { | 1145 | if (tty_hung_up_p(filp)) { |
1128 | #ifdef SERIAL_DO_RESTART | 1146 | #ifdef SERIAL_DO_RESTART |
1129 | retval = -ERESTARTSYS; | 1147 | retval = -ERESTARTSYS; |
@@ -1132,9 +1150,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1132 | #endif | 1150 | #endif |
1133 | break; | 1151 | break; |
1134 | } | 1152 | } |
1135 | spin_lock_bh(&moxa_lock); | 1153 | dcd = tty_port_carrier_raised(port); |
1136 | dcd = ch->DCDState; | ||
1137 | spin_unlock_bh(&moxa_lock); | ||
1138 | if (dcd) | 1154 | if (dcd) |
1139 | break; | 1155 | break; |
1140 | 1156 | ||
@@ -1144,7 +1160,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1144 | } | 1160 | } |
1145 | schedule(); | 1161 | schedule(); |
1146 | } | 1162 | } |
1147 | finish_wait(&ch->port.open_wait, &wait); | 1163 | finish_wait(&port->open_wait, &wait); |
1148 | 1164 | ||
1149 | return retval; | 1165 | return retval; |
1150 | } | 1166 | } |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 047766915411..eafbbcf355e7 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -541,13 +541,21 @@ static unsigned char mxser_get_msr(int baseaddr, int mode, int port) | |||
541 | return status; | 541 | return status; |
542 | } | 542 | } |
543 | 543 | ||
544 | static int mxser_carrier_raised(struct tty_port *port) | ||
545 | { | ||
546 | struct mxser_port *mp = container_of(port, struct mxser_port, port); | ||
547 | return (inb(mp->ioaddr + UART_MSR) & UART_MSR_DCD)?1:0; | ||
548 | } | ||
549 | |||
544 | static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | 550 | static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, |
545 | struct mxser_port *port) | 551 | struct mxser_port *mp) |
546 | { | 552 | { |
547 | DECLARE_WAITQUEUE(wait, current); | 553 | DECLARE_WAITQUEUE(wait, current); |
548 | int retval; | 554 | int retval; |
549 | int do_clocal = 0; | 555 | int do_clocal = 0; |
550 | unsigned long flags; | 556 | unsigned long flags; |
557 | int cd; | ||
558 | struct tty_port *port = &mp->port; | ||
551 | 559 | ||
552 | /* | 560 | /* |
553 | * If non-blocking mode is set, or the port is not enabled, | 561 | * If non-blocking mode is set, or the port is not enabled, |
@@ -555,7 +563,7 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
555 | */ | 563 | */ |
556 | if ((filp->f_flags & O_NONBLOCK) || | 564 | if ((filp->f_flags & O_NONBLOCK) || |
557 | test_bit(TTY_IO_ERROR, &tty->flags)) { | 565 | test_bit(TTY_IO_ERROR, &tty->flags)) { |
558 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 566 | port->flags |= ASYNC_NORMAL_ACTIVE; |
559 | return 0; | 567 | return 0; |
560 | } | 568 | } |
561 | 569 | ||
@@ -565,34 +573,33 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
565 | /* | 573 | /* |
566 | * Block waiting for the carrier detect and the line to become | 574 | * Block waiting for the carrier detect and the line to become |
567 | * free (i.e., not in use by the callout). While we are in | 575 | * free (i.e., not in use by the callout). While we are in |
568 | * this loop, port->port.count is dropped by one, so that | 576 | * this loop, port->count is dropped by one, so that |
569 | * mxser_close() knows when to free things. We restore it upon | 577 | * mxser_close() knows when to free things. We restore it upon |
570 | * exit, either normal or abnormal. | 578 | * exit, either normal or abnormal. |
571 | */ | 579 | */ |
572 | retval = 0; | 580 | retval = 0; |
573 | add_wait_queue(&port->port.open_wait, &wait); | 581 | add_wait_queue(&port->open_wait, &wait); |
574 | 582 | ||
575 | spin_lock_irqsave(&port->slock, flags); | 583 | spin_lock_irqsave(&mp->slock, flags); |
576 | if (!tty_hung_up_p(filp)) | 584 | if (!tty_hung_up_p(filp)) |
577 | port->port.count--; | 585 | port->count--; |
578 | spin_unlock_irqrestore(&port->slock, flags); | 586 | spin_unlock_irqrestore(&mp->slock, flags); |
579 | port->port.blocked_open++; | 587 | port->blocked_open++; |
580 | while (1) { | 588 | while (1) { |
581 | spin_lock_irqsave(&port->slock, flags); | 589 | spin_lock_irqsave(&mp->slock, flags); |
582 | outb(inb(port->ioaddr + UART_MCR) | | 590 | outb(inb(mp->ioaddr + UART_MCR) | |
583 | UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR); | 591 | UART_MCR_DTR | UART_MCR_RTS, mp->ioaddr + UART_MCR); |
584 | spin_unlock_irqrestore(&port->slock, flags); | 592 | spin_unlock_irqrestore(&mp->slock, flags); |
585 | set_current_state(TASK_INTERRUPTIBLE); | 593 | set_current_state(TASK_INTERRUPTIBLE); |
586 | if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) { | 594 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { |
587 | if (port->port.flags & ASYNC_HUP_NOTIFY) | 595 | if (port->flags & ASYNC_HUP_NOTIFY) |
588 | retval = -EAGAIN; | 596 | retval = -EAGAIN; |
589 | else | 597 | else |
590 | retval = -ERESTARTSYS; | 598 | retval = -ERESTARTSYS; |
591 | break; | 599 | break; |
592 | } | 600 | } |
593 | if (!(port->port.flags & ASYNC_CLOSING) && | 601 | cd = tty_port_carrier_raised(port); |
594 | (do_clocal || | 602 | if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd)) |
595 | (inb(port->ioaddr + UART_MSR) & UART_MSR_DCD))) | ||
596 | break; | 603 | break; |
597 | if (signal_pending(current)) { | 604 | if (signal_pending(current)) { |
598 | retval = -ERESTARTSYS; | 605 | retval = -ERESTARTSYS; |
@@ -601,13 +608,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
601 | schedule(); | 608 | schedule(); |
602 | } | 609 | } |
603 | set_current_state(TASK_RUNNING); | 610 | set_current_state(TASK_RUNNING); |
604 | remove_wait_queue(&port->port.open_wait, &wait); | 611 | remove_wait_queue(&port->open_wait, &wait); |
605 | if (!tty_hung_up_p(filp)) | 612 | if (!tty_hung_up_p(filp)) |
606 | port->port.count++; | 613 | port->count++; |
607 | port->port.blocked_open--; | 614 | port->blocked_open--; |
608 | if (retval) | 615 | if (retval) |
609 | return retval; | 616 | return retval; |
610 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 617 | port->flags |= ASYNC_NORMAL_ACTIVE; |
611 | return 0; | 618 | return 0; |
612 | } | 619 | } |
613 | 620 | ||
@@ -2449,6 +2456,10 @@ static const struct tty_operations mxser_ops = { | |||
2449 | .tiocmset = mxser_tiocmset, | 2456 | .tiocmset = mxser_tiocmset, |
2450 | }; | 2457 | }; |
2451 | 2458 | ||
2459 | struct tty_port_operations mxser_port_ops = { | ||
2460 | .carrier_raised = mxser_carrier_raised, | ||
2461 | }; | ||
2462 | |||
2452 | /* | 2463 | /* |
2453 | * The MOXA Smartio/Industio serial driver boot-time initialization code! | 2464 | * The MOXA Smartio/Industio serial driver boot-time initialization code! |
2454 | */ | 2465 | */ |
@@ -2482,6 +2493,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
2482 | for (i = 0; i < brd->info->nports; i++) { | 2493 | for (i = 0; i < brd->info->nports; i++) { |
2483 | info = &brd->ports[i]; | 2494 | info = &brd->ports[i]; |
2484 | tty_port_init(&info->port); | 2495 | tty_port_init(&info->port); |
2496 | info->port.ops = &mxser_port_ops; | ||
2485 | info->board = brd; | 2497 | info->board = brd; |
2486 | info->stop_rx = 0; | 2498 | info->stop_rx = 0; |
2487 | info->ldisc_stop_rx = 0; | 2499 | info->ldisc_stop_rx = 0; |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index a8f68a3f14dd..ec2afd139472 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -173,7 +173,7 @@ static void rio_disable_tx_interrupts(void *ptr); | |||
173 | static void rio_enable_tx_interrupts(void *ptr); | 173 | static void rio_enable_tx_interrupts(void *ptr); |
174 | static void rio_disable_rx_interrupts(void *ptr); | 174 | static void rio_disable_rx_interrupts(void *ptr); |
175 | static void rio_enable_rx_interrupts(void *ptr); | 175 | static void rio_enable_rx_interrupts(void *ptr); |
176 | static int rio_get_CD(void *ptr); | 176 | static int rio_carrier_raised(struct tty_port *port); |
177 | static void rio_shutdown_port(void *ptr); | 177 | static void rio_shutdown_port(void *ptr); |
178 | static int rio_set_real_termios(void *ptr); | 178 | static int rio_set_real_termios(void *ptr); |
179 | static void rio_hungup(void *ptr); | 179 | static void rio_hungup(void *ptr); |
@@ -224,7 +224,6 @@ static struct real_driver rio_real_driver = { | |||
224 | rio_enable_tx_interrupts, | 224 | rio_enable_tx_interrupts, |
225 | rio_disable_rx_interrupts, | 225 | rio_disable_rx_interrupts, |
226 | rio_enable_rx_interrupts, | 226 | rio_enable_rx_interrupts, |
227 | rio_get_CD, | ||
228 | rio_shutdown_port, | 227 | rio_shutdown_port, |
229 | rio_set_real_termios, | 228 | rio_set_real_termios, |
230 | rio_chars_in_buffer, | 229 | rio_chars_in_buffer, |
@@ -476,9 +475,9 @@ static void rio_enable_rx_interrupts(void *ptr) | |||
476 | 475 | ||
477 | 476 | ||
478 | /* Jeez. Isn't this simple? */ | 477 | /* Jeez. Isn't this simple? */ |
479 | static int rio_get_CD(void *ptr) | 478 | static int rio_carrier_raised(struct tty_port *port) |
480 | { | 479 | { |
481 | struct Port *PortP = ptr; | 480 | struct Port *PortP = container_of(port, struct Port, gs.port); |
482 | int rv; | 481 | int rv; |
483 | 482 | ||
484 | func_enter(); | 483 | func_enter(); |
@@ -806,7 +805,9 @@ static void *ckmalloc(int size) | |||
806 | return p; | 805 | return p; |
807 | } | 806 | } |
808 | 807 | ||
809 | 808 | static const struct tty_port_operations rio_port_ops = { | |
809 | .carrier_raised = rio_carrier_raised, | ||
810 | }; | ||
810 | 811 | ||
811 | static int rio_init_datastructures(void) | 812 | static int rio_init_datastructures(void) |
812 | { | 813 | { |
@@ -842,17 +843,14 @@ static int rio_init_datastructures(void) | |||
842 | goto free6; | 843 | goto free6; |
843 | } | 844 | } |
844 | rio_dprintk(RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); | 845 | rio_dprintk(RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); |
846 | tty_port_init(&port->gs.port); | ||
847 | port->gs.port.ops = &rio_port_ops; | ||
845 | port->PortNum = i; | 848 | port->PortNum = i; |
846 | port->gs.magic = RIO_MAGIC; | 849 | port->gs.magic = RIO_MAGIC; |
847 | port->gs.close_delay = HZ / 2; | 850 | port->gs.close_delay = HZ / 2; |
848 | port->gs.closing_wait = 30 * HZ; | 851 | port->gs.closing_wait = 30 * HZ; |
849 | port->gs.rd = &rio_real_driver; | 852 | port->gs.rd = &rio_real_driver; |
850 | spin_lock_init(&port->portSem); | 853 | spin_lock_init(&port->portSem); |
851 | /* | ||
852 | * Initializing wait queue | ||
853 | */ | ||
854 | init_waitqueue_head(&port->gs.port.open_wait); | ||
855 | init_waitqueue_head(&port->gs.port.close_wait); | ||
856 | } | 854 | } |
857 | #else | 855 | #else |
858 | /* We could postpone initializing them to when they are configured. */ | 856 | /* We could postpone initializing them to when they are configured. */ |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 2c6c8f33d6b4..6ad1c2aa2a98 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -857,23 +857,40 @@ static void rc_shutdown_port(struct tty_struct *tty, | |||
857 | rc_shutdown_board(bp); | 857 | rc_shutdown_board(bp); |
858 | } | 858 | } |
859 | 859 | ||
860 | static int carrier_raised(struct tty_port *port) | ||
861 | { | ||
862 | struct riscom_port *p = container_of(port, struct riscom_port, port); | ||
863 | struct riscom_board *bp = port_Board(p); | ||
864 | unsigned long flags; | ||
865 | int CD; | ||
866 | |||
867 | spin_lock_irqsave(&riscom_lock, flags); | ||
868 | rc_out(bp, CD180_CAR, port_No(p)); | ||
869 | CD = rc_in(bp, CD180_MSVR) & MSVR_CD; | ||
870 | rc_out(bp, CD180_MSVR, MSVR_RTS); | ||
871 | bp->DTR &= ~(1u << port_No(p)); | ||
872 | rc_out(bp, RC_DTR, bp->DTR); | ||
873 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
874 | return CD; | ||
875 | } | ||
876 | |||
860 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | 877 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
861 | struct riscom_port *port) | 878 | struct riscom_port *rp) |
862 | { | 879 | { |
863 | DECLARE_WAITQUEUE(wait, current); | 880 | DECLARE_WAITQUEUE(wait, current); |
864 | struct riscom_board *bp = port_Board(port); | ||
865 | int retval; | 881 | int retval; |
866 | int do_clocal = 0; | 882 | int do_clocal = 0; |
867 | int CD; | 883 | int CD; |
868 | unsigned long flags; | 884 | unsigned long flags; |
885 | struct tty_port *port = &rp->port; | ||
869 | 886 | ||
870 | /* | 887 | /* |
871 | * If the device is in the middle of being closed, then block | 888 | * If the device is in the middle of being closed, then block |
872 | * until it's done, and then try again. | 889 | * until it's done, and then try again. |
873 | */ | 890 | */ |
874 | if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { | 891 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { |
875 | interruptible_sleep_on(&port->port.close_wait); | 892 | interruptible_sleep_on(&port->close_wait); |
876 | if (port->port.flags & ASYNC_HUP_NOTIFY) | 893 | if (port->flags & ASYNC_HUP_NOTIFY) |
877 | return -EAGAIN; | 894 | return -EAGAIN; |
878 | else | 895 | else |
879 | return -ERESTARTSYS; | 896 | return -ERESTARTSYS; |
@@ -885,7 +902,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
885 | */ | 902 | */ |
886 | if ((filp->f_flags & O_NONBLOCK) || | 903 | if ((filp->f_flags & O_NONBLOCK) || |
887 | (tty->flags & (1 << TTY_IO_ERROR))) { | 904 | (tty->flags & (1 << TTY_IO_ERROR))) { |
888 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 905 | port->flags |= ASYNC_NORMAL_ACTIVE; |
889 | return 0; | 906 | return 0; |
890 | } | 907 | } |
891 | 908 | ||
@@ -900,37 +917,29 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
900 | * exit, either normal or abnormal. | 917 | * exit, either normal or abnormal. |
901 | */ | 918 | */ |
902 | retval = 0; | 919 | retval = 0; |
903 | add_wait_queue(&port->port.open_wait, &wait); | 920 | add_wait_queue(&port->open_wait, &wait); |
904 | 921 | ||
905 | spin_lock_irqsave(&riscom_lock, flags); | 922 | spin_lock_irqsave(&riscom_lock, flags); |
906 | 923 | ||
907 | if (!tty_hung_up_p(filp)) | 924 | if (!tty_hung_up_p(filp)) |
908 | port->port.count--; | 925 | port->count--; |
909 | 926 | ||
910 | spin_unlock_irqrestore(&riscom_lock, flags); | 927 | spin_unlock_irqrestore(&riscom_lock, flags); |
911 | 928 | ||
912 | port->port.blocked_open++; | 929 | port->blocked_open++; |
913 | while (1) { | 930 | while (1) { |
914 | spin_lock_irqsave(&riscom_lock, flags); | ||
915 | |||
916 | rc_out(bp, CD180_CAR, port_No(port)); | ||
917 | CD = rc_in(bp, CD180_MSVR) & MSVR_CD; | ||
918 | rc_out(bp, CD180_MSVR, MSVR_RTS); | ||
919 | bp->DTR &= ~(1u << port_No(port)); | ||
920 | rc_out(bp, RC_DTR, bp->DTR); | ||
921 | |||
922 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
923 | 931 | ||
932 | CD = tty_port_carrier_raised(port); | ||
924 | set_current_state(TASK_INTERRUPTIBLE); | 933 | set_current_state(TASK_INTERRUPTIBLE); |
925 | if (tty_hung_up_p(filp) || | 934 | if (tty_hung_up_p(filp) || |
926 | !(port->port.flags & ASYNC_INITIALIZED)) { | 935 | !(port->flags & ASYNC_INITIALIZED)) { |
927 | if (port->port.flags & ASYNC_HUP_NOTIFY) | 936 | if (port->flags & ASYNC_HUP_NOTIFY) |
928 | retval = -EAGAIN; | 937 | retval = -EAGAIN; |
929 | else | 938 | else |
930 | retval = -ERESTARTSYS; | 939 | retval = -ERESTARTSYS; |
931 | break; | 940 | break; |
932 | } | 941 | } |
933 | if (!(port->port.flags & ASYNC_CLOSING) && | 942 | if (!(port->flags & ASYNC_CLOSING) && |
934 | (do_clocal || CD)) | 943 | (do_clocal || CD)) |
935 | break; | 944 | break; |
936 | if (signal_pending(current)) { | 945 | if (signal_pending(current)) { |
@@ -940,14 +949,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
940 | schedule(); | 949 | schedule(); |
941 | } | 950 | } |
942 | __set_current_state(TASK_RUNNING); | 951 | __set_current_state(TASK_RUNNING); |
943 | remove_wait_queue(&port->port.open_wait, &wait); | 952 | remove_wait_queue(&port->open_wait, &wait); |
944 | if (!tty_hung_up_p(filp)) | 953 | if (!tty_hung_up_p(filp)) |
945 | port->port.count++; | 954 | port->count++; |
946 | port->port.blocked_open--; | 955 | port->blocked_open--; |
947 | if (retval) | 956 | if (retval) |
948 | return retval; | 957 | return retval; |
949 | 958 | ||
950 | port->port.flags |= ASYNC_NORMAL_ACTIVE; | 959 | port->flags |= ASYNC_NORMAL_ACTIVE; |
951 | return 0; | 960 | return 0; |
952 | } | 961 | } |
953 | 962 | ||
@@ -1510,6 +1519,11 @@ static const struct tty_operations riscom_ops = { | |||
1510 | .break_ctl = rc_send_break, | 1519 | .break_ctl = rc_send_break, |
1511 | }; | 1520 | }; |
1512 | 1521 | ||
1522 | static const struct tty_port_operations riscom_port_ops = { | ||
1523 | .carrier_raised = carrier_raised, | ||
1524 | }; | ||
1525 | |||
1526 | |||
1513 | static int __init rc_init_drivers(void) | 1527 | static int __init rc_init_drivers(void) |
1514 | { | 1528 | { |
1515 | int error; | 1529 | int error; |
@@ -1541,6 +1555,7 @@ static int __init rc_init_drivers(void) | |||
1541 | memset(rc_port, 0, sizeof(rc_port)); | 1555 | memset(rc_port, 0, sizeof(rc_port)); |
1542 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { | 1556 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { |
1543 | tty_port_init(&rc_port[i].port); | 1557 | tty_port_init(&rc_port[i].port); |
1558 | rc_port[i].port.ops = &riscom_port_ops; | ||
1544 | rc_port[i].magic = RISCOM8_MAGIC; | 1559 | rc_port[i].magic = RISCOM8_MAGIC; |
1545 | } | 1560 | } |
1546 | return 0; | 1561 | return 0; |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 584d791e84a6..4a4110e703a5 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -135,6 +135,7 @@ static int rcktpt_type[NUM_BOARDS]; | |||
135 | static int is_PCI[NUM_BOARDS]; | 135 | static int is_PCI[NUM_BOARDS]; |
136 | static rocketModel_t rocketModel[NUM_BOARDS]; | 136 | static rocketModel_t rocketModel[NUM_BOARDS]; |
137 | static int max_board; | 137 | static int max_board; |
138 | static const struct tty_port_operations rocket_port_ops; | ||
138 | 139 | ||
139 | /* | 140 | /* |
140 | * The following arrays define the interrupt bits corresponding to each AIOP. | 141 | * The following arrays define the interrupt bits corresponding to each AIOP. |
@@ -649,9 +650,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
649 | info->board = board; | 650 | info->board = board; |
650 | info->aiop = aiop; | 651 | info->aiop = aiop; |
651 | info->chan = chan; | 652 | info->chan = chan; |
652 | info->port.closing_wait = 3000; | 653 | tty_port_init(&info->port); |
653 | info->port.close_delay = 50; | 654 | info->port.ops = &rocket_port_ops; |
654 | init_waitqueue_head(&info->port.open_wait); | ||
655 | init_completion(&info->close_wait); | 655 | init_completion(&info->close_wait); |
656 | info->flags &= ~ROCKET_MODE_MASK; | 656 | info->flags &= ~ROCKET_MODE_MASK; |
657 | switch (pc104[board][line]) { | 657 | switch (pc104[board][line]) { |
@@ -864,11 +864,18 @@ static void configure_r_port(struct r_port *info, | |||
864 | } | 864 | } |
865 | } | 865 | } |
866 | 866 | ||
867 | static int carrier_raised(struct tty_port *port) | ||
868 | { | ||
869 | struct r_port *info = container_of(port, struct r_port, port); | ||
870 | return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0; | ||
871 | } | ||
872 | |||
867 | /* info->port.count is considered critical, protected by spinlocks. */ | 873 | /* info->port.count is considered critical, protected by spinlocks. */ |
868 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | 874 | static int block_til_ready(struct tty_struct *tty, struct file *filp, |
869 | struct r_port *info) | 875 | struct r_port *info) |
870 | { | 876 | { |
871 | DECLARE_WAITQUEUE(wait, current); | 877 | DECLARE_WAITQUEUE(wait, current); |
878 | struct tty_port *port = &info->port; | ||
872 | int retval; | 879 | int retval; |
873 | int do_clocal = 0, extra_count = 0; | 880 | int do_clocal = 0, extra_count = 0; |
874 | unsigned long flags; | 881 | unsigned long flags; |
@@ -898,13 +905,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
898 | 905 | ||
899 | /* | 906 | /* |
900 | * Block waiting for the carrier detect and the line to become free. While we are in | 907 | * Block waiting for the carrier detect and the line to become free. While we are in |
901 | * this loop, info->port.count is dropped by one, so that rp_close() knows when to free things. | 908 | * this loop, port->count is dropped by one, so that rp_close() knows when to free things. |
902 | * We restore it upon exit, either normal or abnormal. | 909 | * We restore it upon exit, either normal or abnormal. |
903 | */ | 910 | */ |
904 | retval = 0; | 911 | retval = 0; |
905 | add_wait_queue(&info->port.open_wait, &wait); | 912 | add_wait_queue(&port->open_wait, &wait); |
906 | #ifdef ROCKET_DEBUG_OPEN | 913 | #ifdef ROCKET_DEBUG_OPEN |
907 | printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->port.count); | 914 | printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, port->count); |
908 | #endif | 915 | #endif |
909 | spin_lock_irqsave(&info->slock, flags); | 916 | spin_lock_irqsave(&info->slock, flags); |
910 | 917 | ||
@@ -913,10 +920,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
913 | #else | 920 | #else |
914 | if (!tty_hung_up_p(filp)) { | 921 | if (!tty_hung_up_p(filp)) { |
915 | extra_count = 1; | 922 | extra_count = 1; |
916 | info->port.count--; | 923 | port->count--; |
917 | } | 924 | } |
918 | #endif | 925 | #endif |
919 | info->port.blocked_open++; | 926 | port->blocked_open++; |
920 | 927 | ||
921 | spin_unlock_irqrestore(&info->slock, flags); | 928 | spin_unlock_irqrestore(&info->slock, flags); |
922 | 929 | ||
@@ -933,7 +940,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
933 | retval = -ERESTARTSYS; | 940 | retval = -ERESTARTSYS; |
934 | break; | 941 | break; |
935 | } | 942 | } |
936 | if (!(info->flags & ROCKET_CLOSING) && (do_clocal || (sGetChanStatusLo(&info->channel) & CD_ACT))) | 943 | if (!(info->flags & ROCKET_CLOSING) && |
944 | (do_clocal || tty_port_carrier_raised(port))) | ||
937 | break; | 945 | break; |
938 | if (signal_pending(current)) { | 946 | if (signal_pending(current)) { |
939 | retval = -ERESTARTSYS; | 947 | retval = -ERESTARTSYS; |
@@ -941,24 +949,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
941 | } | 949 | } |
942 | #ifdef ROCKET_DEBUG_OPEN | 950 | #ifdef ROCKET_DEBUG_OPEN |
943 | printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n", | 951 | printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n", |
944 | info->line, info->port.count, info->flags); | 952 | info->line, port->count, info->flags); |
945 | #endif | 953 | #endif |
946 | schedule(); /* Don't hold spinlock here, will hang PC */ | 954 | schedule(); /* Don't hold spinlock here, will hang PC */ |
947 | } | 955 | } |
948 | __set_current_state(TASK_RUNNING); | 956 | __set_current_state(TASK_RUNNING); |
949 | remove_wait_queue(&info->port.open_wait, &wait); | 957 | remove_wait_queue(&port->open_wait, &wait); |
950 | 958 | ||
951 | spin_lock_irqsave(&info->slock, flags); | 959 | spin_lock_irqsave(&info->slock, flags); |
952 | 960 | ||
953 | if (extra_count) | 961 | if (extra_count) |
954 | info->port.count++; | 962 | port->count++; |
955 | info->port.blocked_open--; | 963 | port->blocked_open--; |
956 | 964 | ||
957 | spin_unlock_irqrestore(&info->slock, flags); | 965 | spin_unlock_irqrestore(&info->slock, flags); |
958 | 966 | ||
959 | #ifdef ROCKET_DEBUG_OPEN | 967 | #ifdef ROCKET_DEBUG_OPEN |
960 | printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n", | 968 | printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n", |
961 | info->line, info->port.count); | 969 | info->line, port->count); |
962 | #endif | 970 | #endif |
963 | if (retval) | 971 | if (retval) |
964 | return retval; | 972 | return retval; |
@@ -2371,6 +2379,10 @@ static const struct tty_operations rocket_ops = { | |||
2371 | .tiocmset = rp_tiocmset, | 2379 | .tiocmset = rp_tiocmset, |
2372 | }; | 2380 | }; |
2373 | 2381 | ||
2382 | static const struct tty_port_operations rocket_port_ops = { | ||
2383 | .carrier_raised = carrier_raised, | ||
2384 | }; | ||
2385 | |||
2374 | /* | 2386 | /* |
2375 | * The module "startup" routine; it's run when the module is loaded. | 2387 | * The module "startup" routine; it's run when the module is loaded. |
2376 | */ | 2388 | */ |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 7b0c35207d9b..0c97f34df63a 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -122,7 +122,7 @@ static void a2232_disable_tx_interrupts(void *ptr); | |||
122 | static void a2232_enable_tx_interrupts(void *ptr); | 122 | static void a2232_enable_tx_interrupts(void *ptr); |
123 | static void a2232_disable_rx_interrupts(void *ptr); | 123 | static void a2232_disable_rx_interrupts(void *ptr); |
124 | static void a2232_enable_rx_interrupts(void *ptr); | 124 | static void a2232_enable_rx_interrupts(void *ptr); |
125 | static int a2232_get_CD(void *ptr); | 125 | static int a2232_carrier_raised(struct tty_port *port); |
126 | static void a2232_shutdown_port(void *ptr); | 126 | static void a2232_shutdown_port(void *ptr); |
127 | static int a2232_set_real_termios(void *ptr); | 127 | static int a2232_set_real_termios(void *ptr); |
128 | static int a2232_chars_in_buffer(void *ptr); | 128 | static int a2232_chars_in_buffer(void *ptr); |
@@ -148,7 +148,6 @@ static struct real_driver a2232_real_driver = { | |||
148 | a2232_enable_tx_interrupts, | 148 | a2232_enable_tx_interrupts, |
149 | a2232_disable_rx_interrupts, | 149 | a2232_disable_rx_interrupts, |
150 | a2232_enable_rx_interrupts, | 150 | a2232_enable_rx_interrupts, |
151 | a2232_get_CD, | ||
152 | a2232_shutdown_port, | 151 | a2232_shutdown_port, |
153 | a2232_set_real_termios, | 152 | a2232_set_real_termios, |
154 | a2232_chars_in_buffer, | 153 | a2232_chars_in_buffer, |
@@ -260,9 +259,10 @@ static void a2232_enable_rx_interrupts(void *ptr) | |||
260 | port->disable_rx = 0; | 259 | port->disable_rx = 0; |
261 | } | 260 | } |
262 | 261 | ||
263 | static int a2232_get_CD(void *ptr) | 262 | static int a2232_carrier_raised(struct tty_port *port) |
264 | { | 263 | { |
265 | return ((struct a2232_port *) ptr)->cd_status; | 264 | struct a2232_port *ap = container_of(port, struct a2232_port, gs.port); |
265 | return ap->cd_status; | ||
266 | } | 266 | } |
267 | 267 | ||
268 | static void a2232_shutdown_port(void *ptr) | 268 | static void a2232_shutdown_port(void *ptr) |
@@ -638,6 +638,10 @@ int ch, err, n, p; | |||
638 | return IRQ_HANDLED; | 638 | return IRQ_HANDLED; |
639 | } | 639 | } |
640 | 640 | ||
641 | static const struct tty_port_operations a2232_port_ops = { | ||
642 | .carrier_raised = a2232_carrier_raised, | ||
643 | }; | ||
644 | |||
641 | static void a2232_init_portstructs(void) | 645 | static void a2232_init_portstructs(void) |
642 | { | 646 | { |
643 | struct a2232_port *port; | 647 | struct a2232_port *port; |
@@ -645,6 +649,8 @@ static void a2232_init_portstructs(void) | |||
645 | 649 | ||
646 | for (i = 0; i < MAX_A2232_BOARDS*NUMLINES; i++) { | 650 | for (i = 0; i < MAX_A2232_BOARDS*NUMLINES; i++) { |
647 | port = a2232_ports + i; | 651 | port = a2232_ports + i; |
652 | tty_port_init(&port->gs.port); | ||
653 | port->gs.port.ops = &a2232_port_ops; | ||
648 | port->which_a2232 = i/NUMLINES; | 654 | port->which_a2232 = i/NUMLINES; |
649 | port->which_port_on_a2232 = i%NUMLINES; | 655 | port->which_port_on_a2232 = i%NUMLINES; |
650 | port->disable_rx = port->throttle_input = port->cd_status = 0; | 656 | port->disable_rx = port->throttle_input = port->cd_status = 0; |
@@ -652,11 +658,6 @@ static void a2232_init_portstructs(void) | |||
652 | port->gs.close_delay = HZ/2; | 658 | port->gs.close_delay = HZ/2; |
653 | port->gs.closing_wait = 30 * HZ; | 659 | port->gs.closing_wait = 30 * HZ; |
654 | port->gs.rd = &a2232_real_driver; | 660 | port->gs.rd = &a2232_real_driver; |
655 | #ifdef NEW_WRITE_LOCKING | ||
656 | mutex_init(&(port->gs.port_write_mutex)); | ||
657 | #endif | ||
658 | init_waitqueue_head(&port->gs.port.open_wait); | ||
659 | init_waitqueue_head(&port->gs.port.close_wait); | ||
660 | } | 661 | } |
661 | } | 662 | } |
662 | 663 | ||
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 963b03fb29e5..12aecdaf61ec 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -130,6 +130,8 @@ static char stl_unwanted[SC26198_RXFIFOSIZE]; | |||
130 | static DEFINE_MUTEX(stl_brdslock); | 130 | static DEFINE_MUTEX(stl_brdslock); |
131 | static struct stlbrd *stl_brds[STL_MAXBRDS]; | 131 | static struct stlbrd *stl_brds[STL_MAXBRDS]; |
132 | 132 | ||
133 | static const struct tty_port_operations stl_port_ops; | ||
134 | |||
133 | /* | 135 | /* |
134 | * Per board state flags. Used with the state field of the board struct. | 136 | * Per board state flags. Used with the state field of the board struct. |
135 | * Not really much here! | 137 | * Not really much here! |
@@ -786,6 +788,12 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
786 | 788 | ||
787 | /*****************************************************************************/ | 789 | /*****************************************************************************/ |
788 | 790 | ||
791 | static int stl_carrier_raised(struct tty_port *port) | ||
792 | { | ||
793 | struct stlport *portp = container_of(port, struct stlport, port); | ||
794 | return (portp->sigs & TIOCM_CD) ? 1 : 0; | ||
795 | } | ||
796 | |||
789 | /* | 797 | /* |
790 | * Possibly need to wait for carrier (DCD signal) to come high. Say | 798 | * Possibly need to wait for carrier (DCD signal) to come high. Say |
791 | * maybe because if we are clocal then we don't need to wait... | 799 | * maybe because if we are clocal then we don't need to wait... |
@@ -796,6 +804,7 @@ static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, | |||
796 | { | 804 | { |
797 | unsigned long flags; | 805 | unsigned long flags; |
798 | int rc, doclocal; | 806 | int rc, doclocal; |
807 | struct tty_port *port = &portp->port; | ||
799 | 808 | ||
800 | pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp); | 809 | pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp); |
801 | 810 | ||
@@ -809,32 +818,32 @@ static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, | |||
809 | 818 | ||
810 | portp->openwaitcnt++; | 819 | portp->openwaitcnt++; |
811 | if (! tty_hung_up_p(filp)) | 820 | if (! tty_hung_up_p(filp)) |
812 | portp->port.count--; | 821 | port->count--; |
813 | 822 | ||
814 | for (;;) { | 823 | for (;;) { |
815 | /* Takes brd_lock internally */ | 824 | /* Takes brd_lock internally */ |
816 | stl_setsignals(portp, 1, 1); | 825 | stl_setsignals(portp, 1, 1); |
817 | if (tty_hung_up_p(filp) || | 826 | if (tty_hung_up_p(filp) || |
818 | ((portp->port.flags & ASYNC_INITIALIZED) == 0)) { | 827 | ((port->flags & ASYNC_INITIALIZED) == 0)) { |
819 | if (portp->port.flags & ASYNC_HUP_NOTIFY) | 828 | if (port->flags & ASYNC_HUP_NOTIFY) |
820 | rc = -EBUSY; | 829 | rc = -EBUSY; |
821 | else | 830 | else |
822 | rc = -ERESTARTSYS; | 831 | rc = -ERESTARTSYS; |
823 | break; | 832 | break; |
824 | } | 833 | } |
825 | if (((portp->port.flags & ASYNC_CLOSING) == 0) && | 834 | if (((port->flags & ASYNC_CLOSING) == 0) && |
826 | (doclocal || (portp->sigs & TIOCM_CD))) | 835 | (doclocal || tty_port_carrier_raised(port))) |
827 | break; | 836 | break; |
828 | if (signal_pending(current)) { | 837 | if (signal_pending(current)) { |
829 | rc = -ERESTARTSYS; | 838 | rc = -ERESTARTSYS; |
830 | break; | 839 | break; |
831 | } | 840 | } |
832 | /* FIXME */ | 841 | /* FIXME */ |
833 | interruptible_sleep_on(&portp->port.open_wait); | 842 | interruptible_sleep_on(&port->open_wait); |
834 | } | 843 | } |
835 | 844 | ||
836 | if (! tty_hung_up_p(filp)) | 845 | if (! tty_hung_up_p(filp)) |
837 | portp->port.count++; | 846 | port->count++; |
838 | portp->openwaitcnt--; | 847 | portp->openwaitcnt--; |
839 | spin_unlock_irqrestore(&stallion_lock, flags); | 848 | spin_unlock_irqrestore(&stallion_lock, flags); |
840 | 849 | ||
@@ -1776,6 +1785,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) | |||
1776 | break; | 1785 | break; |
1777 | } | 1786 | } |
1778 | tty_port_init(&portp->port); | 1787 | tty_port_init(&portp->port); |
1788 | portp->port.ops = &stl_port_ops; | ||
1779 | portp->magic = STL_PORTMAGIC; | 1789 | portp->magic = STL_PORTMAGIC; |
1780 | portp->portnr = i; | 1790 | portp->portnr = i; |
1781 | portp->brdnr = panelp->brdnr; | 1791 | portp->brdnr = panelp->brdnr; |
@@ -2659,6 +2669,10 @@ static const struct tty_operations stl_ops = { | |||
2659 | .tiocmset = stl_tiocmset, | 2669 | .tiocmset = stl_tiocmset, |
2660 | }; | 2670 | }; |
2661 | 2671 | ||
2672 | static const struct tty_port_operations stl_port_ops = { | ||
2673 | .carrier_raised = stl_carrier_raised, | ||
2674 | }; | ||
2675 | |||
2662 | /*****************************************************************************/ | 2676 | /*****************************************************************************/ |
2663 | /* CD1400 HARDWARE FUNCTIONS */ | 2677 | /* CD1400 HARDWARE FUNCTIONS */ |
2664 | /*****************************************************************************/ | 2678 | /*****************************************************************************/ |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index ba4e86281fbf..a71bc58abe7f 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -279,7 +279,7 @@ static void sx_disable_tx_interrupts(void *ptr); | |||
279 | static void sx_enable_tx_interrupts(void *ptr); | 279 | static void sx_enable_tx_interrupts(void *ptr); |
280 | static void sx_disable_rx_interrupts(void *ptr); | 280 | static void sx_disable_rx_interrupts(void *ptr); |
281 | static void sx_enable_rx_interrupts(void *ptr); | 281 | static void sx_enable_rx_interrupts(void *ptr); |
282 | static int sx_get_CD(void *ptr); | 282 | static int sx_carrier_raised(struct tty_port *port); |
283 | static void sx_shutdown_port(void *ptr); | 283 | static void sx_shutdown_port(void *ptr); |
284 | static int sx_set_real_termios(void *ptr); | 284 | static int sx_set_real_termios(void *ptr); |
285 | static void sx_close(void *ptr); | 285 | static void sx_close(void *ptr); |
@@ -360,7 +360,6 @@ static struct real_driver sx_real_driver = { | |||
360 | sx_enable_tx_interrupts, | 360 | sx_enable_tx_interrupts, |
361 | sx_disable_rx_interrupts, | 361 | sx_disable_rx_interrupts, |
362 | sx_enable_rx_interrupts, | 362 | sx_enable_rx_interrupts, |
363 | sx_get_CD, | ||
364 | sx_shutdown_port, | 363 | sx_shutdown_port, |
365 | sx_set_real_termios, | 364 | sx_set_real_termios, |
366 | sx_chars_in_buffer, | 365 | sx_chars_in_buffer, |
@@ -791,7 +790,7 @@ static int sx_getsignals(struct sx_port *port) | |||
791 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) " | 790 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) " |
792 | "%02x/%02x\n", | 791 | "%02x/%02x\n", |
793 | (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, | 792 | (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, |
794 | port->c_dcd, sx_get_CD(port), | 793 | port->c_dcd, tty_port_carrier_raised(&port->gs.port), |
795 | sx_read_channel_byte(port, hi_ip), | 794 | sx_read_channel_byte(port, hi_ip), |
796 | sx_read_channel_byte(port, hi_state)); | 795 | sx_read_channel_byte(port, hi_state)); |
797 | 796 | ||
@@ -1190,7 +1189,7 @@ static inline void sx_check_modem_signals(struct sx_port *port) | |||
1190 | 1189 | ||
1191 | hi_state = sx_read_channel_byte(port, hi_state); | 1190 | hi_state = sx_read_channel_byte(port, hi_state); |
1192 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", | 1191 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", |
1193 | port->c_dcd, sx_get_CD(port)); | 1192 | port->c_dcd, tty_port_carrier_raised(&port->gs.port)); |
1194 | 1193 | ||
1195 | if (hi_state & ST_BREAK) { | 1194 | if (hi_state & ST_BREAK) { |
1196 | hi_state &= ~ST_BREAK; | 1195 | hi_state &= ~ST_BREAK; |
@@ -1202,11 +1201,11 @@ static inline void sx_check_modem_signals(struct sx_port *port) | |||
1202 | hi_state &= ~ST_DCD; | 1201 | hi_state &= ~ST_DCD; |
1203 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); | 1202 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); |
1204 | sx_write_channel_byte(port, hi_state, hi_state); | 1203 | sx_write_channel_byte(port, hi_state, hi_state); |
1205 | c_dcd = sx_get_CD(port); | 1204 | c_dcd = tty_port_carrier_raised(&port->gs.port); |
1206 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); | 1205 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); |
1207 | if (c_dcd != port->c_dcd) { | 1206 | if (c_dcd != port->c_dcd) { |
1208 | port->c_dcd = c_dcd; | 1207 | port->c_dcd = c_dcd; |
1209 | if (sx_get_CD(port)) { | 1208 | if (tty_port_carrier_raised(&port->gs.port)) { |
1210 | /* DCD went UP */ | 1209 | /* DCD went UP */ |
1211 | if ((sx_read_channel_byte(port, hi_hstat) != | 1210 | if ((sx_read_channel_byte(port, hi_hstat) != |
1212 | HS_IDLE_CLOSED) && | 1211 | HS_IDLE_CLOSED) && |
@@ -1415,13 +1414,10 @@ static void sx_enable_rx_interrupts(void *ptr) | |||
1415 | } | 1414 | } |
1416 | 1415 | ||
1417 | /* Jeez. Isn't this simple? */ | 1416 | /* Jeez. Isn't this simple? */ |
1418 | static int sx_get_CD(void *ptr) | 1417 | static int sx_carrier_raised(struct tty_port *port) |
1419 | { | 1418 | { |
1420 | struct sx_port *port = ptr; | 1419 | struct sx_port *sp = container_of(port, struct sx_port, gs.port); |
1421 | func_enter2(); | 1420 | return ((sx_read_channel_byte(sp, hi_ip) & IP_DCD) != 0); |
1422 | |||
1423 | func_exit(); | ||
1424 | return ((sx_read_channel_byte(port, hi_ip) & IP_DCD) != 0); | ||
1425 | } | 1421 | } |
1426 | 1422 | ||
1427 | /* Jeez. Isn't this simple? */ | 1423 | /* Jeez. Isn't this simple? */ |
@@ -1536,7 +1532,7 @@ static int sx_open(struct tty_struct *tty, struct file *filp) | |||
1536 | } | 1532 | } |
1537 | /* tty->low_latency = 1; */ | 1533 | /* tty->low_latency = 1; */ |
1538 | 1534 | ||
1539 | port->c_dcd = sx_get_CD(port); | 1535 | port->c_dcd = sx_carrier_raised(&port->gs.port); |
1540 | sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); | 1536 | sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); |
1541 | 1537 | ||
1542 | func_exit(); | 1538 | func_exit(); |
@@ -2354,6 +2350,10 @@ static const struct tty_operations sx_ops = { | |||
2354 | .tiocmset = sx_tiocmset, | 2350 | .tiocmset = sx_tiocmset, |
2355 | }; | 2351 | }; |
2356 | 2352 | ||
2353 | static const struct tty_port_operations sx_port_ops = { | ||
2354 | .carrier_raised = sx_carrier_raised, | ||
2355 | }; | ||
2356 | |||
2357 | static int sx_init_drivers(void) | 2357 | static int sx_init_drivers(void) |
2358 | { | 2358 | { |
2359 | int error; | 2359 | int error; |
@@ -2410,6 +2410,7 @@ static int sx_init_portstructs(int nboards, int nports) | |||
2410 | for (j = 0; j < boards[i].nports; j++) { | 2410 | for (j = 0; j < boards[i].nports; j++) { |
2411 | sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); | 2411 | sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); |
2412 | tty_port_init(&port->gs.port); | 2412 | tty_port_init(&port->gs.port); |
2413 | port->gs.port.ops = &sx_port_ops; | ||
2413 | port->gs.magic = SX_MAGIC; | 2414 | port->gs.magic = SX_MAGIC; |
2414 | port->gs.close_delay = HZ / 2; | 2415 | port->gs.close_delay = HZ / 2; |
2415 | port->gs.closing_wait = 30 * HZ; | 2416 | port->gs.closing_wait = 30 * HZ; |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 500f5176b6ba..fb2e6b5e0ef1 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -3281,6 +3281,23 @@ static void mgsl_hangup(struct tty_struct *tty) | |||
3281 | 3281 | ||
3282 | } /* end of mgsl_hangup() */ | 3282 | } /* end of mgsl_hangup() */ |
3283 | 3283 | ||
3284 | /* | ||
3285 | * carrier_raised() | ||
3286 | * | ||
3287 | * Return true if carrier is raised | ||
3288 | */ | ||
3289 | |||
3290 | static int carrier_raised(struct tty_port *port) | ||
3291 | { | ||
3292 | unsigned long flags; | ||
3293 | struct mgsl_struct *info = container_of(port, struct mgsl_struct, port); | ||
3294 | |||
3295 | spin_lock_irqsave(&info->irq_spinlock, flags); | ||
3296 | usc_get_serial_signals(info); | ||
3297 | spin_unlock_irqrestore(&info->irq_spinlock, flags); | ||
3298 | return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; | ||
3299 | } | ||
3300 | |||
3284 | /* block_til_ready() | 3301 | /* block_til_ready() |
3285 | * | 3302 | * |
3286 | * Block the current process until the specified port | 3303 | * Block the current process until the specified port |
@@ -3302,6 +3319,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3302 | bool do_clocal = false; | 3319 | bool do_clocal = false; |
3303 | bool extra_count = false; | 3320 | bool extra_count = false; |
3304 | unsigned long flags; | 3321 | unsigned long flags; |
3322 | int dcd; | ||
3323 | struct tty_port *port = &info->port; | ||
3305 | 3324 | ||
3306 | if (debug_level >= DEBUG_LEVEL_INFO) | 3325 | if (debug_level >= DEBUG_LEVEL_INFO) |
3307 | printk("%s(%d):block_til_ready on %s\n", | 3326 | printk("%s(%d):block_til_ready on %s\n", |
@@ -3309,7 +3328,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3309 | 3328 | ||
3310 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 3329 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ |
3311 | /* nonblock mode is set or port is not enabled */ | 3330 | /* nonblock mode is set or port is not enabled */ |
3312 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 3331 | port->flags |= ASYNC_NORMAL_ACTIVE; |
3313 | return 0; | 3332 | return 0; |
3314 | } | 3333 | } |
3315 | 3334 | ||
@@ -3318,25 +3337,25 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3318 | 3337 | ||
3319 | /* Wait for carrier detect and the line to become | 3338 | /* Wait for carrier detect and the line to become |
3320 | * free (i.e., not in use by the callout). While we are in | 3339 | * free (i.e., not in use by the callout). While we are in |
3321 | * this loop, info->port.count is dropped by one, so that | 3340 | * this loop, port->count is dropped by one, so that |
3322 | * mgsl_close() knows when to free things. We restore it upon | 3341 | * mgsl_close() knows when to free things. We restore it upon |
3323 | * exit, either normal or abnormal. | 3342 | * exit, either normal or abnormal. |
3324 | */ | 3343 | */ |
3325 | 3344 | ||
3326 | retval = 0; | 3345 | retval = 0; |
3327 | add_wait_queue(&info->port.open_wait, &wait); | 3346 | add_wait_queue(&port->open_wait, &wait); |
3328 | 3347 | ||
3329 | if (debug_level >= DEBUG_LEVEL_INFO) | 3348 | if (debug_level >= DEBUG_LEVEL_INFO) |
3330 | printk("%s(%d):block_til_ready before block on %s count=%d\n", | 3349 | printk("%s(%d):block_til_ready before block on %s count=%d\n", |
3331 | __FILE__,__LINE__, tty->driver->name, info->port.count ); | 3350 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3332 | 3351 | ||
3333 | spin_lock_irqsave(&info->irq_spinlock, flags); | 3352 | spin_lock_irqsave(&info->irq_spinlock, flags); |
3334 | if (!tty_hung_up_p(filp)) { | 3353 | if (!tty_hung_up_p(filp)) { |
3335 | extra_count = true; | 3354 | extra_count = true; |
3336 | info->port.count--; | 3355 | port->count--; |
3337 | } | 3356 | } |
3338 | spin_unlock_irqrestore(&info->irq_spinlock, flags); | 3357 | spin_unlock_irqrestore(&info->irq_spinlock, flags); |
3339 | info->port.blocked_open++; | 3358 | port->blocked_open++; |
3340 | 3359 | ||
3341 | while (1) { | 3360 | while (1) { |
3342 | if (tty->termios->c_cflag & CBAUD) { | 3361 | if (tty->termios->c_cflag & CBAUD) { |
@@ -3348,20 +3367,16 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3348 | 3367 | ||
3349 | set_current_state(TASK_INTERRUPTIBLE); | 3368 | set_current_state(TASK_INTERRUPTIBLE); |
3350 | 3369 | ||
3351 | if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){ | 3370 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ |
3352 | retval = (info->port.flags & ASYNC_HUP_NOTIFY) ? | 3371 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
3353 | -EAGAIN : -ERESTARTSYS; | 3372 | -EAGAIN : -ERESTARTSYS; |
3354 | break; | 3373 | break; |
3355 | } | 3374 | } |
3356 | 3375 | ||
3357 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3376 | dcd = tty_port_carrier_raised(&info->port); |
3358 | usc_get_serial_signals(info); | ||
3359 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | ||
3360 | 3377 | ||
3361 | if (!(info->port.flags & ASYNC_CLOSING) && | 3378 | if (!(port->flags & ASYNC_CLOSING) && (do_clocal || dcd)) |
3362 | (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) { | ||
3363 | break; | 3379 | break; |
3364 | } | ||
3365 | 3380 | ||
3366 | if (signal_pending(current)) { | 3381 | if (signal_pending(current)) { |
3367 | retval = -ERESTARTSYS; | 3382 | retval = -ERESTARTSYS; |
@@ -3370,24 +3385,24 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3370 | 3385 | ||
3371 | if (debug_level >= DEBUG_LEVEL_INFO) | 3386 | if (debug_level >= DEBUG_LEVEL_INFO) |
3372 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", | 3387 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", |
3373 | __FILE__,__LINE__, tty->driver->name, info->port.count ); | 3388 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3374 | 3389 | ||
3375 | schedule(); | 3390 | schedule(); |
3376 | } | 3391 | } |
3377 | 3392 | ||
3378 | set_current_state(TASK_RUNNING); | 3393 | set_current_state(TASK_RUNNING); |
3379 | remove_wait_queue(&info->port.open_wait, &wait); | 3394 | remove_wait_queue(&port->open_wait, &wait); |
3380 | 3395 | ||
3381 | if (extra_count) | 3396 | if (extra_count) |
3382 | info->port.count++; | 3397 | port->count++; |
3383 | info->port.blocked_open--; | 3398 | port->blocked_open--; |
3384 | 3399 | ||
3385 | if (debug_level >= DEBUG_LEVEL_INFO) | 3400 | if (debug_level >= DEBUG_LEVEL_INFO) |
3386 | printk("%s(%d):block_til_ready after blocking on %s count=%d\n", | 3401 | printk("%s(%d):block_til_ready after blocking on %s count=%d\n", |
3387 | __FILE__,__LINE__, tty->driver->name, info->port.count ); | 3402 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3388 | 3403 | ||
3389 | if (!retval) | 3404 | if (!retval) |
3390 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 3405 | port->flags |= ASYNC_NORMAL_ACTIVE; |
3391 | 3406 | ||
3392 | return retval; | 3407 | return retval; |
3393 | 3408 | ||
@@ -4304,6 +4319,11 @@ static void mgsl_add_device( struct mgsl_struct *info ) | |||
4304 | 4319 | ||
4305 | } /* end of mgsl_add_device() */ | 4320 | } /* end of mgsl_add_device() */ |
4306 | 4321 | ||
4322 | static const struct tty_port_operations mgsl_port_ops = { | ||
4323 | .carrier_raised = carrier_raised, | ||
4324 | }; | ||
4325 | |||
4326 | |||
4307 | /* mgsl_allocate_device() | 4327 | /* mgsl_allocate_device() |
4308 | * | 4328 | * |
4309 | * Allocate and initialize a device instance structure | 4329 | * Allocate and initialize a device instance structure |
@@ -4322,6 +4342,7 @@ static struct mgsl_struct* mgsl_allocate_device(void) | |||
4322 | printk("Error can't allocate device instance data\n"); | 4342 | printk("Error can't allocate device instance data\n"); |
4323 | } else { | 4343 | } else { |
4324 | tty_port_init(&info->port); | 4344 | tty_port_init(&info->port); |
4345 | info->port.ops = &mgsl_port_ops; | ||
4325 | info->magic = MGSL_MAGIC; | 4346 | info->magic = MGSL_MAGIC; |
4326 | INIT_WORK(&info->task, mgsl_bh_handler); | 4347 | INIT_WORK(&info->task, mgsl_bh_handler); |
4327 | info->max_frame_size = 4096; | 4348 | info->max_frame_size = 4096; |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 08911ed66494..39ccaba8ca37 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -3132,6 +3132,17 @@ static int tiocmset(struct tty_struct *tty, struct file *file, | |||
3132 | return 0; | 3132 | return 0; |
3133 | } | 3133 | } |
3134 | 3134 | ||
3135 | static int carrier_raised(struct tty_port *port) | ||
3136 | { | ||
3137 | unsigned long flags; | ||
3138 | struct slgt_info *info = container_of(port, struct slgt_info, port); | ||
3139 | |||
3140 | spin_lock_irqsave(&info->lock,flags); | ||
3141 | get_signals(info); | ||
3142 | spin_unlock_irqrestore(&info->lock,flags); | ||
3143 | return (info->signals & SerialSignal_DCD) ? 1 : 0; | ||
3144 | } | ||
3145 | |||
3135 | /* | 3146 | /* |
3136 | * block current process until the device is ready to open | 3147 | * block current process until the device is ready to open |
3137 | */ | 3148 | */ |
@@ -3143,12 +3154,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3143 | bool do_clocal = false; | 3154 | bool do_clocal = false; |
3144 | bool extra_count = false; | 3155 | bool extra_count = false; |
3145 | unsigned long flags; | 3156 | unsigned long flags; |
3157 | int cd; | ||
3158 | struct tty_port *port = &info->port; | ||
3146 | 3159 | ||
3147 | DBGINFO(("%s block_til_ready\n", tty->driver->name)); | 3160 | DBGINFO(("%s block_til_ready\n", tty->driver->name)); |
3148 | 3161 | ||
3149 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 3162 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ |
3150 | /* nonblock mode is set or port is not enabled */ | 3163 | /* nonblock mode is set or port is not enabled */ |
3151 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 3164 | port->flags |= ASYNC_NORMAL_ACTIVE; |
3152 | return 0; | 3165 | return 0; |
3153 | } | 3166 | } |
3154 | 3167 | ||
@@ -3157,21 +3170,21 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3157 | 3170 | ||
3158 | /* Wait for carrier detect and the line to become | 3171 | /* Wait for carrier detect and the line to become |
3159 | * free (i.e., not in use by the callout). While we are in | 3172 | * free (i.e., not in use by the callout). While we are in |
3160 | * this loop, info->port.count is dropped by one, so that | 3173 | * this loop, port->count is dropped by one, so that |
3161 | * close() knows when to free things. We restore it upon | 3174 | * close() knows when to free things. We restore it upon |
3162 | * exit, either normal or abnormal. | 3175 | * exit, either normal or abnormal. |
3163 | */ | 3176 | */ |
3164 | 3177 | ||
3165 | retval = 0; | 3178 | retval = 0; |
3166 | add_wait_queue(&info->port.open_wait, &wait); | 3179 | add_wait_queue(&port->open_wait, &wait); |
3167 | 3180 | ||
3168 | spin_lock_irqsave(&info->lock, flags); | 3181 | spin_lock_irqsave(&info->lock, flags); |
3169 | if (!tty_hung_up_p(filp)) { | 3182 | if (!tty_hung_up_p(filp)) { |
3170 | extra_count = true; | 3183 | extra_count = true; |
3171 | info->port.count--; | 3184 | port->count--; |
3172 | } | 3185 | } |
3173 | spin_unlock_irqrestore(&info->lock, flags); | 3186 | spin_unlock_irqrestore(&info->lock, flags); |
3174 | info->port.blocked_open++; | 3187 | port->blocked_open++; |
3175 | 3188 | ||
3176 | while (1) { | 3189 | while (1) { |
3177 | if ((tty->termios->c_cflag & CBAUD)) { | 3190 | if ((tty->termios->c_cflag & CBAUD)) { |
@@ -3183,20 +3196,16 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3183 | 3196 | ||
3184 | set_current_state(TASK_INTERRUPTIBLE); | 3197 | set_current_state(TASK_INTERRUPTIBLE); |
3185 | 3198 | ||
3186 | if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){ | 3199 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ |
3187 | retval = (info->port.flags & ASYNC_HUP_NOTIFY) ? | 3200 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
3188 | -EAGAIN : -ERESTARTSYS; | 3201 | -EAGAIN : -ERESTARTSYS; |
3189 | break; | 3202 | break; |
3190 | } | 3203 | } |
3191 | 3204 | ||
3192 | spin_lock_irqsave(&info->lock,flags); | 3205 | cd = tty_port_carrier_raised(port); |
3193 | get_signals(info); | ||
3194 | spin_unlock_irqrestore(&info->lock,flags); | ||
3195 | 3206 | ||
3196 | if (!(info->port.flags & ASYNC_CLOSING) && | 3207 | if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd )) |
3197 | (do_clocal || (info->signals & SerialSignal_DCD)) ) { | ||
3198 | break; | 3208 | break; |
3199 | } | ||
3200 | 3209 | ||
3201 | if (signal_pending(current)) { | 3210 | if (signal_pending(current)) { |
3202 | retval = -ERESTARTSYS; | 3211 | retval = -ERESTARTSYS; |
@@ -3208,14 +3217,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3208 | } | 3217 | } |
3209 | 3218 | ||
3210 | set_current_state(TASK_RUNNING); | 3219 | set_current_state(TASK_RUNNING); |
3211 | remove_wait_queue(&info->port.open_wait, &wait); | 3220 | remove_wait_queue(&port->open_wait, &wait); |
3212 | 3221 | ||
3213 | if (extra_count) | 3222 | if (extra_count) |
3214 | info->port.count++; | 3223 | port->count++; |
3215 | info->port.blocked_open--; | 3224 | port->blocked_open--; |
3216 | 3225 | ||
3217 | if (!retval) | 3226 | if (!retval) |
3218 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 3227 | port->flags |= ASYNC_NORMAL_ACTIVE; |
3219 | 3228 | ||
3220 | DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); | 3229 | DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); |
3221 | return retval; | 3230 | return retval; |
@@ -3444,6 +3453,10 @@ static void add_device(struct slgt_info *info) | |||
3444 | #endif | 3453 | #endif |
3445 | } | 3454 | } |
3446 | 3455 | ||
3456 | static const struct tty_port_operations slgt_port_ops = { | ||
3457 | .carrier_raised = carrier_raised, | ||
3458 | }; | ||
3459 | |||
3447 | /* | 3460 | /* |
3448 | * allocate device instance structure, return NULL on failure | 3461 | * allocate device instance structure, return NULL on failure |
3449 | */ | 3462 | */ |
@@ -3458,6 +3471,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev | |||
3458 | driver_name, adapter_num, port_num)); | 3471 | driver_name, adapter_num, port_num)); |
3459 | } else { | 3472 | } else { |
3460 | tty_port_init(&info->port); | 3473 | tty_port_init(&info->port); |
3474 | info->port.ops = &slgt_port_ops; | ||
3461 | info->magic = MGSL_MAGIC; | 3475 | info->magic = MGSL_MAGIC; |
3462 | INIT_WORK(&info->task, bh_handler); | 3476 | INIT_WORK(&info->task, bh_handler); |
3463 | info->max_frame_size = 4096; | 3477 | info->max_frame_size = 4096; |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 6bdb44f7bec2..fcf1ec77450d 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -558,6 +558,7 @@ static void release_resources(SLMP_INFO *info); | |||
558 | 558 | ||
559 | static int startup(SLMP_INFO *info); | 559 | static int startup(SLMP_INFO *info); |
560 | static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info); | 560 | static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info); |
561 | static int carrier_raised(struct tty_port *port); | ||
561 | static void shutdown(SLMP_INFO *info); | 562 | static void shutdown(SLMP_INFO *info); |
562 | static void program_hw(SLMP_INFO *info); | 563 | static void program_hw(SLMP_INFO *info); |
563 | static void change_params(SLMP_INFO *info); | 564 | static void change_params(SLMP_INFO *info); |
@@ -3318,7 +3319,17 @@ static int tiocmset(struct tty_struct *tty, struct file *file, | |||
3318 | return 0; | 3319 | return 0; |
3319 | } | 3320 | } |
3320 | 3321 | ||
3322 | static int carrier_raised(struct tty_port *port) | ||
3323 | { | ||
3324 | SLMP_INFO *info = container_of(port, SLMP_INFO, port); | ||
3325 | unsigned long flags; | ||
3321 | 3326 | ||
3327 | spin_lock_irqsave(&info->lock,flags); | ||
3328 | get_signals(info); | ||
3329 | spin_unlock_irqrestore(&info->lock,flags); | ||
3330 | |||
3331 | return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; | ||
3332 | } | ||
3322 | 3333 | ||
3323 | /* Block the current process until the specified port is ready to open. | 3334 | /* Block the current process until the specified port is ready to open. |
3324 | */ | 3335 | */ |
@@ -3330,6 +3341,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3330 | bool do_clocal = false; | 3341 | bool do_clocal = false; |
3331 | bool extra_count = false; | 3342 | bool extra_count = false; |
3332 | unsigned long flags; | 3343 | unsigned long flags; |
3344 | int cd; | ||
3345 | struct tty_port *port = &info->port; | ||
3333 | 3346 | ||
3334 | if (debug_level >= DEBUG_LEVEL_INFO) | 3347 | if (debug_level >= DEBUG_LEVEL_INFO) |
3335 | printk("%s(%d):%s block_til_ready()\n", | 3348 | printk("%s(%d):%s block_til_ready()\n", |
@@ -3338,7 +3351,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3338 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 3351 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ |
3339 | /* nonblock mode is set or port is not enabled */ | 3352 | /* nonblock mode is set or port is not enabled */ |
3340 | /* just verify that callout device is not active */ | 3353 | /* just verify that callout device is not active */ |
3341 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 3354 | port->flags |= ASYNC_NORMAL_ACTIVE; |
3342 | return 0; | 3355 | return 0; |
3343 | } | 3356 | } |
3344 | 3357 | ||
@@ -3347,25 +3360,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3347 | 3360 | ||
3348 | /* Wait for carrier detect and the line to become | 3361 | /* Wait for carrier detect and the line to become |
3349 | * free (i.e., not in use by the callout). While we are in | 3362 | * free (i.e., not in use by the callout). While we are in |
3350 | * this loop, info->port.count is dropped by one, so that | 3363 | * this loop, port->count is dropped by one, so that |
3351 | * close() knows when to free things. We restore it upon | 3364 | * close() knows when to free things. We restore it upon |
3352 | * exit, either normal or abnormal. | 3365 | * exit, either normal or abnormal. |
3353 | */ | 3366 | */ |
3354 | 3367 | ||
3355 | retval = 0; | 3368 | retval = 0; |
3356 | add_wait_queue(&info->port.open_wait, &wait); | 3369 | add_wait_queue(&port->open_wait, &wait); |
3357 | 3370 | ||
3358 | if (debug_level >= DEBUG_LEVEL_INFO) | 3371 | if (debug_level >= DEBUG_LEVEL_INFO) |
3359 | printk("%s(%d):%s block_til_ready() before block, count=%d\n", | 3372 | printk("%s(%d):%s block_til_ready() before block, count=%d\n", |
3360 | __FILE__,__LINE__, tty->driver->name, info->port.count ); | 3373 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3361 | 3374 | ||
3362 | spin_lock_irqsave(&info->lock, flags); | 3375 | spin_lock_irqsave(&info->lock, flags); |
3363 | if (!tty_hung_up_p(filp)) { | 3376 | if (!tty_hung_up_p(filp)) { |
3364 | extra_count = true; | 3377 | extra_count = true; |
3365 | info->port.count--; | 3378 | port->count--; |
3366 | } | 3379 | } |
3367 | spin_unlock_irqrestore(&info->lock, flags); | 3380 | spin_unlock_irqrestore(&info->lock, flags); |
3368 | info->port.blocked_open++; | 3381 | port->blocked_open++; |
3369 | 3382 | ||
3370 | while (1) { | 3383 | while (1) { |
3371 | if ((tty->termios->c_cflag & CBAUD)) { | 3384 | if ((tty->termios->c_cflag & CBAUD)) { |
@@ -3377,20 +3390,16 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3377 | 3390 | ||
3378 | set_current_state(TASK_INTERRUPTIBLE); | 3391 | set_current_state(TASK_INTERRUPTIBLE); |
3379 | 3392 | ||
3380 | if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){ | 3393 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ |
3381 | retval = (info->port.flags & ASYNC_HUP_NOTIFY) ? | 3394 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
3382 | -EAGAIN : -ERESTARTSYS; | 3395 | -EAGAIN : -ERESTARTSYS; |
3383 | break; | 3396 | break; |
3384 | } | 3397 | } |
3385 | 3398 | ||
3386 | spin_lock_irqsave(&info->lock,flags); | 3399 | cd = tty_port_carrier_raised(port); |
3387 | get_signals(info); | ||
3388 | spin_unlock_irqrestore(&info->lock,flags); | ||
3389 | 3400 | ||
3390 | if (!(info->port.flags & ASYNC_CLOSING) && | 3401 | if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd)) |
3391 | (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) { | ||
3392 | break; | 3402 | break; |
3393 | } | ||
3394 | 3403 | ||
3395 | if (signal_pending(current)) { | 3404 | if (signal_pending(current)) { |
3396 | retval = -ERESTARTSYS; | 3405 | retval = -ERESTARTSYS; |
@@ -3399,24 +3408,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3399 | 3408 | ||
3400 | if (debug_level >= DEBUG_LEVEL_INFO) | 3409 | if (debug_level >= DEBUG_LEVEL_INFO) |
3401 | printk("%s(%d):%s block_til_ready() count=%d\n", | 3410 | printk("%s(%d):%s block_til_ready() count=%d\n", |
3402 | __FILE__,__LINE__, tty->driver->name, info->port.count ); | 3411 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3403 | 3412 | ||
3404 | schedule(); | 3413 | schedule(); |
3405 | } | 3414 | } |
3406 | 3415 | ||
3407 | set_current_state(TASK_RUNNING); | 3416 | set_current_state(TASK_RUNNING); |
3408 | remove_wait_queue(&info->port.open_wait, &wait); | 3417 | remove_wait_queue(&port->open_wait, &wait); |
3409 | 3418 | ||
3410 | if (extra_count) | 3419 | if (extra_count) |
3411 | info->port.count++; | 3420 | port->count++; |
3412 | info->port.blocked_open--; | 3421 | port->blocked_open--; |
3413 | 3422 | ||
3414 | if (debug_level >= DEBUG_LEVEL_INFO) | 3423 | if (debug_level >= DEBUG_LEVEL_INFO) |
3415 | printk("%s(%d):%s block_til_ready() after, count=%d\n", | 3424 | printk("%s(%d):%s block_til_ready() after, count=%d\n", |
3416 | __FILE__,__LINE__, tty->driver->name, info->port.count ); | 3425 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3417 | 3426 | ||
3418 | if (!retval) | 3427 | if (!retval) |
3419 | info->port.flags |= ASYNC_NORMAL_ACTIVE; | 3428 | port->flags |= ASYNC_NORMAL_ACTIVE; |
3420 | 3429 | ||
3421 | return retval; | 3430 | return retval; |
3422 | } | 3431 | } |
@@ -3782,6 +3791,10 @@ static void add_device(SLMP_INFO *info) | |||
3782 | #endif | 3791 | #endif |
3783 | } | 3792 | } |
3784 | 3793 | ||
3794 | static const struct tty_port_operations port_ops = { | ||
3795 | .carrier_raised = carrier_raised, | ||
3796 | }; | ||
3797 | |||
3785 | /* Allocate and initialize a device instance structure | 3798 | /* Allocate and initialize a device instance structure |
3786 | * | 3799 | * |
3787 | * Return Value: pointer to SLMP_INFO if success, otherwise NULL | 3800 | * Return Value: pointer to SLMP_INFO if success, otherwise NULL |
@@ -3798,6 +3811,7 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) | |||
3798 | __FILE__,__LINE__, adapter_num, port_num); | 3811 | __FILE__,__LINE__, adapter_num, port_num); |
3799 | } else { | 3812 | } else { |
3800 | tty_port_init(&info->port); | 3813 | tty_port_init(&info->port); |
3814 | info->port.ops = &port_ops; | ||
3801 | info->magic = MGSL_MAGIC; | 3815 | info->magic = MGSL_MAGIC; |
3802 | INIT_WORK(&info->task, bh_handler); | 3816 | INIT_WORK(&info->task, bh_handler); |
3803 | info->max_frame_size = 4096; | 3817 | info->max_frame_size = 4096; |
@@ -3940,6 +3954,7 @@ static const struct tty_operations ops = { | |||
3940 | .tiocmset = tiocmset, | 3954 | .tiocmset = tiocmset, |
3941 | }; | 3955 | }; |
3942 | 3956 | ||
3957 | |||
3943 | static void synclinkmp_cleanup(void) | 3958 | static void synclinkmp_cleanup(void) |
3944 | { | 3959 | { |
3945 | int rc; | 3960 | int rc; |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index c8f8024cb40e..f54e40cbf023 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -94,3 +94,20 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) | |||
94 | spin_unlock_irqrestore(&port->lock, flags); | 94 | spin_unlock_irqrestore(&port->lock, flags); |
95 | } | 95 | } |
96 | EXPORT_SYMBOL(tty_port_tty_set); | 96 | EXPORT_SYMBOL(tty_port_tty_set); |
97 | |||
98 | /** | ||
99 | * tty_port_carrier_raised - carrier raised check | ||
100 | * @port: tty port | ||
101 | * | ||
102 | * Wrapper for the carrier detect logic. For the moment this is used | ||
103 | * to hide some internal details. This will eventually become entirely | ||
104 | * internal to the tty port. | ||
105 | */ | ||
106 | |||
107 | int tty_port_carrier_raised(struct tty_port *port) | ||
108 | { | ||
109 | if (port->ops->carrier_raised == NULL) | ||
110 | return 1; | ||
111 | return port->ops->carrier_raised(port); | ||
112 | } | ||
113 | EXPORT_SYMBOL(tty_port_carrier_raised); | ||
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index 1718b3c481db..d4e1534c0e03 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c | |||
@@ -69,7 +69,7 @@ static void scc_disable_tx_interrupts(void * ptr); | |||
69 | static void scc_enable_tx_interrupts(void * ptr); | 69 | static void scc_enable_tx_interrupts(void * ptr); |
70 | static void scc_disable_rx_interrupts(void * ptr); | 70 | static void scc_disable_rx_interrupts(void * ptr); |
71 | static void scc_enable_rx_interrupts(void * ptr); | 71 | static void scc_enable_rx_interrupts(void * ptr); |
72 | static int scc_get_CD(void * ptr); | 72 | static int scc_carrier_raised(struct tty_port *port); |
73 | static void scc_shutdown_port(void * ptr); | 73 | static void scc_shutdown_port(void * ptr); |
74 | static int scc_set_real_termios(void *ptr); | 74 | static int scc_set_real_termios(void *ptr); |
75 | static void scc_hungup(void *ptr); | 75 | static void scc_hungup(void *ptr); |
@@ -100,7 +100,6 @@ static struct real_driver scc_real_driver = { | |||
100 | scc_enable_tx_interrupts, | 100 | scc_enable_tx_interrupts, |
101 | scc_disable_rx_interrupts, | 101 | scc_disable_rx_interrupts, |
102 | scc_enable_rx_interrupts, | 102 | scc_enable_rx_interrupts, |
103 | scc_get_CD, | ||
104 | scc_shutdown_port, | 103 | scc_shutdown_port, |
105 | scc_set_real_termios, | 104 | scc_set_real_termios, |
106 | scc_chars_in_buffer, | 105 | scc_chars_in_buffer, |
@@ -129,6 +128,10 @@ static const struct tty_operations scc_ops = { | |||
129 | .break_ctl = scc_break_ctl, | 128 | .break_ctl = scc_break_ctl, |
130 | }; | 129 | }; |
131 | 130 | ||
131 | static const struct tty_port_operations scc_port_ops = { | ||
132 | .carrier_raised = scc_carrier_raised, | ||
133 | }; | ||
134 | |||
132 | /*---------------------------------------------------------------------------- | 135 | /*---------------------------------------------------------------------------- |
133 | * vme_scc_init() and support functions | 136 | * vme_scc_init() and support functions |
134 | *---------------------------------------------------------------------------*/ | 137 | *---------------------------------------------------------------------------*/ |
@@ -176,6 +179,8 @@ static void scc_init_portstructs(void) | |||
176 | 179 | ||
177 | for (i = 0; i < 2; i++) { | 180 | for (i = 0; i < 2; i++) { |
178 | port = scc_ports + i; | 181 | port = scc_ports + i; |
182 | tty_port_init(&port->gs.port); | ||
183 | port->gs.port.ops = &scc_port_ops; | ||
179 | port->gs.magic = SCC_MAGIC; | 184 | port->gs.magic = SCC_MAGIC; |
180 | port->gs.close_delay = HZ/2; | 185 | port->gs.close_delay = HZ/2; |
181 | port->gs.closing_wait = 30 * HZ; | 186 | port->gs.closing_wait = 30 * HZ; |
@@ -624,9 +629,9 @@ static void scc_enable_rx_interrupts(void *ptr) | |||
624 | } | 629 | } |
625 | 630 | ||
626 | 631 | ||
627 | static int scc_get_CD(void *ptr) | 632 | static int scc_carrier_raised(struct tty_port *port) |
628 | { | 633 | { |
629 | struct scc_port *port = ptr; | 634 | struct scc_port *scc = container_of(port, struct scc_port, gs.port); |
630 | unsigned channel = port->channel; | 635 | unsigned channel = port->channel; |
631 | 636 | ||
632 | return !!(scc_last_status_reg[channel] & SR_DCD); | 637 | return !!(scc_last_status_reg[channel] & SR_DCD); |
@@ -896,7 +901,7 @@ static int scc_open (struct tty_struct * tty, struct file * filp) | |||
896 | return retval; | 901 | return retval; |
897 | } | 902 | } |
898 | 903 | ||
899 | port->c_dcd = scc_get_CD (port); | 904 | port->c_dcd = tty_port_carrier_raised(&port->gs.port); |
900 | 905 | ||
901 | scc_enable_rx_interrupts(port); | 906 | scc_enable_rx_interrupts(port); |
902 | 907 | ||
diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h index 4cc913939817..fadff28505bb 100644 --- a/include/linux/generic_serial.h +++ b/include/linux/generic_serial.h | |||
@@ -21,7 +21,6 @@ struct real_driver { | |||
21 | void (*enable_tx_interrupts) (void *); | 21 | void (*enable_tx_interrupts) (void *); |
22 | void (*disable_rx_interrupts) (void *); | 22 | void (*disable_rx_interrupts) (void *); |
23 | void (*enable_rx_interrupts) (void *); | 23 | void (*enable_rx_interrupts) (void *); |
24 | int (*get_CD) (void *); | ||
25 | void (*shutdown_port) (void*); | 24 | void (*shutdown_port) (void*); |
26 | int (*set_real_termios) (void*); | 25 | int (*set_real_termios) (void*); |
27 | int (*chars_in_buffer) (void*); | 26 | int (*chars_in_buffer) (void*); |
diff --git a/include/linux/tty.h b/include/linux/tty.h index bbbeaef99626..bc7bae78e22f 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -180,8 +180,16 @@ struct signal_struct; | |||
180 | * until a hangup so don't use the wrong path. | 180 | * until a hangup so don't use the wrong path. |
181 | */ | 181 | */ |
182 | 182 | ||
183 | struct tty_port; | ||
184 | |||
185 | struct tty_port_operations { | ||
186 | /* Return 1 if the carrier is raised */ | ||
187 | int (*carrier_raised)(struct tty_port *port); | ||
188 | }; | ||
189 | |||
183 | struct tty_port { | 190 | struct tty_port { |
184 | struct tty_struct *tty; /* Back pointer */ | 191 | struct tty_struct *tty; /* Back pointer */ |
192 | const struct tty_port_operations *ops; /* Port operations */ | ||
185 | spinlock_t lock; /* Lock protecting tty field */ | 193 | spinlock_t lock; /* Lock protecting tty field */ |
186 | int blocked_open; /* Waiting to open */ | 194 | int blocked_open; /* Waiting to open */ |
187 | int count; /* Usage count */ | 195 | int count; /* Usage count */ |
@@ -427,6 +435,7 @@ extern int tty_port_alloc_xmit_buf(struct tty_port *port); | |||
427 | extern void tty_port_free_xmit_buf(struct tty_port *port); | 435 | extern void tty_port_free_xmit_buf(struct tty_port *port); |
428 | extern struct tty_struct *tty_port_tty_get(struct tty_port *port); | 436 | extern struct tty_struct *tty_port_tty_get(struct tty_port *port); |
429 | extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); | 437 | extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); |
438 | extern int tty_port_carrier_raised(struct tty_port *port); | ||
430 | 439 | ||
431 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); | 440 | extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); |
432 | extern int tty_unregister_ldisc(int disc); | 441 | extern int tty_unregister_ldisc(int disc); |