1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/kernel.h"
7#include "linux/sched.h"
8#include "linux/slab.h"
9#include "linux/list.h"
10#include "linux/kd.h"
11#include "linux/interrupt.h"
12#include "asm/uaccess.h"
13#include "chan_kern.h"
14#include "irq_user.h"
15#include "line.h"
16#include "kern.h"
17#include "kern_util.h"
18#include "os.h"
19#include "irq_kern.h"
20
21#define LINE_BUFSIZE 4096
22
23static irqreturn_t line_interrupt(int irq, void *data)
24{
25	struct chan *chan = data;
26	struct line *line = chan->line;
27	struct tty_struct *tty = line->tty;
28
29	if (line)
30		chan_interrupt(&line->chan_list, &line->task, tty, irq);
31	return IRQ_HANDLED;
32}
33
34static void line_timer_cb(struct work_struct *work)
35{
36	struct line *line = container_of(work, struct line, task.work);
37
38	if(!line->throttled)
39		chan_interrupt(&line->chan_list, &line->task, line->tty,
40			       line->driver->read_irq);
41}
42
43/* Returns the free space inside the ring buffer of this line.
44 *
45 * Should be called while holding line->lock (this does not modify datas).
46 */
47static int write_room(struct line *line)
48{
49	int n;
50
51	if (line->buffer == NULL)
52		return LINE_BUFSIZE - 1;
53
54	/* This is for the case where the buffer is wrapped! */
55	n = line->head - line->tail;
56
57	if (n <= 0)
58		n = LINE_BUFSIZE + n; /* The other case */
59	return n - 1;
60}
61
62int line_write_room(struct tty_struct *tty)
63{
64	struct line *line = tty->driver_data;
65	unsigned long flags;
66	int room;
67
68	if (tty->stopped)
69		return 0;
70
71	spin_lock_irqsave(&line->lock, flags);
72	room = write_room(line);
73	spin_unlock_irqrestore(&line->lock, flags);
74
75	if (0 == room)
76		printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
77		       __FUNCTION__,tty->name);
78	return room;
79}
80
81int line_chars_in_buffer(struct tty_struct *tty)
82{
83	struct line *line = tty->driver_data;
84	unsigned long flags;
85	int ret;
86
87	spin_lock_irqsave(&line->lock, flags);
88
89	/*write_room subtracts 1 for the needed NULL, so we readd it.*/
90	ret = LINE_BUFSIZE - (write_room(line) + 1);
91	spin_unlock_irqrestore(&line->lock, flags);
92
93	return ret;
94}
95
96/*
97 * This copies the content of buf into the circular buffer associated with
98 * this line.
99 * The return value is the number of characters actually copied, i.e. the ones
100 * for which there was space: this function is not supposed to ever flush out
101 * the circular buffer.
102 *
103 * Must be called while holding line->lock!
104 */
105static int buffer_data(struct line *line, const char *buf, int len)
106{
107	int end, room;
108
109	if(line->buffer == NULL){
110		line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
111		if (line->buffer == NULL) {
112			printk("buffer_data - atomic allocation failed\n");
113			return(0);
114		}
115		line->head = line->buffer;
116		line->tail = line->buffer;
117	}
118
119	room = write_room(line);
120	len = (len > room) ? room : len;
121
122	end = line->buffer + LINE_BUFSIZE - line->tail;
123
124	if (len < end){
125		memcpy(line->tail, buf, len);
126		line->tail += len;
127	}
128	else {
129		/* The circular buffer is wrapping */
130		memcpy(line->tail, buf, end);
131		buf += end;
132		memcpy(line->buffer, buf, len - end);
133		line->tail = line->buffer + len - end;
134	}
135
136	return len;
137}
138
139/*
140 * Flushes the ring buffer to the output channels. That is, write_chan is
141 * called, passing it line->head as buffer, and an appropriate count.
142 *
143 * On exit, returns 1 when the buffer is empty,
144 * 0 when the buffer is not empty on exit,
145 * and -errno when an error occurred.
146 *
147 * Must be called while holding line->lock!*/
148static int flush_buffer(struct line *line)
149{
150	int n, count;
151
152	if ((line->buffer == NULL) || (line->head == line->tail))
153		return 1;
154
155	if (line->tail < line->head) {
156		/* line->buffer + LINE_BUFSIZE is the end of the buffer! */
157		count = line->buffer + LINE_BUFSIZE - line->head;
158
159		n = write_chan(&line->chan_list, line->head, count,
160			       line->driver->write_irq);
161		if (n < 0)
162			return n;
163		if (n == count) {
164			/* We have flushed from ->head to buffer end, now we
165			 * must flush only from the beginning to ->tail.*/
166			line->head = line->buffer;
167		} else {
168			line->head += n;
169			return 0;
170		}
171	}
172
173	count = line->tail - line->head;
174	n = write_chan(&line->chan_list, line->head, count,
175		       line->driver->write_irq);
176
177	if(n < 0)
178		return n;
179
180	line->head += n;
181	return line->head == line->tail;
182}
183
184void line_flush_buffer(struct tty_struct *tty)
185{
186	struct line *line = tty->driver_data;
187	unsigned long flags;
188	int err;
189
190	if(tty->stopped)
191		return;
192
193	spin_lock_irqsave(&line->lock, flags);
194	err = flush_buffer(line);
195	/*if (err == 1)
196		err = 0;*/
197	spin_unlock_irqrestore(&line->lock, flags);
198	//return err;
199}
200
201/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer
202 * and ->write. Hope it's not that bad.*/
203void line_flush_chars(struct tty_struct *tty)
204{
205	line_flush_buffer(tty);
206}
207
208void line_put_char(struct tty_struct *tty, unsigned char ch)
209{
210	line_write(tty, &ch, sizeof(ch));
211}
212
213int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
214{
215	struct line *line = tty->driver_data;
216	unsigned long flags;
217	int n, err, ret = 0;
218
219	if(tty->stopped)
220		return 0;
221
222	spin_lock_irqsave(&line->lock, flags);
223	if (line->head != line->tail) {
224		ret = buffer_data(line, buf, len);
225		err = flush_buffer(line);
226		if (err <= 0 && (err != -EAGAIN || !ret))
227			ret = err;
228	} else {
229		n = write_chan(&line->chan_list, buf, len,
230			       line->driver->write_irq);
231		if (n < 0) {
232			ret = n;
233			goto out_up;
234		}
235
236		len -= n;
237		ret += n;
238		if (len > 0)
239			ret += buffer_data(line, buf + n, len);
240	}
241out_up:
242	spin_unlock_irqrestore(&line->lock, flags);
243	return ret;
244}
245
246void line_set_termios(struct tty_struct *tty, struct ktermios * old)
247{
248	/* nothing */
249}
250
251static const struct {
252	int  cmd;
253	char *level;
254	char *name;
255} tty_ioctls[] = {
256	/* don't print these, they flood the log ... */
257	{ TCGETS,      NULL,       "TCGETS"      },
258        { TCSETS,      NULL,       "TCSETS"      },
259        { TCSETSW,     NULL,       "TCSETSW"     },
260        { TCFLSH,      NULL,       "TCFLSH"      },
261        { TCSBRK,      NULL,       "TCSBRK"      },
262
263	/* general tty stuff */
264        { TCSETSF,     KERN_DEBUG, "TCSETSF"     },
265        { TCGETA,      KERN_DEBUG, "TCGETA"      },
266        { TIOCMGET,    KERN_DEBUG, "TIOCMGET"    },
267        { TCSBRKP,     KERN_DEBUG, "TCSBRKP"     },
268        { TIOCMSET,    KERN_DEBUG, "TIOCMSET"    },
269
270	/* linux-specific ones */
271	{ TIOCLINUX,   KERN_INFO,  "TIOCLINUX"   },
272	{ KDGKBMODE,   KERN_INFO,  "KDGKBMODE"   },
273	{ KDGKBTYPE,   KERN_INFO,  "KDGKBTYPE"   },
274	{ KDSIGACCEPT, KERN_INFO,  "KDSIGACCEPT" },
275};
276
277int line_ioctl(struct tty_struct *tty, struct file * file,
278	       unsigned int cmd, unsigned long arg)
279{
280	int ret;
281	int i;
282
283	ret = 0;
284	switch(cmd) {
285#ifdef TIOCGETP
286	case TIOCGETP:
287	case TIOCSETP:
288	case TIOCSETN:
289#endif
290#ifdef TIOCGETC
291	case TIOCGETC:
292	case TIOCSETC:
293#endif
294#ifdef TIOCGLTC
295	case TIOCGLTC:
296	case TIOCSLTC:
297#endif
298	case TCGETS:
299	case TCSETSF:
300	case TCSETSW:
301	case TCSETS:
302	case TCGETA:
303	case TCSETAF:
304	case TCSETAW:
305	case TCSETA:
306	case TCXONC:
307	case TCFLSH:
308	case TIOCOUTQ:
309	case TIOCINQ:
310	case TIOCGLCKTRMIOS:
311	case TIOCSLCKTRMIOS:
312	case TIOCPKT:
313	case TIOCGSOFTCAR:
314	case TIOCSSOFTCAR:
315		return -ENOIOCTLCMD;
316	default:
317		for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
318			if (cmd == tty_ioctls[i].cmd)
319				break;
320		if (i < ARRAY_SIZE(tty_ioctls)) {
321			if (NULL != tty_ioctls[i].level)
322				printk("%s%s: %s: ioctl %s called\n",
323				       tty_ioctls[i].level, __FUNCTION__,
324				       tty->name, tty_ioctls[i].name);
325		} else {
326			printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
327			       __FUNCTION__, tty->name, cmd);
328		}
329		ret = -ENOIOCTLCMD;
330		break;
331	}
332	return ret;
333}
334
335void line_throttle(struct tty_struct *tty)
336{
337	struct line *line = tty->driver_data;
338
339	deactivate_chan(&line->chan_list, line->driver->read_irq);
340	line->throttled = 1;
341}
342
343void line_unthrottle(struct tty_struct *tty)
344{
345	struct line *line = tty->driver_data;
346
347	line->throttled = 0;
348	chan_interrupt(&line->chan_list, &line->task, tty,
349		       line->driver->read_irq);
350
351	/* Maybe there is enough stuff pending that calling the interrupt
352	 * throttles us again.  In this case, line->throttled will be 1
353	 * again and we shouldn't turn the interrupt back on.
354	 */
355	if(!line->throttled)
356		reactivate_chan(&line->chan_list, line->driver->read_irq);
357}
358
359static irqreturn_t line_write_interrupt(int irq, void *data)
360{
361	struct chan *chan = data;
362	struct line *line = chan->line;
363	struct tty_struct *tty = line->tty;
364	int err;
365
366	/* Interrupts are disabled here because we registered the interrupt with
367	 * IRQF_DISABLED (see line_setup_irq).*/
368
369	spin_lock(&line->lock);
370	err = flush_buffer(line);
371	if (err == 0) {
372		return IRQ_NONE;
373	} else if(err < 0) {
374		line->head = line->buffer;
375		line->tail = line->buffer;
376	}
377	spin_unlock(&line->lock);
378
379	if(tty == NULL)
380		return IRQ_NONE;
381
382	if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
383	   (tty->ldisc.write_wakeup != NULL))
384		(tty->ldisc.write_wakeup)(tty);
385
386	/* BLOCKING mode
387	 * In blocking mode, everything sleeps on tty->write_wait.
388	 * Sleeping in the console driver would break non-blocking
389	 * writes.
390	 */
391
392	if (waitqueue_active(&tty->write_wait))
393		wake_up_interruptible(&tty->write_wait);
394	return IRQ_HANDLED;
395}
396
397int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
398{
399	const struct line_driver *driver = line->driver;
400	int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM;
401
402	if (input)
403		err = um_request_irq(driver->read_irq, fd, IRQ_READ,
404				       line_interrupt, flags,
405				       driver->read_irq_name, data);
406	if (err)
407		return err;
408	if (output)
409		err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
410					line_write_interrupt, flags,
411					driver->write_irq_name, data);
412	line->have_irq = 1;
413	return err;
414}
415
416/* Normally, a driver like this can rely mostly on the tty layer
417 * locking, particularly when it comes to the driver structure.
418 * However, in this case, mconsole requests can come in "from the
419 * side", and race with opens and closes.
420 *
421 * mconsole config requests will want to be sure the device isn't in
422 * use, and get_config, open, and close will want a stable
423 * configuration.  The checking and modification of the configuration
424 * is done under a spinlock.  Checking whether the device is in use is
425 * line->tty->count > 1, also under the spinlock.
426 *
427 * tty->count serves to decide whether the device should be enabled or
428 * disabled on the host.  If it's equal to 1, then we are doing the
429 * first open or last close.  Otherwise, open and close just return.
430 */
431
432int line_open(struct line *lines, struct tty_struct *tty)
433{
434	struct line *line = &lines[tty->index];
435	int err = -ENODEV;
436
437	spin_lock(&line->count_lock);
438	if(!line->valid)
439		goto out_unlock;
440
441	err = 0;
442	if(tty->count > 1)
443		goto out_unlock;
444
445	spin_unlock(&line->count_lock);
446
447	tty->driver_data = line;
448	line->tty = tty;
449
450	enable_chan(line);
451	INIT_DELAYED_WORK(&line->task, line_timer_cb);
452
453	if(!line->sigio){
454		chan_enable_winch(&line->chan_list, tty);
455		line->sigio = 1;
456	}
457
458	chan_window_size(&line->chan_list, &tty->winsize.ws_row,
459			 &tty->winsize.ws_col);
460
461	return err;
462
463out_unlock:
464	spin_unlock(&line->count_lock);
465	return err;
466}
467
468static void unregister_winch(struct tty_struct *tty);
469
470void line_close(struct tty_struct *tty, struct file * filp)
471{
472	struct line *line = tty->driver_data;
473
474	/* If line_open fails (and tty->driver_data is never set),
475	 * tty_open will call line_close.  So just return in this case.
476	 */
477	if(line == NULL)
478		return;
479
480	/* We ignore the error anyway! */
481	flush_buffer(line);
482
483	spin_lock(&line->count_lock);
484	if(!line->valid)
485		goto out_unlock;
486
487	if(tty->count > 1)
488		goto out_unlock;
489
490	spin_unlock(&line->count_lock);
491
492	line->tty = NULL;
493	tty->driver_data = NULL;
494
495	if(line->sigio){
496		unregister_winch(tty);
497		line->sigio = 0;
498        }
499
500	return;
501
502out_unlock:
503	spin_unlock(&line->count_lock);
504}
505
506void close_lines(struct line *lines, int nlines)
507{
508	int i;
509
510	for(i = 0; i < nlines; i++)
511		close_chan(&lines[i].chan_list, 0);
512}
513
514static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
515			  char **error_out)
516{
517	struct line *line = &lines[n];
518	int err = -EINVAL;
519
520	spin_lock(&line->count_lock);
521
522	if(line->tty != NULL){
523		*error_out = "Device is already open";
524		goto out;
525	}
526
527	if (line->init_pri <= init_prio){
528		line->init_pri = init_prio;
529		if (!strcmp(init, "none"))
530			line->valid = 0;
531		else {
532			line->init_str = init;
533			line->valid = 1;
534		}
535	}
536	err = 0;
537out:
538	spin_unlock(&line->count_lock);
539	return err;
540}
541
542/* Common setup code for both startup command line and mconsole initialization.
543 * @lines contains the array (of size @num) to modify;
544 * @init is the setup string;
545 * @error_out is an error string in the case of failure;
546 */
547
548int line_setup(struct line *lines, unsigned int num, char *init,
549	       char **error_out)
550{
551	int i, n, err;
552	char *end;
553
554	if(*init == '=') {
555		/* We said con=/ssl= instead of con#=, so we are configuring all
556		 * consoles at once.*/
557		n = -1;
558	}
559	else {
560		n = simple_strtoul(init, &end, 0);
561		if(*end != '='){
562			*error_out = "Couldn't parse device number";
563			return -EINVAL;
564		}
565		init = end;
566	}
567	init++;
568
569	if (n >= (signed int) num) {
570		*error_out = "Device number out of range";
571		return -EINVAL;
572	}
573	else if (n >= 0){
574		err = setup_one_line(lines, n, init, INIT_ONE, error_out);
575		if(err)
576			return err;
577	}
578	else {
579		for(i = 0; i < num; i++){
580			err = setup_one_line(lines, i, init, INIT_ALL,
581					     error_out);
582			if(err)
583				return err;
584		}
585	}
586	return n == -1 ? num : n;
587}
588
589int line_config(struct line *lines, unsigned int num, char *str,
590		const struct chan_opts *opts, char **error_out)
591{
592	struct line *line;
593	char *new;
594	int n;
595
596	if(*str == '='){
597		*error_out = "Can't configure all devices from mconsole";
598		return -EINVAL;
599	}
600
601	new = kstrdup(str, GFP_KERNEL);
602	if(new == NULL){
603		*error_out = "Failed to allocate memory";
604		return -ENOMEM;
605	}
606	n = line_setup(lines, num, new, error_out);
607	if(n < 0)
608		return n;
609
610	line = &lines[n];
611	return parse_chan_pair(line->init_str, line, n, opts, error_out);
612}
613
614int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
615		    int size, char **error_out)
616{
617	struct line *line;
618	char *end;
619	int dev, n = 0;
620
621	dev = simple_strtoul(name, &end, 0);
622	if((*end != '\0') || (end == name)){
623		*error_out = "line_get_config failed to parse device number";
624		return 0;
625	}
626
627	if((dev < 0) || (dev >= num)){
628		*error_out = "device number out of range";
629		return 0;
630	}
631
632	line = &lines[dev];
633
634	spin_lock(&line->count_lock);
635	if(!line->valid)
636		CONFIG_CHUNK(str, size, n, "none", 1);
637	else if(line->tty == NULL)
638		CONFIG_CHUNK(str, size, n, line->init_str, 1);
639	else n = chan_config_string(&line->chan_list, str, size, error_out);
640	spin_unlock(&line->count_lock);
641
642	return n;
643}
644
645int line_id(char **str, int *start_out, int *end_out)
646{
647	char *end;
648        int n;
649
650	n = simple_strtoul(*str, &end, 0);
651	if((*end != '\0') || (end == *str))
652                return -1;
653
654        *str = end;
655        *start_out = n;
656        *end_out = n;
657        return n;
658}
659
660int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
661{
662	int err;
663	char config[sizeof("conxxxx=none\0")];
664
665	sprintf(config, "%d=none", n);
666	err = line_setup(lines, num, config, error_out);
667	if(err >= 0)
668		err = 0;
669	return err;
670}
671
672struct tty_driver *register_lines(struct line_driver *line_driver,
673				  const struct tty_operations *ops,
674				  struct line *lines, int nlines)
675{
676	int i;
677	struct tty_driver *driver = alloc_tty_driver(nlines);
678
679	if (!driver)
680		return NULL;
681
682	driver->driver_name = line_driver->name;
683	driver->name = line_driver->device_name;
684	driver->major = line_driver->major;
685	driver->minor_start = line_driver->minor_start;
686	driver->type = line_driver->type;
687	driver->subtype = line_driver->subtype;
688	driver->flags = TTY_DRIVER_REAL_RAW;
689	driver->init_termios = tty_std_termios;
690	tty_set_operations(driver, ops);
691
692	if (tty_register_driver(driver)) {
693		printk("%s: can't register %s driver\n",
694		       __FUNCTION__,line_driver->name);
695		put_tty_driver(driver);
696		return NULL;
697	}
698
699	for(i = 0; i < nlines; i++){
700		if(!lines[i].valid)
701			tty_unregister_device(driver, i);
702	}
703
704	mconsole_register_dev(&line_driver->mc);
705	return driver;
706}
707
708static DEFINE_SPINLOCK(winch_handler_lock);
709static LIST_HEAD(winch_handlers);
710
711void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
712{
713	struct line *line;
714	char *error;
715	int i;
716
717	for(i = 0; i < nlines; i++){
718		line = &lines[i];
719		INIT_LIST_HEAD(&line->chan_list);
720
721		if(line->init_str == NULL)
722			continue;
723
724		line->init_str = kstrdup(line->init_str, GFP_KERNEL);
725		if(line->init_str == NULL)
726			printk("lines_init - kstrdup returned NULL\n");
727
728		if(parse_chan_pair(line->init_str, line, i, opts, &error)){
729			printk("parse_chan_pair failed for device %d : %s\n",
730			       i, error);
731			line->valid = 0;
732		}
733	}
734}
735
736struct winch {
737	struct list_head list;
738	int fd;
739	int tty_fd;
740	int pid;
741	struct tty_struct *tty;
742};
743
744static irqreturn_t winch_interrupt(int irq, void *data)
745{
746	struct winch *winch = data;
747	struct tty_struct *tty;
748	struct line *line;
749	int err;
750	char c;
751
752	if(winch->fd != -1){
753		err = generic_read(winch->fd, &c, NULL);
754		if(err < 0){
755			if(err != -EAGAIN){
756				printk("winch_interrupt : read failed, "
757				       "errno = %d\n", -err);
758				printk("fd %d is losing SIGWINCH support\n",
759				       winch->tty_fd);
760				return IRQ_HANDLED;
761			}
762			goto out;
763		}
764	}
765	tty  = winch->tty;
766	if (tty != NULL) {
767		line = tty->driver_data;
768		chan_window_size(&line->chan_list, &tty->winsize.ws_row,
769				 &tty->winsize.ws_col);
770		kill_pgrp(tty->pgrp, SIGWINCH, 1);
771	}
772 out:
773	if(winch->fd != -1)
774		reactivate_fd(winch->fd, WINCH_IRQ);
775	return IRQ_HANDLED;
776}
777
778void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
779{
780	struct winch *winch;
781
782	winch = kmalloc(sizeof(*winch), GFP_KERNEL);
783	if (winch == NULL) {
784		printk("register_winch_irq - kmalloc failed\n");
785		return;
786	}
787
788	*winch = ((struct winch) { .list  	= LIST_HEAD_INIT(winch->list),
789				   .fd  	= fd,
790				   .tty_fd 	= tty_fd,
791				   .pid  	= pid,
792				   .tty 	= tty });
793
794	spin_lock(&winch_handler_lock);
795	list_add(&winch->list, &winch_handlers);
796	spin_unlock(&winch_handler_lock);
797
798	if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
799			  IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
800			  "winch", winch) < 0)
801		printk("register_winch_irq - failed to register IRQ\n");
802}
803
804static void free_winch(struct winch *winch)
805{
806	list_del(&winch->list);
807
808	if(winch->pid != -1)
809		os_kill_process(winch->pid, 1);
810	if(winch->fd != -1)
811		os_close_file(winch->fd);
812
813	free_irq(WINCH_IRQ, winch);
814	kfree(winch);
815}
816
817static void unregister_winch(struct tty_struct *tty)
818{
819	struct list_head *ele;
820	struct winch *winch;
821
822	spin_lock(&winch_handler_lock);
823
824	list_for_each(ele, &winch_handlers){
825		winch = list_entry(ele, struct winch, list);
826                if(winch->tty == tty){
827			free_winch(winch);
828			break;
829                }
830        }
831	spin_unlock(&winch_handler_lock);
832}
833
834static void winch_cleanup(void)
835{
836	struct list_head *ele, *next;
837	struct winch *winch;
838
839	spin_lock(&winch_handler_lock);
840
841	list_for_each_safe(ele, next, &winch_handlers){
842		winch = list_entry(ele, struct winch, list);
843		free_winch(winch);
844	}
845
846	spin_unlock(&winch_handler_lock);
847}
848__uml_exitcall(winch_cleanup);
849
850char *add_xterm_umid(char *base)
851{
852	char *umid, *title;
853	int len;
854
855	umid = get_umid();
856	if(*umid == '\0')
857		return base;
858
859	len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
860	title = kmalloc(len, GFP_KERNEL);
861	if(title == NULL){
862		printk("Failed to allocate buffer for xterm title\n");
863		return base;
864	}
865
866	snprintf(title, len, "%s (%s)", base, umid);
867	return title;
868}
869