tty_buffer.c 15.3 KB
Newer Older
A
Alan Cox 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * Tty buffer allocation management
 */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/module.h>

/**
 *	tty_buffer_free_all		-	free buffers used by a tty
 *	@tty: tty to free from
 *
 *	Remove all the buffers pending on a tty whether queued with data
 *	or in the free ring. Must be called when the tty is no longer in use
 *
 *	Locking: none
 */

void tty_buffer_free_all(struct tty_struct *tty)
{
32
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
33
	struct tty_buffer *thead;
34 35 36

	while ((thead = buf->head) != NULL) {
		buf->head = thead->next;
A
Alan Cox 已提交
37 38
		kfree(thead);
	}
39 40
	while ((thead = buf->free) != NULL) {
		buf->free = thead->next;
A
Alan Cox 已提交
41 42
		kfree(thead);
	}
43 44
	buf->tail = NULL;
	buf->memory_used = 0;
A
Alan Cox 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
}

/**
 *	tty_buffer_alloc	-	allocate a tty buffer
 *	@tty: tty device
 *	@size: desired size (characters)
 *
 *	Allocate a new tty buffer to hold the desired number of characters.
 *	Return NULL if out of memory or the allocation would exceed the
 *	per device queue
 *
 *	Locking: Caller must hold tty->buf.lock
 */

static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
{
	struct tty_buffer *p;

	if (tty->buf.memory_used + size > 65536)
		return NULL;
	p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
	if (p == NULL)
		return NULL;
	p->used = 0;
	p->size = size;
	p->next = NULL;
	p->commit = 0;
	p->read = 0;
	p->char_buf_ptr = (char *)(p->data);
	p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
	tty->buf.memory_used += size;
	return p;
}

/**
 *	tty_buffer_free		-	free a tty buffer
 *	@tty: tty owning the buffer
 *	@b: the buffer to free
 *
 *	Free a tty buffer, or add it to the free list according to our
 *	internal strategy
 *
 *	Locking: Caller must hold tty->buf.lock
 */

static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
{
92 93
	struct tty_bufhead *buf = &tty->buf;

A
Alan Cox 已提交
94
	/* Dumb strategy for now - should keep some stats */
95 96
	buf->memory_used -= b->size;
	WARN_ON(buf->memory_used < 0);
A
Alan Cox 已提交
97 98 99 100

	if (b->size >= 512)
		kfree(b);
	else {
101 102
		b->next = buf->free;
		buf->free = b;
A
Alan Cox 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
	}
}

/**
 *	__tty_buffer_flush		-	flush full tty buffers
 *	@tty: tty to flush
 *
 *	flush all the buffers containing receive data. Caller must
 *	hold the buffer lock and must have ensured no parallel flush to
 *	ldisc is running.
 *
 *	Locking: Caller must hold tty->buf.lock
 */

static void __tty_buffer_flush(struct tty_struct *tty)
{
119
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
120 121
	struct tty_buffer *thead;

122 123
	while ((thead = buf->head) != NULL) {
		buf->head = thead->next;
A
Alan Cox 已提交
124 125
		tty_buffer_free(tty, thead);
	}
126
	buf->tail = NULL;
A
Alan Cox 已提交
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
}

/**
 *	tty_buffer_flush		-	flush full tty buffers
 *	@tty: tty to flush
 *
 *	flush all the buffers containing receive data. If the buffer is
 *	being processed by flush_to_ldisc then we defer the processing
 *	to that function
 *
 *	Locking: none
 */

void tty_buffer_flush(struct tty_struct *tty)
{
142
	struct tty_port *port = tty->port;
143
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
144
	unsigned long flags;
145 146

	spin_lock_irqsave(&buf->lock, flags);
A
Alan Cox 已提交
147 148 149 150

	/* If the data is being pushed to the tty layer then we can't
	   process it here. Instead set a flag and the flush_to_ldisc
	   path will process the flush request before it exits */
151 152
	if (test_bit(TTYP_FLUSHING, &port->iflags)) {
		set_bit(TTYP_FLUSHPENDING, &port->iflags);
153
		spin_unlock_irqrestore(&buf->lock, flags);
A
Alan Cox 已提交
154
		wait_event(tty->read_wait,
155
				test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0);
A
Alan Cox 已提交
156 157 158
		return;
	} else
		__tty_buffer_flush(tty);
159
	spin_unlock_irqrestore(&buf->lock, flags);
A
Alan Cox 已提交
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
}

/**
 *	tty_buffer_find		-	find a free tty buffer
 *	@tty: tty owning the buffer
 *	@size: characters wanted
 *
 *	Locate an existing suitable tty buffer or if we are lacking one then
 *	allocate a new one. We round our buffers off in 256 character chunks
 *	to get better allocation behaviour.
 *
 *	Locking: Caller must hold tty->buf.lock
 */

static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
{
	struct tty_buffer **tbh = &tty->buf.free;
	while ((*tbh) != NULL) {
		struct tty_buffer *t = *tbh;
		if (t->size >= size) {
			*tbh = t->next;
			t->next = NULL;
			t->used = 0;
			t->commit = 0;
			t->read = 0;
			tty->buf.memory_used += t->size;
			return t;
		}
		tbh = &((*tbh)->next);
	}
	/* Round the buffer size out */
	size = (size + 0xFF) & ~0xFF;
	return tty_buffer_alloc(tty, size);
	/* Should possibly check if this fails for the largest buffer we
	   have queued and recycle that ? */
}
/**
197
 *	__tty_buffer_request_room		-	grow tty buffer if needed
A
Alan Cox 已提交
198 199 200 201 202
 *	@tty: tty structure
 *	@size: size desired
 *
 *	Make at least size bytes of linear space available for the tty
 *	buffer. If we fail return the size we managed to find.
203
 *      Locking: Caller must hold tty->buf.lock
A
Alan Cox 已提交
204
 */
205
static int __tty_buffer_request_room(struct tty_struct *tty, size_t size)
A
Alan Cox 已提交
206
{
207
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
208 209 210 211 212
	struct tty_buffer *b, *n;
	int left;
	/* OPTIMISATION: We could keep a per tty "zero" sized buffer to
	   remove this conditional if its worth it. This would be invisible
	   to the callers */
213 214
	b = buf->tail;
	if (b != NULL)
A
Alan Cox 已提交
215 216 217 218 219 220 221 222 223 224 225
		left = b->size - b->used;
	else
		left = 0;

	if (left < size) {
		/* This is the slow path - looking for new buffers to use */
		if ((n = tty_buffer_find(tty, size)) != NULL) {
			if (b != NULL) {
				b->next = n;
				b->commit = b->used;
			} else
226 227
				buf->head = n;
			buf->tail = n;
A
Alan Cox 已提交
228 229 230 231 232 233
		} else
			size = left;
	}

	return size;
}
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255


/**
 *	tty_buffer_request_room		-	grow tty buffer if needed
 *	@tty: tty structure
 *	@size: size desired
 *
 *	Make at least size bytes of linear space available for the tty
 *	buffer. If we fail return the size we managed to find.
 *
 *	Locking: Takes tty->buf.lock
 */
int tty_buffer_request_room(struct tty_struct *tty, size_t size)
{
	unsigned long flags;
	int length;

	spin_lock_irqsave(&tty->buf.lock, flags);
	length = __tty_buffer_request_room(tty, size);
	spin_unlock_irqrestore(&tty->buf.lock, flags);
	return length;
}
A
Alan Cox 已提交
256 257 258
EXPORT_SYMBOL_GPL(tty_buffer_request_room);

/**
259
 *	tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
A
Alan Cox 已提交
260 261
 *	@tty: tty structure
 *	@chars: characters
262
 *	@flag: flag value for each character
A
Alan Cox 已提交
263 264 265
 *	@size: size
 *
 *	Queue a series of bytes to the tty buffering. All the characters
266
 *	passed are marked with the supplied flag. Returns the number added.
A
Alan Cox 已提交
267 268 269 270
 *
 *	Locking: Called functions may take tty->buf.lock
 */

271 272
int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
		const unsigned char *chars, char flag, size_t size)
A
Alan Cox 已提交
273
{
274
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
275 276
	int copied = 0;
	do {
277
		int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
278 279 280 281
		int space;
		unsigned long flags;
		struct tty_buffer *tb;

282
		spin_lock_irqsave(&buf->lock, flags);
283
		space = __tty_buffer_request_room(tty, goal);
284
		tb = buf->tail;
A
Alan Cox 已提交
285
		/* If there is no space then tb may be NULL */
286
		if (unlikely(space == 0)) {
287
			spin_unlock_irqrestore(&buf->lock, flags);
A
Alan Cox 已提交
288
			break;
289
		}
A
Alan Cox 已提交
290
		memcpy(tb->char_buf_ptr + tb->used, chars, space);
291
		memset(tb->flag_buf_ptr + tb->used, flag, space);
A
Alan Cox 已提交
292
		tb->used += space;
293
		spin_unlock_irqrestore(&buf->lock, flags);
A
Alan Cox 已提交
294 295 296 297 298 299 300
		copied += space;
		chars += space;
		/* There is a small chance that we need to split the data over
		   several buffers. If this is the case we must loop */
	} while (unlikely(size > copied));
	return copied;
}
301
EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
A
Alan Cox 已提交
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319

/**
 *	tty_insert_flip_string_flags	-	Add characters to the tty buffer
 *	@tty: tty structure
 *	@chars: characters
 *	@flags: flag bytes
 *	@size: size
 *
 *	Queue a series of bytes to the tty buffering. For each character
 *	the flags array indicates the status of the character. Returns the
 *	number added.
 *
 *	Locking: Called functions may take tty->buf.lock
 */

int tty_insert_flip_string_flags(struct tty_struct *tty,
		const unsigned char *chars, const char *flags, size_t size)
{
320
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
321 322
	int copied = 0;
	do {
323
		int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
324 325 326 327
		int space;
		unsigned long __flags;
		struct tty_buffer *tb;

328
		spin_lock_irqsave(&buf->lock, __flags);
329
		space = __tty_buffer_request_room(tty, goal);
330
		tb = buf->tail;
A
Alan Cox 已提交
331
		/* If there is no space then tb may be NULL */
332
		if (unlikely(space == 0)) {
333
			spin_unlock_irqrestore(&buf->lock, __flags);
A
Alan Cox 已提交
334
			break;
335
		}
A
Alan Cox 已提交
336 337 338
		memcpy(tb->char_buf_ptr + tb->used, chars, space);
		memcpy(tb->flag_buf_ptr + tb->used, flags, space);
		tb->used += space;
339
		spin_unlock_irqrestore(&buf->lock, __flags);
A
Alan Cox 已提交
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
		copied += space;
		chars += space;
		flags += space;
		/* There is a small chance that we need to split the data over
		   several buffers. If this is the case we must loop */
	} while (unlikely(size > copied));
	return copied;
}
EXPORT_SYMBOL(tty_insert_flip_string_flags);

/**
 *	tty_schedule_flip	-	push characters to ldisc
 *	@tty: tty to push from
 *
 *	Takes any pending buffers and transfers their ownership to the
 *	ldisc side of the queue. It then schedules those characters for
 *	processing by the line discipline.
357 358
 *	Note that this function can only be used when the low_latency flag
 *	is unset. Otherwise the workqueue won't be flushed.
A
Alan Cox 已提交
359 360 361 362 363 364
 *
 *	Locking: Takes tty->buf.lock
 */

void tty_schedule_flip(struct tty_struct *tty)
{
365
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
366
	unsigned long flags;
367 368 369 370 371 372

	spin_lock_irqsave(&buf->lock, flags);
	if (buf->tail != NULL)
		buf->tail->commit = buf->tail->used;
	spin_unlock_irqrestore(&buf->lock, flags);
	schedule_work(&buf->work);
A
Alan Cox 已提交
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
}
EXPORT_SYMBOL(tty_schedule_flip);

/**
 *	tty_prepare_flip_string		-	make room for characters
 *	@tty: tty
 *	@chars: return pointer for character write area
 *	@size: desired size
 *
 *	Prepare a block of space in the buffer for data. Returns the length
 *	available and buffer pointer to the space which is now allocated and
 *	accounted for as ready for normal characters. This is used for drivers
 *	that need their own block copy routines into the buffer. There is no
 *	guarantee the buffer is a DMA target!
 *
 *	Locking: May call functions taking tty->buf.lock
 */

int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
								size_t size)
{
394
	struct tty_bufhead *buf = &tty->buf;
395 396 397 398
	int space;
	unsigned long flags;
	struct tty_buffer *tb;

399
	spin_lock_irqsave(&buf->lock, flags);
400 401
	space = __tty_buffer_request_room(tty, size);

402
	tb = buf->tail;
A
Alan Cox 已提交
403 404 405 406 407
	if (likely(space)) {
		*chars = tb->char_buf_ptr + tb->used;
		memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
		tb->used += space;
	}
408
	spin_unlock_irqrestore(&buf->lock, flags);
A
Alan Cox 已提交
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
	return space;
}
EXPORT_SYMBOL_GPL(tty_prepare_flip_string);

/**
 *	tty_prepare_flip_string_flags	-	make room for characters
 *	@tty: tty
 *	@chars: return pointer for character write area
 *	@flags: return pointer for status flag write area
 *	@size: desired size
 *
 *	Prepare a block of space in the buffer for data. Returns the length
 *	available and buffer pointer to the space which is now allocated and
 *	accounted for as ready for characters. This is used for drivers
 *	that need their own block copy routines into the buffer. There is no
 *	guarantee the buffer is a DMA target!
 *
 *	Locking: May call functions taking tty->buf.lock
 */

int tty_prepare_flip_string_flags(struct tty_struct *tty,
			unsigned char **chars, char **flags, size_t size)
{
432
	struct tty_bufhead *buf = &tty->buf;
433 434 435 436
	int space;
	unsigned long __flags;
	struct tty_buffer *tb;

437
	spin_lock_irqsave(&buf->lock, __flags);
438 439
	space = __tty_buffer_request_room(tty, size);

440
	tb = buf->tail;
A
Alan Cox 已提交
441 442 443 444 445
	if (likely(space)) {
		*chars = tb->char_buf_ptr + tb->used;
		*flags = tb->flag_buf_ptr + tb->used;
		tb->used += space;
	}
446
	spin_unlock_irqrestore(&buf->lock, __flags);
A
Alan Cox 已提交
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
	return space;
}
EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);



/**
 *	flush_to_ldisc
 *	@work: tty structure passed from work queue.
 *
 *	This routine is called out of the software interrupt to flush data
 *	from the buffer chain to the line discipline.
 *
 *	Locking: holds tty->buf.lock to guard buffer list. Drops the lock
 *	while invoking the line discipline receive_buf method. The
 *	receive_buf method is single threaded for each tty instance.
 */

static void flush_to_ldisc(struct work_struct *work)
{
	struct tty_struct *tty =
468
		container_of(work, struct tty_struct, buf.work);
469
	struct tty_port *port = tty->port;
470
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
471 472 473 474 475 476 477
	unsigned long 	flags;
	struct tty_ldisc *disc;

	disc = tty_ldisc_ref(tty);
	if (disc == NULL)	/*  !TTY_LDISC */
		return;

478
	spin_lock_irqsave(&buf->lock, flags);
479

480
	if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) {
481
		struct tty_buffer *head;
482
		while ((head = buf->head) != NULL) {
483 484 485 486 487
			int count;
			char *char_buf;
			unsigned char *flag_buf;

			count = head->commit - head->read;
A
Alan Cox 已提交
488 489 490
			if (!count) {
				if (head->next == NULL)
					break;
491
				buf->head = head->next;
492
				tty_buffer_free(tty, head);
A
Alan Cox 已提交
493 494 495 496 497
				continue;
			}
			/* Ldisc or user is trying to flush the buffers
			   we are feeding to the ldisc, stop feeding the
			   line discipline as we want to empty the queue */
498
			if (test_bit(TTYP_FLUSHPENDING, &port->iflags))
A
Alan Cox 已提交
499
				break;
500
			if (!tty->receive_room)
501 502 503
				break;
			if (count > tty->receive_room)
				count = tty->receive_room;
A
Alan Cox 已提交
504 505
			char_buf = head->char_buf_ptr + head->read;
			flag_buf = head->flag_buf_ptr + head->read;
506
			head->read += count;
507
			spin_unlock_irqrestore(&buf->lock, flags);
508
			disc->ops->receive_buf(tty, char_buf,
A
Alan Cox 已提交
509
							flag_buf, count);
510
			spin_lock_irqsave(&buf->lock, flags);
A
Alan Cox 已提交
511
		}
512
		clear_bit(TTYP_FLUSHING, &port->iflags);
A
Alan Cox 已提交
513
	}
514

A
Alan Cox 已提交
515 516
	/* We may have a deferred request to flush the input buffer,
	   if so pull the chain under the lock and empty the queue */
517
	if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) {
A
Alan Cox 已提交
518
		__tty_buffer_flush(tty);
519
		clear_bit(TTYP_FLUSHPENDING, &port->iflags);
A
Alan Cox 已提交
520 521
		wake_up(&tty->read_wait);
	}
522
	spin_unlock_irqrestore(&buf->lock, flags);
A
Alan Cox 已提交
523 524 525 526

	tty_ldisc_deref(disc);
}

527 528 529 530 531 532 533 534 535 536
/**
 *	tty_flush_to_ldisc
 *	@tty: tty to push
 *
 *	Push the terminal flip buffers to the line discipline.
 *
 *	Must not be called from IRQ context.
 */
void tty_flush_to_ldisc(struct tty_struct *tty)
{
537 538
	if (!tty->low_latency)
		flush_work(&tty->buf.work);
539 540
}

A
Alan Cox 已提交
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
/**
 *	tty_flip_buffer_push	-	terminal
 *	@tty: tty to push
 *
 *	Queue a push of the terminal flip buffers to the line discipline. This
 *	function must not be called from IRQ context if tty->low_latency is set.
 *
 *	In the event of the queue being busy for flipping the work will be
 *	held off and retried later.
 *
 *	Locking: tty buffer lock. Driver locks in low latency mode.
 */

void tty_flip_buffer_push(struct tty_struct *tty)
{
556
	struct tty_bufhead *buf = &tty->buf;
A
Alan Cox 已提交
557
	unsigned long flags;
558 559 560 561 562

	spin_lock_irqsave(&buf->lock, flags);
	if (buf->tail != NULL)
		buf->tail->commit = buf->tail->used;
	spin_unlock_irqrestore(&buf->lock, flags);
A
Alan Cox 已提交
563 564

	if (tty->low_latency)
565
		flush_to_ldisc(&buf->work);
A
Alan Cox 已提交
566
	else
567
		schedule_work(&buf->work);
A
Alan Cox 已提交
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
}
EXPORT_SYMBOL(tty_flip_buffer_push);

/**
 *	tty_buffer_init		-	prepare a tty buffer structure
 *	@tty: tty to initialise
 *
 *	Set up the initial state of the buffer management for a tty device.
 *	Must be called before the other tty buffer functions are used.
 *
 *	Locking: none
 */

void tty_buffer_init(struct tty_struct *tty)
{
583 584 585 586 587 588 589 590
	struct tty_bufhead *buf = &tty->buf;

	spin_lock_init(&buf->lock);
	buf->head = NULL;
	buf->tail = NULL;
	buf->free = NULL;
	buf->memory_used = 0;
	INIT_WORK(&buf->work, flush_to_ldisc);
A
Alan Cox 已提交
591 592
}