2005-04-17 02:20:36 +04:00
/*
2007-07-16 10:38:52 +04:00
* Copyright ( C ) 2001 - 2007 Jeff Dike ( jdike @ { addtoit , linux . intel } . com )
2005-04-17 02:20:36 +04:00
* Licensed under the GPL
*/
2007-07-16 10:38:52 +04:00
# include <linux/slab.h>
# include <linux/completion.h>
# include <linux/irqreturn.h>
# include <asm/irq.h>
2012-10-08 06:27:32 +04:00
# include <irq_kern.h>
# include <os.h>
2005-04-17 02:20:36 +04:00
struct xterm_wait {
struct completion ready ;
int fd ;
int pid ;
int new_fd ;
} ;
2006-10-09 01:49:34 +04:00
static irqreturn_t xterm_interrupt ( int irq , void * data )
2005-04-17 02:20:36 +04:00
{
struct xterm_wait * xterm = data ;
int fd ;
fd = os_rcv_fd ( xterm - > fd , & xterm - > pid ) ;
2007-07-16 10:38:52 +04:00
if ( fd = = - EAGAIN )
return IRQ_NONE ;
2005-04-17 02:20:36 +04:00
xterm - > new_fd = fd ;
complete ( & xterm - > ready ) ;
2007-07-16 10:38:52 +04:00
return IRQ_HANDLED ;
2005-04-17 02:20:36 +04:00
}
int xterm_fd ( int socket , int * pid_out )
{
struct xterm_wait * data ;
int err , ret ;
data = kmalloc ( sizeof ( * data ) , GFP_KERNEL ) ;
2007-07-16 10:38:52 +04:00
if ( data = = NULL ) {
2005-04-17 02:20:36 +04:00
printk ( KERN_ERR " xterm_fd : failed to allocate xterm_wait \n " ) ;
2007-07-16 10:38:52 +04:00
return - ENOMEM ;
2005-04-17 02:20:36 +04:00
}
/* This is a locked semaphore... */
2007-07-16 10:38:52 +04:00
* data = ( ( struct xterm_wait ) { . fd = socket ,
. pid = - 1 ,
. new_fd = - 1 } ) ;
2005-04-17 02:20:36 +04:00
init_completion ( & data - > ready ) ;
2007-07-16 10:38:52 +04:00
err = um_request_irq ( XTERM_IRQ , socket , IRQ_READ , xterm_interrupt ,
2012-07-17 22:18:23 +04:00
IRQF_SHARED , " xterm " , data ) ;
2007-07-16 10:38:52 +04:00
if ( err ) {
2005-04-17 02:20:36 +04:00
printk ( KERN_ERR " xterm_fd : failed to get IRQ for xterm, "
" err = %d \n " , err ) ;
ret = err ;
goto out ;
}
/* ... so here we wait for an xterm interrupt.
*
* XXX Note , if the xterm doesn ' t work for some reason ( eg . DISPLAY
* isn ' t set ) this will hang . . . */
wait_for_completion ( & data - > ready ) ;
2012-04-18 00:37:13 +04:00
um_free_irq ( XTERM_IRQ , data ) ;
2005-04-17 02:20:36 +04:00
ret = data - > new_fd ;
* pid_out = data - > pid ;
out :
kfree ( data ) ;
2007-07-16 10:38:52 +04:00
return ret ;
2005-04-17 02:20:36 +04:00
}