xref: /linux/arch/um/drivers/xterm_kern.c (revision 7bea96fd22a8fd19f90817405b4abe032317a0e3)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31da177e4SLinus Torvalds  * Licensed under the GPL
41da177e4SLinus Torvalds  */
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds #include "linux/errno.h"
71da177e4SLinus Torvalds #include "linux/slab.h"
81da177e4SLinus Torvalds #include "linux/signal.h"
91da177e4SLinus Torvalds #include "linux/interrupt.h"
101da177e4SLinus Torvalds #include "asm/irq.h"
111da177e4SLinus Torvalds #include "irq_user.h"
121da177e4SLinus Torvalds #include "irq_kern.h"
131da177e4SLinus Torvalds #include "kern_util.h"
141da177e4SLinus Torvalds #include "os.h"
151da177e4SLinus Torvalds #include "xterm.h"
161da177e4SLinus Torvalds 
171da177e4SLinus Torvalds struct xterm_wait {
181da177e4SLinus Torvalds 	struct completion ready;
191da177e4SLinus Torvalds 	int fd;
201da177e4SLinus Torvalds 	int pid;
211da177e4SLinus Torvalds 	int new_fd;
221da177e4SLinus Torvalds };
231da177e4SLinus Torvalds 
24*7bea96fdSAl Viro static irqreturn_t xterm_interrupt(int irq, void *data)
251da177e4SLinus Torvalds {
261da177e4SLinus Torvalds 	struct xterm_wait *xterm = data;
271da177e4SLinus Torvalds 	int fd;
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds 	fd = os_rcv_fd(xterm->fd, &xterm->pid);
301da177e4SLinus Torvalds 	if(fd == -EAGAIN)
311da177e4SLinus Torvalds 		return(IRQ_NONE);
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds 	xterm->new_fd = fd;
341da177e4SLinus Torvalds 	complete(&xterm->ready);
351da177e4SLinus Torvalds 	return(IRQ_HANDLED);
361da177e4SLinus Torvalds }
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds int xterm_fd(int socket, int *pid_out)
391da177e4SLinus Torvalds {
401da177e4SLinus Torvalds 	struct xterm_wait *data;
411da177e4SLinus Torvalds 	int err, ret;
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds 	data = kmalloc(sizeof(*data), GFP_KERNEL);
441da177e4SLinus Torvalds 	if(data == NULL){
451da177e4SLinus Torvalds 		printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
461da177e4SLinus Torvalds 		return(-ENOMEM);
471da177e4SLinus Torvalds 	}
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds 	/* This is a locked semaphore... */
501da177e4SLinus Torvalds 	*data = ((struct xterm_wait)
511da177e4SLinus Torvalds 		{ .fd 		= socket,
521da177e4SLinus Torvalds 		  .pid 		= -1,
531da177e4SLinus Torvalds 		  .new_fd 	= -1 });
541da177e4SLinus Torvalds 	init_completion(&data->ready);
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds 	err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
57bd6aa650SThomas Gleixner 			     IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
581da177e4SLinus Torvalds 			     "xterm", data);
591da177e4SLinus Torvalds 	if (err){
601da177e4SLinus Torvalds 		printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
611da177e4SLinus Torvalds 		       "err = %d\n",  err);
621da177e4SLinus Torvalds 		ret = err;
631da177e4SLinus Torvalds 		goto out;
641da177e4SLinus Torvalds 	}
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds 	/* ... so here we wait for an xterm interrupt.
671da177e4SLinus Torvalds 	 *
681da177e4SLinus Torvalds 	 * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY
691da177e4SLinus Torvalds 	 * isn't set) this will hang... */
701da177e4SLinus Torvalds 	wait_for_completion(&data->ready);
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds 	free_irq(XTERM_IRQ, data);
731da177e4SLinus Torvalds 
741da177e4SLinus Torvalds 	ret = data->new_fd;
751da177e4SLinus Torvalds 	*pid_out = data->pid;
761da177e4SLinus Torvalds  out:
771da177e4SLinus Torvalds 	kfree(data);
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds 	return(ret);
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds /*
831da177e4SLinus Torvalds  * Overrides for Emacs so that we follow Linus's tabbing style.
841da177e4SLinus Torvalds  * Emacs will notice this stuff at the end of the file and automatically
851da177e4SLinus Torvalds  * adjust the settings for this buffer only.  This must remain at the end
861da177e4SLinus Torvalds  * of the file.
871da177e4SLinus Torvalds  * ---------------------------------------------------------------------------
881da177e4SLinus Torvalds  * Local variables:
891da177e4SLinus Torvalds  * c-file-style: "linux"
901da177e4SLinus Torvalds  * End:
911da177e4SLinus Torvalds  */
92