aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_port.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_port.c')
-rw-r--r--drivers/char/tty_port.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 9b8004c72686..62dadfc95e34 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -137,7 +137,7 @@ int tty_port_carrier_raised(struct tty_port *port)
137EXPORT_SYMBOL(tty_port_carrier_raised); 137EXPORT_SYMBOL(tty_port_carrier_raised);
138 138
139/** 139/**
140 * tty_port_raise_dtr_rts - Riase DTR/RTS 140 * tty_port_raise_dtr_rts - Raise DTR/RTS
141 * @port: tty port 141 * @port: tty port
142 * 142 *
143 * Wrapper for the DTR/RTS raise logic. For the moment this is used 143 * Wrapper for the DTR/RTS raise logic. For the moment this is used
@@ -147,12 +147,28 @@ EXPORT_SYMBOL(tty_port_carrier_raised);
147 147
148void tty_port_raise_dtr_rts(struct tty_port *port) 148void tty_port_raise_dtr_rts(struct tty_port *port)
149{ 149{
150 if (port->ops->raise_dtr_rts) 150 if (port->ops->dtr_rts)
151 port->ops->raise_dtr_rts(port); 151 port->ops->dtr_rts(port, 1);
152} 152}
153EXPORT_SYMBOL(tty_port_raise_dtr_rts); 153EXPORT_SYMBOL(tty_port_raise_dtr_rts);
154 154
155/** 155/**
156 * tty_port_lower_dtr_rts - Lower DTR/RTS
157 * @port: tty port
158 *
159 * Wrapper for the DTR/RTS raise logic. For the moment this is used
160 * to hide some internal details. This will eventually become entirely
161 * internal to the tty port.
162 */
163
164void tty_port_lower_dtr_rts(struct tty_port *port)
165{
166 if (port->ops->dtr_rts)
167 port->ops->dtr_rts(port, 0);
168}
169EXPORT_SYMBOL(tty_port_lower_dtr_rts);
170
171/**
156 * tty_port_block_til_ready - Waiting logic for tty open 172 * tty_port_block_til_ready - Waiting logic for tty open
157 * @port: the tty port being opened 173 * @port: the tty port being opened
158 * @tty: the tty device being bound 174 * @tty: the tty device being bound
@@ -167,7 +183,7 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts);
167 * - port flags and counts 183 * - port flags and counts
168 * 184 *
169 * The passed tty_port must implement the carrier_raised method if it can 185 * The passed tty_port must implement the carrier_raised method if it can
170 * do carrier detect and the raise_dtr_rts method if it supports software 186 * do carrier detect and the dtr_rts method if it supports software
171 * management of these lines. Note that the dtr/rts raise is done each 187 * management of these lines. Note that the dtr/rts raise is done each
172 * iteration as a hangup may have previously dropped them while we wait. 188 * iteration as a hangup may have previously dropped them while we wait.
173 */ 189 */
@@ -182,7 +198,8 @@ int tty_port_block_til_ready(struct tty_port *port,
182 198
183 /* block if port is in the process of being closed */ 199 /* block if port is in the process of being closed */
184 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 200 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
185 interruptible_sleep_on(&port->close_wait); 201 wait_event_interruptible(port->close_wait,
202 !(port->flags & ASYNC_CLOSING));
186 if (port->flags & ASYNC_HUP_NOTIFY) 203 if (port->flags & ASYNC_HUP_NOTIFY)
187 return -EAGAIN; 204 return -EAGAIN;
188 else 205 else
@@ -205,7 +222,6 @@ int tty_port_block_til_ready(struct tty_port *port,
205 before the next open may complete */ 222 before the next open may complete */
206 223
207 retval = 0; 224 retval = 0;
208 add_wait_queue(&port->open_wait, &wait);
209 225
210 /* The port lock protects the port counts */ 226 /* The port lock protects the port counts */
211 spin_lock_irqsave(&port->lock, flags); 227 spin_lock_irqsave(&port->lock, flags);
@@ -219,7 +235,7 @@ int tty_port_block_til_ready(struct tty_port *port,
219 if (tty->termios->c_cflag & CBAUD) 235 if (tty->termios->c_cflag & CBAUD)
220 tty_port_raise_dtr_rts(port); 236 tty_port_raise_dtr_rts(port);
221 237
222 set_current_state(TASK_INTERRUPTIBLE); 238 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
223 /* Check for a hangup or uninitialised port. Return accordingly */ 239 /* Check for a hangup or uninitialised port. Return accordingly */
224 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { 240 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
225 if (port->flags & ASYNC_HUP_NOTIFY) 241 if (port->flags & ASYNC_HUP_NOTIFY)
@@ -240,8 +256,7 @@ int tty_port_block_til_ready(struct tty_port *port,
240 } 256 }
241 schedule(); 257 schedule();
242 } 258 }
243 set_current_state(TASK_RUNNING); 259 finish_wait(&port->open_wait, &wait);
244 remove_wait_queue(&port->open_wait, &wait);
245 260
246 /* Update counts. A parallel hangup will have set count to zero and 261 /* Update counts. A parallel hangup will have set count to zero and
247 we must not mess that up further */ 262 we must not mess that up further */
@@ -292,6 +307,17 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
292 if (port->flags & ASYNC_INITIALIZED && 307 if (port->flags & ASYNC_INITIALIZED &&
293 port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 308 port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
294 tty_wait_until_sent(tty, port->closing_wait); 309 tty_wait_until_sent(tty, port->closing_wait);
310 if (port->drain_delay) {
311 unsigned int bps = tty_get_baud_rate(tty);
312 long timeout;
313
314 if (bps > 1200)
315 timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
316 HZ / 10);
317 else
318 timeout = 2 * HZ;
319 schedule_timeout_interruptible(timeout);
320 }
295 return 1; 321 return 1;
296} 322}
297EXPORT_SYMBOL(tty_port_close_start); 323EXPORT_SYMBOL(tty_port_close_start);
@@ -302,6 +328,9 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
302 328
303 tty_ldisc_flush(tty); 329 tty_ldisc_flush(tty);
304 330
331 if (tty->termios->c_cflag & HUPCL)
332 tty_port_lower_dtr_rts(port);
333
305 spin_lock_irqsave(&port->lock, flags); 334 spin_lock_irqsave(&port->lock, flags);
306 tty->closing = 0; 335 tty->closing = 0;
307 336