1 /* 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6 #include <linux/slab.h> 7 #include <linux/completion.h> 8 #include <linux/irqreturn.h> 9 #include <asm/irq.h> 10 #include "irq_kern.h" 11 #include "os.h" 12 13 struct xterm_wait { 14 struct completion ready; 15 int fd; 16 int pid; 17 int new_fd; 18 }; 19 20 static irqreturn_t xterm_interrupt(int irq, void *data) 21 { 22 struct xterm_wait *xterm = data; 23 int fd; 24 25 fd = os_rcv_fd(xterm->fd, &xterm->pid); 26 if (fd == -EAGAIN) 27 return IRQ_NONE; 28 29 xterm->new_fd = fd; 30 complete(&xterm->ready); 31 32 return IRQ_HANDLED; 33 } 34 35 int xterm_fd(int socket, int *pid_out) 36 { 37 struct xterm_wait *data; 38 int err, ret; 39 40 data = kmalloc(sizeof(*data), GFP_KERNEL); 41 if (data == NULL) { 42 printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n"); 43 return -ENOMEM; 44 } 45 46 /* This is a locked semaphore... */ 47 *data = ((struct xterm_wait) { .fd = socket, 48 .pid = -1, 49 .new_fd = -1 }); 50 init_completion(&data->ready); 51 52 err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 53 IRQF_SHARED | IRQF_SAMPLE_RANDOM, 54 "xterm", data); 55 if (err) { 56 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " 57 "err = %d\n", err); 58 ret = err; 59 goto out; 60 } 61 62 /* ... so here we wait for an xterm interrupt. 63 * 64 * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY 65 * isn't set) this will hang... */ 66 wait_for_completion(&data->ready); 67 68 free_irq(XTERM_IRQ, data); 69 70 ret = data->new_fd; 71 *pid_out = data->pid; 72 out: 73 kfree(data); 74 75 return ret; 76 } 77