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