^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 Anton Blanchard <anton@au.ibm.com>, IBM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Additional Author(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Ryan S. Arnold <rsa@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/cpumask.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kbd_kern.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sysrq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "hvc_console.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define HVC_MAJOR 229
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define HVC_MINOR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Wait this long per iteration while trying to push buffered data to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * hypervisor before allowing the tty to complete a close operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * These sizes are most efficient for vio, because they are the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * native transfer size. We could make them selectable in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * future to better deal with backends that want other buffer sizes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define N_OUTBUF 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define N_INBUF 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static struct tty_driver *hvc_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static struct task_struct *hvc_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Picks up late kicks after list walk but before schedule() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int hvc_kicked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* hvc_init is triggered from hvc_alloc, i.e. only when actually used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static atomic_t hvc_needs_init __read_mostly = ATOMIC_INIT(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int hvc_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int sysrq_pressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* dynamic list of hvc_struct instances */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static LIST_HEAD(hvc_structs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Protect the list of hvc_struct instances from inserts and removals during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * list traversal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static DEFINE_MUTEX(hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * This value is used to assign a tty->index value to a hvc_struct based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * upon order of exposure via hvc_probe(), when we can not match it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * a console candidate registered with hvc_instantiate().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int last_hvc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * Do not call this function with either the hvc_structs_mutex or the hvc_struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * lock held. If successful, this function increments the kref reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * count against the target hvc_struct so it should be released when finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static struct hvc_struct *hvc_get_by_index(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct hvc_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) mutex_lock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) list_for_each_entry(hp, &hvc_structs, next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (hp->index == index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) tty_port_get(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mutex_unlock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) hp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mutex_unlock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int __hvc_flush(const struct hv_ops *ops, uint32_t vtermno, bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ops->flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return ops->flush(vtermno, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int hvc_console_flush(const struct hv_ops *ops, uint32_t vtermno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return __hvc_flush(ops, vtermno, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Wait for the console to flush before writing more to it. This sleeps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int hvc_flush(struct hvc_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return __hvc_flush(hp->ops, hp->vtermno, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Initial console vtermnos for console API usage prior to full console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * initialization. Any vty adapter outside this range will not have usable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * console interfaces but can still be used as a tty device. This has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * static because kmalloc will not work during early console init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static const struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * Console APIs, NOT TTY. These APIs are available immediately when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * hvc_console_setup() finds adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void hvc_console_print(struct console *co, const char *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) char c[N_OUTBUF] __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned i = 0, n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int r, donecr = 0, index = co->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Console access attempt outside of acceptable console range. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (index >= MAX_NR_HVC_CONSOLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* This console adapter was removed so it is not usable. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (vtermnos[index] == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) while (count > 0 || i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (count > 0 && i < sizeof(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (b[n] == '\n' && !donecr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) c[i++] = '\r';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) donecr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) c[i++] = b[n++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) donecr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) --count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) r = cons_ops[index]->put_chars(vtermnos[index], c, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (r <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* throw away characters on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * but spin in case of -EAGAIN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (r != -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) hvc_console_flush(cons_ops[index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) vtermnos[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } else if (r > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) i -= r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) memmove(c, c+r, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) hvc_console_flush(cons_ops[index], vtermnos[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static struct tty_driver *hvc_console_device(struct console *c, int *index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (vtermnos[c->index] == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *index = c->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return hvc_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int hvc_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (vtermnos[co->index] == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static struct console hvc_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .name = "hvc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .write = hvc_console_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .device = hvc_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .setup = hvc_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * Early console initialization. Precedes driver initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * (1) we are first, and the user specified another driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * -- index will remain -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * (2) we are first and the user specified no driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * -- index will be set to 0, then we will fail setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * (3) we are first and the user specified our driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * -- index will be set to user specified driver, and we will fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * (4) we are after driver, and this initcall will register us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * -- if the user didn't specify a driver then the console will match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Note that for cases 2 and 3, we will match later when the io driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * calls hvc_instantiate() and call register again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int __init hvc_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) register_console(&hvc_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) console_initcall(hvc_console_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* callback when the kboject ref count reaches zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static void hvc_port_destruct(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct hvc_struct *hp = container_of(port, struct hvc_struct, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) mutex_lock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) list_del(&(hp->next));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mutex_unlock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) kfree(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void hvc_check_console(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Already enabled, bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (hvc_console.flags & CON_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* If this index is what the user requested, then register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * now (setup won't fail at this point). It's ok to just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * call register again if previously .setup failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (index == hvc_console.index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) register_console(&hvc_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * hvc_instantiate() is an early console discovery method which locates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * consoles * prior to the vio subsystem discovering them. Hotplugged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * vty adapters do NOT get an hvc_instantiate() callback since they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * appear after early console init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct hvc_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (vtermnos[index] != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* make sure no no tty has been registered in this index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) hp = hvc_get_by_index(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (hp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) tty_port_put(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) vtermnos[index] = vtermno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cons_ops[index] = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* check if we need to re-register the kernel console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) hvc_check_console(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) EXPORT_SYMBOL_GPL(hvc_instantiate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* Wake the sleeping khvcd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) void hvc_kick(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) hvc_kicked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) wake_up_process(hvc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) EXPORT_SYMBOL_GPL(hvc_kick);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static void hvc_unthrottle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) hvc_kick();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int hvc_install(struct tty_driver *driver, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct hvc_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* Auto increments kref reference if found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) hp = hvc_get_by_index(tty->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) tty->driver_data = hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) rc = tty_port_install(&hp->port, driver, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) tty_port_put(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * The TTY interface won't be used until after the vio layer has exposed the vty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * adapter to the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int hvc_open(struct tty_struct *tty, struct file * filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) spin_lock_irqsave(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Check and then increment for fast path open. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (hp->port.count++ > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) spin_unlock_irqrestore(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) hvc_kick();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) } /* else count == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) spin_unlock_irqrestore(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) tty_port_tty_set(&hp->port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (hp->ops->notifier_add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) rc = hp->ops->notifier_add(hp, hp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * If the notifier fails we return an error. The tty layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * will call hvc_close() after a failed open but we don't want to clean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * up there so we'll clean up here and clear out the previously set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * tty fields and return the kref reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* We are ready... raise DTR/RTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (C_BAUD(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (hp->ops->dtr_rts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) hp->ops->dtr_rts(hp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) tty_port_set_initialized(&hp->port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Force wakeup of the polling thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) hvc_kick();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void hvc_close(struct tty_struct *tty, struct file * filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (tty_hung_up_p(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) spin_lock_irqsave(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (--hp->port.count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) spin_unlock_irqrestore(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* We are done with the tty pointer now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) tty_port_tty_set(&hp->port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (!tty_port_initialized(&hp->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (C_HUPCL(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (hp->ops->dtr_rts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) hp->ops->dtr_rts(hp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (hp->ops->notifier_del)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) hp->ops->notifier_del(hp, hp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* cancel pending tty resize work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) cancel_work_sync(&hp->tty_resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * Chain calls chars_in_buffer() and returns immediately if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * there is no buffered data otherwise sleeps on a wait queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * waking periodically to check chars_in_buffer().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) tty_port_set_initialized(&hp->port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (hp->port.count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) hp->vtermno, hp->port.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) spin_unlock_irqrestore(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static void hvc_cleanup(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) tty_port_put(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static void hvc_hangup(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* cancel pending tty resize work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) cancel_work_sync(&hp->tty_resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) spin_lock_irqsave(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * The N_TTY line discipline has problems such that in a close vs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * open->hangup case this can be called after the final close so prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * that from happening for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (hp->port.count <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) spin_unlock_irqrestore(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) hp->port.count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) spin_unlock_irqrestore(&hp->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) tty_port_tty_set(&hp->port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) hp->n_outbuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (hp->ops->notifier_hangup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) hp->ops->notifier_hangup(hp, hp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Push buffered characters whether they were just recently buffered or waiting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * on a blocked hypervisor. Call this function with hp->lock held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static int hvc_push(struct hvc_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (n <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (n == 0 || n == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) hp->do_wakeup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* throw away output on error; this happens when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) there is no session connected to the vterm. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) hp->n_outbuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) hp->n_outbuf -= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (hp->n_outbuf > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) hp->do_wakeup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int rsize, written = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* This write was probably executed during a tty close. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (!hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* FIXME what's this (unprotected) check for? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (hp->port.count <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) while (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) rsize = hp->outbuf_size - hp->n_outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (rsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (rsize > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) rsize = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) memcpy(hp->outbuf + hp->n_outbuf, buf, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) count -= rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) buf += rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) hp->n_outbuf += rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) written += rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (hp->n_outbuf > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ret = hvc_push(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (hp->n_outbuf > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) hvc_flush(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * Racy, but harmless, kick thread if there is still pending data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (hp->n_outbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) hvc_kick();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * hvc_set_winsz() - Resize the hvc tty terminal window.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * @work: work structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * The routine shall not be called within an atomic context because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * might sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * Locking: hp->lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static void hvc_set_winsz(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct hvc_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) unsigned long hvc_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct winsize ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) hp = container_of(work, struct hvc_struct, tty_resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) tty = tty_port_tty_get(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (!tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) spin_lock_irqsave(&hp->lock, hvc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) ws = hp->ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) spin_unlock_irqrestore(&hp->lock, hvc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) tty_do_resize(tty, &ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * This is actually a contract between the driver and the tty layer outlining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * how much write room the driver can guarantee will be sent OR BUFFERED. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * driver MUST honor the return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static int hvc_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (!hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return hp->outbuf_size - hp->n_outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static int hvc_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (!hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return hp->n_outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * timeout will vary between the MIN and MAX values defined here. By default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * and during console activity we will use a default MIN_TIMEOUT of 10. When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * the console is idle, we increase the timeout value on each pass through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * msleep until we reach the max. This may be noticeable as a brief (average
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * one second) delay on the console before the console responds to input when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * there has been no input for some time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) #define MIN_TIMEOUT (10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) #define MAX_TIMEOUT (2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static u32 timeout = MIN_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * Maximum number of bytes to get from the console driver if hvc_poll is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * called from driver (and can't sleep). Any more than this and we break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * and start polling with khvcd. This value was derived from from an OpenBMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * console with the OPAL driver that results in about 0.25ms interrupts off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * latency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) #define HVC_ATOMIC_READ_MAX 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) #define HVC_POLL_READ 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) #define HVC_POLL_WRITE 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int __hvc_poll(struct hvc_struct *hp, bool may_sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int i, n, count, poll_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) char buf[N_INBUF] __ALIGNED__;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int read_total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int written_total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* Push pending writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (hp->n_outbuf > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) written_total = hvc_push(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* Reschedule us if still some write pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (hp->n_outbuf > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) poll_mask |= HVC_POLL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* If hvc_push() was not able to write, sleep a few msecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) timeout = (written_total) ? 0 : MIN_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (may_sleep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* No tty attached, just skip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) tty = tty_port_tty_get(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (tty == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* Now check if we can get data (are we throttled ?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (tty_throttled(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* If we aren't notifier driven and aren't throttled, we always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * request a reschedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!hp->irq_requested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) poll_mask |= HVC_POLL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) read_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* Read data if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) count = tty_buffer_request_room(&hp->port, N_INBUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* If flip is full, just reschedule a later read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) poll_mask |= HVC_POLL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) n = hp->ops->get_chars(hp->vtermno, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (n <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* Hangup the tty when disconnected from host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (n == -EPIPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) tty_hangup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) } else if ( n == -EAGAIN ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Some back-ends can only ensure a certain min
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * num of bytes read, which may be > 'count'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * Let the tty clear the flip buff to make room.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) poll_mask |= HVC_POLL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) for (i = 0; i < n; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (hp->index == hvc_console.index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* Handle the SysRq Hack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /* XXX should support a sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (buf[i] == '\x0f') { /* ^O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* if ^O is pressed again, reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * sysrq_pressed and flip ^O char */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sysrq_pressed = !sysrq_pressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (sysrq_pressed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) } else if (sysrq_pressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) handle_sysrq(buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) sysrq_pressed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) #endif /* CONFIG_MAGIC_SYSRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) tty_insert_flip_char(&hp->port, buf[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) read_total += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (may_sleep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Keep going until the flip is full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) goto read_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) } else if (read_total < HVC_ATOMIC_READ_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /* Break and defer if it's a large read in atomic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) goto read_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * Latency break, schedule another poll immediately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) poll_mask |= HVC_POLL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* Wakeup write queue if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (hp->do_wakeup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) hp->do_wakeup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) tty_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (read_total) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* Activity is occurring, so reset the polling backoff value to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) a minimum for performance. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) timeout = MIN_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) tty_flip_buffer_push(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return poll_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int hvc_poll(struct hvc_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return __hvc_poll(hp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) EXPORT_SYMBOL_GPL(hvc_poll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * __hvc_resize() - Update terminal window size information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * @hp: HVC console pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * @ws: Terminal window size structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * Stores the specified window size information in the hvc structure of @hp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * The function schedule the tty resize update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * Locking: Locking free; the function MUST be called holding hp->lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) void __hvc_resize(struct hvc_struct *hp, struct winsize ws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) hp->ws = ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) schedule_work(&hp->tty_resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) EXPORT_SYMBOL_GPL(__hvc_resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * This kthread is either polling or interrupt driven. This is determined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * calling hvc_poll() who determines whether a console adapter support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static int khvcd(void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) int poll_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct hvc_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) set_freezable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) poll_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) hvc_kicked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) try_to_freeze();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!cpus_are_in_xmon()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) mutex_lock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) list_for_each_entry(hp, &hvc_structs, next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) poll_mask |= __hvc_poll(hp, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) mutex_unlock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) poll_mask |= HVC_POLL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (hvc_kicked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (!hvc_kicked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (poll_mask == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned long j_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (timeout < MAX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) timeout += (timeout >> 6) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * We don't use msleep_interruptible otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * "kick" will fail to wake us up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) j_timeout = msecs_to_jiffies(timeout) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) schedule_timeout_interruptible(j_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) __set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) } while (!kthread_should_stop());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static int hvc_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (!hp || !hp->ops->tiocmget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return hp->ops->tiocmget(hp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int hvc_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (!hp || !hp->ops->tiocmset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return hp->ops->tiocmset(hp, set, clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static int hvc_poll_init(struct tty_driver *driver, int line, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static int hvc_poll_get_char(struct tty_driver *driver, int line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct tty_struct *tty = driver->ttys[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) n = hp->ops->get_chars(hp->vtermno, &ch, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (n <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return NO_POLL_CHAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct tty_struct *tty = driver->ttys[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct hvc_struct *hp = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) n = hp->ops->put_chars(hp->vtermno, &ch, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) } while (n <= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static const struct tty_operations hvc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .install = hvc_install,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .open = hvc_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .close = hvc_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .cleanup = hvc_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .write = hvc_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .hangup = hvc_hangup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .unthrottle = hvc_unthrottle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .write_room = hvc_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .chars_in_buffer = hvc_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .tiocmget = hvc_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .tiocmset = hvc_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .poll_init = hvc_poll_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .poll_get_char = hvc_poll_get_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .poll_put_char = hvc_poll_put_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static const struct tty_port_operations hvc_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .destruct = hvc_port_destruct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) const struct hv_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) int outbuf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct hvc_struct *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* We wait until a driver actually comes along */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (atomic_inc_not_zero(&hvc_needs_init)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) int err = hvc_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) hp = kzalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (!hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) hp->vtermno = vtermno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) hp->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) hp->ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) hp->outbuf_size = outbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) tty_port_init(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) hp->port.ops = &hvc_port_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) INIT_WORK(&hp->tty_resize, hvc_set_winsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) spin_lock_init(&hp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) mutex_lock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * find index to use:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * see if this vterm id matches one registered for console.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (vtermnos[i] == hp->vtermno &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) cons_ops[i] == hp->ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (i >= MAX_NR_HVC_CONSOLES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /* find 'empty' slot for console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* no matching slot, just use a counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (i == MAX_NR_HVC_CONSOLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) i = ++last_hvc + MAX_NR_HVC_CONSOLES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) hp->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (i < MAX_NR_HVC_CONSOLES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) cons_ops[i] = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) vtermnos[i] = vtermno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) list_add_tail(&(hp->next), &hvc_structs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) mutex_unlock(&hvc_structs_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* check if we need to re-register the kernel console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) hvc_check_console(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) EXPORT_SYMBOL_GPL(hvc_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) int hvc_remove(struct hvc_struct *hp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) tty = tty_port_tty_get(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) spin_lock_irqsave(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (hp->index < MAX_NR_HVC_CONSOLES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) vtermnos[hp->index] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) cons_ops[hp->index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /* Don't whack hp->irq because tty_hangup() will need to free the irq. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) spin_unlock_irqrestore(&hp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * We 'put' the instance that was grabbed when the kref instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * was initialized using kref_init(). Let the last holder of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * kref cause it to be removed, which will probably be the tty_vhangup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) tty_port_put(&hp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * This function call will auto chain call hvc_hangup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) tty_vhangup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) EXPORT_SYMBOL_GPL(hvc_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* Driver initialization: called as soon as someone uses hvc_alloc(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static int hvc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) struct tty_driver *drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* We need more than hvc_count adapters due to hotplug additions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (!drv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) drv->driver_name = "hvc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) drv->name = "hvc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) drv->major = HVC_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) drv->minor_start = HVC_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) drv->type = TTY_DRIVER_TYPE_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) drv->init_termios = tty_std_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) tty_set_operations(drv, &hvc_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* Always start the kthread because there can be hotplug vty adapters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * added later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) hvc_task = kthread_run(khvcd, NULL, "khvcd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (IS_ERR(hvc_task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) printk(KERN_ERR "Couldn't create kthread for console.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) err = PTR_ERR(hvc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) goto put_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) err = tty_register_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) printk(KERN_ERR "Couldn't register hvc console driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) goto stop_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * Make sure tty is fully registered before allowing it to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * found by hvc_console_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) smp_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) hvc_driver = drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) stop_thread:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) kthread_stop(hvc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) hvc_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) put_tty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) put_tty_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }