Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Tty port functions
  3 */
  4
  5#include <linux/types.h>
  6#include <linux/errno.h>
  7#include <linux/tty.h>
  8#include <linux/tty_driver.h>
  9#include <linux/tty_flip.h>
 10#include <linux/serial.h>
 11#include <linux/timer.h>
 12#include <linux/string.h>
 13#include <linux/slab.h>
 14#include <linux/sched.h>
 15#include <linux/init.h>
 16#include <linux/wait.h>
 17#include <linux/bitops.h>
 18#include <linux/delay.h>
 19#include <linux/module.h>
 20
 21void tty_port_init(struct tty_port *port)
 22{
 23	memset(port, 0, sizeof(*port));
 
 24	init_waitqueue_head(&port->open_wait);
 25	init_waitqueue_head(&port->close_wait);
 26	init_waitqueue_head(&port->delta_msr_wait);
 27	mutex_init(&port->mutex);
 28	mutex_init(&port->buf_mutex);
 29	spin_lock_init(&port->lock);
 30	port->close_delay = (50 * HZ) / 100;
 31	port->closing_wait = (3000 * HZ) / 100;
 32	kref_init(&port->kref);
 33}
 34EXPORT_SYMBOL(tty_port_init);
 35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 36int tty_port_alloc_xmit_buf(struct tty_port *port)
 37{
 38	/* We may sleep in get_zeroed_page() */
 39	mutex_lock(&port->buf_mutex);
 40	if (port->xmit_buf == NULL)
 41		port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
 42	mutex_unlock(&port->buf_mutex);
 43	if (port->xmit_buf == NULL)
 44		return -ENOMEM;
 45	return 0;
 46}
 47EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
 48
 49void tty_port_free_xmit_buf(struct tty_port *port)
 50{
 51	mutex_lock(&port->buf_mutex);
 52	if (port->xmit_buf != NULL) {
 53		free_page((unsigned long)port->xmit_buf);
 54		port->xmit_buf = NULL;
 55	}
 56	mutex_unlock(&port->buf_mutex);
 57}
 58EXPORT_SYMBOL(tty_port_free_xmit_buf);
 59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 60static void tty_port_destructor(struct kref *kref)
 61{
 62	struct tty_port *port = container_of(kref, struct tty_port, kref);
 
 
 
 
 63	if (port->xmit_buf)
 64		free_page((unsigned long)port->xmit_buf);
 65	if (port->ops->destruct)
 
 66		port->ops->destruct(port);
 67	else
 68		kfree(port);
 69}
 70
 71void tty_port_put(struct tty_port *port)
 72{
 73	if (port)
 74		kref_put(&port->kref, tty_port_destructor);
 75}
 76EXPORT_SYMBOL(tty_port_put);
 77
 78/**
 79 *	tty_port_tty_get	-	get a tty reference
 80 *	@port: tty port
 81 *
 82 *	Return a refcount protected tty instance or NULL if the port is not
 83 *	associated with a tty (eg due to close or hangup)
 84 */
 85
 86struct tty_struct *tty_port_tty_get(struct tty_port *port)
 87{
 88	unsigned long flags;
 89	struct tty_struct *tty;
 90
 91	spin_lock_irqsave(&port->lock, flags);
 92	tty = tty_kref_get(port->tty);
 93	spin_unlock_irqrestore(&port->lock, flags);
 94	return tty;
 95}
 96EXPORT_SYMBOL(tty_port_tty_get);
 97
 98/**
 99 *	tty_port_tty_set	-	set the tty of a port
100 *	@port: tty port
101 *	@tty: the tty
102 *
103 *	Associate the port and tty pair. Manages any internal refcounts.
104 *	Pass NULL to deassociate a port
105 */
106
107void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
108{
109	unsigned long flags;
110
111	spin_lock_irqsave(&port->lock, flags);
112	if (port->tty)
113		tty_kref_put(port->tty);
114	port->tty = tty_kref_get(tty);
115	spin_unlock_irqrestore(&port->lock, flags);
116}
117EXPORT_SYMBOL(tty_port_tty_set);
118
119static void tty_port_shutdown(struct tty_port *port)
120{
121	mutex_lock(&port->mutex);
122	if (port->ops->shutdown && !port->console &&
123		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
 
 
 
 
 
 
 
 
 
 
124			port->ops->shutdown(port);
 
 
125	mutex_unlock(&port->mutex);
126}
127
128/**
129 *	tty_port_hangup		-	hangup helper
130 *	@port: tty port
131 *
132 *	Perform port level tty hangup flag and count changes. Drop the tty
133 *	reference.
 
 
134 */
135
136void tty_port_hangup(struct tty_port *port)
137{
 
138	unsigned long flags;
139
140	spin_lock_irqsave(&port->lock, flags);
141	port->count = 0;
142	port->flags &= ~ASYNC_NORMAL_ACTIVE;
143	if (port->tty) {
144		set_bit(TTY_IO_ERROR, &port->tty->flags);
145		tty_kref_put(port->tty);
146	}
147	port->tty = NULL;
148	spin_unlock_irqrestore(&port->lock, flags);
 
 
149	wake_up_interruptible(&port->open_wait);
150	wake_up_interruptible(&port->delta_msr_wait);
151	tty_port_shutdown(port);
152}
153EXPORT_SYMBOL(tty_port_hangup);
154
155/**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156 *	tty_port_carrier_raised	-	carrier raised check
157 *	@port: tty port
158 *
159 *	Wrapper for the carrier detect 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
164int tty_port_carrier_raised(struct tty_port *port)
165{
166	if (port->ops->carrier_raised == NULL)
167		return 1;
168	return port->ops->carrier_raised(port);
169}
170EXPORT_SYMBOL(tty_port_carrier_raised);
171
172/**
173 *	tty_port_raise_dtr_rts	-	Raise DTR/RTS
174 *	@port: tty port
175 *
176 *	Wrapper for the DTR/RTS raise logic. For the moment this is used
177 *	to hide some internal details. This will eventually become entirely
178 *	internal to the tty port.
179 */
180
181void tty_port_raise_dtr_rts(struct tty_port *port)
182{
183	if (port->ops->dtr_rts)
184		port->ops->dtr_rts(port, 1);
185}
186EXPORT_SYMBOL(tty_port_raise_dtr_rts);
187
188/**
189 *	tty_port_lower_dtr_rts	-	Lower DTR/RTS
190 *	@port: tty port
191 *
192 *	Wrapper for the DTR/RTS raise logic. For the moment this is used
193 *	to hide some internal details. This will eventually become entirely
194 *	internal to the tty port.
195 */
196
197void tty_port_lower_dtr_rts(struct tty_port *port)
198{
199	if (port->ops->dtr_rts)
200		port->ops->dtr_rts(port, 0);
201}
202EXPORT_SYMBOL(tty_port_lower_dtr_rts);
203
204/**
205 *	tty_port_block_til_ready	-	Waiting logic for tty open
206 *	@port: the tty port being opened
207 *	@tty: the tty device being bound
208 *	@filp: the file pointer of the opener
209 *
210 *	Implement the core POSIX/SuS tty behaviour when opening a tty device.
211 *	Handles:
212 *		- hangup (both before and during)
213 *		- non blocking open
214 *		- rts/dtr/dcd
215 *		- signals
216 *		- port flags and counts
217 *
218 *	The passed tty_port must implement the carrier_raised method if it can
219 *	do carrier detect and the dtr_rts method if it supports software
220 *	management of these lines. Note that the dtr/rts raise is done each
221 *	iteration as a hangup may have previously dropped them while we wait.
 
 
 
 
 
222 */
223
224int tty_port_block_til_ready(struct tty_port *port,
225				struct tty_struct *tty, struct file *filp)
226{
227	int do_clocal = 0, retval;
228	unsigned long flags;
229	DEFINE_WAIT(wait);
230	int cd;
231
232	/* block if port is in the process of being closed */
233	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
234		wait_event_interruptible_tty(port->close_wait,
235				!(port->flags & ASYNC_CLOSING));
236		if (port->flags & ASYNC_HUP_NOTIFY)
237			return -EAGAIN;
238		else
239			return -ERESTARTSYS;
240	}
241
242	/* if non-blocking mode is set we can pass directly to open unless
243	   the port has just hung up or is in another error state */
244	if (tty->flags & (1 << TTY_IO_ERROR)) {
245		port->flags |= ASYNC_NORMAL_ACTIVE;
246		return 0;
247	}
248	if (filp->f_flags & O_NONBLOCK) {
249		/* Indicate we are open */
250		if (tty->termios->c_cflag & CBAUD)
251			tty_port_raise_dtr_rts(port);
252		port->flags |= ASYNC_NORMAL_ACTIVE;
253		return 0;
254	}
255
256	if (C_CLOCAL(tty))
257		do_clocal = 1;
258
259	/* Block waiting until we can proceed. We may need to wait for the
260	   carrier, but we must also wait for any close that is in progress
261	   before the next open may complete */
262
263	retval = 0;
264
265	/* The port lock protects the port counts */
266	spin_lock_irqsave(&port->lock, flags);
267	if (!tty_hung_up_p(filp))
268		port->count--;
269	port->blocked_open++;
270	spin_unlock_irqrestore(&port->lock, flags);
271
272	while (1) {
273		/* Indicate we are open */
274		if (tty->termios->c_cflag & CBAUD)
275			tty_port_raise_dtr_rts(port);
276
277		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
278		/* Check for a hangup or uninitialised port.
279							Return accordingly */
280		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
281			if (port->flags & ASYNC_HUP_NOTIFY)
282				retval = -EAGAIN;
283			else
284				retval = -ERESTARTSYS;
285			break;
286		}
287		/* Probe the carrier. For devices with no carrier detect this
288		   will always return true */
289		cd = tty_port_carrier_raised(port);
290		if (!(port->flags & ASYNC_CLOSING) &&
291				(do_clocal || cd))
 
 
292			break;
293		if (signal_pending(current)) {
294			retval = -ERESTARTSYS;
295			break;
296		}
297		tty_unlock();
298		schedule();
299		tty_lock();
300	}
301	finish_wait(&port->open_wait, &wait);
302
303	/* Update counts. A parallel hangup will have set count to zero and
304	   we must not mess that up further */
305	spin_lock_irqsave(&port->lock, flags);
306	if (!tty_hung_up_p(filp))
307		port->count++;
308	port->blocked_open--;
309	if (retval == 0)
310		port->flags |= ASYNC_NORMAL_ACTIVE;
311	spin_unlock_irqrestore(&port->lock, flags);
312	return retval;
313}
314EXPORT_SYMBOL(tty_port_block_til_ready);
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316int tty_port_close_start(struct tty_port *port,
317				struct tty_struct *tty, struct file *filp)
318{
319	unsigned long flags;
320
321	spin_lock_irqsave(&port->lock, flags);
322	if (tty_hung_up_p(filp)) {
323		spin_unlock_irqrestore(&port->lock, flags);
324		return 0;
325	}
326
 
327	if (tty->count == 1 && port->count != 1) {
328		printk(KERN_WARNING
329		    "tty_port_close_start: tty->count = 1 port count = %d.\n",
330								port->count);
331		port->count = 1;
332	}
333	if (--port->count < 0) {
334		printk(KERN_WARNING "tty_port_close_start: count = %d\n",
335								port->count);
336		port->count = 0;
337	}
338
339	if (port->count) {
340		spin_unlock_irqrestore(&port->lock, flags);
341		if (port->ops->drop)
342			port->ops->drop(port);
343		return 0;
344	}
345	set_bit(ASYNCB_CLOSING, &port->flags);
346	tty->closing = 1;
347	spin_unlock_irqrestore(&port->lock, flags);
348	/* Don't block on a stalled port, just pull the chain */
349	if (tty->flow_stopped)
350		tty_driver_flush_buffer(tty);
351	if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
352			port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
353		tty_wait_until_sent(tty, port->closing_wait);
354	if (port->drain_delay) {
355		unsigned int bps = tty_get_baud_rate(tty);
356		long timeout;
357
358		if (bps > 1200)
359			timeout = max_t(long,
360				(HZ * 10 * port->drain_delay) / bps, HZ / 10);
361		else
362			timeout = 2 * HZ;
363		schedule_timeout_interruptible(timeout);
364	}
365	/* Flush the ldisc buffering */
366	tty_ldisc_flush(tty);
367
368	/* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
369	   hang up the line */
370	if (tty->termios->c_cflag & HUPCL)
371		tty_port_lower_dtr_rts(port);
372
373	/* Don't call port->drop for the last reference. Callers will want
374	   to drop the last active reference in ->shutdown() or the tty
375	   shutdown path */
376	return 1;
377}
378EXPORT_SYMBOL(tty_port_close_start);
379
 
380void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
381{
382	unsigned long flags;
383
384	spin_lock_irqsave(&port->lock, flags);
385	tty->closing = 0;
386
 
 
387	if (port->blocked_open) {
388		spin_unlock_irqrestore(&port->lock, flags);
389		if (port->close_delay) {
390			msleep_interruptible(
391				jiffies_to_msecs(port->close_delay));
392		}
393		spin_lock_irqsave(&port->lock, flags);
394		wake_up_interruptible(&port->open_wait);
395	}
396	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
397	wake_up_interruptible(&port->close_wait);
398	spin_unlock_irqrestore(&port->lock, flags);
399}
400EXPORT_SYMBOL(tty_port_close_end);
401
 
 
 
 
 
402void tty_port_close(struct tty_port *port, struct tty_struct *tty,
403							struct file *filp)
404{
405	if (tty_port_close_start(port, tty, filp) == 0)
406		return;
407	tty_port_shutdown(port);
408	set_bit(TTY_IO_ERROR, &tty->flags);
409	tty_port_close_end(port, tty);
410	tty_port_tty_set(port, NULL);
411}
412EXPORT_SYMBOL(tty_port_close);
413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414int tty_port_open(struct tty_port *port, struct tty_struct *tty,
415							struct file *filp)
416{
417	spin_lock_irq(&port->lock);
418	if (!tty_hung_up_p(filp))
419		++port->count;
420	spin_unlock_irq(&port->lock);
421	tty_port_tty_set(port, tty);
422
423	/*
424	 * Do the device-specific open only if the hardware isn't
425	 * already initialized. Serialize open and shutdown using the
426	 * port mutex.
427	 */
428
429	mutex_lock(&port->mutex);
430
431	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
432		clear_bit(TTY_IO_ERROR, &tty->flags);
433		if (port->ops->activate) {
434			int retval = port->ops->activate(port, tty);
435			if (retval) {
436				mutex_unlock(&port->mutex);
437				return retval;
438			}
439		}
440		set_bit(ASYNCB_INITIALIZED, &port->flags);
441	}
442	mutex_unlock(&port->mutex);
443	return tty_port_block_til_ready(port, tty, filp);
444}
445
446EXPORT_SYMBOL(tty_port_open);
v4.6
  1/*
  2 * Tty port functions
  3 */
  4
  5#include <linux/types.h>
  6#include <linux/errno.h>
  7#include <linux/tty.h>
  8#include <linux/tty_driver.h>
  9#include <linux/tty_flip.h>
 10#include <linux/serial.h>
 11#include <linux/timer.h>
 12#include <linux/string.h>
 13#include <linux/slab.h>
 14#include <linux/sched.h>
 
 15#include <linux/wait.h>
 16#include <linux/bitops.h>
 17#include <linux/delay.h>
 18#include <linux/module.h>
 19
 20void tty_port_init(struct tty_port *port)
 21{
 22	memset(port, 0, sizeof(*port));
 23	tty_buffer_init(port);
 24	init_waitqueue_head(&port->open_wait);
 
 25	init_waitqueue_head(&port->delta_msr_wait);
 26	mutex_init(&port->mutex);
 27	mutex_init(&port->buf_mutex);
 28	spin_lock_init(&port->lock);
 29	port->close_delay = (50 * HZ) / 100;
 30	port->closing_wait = (3000 * HZ) / 100;
 31	kref_init(&port->kref);
 32}
 33EXPORT_SYMBOL(tty_port_init);
 34
 35/**
 36 * tty_port_link_device - link tty and tty_port
 37 * @port: tty_port of the device
 38 * @driver: tty_driver for this device
 39 * @index: index of the tty
 40 *
 41 * Provide the tty layer wit ha link from a tty (specified by @index) to a
 42 * tty_port (@port). Use this only if neither tty_port_register_device nor
 43 * tty_port_install is used in the driver. If used, this has to be called before
 44 * tty_register_driver.
 45 */
 46void tty_port_link_device(struct tty_port *port,
 47		struct tty_driver *driver, unsigned index)
 48{
 49	if (WARN_ON(index >= driver->num))
 50		return;
 51	driver->ports[index] = port;
 52}
 53EXPORT_SYMBOL_GPL(tty_port_link_device);
 54
 55/**
 56 * tty_port_register_device - register tty device
 57 * @port: tty_port of the device
 58 * @driver: tty_driver for this device
 59 * @index: index of the tty
 60 * @device: parent if exists, otherwise NULL
 61 *
 62 * It is the same as tty_register_device except the provided @port is linked to
 63 * a concrete tty specified by @index. Use this or tty_port_install (or both).
 64 * Call tty_port_link_device as a last resort.
 65 */
 66struct device *tty_port_register_device(struct tty_port *port,
 67		struct tty_driver *driver, unsigned index,
 68		struct device *device)
 69{
 70	tty_port_link_device(port, driver, index);
 71	return tty_register_device(driver, index, device);
 72}
 73EXPORT_SYMBOL_GPL(tty_port_register_device);
 74
 75/**
 76 * tty_port_register_device_attr - register tty device
 77 * @port: tty_port of the device
 78 * @driver: tty_driver for this device
 79 * @index: index of the tty
 80 * @device: parent if exists, otherwise NULL
 81 * @drvdata: Driver data to be set to device.
 82 * @attr_grp: Attribute group to be set on device.
 83 *
 84 * It is the same as tty_register_device_attr except the provided @port is
 85 * linked to a concrete tty specified by @index. Use this or tty_port_install
 86 * (or both). Call tty_port_link_device as a last resort.
 87 */
 88struct device *tty_port_register_device_attr(struct tty_port *port,
 89		struct tty_driver *driver, unsigned index,
 90		struct device *device, void *drvdata,
 91		const struct attribute_group **attr_grp)
 92{
 93	tty_port_link_device(port, driver, index);
 94	return tty_register_device_attr(driver, index, device, drvdata,
 95			attr_grp);
 96}
 97EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
 98
 99int tty_port_alloc_xmit_buf(struct tty_port *port)
100{
101	/* We may sleep in get_zeroed_page() */
102	mutex_lock(&port->buf_mutex);
103	if (port->xmit_buf == NULL)
104		port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
105	mutex_unlock(&port->buf_mutex);
106	if (port->xmit_buf == NULL)
107		return -ENOMEM;
108	return 0;
109}
110EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
111
112void tty_port_free_xmit_buf(struct tty_port *port)
113{
114	mutex_lock(&port->buf_mutex);
115	if (port->xmit_buf != NULL) {
116		free_page((unsigned long)port->xmit_buf);
117		port->xmit_buf = NULL;
118	}
119	mutex_unlock(&port->buf_mutex);
120}
121EXPORT_SYMBOL(tty_port_free_xmit_buf);
122
123/**
124 * tty_port_destroy -- destroy inited port
125 * @port: tty port to be doestroyed
126 *
127 * When a port was initialized using tty_port_init, one has to destroy the
128 * port by this function. Either indirectly by using tty_port refcounting
129 * (tty_port_put) or directly if refcounting is not used.
130 */
131void tty_port_destroy(struct tty_port *port)
132{
133	tty_buffer_cancel_work(port);
134	tty_buffer_free_all(port);
135}
136EXPORT_SYMBOL(tty_port_destroy);
137
138static void tty_port_destructor(struct kref *kref)
139{
140	struct tty_port *port = container_of(kref, struct tty_port, kref);
141
142	/* check if last port ref was dropped before tty release */
143	if (WARN_ON(port->itty))
144		return;
145	if (port->xmit_buf)
146		free_page((unsigned long)port->xmit_buf);
147	tty_port_destroy(port);
148	if (port->ops && port->ops->destruct)
149		port->ops->destruct(port);
150	else
151		kfree(port);
152}
153
154void tty_port_put(struct tty_port *port)
155{
156	if (port)
157		kref_put(&port->kref, tty_port_destructor);
158}
159EXPORT_SYMBOL(tty_port_put);
160
161/**
162 *	tty_port_tty_get	-	get a tty reference
163 *	@port: tty port
164 *
165 *	Return a refcount protected tty instance or NULL if the port is not
166 *	associated with a tty (eg due to close or hangup)
167 */
168
169struct tty_struct *tty_port_tty_get(struct tty_port *port)
170{
171	unsigned long flags;
172	struct tty_struct *tty;
173
174	spin_lock_irqsave(&port->lock, flags);
175	tty = tty_kref_get(port->tty);
176	spin_unlock_irqrestore(&port->lock, flags);
177	return tty;
178}
179EXPORT_SYMBOL(tty_port_tty_get);
180
181/**
182 *	tty_port_tty_set	-	set the tty of a port
183 *	@port: tty port
184 *	@tty: the tty
185 *
186 *	Associate the port and tty pair. Manages any internal refcounts.
187 *	Pass NULL to deassociate a port
188 */
189
190void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
191{
192	unsigned long flags;
193
194	spin_lock_irqsave(&port->lock, flags);
195	tty_kref_put(port->tty);
 
196	port->tty = tty_kref_get(tty);
197	spin_unlock_irqrestore(&port->lock, flags);
198}
199EXPORT_SYMBOL(tty_port_tty_set);
200
201static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
202{
203	mutex_lock(&port->mutex);
204	if (port->console)
205		goto out;
206
207	if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
208		/*
209		 * Drop DTR/RTS if HUPCL is set. This causes any attached
210		 * modem to hang up the line.
211		 */
212		if (tty && C_HUPCL(tty))
213			tty_port_lower_dtr_rts(port);
214
215		if (port->ops->shutdown)
216			port->ops->shutdown(port);
217	}
218out:
219	mutex_unlock(&port->mutex);
220}
221
222/**
223 *	tty_port_hangup		-	hangup helper
224 *	@port: tty port
225 *
226 *	Perform port level tty hangup flag and count changes. Drop the tty
227 *	reference.
228 *
229 *	Caller holds tty lock.
230 */
231
232void tty_port_hangup(struct tty_port *port)
233{
234	struct tty_struct *tty;
235	unsigned long flags;
236
237	spin_lock_irqsave(&port->lock, flags);
238	port->count = 0;
239	port->flags &= ~ASYNC_NORMAL_ACTIVE;
240	tty = port->tty;
241	if (tty)
242		set_bit(TTY_IO_ERROR, &tty->flags);
 
243	port->tty = NULL;
244	spin_unlock_irqrestore(&port->lock, flags);
245	tty_port_shutdown(port, tty);
246	tty_kref_put(tty);
247	wake_up_interruptible(&port->open_wait);
248	wake_up_interruptible(&port->delta_msr_wait);
 
249}
250EXPORT_SYMBOL(tty_port_hangup);
251
252/**
253 * tty_port_tty_hangup - helper to hang up a tty
254 *
255 * @port: tty port
256 * @check_clocal: hang only ttys with CLOCAL unset?
257 */
258void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
259{
260	struct tty_struct *tty = tty_port_tty_get(port);
261
262	if (tty && (!check_clocal || !C_CLOCAL(tty)))
263		tty_hangup(tty);
264	tty_kref_put(tty);
265}
266EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
267
268/**
269 * tty_port_tty_wakeup - helper to wake up a tty
270 *
271 * @port: tty port
272 */
273void tty_port_tty_wakeup(struct tty_port *port)
274{
275	struct tty_struct *tty = tty_port_tty_get(port);
276
277	if (tty) {
278		tty_wakeup(tty);
279		tty_kref_put(tty);
280	}
281}
282EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
283
284/**
285 *	tty_port_carrier_raised	-	carrier raised check
286 *	@port: tty port
287 *
288 *	Wrapper for the carrier detect logic. For the moment this is used
289 *	to hide some internal details. This will eventually become entirely
290 *	internal to the tty port.
291 */
292
293int tty_port_carrier_raised(struct tty_port *port)
294{
295	if (port->ops->carrier_raised == NULL)
296		return 1;
297	return port->ops->carrier_raised(port);
298}
299EXPORT_SYMBOL(tty_port_carrier_raised);
300
301/**
302 *	tty_port_raise_dtr_rts	-	Raise DTR/RTS
303 *	@port: tty port
304 *
305 *	Wrapper for the DTR/RTS raise logic. For the moment this is used
306 *	to hide some internal details. This will eventually become entirely
307 *	internal to the tty port.
308 */
309
310void tty_port_raise_dtr_rts(struct tty_port *port)
311{
312	if (port->ops->dtr_rts)
313		port->ops->dtr_rts(port, 1);
314}
315EXPORT_SYMBOL(tty_port_raise_dtr_rts);
316
317/**
318 *	tty_port_lower_dtr_rts	-	Lower DTR/RTS
319 *	@port: tty port
320 *
321 *	Wrapper for the DTR/RTS raise logic. For the moment this is used
322 *	to hide some internal details. This will eventually become entirely
323 *	internal to the tty port.
324 */
325
326void tty_port_lower_dtr_rts(struct tty_port *port)
327{
328	if (port->ops->dtr_rts)
329		port->ops->dtr_rts(port, 0);
330}
331EXPORT_SYMBOL(tty_port_lower_dtr_rts);
332
333/**
334 *	tty_port_block_til_ready	-	Waiting logic for tty open
335 *	@port: the tty port being opened
336 *	@tty: the tty device being bound
337 *	@filp: the file pointer of the opener
338 *
339 *	Implement the core POSIX/SuS tty behaviour when opening a tty device.
340 *	Handles:
341 *		- hangup (both before and during)
342 *		- non blocking open
343 *		- rts/dtr/dcd
344 *		- signals
345 *		- port flags and counts
346 *
347 *	The passed tty_port must implement the carrier_raised method if it can
348 *	do carrier detect and the dtr_rts method if it supports software
349 *	management of these lines. Note that the dtr/rts raise is done each
350 *	iteration as a hangup may have previously dropped them while we wait.
351 *
352 *	Caller holds tty lock.
353 *
354 *      NB: May drop and reacquire tty lock when blocking, so tty and tty_port
355 *      may have changed state (eg., may have been hung up).
356 */
357
358int tty_port_block_til_ready(struct tty_port *port,
359				struct tty_struct *tty, struct file *filp)
360{
361	int do_clocal = 0, retval;
362	unsigned long flags;
363	DEFINE_WAIT(wait);
 
 
 
 
 
 
 
 
 
 
 
364
365	/* if non-blocking mode is set we can pass directly to open unless
366	   the port has just hung up or is in another error state */
367	if (tty->flags & (1 << TTY_IO_ERROR)) {
368		port->flags |= ASYNC_NORMAL_ACTIVE;
369		return 0;
370	}
371	if (filp->f_flags & O_NONBLOCK) {
372		/* Indicate we are open */
373		if (C_BAUD(tty))
374			tty_port_raise_dtr_rts(port);
375		port->flags |= ASYNC_NORMAL_ACTIVE;
376		return 0;
377	}
378
379	if (C_CLOCAL(tty))
380		do_clocal = 1;
381
382	/* Block waiting until we can proceed. We may need to wait for the
383	   carrier, but we must also wait for any close that is in progress
384	   before the next open may complete */
385
386	retval = 0;
387
388	/* The port lock protects the port counts */
389	spin_lock_irqsave(&port->lock, flags);
390	port->count--;
 
391	port->blocked_open++;
392	spin_unlock_irqrestore(&port->lock, flags);
393
394	while (1) {
395		/* Indicate we are open */
396		if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
397			tty_port_raise_dtr_rts(port);
398
399		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
400		/* Check for a hangup or uninitialised port.
401							Return accordingly */
402		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
403			if (port->flags & ASYNC_HUP_NOTIFY)
404				retval = -EAGAIN;
405			else
406				retval = -ERESTARTSYS;
407			break;
408		}
409		/*
410		 * Probe the carrier. For devices with no carrier detect
411		 * tty_port_carrier_raised will always return true.
412		 * Never ask drivers if CLOCAL is set, this causes troubles
413		 * on some hardware.
414		 */
415		if (do_clocal || tty_port_carrier_raised(port))
416			break;
417		if (signal_pending(current)) {
418			retval = -ERESTARTSYS;
419			break;
420		}
421		tty_unlock(tty);
422		schedule();
423		tty_lock(tty);
424	}
425	finish_wait(&port->open_wait, &wait);
426
427	/* Update counts. A parallel hangup will have set count to zero and
428	   we must not mess that up further */
429	spin_lock_irqsave(&port->lock, flags);
430	if (!tty_hung_up_p(filp))
431		port->count++;
432	port->blocked_open--;
433	if (retval == 0)
434		port->flags |= ASYNC_NORMAL_ACTIVE;
435	spin_unlock_irqrestore(&port->lock, flags);
436	return retval;
437}
438EXPORT_SYMBOL(tty_port_block_til_ready);
439
440static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
441{
442	unsigned int bps = tty_get_baud_rate(tty);
443	long timeout;
444
445	if (bps > 1200) {
446		timeout = (HZ * 10 * port->drain_delay) / bps;
447		timeout = max_t(long, timeout, HZ / 10);
448	} else {
449		timeout = 2 * HZ;
450	}
451	schedule_timeout_interruptible(timeout);
452}
453
454/* Caller holds tty lock. */
455int tty_port_close_start(struct tty_port *port,
456				struct tty_struct *tty, struct file *filp)
457{
458	unsigned long flags;
459
460	if (tty_hung_up_p(filp))
 
 
461		return 0;
 
462
463	spin_lock_irqsave(&port->lock, flags);
464	if (tty->count == 1 && port->count != 1) {
465		tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__,
466			 port->count);
 
467		port->count = 1;
468	}
469	if (--port->count < 0) {
470		tty_warn(tty, "%s: bad port count (%d)\n", __func__,
471			 port->count);
472		port->count = 0;
473	}
474
475	if (port->count) {
476		spin_unlock_irqrestore(&port->lock, flags);
 
 
477		return 0;
478	}
 
 
479	spin_unlock_irqrestore(&port->lock, flags);
480
481	tty->closing = 1;
482
483	if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
484		/* Don't block on a stalled port, just pull the chain */
485		if (tty->flow_stopped)
486			tty_driver_flush_buffer(tty);
487		if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
488			tty_wait_until_sent(tty, port->closing_wait);
489		if (port->drain_delay)
490			tty_port_drain_delay(port, tty);
 
 
 
 
 
491	}
492	/* Flush the ldisc buffering */
493	tty_ldisc_flush(tty);
494
495	/* Report to caller this is the last port reference */
 
 
 
 
 
 
 
496	return 1;
497}
498EXPORT_SYMBOL(tty_port_close_start);
499
500/* Caller holds tty lock */
501void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
502{
503	unsigned long flags;
504
505	tty_ldisc_flush(tty);
506	tty->closing = 0;
507
508	spin_lock_irqsave(&port->lock, flags);
509
510	if (port->blocked_open) {
511		spin_unlock_irqrestore(&port->lock, flags);
512		if (port->close_delay)
513			msleep_interruptible(jiffies_to_msecs(port->close_delay));
 
 
514		spin_lock_irqsave(&port->lock, flags);
515		wake_up_interruptible(&port->open_wait);
516	}
517	port->flags &= ~ASYNC_NORMAL_ACTIVE;
 
518	spin_unlock_irqrestore(&port->lock, flags);
519}
520EXPORT_SYMBOL(tty_port_close_end);
521
522/**
523 * tty_port_close
524 *
525 * Caller holds tty lock
526 */
527void tty_port_close(struct tty_port *port, struct tty_struct *tty,
528							struct file *filp)
529{
530	if (tty_port_close_start(port, tty, filp) == 0)
531		return;
532	tty_port_shutdown(port, tty);
533	set_bit(TTY_IO_ERROR, &tty->flags);
534	tty_port_close_end(port, tty);
535	tty_port_tty_set(port, NULL);
536}
537EXPORT_SYMBOL(tty_port_close);
538
539/**
540 * tty_port_install - generic tty->ops->install handler
541 * @port: tty_port of the device
542 * @driver: tty_driver for this device
543 * @tty: tty to be installed
544 *
545 * It is the same as tty_standard_install except the provided @port is linked
546 * to a concrete tty specified by @tty. Use this or tty_port_register_device
547 * (or both). Call tty_port_link_device as a last resort.
548 */
549int tty_port_install(struct tty_port *port, struct tty_driver *driver,
550		struct tty_struct *tty)
551{
552	tty->port = port;
553	return tty_standard_install(driver, tty);
554}
555EXPORT_SYMBOL_GPL(tty_port_install);
556
557/**
558 * tty_port_open
559 *
560 * Caller holds tty lock.
561 *
562 * NB: may drop and reacquire tty lock (in tty_port_block_til_ready()) so
563 * tty and tty_port may have changed state (eg., may be hung up now)
564 */
565int tty_port_open(struct tty_port *port, struct tty_struct *tty,
566							struct file *filp)
567{
568	spin_lock_irq(&port->lock);
569	++port->count;
 
570	spin_unlock_irq(&port->lock);
571	tty_port_tty_set(port, tty);
572
573	/*
574	 * Do the device-specific open only if the hardware isn't
575	 * already initialized. Serialize open and shutdown using the
576	 * port mutex.
577	 */
578
579	mutex_lock(&port->mutex);
580
581	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
582		clear_bit(TTY_IO_ERROR, &tty->flags);
583		if (port->ops->activate) {
584			int retval = port->ops->activate(port, tty);
585			if (retval) {
586				mutex_unlock(&port->mutex);
587				return retval;
588			}
589		}
590		set_bit(ASYNCB_INITIALIZED, &port->flags);
591	}
592	mutex_unlock(&port->mutex);
593	return tty_port_block_til_ready(port, tty, filp);
594}
595
596EXPORT_SYMBOL(tty_port_open);