aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/Kconfig105
-rw-r--r--drivers/tty/hvc/Makefile13
-rw-r--r--drivers/tty/hvc/hvc_beat.c134
-rw-r--r--drivers/tty/hvc/hvc_bfin_jtag.c105
-rw-r--r--drivers/tty/hvc/hvc_console.c914
-rw-r--r--drivers/tty/hvc/hvc_console.h119
-rw-r--r--drivers/tty/hvc/hvc_dcc.c104
-rw-r--r--drivers/tty/hvc/hvc_irq.c49
-rw-r--r--drivers/tty/hvc/hvc_iseries.c598
-rw-r--r--drivers/tty/hvc/hvc_iucv.c1337
-rw-r--r--drivers/tty/hvc/hvc_rtas.c133
-rw-r--r--drivers/tty/hvc/hvc_tile.c68
-rw-r--r--drivers/tty/hvc/hvc_udbg.c96
-rw-r--r--drivers/tty/hvc/hvc_vio.c173
-rw-r--r--drivers/tty/hvc/hvc_xen.c273
-rw-r--r--drivers/tty/hvc/hvcs.c1616
-rw-r--r--drivers/tty/hvc/hvsi.c1314
17 files changed, 7151 insertions, 0 deletions
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
new file mode 100644
index 000000000000..6f2c9809f1fb
--- /dev/null
+++ b/drivers/tty/hvc/Kconfig
@@ -0,0 +1,105 @@
1config HVC_DRIVER
2 bool
3 help
4 Generic "hypervisor virtual console" infrastructure for various
5 hypervisors (pSeries, iSeries, Xen, lguest).
6 It will automatically be selected if one of the back-end console drivers
7 is selected.
8
9config HVC_IRQ
10 bool
11
12config HVC_CONSOLE
13 bool "pSeries Hypervisor Virtual Console support"
14 depends on PPC_PSERIES
15 select HVC_DRIVER
16 select HVC_IRQ
17 help
18 pSeries machines when partitioned support a hypervisor virtual
19 console. This driver allows each pSeries partition to have a console
20 which is accessed via the HMC.
21
22config HVC_ISERIES
23 bool "iSeries Hypervisor Virtual Console support"
24 depends on PPC_ISERIES
25 default y
26 select HVC_DRIVER
27 select HVC_IRQ
28 select VIOPATH
29 help
30 iSeries machines support a hypervisor virtual console.
31
32config HVC_RTAS
33 bool "IBM RTAS Console support"
34 depends on PPC_RTAS
35 select HVC_DRIVER
36 help
37 IBM Console device driver which makes use of RTAS
38
39config HVC_BEAT
40 bool "Toshiba's Beat Hypervisor Console support"
41 depends on PPC_CELLEB
42 select HVC_DRIVER
43 help
44 Toshiba's Cell Reference Set Beat Console device driver
45
46config HVC_IUCV
47 bool "z/VM IUCV Hypervisor console support (VM only)"
48 depends on S390
49 select HVC_DRIVER
50 select IUCV
51 default y
52 help
53 This driver provides a Hypervisor console (HVC) back-end to access
54 a Linux (console) terminal via a z/VM IUCV communication path.
55
56config HVC_XEN
57 bool "Xen Hypervisor Console support"
58 depends on XEN
59 select HVC_DRIVER
60 select HVC_IRQ
61 default y
62 help
63 Xen virtual console device driver
64
65config HVC_UDBG
66 bool "udbg based fake hypervisor console"
67 depends on PPC && EXPERIMENTAL
68 select HVC_DRIVER
69 default n
70
71config HVC_DCC
72 bool "ARM JTAG DCC console"
73 depends on ARM
74 select HVC_DRIVER
75 help
76 This console uses the JTAG DCC on ARM to create a console under the HVC
77 driver. This console is used through a JTAG only on ARM. If you don't have
78 a JTAG then you probably don't want this option.
79
80config HVC_BFIN_JTAG
81 bool "Blackfin JTAG console"
82 depends on BLACKFIN
83 select HVC_DRIVER
84 help
85 This console uses the Blackfin JTAG to create a console under the
86 the HVC driver. If you don't have JTAG, then you probably don't
87 want this option.
88
89config HVCS
90 tristate "IBM Hypervisor Virtual Console Server support"
91 depends on PPC_PSERIES && HVC_CONSOLE
92 help
93 Partitionable IBM Power5 ppc64 machines allow hosting of
94 firmware virtual consoles from one Linux partition by
95 another Linux partition. This driver allows console data
96 from Linux partitions to be accessed through TTY device
97 interfaces in the device tree of a Linux partition running
98 this driver.
99
100 To compile this driver as a module, choose M here: the
101 module will be called hvcs. Additionally, this module
102 will depend on arch specific APIs exported from hvcserver.ko
103 which will also be compiled when this driver is built as a
104 module.
105
diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile
new file mode 100644
index 000000000000..40a25d93fe52
--- /dev/null
+++ b/drivers/tty/hvc/Makefile
@@ -0,0 +1,13 @@
1obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
2obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
3obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
4obj-$(CONFIG_HVC_TILE) += hvc_tile.o
5obj-$(CONFIG_HVC_DCC) += hvc_dcc.o
6obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
7obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
8obj-$(CONFIG_HVC_IRQ) += hvc_irq.o
9obj-$(CONFIG_HVC_XEN) += hvc_xen.o
10obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o
11obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o
12obj-$(CONFIG_HVC_BFIN_JTAG) += hvc_bfin_jtag.o
13obj-$(CONFIG_HVCS) += hvcs.o
diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c
new file mode 100644
index 000000000000..5fe4631e2a61
--- /dev/null
+++ b/drivers/tty/hvc/hvc_beat.c
@@ -0,0 +1,134 @@
1/*
2 * Beat hypervisor console driver
3 *
4 * (C) Copyright 2006 TOSHIBA CORPORATION
5 *
6 * This code is based on drivers/char/hvc_rtas.c:
7 * (C) Copyright IBM Corporation 2001-2005
8 * (C) Copyright Red Hat, Inc. 2005
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/err.h>
28#include <linux/string.h>
29#include <linux/console.h>
30#include <asm/prom.h>
31#include <asm/hvconsole.h>
32#include <asm/firmware.h>
33
34#include "hvc_console.h"
35
36extern int64_t beat_get_term_char(uint64_t, uint64_t *, uint64_t *, uint64_t *);
37extern int64_t beat_put_term_char(uint64_t, uint64_t, uint64_t, uint64_t);
38
39struct hvc_struct *hvc_beat_dev = NULL;
40
41/* bug: only one queue is available regardless of vtermno */
42static int hvc_beat_get_chars(uint32_t vtermno, char *buf, int cnt)
43{
44 static unsigned char q[sizeof(unsigned long) * 2]
45 __attribute__((aligned(sizeof(unsigned long))));
46 static int qlen = 0;
47 u64 got;
48
49again:
50 if (qlen) {
51 if (qlen > cnt) {
52 memcpy(buf, q, cnt);
53 qlen -= cnt;
54 memmove(q + cnt, q, qlen);
55 return cnt;
56 } else { /* qlen <= cnt */
57 int r;
58
59 memcpy(buf, q, qlen);
60 r = qlen;
61 qlen = 0;
62 return r;
63 }
64 }
65 if (beat_get_term_char(vtermno, &got,
66 ((u64 *)q), ((u64 *)q) + 1) == 0) {
67 qlen = got;
68 goto again;
69 }
70 return 0;
71}
72
73static int hvc_beat_put_chars(uint32_t vtermno, const char *buf, int cnt)
74{
75 unsigned long kb[2];
76 int rest, nlen;
77
78 for (rest = cnt; rest > 0; rest -= nlen) {
79 nlen = (rest > 16) ? 16 : rest;
80 memcpy(kb, buf, nlen);
81 beat_put_term_char(vtermno, nlen, kb[0], kb[1]);
82 buf += nlen;
83 }
84 return cnt;
85}
86
87static const struct hv_ops hvc_beat_get_put_ops = {
88 .get_chars = hvc_beat_get_chars,
89 .put_chars = hvc_beat_put_chars,
90};
91
92static int hvc_beat_useit = 1;
93
94static int hvc_beat_config(char *p)
95{
96 hvc_beat_useit = simple_strtoul(p, NULL, 0);
97 return 0;
98}
99
100static int __init hvc_beat_console_init(void)
101{
102 if (hvc_beat_useit && of_machine_is_compatible("Beat")) {
103 hvc_instantiate(0, 0, &hvc_beat_get_put_ops);
104 }
105 return 0;
106}
107
108/* temp */
109static int __init hvc_beat_init(void)
110{
111 struct hvc_struct *hp;
112
113 if (!firmware_has_feature(FW_FEATURE_BEAT))
114 return -ENODEV;
115
116 hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16);
117 if (IS_ERR(hp))
118 return PTR_ERR(hp);
119 hvc_beat_dev = hp;
120 return 0;
121}
122
123static void __exit hvc_beat_exit(void)
124{
125 if (hvc_beat_dev)
126 hvc_remove(hvc_beat_dev);
127}
128
129module_init(hvc_beat_init);
130module_exit(hvc_beat_exit);
131
132__setup("hvc_beat=", hvc_beat_config);
133
134console_initcall(hvc_beat_console_init);
diff --git a/drivers/tty/hvc/hvc_bfin_jtag.c b/drivers/tty/hvc/hvc_bfin_jtag.c
new file mode 100644
index 000000000000..31d6cc6a77af
--- /dev/null
+++ b/drivers/tty/hvc/hvc_bfin_jtag.c
@@ -0,0 +1,105 @@
1/*
2 * Console via Blackfin JTAG Communication
3 *
4 * Copyright 2008-2011 Analog Devices Inc.
5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/console.h>
12#include <linux/delay.h>
13#include <linux/err.h>
14#include <linux/init.h>
15#include <linux/moduleparam.h>
16#include <linux/types.h>
17
18#include "hvc_console.h"
19
20/* See the Debug/Emulation chapter in the HRM */
21#define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */
22#define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */
23#define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */
24#define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */
25
26/* Helper functions to glue the register API to simple C operations */
27static inline uint32_t bfin_write_emudat(uint32_t emudat)
28{
29 __asm__ __volatile__("emudat = %0;" : : "d"(emudat));
30 return emudat;
31}
32
33static inline uint32_t bfin_read_emudat(void)
34{
35 uint32_t emudat;
36 __asm__ __volatile__("%0 = emudat;" : "=d"(emudat));
37 return emudat;
38}
39
40/* Send data to the host */
41static int hvc_bfin_put_chars(uint32_t vt, const char *buf, int count)
42{
43 static uint32_t outbound_len;
44 uint32_t emudat;
45 int ret;
46
47 if (bfin_read_DBGSTAT() & EMUDOF)
48 return 0;
49
50 if (!outbound_len) {
51 outbound_len = count;
52 bfin_write_emudat(outbound_len);
53 return 0;
54 }
55
56 ret = min(outbound_len, (uint32_t)4);
57 memcpy(&emudat, buf, ret);
58 bfin_write_emudat(emudat);
59 outbound_len -= ret;
60
61 return ret;
62}
63
64/* Receive data from the host */
65static int hvc_bfin_get_chars(uint32_t vt, char *buf, int count)
66{
67 static uint32_t inbound_len;
68 uint32_t emudat;
69 int ret;
70
71 if (!(bfin_read_DBGSTAT() & EMUDIF))
72 return 0;
73 emudat = bfin_read_emudat();
74
75 if (!inbound_len) {
76 inbound_len = emudat;
77 return 0;
78 }
79
80 ret = min(inbound_len, (uint32_t)4);
81 memcpy(buf, &emudat, ret);
82 inbound_len -= ret;
83
84 return ret;
85}
86
87/* Glue the HVC layers to the Blackfin layers */
88static const struct hv_ops hvc_bfin_get_put_ops = {
89 .get_chars = hvc_bfin_get_chars,
90 .put_chars = hvc_bfin_put_chars,
91};
92
93static int __init hvc_bfin_console_init(void)
94{
95 hvc_instantiate(0, 0, &hvc_bfin_get_put_ops);
96 return 0;
97}
98console_initcall(hvc_bfin_console_init);
99
100static int __init hvc_bfin_init(void)
101{
102 hvc_alloc(0, 0, &hvc_bfin_get_put_ops, 128);
103 return 0;
104}
105device_initcall(hvc_bfin_init);
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
new file mode 100644
index 000000000000..e9cba13ee800
--- /dev/null
+++ b/drivers/tty/hvc/hvc_console.c
@@ -0,0 +1,914 @@
1/*
2 * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
3 * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
4 * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
5 * Copyright (C) 2004 IBM Corporation
6 *
7 * Additional Author(s):
8 * Ryan S. Arnold <rsa@us.ibm.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/console.h>
26#include <linux/cpumask.h>
27#include <linux/init.h>
28#include <linux/kbd_kern.h>
29#include <linux/kernel.h>
30#include <linux/kthread.h>
31#include <linux/list.h>
32#include <linux/module.h>
33#include <linux/major.h>
34#include <linux/sysrq.h>
35#include <linux/tty.h>
36#include <linux/tty_flip.h>
37#include <linux/sched.h>
38#include <linux/spinlock.h>
39#include <linux/delay.h>
40#include <linux/freezer.h>
41#include <linux/slab.h>
42
43#include <asm/uaccess.h>
44
45#include "hvc_console.h"
46
47#define HVC_MAJOR 229
48#define HVC_MINOR 0
49
50/*
51 * Wait this long per iteration while trying to push buffered data to the
52 * hypervisor before allowing the tty to complete a close operation.
53 */
54#define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */
55
56/*
57 * These sizes are most efficient for vio, because they are the
58 * native transfer size. We could make them selectable in the
59 * future to better deal with backends that want other buffer sizes.
60 */
61#define N_OUTBUF 16
62#define N_INBUF 16
63
64#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
65
66static struct tty_driver *hvc_driver;
67static struct task_struct *hvc_task;
68
69/* Picks up late kicks after list walk but before schedule() */
70static int hvc_kicked;
71
72static int hvc_init(void);
73
74#ifdef CONFIG_MAGIC_SYSRQ
75static int sysrq_pressed;
76#endif
77
78/* dynamic list of hvc_struct instances */
79static LIST_HEAD(hvc_structs);
80
81/*
82 * Protect the list of hvc_struct instances from inserts and removals during
83 * list traversal.
84 */
85static DEFINE_SPINLOCK(hvc_structs_lock);
86
87/*
88 * This value is used to assign a tty->index value to a hvc_struct based
89 * upon order of exposure via hvc_probe(), when we can not match it to
90 * a console candidate registered with hvc_instantiate().
91 */
92static int last_hvc = -1;
93
94/*
95 * Do not call this function with either the hvc_structs_lock or the hvc_struct
96 * lock held. If successful, this function increments the kref reference
97 * count against the target hvc_struct so it should be released when finished.
98 */
99static struct hvc_struct *hvc_get_by_index(int index)
100{
101 struct hvc_struct *hp;
102 unsigned long flags;
103
104 spin_lock(&hvc_structs_lock);
105
106 list_for_each_entry(hp, &hvc_structs, next) {
107 spin_lock_irqsave(&hp->lock, flags);
108 if (hp->index == index) {
109 kref_get(&hp->kref);
110 spin_unlock_irqrestore(&hp->lock, flags);
111 spin_unlock(&hvc_structs_lock);
112 return hp;
113 }
114 spin_unlock_irqrestore(&hp->lock, flags);
115 }
116 hp = NULL;
117
118 spin_unlock(&hvc_structs_lock);
119 return hp;
120}
121
122
123/*
124 * Initial console vtermnos for console API usage prior to full console
125 * initialization. Any vty adapter outside this range will not have usable
126 * console interfaces but can still be used as a tty device. This has to be
127 * static because kmalloc will not work during early console init.
128 */
129static const struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
130static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
131 {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
132
133/*
134 * Console APIs, NOT TTY. These APIs are available immediately when
135 * hvc_console_setup() finds adapters.
136 */
137
138static void hvc_console_print(struct console *co, const char *b,
139 unsigned count)
140{
141 char c[N_OUTBUF] __ALIGNED__;
142 unsigned i = 0, n = 0;
143 int r, donecr = 0, index = co->index;
144
145 /* Console access attempt outside of acceptable console range. */
146 if (index >= MAX_NR_HVC_CONSOLES)
147 return;
148
149 /* This console adapter was removed so it is not usable. */
150 if (vtermnos[index] == -1)
151 return;
152
153 while (count > 0 || i > 0) {
154 if (count > 0 && i < sizeof(c)) {
155 if (b[n] == '\n' && !donecr) {
156 c[i++] = '\r';
157 donecr = 1;
158 } else {
159 c[i++] = b[n++];
160 donecr = 0;
161 --count;
162 }
163 } else {
164 r = cons_ops[index]->put_chars(vtermnos[index], c, i);
165 if (r <= 0) {
166 /* throw away chars on error */
167 i = 0;
168 } else if (r > 0) {
169 i -= r;
170 if (i > 0)
171 memmove(c, c+r, i);
172 }
173 }
174 }
175}
176
177static struct tty_driver *hvc_console_device(struct console *c, int *index)
178{
179 if (vtermnos[c->index] == -1)
180 return NULL;
181
182 *index = c->index;
183 return hvc_driver;
184}
185
186static int __init hvc_console_setup(struct console *co, char *options)
187{
188 if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
189 return -ENODEV;
190
191 if (vtermnos[co->index] == -1)
192 return -ENODEV;
193
194 return 0;
195}
196
197static struct console hvc_console = {
198 .name = "hvc",
199 .write = hvc_console_print,
200 .device = hvc_console_device,
201 .setup = hvc_console_setup,
202 .flags = CON_PRINTBUFFER,
203 .index = -1,
204};
205
206/*
207 * Early console initialization. Precedes driver initialization.
208 *
209 * (1) we are first, and the user specified another driver
210 * -- index will remain -1
211 * (2) we are first and the user specified no driver
212 * -- index will be set to 0, then we will fail setup.
213 * (3) we are first and the user specified our driver
214 * -- index will be set to user specified driver, and we will fail
215 * (4) we are after driver, and this initcall will register us
216 * -- if the user didn't specify a driver then the console will match
217 *
218 * Note that for cases 2 and 3, we will match later when the io driver
219 * calls hvc_instantiate() and call register again.
220 */
221static int __init hvc_console_init(void)
222{
223 register_console(&hvc_console);
224 return 0;
225}
226console_initcall(hvc_console_init);
227
228/* callback when the kboject ref count reaches zero. */
229static void destroy_hvc_struct(struct kref *kref)
230{
231 struct hvc_struct *hp = container_of(kref, struct hvc_struct, kref);
232 unsigned long flags;
233
234 spin_lock(&hvc_structs_lock);
235
236 spin_lock_irqsave(&hp->lock, flags);
237 list_del(&(hp->next));
238 spin_unlock_irqrestore(&hp->lock, flags);
239
240 spin_unlock(&hvc_structs_lock);
241
242 kfree(hp);
243}
244
245/*
246 * hvc_instantiate() is an early console discovery method which locates
247 * consoles * prior to the vio subsystem discovering them. Hotplugged
248 * vty adapters do NOT get an hvc_instantiate() callback since they
249 * appear after early console init.
250 */
251int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
252{
253 struct hvc_struct *hp;
254
255 if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
256 return -1;
257
258 if (vtermnos[index] != -1)
259 return -1;
260
261 /* make sure no no tty has been registered in this index */
262 hp = hvc_get_by_index(index);
263 if (hp) {
264 kref_put(&hp->kref, destroy_hvc_struct);
265 return -1;
266 }
267
268 vtermnos[index] = vtermno;
269 cons_ops[index] = ops;
270
271 /* reserve all indices up to and including this index */
272 if (last_hvc < index)
273 last_hvc = index;
274
275 /* if this index is what the user requested, then register
276 * now (setup won't fail at this point). It's ok to just
277 * call register again if previously .setup failed.
278 */
279 if (index == hvc_console.index)
280 register_console(&hvc_console);
281
282 return 0;
283}
284EXPORT_SYMBOL_GPL(hvc_instantiate);
285
286/* Wake the sleeping khvcd */
287void hvc_kick(void)
288{
289 hvc_kicked = 1;
290 wake_up_process(hvc_task);
291}
292EXPORT_SYMBOL_GPL(hvc_kick);
293
294static void hvc_unthrottle(struct tty_struct *tty)
295{
296 hvc_kick();
297}
298
299/*
300 * The TTY interface won't be used until after the vio layer has exposed the vty
301 * adapter to the kernel.
302 */
303static int hvc_open(struct tty_struct *tty, struct file * filp)
304{
305 struct hvc_struct *hp;
306 unsigned long flags;
307 int rc = 0;
308
309 /* Auto increments kref reference if found. */
310 if (!(hp = hvc_get_by_index(tty->index)))
311 return -ENODEV;
312
313 spin_lock_irqsave(&hp->lock, flags);
314 /* Check and then increment for fast path open. */
315 if (hp->count++ > 0) {
316 tty_kref_get(tty);
317 spin_unlock_irqrestore(&hp->lock, flags);
318 hvc_kick();
319 return 0;
320 } /* else count == 0 */
321
322 tty->driver_data = hp;
323
324 hp->tty = tty_kref_get(tty);
325
326 spin_unlock_irqrestore(&hp->lock, flags);
327
328 if (hp->ops->notifier_add)
329 rc = hp->ops->notifier_add(hp, hp->data);
330
331 /*
332 * If the notifier fails we return an error. The tty layer
333 * will call hvc_close() after a failed open but we don't want to clean
334 * up there so we'll clean up here and clear out the previously set
335 * tty fields and return the kref reference.
336 */
337 if (rc) {
338 spin_lock_irqsave(&hp->lock, flags);
339 hp->tty = NULL;
340 spin_unlock_irqrestore(&hp->lock, flags);
341 tty_kref_put(tty);
342 tty->driver_data = NULL;
343 kref_put(&hp->kref, destroy_hvc_struct);
344 printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
345 }
346 /* Force wakeup of the polling thread */
347 hvc_kick();
348
349 return rc;
350}
351
352static void hvc_close(struct tty_struct *tty, struct file * filp)
353{
354 struct hvc_struct *hp;
355 unsigned long flags;
356
357 if (tty_hung_up_p(filp))
358 return;
359
360 /*
361 * No driver_data means that this close was issued after a failed
362 * hvc_open by the tty layer's release_dev() function and we can just
363 * exit cleanly because the kref reference wasn't made.
364 */
365 if (!tty->driver_data)
366 return;
367
368 hp = tty->driver_data;
369
370 spin_lock_irqsave(&hp->lock, flags);
371
372 if (--hp->count == 0) {
373 /* We are done with the tty pointer now. */
374 hp->tty = NULL;
375 spin_unlock_irqrestore(&hp->lock, flags);
376
377 if (hp->ops->notifier_del)
378 hp->ops->notifier_del(hp, hp->data);
379
380 /* cancel pending tty resize work */
381 cancel_work_sync(&hp->tty_resize);
382
383 /*
384 * Chain calls chars_in_buffer() and returns immediately if
385 * there is no buffered data otherwise sleeps on a wait queue
386 * waking periodically to check chars_in_buffer().
387 */
388 tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
389 } else {
390 if (hp->count < 0)
391 printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
392 hp->vtermno, hp->count);
393 spin_unlock_irqrestore(&hp->lock, flags);
394 }
395
396 tty_kref_put(tty);
397 kref_put(&hp->kref, destroy_hvc_struct);
398}
399
400static void hvc_hangup(struct tty_struct *tty)
401{
402 struct hvc_struct *hp = tty->driver_data;
403 unsigned long flags;
404 int temp_open_count;
405
406 if (!hp)
407 return;
408
409 /* cancel pending tty resize work */
410 cancel_work_sync(&hp->tty_resize);
411
412 spin_lock_irqsave(&hp->lock, flags);
413
414 /*
415 * The N_TTY line discipline has problems such that in a close vs
416 * open->hangup case this can be called after the final close so prevent
417 * that from happening for now.
418 */
419 if (hp->count <= 0) {
420 spin_unlock_irqrestore(&hp->lock, flags);
421 return;
422 }
423
424 temp_open_count = hp->count;
425 hp->count = 0;
426 hp->n_outbuf = 0;
427 hp->tty = NULL;
428
429 spin_unlock_irqrestore(&hp->lock, flags);
430
431 if (hp->ops->notifier_hangup)
432 hp->ops->notifier_hangup(hp, hp->data);
433
434 while(temp_open_count) {
435 --temp_open_count;
436 tty_kref_put(tty);
437 kref_put(&hp->kref, destroy_hvc_struct);
438 }
439}
440
441/*
442 * Push buffered characters whether they were just recently buffered or waiting
443 * on a blocked hypervisor. Call this function with hp->lock held.
444 */
445static int hvc_push(struct hvc_struct *hp)
446{
447 int n;
448
449 n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
450 if (n <= 0) {
451 if (n == 0) {
452 hp->do_wakeup = 1;
453 return 0;
454 }
455 /* throw away output on error; this happens when
456 there is no session connected to the vterm. */
457 hp->n_outbuf = 0;
458 } else
459 hp->n_outbuf -= n;
460 if (hp->n_outbuf > 0)
461 memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf);
462 else
463 hp->do_wakeup = 1;
464
465 return n;
466}
467
468static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
469{
470 struct hvc_struct *hp = tty->driver_data;
471 unsigned long flags;
472 int rsize, written = 0;
473
474 /* This write was probably executed during a tty close. */
475 if (!hp)
476 return -EPIPE;
477
478 if (hp->count <= 0)
479 return -EIO;
480
481 spin_lock_irqsave(&hp->lock, flags);
482
483 /* Push pending writes */
484 if (hp->n_outbuf > 0)
485 hvc_push(hp);
486
487 while (count > 0 && (rsize = hp->outbuf_size - hp->n_outbuf) > 0) {
488 if (rsize > count)
489 rsize = count;
490 memcpy(hp->outbuf + hp->n_outbuf, buf, rsize);
491 count -= rsize;
492 buf += rsize;
493 hp->n_outbuf += rsize;
494 written += rsize;
495 hvc_push(hp);
496 }
497 spin_unlock_irqrestore(&hp->lock, flags);
498
499 /*
500 * Racy, but harmless, kick thread if there is still pending data.
501 */
502 if (hp->n_outbuf)
503 hvc_kick();
504
505 return written;
506}
507
508/**
509 * hvc_set_winsz() - Resize the hvc tty terminal window.
510 * @work: work structure.
511 *
512 * The routine shall not be called within an atomic context because it
513 * might sleep.
514 *
515 * Locking: hp->lock
516 */
517static void hvc_set_winsz(struct work_struct *work)
518{
519 struct hvc_struct *hp;
520 unsigned long hvc_flags;
521 struct tty_struct *tty;
522 struct winsize ws;
523
524 hp = container_of(work, struct hvc_struct, tty_resize);
525
526 spin_lock_irqsave(&hp->lock, hvc_flags);
527 if (!hp->tty) {
528 spin_unlock_irqrestore(&hp->lock, hvc_flags);
529 return;
530 }
531 ws = hp->ws;
532 tty = tty_kref_get(hp->tty);
533 spin_unlock_irqrestore(&hp->lock, hvc_flags);
534
535 tty_do_resize(tty, &ws);
536 tty_kref_put(tty);
537}
538
539/*
540 * This is actually a contract between the driver and the tty layer outlining
541 * how much write room the driver can guarantee will be sent OR BUFFERED. This
542 * driver MUST honor the return value.
543 */
544static int hvc_write_room(struct tty_struct *tty)
545{
546 struct hvc_struct *hp = tty->driver_data;
547
548 if (!hp)
549 return -1;
550
551 return hp->outbuf_size - hp->n_outbuf;
552}
553
554static int hvc_chars_in_buffer(struct tty_struct *tty)
555{
556 struct hvc_struct *hp = tty->driver_data;
557
558 if (!hp)
559 return 0;
560 return hp->n_outbuf;
561}
562
563/*
564 * timeout will vary between the MIN and MAX values defined here. By default
565 * and during console activity we will use a default MIN_TIMEOUT of 10. When
566 * the console is idle, we increase the timeout value on each pass through
567 * msleep until we reach the max. This may be noticeable as a brief (average
568 * one second) delay on the console before the console responds to input when
569 * there has been no input for some time.
570 */
571#define MIN_TIMEOUT (10)
572#define MAX_TIMEOUT (2000)
573static u32 timeout = MIN_TIMEOUT;
574
575#define HVC_POLL_READ 0x00000001
576#define HVC_POLL_WRITE 0x00000002
577
578int hvc_poll(struct hvc_struct *hp)
579{
580 struct tty_struct *tty;
581 int i, n, poll_mask = 0;
582 char buf[N_INBUF] __ALIGNED__;
583 unsigned long flags;
584 int read_total = 0;
585 int written_total = 0;
586
587 spin_lock_irqsave(&hp->lock, flags);
588
589 /* Push pending writes */
590 if (hp->n_outbuf > 0)
591 written_total = hvc_push(hp);
592
593 /* Reschedule us if still some write pending */
594 if (hp->n_outbuf > 0) {
595 poll_mask |= HVC_POLL_WRITE;
596 /* If hvc_push() was not able to write, sleep a few msecs */
597 timeout = (written_total) ? 0 : MIN_TIMEOUT;
598 }
599
600 /* No tty attached, just skip */
601 tty = tty_kref_get(hp->tty);
602 if (tty == NULL)
603 goto bail;
604
605 /* Now check if we can get data (are we throttled ?) */
606 if (test_bit(TTY_THROTTLED, &tty->flags))
607 goto throttled;
608
609 /* If we aren't notifier driven and aren't throttled, we always
610 * request a reschedule
611 */
612 if (!hp->irq_requested)
613 poll_mask |= HVC_POLL_READ;
614
615 /* Read data if any */
616 for (;;) {
617 int count = tty_buffer_request_room(tty, N_INBUF);
618
619 /* If flip is full, just reschedule a later read */
620 if (count == 0) {
621 poll_mask |= HVC_POLL_READ;
622 break;
623 }
624
625 n = hp->ops->get_chars(hp->vtermno, buf, count);
626 if (n <= 0) {
627 /* Hangup the tty when disconnected from host */
628 if (n == -EPIPE) {
629 spin_unlock_irqrestore(&hp->lock, flags);
630 tty_hangup(tty);
631 spin_lock_irqsave(&hp->lock, flags);
632 } else if ( n == -EAGAIN ) {
633 /*
634 * Some back-ends can only ensure a certain min
635 * num of bytes read, which may be > 'count'.
636 * Let the tty clear the flip buff to make room.
637 */
638 poll_mask |= HVC_POLL_READ;
639 }
640 break;
641 }
642 for (i = 0; i < n; ++i) {
643#ifdef CONFIG_MAGIC_SYSRQ
644 if (hp->index == hvc_console.index) {
645 /* Handle the SysRq Hack */
646 /* XXX should support a sequence */
647 if (buf[i] == '\x0f') { /* ^O */
648 /* if ^O is pressed again, reset
649 * sysrq_pressed and flip ^O char */
650 sysrq_pressed = !sysrq_pressed;
651 if (sysrq_pressed)
652 continue;
653 } else if (sysrq_pressed) {
654 handle_sysrq(buf[i]);
655 sysrq_pressed = 0;
656 continue;
657 }
658 }
659#endif /* CONFIG_MAGIC_SYSRQ */
660 tty_insert_flip_char(tty, buf[i], 0);
661 }
662
663 read_total += n;
664 }
665 throttled:
666 /* Wakeup write queue if necessary */
667 if (hp->do_wakeup) {
668 hp->do_wakeup = 0;
669 tty_wakeup(tty);
670 }
671 bail:
672 spin_unlock_irqrestore(&hp->lock, flags);
673
674 if (read_total) {
675 /* Activity is occurring, so reset the polling backoff value to
676 a minimum for performance. */
677 timeout = MIN_TIMEOUT;
678
679 tty_flip_buffer_push(tty);
680 }
681 if (tty)
682 tty_kref_put(tty);
683
684 return poll_mask;
685}
686EXPORT_SYMBOL_GPL(hvc_poll);
687
688/**
689 * __hvc_resize() - Update terminal window size information.
690 * @hp: HVC console pointer
691 * @ws: Terminal window size structure
692 *
693 * Stores the specified window size information in the hvc structure of @hp.
694 * The function schedule the tty resize update.
695 *
696 * Locking: Locking free; the function MUST be called holding hp->lock
697 */
698void __hvc_resize(struct hvc_struct *hp, struct winsize ws)
699{
700 hp->ws = ws;
701 schedule_work(&hp->tty_resize);
702}
703EXPORT_SYMBOL_GPL(__hvc_resize);
704
705/*
706 * This kthread is either polling or interrupt driven. This is determined by
707 * calling hvc_poll() who determines whether a console adapter support
708 * interrupts.
709 */
710static int khvcd(void *unused)
711{
712 int poll_mask;
713 struct hvc_struct *hp;
714
715 set_freezable();
716 do {
717 poll_mask = 0;
718 hvc_kicked = 0;
719 try_to_freeze();
720 wmb();
721 if (!cpus_are_in_xmon()) {
722 spin_lock(&hvc_structs_lock);
723 list_for_each_entry(hp, &hvc_structs, next) {
724 poll_mask |= hvc_poll(hp);
725 }
726 spin_unlock(&hvc_structs_lock);
727 } else
728 poll_mask |= HVC_POLL_READ;
729 if (hvc_kicked)
730 continue;
731 set_current_state(TASK_INTERRUPTIBLE);
732 if (!hvc_kicked) {
733 if (poll_mask == 0)
734 schedule();
735 else {
736 if (timeout < MAX_TIMEOUT)
737 timeout += (timeout >> 6) + 1;
738
739 msleep_interruptible(timeout);
740 }
741 }
742 __set_current_state(TASK_RUNNING);
743 } while (!kthread_should_stop());
744
745 return 0;
746}
747
748static const struct tty_operations hvc_ops = {
749 .open = hvc_open,
750 .close = hvc_close,
751 .write = hvc_write,
752 .hangup = hvc_hangup,
753 .unthrottle = hvc_unthrottle,
754 .write_room = hvc_write_room,
755 .chars_in_buffer = hvc_chars_in_buffer,
756};
757
758struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
759 const struct hv_ops *ops,
760 int outbuf_size)
761{
762 struct hvc_struct *hp;
763 int i;
764
765 /* We wait until a driver actually comes along */
766 if (!hvc_driver) {
767 int err = hvc_init();
768 if (err)
769 return ERR_PTR(err);
770 }
771
772 hp = kzalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
773 GFP_KERNEL);
774 if (!hp)
775 return ERR_PTR(-ENOMEM);
776
777 hp->vtermno = vtermno;
778 hp->data = data;
779 hp->ops = ops;
780 hp->outbuf_size = outbuf_size;
781 hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
782
783 kref_init(&hp->kref);
784
785 INIT_WORK(&hp->tty_resize, hvc_set_winsz);
786 spin_lock_init(&hp->lock);
787 spin_lock(&hvc_structs_lock);
788
789 /*
790 * find index to use:
791 * see if this vterm id matches one registered for console.
792 */
793 for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
794 if (vtermnos[i] == hp->vtermno &&
795 cons_ops[i] == hp->ops)
796 break;
797
798 /* no matching slot, just use a counter */
799 if (i >= MAX_NR_HVC_CONSOLES)
800 i = ++last_hvc;
801
802 hp->index = i;
803
804 list_add_tail(&(hp->next), &hvc_structs);
805 spin_unlock(&hvc_structs_lock);
806
807 return hp;
808}
809EXPORT_SYMBOL_GPL(hvc_alloc);
810
811int hvc_remove(struct hvc_struct *hp)
812{
813 unsigned long flags;
814 struct tty_struct *tty;
815
816 spin_lock_irqsave(&hp->lock, flags);
817 tty = tty_kref_get(hp->tty);
818
819 if (hp->index < MAX_NR_HVC_CONSOLES)
820 vtermnos[hp->index] = -1;
821
822 /* Don't whack hp->irq because tty_hangup() will need to free the irq. */
823
824 spin_unlock_irqrestore(&hp->lock, flags);
825
826 /*
827 * We 'put' the instance that was grabbed when the kref instance
828 * was initialized using kref_init(). Let the last holder of this
829 * kref cause it to be removed, which will probably be the tty_vhangup
830 * below.
831 */
832 kref_put(&hp->kref, destroy_hvc_struct);
833
834 /*
835 * This function call will auto chain call hvc_hangup.
836 */
837 if (tty) {
838 tty_vhangup(tty);
839 tty_kref_put(tty);
840 }
841 return 0;
842}
843EXPORT_SYMBOL_GPL(hvc_remove);
844
845/* Driver initialization: called as soon as someone uses hvc_alloc(). */
846static int hvc_init(void)
847{
848 struct tty_driver *drv;
849 int err;
850
851 /* We need more than hvc_count adapters due to hotplug additions. */
852 drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
853 if (!drv) {
854 err = -ENOMEM;
855 goto out;
856 }
857
858 drv->owner = THIS_MODULE;
859 drv->driver_name = "hvc";
860 drv->name = "hvc";
861 drv->major = HVC_MAJOR;
862 drv->minor_start = HVC_MINOR;
863 drv->type = TTY_DRIVER_TYPE_SYSTEM;
864 drv->init_termios = tty_std_termios;
865 drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
866 tty_set_operations(drv, &hvc_ops);
867
868 /* Always start the kthread because there can be hotplug vty adapters
869 * added later. */
870 hvc_task = kthread_run(khvcd, NULL, "khvcd");
871 if (IS_ERR(hvc_task)) {
872 printk(KERN_ERR "Couldn't create kthread for console.\n");
873 err = PTR_ERR(hvc_task);
874 goto put_tty;
875 }
876
877 err = tty_register_driver(drv);
878 if (err) {
879 printk(KERN_ERR "Couldn't register hvc console driver\n");
880 goto stop_thread;
881 }
882
883 /*
884 * Make sure tty is fully registered before allowing it to be
885 * found by hvc_console_device.
886 */
887 smp_mb();
888 hvc_driver = drv;
889 return 0;
890
891stop_thread:
892 kthread_stop(hvc_task);
893 hvc_task = NULL;
894put_tty:
895 put_tty_driver(drv);
896out:
897 return err;
898}
899
900/* This isn't particularly necessary due to this being a console driver
901 * but it is nice to be thorough.
902 */
903static void __exit hvc_exit(void)
904{
905 if (hvc_driver) {
906 kthread_stop(hvc_task);
907
908 tty_unregister_driver(hvc_driver);
909 /* return tty_struct instances allocated in hvc_init(). */
910 put_tty_driver(hvc_driver);
911 unregister_console(&hvc_console);
912 }
913}
914module_exit(hvc_exit);
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
new file mode 100644
index 000000000000..54381eba4e4a
--- /dev/null
+++ b/drivers/tty/hvc/hvc_console.h
@@ -0,0 +1,119 @@
1/*
2 * hvc_console.h
3 * Copyright (C) 2005 IBM Corporation
4 *
5 * Author(s):
6 * Ryan S. Arnold <rsa@us.ibm.com>
7 *
8 * hvc_console header information:
9 * moved here from arch/powerpc/include/asm/hvconsole.h
10 * and drivers/char/hvc_console.c
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#ifndef HVC_CONSOLE_H
28#define HVC_CONSOLE_H
29#include <linux/kref.h>
30#include <linux/tty.h>
31#include <linux/spinlock.h>
32
33/*
34 * This is the max number of console adapters that can/will be found as
35 * console devices on first stage console init. Any number beyond this range
36 * can't be used as a console device but is still a valid tty device.
37 */
38#define MAX_NR_HVC_CONSOLES 16
39
40/*
41 * The Linux TTY code does not support dynamic addition of tty derived devices
42 * so we need to know how many tty devices we might need when space is allocated
43 * for the tty device. Since this driver supports hotplug of vty adapters we
44 * need to make sure we have enough allocated.
45 */
46#define HVC_ALLOC_TTY_ADAPTERS 8
47
48struct hvc_struct {
49 spinlock_t lock;
50 int index;
51 struct tty_struct *tty;
52 int count;
53 int do_wakeup;
54 char *outbuf;
55 int outbuf_size;
56 int n_outbuf;
57 uint32_t vtermno;
58 const struct hv_ops *ops;
59 int irq_requested;
60 int data;
61 struct winsize ws;
62 struct work_struct tty_resize;
63 struct list_head next;
64 struct kref kref; /* ref count & hvc_struct lifetime */
65};
66
67/* implemented by a low level driver */
68struct hv_ops {
69 int (*get_chars)(uint32_t vtermno, char *buf, int count);
70 int (*put_chars)(uint32_t vtermno, const char *buf, int count);
71
72 /* Callbacks for notification. Called in open, close and hangup */
73 int (*notifier_add)(struct hvc_struct *hp, int irq);
74 void (*notifier_del)(struct hvc_struct *hp, int irq);
75 void (*notifier_hangup)(struct hvc_struct *hp, int irq);
76};
77
78/* Register a vterm and a slot index for use as a console (console_init) */
79extern int hvc_instantiate(uint32_t vtermno, int index,
80 const struct hv_ops *ops);
81
82/* register a vterm for hvc tty operation (module_init or hotplug add) */
83extern struct hvc_struct * hvc_alloc(uint32_t vtermno, int data,
84 const struct hv_ops *ops, int outbuf_size);
85/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
86extern int hvc_remove(struct hvc_struct *hp);
87
88/* data available */
89int hvc_poll(struct hvc_struct *hp);
90void hvc_kick(void);
91
92/* Resize hvc tty terminal window */
93extern void __hvc_resize(struct hvc_struct *hp, struct winsize ws);
94
95static inline void hvc_resize(struct hvc_struct *hp, struct winsize ws)
96{
97 unsigned long flags;
98
99 spin_lock_irqsave(&hp->lock, flags);
100 __hvc_resize(hp, ws);
101 spin_unlock_irqrestore(&hp->lock, flags);
102}
103
104/* default notifier for irq based notification */
105extern int notifier_add_irq(struct hvc_struct *hp, int data);
106extern void notifier_del_irq(struct hvc_struct *hp, int data);
107extern void notifier_hangup_irq(struct hvc_struct *hp, int data);
108
109
110#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
111#include <asm/xmon.h>
112#else
113static inline int cpus_are_in_xmon(void)
114{
115 return 0;
116}
117#endif
118
119#endif // HVC_CONSOLE_H
diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
new file mode 100644
index 000000000000..435f6facbc23
--- /dev/null
+++ b/drivers/tty/hvc/hvc_dcc.c
@@ -0,0 +1,104 @@
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/console.h>
19#include <linux/delay.h>
20#include <linux/err.h>
21#include <linux/init.h>
22#include <linux/moduleparam.h>
23#include <linux/types.h>
24
25#include <asm/processor.h>
26
27#include "hvc_console.h"
28
29/* DCC Status Bits */
30#define DCC_STATUS_RX (1 << 30)
31#define DCC_STATUS_TX (1 << 29)
32
33static inline u32 __dcc_getstatus(void)
34{
35 u32 __ret;
36 asm volatile("mrc p14, 0, %0, c0, c1, 0 @ read comms ctrl reg"
37 : "=r" (__ret) : : "cc");
38
39 return __ret;
40}
41
42
43static inline char __dcc_getchar(void)
44{
45 char __c;
46
47 asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg"
48 : "=r" (__c));
49
50 return __c;
51}
52
53static inline void __dcc_putchar(char c)
54{
55 asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char"
56 : /* no output register */
57 : "r" (c));
58}
59
60static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
61{
62 int i;
63
64 for (i = 0; i < count; i++) {
65 while (__dcc_getstatus() & DCC_STATUS_TX)
66 cpu_relax();
67
68 __dcc_putchar(buf[i]);
69 }
70
71 return count;
72}
73
74static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
75{
76 int i;
77
78 for (i = 0; i < count; ++i)
79 if (__dcc_getstatus() & DCC_STATUS_RX)
80 buf[i] = __dcc_getchar();
81 else
82 break;
83
84 return i;
85}
86
87static const struct hv_ops hvc_dcc_get_put_ops = {
88 .get_chars = hvc_dcc_get_chars,
89 .put_chars = hvc_dcc_put_chars,
90};
91
92static int __init hvc_dcc_console_init(void)
93{
94 hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
95 return 0;
96}
97console_initcall(hvc_dcc_console_init);
98
99static int __init hvc_dcc_init(void)
100{
101 hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
102 return 0;
103}
104device_initcall(hvc_dcc_init);
diff --git a/drivers/tty/hvc/hvc_irq.c b/drivers/tty/hvc/hvc_irq.c
new file mode 100644
index 000000000000..2623e177e8d6
--- /dev/null
+++ b/drivers/tty/hvc/hvc_irq.c
@@ -0,0 +1,49 @@
1/*
2 * Copyright IBM Corp. 2001,2008
3 *
4 * This file contains the IRQ specific code for hvc_console
5 *
6 */
7
8#include <linux/interrupt.h>
9
10#include "hvc_console.h"
11
12static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
13{
14 /* if hvc_poll request a repoll, then kick the hvcd thread */
15 if (hvc_poll(dev_instance))
16 hvc_kick();
17 return IRQ_HANDLED;
18}
19
20/*
21 * For IRQ based systems these callbacks can be used
22 */
23int notifier_add_irq(struct hvc_struct *hp, int irq)
24{
25 int rc;
26
27 if (!irq) {
28 hp->irq_requested = 0;
29 return 0;
30 }
31 rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED,
32 "hvc_console", hp);
33 if (!rc)
34 hp->irq_requested = 1;
35 return rc;
36}
37
38void notifier_del_irq(struct hvc_struct *hp, int irq)
39{
40 if (!hp->irq_requested)
41 return;
42 free_irq(irq, hp);
43 hp->irq_requested = 0;
44}
45
46void notifier_hangup_irq(struct hvc_struct *hp, int irq)
47{
48 notifier_del_irq(hp, irq);
49}
diff --git a/drivers/tty/hvc/hvc_iseries.c b/drivers/tty/hvc/hvc_iseries.c
new file mode 100644
index 000000000000..21c54955084e
--- /dev/null
+++ b/drivers/tty/hvc/hvc_iseries.c
@@ -0,0 +1,598 @@
1/*
2 * iSeries vio driver interface to hvc_console.c
3 *
4 * This code is based heavily on hvc_vio.c and viocons.c
5 *
6 * Copyright (C) 2006 Stephen Rothwell, IBM Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#include <stdarg.h>
23#include <linux/types.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/spinlock.h>
27#include <linux/console.h>
28
29#include <asm/hvconsole.h>
30#include <asm/vio.h>
31#include <asm/prom.h>
32#include <asm/firmware.h>
33#include <asm/iseries/vio.h>
34#include <asm/iseries/hv_call.h>
35#include <asm/iseries/hv_lp_config.h>
36#include <asm/iseries/hv_lp_event.h>
37
38#include "hvc_console.h"
39
40#define VTTY_PORTS 10
41
42static DEFINE_SPINLOCK(consolelock);
43static DEFINE_SPINLOCK(consoleloglock);
44
45static const char hvc_driver_name[] = "hvc_console";
46
47#define IN_BUF_SIZE 200
48
49/*
50 * Our port information.
51 */
52static struct port_info {
53 HvLpIndex lp;
54 u64 seq; /* sequence number of last HV send */
55 u64 ack; /* last ack from HV */
56 struct hvc_struct *hp;
57 int in_start;
58 int in_end;
59 unsigned char in_buf[IN_BUF_SIZE];
60} port_info[VTTY_PORTS] = {
61 [ 0 ... VTTY_PORTS - 1 ] = {
62 .lp = HvLpIndexInvalid
63 }
64};
65
66#define viochar_is_console(pi) ((pi) == &port_info[0])
67
68static struct vio_device_id hvc_driver_table[] __devinitdata = {
69 {"serial", "IBM,iSeries-vty"},
70 { "", "" }
71};
72MODULE_DEVICE_TABLE(vio, hvc_driver_table);
73
74static void hvlog(char *fmt, ...)
75{
76 int i;
77 unsigned long flags;
78 va_list args;
79 static char buf[256];
80
81 spin_lock_irqsave(&consoleloglock, flags);
82 va_start(args, fmt);
83 i = vscnprintf(buf, sizeof(buf) - 1, fmt, args);
84 va_end(args);
85 buf[i++] = '\r';
86 HvCall_writeLogBuffer(buf, i);
87 spin_unlock_irqrestore(&consoleloglock, flags);
88}
89
90/*
91 * Initialize the common fields in a charLpEvent
92 */
93static void init_data_event(struct viocharlpevent *viochar, HvLpIndex lp)
94{
95 struct HvLpEvent *hev = &viochar->event;
96
97 memset(viochar, 0, sizeof(struct viocharlpevent));
98
99 hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
100 HV_LP_EVENT_INT;
101 hev->xType = HvLpEvent_Type_VirtualIo;
102 hev->xSubtype = viomajorsubtype_chario | viochardata;
103 hev->xSourceLp = HvLpConfig_getLpIndex();
104 hev->xTargetLp = lp;
105 hev->xSizeMinus1 = sizeof(struct viocharlpevent);
106 hev->xSourceInstanceId = viopath_sourceinst(lp);
107 hev->xTargetInstanceId = viopath_targetinst(lp);
108}
109
110static int get_chars(uint32_t vtermno, char *buf, int count)
111{
112 struct port_info *pi;
113 int n = 0;
114 unsigned long flags;
115
116 if (vtermno >= VTTY_PORTS)
117 return -EINVAL;
118 if (count == 0)
119 return 0;
120
121 pi = &port_info[vtermno];
122 spin_lock_irqsave(&consolelock, flags);
123
124 if (pi->in_end == 0)
125 goto done;
126
127 n = pi->in_end - pi->in_start;
128 if (n > count)
129 n = count;
130 memcpy(buf, &pi->in_buf[pi->in_start], n);
131 pi->in_start += n;
132 if (pi->in_start == pi->in_end) {
133 pi->in_start = 0;
134 pi->in_end = 0;
135 }
136done:
137 spin_unlock_irqrestore(&consolelock, flags);
138 return n;
139}
140
141static int put_chars(uint32_t vtermno, const char *buf, int count)
142{
143 struct viocharlpevent *viochar;
144 struct port_info *pi;
145 HvLpEvent_Rc hvrc;
146 unsigned long flags;
147 int sent = 0;
148
149 if (vtermno >= VTTY_PORTS)
150 return -EINVAL;
151
152 pi = &port_info[vtermno];
153
154 spin_lock_irqsave(&consolelock, flags);
155
156 if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) {
157 HvCall_writeLogBuffer(buf, count);
158 sent = count;
159 goto done;
160 }
161
162 viochar = vio_get_event_buffer(viomajorsubtype_chario);
163 if (viochar == NULL) {
164 hvlog("\n\rviocons: Can't get viochar buffer.");
165 goto done;
166 }
167
168 while ((count > 0) && ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
169 int len;
170
171 len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count;
172
173 if (viochar_is_console(pi))
174 HvCall_writeLogBuffer(buf, len);
175
176 init_data_event(viochar, pi->lp);
177
178 viochar->len = len;
179 viochar->event.xCorrelationToken = pi->seq++;
180 viochar->event.xSizeMinus1 =
181 offsetof(struct viocharlpevent, data) + len;
182
183 memcpy(viochar->data, buf, len);
184
185 hvrc = HvCallEvent_signalLpEvent(&viochar->event);
186 if (hvrc)
187 hvlog("\n\rerror sending event! return code %d\n\r",
188 (int)hvrc);
189 sent += len;
190 count -= len;
191 buf += len;
192 }
193
194 vio_free_event_buffer(viomajorsubtype_chario, viochar);
195done:
196 spin_unlock_irqrestore(&consolelock, flags);
197 return sent;
198}
199
200static const struct hv_ops hvc_get_put_ops = {
201 .get_chars = get_chars,
202 .put_chars = put_chars,
203 .notifier_add = notifier_add_irq,
204 .notifier_del = notifier_del_irq,
205 .notifier_hangup = notifier_hangup_irq,
206};
207
208static int __devinit hvc_vio_probe(struct vio_dev *vdev,
209 const struct vio_device_id *id)
210{
211 struct hvc_struct *hp;
212 struct port_info *pi;
213
214 /* probed with invalid parameters. */
215 if (!vdev || !id)
216 return -EPERM;
217
218 if (vdev->unit_address >= VTTY_PORTS)
219 return -ENODEV;
220
221 pi = &port_info[vdev->unit_address];
222
223 hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops,
224 VIOCHAR_MAX_DATA);
225 if (IS_ERR(hp))
226 return PTR_ERR(hp);
227 pi->hp = hp;
228 dev_set_drvdata(&vdev->dev, pi);
229
230 return 0;
231}
232
233static int __devexit hvc_vio_remove(struct vio_dev *vdev)
234{
235 struct port_info *pi = dev_get_drvdata(&vdev->dev);
236 struct hvc_struct *hp = pi->hp;
237
238 return hvc_remove(hp);
239}
240
241static struct vio_driver hvc_vio_driver = {
242 .id_table = hvc_driver_table,
243 .probe = hvc_vio_probe,
244 .remove = __devexit_p(hvc_vio_remove),
245 .driver = {
246 .name = hvc_driver_name,
247 .owner = THIS_MODULE,
248 }
249};
250
251static void hvc_open_event(struct HvLpEvent *event)
252{
253 unsigned long flags;
254 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
255 u8 port = cevent->virtual_device;
256 struct port_info *pi;
257 int reject = 0;
258
259 if (hvlpevent_is_ack(event)) {
260 if (port >= VTTY_PORTS)
261 return;
262
263 spin_lock_irqsave(&consolelock, flags);
264
265 pi = &port_info[port];
266 if (event->xRc == HvLpEvent_Rc_Good) {
267 pi->seq = pi->ack = 0;
268 /*
269 * This line allows connections from the primary
270 * partition but once one is connected from the
271 * primary partition nothing short of a reboot
272 * of linux will allow access from the hosting
273 * partition again without a required iSeries fix.
274 */
275 pi->lp = event->xTargetLp;
276 }
277
278 spin_unlock_irqrestore(&consolelock, flags);
279 if (event->xRc != HvLpEvent_Rc_Good)
280 printk(KERN_WARNING
281 "hvc: handle_open_event: event->xRc == (%d).\n",
282 event->xRc);
283
284 if (event->xCorrelationToken != 0) {
285 atomic_t *aptr= (atomic_t *)event->xCorrelationToken;
286 atomic_set(aptr, 1);
287 } else
288 printk(KERN_WARNING
289 "hvc: weird...got open ack without atomic\n");
290 return;
291 }
292
293 /* This had better require an ack, otherwise complain */
294 if (!hvlpevent_need_ack(event)) {
295 printk(KERN_WARNING "hvc: viocharopen without ack bit!\n");
296 return;
297 }
298
299 spin_lock_irqsave(&consolelock, flags);
300
301 /* Make sure this is a good virtual tty */
302 if (port >= VTTY_PORTS) {
303 event->xRc = HvLpEvent_Rc_SubtypeError;
304 cevent->subtype_result_code = viorc_openRejected;
305 /*
306 * Flag state here since we can't printk while holding
307 * the consolelock spinlock.
308 */
309 reject = 1;
310 } else {
311 pi = &port_info[port];
312 if ((pi->lp != HvLpIndexInvalid) &&
313 (pi->lp != event->xSourceLp)) {
314 /*
315 * If this is tty is already connected to a different
316 * partition, fail.
317 */
318 event->xRc = HvLpEvent_Rc_SubtypeError;
319 cevent->subtype_result_code = viorc_openRejected;
320 reject = 2;
321 } else {
322 pi->lp = event->xSourceLp;
323 event->xRc = HvLpEvent_Rc_Good;
324 cevent->subtype_result_code = viorc_good;
325 pi->seq = pi->ack = 0;
326 }
327 }
328
329 spin_unlock_irqrestore(&consolelock, flags);
330
331 if (reject == 1)
332 printk(KERN_WARNING "hvc: open rejected: bad virtual tty.\n");
333 else if (reject == 2)
334 printk(KERN_WARNING "hvc: open rejected: console in exclusive "
335 "use by another partition.\n");
336
337 /* Return the acknowledgement */
338 HvCallEvent_ackLpEvent(event);
339}
340
341/*
342 * Handle a close charLpEvent. This should ONLY be an Interrupt because the
343 * virtual console should never actually issue a close event to the hypervisor
344 * because the virtual console never goes away. A close event coming from the
345 * hypervisor simply means that there are no client consoles connected to the
346 * virtual console.
347 */
348static void hvc_close_event(struct HvLpEvent *event)
349{
350 unsigned long flags;
351 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
352 u8 port = cevent->virtual_device;
353
354 if (!hvlpevent_is_int(event)) {
355 printk(KERN_WARNING
356 "hvc: got unexpected close acknowledgement\n");
357 return;
358 }
359
360 if (port >= VTTY_PORTS) {
361 printk(KERN_WARNING
362 "hvc: close message from invalid virtual device.\n");
363 return;
364 }
365
366 /* For closes, just mark the console partition invalid */
367 spin_lock_irqsave(&consolelock, flags);
368
369 if (port_info[port].lp == event->xSourceLp)
370 port_info[port].lp = HvLpIndexInvalid;
371
372 spin_unlock_irqrestore(&consolelock, flags);
373}
374
375static void hvc_data_event(struct HvLpEvent *event)
376{
377 unsigned long flags;
378 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
379 struct port_info *pi;
380 int n;
381 u8 port = cevent->virtual_device;
382
383 if (port >= VTTY_PORTS) {
384 printk(KERN_WARNING "hvc: data on invalid virtual device %d\n",
385 port);
386 return;
387 }
388 if (cevent->len == 0)
389 return;
390
391 /*
392 * Change 05/01/2003 - Ryan Arnold: If a partition other than
393 * the current exclusive partition tries to send us data
394 * events then just drop them on the floor because we don't
395 * want his stinking data. He isn't authorized to receive
396 * data because he wasn't the first one to get the console,
397 * therefore he shouldn't be allowed to send data either.
398 * This will work without an iSeries fix.
399 */
400 pi = &port_info[port];
401 if (pi->lp != event->xSourceLp)
402 return;
403
404 spin_lock_irqsave(&consolelock, flags);
405
406 n = IN_BUF_SIZE - pi->in_end;
407 if (n > cevent->len)
408 n = cevent->len;
409 if (n > 0) {
410 memcpy(&pi->in_buf[pi->in_end], cevent->data, n);
411 pi->in_end += n;
412 }
413 spin_unlock_irqrestore(&consolelock, flags);
414 if (n == 0)
415 printk(KERN_WARNING "hvc: input buffer overflow\n");
416}
417
418static void hvc_ack_event(struct HvLpEvent *event)
419{
420 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
421 unsigned long flags;
422 u8 port = cevent->virtual_device;
423
424 if (port >= VTTY_PORTS) {
425 printk(KERN_WARNING "hvc: data on invalid virtual device\n");
426 return;
427 }
428
429 spin_lock_irqsave(&consolelock, flags);
430 port_info[port].ack = event->xCorrelationToken;
431 spin_unlock_irqrestore(&consolelock, flags);
432}
433
434static void hvc_config_event(struct HvLpEvent *event)
435{
436 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
437
438 if (cevent->data[0] == 0x01)
439 printk(KERN_INFO "hvc: window resized to %d: %d: %d: %d\n",
440 cevent->data[1], cevent->data[2],
441 cevent->data[3], cevent->data[4]);
442 else
443 printk(KERN_WARNING "hvc: unknown config event\n");
444}
445
446static void hvc_handle_event(struct HvLpEvent *event)
447{
448 int charminor;
449
450 if (event == NULL)
451 return;
452
453 charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
454 switch (charminor) {
455 case viocharopen:
456 hvc_open_event(event);
457 break;
458 case viocharclose:
459 hvc_close_event(event);
460 break;
461 case viochardata:
462 hvc_data_event(event);
463 break;
464 case viocharack:
465 hvc_ack_event(event);
466 break;
467 case viocharconfig:
468 hvc_config_event(event);
469 break;
470 default:
471 if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
472 event->xRc = HvLpEvent_Rc_InvalidSubtype;
473 HvCallEvent_ackLpEvent(event);
474 }
475 }
476}
477
478static int __init send_open(HvLpIndex remoteLp, void *sem)
479{
480 return HvCallEvent_signalLpEventFast(remoteLp,
481 HvLpEvent_Type_VirtualIo,
482 viomajorsubtype_chario | viocharopen,
483 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
484 viopath_sourceinst(remoteLp),
485 viopath_targetinst(remoteLp),
486 (u64)(unsigned long)sem, VIOVERSION << 16,
487 0, 0, 0, 0);
488}
489
490static int __init hvc_vio_init(void)
491{
492 atomic_t wait_flag;
493 int rc;
494
495 if (!firmware_has_feature(FW_FEATURE_ISERIES))
496 return -EIO;
497
498 /* +2 for fudge */
499 rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
500 viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
501 if (rc)
502 printk(KERN_WARNING "hvc: error opening to primary %d\n", rc);
503
504 if (viopath_hostLp == HvLpIndexInvalid)
505 vio_set_hostlp();
506
507 /*
508 * And if the primary is not the same as the hosting LP, open to the
509 * hosting lp
510 */
511 if ((viopath_hostLp != HvLpIndexInvalid) &&
512 (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) {
513 printk(KERN_INFO "hvc: open path to hosting (%d)\n",
514 viopath_hostLp);
515 rc = viopath_open(viopath_hostLp, viomajorsubtype_chario,
516 VIOCHAR_WINDOW + 2); /* +2 for fudge */
517 if (rc)
518 printk(KERN_WARNING
519 "error opening to partition %d: %d\n",
520 viopath_hostLp, rc);
521 }
522
523 if (vio_setHandler(viomajorsubtype_chario, hvc_handle_event) < 0)
524 printk(KERN_WARNING
525 "hvc: error seting handler for console events!\n");
526
527 /*
528 * First, try to open the console to the hosting lp.
529 * Wait on a semaphore for the response.
530 */
531 atomic_set(&wait_flag, 0);
532 if ((viopath_isactive(viopath_hostLp)) &&
533 (send_open(viopath_hostLp, &wait_flag) == 0)) {
534 printk(KERN_INFO "hvc: hosting partition %d\n", viopath_hostLp);
535 while (atomic_read(&wait_flag) == 0)
536 mb();
537 atomic_set(&wait_flag, 0);
538 }
539
540 /*
541 * If we don't have an active console, try the primary
542 */
543 if ((!viopath_isactive(port_info[0].lp)) &&
544 (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) &&
545 (send_open(HvLpConfig_getPrimaryLpIndex(), &wait_flag) == 0)) {
546 printk(KERN_INFO "hvc: opening console to primary partition\n");
547 while (atomic_read(&wait_flag) == 0)
548 mb();
549 }
550
551 /* Register as a vio device to receive callbacks */
552 rc = vio_register_driver(&hvc_vio_driver);
553
554 return rc;
555}
556module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
557
558static void __exit hvc_vio_exit(void)
559{
560 vio_unregister_driver(&hvc_vio_driver);
561}
562module_exit(hvc_vio_exit);
563
564/* the device tree order defines our numbering */
565static int __init hvc_find_vtys(void)
566{
567 struct device_node *vty;
568 int num_found = 0;
569
570 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
571 vty = of_find_node_by_name(vty, "vty")) {
572 const uint32_t *vtermno;
573
574 /* We have statically defined space for only a certain number
575 * of console adapters.
576 */
577 if ((num_found >= MAX_NR_HVC_CONSOLES) ||
578 (num_found >= VTTY_PORTS)) {
579 of_node_put(vty);
580 break;
581 }
582
583 vtermno = of_get_property(vty, "reg", NULL);
584 if (!vtermno)
585 continue;
586
587 if (!of_device_is_compatible(vty, "IBM,iSeries-vty"))
588 continue;
589
590 if (num_found == 0)
591 add_preferred_console("hvc", 0, NULL);
592 hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
593 ++num_found;
594 }
595
596 return num_found;
597}
598console_initcall(hvc_find_vtys);
diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c
new file mode 100644
index 000000000000..b6f7d52f7c35
--- /dev/null
+++ b/drivers/tty/hvc/hvc_iucv.c
@@ -0,0 +1,1337 @@
1/*
2 * hvc_iucv.c - z/VM IUCV hypervisor console (HVC) device driver
3 *
4 * This HVC device driver provides terminal access using
5 * z/VM IUCV communication paths.
6 *
7 * Copyright IBM Corp. 2008, 2009
8 *
9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
10 */
11#define KMSG_COMPONENT "hvc_iucv"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13
14#include <linux/types.h>
15#include <linux/slab.h>
16#include <asm/ebcdic.h>
17#include <linux/ctype.h>
18#include <linux/delay.h>
19#include <linux/device.h>
20#include <linux/init.h>
21#include <linux/mempool.h>
22#include <linux/moduleparam.h>
23#include <linux/tty.h>
24#include <linux/wait.h>
25#include <net/iucv/iucv.h>
26
27#include "hvc_console.h"
28
29
30/* General device driver settings */
31#define HVC_IUCV_MAGIC 0xc9e4c3e5
32#define MAX_HVC_IUCV_LINES HVC_ALLOC_TTY_ADAPTERS
33#define MEMPOOL_MIN_NR (PAGE_SIZE / sizeof(struct iucv_tty_buffer)/4)
34
35/* IUCV TTY message */
36#define MSG_VERSION 0x02 /* Message version */
37#define MSG_TYPE_ERROR 0x01 /* Error message */
38#define MSG_TYPE_TERMENV 0x02 /* Terminal environment variable */
39#define MSG_TYPE_TERMIOS 0x04 /* Terminal IO struct update */
40#define MSG_TYPE_WINSIZE 0x08 /* Terminal window size update */
41#define MSG_TYPE_DATA 0x10 /* Terminal data */
42
43struct iucv_tty_msg {
44 u8 version; /* Message version */
45 u8 type; /* Message type */
46#define MSG_MAX_DATALEN ((u16)(~0))
47 u16 datalen; /* Payload length */
48 u8 data[]; /* Payload buffer */
49} __attribute__((packed));
50#define MSG_SIZE(s) ((s) + offsetof(struct iucv_tty_msg, data))
51
52enum iucv_state_t {
53 IUCV_DISCONN = 0,
54 IUCV_CONNECTED = 1,
55 IUCV_SEVERED = 2,
56};
57
58enum tty_state_t {
59 TTY_CLOSED = 0,
60 TTY_OPENED = 1,
61};
62
63struct hvc_iucv_private {
64 struct hvc_struct *hvc; /* HVC struct reference */
65 u8 srv_name[8]; /* IUCV service name (ebcdic) */
66 unsigned char is_console; /* Linux console usage flag */
67 enum iucv_state_t iucv_state; /* IUCV connection status */
68 enum tty_state_t tty_state; /* TTY status */
69 struct iucv_path *path; /* IUCV path pointer */
70 spinlock_t lock; /* hvc_iucv_private lock */
71#define SNDBUF_SIZE (PAGE_SIZE) /* must be < MSG_MAX_DATALEN */
72 void *sndbuf; /* send buffer */
73 size_t sndbuf_len; /* length of send buffer */
74#define QUEUE_SNDBUF_DELAY (HZ / 25)
75 struct delayed_work sndbuf_work; /* work: send iucv msg(s) */
76 wait_queue_head_t sndbuf_waitq; /* wait for send completion */
77 struct list_head tty_outqueue; /* outgoing IUCV messages */
78 struct list_head tty_inqueue; /* incoming IUCV messages */
79 struct device *dev; /* device structure */
80};
81
82struct iucv_tty_buffer {
83 struct list_head list; /* list pointer */
84 struct iucv_message msg; /* store an IUCV message */
85 size_t offset; /* data buffer offset */
86 struct iucv_tty_msg *mbuf; /* buffer to store input/output data */
87};
88
89/* IUCV callback handler */
90static int hvc_iucv_path_pending(struct iucv_path *, u8[8], u8[16]);
91static void hvc_iucv_path_severed(struct iucv_path *, u8[16]);
92static void hvc_iucv_msg_pending(struct iucv_path *, struct iucv_message *);
93static void hvc_iucv_msg_complete(struct iucv_path *, struct iucv_message *);
94
95
96/* Kernel module parameter: use one terminal device as default */
97static unsigned long hvc_iucv_devices = 1;
98
99/* Array of allocated hvc iucv tty lines... */
100static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
101#define IUCV_HVC_CON_IDX (0)
102/* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
103#define MAX_VMID_FILTER (500)
104static size_t hvc_iucv_filter_size;
105static void *hvc_iucv_filter;
106static const char *hvc_iucv_filter_string;
107static DEFINE_RWLOCK(hvc_iucv_filter_lock);
108
109/* Kmem cache and mempool for iucv_tty_buffer elements */
110static struct kmem_cache *hvc_iucv_buffer_cache;
111static mempool_t *hvc_iucv_mempool;
112
113/* IUCV handler callback functions */
114static struct iucv_handler hvc_iucv_handler = {
115 .path_pending = hvc_iucv_path_pending,
116 .path_severed = hvc_iucv_path_severed,
117 .message_complete = hvc_iucv_msg_complete,
118 .message_pending = hvc_iucv_msg_pending,
119};
120
121
122/**
123 * hvc_iucv_get_private() - Return a struct hvc_iucv_private instance.
124 * @num: The HVC virtual terminal number (vtermno)
125 *
126 * This function returns the struct hvc_iucv_private instance that corresponds
127 * to the HVC virtual terminal number specified as parameter @num.
128 */
129struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
130{
131 if ((num < HVC_IUCV_MAGIC) || (num - HVC_IUCV_MAGIC > hvc_iucv_devices))
132 return NULL;
133 return hvc_iucv_table[num - HVC_IUCV_MAGIC];
134}
135
136/**
137 * alloc_tty_buffer() - Return a new struct iucv_tty_buffer element.
138 * @size: Size of the internal buffer used to store data.
139 * @flags: Memory allocation flags passed to mempool.
140 *
141 * This function allocates a new struct iucv_tty_buffer element and, optionally,
142 * allocates an internal data buffer with the specified size @size.
143 * The internal data buffer is always allocated with GFP_DMA which is
144 * required for receiving and sending data with IUCV.
145 * Note: The total message size arises from the internal buffer size and the
146 * members of the iucv_tty_msg structure.
147 * The function returns NULL if memory allocation has failed.
148 */
149static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
150{
151 struct iucv_tty_buffer *bufp;
152
153 bufp = mempool_alloc(hvc_iucv_mempool, flags);
154 if (!bufp)
155 return NULL;
156 memset(bufp, 0, sizeof(*bufp));
157
158 if (size > 0) {
159 bufp->msg.length = MSG_SIZE(size);
160 bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA);
161 if (!bufp->mbuf) {
162 mempool_free(bufp, hvc_iucv_mempool);
163 return NULL;
164 }
165 bufp->mbuf->version = MSG_VERSION;
166 bufp->mbuf->type = MSG_TYPE_DATA;
167 bufp->mbuf->datalen = (u16) size;
168 }
169 return bufp;
170}
171
172/**
173 * destroy_tty_buffer() - destroy struct iucv_tty_buffer element.
174 * @bufp: Pointer to a struct iucv_tty_buffer element, SHALL NOT be NULL.
175 */
176static void destroy_tty_buffer(struct iucv_tty_buffer *bufp)
177{
178 kfree(bufp->mbuf);
179 mempool_free(bufp, hvc_iucv_mempool);
180}
181
182/**
183 * destroy_tty_buffer_list() - call destroy_tty_buffer() for each list element.
184 * @list: List containing struct iucv_tty_buffer elements.
185 */
186static void destroy_tty_buffer_list(struct list_head *list)
187{
188 struct iucv_tty_buffer *ent, *next;
189
190 list_for_each_entry_safe(ent, next, list, list) {
191 list_del(&ent->list);
192 destroy_tty_buffer(ent);
193 }
194}
195
196/**
197 * hvc_iucv_write() - Receive IUCV message & write data to HVC buffer.
198 * @priv: Pointer to struct hvc_iucv_private
199 * @buf: HVC buffer for writing received terminal data.
200 * @count: HVC buffer size.
201 * @has_more_data: Pointer to an int variable.
202 *
203 * The function picks up pending messages from the input queue and receives
204 * the message data that is then written to the specified buffer @buf.
205 * If the buffer size @count is less than the data message size, the
206 * message is kept on the input queue and @has_more_data is set to 1.
207 * If all message data has been written, the message is removed from
208 * the input queue.
209 *
210 * The function returns the number of bytes written to the terminal, zero if
211 * there are no pending data messages available or if there is no established
212 * IUCV path.
213 * If the IUCV path has been severed, then -EPIPE is returned to cause a
214 * hang up (that is issued by the HVC layer).
215 */
216static int hvc_iucv_write(struct hvc_iucv_private *priv,
217 char *buf, int count, int *has_more_data)
218{
219 struct iucv_tty_buffer *rb;
220 int written;
221 int rc;
222
223 /* immediately return if there is no IUCV connection */
224 if (priv->iucv_state == IUCV_DISCONN)
225 return 0;
226
227 /* if the IUCV path has been severed, return -EPIPE to inform the
228 * HVC layer to hang up the tty device. */
229 if (priv->iucv_state == IUCV_SEVERED)
230 return -EPIPE;
231
232 /* check if there are pending messages */
233 if (list_empty(&priv->tty_inqueue))
234 return 0;
235
236 /* receive an iucv message and flip data to the tty (ldisc) */
237 rb = list_first_entry(&priv->tty_inqueue, struct iucv_tty_buffer, list);
238
239 written = 0;
240 if (!rb->mbuf) { /* message not yet received ... */
241 /* allocate mem to store msg data; if no memory is available
242 * then leave the buffer on the list and re-try later */
243 rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA);
244 if (!rb->mbuf)
245 return -ENOMEM;
246
247 rc = __iucv_message_receive(priv->path, &rb->msg, 0,
248 rb->mbuf, rb->msg.length, NULL);
249 switch (rc) {
250 case 0: /* Successful */
251 break;
252 case 2: /* No message found */
253 case 9: /* Message purged */
254 break;
255 default:
256 written = -EIO;
257 }
258 /* remove buffer if an error has occurred or received data
259 * is not correct */
260 if (rc || (rb->mbuf->version != MSG_VERSION) ||
261 (rb->msg.length != MSG_SIZE(rb->mbuf->datalen)))
262 goto out_remove_buffer;
263 }
264
265 switch (rb->mbuf->type) {
266 case MSG_TYPE_DATA:
267 written = min_t(int, rb->mbuf->datalen - rb->offset, count);
268 memcpy(buf, rb->mbuf->data + rb->offset, written);
269 if (written < (rb->mbuf->datalen - rb->offset)) {
270 rb->offset += written;
271 *has_more_data = 1;
272 goto out_written;
273 }
274 break;
275
276 case MSG_TYPE_WINSIZE:
277 if (rb->mbuf->datalen != sizeof(struct winsize))
278 break;
279 /* The caller must ensure that the hvc is locked, which
280 * is the case when called from hvc_iucv_get_chars() */
281 __hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data));
282 break;
283
284 case MSG_TYPE_ERROR: /* ignored ... */
285 case MSG_TYPE_TERMENV: /* ignored ... */
286 case MSG_TYPE_TERMIOS: /* ignored ... */
287 break;
288 }
289
290out_remove_buffer:
291 list_del(&rb->list);
292 destroy_tty_buffer(rb);
293 *has_more_data = !list_empty(&priv->tty_inqueue);
294
295out_written:
296 return written;
297}
298
299/**
300 * hvc_iucv_get_chars() - HVC get_chars operation.
301 * @vtermno: HVC virtual terminal number.
302 * @buf: Pointer to a buffer to store data
303 * @count: Size of buffer available for writing
304 *
305 * The HVC thread calls this method to read characters from the back-end.
306 * If an IUCV communication path has been established, pending IUCV messages
307 * are received and data is copied into buffer @buf up to @count bytes.
308 *
309 * Locking: The routine gets called under an irqsave() spinlock; and
310 * the routine locks the struct hvc_iucv_private->lock to call
311 * helper functions.
312 */
313static int hvc_iucv_get_chars(uint32_t vtermno, char *buf, int count)
314{
315 struct hvc_iucv_private *priv = hvc_iucv_get_private(vtermno);
316 int written;
317 int has_more_data;
318
319 if (count <= 0)
320 return 0;
321
322 if (!priv)
323 return -ENODEV;
324
325 spin_lock(&priv->lock);
326 has_more_data = 0;
327 written = hvc_iucv_write(priv, buf, count, &has_more_data);
328 spin_unlock(&priv->lock);
329
330 /* if there are still messages on the queue... schedule another run */
331 if (has_more_data)
332 hvc_kick();
333
334 return written;
335}
336
337/**
338 * hvc_iucv_queue() - Buffer terminal data for sending.
339 * @priv: Pointer to struct hvc_iucv_private instance.
340 * @buf: Buffer containing data to send.
341 * @count: Size of buffer and amount of data to send.
342 *
343 * The function queues data for sending. To actually send the buffered data,
344 * a work queue function is scheduled (with QUEUE_SNDBUF_DELAY).
345 * The function returns the number of data bytes that has been buffered.
346 *
347 * If the device is not connected, data is ignored and the function returns
348 * @count.
349 * If the buffer is full, the function returns 0.
350 * If an existing IUCV communicaton path has been severed, -EPIPE is returned
351 * (that can be passed to HVC layer to cause a tty hangup).
352 */
353static int hvc_iucv_queue(struct hvc_iucv_private *priv, const char *buf,
354 int count)
355{
356 size_t len;
357
358 if (priv->iucv_state == IUCV_DISCONN)
359 return count; /* ignore data */
360
361 if (priv->iucv_state == IUCV_SEVERED)
362 return -EPIPE;
363
364 len = min_t(size_t, count, SNDBUF_SIZE - priv->sndbuf_len);
365 if (!len)
366 return 0;
367
368 memcpy(priv->sndbuf + priv->sndbuf_len, buf, len);
369 priv->sndbuf_len += len;
370
371 if (priv->iucv_state == IUCV_CONNECTED)
372 schedule_delayed_work(&priv->sndbuf_work, QUEUE_SNDBUF_DELAY);
373
374 return len;
375}
376
377/**
378 * hvc_iucv_send() - Send an IUCV message containing terminal data.
379 * @priv: Pointer to struct hvc_iucv_private instance.
380 *
381 * If an IUCV communication path has been established, the buffered output data
382 * is sent via an IUCV message and the number of bytes sent is returned.
383 * Returns 0 if there is no established IUCV communication path or
384 * -EPIPE if an existing IUCV communicaton path has been severed.
385 */
386static int hvc_iucv_send(struct hvc_iucv_private *priv)
387{
388 struct iucv_tty_buffer *sb;
389 int rc, len;
390
391 if (priv->iucv_state == IUCV_SEVERED)
392 return -EPIPE;
393
394 if (priv->iucv_state == IUCV_DISCONN)
395 return -EIO;
396
397 if (!priv->sndbuf_len)
398 return 0;
399
400 /* allocate internal buffer to store msg data and also compute total
401 * message length */
402 sb = alloc_tty_buffer(priv->sndbuf_len, GFP_ATOMIC);
403 if (!sb)
404 return -ENOMEM;
405
406 memcpy(sb->mbuf->data, priv->sndbuf, priv->sndbuf_len);
407 sb->mbuf->datalen = (u16) priv->sndbuf_len;
408 sb->msg.length = MSG_SIZE(sb->mbuf->datalen);
409
410 list_add_tail(&sb->list, &priv->tty_outqueue);
411
412 rc = __iucv_message_send(priv->path, &sb->msg, 0, 0,
413 (void *) sb->mbuf, sb->msg.length);
414 if (rc) {
415 /* drop the message here; however we might want to handle
416 * 0x03 (msg limit reached) by trying again... */
417 list_del(&sb->list);
418 destroy_tty_buffer(sb);
419 }
420 len = priv->sndbuf_len;
421 priv->sndbuf_len = 0;
422
423 return len;
424}
425
426/**
427 * hvc_iucv_sndbuf_work() - Send buffered data over IUCV
428 * @work: Work structure.
429 *
430 * This work queue function sends buffered output data over IUCV and,
431 * if not all buffered data could be sent, reschedules itself.
432 */
433static void hvc_iucv_sndbuf_work(struct work_struct *work)
434{
435 struct hvc_iucv_private *priv;
436
437 priv = container_of(work, struct hvc_iucv_private, sndbuf_work.work);
438 if (!priv)
439 return;
440
441 spin_lock_bh(&priv->lock);
442 hvc_iucv_send(priv);
443 spin_unlock_bh(&priv->lock);
444}
445
446/**
447 * hvc_iucv_put_chars() - HVC put_chars operation.
448 * @vtermno: HVC virtual terminal number.
449 * @buf: Pointer to an buffer to read data from
450 * @count: Size of buffer available for reading
451 *
452 * The HVC thread calls this method to write characters to the back-end.
453 * The function calls hvc_iucv_queue() to queue terminal data for sending.
454 *
455 * Locking: The method gets called under an irqsave() spinlock; and
456 * locks struct hvc_iucv_private->lock.
457 */
458static int hvc_iucv_put_chars(uint32_t vtermno, const char *buf, int count)
459{
460 struct hvc_iucv_private *priv = hvc_iucv_get_private(vtermno);
461 int queued;
462
463 if (count <= 0)
464 return 0;
465
466 if (!priv)
467 return -ENODEV;
468
469 spin_lock(&priv->lock);
470 queued = hvc_iucv_queue(priv, buf, count);
471 spin_unlock(&priv->lock);
472
473 return queued;
474}
475
476/**
477 * hvc_iucv_notifier_add() - HVC notifier for opening a TTY for the first time.
478 * @hp: Pointer to the HVC device (struct hvc_struct)
479 * @id: Additional data (originally passed to hvc_alloc): the index of an struct
480 * hvc_iucv_private instance.
481 *
482 * The function sets the tty state to TTY_OPENED for the struct hvc_iucv_private
483 * instance that is derived from @id. Always returns 0.
484 *
485 * Locking: struct hvc_iucv_private->lock, spin_lock_bh
486 */
487static int hvc_iucv_notifier_add(struct hvc_struct *hp, int id)
488{
489 struct hvc_iucv_private *priv;
490
491 priv = hvc_iucv_get_private(id);
492 if (!priv)
493 return 0;
494
495 spin_lock_bh(&priv->lock);
496 priv->tty_state = TTY_OPENED;
497 spin_unlock_bh(&priv->lock);
498
499 return 0;
500}
501
502/**
503 * hvc_iucv_cleanup() - Clean up and reset a z/VM IUCV HVC instance.
504 * @priv: Pointer to the struct hvc_iucv_private instance.
505 */
506static void hvc_iucv_cleanup(struct hvc_iucv_private *priv)
507{
508 destroy_tty_buffer_list(&priv->tty_outqueue);
509 destroy_tty_buffer_list(&priv->tty_inqueue);
510
511 priv->tty_state = TTY_CLOSED;
512 priv->iucv_state = IUCV_DISCONN;
513
514 priv->sndbuf_len = 0;
515}
516
517/**
518 * tty_outqueue_empty() - Test if the tty outq is empty
519 * @priv: Pointer to struct hvc_iucv_private instance.
520 */
521static inline int tty_outqueue_empty(struct hvc_iucv_private *priv)
522{
523 int rc;
524
525 spin_lock_bh(&priv->lock);
526 rc = list_empty(&priv->tty_outqueue);
527 spin_unlock_bh(&priv->lock);
528
529 return rc;
530}
531
532/**
533 * flush_sndbuf_sync() - Flush send buffer and wait for completion
534 * @priv: Pointer to struct hvc_iucv_private instance.
535 *
536 * The routine cancels a pending sndbuf work, calls hvc_iucv_send()
537 * to flush any buffered terminal output data and waits for completion.
538 */
539static void flush_sndbuf_sync(struct hvc_iucv_private *priv)
540{
541 int sync_wait;
542
543 cancel_delayed_work_sync(&priv->sndbuf_work);
544
545 spin_lock_bh(&priv->lock);
546 hvc_iucv_send(priv); /* force sending buffered data */
547 sync_wait = !list_empty(&priv->tty_outqueue); /* anything queued ? */
548 spin_unlock_bh(&priv->lock);
549
550 if (sync_wait)
551 wait_event_timeout(priv->sndbuf_waitq,
552 tty_outqueue_empty(priv), HZ/10);
553}
554
555/**
556 * hvc_iucv_hangup() - Sever IUCV path and schedule hvc tty hang up
557 * @priv: Pointer to hvc_iucv_private structure
558 *
559 * This routine severs an existing IUCV communication path and hangs
560 * up the underlying HVC terminal device.
561 * The hang-up occurs only if an IUCV communication path is established;
562 * otherwise there is no need to hang up the terminal device.
563 *
564 * The IUCV HVC hang-up is separated into two steps:
565 * 1. After the IUCV path has been severed, the iucv_state is set to
566 * IUCV_SEVERED.
567 * 2. Later, when the HVC thread calls hvc_iucv_get_chars(), the
568 * IUCV_SEVERED state causes the tty hang-up in the HVC layer.
569 *
570 * If the tty has not yet been opened, clean up the hvc_iucv_private
571 * structure to allow re-connects.
572 * If the tty has been opened, let get_chars() return -EPIPE to signal
573 * the HVC layer to hang up the tty and, if so, wake up the HVC thread
574 * to call get_chars()...
575 *
576 * Special notes on hanging up a HVC terminal instantiated as console:
577 * Hang-up: 1. do_tty_hangup() replaces file ops (= hung_up_tty_fops)
578 * 2. do_tty_hangup() calls tty->ops->close() for console_filp
579 * => no hangup notifier is called by HVC (default)
580 * 2. hvc_close() returns because of tty_hung_up_p(filp)
581 * => no delete notifier is called!
582 * Finally, the back-end is not being notified, thus, the tty session is
583 * kept active (TTY_OPEN) to be ready for re-connects.
584 *
585 * Locking: spin_lock(&priv->lock) w/o disabling bh
586 */
587static void hvc_iucv_hangup(struct hvc_iucv_private *priv)
588{
589 struct iucv_path *path;
590
591 path = NULL;
592 spin_lock(&priv->lock);
593 if (priv->iucv_state == IUCV_CONNECTED) {
594 path = priv->path;
595 priv->path = NULL;
596 priv->iucv_state = IUCV_SEVERED;
597 if (priv->tty_state == TTY_CLOSED)
598 hvc_iucv_cleanup(priv);
599 else
600 /* console is special (see above) */
601 if (priv->is_console) {
602 hvc_iucv_cleanup(priv);
603 priv->tty_state = TTY_OPENED;
604 } else
605 hvc_kick();
606 }
607 spin_unlock(&priv->lock);
608
609 /* finally sever path (outside of priv->lock due to lock ordering) */
610 if (path) {
611 iucv_path_sever(path, NULL);
612 iucv_path_free(path);
613 }
614}
615
616/**
617 * hvc_iucv_notifier_hangup() - HVC notifier for TTY hangups.
618 * @hp: Pointer to the HVC device (struct hvc_struct)
619 * @id: Additional data (originally passed to hvc_alloc):
620 * the index of an struct hvc_iucv_private instance.
621 *
622 * This routine notifies the HVC back-end that a tty hangup (carrier loss,
623 * virtual or otherwise) has occurred.
624 * The z/VM IUCV HVC device driver ignores virtual hangups (vhangup())
625 * to keep an existing IUCV communication path established.
626 * (Background: vhangup() is called from user space (by getty or login) to
627 * disable writing to the tty by other applications).
628 * If the tty has been opened and an established IUCV path has been severed
629 * (we caused the tty hangup), the function calls hvc_iucv_cleanup().
630 *
631 * Locking: struct hvc_iucv_private->lock
632 */
633static void hvc_iucv_notifier_hangup(struct hvc_struct *hp, int id)
634{
635 struct hvc_iucv_private *priv;
636
637 priv = hvc_iucv_get_private(id);
638 if (!priv)
639 return;
640
641 flush_sndbuf_sync(priv);
642
643 spin_lock_bh(&priv->lock);
644 /* NOTE: If the hangup was scheduled by ourself (from the iucv
645 * path_servered callback [IUCV_SEVERED]), we have to clean up
646 * our structure and to set state to TTY_CLOSED.
647 * If the tty was hung up otherwise (e.g. vhangup()), then we
648 * ignore this hangup and keep an established IUCV path open...
649 * (...the reason is that we are not able to connect back to the
650 * client if we disconnect on hang up) */
651 priv->tty_state = TTY_CLOSED;
652
653 if (priv->iucv_state == IUCV_SEVERED)
654 hvc_iucv_cleanup(priv);
655 spin_unlock_bh(&priv->lock);
656}
657
658/**
659 * hvc_iucv_notifier_del() - HVC notifier for closing a TTY for the last time.
660 * @hp: Pointer to the HVC device (struct hvc_struct)
661 * @id: Additional data (originally passed to hvc_alloc):
662 * the index of an struct hvc_iucv_private instance.
663 *
664 * This routine notifies the HVC back-end that the last tty device fd has been
665 * closed. The function calls hvc_iucv_cleanup() to clean up the struct
666 * hvc_iucv_private instance.
667 *
668 * Locking: struct hvc_iucv_private->lock
669 */
670static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
671{
672 struct hvc_iucv_private *priv;
673 struct iucv_path *path;
674
675 priv = hvc_iucv_get_private(id);
676 if (!priv)
677 return;
678
679 flush_sndbuf_sync(priv);
680
681 spin_lock_bh(&priv->lock);
682 path = priv->path; /* save reference to IUCV path */
683 priv->path = NULL;
684 hvc_iucv_cleanup(priv);
685 spin_unlock_bh(&priv->lock);
686
687 /* sever IUCV path outside of priv->lock due to lock ordering of:
688 * priv->lock <--> iucv_table_lock */
689 if (path) {
690 iucv_path_sever(path, NULL);
691 iucv_path_free(path);
692 }
693}
694
695/**
696 * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
697 * @ipvmid: Originating z/VM user ID (right padded with blanks)
698 *
699 * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
700 * non-zero.
701 */
702static int hvc_iucv_filter_connreq(u8 ipvmid[8])
703{
704 size_t i;
705
706 /* Note: default policy is ACCEPT if no filter is set */
707 if (!hvc_iucv_filter_size)
708 return 0;
709
710 for (i = 0; i < hvc_iucv_filter_size; i++)
711 if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
712 return 0;
713 return 1;
714}
715
716/**
717 * hvc_iucv_path_pending() - IUCV handler to process a connection request.
718 * @path: Pending path (struct iucv_path)
719 * @ipvmid: z/VM system identifier of originator
720 * @ipuser: User specified data for this path
721 * (AF_IUCV: port/service name and originator port)
722 *
723 * The function uses the @ipuser data to determine if the pending path belongs
724 * to a terminal managed by this device driver.
725 * If the path belongs to this driver, ensure that the terminal is not accessed
726 * multiple times (only one connection to a terminal is allowed).
727 * If the terminal is not yet connected, the pending path is accepted and is
728 * associated to the appropriate struct hvc_iucv_private instance.
729 *
730 * Returns 0 if @path belongs to a terminal managed by the this device driver;
731 * otherwise returns -ENODEV in order to dispatch this path to other handlers.
732 *
733 * Locking: struct hvc_iucv_private->lock
734 */
735static int hvc_iucv_path_pending(struct iucv_path *path,
736 u8 ipvmid[8], u8 ipuser[16])
737{
738 struct hvc_iucv_private *priv;
739 u8 nuser_data[16];
740 u8 vm_user_id[9];
741 int i, rc;
742
743 priv = NULL;
744 for (i = 0; i < hvc_iucv_devices; i++)
745 if (hvc_iucv_table[i] &&
746 (0 == memcmp(hvc_iucv_table[i]->srv_name, ipuser, 8))) {
747 priv = hvc_iucv_table[i];
748 break;
749 }
750 if (!priv)
751 return -ENODEV;
752
753 /* Enforce that ipvmid is allowed to connect to us */
754 read_lock(&hvc_iucv_filter_lock);
755 rc = hvc_iucv_filter_connreq(ipvmid);
756 read_unlock(&hvc_iucv_filter_lock);
757 if (rc) {
758 iucv_path_sever(path, ipuser);
759 iucv_path_free(path);
760 memcpy(vm_user_id, ipvmid, 8);
761 vm_user_id[8] = 0;
762 pr_info("A connection request from z/VM user ID %s "
763 "was refused\n", vm_user_id);
764 return 0;
765 }
766
767 spin_lock(&priv->lock);
768
769 /* If the terminal is already connected or being severed, then sever
770 * this path to enforce that there is only ONE established communication
771 * path per terminal. */
772 if (priv->iucv_state != IUCV_DISCONN) {
773 iucv_path_sever(path, ipuser);
774 iucv_path_free(path);
775 goto out_path_handled;
776 }
777
778 /* accept path */
779 memcpy(nuser_data, ipuser + 8, 8); /* remote service (for af_iucv) */
780 memcpy(nuser_data + 8, ipuser, 8); /* local service (for af_iucv) */
781 path->msglim = 0xffff; /* IUCV MSGLIMIT */
782 path->flags &= ~IUCV_IPRMDATA; /* TODO: use IUCV_IPRMDATA */
783 rc = iucv_path_accept(path, &hvc_iucv_handler, nuser_data, priv);
784 if (rc) {
785 iucv_path_sever(path, ipuser);
786 iucv_path_free(path);
787 goto out_path_handled;
788 }
789 priv->path = path;
790 priv->iucv_state = IUCV_CONNECTED;
791
792 /* flush buffered output data... */
793 schedule_delayed_work(&priv->sndbuf_work, 5);
794
795out_path_handled:
796 spin_unlock(&priv->lock);
797 return 0;
798}
799
800/**
801 * hvc_iucv_path_severed() - IUCV handler to process a path sever.
802 * @path: Pending path (struct iucv_path)
803 * @ipuser: User specified data for this path
804 * (AF_IUCV: port/service name and originator port)
805 *
806 * This function calls the hvc_iucv_hangup() function for the
807 * respective IUCV HVC terminal.
808 *
809 * Locking: struct hvc_iucv_private->lock
810 */
811static void hvc_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
812{
813 struct hvc_iucv_private *priv = path->private;
814
815 hvc_iucv_hangup(priv);
816}
817
818/**
819 * hvc_iucv_msg_pending() - IUCV handler to process an incoming IUCV message.
820 * @path: Pending path (struct iucv_path)
821 * @msg: Pointer to the IUCV message
822 *
823 * The function puts an incoming message on the input queue for later
824 * processing (by hvc_iucv_get_chars() / hvc_iucv_write()).
825 * If the tty has not yet been opened, the message is rejected.
826 *
827 * Locking: struct hvc_iucv_private->lock
828 */
829static void hvc_iucv_msg_pending(struct iucv_path *path,
830 struct iucv_message *msg)
831{
832 struct hvc_iucv_private *priv = path->private;
833 struct iucv_tty_buffer *rb;
834
835 /* reject messages that exceed max size of iucv_tty_msg->datalen */
836 if (msg->length > MSG_SIZE(MSG_MAX_DATALEN)) {
837 iucv_message_reject(path, msg);
838 return;
839 }
840
841 spin_lock(&priv->lock);
842
843 /* reject messages if tty has not yet been opened */
844 if (priv->tty_state == TTY_CLOSED) {
845 iucv_message_reject(path, msg);
846 goto unlock_return;
847 }
848
849 /* allocate tty buffer to save iucv msg only */
850 rb = alloc_tty_buffer(0, GFP_ATOMIC);
851 if (!rb) {
852 iucv_message_reject(path, msg);
853 goto unlock_return; /* -ENOMEM */
854 }
855 rb->msg = *msg;
856
857 list_add_tail(&rb->list, &priv->tty_inqueue);
858
859 hvc_kick(); /* wake up hvc thread */
860
861unlock_return:
862 spin_unlock(&priv->lock);
863}
864
865/**
866 * hvc_iucv_msg_complete() - IUCV handler to process message completion
867 * @path: Pending path (struct iucv_path)
868 * @msg: Pointer to the IUCV message
869 *
870 * The function is called upon completion of message delivery to remove the
871 * message from the outqueue. Additional delivery information can be found
872 * msg->audit: rejected messages (0x040000 (IPADRJCT)), and
873 * purged messages (0x010000 (IPADPGNR)).
874 *
875 * Locking: struct hvc_iucv_private->lock
876 */
877static void hvc_iucv_msg_complete(struct iucv_path *path,
878 struct iucv_message *msg)
879{
880 struct hvc_iucv_private *priv = path->private;
881 struct iucv_tty_buffer *ent, *next;
882 LIST_HEAD(list_remove);
883
884 spin_lock(&priv->lock);
885 list_for_each_entry_safe(ent, next, &priv->tty_outqueue, list)
886 if (ent->msg.id == msg->id) {
887 list_move(&ent->list, &list_remove);
888 break;
889 }
890 wake_up(&priv->sndbuf_waitq);
891 spin_unlock(&priv->lock);
892 destroy_tty_buffer_list(&list_remove);
893}
894
895/**
896 * hvc_iucv_pm_freeze() - Freeze PM callback
897 * @dev: IUVC HVC terminal device
898 *
899 * Sever an established IUCV communication path and
900 * trigger a hang-up of the underlying HVC terminal.
901 */
902static int hvc_iucv_pm_freeze(struct device *dev)
903{
904 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
905
906 local_bh_disable();
907 hvc_iucv_hangup(priv);
908 local_bh_enable();
909
910 return 0;
911}
912
913/**
914 * hvc_iucv_pm_restore_thaw() - Thaw and restore PM callback
915 * @dev: IUVC HVC terminal device
916 *
917 * Wake up the HVC thread to trigger hang-up and respective
918 * HVC back-end notifier invocations.
919 */
920static int hvc_iucv_pm_restore_thaw(struct device *dev)
921{
922 hvc_kick();
923 return 0;
924}
925
926
927/* HVC operations */
928static const struct hv_ops hvc_iucv_ops = {
929 .get_chars = hvc_iucv_get_chars,
930 .put_chars = hvc_iucv_put_chars,
931 .notifier_add = hvc_iucv_notifier_add,
932 .notifier_del = hvc_iucv_notifier_del,
933 .notifier_hangup = hvc_iucv_notifier_hangup,
934};
935
936/* Suspend / resume device operations */
937static const struct dev_pm_ops hvc_iucv_pm_ops = {
938 .freeze = hvc_iucv_pm_freeze,
939 .thaw = hvc_iucv_pm_restore_thaw,
940 .restore = hvc_iucv_pm_restore_thaw,
941};
942
943/* IUCV HVC device driver */
944static struct device_driver hvc_iucv_driver = {
945 .name = KMSG_COMPONENT,
946 .bus = &iucv_bus,
947 .pm = &hvc_iucv_pm_ops,
948};
949
950/**
951 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance
952 * @id: hvc_iucv_table index
953 * @is_console: Flag if the instance is used as Linux console
954 *
955 * This function allocates a new hvc_iucv_private structure and stores
956 * the instance in hvc_iucv_table at index @id.
957 * Returns 0 on success; otherwise non-zero.
958 */
959static int __init hvc_iucv_alloc(int id, unsigned int is_console)
960{
961 struct hvc_iucv_private *priv;
962 char name[9];
963 int rc;
964
965 priv = kzalloc(sizeof(struct hvc_iucv_private), GFP_KERNEL);
966 if (!priv)
967 return -ENOMEM;
968
969 spin_lock_init(&priv->lock);
970 INIT_LIST_HEAD(&priv->tty_outqueue);
971 INIT_LIST_HEAD(&priv->tty_inqueue);
972 INIT_DELAYED_WORK(&priv->sndbuf_work, hvc_iucv_sndbuf_work);
973 init_waitqueue_head(&priv->sndbuf_waitq);
974
975 priv->sndbuf = (void *) get_zeroed_page(GFP_KERNEL);
976 if (!priv->sndbuf) {
977 kfree(priv);
978 return -ENOMEM;
979 }
980
981 /* set console flag */
982 priv->is_console = is_console;
983
984 /* allocate hvc device */
985 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */
986 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256);
987 if (IS_ERR(priv->hvc)) {
988 rc = PTR_ERR(priv->hvc);
989 goto out_error_hvc;
990 }
991
992 /* notify HVC thread instead of using polling */
993 priv->hvc->irq_requested = 1;
994
995 /* setup iucv related information */
996 snprintf(name, 9, "lnxhvc%-2d", id);
997 memcpy(priv->srv_name, name, 8);
998 ASCEBC(priv->srv_name, 8);
999
1000 /* create and setup device */
1001 priv->dev = kzalloc(sizeof(*priv->dev), GFP_KERNEL);
1002 if (!priv->dev) {
1003 rc = -ENOMEM;
1004 goto out_error_dev;
1005 }
1006 dev_set_name(priv->dev, "hvc_iucv%d", id);
1007 dev_set_drvdata(priv->dev, priv);
1008 priv->dev->bus = &iucv_bus;
1009 priv->dev->parent = iucv_root;
1010 priv->dev->driver = &hvc_iucv_driver;
1011 priv->dev->release = (void (*)(struct device *)) kfree;
1012 rc = device_register(priv->dev);
1013 if (rc) {
1014 put_device(priv->dev);
1015 goto out_error_dev;
1016 }
1017
1018 hvc_iucv_table[id] = priv;
1019 return 0;
1020
1021out_error_dev:
1022 hvc_remove(priv->hvc);
1023out_error_hvc:
1024 free_page((unsigned long) priv->sndbuf);
1025 kfree(priv);
1026
1027 return rc;
1028}
1029
1030/**
1031 * hvc_iucv_destroy() - Destroy and free hvc_iucv_private instances
1032 */
1033static void __init hvc_iucv_destroy(struct hvc_iucv_private *priv)
1034{
1035 hvc_remove(priv->hvc);
1036 device_unregister(priv->dev);
1037 free_page((unsigned long) priv->sndbuf);
1038 kfree(priv);
1039}
1040
1041/**
1042 * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
1043 * @filter: String containing a comma-separated list of z/VM user IDs
1044 */
1045static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
1046{
1047 const char *nextdelim, *residual;
1048 size_t len;
1049
1050 nextdelim = strchr(filter, ',');
1051 if (nextdelim) {
1052 len = nextdelim - filter;
1053 residual = nextdelim + 1;
1054 } else {
1055 len = strlen(filter);
1056 residual = filter + len;
1057 }
1058
1059 if (len == 0)
1060 return ERR_PTR(-EINVAL);
1061
1062 /* check for '\n' (if called from sysfs) */
1063 if (filter[len - 1] == '\n')
1064 len--;
1065
1066 if (len > 8)
1067 return ERR_PTR(-EINVAL);
1068
1069 /* pad with blanks and save upper case version of user ID */
1070 memset(dest, ' ', 8);
1071 while (len--)
1072 dest[len] = toupper(filter[len]);
1073 return residual;
1074}
1075
1076/**
1077 * hvc_iucv_setup_filter() - Set up z/VM user ID filter
1078 * @filter: String consisting of a comma-separated list of z/VM user IDs
1079 *
1080 * The function parses the @filter string and creates an array containing
1081 * the list of z/VM user ID filter entries.
1082 * Return code 0 means success, -EINVAL if the filter is syntactically
1083 * incorrect, -ENOMEM if there was not enough memory to allocate the
1084 * filter list array, or -ENOSPC if too many z/VM user IDs have been specified.
1085 */
1086static int hvc_iucv_setup_filter(const char *val)
1087{
1088 const char *residual;
1089 int err;
1090 size_t size, count;
1091 void *array, *old_filter;
1092
1093 count = strlen(val);
1094 if (count == 0 || (count == 1 && val[0] == '\n')) {
1095 size = 0;
1096 array = NULL;
1097 goto out_replace_filter; /* clear filter */
1098 }
1099
1100 /* count user IDs in order to allocate sufficient memory */
1101 size = 1;
1102 residual = val;
1103 while ((residual = strchr(residual, ',')) != NULL) {
1104 residual++;
1105 size++;
1106 }
1107
1108 /* check if the specified list exceeds the filter limit */
1109 if (size > MAX_VMID_FILTER)
1110 return -ENOSPC;
1111
1112 array = kzalloc(size * 8, GFP_KERNEL);
1113 if (!array)
1114 return -ENOMEM;
1115
1116 count = size;
1117 residual = val;
1118 while (*residual && count) {
1119 residual = hvc_iucv_parse_filter(residual,
1120 array + ((size - count) * 8));
1121 if (IS_ERR(residual)) {
1122 err = PTR_ERR(residual);
1123 kfree(array);
1124 goto out_err;
1125 }
1126 count--;
1127 }
1128
1129out_replace_filter:
1130 write_lock_bh(&hvc_iucv_filter_lock);
1131 old_filter = hvc_iucv_filter;
1132 hvc_iucv_filter_size = size;
1133 hvc_iucv_filter = array;
1134 write_unlock_bh(&hvc_iucv_filter_lock);
1135 kfree(old_filter);
1136
1137 err = 0;
1138out_err:
1139 return err;
1140}
1141
1142/**
1143 * param_set_vmidfilter() - Set z/VM user ID filter parameter
1144 * @val: String consisting of a comma-separated list of z/VM user IDs
1145 * @kp: Kernel parameter pointing to hvc_iucv_filter array
1146 *
1147 * The function sets up the z/VM user ID filter specified as comma-separated
1148 * list of user IDs in @val.
1149 * Note: If it is called early in the boot process, @val is stored and
1150 * parsed later in hvc_iucv_init().
1151 */
1152static int param_set_vmidfilter(const char *val, const struct kernel_param *kp)
1153{
1154 int rc;
1155
1156 if (!MACHINE_IS_VM || !hvc_iucv_devices)
1157 return -ENODEV;
1158
1159 if (!val)
1160 return -EINVAL;
1161
1162 rc = 0;
1163 if (slab_is_available())
1164 rc = hvc_iucv_setup_filter(val);
1165 else
1166 hvc_iucv_filter_string = val; /* defer... */
1167 return rc;
1168}
1169
1170/**
1171 * param_get_vmidfilter() - Get z/VM user ID filter
1172 * @buffer: Buffer to store z/VM user ID filter,
1173 * (buffer size assumption PAGE_SIZE)
1174 * @kp: Kernel parameter pointing to the hvc_iucv_filter array
1175 *
1176 * The function stores the filter as a comma-separated list of z/VM user IDs
1177 * in @buffer. Typically, sysfs routines call this function for attr show.
1178 */
1179static int param_get_vmidfilter(char *buffer, const struct kernel_param *kp)
1180{
1181 int rc;
1182 size_t index, len;
1183 void *start, *end;
1184
1185 if (!MACHINE_IS_VM || !hvc_iucv_devices)
1186 return -ENODEV;
1187
1188 rc = 0;
1189 read_lock_bh(&hvc_iucv_filter_lock);
1190 for (index = 0; index < hvc_iucv_filter_size; index++) {
1191 start = hvc_iucv_filter + (8 * index);
1192 end = memchr(start, ' ', 8);
1193 len = (end) ? end - start : 8;
1194 memcpy(buffer + rc, start, len);
1195 rc += len;
1196 buffer[rc++] = ',';
1197 }
1198 read_unlock_bh(&hvc_iucv_filter_lock);
1199 if (rc)
1200 buffer[--rc] = '\0'; /* replace last comma and update rc */
1201 return rc;
1202}
1203
1204#define param_check_vmidfilter(name, p) __param_check(name, p, void)
1205
1206static struct kernel_param_ops param_ops_vmidfilter = {
1207 .set = param_set_vmidfilter,
1208 .get = param_get_vmidfilter,
1209};
1210
1211/**
1212 * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
1213 */
1214static int __init hvc_iucv_init(void)
1215{
1216 int rc;
1217 unsigned int i;
1218
1219 if (!hvc_iucv_devices)
1220 return -ENODEV;
1221
1222 if (!MACHINE_IS_VM) {
1223 pr_notice("The z/VM IUCV HVC device driver cannot "
1224 "be used without z/VM\n");
1225 rc = -ENODEV;
1226 goto out_error;
1227 }
1228
1229 if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
1230 pr_err("%lu is not a valid value for the hvc_iucv= "
1231 "kernel parameter\n", hvc_iucv_devices);
1232 rc = -EINVAL;
1233 goto out_error;
1234 }
1235
1236 /* register IUCV HVC device driver */
1237 rc = driver_register(&hvc_iucv_driver);
1238 if (rc)
1239 goto out_error;
1240
1241 /* parse hvc_iucv_allow string and create z/VM user ID filter list */
1242 if (hvc_iucv_filter_string) {
1243 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
1244 switch (rc) {
1245 case 0:
1246 break;
1247 case -ENOMEM:
1248 pr_err("Allocating memory failed with "
1249 "reason code=%d\n", 3);
1250 goto out_error;
1251 case -EINVAL:
1252 pr_err("hvc_iucv_allow= does not specify a valid "
1253 "z/VM user ID list\n");
1254 goto out_error;
1255 case -ENOSPC:
1256 pr_err("hvc_iucv_allow= specifies too many "
1257 "z/VM user IDs\n");
1258 goto out_error;
1259 default:
1260 goto out_error;
1261 }
1262 }
1263
1264 hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
1265 sizeof(struct iucv_tty_buffer),
1266 0, 0, NULL);
1267 if (!hvc_iucv_buffer_cache) {
1268 pr_err("Allocating memory failed with reason code=%d\n", 1);
1269 rc = -ENOMEM;
1270 goto out_error;
1271 }
1272
1273 hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
1274 hvc_iucv_buffer_cache);
1275 if (!hvc_iucv_mempool) {
1276 pr_err("Allocating memory failed with reason code=%d\n", 2);
1277 kmem_cache_destroy(hvc_iucv_buffer_cache);
1278 rc = -ENOMEM;
1279 goto out_error;
1280 }
1281
1282 /* register the first terminal device as console
1283 * (must be done before allocating hvc terminal devices) */
1284 rc = hvc_instantiate(HVC_IUCV_MAGIC, IUCV_HVC_CON_IDX, &hvc_iucv_ops);
1285 if (rc) {
1286 pr_err("Registering HVC terminal device as "
1287 "Linux console failed\n");
1288 goto out_error_memory;
1289 }
1290
1291 /* allocate hvc_iucv_private structs */
1292 for (i = 0; i < hvc_iucv_devices; i++) {
1293 rc = hvc_iucv_alloc(i, (i == IUCV_HVC_CON_IDX) ? 1 : 0);
1294 if (rc) {
1295 pr_err("Creating a new HVC terminal device "
1296 "failed with error code=%d\n", rc);
1297 goto out_error_hvc;
1298 }
1299 }
1300
1301 /* register IUCV callback handler */
1302 rc = iucv_register(&hvc_iucv_handler, 0);
1303 if (rc) {
1304 pr_err("Registering IUCV handlers failed with error code=%d\n",
1305 rc);
1306 goto out_error_hvc;
1307 }
1308
1309 return 0;
1310
1311out_error_hvc:
1312 for (i = 0; i < hvc_iucv_devices; i++)
1313 if (hvc_iucv_table[i])
1314 hvc_iucv_destroy(hvc_iucv_table[i]);
1315out_error_memory:
1316 mempool_destroy(hvc_iucv_mempool);
1317 kmem_cache_destroy(hvc_iucv_buffer_cache);
1318out_error:
1319 if (hvc_iucv_filter)
1320 kfree(hvc_iucv_filter);
1321 hvc_iucv_devices = 0; /* ensure that we do not provide any device */
1322 return rc;
1323}
1324
1325/**
1326 * hvc_iucv_config() - Parsing of hvc_iucv= kernel command line parameter
1327 * @val: Parameter value (numeric)
1328 */
1329static int __init hvc_iucv_config(char *val)
1330{
1331 return strict_strtoul(val, 10, &hvc_iucv_devices);
1332}
1333
1334
1335device_initcall(hvc_iucv_init);
1336__setup("hvc_iucv=", hvc_iucv_config);
1337core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c
new file mode 100644
index 000000000000..61c4a61558d9
--- /dev/null
+++ b/drivers/tty/hvc/hvc_rtas.c
@@ -0,0 +1,133 @@
1/*
2 * IBM RTAS driver interface to hvc_console.c
3 *
4 * (C) Copyright IBM Corporation 2001-2005
5 * (C) Copyright Red Hat, Inc. 2005
6 *
7 * Author(s): Maximino Augilar <IBM STI Design Center>
8 * : Ryan S. Arnold <rsa@us.ibm.com>
9 * : Utz Bacher <utz.bacher@de.ibm.com>
10 * : David Woodhouse <dwmw2@infradead.org>
11 *
12 * inspired by drivers/char/hvc_console.c
13 * written by Anton Blanchard and Paul Mackerras
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/console.h>
31#include <linux/delay.h>
32#include <linux/err.h>
33#include <linux/init.h>
34#include <linux/moduleparam.h>
35#include <linux/types.h>
36
37#include <asm/irq.h>
38#include <asm/rtas.h>
39#include "hvc_console.h"
40
41#define hvc_rtas_cookie 0x67781e15
42struct hvc_struct *hvc_rtas_dev;
43
44static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE;
45static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE;
46
47static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf,
48 int count)
49{
50 int i;
51
52 for (i = 0; i < count; i++) {
53 if (rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[i]))
54 break;
55 }
56
57 return i;
58}
59
60static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count)
61{
62 int i, c;
63
64 for (i = 0; i < count; i++) {
65 if (rtas_call(rtascons_get_char_token, 0, 2, &c))
66 break;
67
68 buf[i] = c;
69 }
70
71 return i;
72}
73
74static const struct hv_ops hvc_rtas_get_put_ops = {
75 .get_chars = hvc_rtas_read_console,
76 .put_chars = hvc_rtas_write_console,
77};
78
79static int __init hvc_rtas_init(void)
80{
81 struct hvc_struct *hp;
82
83 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
84 rtascons_put_char_token = rtas_token("put-term-char");
85 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
86 return -EIO;
87
88 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
89 rtascons_get_char_token = rtas_token("get-term-char");
90 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
91 return -EIO;
92
93 BUG_ON(hvc_rtas_dev);
94
95 /* Allocate an hvc_struct for the console device we instantiated
96 * earlier. Save off hp so that we can return it on exit */
97 hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16);
98 if (IS_ERR(hp))
99 return PTR_ERR(hp);
100
101 hvc_rtas_dev = hp;
102
103 return 0;
104}
105module_init(hvc_rtas_init);
106
107/* This will tear down the tty portion of the driver */
108static void __exit hvc_rtas_exit(void)
109{
110 /* Really the fun isn't over until the worker thread breaks down and
111 * the tty cleans up */
112 if (hvc_rtas_dev)
113 hvc_remove(hvc_rtas_dev);
114}
115module_exit(hvc_rtas_exit);
116
117/* This will happen prior to module init. There is no tty at this time? */
118static int __init hvc_rtas_console_init(void)
119{
120 rtascons_put_char_token = rtas_token("put-term-char");
121 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
122 return -EIO;
123
124 rtascons_get_char_token = rtas_token("get-term-char");
125 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
126 return -EIO;
127
128 hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops);
129 add_preferred_console("hvc", 0, NULL);
130
131 return 0;
132}
133console_initcall(hvc_rtas_console_init);
diff --git a/drivers/tty/hvc/hvc_tile.c b/drivers/tty/hvc/hvc_tile.c
new file mode 100644
index 000000000000..7a84a0595477
--- /dev/null
+++ b/drivers/tty/hvc/hvc_tile.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 *
14 * Tilera TILE Processor hypervisor console
15 */
16
17#include <linux/console.h>
18#include <linux/delay.h>
19#include <linux/err.h>
20#include <linux/init.h>
21#include <linux/moduleparam.h>
22#include <linux/types.h>
23
24#include <hv/hypervisor.h>
25
26#include "hvc_console.h"
27
28static int hvc_tile_put_chars(uint32_t vt, const char *buf, int count)
29{
30 return hv_console_write((HV_VirtAddr)buf, count);
31}
32
33static int hvc_tile_get_chars(uint32_t vt, char *buf, int count)
34{
35 int i, c;
36
37 for (i = 0; i < count; ++i) {
38 c = hv_console_read_if_ready();
39 if (c < 0)
40 break;
41 buf[i] = c;
42 }
43
44 return i;
45}
46
47static const struct hv_ops hvc_tile_get_put_ops = {
48 .get_chars = hvc_tile_get_chars,
49 .put_chars = hvc_tile_put_chars,
50};
51
52static int __init hvc_tile_console_init(void)
53{
54 extern void disable_early_printk(void);
55 hvc_instantiate(0, 0, &hvc_tile_get_put_ops);
56 add_preferred_console("hvc", 0, NULL);
57 disable_early_printk();
58 return 0;
59}
60console_initcall(hvc_tile_console_init);
61
62static int __init hvc_tile_init(void)
63{
64 struct hvc_struct *s;
65 s = hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128);
66 return IS_ERR(s) ? PTR_ERR(s) : 0;
67}
68device_initcall(hvc_tile_init);
diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c
new file mode 100644
index 000000000000..b0957e61a7be
--- /dev/null
+++ b/drivers/tty/hvc/hvc_udbg.c
@@ -0,0 +1,96 @@
1/*
2 * udbg interface to hvc_console.c
3 *
4 * (C) Copyright David Gibson, IBM Corporation 2008.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/err.h>
24#include <linux/init.h>
25#include <linux/moduleparam.h>
26#include <linux/types.h>
27#include <linux/irq.h>
28
29#include <asm/udbg.h>
30
31#include "hvc_console.h"
32
33struct hvc_struct *hvc_udbg_dev;
34
35static int hvc_udbg_put(uint32_t vtermno, const char *buf, int count)
36{
37 int i;
38
39 for (i = 0; i < count; i++)
40 udbg_putc(buf[i]);
41
42 return i;
43}
44
45static int hvc_udbg_get(uint32_t vtermno, char *buf, int count)
46{
47 int i, c;
48
49 if (!udbg_getc_poll)
50 return 0;
51
52 for (i = 0; i < count; i++) {
53 if ((c = udbg_getc_poll()) == -1)
54 break;
55 buf[i] = c;
56 }
57
58 return i;
59}
60
61static const struct hv_ops hvc_udbg_ops = {
62 .get_chars = hvc_udbg_get,
63 .put_chars = hvc_udbg_put,
64};
65
66static int __init hvc_udbg_init(void)
67{
68 struct hvc_struct *hp;
69
70 BUG_ON(hvc_udbg_dev);
71
72 hp = hvc_alloc(0, NO_IRQ, &hvc_udbg_ops, 16);
73 if (IS_ERR(hp))
74 return PTR_ERR(hp);
75
76 hvc_udbg_dev = hp;
77
78 return 0;
79}
80module_init(hvc_udbg_init);
81
82static void __exit hvc_udbg_exit(void)
83{
84 if (hvc_udbg_dev)
85 hvc_remove(hvc_udbg_dev);
86}
87module_exit(hvc_udbg_exit);
88
89static int __init hvc_udbg_console_init(void)
90{
91 hvc_instantiate(0, 0, &hvc_udbg_ops);
92 add_preferred_console("hvc", 0, NULL);
93
94 return 0;
95}
96console_initcall(hvc_udbg_console_init);
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
new file mode 100644
index 000000000000..e6eea1485244
--- /dev/null
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -0,0 +1,173 @@
1/*
2 * vio driver interface to hvc_console.c
3 *
4 * This code was moved here to allow the remaining code to be reused as a
5 * generic polling mode with semi-reliable transport driver core to the
6 * console and tty subsystems.
7 *
8 *
9 * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
10 * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
11 * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
12 * Copyright (C) 2004 IBM Corporation
13 *
14 * Additional Author(s):
15 * Ryan S. Arnold <rsa@us.ibm.com>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32#include <linux/types.h>
33#include <linux/init.h>
34
35#include <asm/hvconsole.h>
36#include <asm/vio.h>
37#include <asm/prom.h>
38#include <asm/firmware.h>
39
40#include "hvc_console.h"
41
42static const char hvc_driver_name[] = "hvc_console";
43
44static struct vio_device_id hvc_driver_table[] __devinitdata = {
45 {"serial", "hvterm1"},
46 { "", "" }
47};
48MODULE_DEVICE_TABLE(vio, hvc_driver_table);
49
50static int filtered_get_chars(uint32_t vtermno, char *buf, int count)
51{
52 unsigned long got;
53 int i;
54
55 /*
56 * Vio firmware will read up to SIZE_VIO_GET_CHARS at its own discretion
57 * so we play safe and avoid the situation where got > count which could
58 * overload the flip buffer.
59 */
60 if (count < SIZE_VIO_GET_CHARS)
61 return -EAGAIN;
62
63 got = hvc_get_chars(vtermno, buf, count);
64
65 /*
66 * Work around a HV bug where it gives us a null
67 * after every \r. -- paulus
68 */
69 for (i = 1; i < got; ++i) {
70 if (buf[i] == 0 && buf[i-1] == '\r') {
71 --got;
72 if (i < got)
73 memmove(&buf[i], &buf[i+1],
74 got - i);
75 }
76 }
77 return got;
78}
79
80static const struct hv_ops hvc_get_put_ops = {
81 .get_chars = filtered_get_chars,
82 .put_chars = hvc_put_chars,
83 .notifier_add = notifier_add_irq,
84 .notifier_del = notifier_del_irq,
85 .notifier_hangup = notifier_hangup_irq,
86};
87
88static int __devinit hvc_vio_probe(struct vio_dev *vdev,
89 const struct vio_device_id *id)
90{
91 struct hvc_struct *hp;
92
93 /* probed with invalid parameters. */
94 if (!vdev || !id)
95 return -EPERM;
96
97 hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops,
98 MAX_VIO_PUT_CHARS);
99 if (IS_ERR(hp))
100 return PTR_ERR(hp);
101 dev_set_drvdata(&vdev->dev, hp);
102
103 return 0;
104}
105
106static int __devexit hvc_vio_remove(struct vio_dev *vdev)
107{
108 struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
109
110 return hvc_remove(hp);
111}
112
113static struct vio_driver hvc_vio_driver = {
114 .id_table = hvc_driver_table,
115 .probe = hvc_vio_probe,
116 .remove = __devexit_p(hvc_vio_remove),
117 .driver = {
118 .name = hvc_driver_name,
119 .owner = THIS_MODULE,
120 }
121};
122
123static int __init hvc_vio_init(void)
124{
125 int rc;
126
127 if (firmware_has_feature(FW_FEATURE_ISERIES))
128 return -EIO;
129
130 /* Register as a vio device to receive callbacks */
131 rc = vio_register_driver(&hvc_vio_driver);
132
133 return rc;
134}
135module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
136
137static void __exit hvc_vio_exit(void)
138{
139 vio_unregister_driver(&hvc_vio_driver);
140}
141module_exit(hvc_vio_exit);
142
143/* the device tree order defines our numbering */
144static int hvc_find_vtys(void)
145{
146 struct device_node *vty;
147 int num_found = 0;
148
149 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
150 vty = of_find_node_by_name(vty, "vty")) {
151 const uint32_t *vtermno;
152
153 /* We have statically defined space for only a certain number
154 * of console adapters.
155 */
156 if (num_found >= MAX_NR_HVC_CONSOLES) {
157 of_node_put(vty);
158 break;
159 }
160
161 vtermno = of_get_property(vty, "reg", NULL);
162 if (!vtermno)
163 continue;
164
165 if (of_device_is_compatible(vty, "hvterm1")) {
166 hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
167 ++num_found;
168 }
169 }
170
171 return num_found;
172}
173console_initcall(hvc_find_vtys);
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
new file mode 100644
index 000000000000..52fdf60bdbe2
--- /dev/null
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -0,0 +1,273 @@
1/*
2 * xen console driver interface to hvc_console.c
3 *
4 * (c) 2007 Gerd Hoffmann <kraxel@suse.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/err.h>
24#include <linux/init.h>
25#include <linux/types.h>
26
27#include <asm/xen/hypervisor.h>
28
29#include <xen/xen.h>
30#include <xen/page.h>
31#include <xen/events.h>
32#include <xen/interface/io/console.h>
33#include <xen/hvc-console.h>
34
35#include "hvc_console.h"
36
37#define HVC_COOKIE 0x58656e /* "Xen" in hex */
38
39static struct hvc_struct *hvc;
40static int xencons_irq;
41
42/* ------------------------------------------------------------------ */
43
44static unsigned long console_pfn = ~0ul;
45
46static inline struct xencons_interface *xencons_interface(void)
47{
48 if (console_pfn == ~0ul)
49 return mfn_to_virt(xen_start_info->console.domU.mfn);
50 else
51 return __va(console_pfn << PAGE_SHIFT);
52}
53
54static inline void notify_daemon(void)
55{
56 /* Use evtchn: this is called early, before irq is set up. */
57 notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
58}
59
60static int __write_console(const char *data, int len)
61{
62 struct xencons_interface *intf = xencons_interface();
63 XENCONS_RING_IDX cons, prod;
64 int sent = 0;
65
66 cons = intf->out_cons;
67 prod = intf->out_prod;
68 mb(); /* update queue values before going on */
69 BUG_ON((prod - cons) > sizeof(intf->out));
70
71 while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
72 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
73
74 wmb(); /* write ring before updating pointer */
75 intf->out_prod = prod;
76
77 if (sent)
78 notify_daemon();
79 return sent;
80}
81
82static int domU_write_console(uint32_t vtermno, const char *data, int len)
83{
84 int ret = len;
85
86 /*
87 * Make sure the whole buffer is emitted, polling if
88 * necessary. We don't ever want to rely on the hvc daemon
89 * because the most interesting console output is when the
90 * kernel is crippled.
91 */
92 while (len) {
93 int sent = __write_console(data, len);
94
95 data += sent;
96 len -= sent;
97
98 if (unlikely(len))
99 HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
100 }
101
102 return ret;
103}
104
105static int domU_read_console(uint32_t vtermno, char *buf, int len)
106{
107 struct xencons_interface *intf = xencons_interface();
108 XENCONS_RING_IDX cons, prod;
109 int recv = 0;
110
111 cons = intf->in_cons;
112 prod = intf->in_prod;
113 mb(); /* get pointers before reading ring */
114 BUG_ON((prod - cons) > sizeof(intf->in));
115
116 while (cons != prod && recv < len)
117 buf[recv++] = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
118
119 mb(); /* read ring before consuming */
120 intf->in_cons = cons;
121
122 notify_daemon();
123 return recv;
124}
125
126static struct hv_ops domU_hvc_ops = {
127 .get_chars = domU_read_console,
128 .put_chars = domU_write_console,
129 .notifier_add = notifier_add_irq,
130 .notifier_del = notifier_del_irq,
131 .notifier_hangup = notifier_hangup_irq,
132};
133
134static int dom0_read_console(uint32_t vtermno, char *buf, int len)
135{
136 return HYPERVISOR_console_io(CONSOLEIO_read, len, buf);
137}
138
139/*
140 * Either for a dom0 to write to the system console, or a domU with a
141 * debug version of Xen
142 */
143static int dom0_write_console(uint32_t vtermno, const char *str, int len)
144{
145 int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
146 if (rc < 0)
147 return 0;
148
149 return len;
150}
151
152static struct hv_ops dom0_hvc_ops = {
153 .get_chars = dom0_read_console,
154 .put_chars = dom0_write_console,
155 .notifier_add = notifier_add_irq,
156 .notifier_del = notifier_del_irq,
157 .notifier_hangup = notifier_hangup_irq,
158};
159
160static int __init xen_hvc_init(void)
161{
162 struct hvc_struct *hp;
163 struct hv_ops *ops;
164
165 if (!xen_pv_domain())
166 return -ENODEV;
167
168 if (xen_initial_domain()) {
169 ops = &dom0_hvc_ops;
170 xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
171 } else {
172 if (!xen_start_info->console.domU.evtchn)
173 return -ENODEV;
174
175 ops = &domU_hvc_ops;
176 xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
177 }
178 if (xencons_irq < 0)
179 xencons_irq = 0; /* NO_IRQ */
180 else
181 irq_set_noprobe(xencons_irq);
182
183 hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256);
184 if (IS_ERR(hp))
185 return PTR_ERR(hp);
186
187 hvc = hp;
188
189 console_pfn = mfn_to_pfn(xen_start_info->console.domU.mfn);
190
191 return 0;
192}
193
194void xen_console_resume(void)
195{
196 if (xencons_irq)
197 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
198}
199
200static void __exit xen_hvc_fini(void)
201{
202 if (hvc)
203 hvc_remove(hvc);
204}
205
206static int xen_cons_init(void)
207{
208 struct hv_ops *ops;
209
210 if (!xen_pv_domain())
211 return 0;
212
213 if (xen_initial_domain())
214 ops = &dom0_hvc_ops;
215 else
216 ops = &domU_hvc_ops;
217
218 hvc_instantiate(HVC_COOKIE, 0, ops);
219 return 0;
220}
221
222module_init(xen_hvc_init);
223module_exit(xen_hvc_fini);
224console_initcall(xen_cons_init);
225
226#ifdef CONFIG_EARLY_PRINTK
227static void xenboot_write_console(struct console *console, const char *string,
228 unsigned len)
229{
230 unsigned int linelen, off = 0;
231 const char *pos;
232
233 dom0_write_console(0, string, len);
234
235 if (xen_initial_domain())
236 return;
237
238 domU_write_console(0, "(early) ", 8);
239 while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
240 linelen = pos-string+off;
241 if (off + linelen > len)
242 break;
243 domU_write_console(0, string+off, linelen);
244 domU_write_console(0, "\r\n", 2);
245 off += linelen + 1;
246 }
247 if (off < len)
248 domU_write_console(0, string+off, len-off);
249}
250
251struct console xenboot_console = {
252 .name = "xenboot",
253 .write = xenboot_write_console,
254 .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
255};
256#endif /* CONFIG_EARLY_PRINTK */
257
258void xen_raw_console_write(const char *str)
259{
260 dom0_write_console(0, str, strlen(str));
261}
262
263void xen_raw_printk(const char *fmt, ...)
264{
265 static char buf[512];
266 va_list ap;
267
268 va_start(ap, fmt);
269 vsnprintf(buf, sizeof(buf), fmt, ap);
270 va_end(ap);
271
272 xen_raw_console_write(buf);
273}
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
new file mode 100644
index 000000000000..4c8b66546930
--- /dev/null
+++ b/drivers/tty/hvc/hvcs.c
@@ -0,0 +1,1616 @@
1/*
2 * IBM eServer Hypervisor Virtual Console Server Device Driver
3 * Copyright (C) 2003, 2004 IBM Corp.
4 * Ryan S. Arnold (rsa@us.ibm.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Author(s) : Ryan S. Arnold <rsa@us.ibm.com>
21 *
22 * This is the device driver for the IBM Hypervisor Virtual Console Server,
23 * "hvcs". The IBM hvcs provides a tty driver interface to allow Linux
24 * user space applications access to the system consoles of logically
25 * partitioned operating systems, e.g. Linux, running on the same partitioned
26 * Power5 ppc64 system. Physical hardware consoles per partition are not
27 * practical on this hardware so system consoles are accessed by this driver
28 * using inter-partition firmware interfaces to virtual terminal devices.
29 *
30 * A vty is known to the HMC as a "virtual serial server adapter". It is a
31 * virtual terminal device that is created by firmware upon partition creation
32 * to act as a partitioned OS's console device.
33 *
34 * Firmware dynamically (via hotplug) exposes vty-servers to a running ppc64
35 * Linux system upon their creation by the HMC or their exposure during boot.
36 * The non-user interactive backend of this driver is implemented as a vio
37 * device driver so that it can receive notification of vty-server lifetimes
38 * after it registers with the vio bus to handle vty-server probe and remove
39 * callbacks.
40 *
41 * Many vty-servers can be configured to connect to one vty, but a vty can
42 * only be actively connected to by a single vty-server, in any manner, at one
43 * time. If the HMC is currently hosting the console for a target Linux
44 * partition; attempts to open the tty device to the partition's console using
45 * the hvcs on any partition will return -EBUSY with every open attempt until
46 * the HMC frees the connection between its vty-server and the desired
47 * partition's vty device. Conversely, a vty-server may only be connected to
48 * a single vty at one time even though it may have several configured vty
49 * partner possibilities.
50 *
51 * Firmware does not provide notification of vty partner changes to this
52 * driver. This means that an HMC Super Admin may add or remove partner vtys
53 * from a vty-server's partner list but the changes will not be signaled to
54 * the vty-server. Firmware only notifies the driver when a vty-server is
55 * added or removed from the system. To compensate for this deficiency, this
56 * driver implements a sysfs update attribute which provides a method for
57 * rescanning partner information upon a user's request.
58 *
59 * Each vty-server, prior to being exposed to this driver is reference counted
60 * using the 2.6 Linux kernel kref construct.
61 *
62 * For direction on installation and usage of this driver please reference
63 * Documentation/powerpc/hvcs.txt.
64 */
65
66#include <linux/device.h>
67#include <linux/init.h>
68#include <linux/interrupt.h>
69#include <linux/kernel.h>
70#include <linux/kref.h>
71#include <linux/kthread.h>
72#include <linux/list.h>
73#include <linux/major.h>
74#include <linux/module.h>
75#include <linux/moduleparam.h>
76#include <linux/sched.h>
77#include <linux/slab.h>
78#include <linux/spinlock.h>
79#include <linux/stat.h>
80#include <linux/tty.h>
81#include <linux/tty_flip.h>
82#include <asm/hvconsole.h>
83#include <asm/hvcserver.h>
84#include <asm/uaccess.h>
85#include <asm/vio.h>
86
87/*
88 * 1.3.0 -> 1.3.1 In hvcs_open memset(..,0x00,..) instead of memset(..,0x3F,00).
89 * Removed braces around single statements following conditionals. Removed '=
90 * 0' after static int declarations since these default to zero. Removed
91 * list_for_each_safe() and replaced with list_for_each_entry() in
92 * hvcs_get_by_index(). The 'safe' version is un-needed now that the driver is
93 * using spinlocks. Changed spin_lock_irqsave() to spin_lock() when locking
94 * hvcs_structs_lock and hvcs_pi_lock since these are not touched in an int
95 * handler. Initialized hvcs_structs_lock and hvcs_pi_lock to
96 * SPIN_LOCK_UNLOCKED at declaration time rather than in hvcs_module_init().
97 * Added spin_lock around list_del() in destroy_hvcs_struct() to protect the
98 * list traversals from a deletion. Removed '= NULL' from pointer declaration
99 * statements since they are initialized NULL by default. Removed wmb()
100 * instances from hvcs_try_write(). They probably aren't needed with locking in
101 * place. Added check and cleanup for hvcs_pi_buff = kmalloc() in
102 * hvcs_module_init(). Exposed hvcs_struct.index via a sysfs attribute so that
103 * the coupling between /dev/hvcs* and a vty-server can be automatically
104 * determined. Moved kobject_put() in hvcs_open outside of the
105 * spin_unlock_irqrestore().
106 *
107 * 1.3.1 -> 1.3.2 Changed method for determining hvcs_struct->index and had it
108 * align with how the tty layer always assigns the lowest index available. This
109 * change resulted in a list of ints that denotes which indexes are available.
110 * Device additions and removals use the new hvcs_get_index() and
111 * hvcs_return_index() helper functions. The list is created with
112 * hvsc_alloc_index_list() and it is destroyed with hvcs_free_index_list().
113 * Without these fixes hotplug vty-server adapter support goes crazy with this
114 * driver if the user removes a vty-server adapter. Moved free_irq() outside of
115 * the hvcs_final_close() function in order to get it out of the spinlock.
116 * Rearranged hvcs_close(). Cleaned up some printks and did some housekeeping
117 * on the changelog. Removed local CLC_LENGTH and used HVCS_CLC_LENGTH from
118 * arch/powerepc/include/asm/hvcserver.h
119 *
120 * 1.3.2 -> 1.3.3 Replaced yield() in hvcs_close() with tty_wait_until_sent() to
121 * prevent possible lockup with realtime scheduling as similarly pointed out by
122 * akpm in hvc_console. Changed resulted in the removal of hvcs_final_close()
123 * to reorder cleanup operations and prevent discarding of pending data during
124 * an hvcs_close(). Removed spinlock protection of hvcs_struct data members in
125 * hvcs_write_room() and hvcs_chars_in_buffer() because they aren't needed.
126 */
127
128#define HVCS_DRIVER_VERSION "1.3.3"
129
130MODULE_AUTHOR("Ryan S. Arnold <rsa@us.ibm.com>");
131MODULE_DESCRIPTION("IBM hvcs (Hypervisor Virtual Console Server) Driver");
132MODULE_LICENSE("GPL");
133MODULE_VERSION(HVCS_DRIVER_VERSION);
134
135/*
136 * Wait this long per iteration while trying to push buffered data to the
137 * hypervisor before allowing the tty to complete a close operation.
138 */
139#define HVCS_CLOSE_WAIT (HZ/100) /* 1/10 of a second */
140
141/*
142 * Since the Linux TTY code does not currently (2-04-2004) support dynamic
143 * addition of tty derived devices and we shouldn't allocate thousands of
144 * tty_device pointers when the number of vty-server & vty partner connections
145 * will most often be much lower than this, we'll arbitrarily allocate
146 * HVCS_DEFAULT_SERVER_ADAPTERS tty_structs and cdev's by default when we
147 * register the tty_driver. This can be overridden using an insmod parameter.
148 */
149#define HVCS_DEFAULT_SERVER_ADAPTERS 64
150
151/*
152 * The user can't insmod with more than HVCS_MAX_SERVER_ADAPTERS hvcs device
153 * nodes as a sanity check. Theoretically there can be over 1 Billion
154 * vty-server & vty partner connections.
155 */
156#define HVCS_MAX_SERVER_ADAPTERS 1024
157
158/*
159 * We let Linux assign us a major number and we start the minors at zero. There
160 * is no intuitive mapping between minor number and the target vty-server
161 * adapter except that each new vty-server adapter is always assigned to the
162 * smallest minor number available.
163 */
164#define HVCS_MINOR_START 0
165
166/*
167 * The hcall interface involves putting 8 chars into each of two registers.
168 * We load up those 2 registers (in arch/powerpc/platforms/pseries/hvconsole.c)
169 * by casting char[16] to long[2]. It would work without __ALIGNED__, but a
170 * little (tiny) bit slower because an unaligned load is slower than aligned
171 * load.
172 */
173#define __ALIGNED__ __attribute__((__aligned__(8)))
174
175/*
176 * How much data can firmware send with each hvc_put_chars()? Maybe this
177 * should be moved into an architecture specific area.
178 */
179#define HVCS_BUFF_LEN 16
180
181/*
182 * This is the maximum amount of data we'll let the user send us (hvcs_write) at
183 * once in a chunk as a sanity check.
184 */
185#define HVCS_MAX_FROM_USER 4096
186
187/*
188 * Be careful when adding flags to this line discipline. Don't add anything
189 * that will cause echoing or we'll go into recursive loop echoing chars back
190 * and forth with the console drivers.
191 */
192static struct ktermios hvcs_tty_termios = {
193 .c_iflag = IGNBRK | IGNPAR,
194 .c_oflag = OPOST,
195 .c_cflag = B38400 | CS8 | CREAD | HUPCL,
196 .c_cc = INIT_C_CC,
197 .c_ispeed = 38400,
198 .c_ospeed = 38400
199};
200
201/*
202 * This value is used to take the place of a command line parameter when the
203 * module is inserted. It starts as -1 and stays as such if the user doesn't
204 * specify a module insmod parameter. If they DO specify one then it is set to
205 * the value of the integer passed in.
206 */
207static int hvcs_parm_num_devs = -1;
208module_param(hvcs_parm_num_devs, int, 0);
209
210static const char hvcs_driver_name[] = "hvcs";
211static const char hvcs_device_node[] = "hvcs";
212static const char hvcs_driver_string[]
213 = "IBM hvcs (Hypervisor Virtual Console Server) Driver";
214
215/* Status of partner info rescan triggered via sysfs. */
216static int hvcs_rescan_status;
217
218static struct tty_driver *hvcs_tty_driver;
219
220/*
221 * In order to be somewhat sane this driver always associates the hvcs_struct
222 * index element with the numerically equal tty->index. This means that a
223 * hotplugged vty-server adapter will always map to the lowest index valued
224 * device node. If vty-servers were hotplug removed from the system and then
225 * new ones added the new vty-server may have the largest slot number of all
226 * the vty-server adapters in the partition but it may have the lowest dev node
227 * index of all the adapters due to the hole left by the hotplug removed
228 * adapter. There are a set of functions provided to get the lowest index for
229 * a new device as well as return the index to the list. This list is allocated
230 * with a number of elements equal to the number of device nodes requested when
231 * the module was inserted.
232 */
233static int *hvcs_index_list;
234
235/*
236 * How large is the list? This is kept for traversal since the list is
237 * dynamically created.
238 */
239static int hvcs_index_count;
240
241/*
242 * Used by the khvcsd to pick up I/O operations when the kernel_thread is
243 * already awake but potentially shifted to TASK_INTERRUPTIBLE state.
244 */
245static int hvcs_kicked;
246
247/*
248 * Use by the kthread construct for task operations like waking the sleeping
249 * thread and stopping the kthread.
250 */
251static struct task_struct *hvcs_task;
252
253/*
254 * We allocate this for the use of all of the hvcs_structs when they fetch
255 * partner info.
256 */
257static unsigned long *hvcs_pi_buff;
258
259/* Only allow one hvcs_struct to use the hvcs_pi_buff at a time. */
260static DEFINE_SPINLOCK(hvcs_pi_lock);
261
262/* One vty-server per hvcs_struct */
263struct hvcs_struct {
264 spinlock_t lock;
265
266 /*
267 * This index identifies this hvcs device as the complement to a
268 * specific tty index.
269 */
270 unsigned int index;
271
272 struct tty_struct *tty;
273 int open_count;
274
275 /*
276 * Used to tell the driver kernel_thread what operations need to take
277 * place upon this hvcs_struct instance.
278 */
279 int todo_mask;
280
281 /*
282 * This buffer is required so that when hvcs_write_room() reports that
283 * it can send HVCS_BUFF_LEN characters that it will buffer the full
284 * HVCS_BUFF_LEN characters if need be. This is essential for opost
285 * writes since they do not do high level buffering and expect to be
286 * able to send what the driver commits to sending buffering
287 * [e.g. tab to space conversions in n_tty.c opost()].
288 */
289 char buffer[HVCS_BUFF_LEN];
290 int chars_in_buffer;
291
292 /*
293 * Any variable below the kref is valid before a tty is connected and
294 * stays valid after the tty is disconnected. These shouldn't be
295 * whacked until the kobject refcount reaches zero though some entries
296 * may be changed via sysfs initiatives.
297 */
298 struct kref kref; /* ref count & hvcs_struct lifetime */
299 int connected; /* is the vty-server currently connected to a vty? */
300 uint32_t p_unit_address; /* partner unit address */
301 uint32_t p_partition_ID; /* partner partition ID */
302 char p_location_code[HVCS_CLC_LENGTH + 1]; /* CLC + Null Term */
303 struct list_head next; /* list management */
304 struct vio_dev *vdev;
305};
306
307/* Required to back map a kref to its containing object */
308#define from_kref(k) container_of(k, struct hvcs_struct, kref)
309
310static LIST_HEAD(hvcs_structs);
311static DEFINE_SPINLOCK(hvcs_structs_lock);
312static DEFINE_MUTEX(hvcs_init_mutex);
313
314static void hvcs_unthrottle(struct tty_struct *tty);
315static void hvcs_throttle(struct tty_struct *tty);
316static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance);
317
318static int hvcs_write(struct tty_struct *tty,
319 const unsigned char *buf, int count);
320static int hvcs_write_room(struct tty_struct *tty);
321static int hvcs_chars_in_buffer(struct tty_struct *tty);
322
323static int hvcs_has_pi(struct hvcs_struct *hvcsd);
324static void hvcs_set_pi(struct hvcs_partner_info *pi,
325 struct hvcs_struct *hvcsd);
326static int hvcs_get_pi(struct hvcs_struct *hvcsd);
327static int hvcs_rescan_devices_list(void);
328
329static int hvcs_partner_connect(struct hvcs_struct *hvcsd);
330static void hvcs_partner_free(struct hvcs_struct *hvcsd);
331
332static int hvcs_enable_device(struct hvcs_struct *hvcsd,
333 uint32_t unit_address, unsigned int irq, struct vio_dev *dev);
334
335static int hvcs_open(struct tty_struct *tty, struct file *filp);
336static void hvcs_close(struct tty_struct *tty, struct file *filp);
337static void hvcs_hangup(struct tty_struct * tty);
338
339static int __devinit hvcs_probe(struct vio_dev *dev,
340 const struct vio_device_id *id);
341static int __devexit hvcs_remove(struct vio_dev *dev);
342static int __init hvcs_module_init(void);
343static void __exit hvcs_module_exit(void);
344static int __devinit hvcs_initialize(void);
345
346#define HVCS_SCHED_READ 0x00000001
347#define HVCS_QUICK_READ 0x00000002
348#define HVCS_TRY_WRITE 0x00000004
349#define HVCS_READ_MASK (HVCS_SCHED_READ | HVCS_QUICK_READ)
350
351static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod)
352{
353 return dev_get_drvdata(&viod->dev);
354}
355/* The sysfs interface for the driver and devices */
356
357static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf)
358{
359 struct vio_dev *viod = to_vio_dev(dev);
360 struct hvcs_struct *hvcsd = from_vio_dev(viod);
361 unsigned long flags;
362 int retval;
363
364 spin_lock_irqsave(&hvcsd->lock, flags);
365 retval = sprintf(buf, "%X\n", hvcsd->p_unit_address);
366 spin_unlock_irqrestore(&hvcsd->lock, flags);
367 return retval;
368}
369static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL);
370
371static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf)
372{
373 struct vio_dev *viod = to_vio_dev(dev);
374 struct hvcs_struct *hvcsd = from_vio_dev(viod);
375 unsigned long flags;
376 int retval;
377
378 spin_lock_irqsave(&hvcsd->lock, flags);
379 retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]);
380 spin_unlock_irqrestore(&hvcsd->lock, flags);
381 return retval;
382}
383static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL);
384
385static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf,
386 size_t count)
387{
388 /*
389 * Don't need this feature at the present time because firmware doesn't
390 * yet support multiple partners.
391 */
392 printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n");
393 return -EPERM;
394}
395
396static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf)
397{
398 struct vio_dev *viod = to_vio_dev(dev);
399 struct hvcs_struct *hvcsd = from_vio_dev(viod);
400 unsigned long flags;
401 int retval;
402
403 spin_lock_irqsave(&hvcsd->lock, flags);
404 retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]);
405 spin_unlock_irqrestore(&hvcsd->lock, flags);
406 return retval;
407}
408
409static DEVICE_ATTR(current_vty,
410 S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store);
411
412static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf,
413 size_t count)
414{
415 struct vio_dev *viod = to_vio_dev(dev);
416 struct hvcs_struct *hvcsd = from_vio_dev(viod);
417 unsigned long flags;
418
419 /* writing a '0' to this sysfs entry will result in the disconnect. */
420 if (simple_strtol(buf, NULL, 0) != 0)
421 return -EINVAL;
422
423 spin_lock_irqsave(&hvcsd->lock, flags);
424
425 if (hvcsd->open_count > 0) {
426 spin_unlock_irqrestore(&hvcsd->lock, flags);
427 printk(KERN_INFO "HVCS: vterm state unchanged. "
428 "The hvcs device node is still in use.\n");
429 return -EPERM;
430 }
431
432 if (hvcsd->connected == 0) {
433 spin_unlock_irqrestore(&hvcsd->lock, flags);
434 printk(KERN_INFO "HVCS: vterm state unchanged. The"
435 " vty-server is not connected to a vty.\n");
436 return -EPERM;
437 }
438
439 hvcs_partner_free(hvcsd);
440 printk(KERN_INFO "HVCS: Closed vty-server@%X and"
441 " partner vty@%X:%d connection.\n",
442 hvcsd->vdev->unit_address,
443 hvcsd->p_unit_address,
444 (uint32_t)hvcsd->p_partition_ID);
445
446 spin_unlock_irqrestore(&hvcsd->lock, flags);
447 return count;
448}
449
450static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
451{
452 struct vio_dev *viod = to_vio_dev(dev);
453 struct hvcs_struct *hvcsd = from_vio_dev(viod);
454 unsigned long flags;
455 int retval;
456
457 spin_lock_irqsave(&hvcsd->lock, flags);
458 retval = sprintf(buf, "%d\n", hvcsd->connected);
459 spin_unlock_irqrestore(&hvcsd->lock, flags);
460 return retval;
461}
462static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR,
463 hvcs_vterm_state_show, hvcs_vterm_state_store);
464
465static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf)
466{
467 struct vio_dev *viod = to_vio_dev(dev);
468 struct hvcs_struct *hvcsd = from_vio_dev(viod);
469 unsigned long flags;
470 int retval;
471
472 spin_lock_irqsave(&hvcsd->lock, flags);
473 retval = sprintf(buf, "%d\n", hvcsd->index);
474 spin_unlock_irqrestore(&hvcsd->lock, flags);
475 return retval;
476}
477
478static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL);
479
480static struct attribute *hvcs_attrs[] = {
481 &dev_attr_partner_vtys.attr,
482 &dev_attr_partner_clcs.attr,
483 &dev_attr_current_vty.attr,
484 &dev_attr_vterm_state.attr,
485 &dev_attr_index.attr,
486 NULL,
487};
488
489static struct attribute_group hvcs_attr_group = {
490 .attrs = hvcs_attrs,
491};
492
493static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf)
494{
495 /* A 1 means it is updating, a 0 means it is done updating */
496 return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status);
497}
498
499static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf,
500 size_t count)
501{
502 if ((simple_strtol(buf, NULL, 0) != 1)
503 && (hvcs_rescan_status != 0))
504 return -EINVAL;
505
506 hvcs_rescan_status = 1;
507 printk(KERN_INFO "HVCS: rescanning partner info for all"
508 " vty-servers.\n");
509 hvcs_rescan_devices_list();
510 hvcs_rescan_status = 0;
511 return count;
512}
513
514static DRIVER_ATTR(rescan,
515 S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store);
516
517static void hvcs_kick(void)
518{
519 hvcs_kicked = 1;
520 wmb();
521 wake_up_process(hvcs_task);
522}
523
524static void hvcs_unthrottle(struct tty_struct *tty)
525{
526 struct hvcs_struct *hvcsd = tty->driver_data;
527 unsigned long flags;
528
529 spin_lock_irqsave(&hvcsd->lock, flags);
530 hvcsd->todo_mask |= HVCS_SCHED_READ;
531 spin_unlock_irqrestore(&hvcsd->lock, flags);
532 hvcs_kick();
533}
534
535static void hvcs_throttle(struct tty_struct *tty)
536{
537 struct hvcs_struct *hvcsd = tty->driver_data;
538 unsigned long flags;
539
540 spin_lock_irqsave(&hvcsd->lock, flags);
541 vio_disable_interrupts(hvcsd->vdev);
542 spin_unlock_irqrestore(&hvcsd->lock, flags);
543}
544
545/*
546 * If the device is being removed we don't have to worry about this interrupt
547 * handler taking any further interrupts because they are disabled which means
548 * the hvcs_struct will always be valid in this handler.
549 */
550static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance)
551{
552 struct hvcs_struct *hvcsd = dev_instance;
553
554 spin_lock(&hvcsd->lock);
555 vio_disable_interrupts(hvcsd->vdev);
556 hvcsd->todo_mask |= HVCS_SCHED_READ;
557 spin_unlock(&hvcsd->lock);
558 hvcs_kick();
559
560 return IRQ_HANDLED;
561}
562
563/* This function must be called with the hvcsd->lock held */
564static void hvcs_try_write(struct hvcs_struct *hvcsd)
565{
566 uint32_t unit_address = hvcsd->vdev->unit_address;
567 struct tty_struct *tty = hvcsd->tty;
568 int sent;
569
570 if (hvcsd->todo_mask & HVCS_TRY_WRITE) {
571 /* won't send partial writes */
572 sent = hvc_put_chars(unit_address,
573 &hvcsd->buffer[0],
574 hvcsd->chars_in_buffer );
575 if (sent > 0) {
576 hvcsd->chars_in_buffer = 0;
577 /* wmb(); */
578 hvcsd->todo_mask &= ~(HVCS_TRY_WRITE);
579 /* wmb(); */
580
581 /*
582 * We are still obligated to deliver the data to the
583 * hypervisor even if the tty has been closed because
584 * we committed to delivering it. But don't try to wake
585 * a non-existent tty.
586 */
587 if (tty) {
588 tty_wakeup(tty);
589 }
590 }
591 }
592}
593
594static int hvcs_io(struct hvcs_struct *hvcsd)
595{
596 uint32_t unit_address;
597 struct tty_struct *tty;
598 char buf[HVCS_BUFF_LEN] __ALIGNED__;
599 unsigned long flags;
600 int got = 0;
601
602 spin_lock_irqsave(&hvcsd->lock, flags);
603
604 unit_address = hvcsd->vdev->unit_address;
605 tty = hvcsd->tty;
606
607 hvcs_try_write(hvcsd);
608
609 if (!tty || test_bit(TTY_THROTTLED, &tty->flags)) {
610 hvcsd->todo_mask &= ~(HVCS_READ_MASK);
611 goto bail;
612 } else if (!(hvcsd->todo_mask & (HVCS_READ_MASK)))
613 goto bail;
614
615 /* remove the read masks */
616 hvcsd->todo_mask &= ~(HVCS_READ_MASK);
617
618 if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) {
619 got = hvc_get_chars(unit_address,
620 &buf[0],
621 HVCS_BUFF_LEN);
622 tty_insert_flip_string(tty, buf, got);
623 }
624
625 /* Give the TTY time to process the data we just sent. */
626 if (got)
627 hvcsd->todo_mask |= HVCS_QUICK_READ;
628
629 spin_unlock_irqrestore(&hvcsd->lock, flags);
630 /* This is synch because tty->low_latency == 1 */
631 if(got)
632 tty_flip_buffer_push(tty);
633
634 if (!got) {
635 /* Do this _after_ the flip_buffer_push */
636 spin_lock_irqsave(&hvcsd->lock, flags);
637 vio_enable_interrupts(hvcsd->vdev);
638 spin_unlock_irqrestore(&hvcsd->lock, flags);
639 }
640
641 return hvcsd->todo_mask;
642
643 bail:
644 spin_unlock_irqrestore(&hvcsd->lock, flags);
645 return hvcsd->todo_mask;
646}
647
648static int khvcsd(void *unused)
649{
650 struct hvcs_struct *hvcsd;
651 int hvcs_todo_mask;
652
653 __set_current_state(TASK_RUNNING);
654
655 do {
656 hvcs_todo_mask = 0;
657 hvcs_kicked = 0;
658 wmb();
659
660 spin_lock(&hvcs_structs_lock);
661 list_for_each_entry(hvcsd, &hvcs_structs, next) {
662 hvcs_todo_mask |= hvcs_io(hvcsd);
663 }
664 spin_unlock(&hvcs_structs_lock);
665
666 /*
667 * If any of the hvcs adapters want to try a write or quick read
668 * don't schedule(), yield a smidgen then execute the hvcs_io
669 * thread again for those that want the write.
670 */
671 if (hvcs_todo_mask & (HVCS_TRY_WRITE | HVCS_QUICK_READ)) {
672 yield();
673 continue;
674 }
675
676 set_current_state(TASK_INTERRUPTIBLE);
677 if (!hvcs_kicked)
678 schedule();
679 __set_current_state(TASK_RUNNING);
680 } while (!kthread_should_stop());
681
682 return 0;
683}
684
685static struct vio_device_id hvcs_driver_table[] __devinitdata= {
686 {"serial-server", "hvterm2"},
687 { "", "" }
688};
689MODULE_DEVICE_TABLE(vio, hvcs_driver_table);
690
691static void hvcs_return_index(int index)
692{
693 /* Paranoia check */
694 if (!hvcs_index_list)
695 return;
696 if (index < 0 || index >= hvcs_index_count)
697 return;
698 if (hvcs_index_list[index] == -1)
699 return;
700 else
701 hvcs_index_list[index] = -1;
702}
703
704/* callback when the kref ref count reaches zero */
705static void destroy_hvcs_struct(struct kref *kref)
706{
707 struct hvcs_struct *hvcsd = from_kref(kref);
708 struct vio_dev *vdev;
709 unsigned long flags;
710
711 spin_lock(&hvcs_structs_lock);
712 spin_lock_irqsave(&hvcsd->lock, flags);
713
714 /* the list_del poisons the pointers */
715 list_del(&(hvcsd->next));
716
717 if (hvcsd->connected == 1) {
718 hvcs_partner_free(hvcsd);
719 printk(KERN_INFO "HVCS: Closed vty-server@%X and"
720 " partner vty@%X:%d connection.\n",
721 hvcsd->vdev->unit_address,
722 hvcsd->p_unit_address,
723 (uint32_t)hvcsd->p_partition_ID);
724 }
725 printk(KERN_INFO "HVCS: Destroyed hvcs_struct for vty-server@%X.\n",
726 hvcsd->vdev->unit_address);
727
728 vdev = hvcsd->vdev;
729 hvcsd->vdev = NULL;
730
731 hvcsd->p_unit_address = 0;
732 hvcsd->p_partition_ID = 0;
733 hvcs_return_index(hvcsd->index);
734 memset(&hvcsd->p_location_code[0], 0x00, HVCS_CLC_LENGTH + 1);
735
736 spin_unlock_irqrestore(&hvcsd->lock, flags);
737 spin_unlock(&hvcs_structs_lock);
738
739 sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group);
740
741 kfree(hvcsd);
742}
743
744static int hvcs_get_index(void)
745{
746 int i;
747 /* Paranoia check */
748 if (!hvcs_index_list) {
749 printk(KERN_ERR "HVCS: hvcs_index_list NOT valid!.\n");
750 return -EFAULT;
751 }
752 /* Find the numerically lowest first free index. */
753 for(i = 0; i < hvcs_index_count; i++) {
754 if (hvcs_index_list[i] == -1) {
755 hvcs_index_list[i] = 0;
756 return i;
757 }
758 }
759 return -1;
760}
761
762static int __devinit hvcs_probe(
763 struct vio_dev *dev,
764 const struct vio_device_id *id)
765{
766 struct hvcs_struct *hvcsd;
767 int index, rc;
768 int retval;
769
770 if (!dev || !id) {
771 printk(KERN_ERR "HVCS: probed with invalid parameter.\n");
772 return -EPERM;
773 }
774
775 /* Make sure we are properly initialized */
776 rc = hvcs_initialize();
777 if (rc) {
778 pr_err("HVCS: Failed to initialize core driver.\n");
779 return rc;
780 }
781
782 /* early to avoid cleanup on failure */
783 index = hvcs_get_index();
784 if (index < 0) {
785 return -EFAULT;
786 }
787
788 hvcsd = kzalloc(sizeof(*hvcsd), GFP_KERNEL);
789 if (!hvcsd)
790 return -ENODEV;
791
792
793 spin_lock_init(&hvcsd->lock);
794 /* Automatically incs the refcount the first time */
795 kref_init(&hvcsd->kref);
796
797 hvcsd->vdev = dev;
798 dev_set_drvdata(&dev->dev, hvcsd);
799
800 hvcsd->index = index;
801
802 /* hvcsd->index = ++hvcs_struct_count; */
803 hvcsd->chars_in_buffer = 0;
804 hvcsd->todo_mask = 0;
805 hvcsd->connected = 0;
806
807 /*
808 * This will populate the hvcs_struct's partner info fields for the
809 * first time.
810 */
811 if (hvcs_get_pi(hvcsd)) {
812 printk(KERN_ERR "HVCS: Failed to fetch partner"
813 " info for vty-server@%X on device probe.\n",
814 hvcsd->vdev->unit_address);
815 }
816
817 /*
818 * If a user app opens a tty that corresponds to this vty-server before
819 * the hvcs_struct has been added to the devices list then the user app
820 * will get -ENODEV.
821 */
822 spin_lock(&hvcs_structs_lock);
823 list_add_tail(&(hvcsd->next), &hvcs_structs);
824 spin_unlock(&hvcs_structs_lock);
825
826 retval = sysfs_create_group(&dev->dev.kobj, &hvcs_attr_group);
827 if (retval) {
828 printk(KERN_ERR "HVCS: Can't create sysfs attrs for vty-server@%X\n",
829 hvcsd->vdev->unit_address);
830 return retval;
831 }
832
833 printk(KERN_INFO "HVCS: vty-server@%X added to the vio bus.\n", dev->unit_address);
834
835 /*
836 * DON'T enable interrupts here because there is no user to receive the
837 * data.
838 */
839 return 0;
840}
841
842static int __devexit hvcs_remove(struct vio_dev *dev)
843{
844 struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev);
845 unsigned long flags;
846 struct tty_struct *tty;
847
848 if (!hvcsd)
849 return -ENODEV;
850
851 /* By this time the vty-server won't be getting any more interrupts */
852
853 spin_lock_irqsave(&hvcsd->lock, flags);
854
855 tty = hvcsd->tty;
856
857 spin_unlock_irqrestore(&hvcsd->lock, flags);
858
859 /*
860 * Let the last holder of this object cause it to be removed, which
861 * would probably be tty_hangup below.
862 */
863 kref_put(&hvcsd->kref, destroy_hvcs_struct);
864
865 /*
866 * The hangup is a scheduled function which will auto chain call
867 * hvcs_hangup. The tty should always be valid at this time unless a
868 * simultaneous tty close already cleaned up the hvcs_struct.
869 */
870 if (tty)
871 tty_hangup(tty);
872
873 printk(KERN_INFO "HVCS: vty-server@%X removed from the"
874 " vio bus.\n", dev->unit_address);
875 return 0;
876};
877
878static struct vio_driver hvcs_vio_driver = {
879 .id_table = hvcs_driver_table,
880 .probe = hvcs_probe,
881 .remove = __devexit_p(hvcs_remove),
882 .driver = {
883 .name = hvcs_driver_name,
884 .owner = THIS_MODULE,
885 }
886};
887
888/* Only called from hvcs_get_pi please */
889static void hvcs_set_pi(struct hvcs_partner_info *pi, struct hvcs_struct *hvcsd)
890{
891 int clclength;
892
893 hvcsd->p_unit_address = pi->unit_address;
894 hvcsd->p_partition_ID = pi->partition_ID;
895 clclength = strlen(&pi->location_code[0]);
896 if (clclength > HVCS_CLC_LENGTH)
897 clclength = HVCS_CLC_LENGTH;
898
899 /* copy the null-term char too */
900 strncpy(&hvcsd->p_location_code[0],
901 &pi->location_code[0], clclength + 1);
902}
903
904/*
905 * Traverse the list and add the partner info that is found to the hvcs_struct
906 * struct entry. NOTE: At this time I know that partner info will return a
907 * single entry but in the future there may be multiple partner info entries per
908 * vty-server and you'll want to zero out that list and reset it. If for some
909 * reason you have an old version of this driver but there IS more than one
910 * partner info then hvcsd->p_* will hold the last partner info data from the
911 * firmware query. A good way to update this code would be to replace the three
912 * partner info fields in hvcs_struct with a list of hvcs_partner_info
913 * instances.
914 *
915 * This function must be called with the hvcsd->lock held.
916 */
917static int hvcs_get_pi(struct hvcs_struct *hvcsd)
918{
919 struct hvcs_partner_info *pi;
920 uint32_t unit_address = hvcsd->vdev->unit_address;
921 struct list_head head;
922 int retval;
923
924 spin_lock(&hvcs_pi_lock);
925 if (!hvcs_pi_buff) {
926 spin_unlock(&hvcs_pi_lock);
927 return -EFAULT;
928 }
929 retval = hvcs_get_partner_info(unit_address, &head, hvcs_pi_buff);
930 spin_unlock(&hvcs_pi_lock);
931 if (retval) {
932 printk(KERN_ERR "HVCS: Failed to fetch partner"
933 " info for vty-server@%x.\n", unit_address);
934 return retval;
935 }
936
937 /* nixes the values if the partner vty went away */
938 hvcsd->p_unit_address = 0;
939 hvcsd->p_partition_ID = 0;
940
941 list_for_each_entry(pi, &head, node)
942 hvcs_set_pi(pi, hvcsd);
943
944 hvcs_free_partner_info(&head);
945 return 0;
946}
947
948/*
949 * This function is executed by the driver "rescan" sysfs entry. It shouldn't
950 * be executed elsewhere, in order to prevent deadlock issues.
951 */
952static int hvcs_rescan_devices_list(void)
953{
954 struct hvcs_struct *hvcsd;
955 unsigned long flags;
956
957 spin_lock(&hvcs_structs_lock);
958
959 list_for_each_entry(hvcsd, &hvcs_structs, next) {
960 spin_lock_irqsave(&hvcsd->lock, flags);
961 hvcs_get_pi(hvcsd);
962 spin_unlock_irqrestore(&hvcsd->lock, flags);
963 }
964
965 spin_unlock(&hvcs_structs_lock);
966
967 return 0;
968}
969
970/*
971 * Farm this off into its own function because it could be more complex once
972 * multiple partners support is added. This function should be called with
973 * the hvcsd->lock held.
974 */
975static int hvcs_has_pi(struct hvcs_struct *hvcsd)
976{
977 if ((!hvcsd->p_unit_address) || (!hvcsd->p_partition_ID))
978 return 0;
979 return 1;
980}
981
982/*
983 * NOTE: It is possible that the super admin removed a partner vty and then
984 * added a different vty as the new partner.
985 *
986 * This function must be called with the hvcsd->lock held.
987 */
988static int hvcs_partner_connect(struct hvcs_struct *hvcsd)
989{
990 int retval;
991 unsigned int unit_address = hvcsd->vdev->unit_address;
992
993 /*
994 * If there wasn't any pi when the device was added it doesn't meant
995 * there isn't any now. This driver isn't notified when a new partner
996 * vty is added to a vty-server so we discover changes on our own.
997 * Please see comments in hvcs_register_connection() for justification
998 * of this bizarre code.
999 */
1000 retval = hvcs_register_connection(unit_address,
1001 hvcsd->p_partition_ID,
1002 hvcsd->p_unit_address);
1003 if (!retval) {
1004 hvcsd->connected = 1;
1005 return 0;
1006 } else if (retval != -EINVAL)
1007 return retval;
1008
1009 /*
1010 * As per the spec re-get the pi and try again if -EINVAL after the
1011 * first connection attempt.
1012 */
1013 if (hvcs_get_pi(hvcsd))
1014 return -ENOMEM;
1015
1016 if (!hvcs_has_pi(hvcsd))
1017 return -ENODEV;
1018
1019 retval = hvcs_register_connection(unit_address,
1020 hvcsd->p_partition_ID,
1021 hvcsd->p_unit_address);
1022 if (retval != -EINVAL) {
1023 hvcsd->connected = 1;
1024 return retval;
1025 }
1026
1027 /*
1028 * EBUSY is the most likely scenario though the vty could have been
1029 * removed or there really could be an hcall error due to the parameter
1030 * data but thanks to ambiguous firmware return codes we can't really
1031 * tell.
1032 */
1033 printk(KERN_INFO "HVCS: vty-server or partner"
1034 " vty is busy. Try again later.\n");
1035 return -EBUSY;
1036}
1037
1038/* This function must be called with the hvcsd->lock held */
1039static void hvcs_partner_free(struct hvcs_struct *hvcsd)
1040{
1041 int retval;
1042 do {
1043 retval = hvcs_free_connection(hvcsd->vdev->unit_address);
1044 } while (retval == -EBUSY);
1045 hvcsd->connected = 0;
1046}
1047
1048/* This helper function must be called WITHOUT the hvcsd->lock held */
1049static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
1050 unsigned int irq, struct vio_dev *vdev)
1051{
1052 unsigned long flags;
1053 int rc;
1054
1055 /*
1056 * It is possible that the vty-server was removed between the time that
1057 * the conn was registered and now.
1058 */
1059 if (!(rc = request_irq(irq, &hvcs_handle_interrupt,
1060 IRQF_DISABLED, "ibmhvcs", hvcsd))) {
1061 /*
1062 * It is possible the vty-server was removed after the irq was
1063 * requested but before we have time to enable interrupts.
1064 */
1065 if (vio_enable_interrupts(vdev) == H_SUCCESS)
1066 return 0;
1067 else {
1068 printk(KERN_ERR "HVCS: int enable failed for"
1069 " vty-server@%X.\n", unit_address);
1070 free_irq(irq, hvcsd);
1071 }
1072 } else
1073 printk(KERN_ERR "HVCS: irq req failed for"
1074 " vty-server@%X.\n", unit_address);
1075
1076 spin_lock_irqsave(&hvcsd->lock, flags);
1077 hvcs_partner_free(hvcsd);
1078 spin_unlock_irqrestore(&hvcsd->lock, flags);
1079
1080 return rc;
1081
1082}
1083
1084/*
1085 * This always increments the kref ref count if the call is successful.
1086 * Please remember to dec when you are done with the instance.
1087 *
1088 * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when
1089 * calling this function or you will get deadlock.
1090 */
1091static struct hvcs_struct *hvcs_get_by_index(int index)
1092{
1093 struct hvcs_struct *hvcsd = NULL;
1094 unsigned long flags;
1095
1096 spin_lock(&hvcs_structs_lock);
1097 /* We can immediately discard OOB requests */
1098 if (index >= 0 && index < HVCS_MAX_SERVER_ADAPTERS) {
1099 list_for_each_entry(hvcsd, &hvcs_structs, next) {
1100 spin_lock_irqsave(&hvcsd->lock, flags);
1101 if (hvcsd->index == index) {
1102 kref_get(&hvcsd->kref);
1103 spin_unlock_irqrestore(&hvcsd->lock, flags);
1104 spin_unlock(&hvcs_structs_lock);
1105 return hvcsd;
1106 }
1107 spin_unlock_irqrestore(&hvcsd->lock, flags);
1108 }
1109 hvcsd = NULL;
1110 }
1111
1112 spin_unlock(&hvcs_structs_lock);
1113 return hvcsd;
1114}
1115
1116/*
1117 * This is invoked via the tty_open interface when a user app connects to the
1118 * /dev node.
1119 */
1120static int hvcs_open(struct tty_struct *tty, struct file *filp)
1121{
1122 struct hvcs_struct *hvcsd;
1123 int rc, retval = 0;
1124 unsigned long flags;
1125 unsigned int irq;
1126 struct vio_dev *vdev;
1127 unsigned long unit_address;
1128
1129 if (tty->driver_data)
1130 goto fast_open;
1131
1132 /*
1133 * Is there a vty-server that shares the same index?
1134 * This function increments the kref index.
1135 */
1136 if (!(hvcsd = hvcs_get_by_index(tty->index))) {
1137 printk(KERN_WARNING "HVCS: open failed, no device associated"
1138 " with tty->index %d.\n", tty->index);
1139 return -ENODEV;
1140 }
1141
1142 spin_lock_irqsave(&hvcsd->lock, flags);
1143
1144 if (hvcsd->connected == 0)
1145 if ((retval = hvcs_partner_connect(hvcsd)))
1146 goto error_release;
1147
1148 hvcsd->open_count = 1;
1149 hvcsd->tty = tty;
1150 tty->driver_data = hvcsd;
1151
1152 memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN);
1153
1154 /*
1155 * Save these in the spinlock for the enable operations that need them
1156 * outside of the spinlock.
1157 */
1158 irq = hvcsd->vdev->irq;
1159 vdev = hvcsd->vdev;
1160 unit_address = hvcsd->vdev->unit_address;
1161
1162 hvcsd->todo_mask |= HVCS_SCHED_READ;
1163 spin_unlock_irqrestore(&hvcsd->lock, flags);
1164
1165 /*
1166 * This must be done outside of the spinlock because it requests irqs
1167 * and will grab the spinlock and free the connection if it fails.
1168 */
1169 if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) {
1170 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1171 printk(KERN_WARNING "HVCS: enable device failed.\n");
1172 return rc;
1173 }
1174
1175 goto open_success;
1176
1177fast_open:
1178 hvcsd = tty->driver_data;
1179
1180 spin_lock_irqsave(&hvcsd->lock, flags);
1181 kref_get(&hvcsd->kref);
1182 hvcsd->open_count++;
1183 hvcsd->todo_mask |= HVCS_SCHED_READ;
1184 spin_unlock_irqrestore(&hvcsd->lock, flags);
1185
1186open_success:
1187 hvcs_kick();
1188
1189 printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n",
1190 hvcsd->vdev->unit_address );
1191
1192 return 0;
1193
1194error_release:
1195 spin_unlock_irqrestore(&hvcsd->lock, flags);
1196 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1197
1198 printk(KERN_WARNING "HVCS: partner connect failed.\n");
1199 return retval;
1200}
1201
1202static void hvcs_close(struct tty_struct *tty, struct file *filp)
1203{
1204 struct hvcs_struct *hvcsd;
1205 unsigned long flags;
1206 int irq = NO_IRQ;
1207
1208 /*
1209 * Is someone trying to close the file associated with this device after
1210 * we have hung up? If so tty->driver_data wouldn't be valid.
1211 */
1212 if (tty_hung_up_p(filp))
1213 return;
1214
1215 /*
1216 * No driver_data means that this close was probably issued after a
1217 * failed hvcs_open by the tty layer's release_dev() api and we can just
1218 * exit cleanly.
1219 */
1220 if (!tty->driver_data)
1221 return;
1222
1223 hvcsd = tty->driver_data;
1224
1225 spin_lock_irqsave(&hvcsd->lock, flags);
1226 if (--hvcsd->open_count == 0) {
1227
1228 vio_disable_interrupts(hvcsd->vdev);
1229
1230 /*
1231 * NULL this early so that the kernel_thread doesn't try to
1232 * execute any operations on the TTY even though it is obligated
1233 * to deliver any pending I/O to the hypervisor.
1234 */
1235 hvcsd->tty = NULL;
1236
1237 irq = hvcsd->vdev->irq;
1238 spin_unlock_irqrestore(&hvcsd->lock, flags);
1239
1240 tty_wait_until_sent(tty, HVCS_CLOSE_WAIT);
1241
1242 /*
1243 * This line is important because it tells hvcs_open that this
1244 * device needs to be re-configured the next time hvcs_open is
1245 * called.
1246 */
1247 tty->driver_data = NULL;
1248
1249 free_irq(irq, hvcsd);
1250 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1251 return;
1252 } else if (hvcsd->open_count < 0) {
1253 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
1254 " is missmanaged.\n",
1255 hvcsd->vdev->unit_address, hvcsd->open_count);
1256 }
1257
1258 spin_unlock_irqrestore(&hvcsd->lock, flags);
1259 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1260}
1261
1262static void hvcs_hangup(struct tty_struct * tty)
1263{
1264 struct hvcs_struct *hvcsd = tty->driver_data;
1265 unsigned long flags;
1266 int temp_open_count;
1267 int irq = NO_IRQ;
1268
1269 spin_lock_irqsave(&hvcsd->lock, flags);
1270 /* Preserve this so that we know how many kref refs to put */
1271 temp_open_count = hvcsd->open_count;
1272
1273 /*
1274 * Don't kref put inside the spinlock because the destruction
1275 * callback may use the spinlock and it may get called before the
1276 * spinlock has been released.
1277 */
1278 vio_disable_interrupts(hvcsd->vdev);
1279
1280 hvcsd->todo_mask = 0;
1281
1282 /* I don't think the tty needs the hvcs_struct pointer after a hangup */
1283 hvcsd->tty->driver_data = NULL;
1284 hvcsd->tty = NULL;
1285
1286 hvcsd->open_count = 0;
1287
1288 /* This will drop any buffered data on the floor which is OK in a hangup
1289 * scenario. */
1290 memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN);
1291 hvcsd->chars_in_buffer = 0;
1292
1293 irq = hvcsd->vdev->irq;
1294
1295 spin_unlock_irqrestore(&hvcsd->lock, flags);
1296
1297 free_irq(irq, hvcsd);
1298
1299 /*
1300 * We need to kref_put() for every open_count we have since the
1301 * tty_hangup() function doesn't invoke a close per open connection on a
1302 * non-console device.
1303 */
1304 while(temp_open_count) {
1305 --temp_open_count;
1306 /*
1307 * The final put will trigger destruction of the hvcs_struct.
1308 * NOTE: If this hangup was signaled from user space then the
1309 * final put will never happen.
1310 */
1311 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1312 }
1313}
1314
1315/*
1316 * NOTE: This is almost always from_user since user level apps interact with the
1317 * /dev nodes. I'm trusting that if hvcs_write gets called and interrupted by
1318 * hvcs_remove (which removes the target device and executes tty_hangup()) that
1319 * tty_hangup will allow hvcs_write time to complete execution before it
1320 * terminates our device.
1321 */
1322static int hvcs_write(struct tty_struct *tty,
1323 const unsigned char *buf, int count)
1324{
1325 struct hvcs_struct *hvcsd = tty->driver_data;
1326 unsigned int unit_address;
1327 const unsigned char *charbuf;
1328 unsigned long flags;
1329 int total_sent = 0;
1330 int tosend = 0;
1331 int result = 0;
1332
1333 /*
1334 * If they don't check the return code off of their open they may
1335 * attempt this even if there is no connected device.
1336 */
1337 if (!hvcsd)
1338 return -ENODEV;
1339
1340 /* Reasonable size to prevent user level flooding */
1341 if (count > HVCS_MAX_FROM_USER) {
1342 printk(KERN_WARNING "HVCS write: count being truncated to"
1343 " HVCS_MAX_FROM_USER.\n");
1344 count = HVCS_MAX_FROM_USER;
1345 }
1346
1347 charbuf = buf;
1348
1349 spin_lock_irqsave(&hvcsd->lock, flags);
1350
1351 /*
1352 * Somehow an open succeeded but the device was removed or the
1353 * connection terminated between the vty-server and partner vty during
1354 * the middle of a write operation? This is a crummy place to do this
1355 * but we want to keep it all in the spinlock.
1356 */
1357 if (hvcsd->open_count <= 0) {
1358 spin_unlock_irqrestore(&hvcsd->lock, flags);
1359 return -ENODEV;
1360 }
1361
1362 unit_address = hvcsd->vdev->unit_address;
1363
1364 while (count > 0) {
1365 tosend = min(count, (HVCS_BUFF_LEN - hvcsd->chars_in_buffer));
1366 /*
1367 * No more space, this probably means that the last call to
1368 * hvcs_write() didn't succeed and the buffer was filled up.
1369 */
1370 if (!tosend)
1371 break;
1372
1373 memcpy(&hvcsd->buffer[hvcsd->chars_in_buffer],
1374 &charbuf[total_sent],
1375 tosend);
1376
1377 hvcsd->chars_in_buffer += tosend;
1378
1379 result = 0;
1380
1381 /*
1382 * If this is true then we don't want to try writing to the
1383 * hypervisor because that is the kernel_threads job now. We'll
1384 * just add to the buffer.
1385 */
1386 if (!(hvcsd->todo_mask & HVCS_TRY_WRITE))
1387 /* won't send partial writes */
1388 result = hvc_put_chars(unit_address,
1389 &hvcsd->buffer[0],
1390 hvcsd->chars_in_buffer);
1391
1392 /*
1393 * Since we know we have enough room in hvcsd->buffer for
1394 * tosend we record that it was sent regardless of whether the
1395 * hypervisor actually took it because we have it buffered.
1396 */
1397 total_sent+=tosend;
1398 count-=tosend;
1399 if (result == 0) {
1400 hvcsd->todo_mask |= HVCS_TRY_WRITE;
1401 hvcs_kick();
1402 break;
1403 }
1404
1405 hvcsd->chars_in_buffer = 0;
1406 /*
1407 * Test after the chars_in_buffer reset otherwise this could
1408 * deadlock our writes if hvc_put_chars fails.
1409 */
1410 if (result < 0)
1411 break;
1412 }
1413
1414 spin_unlock_irqrestore(&hvcsd->lock, flags);
1415
1416 if (result == -1)
1417 return -EIO;
1418 else
1419 return total_sent;
1420}
1421
1422/*
1423 * This is really asking how much can we guarantee that we can send or that we
1424 * absolutely WILL BUFFER if we can't send it. This driver MUST honor the
1425 * return value, hence the reason for hvcs_struct buffering.
1426 */
1427static int hvcs_write_room(struct tty_struct *tty)
1428{
1429 struct hvcs_struct *hvcsd = tty->driver_data;
1430
1431 if (!hvcsd || hvcsd->open_count <= 0)
1432 return 0;
1433
1434 return HVCS_BUFF_LEN - hvcsd->chars_in_buffer;
1435}
1436
1437static int hvcs_chars_in_buffer(struct tty_struct *tty)
1438{
1439 struct hvcs_struct *hvcsd = tty->driver_data;
1440
1441 return hvcsd->chars_in_buffer;
1442}
1443
1444static const struct tty_operations hvcs_ops = {
1445 .open = hvcs_open,
1446 .close = hvcs_close,
1447 .hangup = hvcs_hangup,
1448 .write = hvcs_write,
1449 .write_room = hvcs_write_room,
1450 .chars_in_buffer = hvcs_chars_in_buffer,
1451 .unthrottle = hvcs_unthrottle,
1452 .throttle = hvcs_throttle,
1453};
1454
1455static int hvcs_alloc_index_list(int n)
1456{
1457 int i;
1458
1459 hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL);
1460 if (!hvcs_index_list)
1461 return -ENOMEM;
1462 hvcs_index_count = n;
1463 for (i = 0; i < hvcs_index_count; i++)
1464 hvcs_index_list[i] = -1;
1465 return 0;
1466}
1467
1468static void hvcs_free_index_list(void)
1469{
1470 /* Paranoia check to be thorough. */
1471 kfree(hvcs_index_list);
1472 hvcs_index_list = NULL;
1473 hvcs_index_count = 0;
1474}
1475
1476static int __devinit hvcs_initialize(void)
1477{
1478 int rc, num_ttys_to_alloc;
1479
1480 mutex_lock(&hvcs_init_mutex);
1481 if (hvcs_task) {
1482 mutex_unlock(&hvcs_init_mutex);
1483 return 0;
1484 }
1485
1486 /* Has the user specified an overload with an insmod param? */
1487 if (hvcs_parm_num_devs <= 0 ||
1488 (hvcs_parm_num_devs > HVCS_MAX_SERVER_ADAPTERS)) {
1489 num_ttys_to_alloc = HVCS_DEFAULT_SERVER_ADAPTERS;
1490 } else
1491 num_ttys_to_alloc = hvcs_parm_num_devs;
1492
1493 hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc);
1494 if (!hvcs_tty_driver)
1495 return -ENOMEM;
1496
1497 if (hvcs_alloc_index_list(num_ttys_to_alloc)) {
1498 rc = -ENOMEM;
1499 goto index_fail;
1500 }
1501
1502 hvcs_tty_driver->owner = THIS_MODULE;
1503
1504 hvcs_tty_driver->driver_name = hvcs_driver_name;
1505 hvcs_tty_driver->name = hvcs_device_node;
1506
1507 /*
1508 * We'll let the system assign us a major number, indicated by leaving
1509 * it blank.
1510 */
1511
1512 hvcs_tty_driver->minor_start = HVCS_MINOR_START;
1513 hvcs_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
1514
1515 /*
1516 * We role our own so that we DONT ECHO. We can't echo because the
1517 * device we are connecting to already echoes by default and this would
1518 * throw us into a horrible recursive echo-echo-echo loop.
1519 */
1520 hvcs_tty_driver->init_termios = hvcs_tty_termios;
1521 hvcs_tty_driver->flags = TTY_DRIVER_REAL_RAW;
1522
1523 tty_set_operations(hvcs_tty_driver, &hvcs_ops);
1524
1525 /*
1526 * The following call will result in sysfs entries that denote the
1527 * dynamically assigned major and minor numbers for our devices.
1528 */
1529 if (tty_register_driver(hvcs_tty_driver)) {
1530 printk(KERN_ERR "HVCS: registration as a tty driver failed.\n");
1531 rc = -EIO;
1532 goto register_fail;
1533 }
1534
1535 hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL);
1536 if (!hvcs_pi_buff) {
1537 rc = -ENOMEM;
1538 goto buff_alloc_fail;
1539 }
1540
1541 hvcs_task = kthread_run(khvcsd, NULL, "khvcsd");
1542 if (IS_ERR(hvcs_task)) {
1543 printk(KERN_ERR "HVCS: khvcsd creation failed.\n");
1544 rc = -EIO;
1545 goto kthread_fail;
1546 }
1547 mutex_unlock(&hvcs_init_mutex);
1548 return 0;
1549
1550kthread_fail:
1551 kfree(hvcs_pi_buff);
1552buff_alloc_fail:
1553 tty_unregister_driver(hvcs_tty_driver);
1554register_fail:
1555 hvcs_free_index_list();
1556index_fail:
1557 put_tty_driver(hvcs_tty_driver);
1558 hvcs_tty_driver = NULL;
1559 mutex_unlock(&hvcs_init_mutex);
1560 return rc;
1561}
1562
1563static int __init hvcs_module_init(void)
1564{
1565 int rc = vio_register_driver(&hvcs_vio_driver);
1566 if (rc) {
1567 printk(KERN_ERR "HVCS: can't register vio driver\n");
1568 return rc;
1569 }
1570
1571 pr_info("HVCS: Driver registered.\n");
1572
1573 /* This needs to be done AFTER the vio_register_driver() call or else
1574 * the kobjects won't be initialized properly.
1575 */
1576 rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan);
1577 if (rc)
1578 pr_warning(KERN_ERR "HVCS: Failed to create rescan file (err %d)\n", rc);
1579
1580 return 0;
1581}
1582
1583static void __exit hvcs_module_exit(void)
1584{
1585 /*
1586 * This driver receives hvcs_remove callbacks for each device upon
1587 * module removal.
1588 */
1589 vio_unregister_driver(&hvcs_vio_driver);
1590 if (!hvcs_task)
1591 return;
1592
1593 /*
1594 * This synchronous operation will wake the khvcsd kthread if it is
1595 * asleep and will return when khvcsd has terminated.
1596 */
1597 kthread_stop(hvcs_task);
1598
1599 spin_lock(&hvcs_pi_lock);
1600 kfree(hvcs_pi_buff);
1601 hvcs_pi_buff = NULL;
1602 spin_unlock(&hvcs_pi_lock);
1603
1604 driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan);
1605
1606 tty_unregister_driver(hvcs_tty_driver);
1607
1608 hvcs_free_index_list();
1609
1610 put_tty_driver(hvcs_tty_driver);
1611
1612 printk(KERN_INFO "HVCS: driver module removed.\n");
1613}
1614
1615module_init(hvcs_module_init);
1616module_exit(hvcs_module_exit);
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
new file mode 100644
index 000000000000..8a8d6373f164
--- /dev/null
+++ b/drivers/tty/hvc/hvsi.c
@@ -0,0 +1,1314 @@
1/*
2 * Copyright (C) 2004 Hollis Blanchard <hollisb@us.ibm.com>, IBM
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/* Host Virtual Serial Interface (HVSI) is a protocol between the hosted OS
20 * and the service processor on IBM pSeries servers. On these servers, there
21 * are no serial ports under the OS's control, and sometimes there is no other
22 * console available either. However, the service processor has two standard
23 * serial ports, so this over-complicated protocol allows the OS to control
24 * those ports by proxy.
25 *
26 * Besides data, the procotol supports the reading/writing of the serial
27 * port's DTR line, and the reading of the CD line. This is to allow the OS to
28 * control a modem attached to the service processor's serial port. Note that
29 * the OS cannot change the speed of the port through this protocol.
30 */
31
32#undef DEBUG
33
34#include <linux/console.h>
35#include <linux/ctype.h>
36#include <linux/delay.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/module.h>
40#include <linux/major.h>
41#include <linux/kernel.h>
42#include <linux/spinlock.h>
43#include <linux/sysrq.h>
44#include <linux/tty.h>
45#include <linux/tty_flip.h>
46#include <asm/hvcall.h>
47#include <asm/hvconsole.h>
48#include <asm/prom.h>
49#include <asm/uaccess.h>
50#include <asm/vio.h>
51#include <asm/param.h>
52
53#define HVSI_MAJOR 229
54#define HVSI_MINOR 128
55#define MAX_NR_HVSI_CONSOLES 4
56
57#define HVSI_TIMEOUT (5*HZ)
58#define HVSI_VERSION 1
59#define HVSI_MAX_PACKET 256
60#define HVSI_MAX_READ 16
61#define HVSI_MAX_OUTGOING_DATA 12
62#define N_OUTBUF 12
63
64/*
65 * we pass data via two 8-byte registers, so we would like our char arrays
66 * properly aligned for those loads.
67 */
68#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
69
70struct hvsi_struct {
71 struct delayed_work writer;
72 struct work_struct handshaker;
73 wait_queue_head_t emptyq; /* woken when outbuf is emptied */
74 wait_queue_head_t stateq; /* woken when HVSI state changes */
75 spinlock_t lock;
76 int index;
77 struct tty_struct *tty;
78 int count;
79 uint8_t throttle_buf[128];
80 uint8_t outbuf[N_OUTBUF]; /* to implement write_room and chars_in_buffer */
81 /* inbuf is for packet reassembly. leave a little room for leftovers. */
82 uint8_t inbuf[HVSI_MAX_PACKET + HVSI_MAX_READ];
83 uint8_t *inbuf_end;
84 int n_throttle;
85 int n_outbuf;
86 uint32_t vtermno;
87 uint32_t virq;
88 atomic_t seqno; /* HVSI packet sequence number */
89 uint16_t mctrl;
90 uint8_t state; /* HVSI protocol state */
91 uint8_t flags;
92#ifdef CONFIG_MAGIC_SYSRQ
93 uint8_t sysrq;
94#endif /* CONFIG_MAGIC_SYSRQ */
95};
96static struct hvsi_struct hvsi_ports[MAX_NR_HVSI_CONSOLES];
97
98static struct tty_driver *hvsi_driver;
99static int hvsi_count;
100static int (*hvsi_wait)(struct hvsi_struct *hp, int state);
101
102enum HVSI_PROTOCOL_STATE {
103 HVSI_CLOSED,
104 HVSI_WAIT_FOR_VER_RESPONSE,
105 HVSI_WAIT_FOR_VER_QUERY,
106 HVSI_OPEN,
107 HVSI_WAIT_FOR_MCTRL_RESPONSE,
108 HVSI_FSP_DIED,
109};
110#define HVSI_CONSOLE 0x1
111
112#define VS_DATA_PACKET_HEADER 0xff
113#define VS_CONTROL_PACKET_HEADER 0xfe
114#define VS_QUERY_PACKET_HEADER 0xfd
115#define VS_QUERY_RESPONSE_PACKET_HEADER 0xfc
116
117/* control verbs */
118#define VSV_SET_MODEM_CTL 1 /* to service processor only */
119#define VSV_MODEM_CTL_UPDATE 2 /* from service processor only */
120#define VSV_CLOSE_PROTOCOL 3
121
122/* query verbs */
123#define VSV_SEND_VERSION_NUMBER 1
124#define VSV_SEND_MODEM_CTL_STATUS 2
125
126/* yes, these masks are not consecutive. */
127#define HVSI_TSDTR 0x01
128#define HVSI_TSCD 0x20
129
130struct hvsi_header {
131 uint8_t type;
132 uint8_t len;
133 uint16_t seqno;
134} __attribute__((packed));
135
136struct hvsi_data {
137 uint8_t type;
138 uint8_t len;
139 uint16_t seqno;
140 uint8_t data[HVSI_MAX_OUTGOING_DATA];
141} __attribute__((packed));
142
143struct hvsi_control {
144 uint8_t type;
145 uint8_t len;
146 uint16_t seqno;
147 uint16_t verb;
148 /* optional depending on verb: */
149 uint32_t word;
150 uint32_t mask;
151} __attribute__((packed));
152
153struct hvsi_query {
154 uint8_t type;
155 uint8_t len;
156 uint16_t seqno;
157 uint16_t verb;
158} __attribute__((packed));
159
160struct hvsi_query_response {
161 uint8_t type;
162 uint8_t len;
163 uint16_t seqno;
164 uint16_t verb;
165 uint16_t query_seqno;
166 union {
167 uint8_t version;
168 uint32_t mctrl_word;
169 } u;
170} __attribute__((packed));
171
172
173
174static inline int is_console(struct hvsi_struct *hp)
175{
176 return hp->flags & HVSI_CONSOLE;
177}
178
179static inline int is_open(struct hvsi_struct *hp)
180{
181 /* if we're waiting for an mctrl then we're already open */
182 return (hp->state == HVSI_OPEN)
183 || (hp->state == HVSI_WAIT_FOR_MCTRL_RESPONSE);
184}
185
186static inline void print_state(struct hvsi_struct *hp)
187{
188#ifdef DEBUG
189 static const char *state_names[] = {
190 "HVSI_CLOSED",
191 "HVSI_WAIT_FOR_VER_RESPONSE",
192 "HVSI_WAIT_FOR_VER_QUERY",
193 "HVSI_OPEN",
194 "HVSI_WAIT_FOR_MCTRL_RESPONSE",
195 "HVSI_FSP_DIED",
196 };
197 const char *name = (hp->state < ARRAY_SIZE(state_names))
198 ? state_names[hp->state] : "UNKNOWN";
199
200 pr_debug("hvsi%i: state = %s\n", hp->index, name);
201#endif /* DEBUG */
202}
203
204static inline void __set_state(struct hvsi_struct *hp, int state)
205{
206 hp->state = state;
207 print_state(hp);
208 wake_up_all(&hp->stateq);
209}
210
211static inline void set_state(struct hvsi_struct *hp, int state)
212{
213 unsigned long flags;
214
215 spin_lock_irqsave(&hp->lock, flags);
216 __set_state(hp, state);
217 spin_unlock_irqrestore(&hp->lock, flags);
218}
219
220static inline int len_packet(const uint8_t *packet)
221{
222 return (int)((struct hvsi_header *)packet)->len;
223}
224
225static inline int is_header(const uint8_t *packet)
226{
227 struct hvsi_header *header = (struct hvsi_header *)packet;
228 return header->type >= VS_QUERY_RESPONSE_PACKET_HEADER;
229}
230
231static inline int got_packet(const struct hvsi_struct *hp, uint8_t *packet)
232{
233 if (hp->inbuf_end < packet + sizeof(struct hvsi_header))
234 return 0; /* don't even have the packet header */
235
236 if (hp->inbuf_end < (packet + len_packet(packet)))
237 return 0; /* don't have the rest of the packet */
238
239 return 1;
240}
241
242/* shift remaining bytes in packetbuf down */
243static void compact_inbuf(struct hvsi_struct *hp, uint8_t *read_to)
244{
245 int remaining = (int)(hp->inbuf_end - read_to);
246
247 pr_debug("%s: %i chars remain\n", __func__, remaining);
248
249 if (read_to != hp->inbuf)
250 memmove(hp->inbuf, read_to, remaining);
251
252 hp->inbuf_end = hp->inbuf + remaining;
253}
254
255#ifdef DEBUG
256#define dbg_dump_packet(packet) dump_packet(packet)
257#define dbg_dump_hex(data, len) dump_hex(data, len)
258#else
259#define dbg_dump_packet(packet) do { } while (0)
260#define dbg_dump_hex(data, len) do { } while (0)
261#endif
262
263static void dump_hex(const uint8_t *data, int len)
264{
265 int i;
266
267 printk(" ");
268 for (i=0; i < len; i++)
269 printk("%.2x", data[i]);
270
271 printk("\n ");
272 for (i=0; i < len; i++) {
273 if (isprint(data[i]))
274 printk("%c", data[i]);
275 else
276 printk(".");
277 }
278 printk("\n");
279}
280
281static void dump_packet(uint8_t *packet)
282{
283 struct hvsi_header *header = (struct hvsi_header *)packet;
284
285 printk("type 0x%x, len %i, seqno %i:\n", header->type, header->len,
286 header->seqno);
287
288 dump_hex(packet, header->len);
289}
290
291static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
292{
293 unsigned long got;
294
295 got = hvc_get_chars(hp->vtermno, buf, count);
296
297 return got;
298}
299
300static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
301 struct tty_struct **to_hangup, struct hvsi_struct **to_handshake)
302{
303 struct hvsi_control *header = (struct hvsi_control *)packet;
304
305 switch (header->verb) {
306 case VSV_MODEM_CTL_UPDATE:
307 if ((header->word & HVSI_TSCD) == 0) {
308 /* CD went away; no more connection */
309 pr_debug("hvsi%i: CD dropped\n", hp->index);
310 hp->mctrl &= TIOCM_CD;
311 /* If userland hasn't done an open(2) yet, hp->tty is NULL. */
312 if (hp->tty && !(hp->tty->flags & CLOCAL))
313 *to_hangup = hp->tty;
314 }
315 break;
316 case VSV_CLOSE_PROTOCOL:
317 pr_debug("hvsi%i: service processor came back\n", hp->index);
318 if (hp->state != HVSI_CLOSED) {
319 *to_handshake = hp;
320 }
321 break;
322 default:
323 printk(KERN_WARNING "hvsi%i: unknown HVSI control packet: ",
324 hp->index);
325 dump_packet(packet);
326 break;
327 }
328}
329
330static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet)
331{
332 struct hvsi_query_response *resp = (struct hvsi_query_response *)packet;
333
334 switch (hp->state) {
335 case HVSI_WAIT_FOR_VER_RESPONSE:
336 __set_state(hp, HVSI_WAIT_FOR_VER_QUERY);
337 break;
338 case HVSI_WAIT_FOR_MCTRL_RESPONSE:
339 hp->mctrl = 0;
340 if (resp->u.mctrl_word & HVSI_TSDTR)
341 hp->mctrl |= TIOCM_DTR;
342 if (resp->u.mctrl_word & HVSI_TSCD)
343 hp->mctrl |= TIOCM_CD;
344 __set_state(hp, HVSI_OPEN);
345 break;
346 default:
347 printk(KERN_ERR "hvsi%i: unexpected query response: ", hp->index);
348 dump_packet(packet);
349 break;
350 }
351}
352
353/* respond to service processor's version query */
354static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno)
355{
356 struct hvsi_query_response packet __ALIGNED__;
357 int wrote;
358
359 packet.type = VS_QUERY_RESPONSE_PACKET_HEADER;
360 packet.len = sizeof(struct hvsi_query_response);
361 packet.seqno = atomic_inc_return(&hp->seqno);
362 packet.verb = VSV_SEND_VERSION_NUMBER;
363 packet.u.version = HVSI_VERSION;
364 packet.query_seqno = query_seqno+1;
365
366 pr_debug("%s: sending %i bytes\n", __func__, packet.len);
367 dbg_dump_hex((uint8_t*)&packet, packet.len);
368
369 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
370 if (wrote != packet.len) {
371 printk(KERN_ERR "hvsi%i: couldn't send query response!\n",
372 hp->index);
373 return -EIO;
374 }
375
376 return 0;
377}
378
379static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet)
380{
381 struct hvsi_query *query = (struct hvsi_query *)packet;
382
383 switch (hp->state) {
384 case HVSI_WAIT_FOR_VER_QUERY:
385 hvsi_version_respond(hp, query->seqno);
386 __set_state(hp, HVSI_OPEN);
387 break;
388 default:
389 printk(KERN_ERR "hvsi%i: unexpected query: ", hp->index);
390 dump_packet(packet);
391 break;
392 }
393}
394
395static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
396{
397 int i;
398
399 for (i=0; i < len; i++) {
400 char c = buf[i];
401#ifdef CONFIG_MAGIC_SYSRQ
402 if (c == '\0') {
403 hp->sysrq = 1;
404 continue;
405 } else if (hp->sysrq) {
406 handle_sysrq(c);
407 hp->sysrq = 0;
408 continue;
409 }
410#endif /* CONFIG_MAGIC_SYSRQ */
411 tty_insert_flip_char(hp->tty, c, 0);
412 }
413}
414
415/*
416 * We could get 252 bytes of data at once here. But the tty layer only
417 * throttles us at TTY_THRESHOLD_THROTTLE (128) bytes, so we could overflow
418 * it. Accordingly we won't send more than 128 bytes at a time to the flip
419 * buffer, which will give the tty buffer a chance to throttle us. Should the
420 * value of TTY_THRESHOLD_THROTTLE change in n_tty.c, this code should be
421 * revisited.
422 */
423#define TTY_THRESHOLD_THROTTLE 128
424static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
425 const uint8_t *packet)
426{
427 const struct hvsi_header *header = (const struct hvsi_header *)packet;
428 const uint8_t *data = packet + sizeof(struct hvsi_header);
429 int datalen = header->len - sizeof(struct hvsi_header);
430 int overflow = datalen - TTY_THRESHOLD_THROTTLE;
431
432 pr_debug("queueing %i chars '%.*s'\n", datalen, datalen, data);
433
434 if (datalen == 0)
435 return NULL;
436
437 if (overflow > 0) {
438 pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__);
439 datalen = TTY_THRESHOLD_THROTTLE;
440 }
441
442 hvsi_insert_chars(hp, data, datalen);
443
444 if (overflow > 0) {
445 /*
446 * we still have more data to deliver, so we need to save off the
447 * overflow and send it later
448 */
449 pr_debug("%s: deferring overflow\n", __func__);
450 memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow);
451 hp->n_throttle = overflow;
452 }
453
454 return hp->tty;
455}
456
457/*
458 * Returns true/false indicating data successfully read from hypervisor.
459 * Used both to get packets for tty connections and to advance the state
460 * machine during console handshaking (in which case tty = NULL and we ignore
461 * incoming data).
462 */
463static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
464 struct tty_struct **hangup, struct hvsi_struct **handshake)
465{
466 uint8_t *packet = hp->inbuf;
467 int chunklen;
468
469 *flip = NULL;
470 *hangup = NULL;
471 *handshake = NULL;
472
473 chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ);
474 if (chunklen == 0) {
475 pr_debug("%s: 0-length read\n", __func__);
476 return 0;
477 }
478
479 pr_debug("%s: got %i bytes\n", __func__, chunklen);
480 dbg_dump_hex(hp->inbuf_end, chunklen);
481
482 hp->inbuf_end += chunklen;
483
484 /* handle all completed packets */
485 while ((packet < hp->inbuf_end) && got_packet(hp, packet)) {
486 struct hvsi_header *header = (struct hvsi_header *)packet;
487
488 if (!is_header(packet)) {
489 printk(KERN_ERR "hvsi%i: got malformed packet\n", hp->index);
490 /* skip bytes until we find a header or run out of data */
491 while ((packet < hp->inbuf_end) && (!is_header(packet)))
492 packet++;
493 continue;
494 }
495
496 pr_debug("%s: handling %i-byte packet\n", __func__,
497 len_packet(packet));
498 dbg_dump_packet(packet);
499
500 switch (header->type) {
501 case VS_DATA_PACKET_HEADER:
502 if (!is_open(hp))
503 break;
504 if (hp->tty == NULL)
505 break; /* no tty buffer to put data in */
506 *flip = hvsi_recv_data(hp, packet);
507 break;
508 case VS_CONTROL_PACKET_HEADER:
509 hvsi_recv_control(hp, packet, hangup, handshake);
510 break;
511 case VS_QUERY_RESPONSE_PACKET_HEADER:
512 hvsi_recv_response(hp, packet);
513 break;
514 case VS_QUERY_PACKET_HEADER:
515 hvsi_recv_query(hp, packet);
516 break;
517 default:
518 printk(KERN_ERR "hvsi%i: unknown HVSI packet type 0x%x\n",
519 hp->index, header->type);
520 dump_packet(packet);
521 break;
522 }
523
524 packet += len_packet(packet);
525
526 if (*hangup || *handshake) {
527 pr_debug("%s: hangup or handshake\n", __func__);
528 /*
529 * we need to send the hangup now before receiving any more data.
530 * If we get "data, hangup, data", we can't deliver the second
531 * data before the hangup.
532 */
533 break;
534 }
535 }
536
537 compact_inbuf(hp, packet);
538
539 return 1;
540}
541
542static void hvsi_send_overflow(struct hvsi_struct *hp)
543{
544 pr_debug("%s: delivering %i bytes overflow\n", __func__,
545 hp->n_throttle);
546
547 hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle);
548 hp->n_throttle = 0;
549}
550
551/*
552 * must get all pending data because we only get an irq on empty->non-empty
553 * transition
554 */
555static irqreturn_t hvsi_interrupt(int irq, void *arg)
556{
557 struct hvsi_struct *hp = (struct hvsi_struct *)arg;
558 struct tty_struct *flip;
559 struct tty_struct *hangup;
560 struct hvsi_struct *handshake;
561 unsigned long flags;
562 int again = 1;
563
564 pr_debug("%s\n", __func__);
565
566 while (again) {
567 spin_lock_irqsave(&hp->lock, flags);
568 again = hvsi_load_chunk(hp, &flip, &hangup, &handshake);
569 spin_unlock_irqrestore(&hp->lock, flags);
570
571 /*
572 * we have to call tty_flip_buffer_push() and tty_hangup() outside our
573 * spinlock. But we also have to keep going until we've read all the
574 * available data.
575 */
576
577 if (flip) {
578 /* there was data put in the tty flip buffer */
579 tty_flip_buffer_push(flip);
580 flip = NULL;
581 }
582
583 if (hangup) {
584 tty_hangup(hangup);
585 }
586
587 if (handshake) {
588 pr_debug("hvsi%i: attempting re-handshake\n", handshake->index);
589 schedule_work(&handshake->handshaker);
590 }
591 }
592
593 spin_lock_irqsave(&hp->lock, flags);
594 if (hp->tty && hp->n_throttle
595 && (!test_bit(TTY_THROTTLED, &hp->tty->flags))) {
596 /* we weren't hung up and we weren't throttled, so we can deliver the
597 * rest now */
598 flip = hp->tty;
599 hvsi_send_overflow(hp);
600 }
601 spin_unlock_irqrestore(&hp->lock, flags);
602
603 if (flip) {
604 tty_flip_buffer_push(flip);
605 }
606
607 return IRQ_HANDLED;
608}
609
610/* for boot console, before the irq handler is running */
611static int __init poll_for_state(struct hvsi_struct *hp, int state)
612{
613 unsigned long end_jiffies = jiffies + HVSI_TIMEOUT;
614
615 for (;;) {
616 hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */
617
618 if (hp->state == state)
619 return 0;
620
621 mdelay(5);
622 if (time_after(jiffies, end_jiffies))
623 return -EIO;
624 }
625}
626
627/* wait for irq handler to change our state */
628static int wait_for_state(struct hvsi_struct *hp, int state)
629{
630 int ret = 0;
631
632 if (!wait_event_timeout(hp->stateq, (hp->state == state), HVSI_TIMEOUT))
633 ret = -EIO;
634
635 return ret;
636}
637
638static int hvsi_query(struct hvsi_struct *hp, uint16_t verb)
639{
640 struct hvsi_query packet __ALIGNED__;
641 int wrote;
642
643 packet.type = VS_QUERY_PACKET_HEADER;
644 packet.len = sizeof(struct hvsi_query);
645 packet.seqno = atomic_inc_return(&hp->seqno);
646 packet.verb = verb;
647
648 pr_debug("%s: sending %i bytes\n", __func__, packet.len);
649 dbg_dump_hex((uint8_t*)&packet, packet.len);
650
651 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
652 if (wrote != packet.len) {
653 printk(KERN_ERR "hvsi%i: couldn't send query (%i)!\n", hp->index,
654 wrote);
655 return -EIO;
656 }
657
658 return 0;
659}
660
661static int hvsi_get_mctrl(struct hvsi_struct *hp)
662{
663 int ret;
664
665 set_state(hp, HVSI_WAIT_FOR_MCTRL_RESPONSE);
666 hvsi_query(hp, VSV_SEND_MODEM_CTL_STATUS);
667
668 ret = hvsi_wait(hp, HVSI_OPEN);
669 if (ret < 0) {
670 printk(KERN_ERR "hvsi%i: didn't get modem flags\n", hp->index);
671 set_state(hp, HVSI_OPEN);
672 return ret;
673 }
674
675 pr_debug("%s: mctrl 0x%x\n", __func__, hp->mctrl);
676
677 return 0;
678}
679
680/* note that we can only set DTR */
681static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl)
682{
683 struct hvsi_control packet __ALIGNED__;
684 int wrote;
685
686 packet.type = VS_CONTROL_PACKET_HEADER,
687 packet.seqno = atomic_inc_return(&hp->seqno);
688 packet.len = sizeof(struct hvsi_control);
689 packet.verb = VSV_SET_MODEM_CTL;
690 packet.mask = HVSI_TSDTR;
691
692 if (mctrl & TIOCM_DTR)
693 packet.word = HVSI_TSDTR;
694
695 pr_debug("%s: sending %i bytes\n", __func__, packet.len);
696 dbg_dump_hex((uint8_t*)&packet, packet.len);
697
698 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
699 if (wrote != packet.len) {
700 printk(KERN_ERR "hvsi%i: couldn't set DTR!\n", hp->index);
701 return -EIO;
702 }
703
704 return 0;
705}
706
707static void hvsi_drain_input(struct hvsi_struct *hp)
708{
709 uint8_t buf[HVSI_MAX_READ] __ALIGNED__;
710 unsigned long end_jiffies = jiffies + HVSI_TIMEOUT;
711
712 while (time_before(end_jiffies, jiffies))
713 if (0 == hvsi_read(hp, buf, HVSI_MAX_READ))
714 break;
715}
716
717static int hvsi_handshake(struct hvsi_struct *hp)
718{
719 int ret;
720
721 /*
722 * We could have a CLOSE or other data waiting for us before we even try
723 * to open; try to throw it all away so we don't get confused. (CLOSE
724 * is the first message sent up the pipe when the FSP comes online. We
725 * need to distinguish between "it came up a while ago and we're the first
726 * user" and "it was just reset before it saw our handshake packet".)
727 */
728 hvsi_drain_input(hp);
729
730 set_state(hp, HVSI_WAIT_FOR_VER_RESPONSE);
731 ret = hvsi_query(hp, VSV_SEND_VERSION_NUMBER);
732 if (ret < 0) {
733 printk(KERN_ERR "hvsi%i: couldn't send version query\n", hp->index);
734 return ret;
735 }
736
737 ret = hvsi_wait(hp, HVSI_OPEN);
738 if (ret < 0)
739 return ret;
740
741 return 0;
742}
743
744static void hvsi_handshaker(struct work_struct *work)
745{
746 struct hvsi_struct *hp =
747 container_of(work, struct hvsi_struct, handshaker);
748
749 if (hvsi_handshake(hp) >= 0)
750 return;
751
752 printk(KERN_ERR "hvsi%i: re-handshaking failed\n", hp->index);
753 if (is_console(hp)) {
754 /*
755 * ttys will re-attempt the handshake via hvsi_open, but
756 * the console will not.
757 */
758 printk(KERN_ERR "hvsi%i: lost console!\n", hp->index);
759 }
760}
761
762static int hvsi_put_chars(struct hvsi_struct *hp, const char *buf, int count)
763{
764 struct hvsi_data packet __ALIGNED__;
765 int ret;
766
767 BUG_ON(count > HVSI_MAX_OUTGOING_DATA);
768
769 packet.type = VS_DATA_PACKET_HEADER;
770 packet.seqno = atomic_inc_return(&hp->seqno);
771 packet.len = count + sizeof(struct hvsi_header);
772 memcpy(&packet.data, buf, count);
773
774 ret = hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
775 if (ret == packet.len) {
776 /* return the number of chars written, not the packet length */
777 return count;
778 }
779 return ret; /* return any errors */
780}
781
782static void hvsi_close_protocol(struct hvsi_struct *hp)
783{
784 struct hvsi_control packet __ALIGNED__;
785
786 packet.type = VS_CONTROL_PACKET_HEADER;
787 packet.seqno = atomic_inc_return(&hp->seqno);
788 packet.len = 6;
789 packet.verb = VSV_CLOSE_PROTOCOL;
790
791 pr_debug("%s: sending %i bytes\n", __func__, packet.len);
792 dbg_dump_hex((uint8_t*)&packet, packet.len);
793
794 hvc_put_chars(hp->vtermno, (char *)&packet, packet.len);
795}
796
797static int hvsi_open(struct tty_struct *tty, struct file *filp)
798{
799 struct hvsi_struct *hp;
800 unsigned long flags;
801 int line = tty->index;
802 int ret;
803
804 pr_debug("%s\n", __func__);
805
806 if (line < 0 || line >= hvsi_count)
807 return -ENODEV;
808 hp = &hvsi_ports[line];
809
810 tty->driver_data = hp;
811
812 mb();
813 if (hp->state == HVSI_FSP_DIED)
814 return -EIO;
815
816 spin_lock_irqsave(&hp->lock, flags);
817 hp->tty = tty;
818 hp->count++;
819 atomic_set(&hp->seqno, 0);
820 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
821 spin_unlock_irqrestore(&hp->lock, flags);
822
823 if (is_console(hp))
824 return 0; /* this has already been handshaked as the console */
825
826 ret = hvsi_handshake(hp);
827 if (ret < 0) {
828 printk(KERN_ERR "%s: HVSI handshaking failed\n", tty->name);
829 return ret;
830 }
831
832 ret = hvsi_get_mctrl(hp);
833 if (ret < 0) {
834 printk(KERN_ERR "%s: couldn't get initial modem flags\n", tty->name);
835 return ret;
836 }
837
838 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR);
839 if (ret < 0) {
840 printk(KERN_ERR "%s: couldn't set DTR\n", tty->name);
841 return ret;
842 }
843
844 return 0;
845}
846
847/* wait for hvsi_write_worker to empty hp->outbuf */
848static void hvsi_flush_output(struct hvsi_struct *hp)
849{
850 wait_event_timeout(hp->emptyq, (hp->n_outbuf <= 0), HVSI_TIMEOUT);
851
852 /* 'writer' could still be pending if it didn't see n_outbuf = 0 yet */
853 cancel_delayed_work_sync(&hp->writer);
854 flush_work_sync(&hp->handshaker);
855
856 /*
857 * it's also possible that our timeout expired and hvsi_write_worker
858 * didn't manage to push outbuf. poof.
859 */
860 hp->n_outbuf = 0;
861}
862
863static void hvsi_close(struct tty_struct *tty, struct file *filp)
864{
865 struct hvsi_struct *hp = tty->driver_data;
866 unsigned long flags;
867
868 pr_debug("%s\n", __func__);
869
870 if (tty_hung_up_p(filp))
871 return;
872
873 spin_lock_irqsave(&hp->lock, flags);
874
875 if (--hp->count == 0) {
876 hp->tty = NULL;
877 hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */
878
879 /* only close down connection if it is not the console */
880 if (!is_console(hp)) {
881 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); /* no more irqs */
882 __set_state(hp, HVSI_CLOSED);
883 /*
884 * any data delivered to the tty layer after this will be
885 * discarded (except for XON/XOFF)
886 */
887 tty->closing = 1;
888
889 spin_unlock_irqrestore(&hp->lock, flags);
890
891 /* let any existing irq handlers finish. no more will start. */
892 synchronize_irq(hp->virq);
893
894 /* hvsi_write_worker will re-schedule until outbuf is empty. */
895 hvsi_flush_output(hp);
896
897 /* tell FSP to stop sending data */
898 hvsi_close_protocol(hp);
899
900 /*
901 * drain anything FSP is still in the middle of sending, and let
902 * hvsi_handshake drain the rest on the next open.
903 */
904 hvsi_drain_input(hp);
905
906 spin_lock_irqsave(&hp->lock, flags);
907 }
908 } else if (hp->count < 0)
909 printk(KERN_ERR "hvsi_close %lu: oops, count is %d\n",
910 hp - hvsi_ports, hp->count);
911
912 spin_unlock_irqrestore(&hp->lock, flags);
913}
914
915static void hvsi_hangup(struct tty_struct *tty)
916{
917 struct hvsi_struct *hp = tty->driver_data;
918 unsigned long flags;
919
920 pr_debug("%s\n", __func__);
921
922 spin_lock_irqsave(&hp->lock, flags);
923
924 hp->count = 0;
925 hp->n_outbuf = 0;
926 hp->tty = NULL;
927
928 spin_unlock_irqrestore(&hp->lock, flags);
929}
930
931/* called with hp->lock held */
932static void hvsi_push(struct hvsi_struct *hp)
933{
934 int n;
935
936 if (hp->n_outbuf <= 0)
937 return;
938
939 n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf);
940 if (n > 0) {
941 /* success */
942 pr_debug("%s: wrote %i chars\n", __func__, n);
943 hp->n_outbuf = 0;
944 } else if (n == -EIO) {
945 __set_state(hp, HVSI_FSP_DIED);
946 printk(KERN_ERR "hvsi%i: service processor died\n", hp->index);
947 }
948}
949
950/* hvsi_write_worker will keep rescheduling itself until outbuf is empty */
951static void hvsi_write_worker(struct work_struct *work)
952{
953 struct hvsi_struct *hp =
954 container_of(work, struct hvsi_struct, writer.work);
955 unsigned long flags;
956#ifdef DEBUG
957 static long start_j = 0;
958
959 if (start_j == 0)
960 start_j = jiffies;
961#endif /* DEBUG */
962
963 spin_lock_irqsave(&hp->lock, flags);
964
965 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf);
966
967 if (!is_open(hp)) {
968 /*
969 * We could have a non-open connection if the service processor died
970 * while we were busily scheduling ourselves. In that case, it could
971 * be minutes before the service processor comes back, so only try
972 * again once a second.
973 */
974 schedule_delayed_work(&hp->writer, HZ);
975 goto out;
976 }
977
978 hvsi_push(hp);
979 if (hp->n_outbuf > 0)
980 schedule_delayed_work(&hp->writer, 10);
981 else {
982#ifdef DEBUG
983 pr_debug("%s: outbuf emptied after %li jiffies\n", __func__,
984 jiffies - start_j);
985 start_j = 0;
986#endif /* DEBUG */
987 wake_up_all(&hp->emptyq);
988 tty_wakeup(hp->tty);
989 }
990
991out:
992 spin_unlock_irqrestore(&hp->lock, flags);
993}
994
995static int hvsi_write_room(struct tty_struct *tty)
996{
997 struct hvsi_struct *hp = tty->driver_data;
998
999 return N_OUTBUF - hp->n_outbuf;
1000}
1001
1002static int hvsi_chars_in_buffer(struct tty_struct *tty)
1003{
1004 struct hvsi_struct *hp = tty->driver_data;
1005
1006 return hp->n_outbuf;
1007}
1008
1009static int hvsi_write(struct tty_struct *tty,
1010 const unsigned char *buf, int count)
1011{
1012 struct hvsi_struct *hp = tty->driver_data;
1013 const char *source = buf;
1014 unsigned long flags;
1015 int total = 0;
1016 int origcount = count;
1017
1018 spin_lock_irqsave(&hp->lock, flags);
1019
1020 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf);
1021
1022 if (!is_open(hp)) {
1023 /* we're either closing or not yet open; don't accept data */
1024 pr_debug("%s: not open\n", __func__);
1025 goto out;
1026 }
1027
1028 /*
1029 * when the hypervisor buffer (16K) fills, data will stay in hp->outbuf
1030 * and hvsi_write_worker will be scheduled. subsequent hvsi_write() calls
1031 * will see there is no room in outbuf and return.
1032 */
1033 while ((count > 0) && (hvsi_write_room(hp->tty) > 0)) {
1034 int chunksize = min(count, hvsi_write_room(hp->tty));
1035
1036 BUG_ON(hp->n_outbuf < 0);
1037 memcpy(hp->outbuf + hp->n_outbuf, source, chunksize);
1038 hp->n_outbuf += chunksize;
1039
1040 total += chunksize;
1041 source += chunksize;
1042 count -= chunksize;
1043 hvsi_push(hp);
1044 }
1045
1046 if (hp->n_outbuf > 0) {
1047 /*
1048 * we weren't able to write it all to the hypervisor.
1049 * schedule another push attempt.
1050 */
1051 schedule_delayed_work(&hp->writer, 10);
1052 }
1053
1054out:
1055 spin_unlock_irqrestore(&hp->lock, flags);
1056
1057 if (total != origcount)
1058 pr_debug("%s: wanted %i, only wrote %i\n", __func__, origcount,
1059 total);
1060
1061 return total;
1062}
1063
1064/*
1065 * I have never seen throttle or unthrottle called, so this little throttle
1066 * buffering scheme may or may not work.
1067 */
1068static void hvsi_throttle(struct tty_struct *tty)
1069{
1070 struct hvsi_struct *hp = tty->driver_data;
1071
1072 pr_debug("%s\n", __func__);
1073
1074 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE);
1075}
1076
1077static void hvsi_unthrottle(struct tty_struct *tty)
1078{
1079 struct hvsi_struct *hp = tty->driver_data;
1080 unsigned long flags;
1081 int shouldflip = 0;
1082
1083 pr_debug("%s\n", __func__);
1084
1085 spin_lock_irqsave(&hp->lock, flags);
1086 if (hp->n_throttle) {
1087 hvsi_send_overflow(hp);
1088 shouldflip = 1;
1089 }
1090 spin_unlock_irqrestore(&hp->lock, flags);
1091
1092 if (shouldflip)
1093 tty_flip_buffer_push(hp->tty);
1094
1095 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
1096}
1097
1098static int hvsi_tiocmget(struct tty_struct *tty)
1099{
1100 struct hvsi_struct *hp = tty->driver_data;
1101
1102 hvsi_get_mctrl(hp);
1103 return hp->mctrl;
1104}
1105
1106static int hvsi_tiocmset(struct tty_struct *tty,
1107 unsigned int set, unsigned int clear)
1108{
1109 struct hvsi_struct *hp = tty->driver_data;
1110 unsigned long flags;
1111 uint16_t new_mctrl;
1112
1113 /* we can only alter DTR */
1114 clear &= TIOCM_DTR;
1115 set &= TIOCM_DTR;
1116
1117 spin_lock_irqsave(&hp->lock, flags);
1118
1119 new_mctrl = (hp->mctrl & ~clear) | set;
1120
1121 if (hp->mctrl != new_mctrl) {
1122 hvsi_set_mctrl(hp, new_mctrl);
1123 hp->mctrl = new_mctrl;
1124 }
1125 spin_unlock_irqrestore(&hp->lock, flags);
1126
1127 return 0;
1128}
1129
1130
1131static const struct tty_operations hvsi_ops = {
1132 .open = hvsi_open,
1133 .close = hvsi_close,
1134 .write = hvsi_write,
1135 .hangup = hvsi_hangup,
1136 .write_room = hvsi_write_room,
1137 .chars_in_buffer = hvsi_chars_in_buffer,
1138 .throttle = hvsi_throttle,
1139 .unthrottle = hvsi_unthrottle,
1140 .tiocmget = hvsi_tiocmget,
1141 .tiocmset = hvsi_tiocmset,
1142};
1143
1144static int __init hvsi_init(void)
1145{
1146 int i;
1147
1148 hvsi_driver = alloc_tty_driver(hvsi_count);
1149 if (!hvsi_driver)
1150 return -ENOMEM;
1151
1152 hvsi_driver->owner = THIS_MODULE;
1153 hvsi_driver->driver_name = "hvsi";
1154 hvsi_driver->name = "hvsi";
1155 hvsi_driver->major = HVSI_MAJOR;
1156 hvsi_driver->minor_start = HVSI_MINOR;
1157 hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM;
1158 hvsi_driver->init_termios = tty_std_termios;
1159 hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
1160 hvsi_driver->init_termios.c_ispeed = 9600;
1161 hvsi_driver->init_termios.c_ospeed = 9600;
1162 hvsi_driver->flags = TTY_DRIVER_REAL_RAW;
1163 tty_set_operations(hvsi_driver, &hvsi_ops);
1164
1165 for (i=0; i < hvsi_count; i++) {
1166 struct hvsi_struct *hp = &hvsi_ports[i];
1167 int ret = 1;
1168
1169 ret = request_irq(hp->virq, hvsi_interrupt, IRQF_DISABLED, "hvsi", hp);
1170 if (ret)
1171 printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n",
1172 hp->virq, ret);
1173 }
1174 hvsi_wait = wait_for_state; /* irqs active now */
1175
1176 if (tty_register_driver(hvsi_driver))
1177 panic("Couldn't register hvsi console driver\n");
1178
1179 printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count);
1180
1181 return 0;
1182}
1183device_initcall(hvsi_init);
1184
1185/***** console (not tty) code: *****/
1186
1187static void hvsi_console_print(struct console *console, const char *buf,
1188 unsigned int count)
1189{
1190 struct hvsi_struct *hp = &hvsi_ports[console->index];
1191 char c[HVSI_MAX_OUTGOING_DATA] __ALIGNED__;
1192 unsigned int i = 0, n = 0;
1193 int ret, donecr = 0;
1194
1195 mb();
1196 if (!is_open(hp))
1197 return;
1198
1199 /*
1200 * ugh, we have to translate LF -> CRLF ourselves, in place.
1201 * copied from hvc_console.c:
1202 */
1203 while (count > 0 || i > 0) {
1204 if (count > 0 && i < sizeof(c)) {
1205 if (buf[n] == '\n' && !donecr) {
1206 c[i++] = '\r';
1207 donecr = 1;
1208 } else {
1209 c[i++] = buf[n++];
1210 donecr = 0;
1211 --count;
1212 }
1213 } else {
1214 ret = hvsi_put_chars(hp, c, i);
1215 if (ret < 0)
1216 i = 0;
1217 i -= ret;
1218 }
1219 }
1220}
1221
1222static struct tty_driver *hvsi_console_device(struct console *console,
1223 int *index)
1224{
1225 *index = console->index;
1226 return hvsi_driver;
1227}
1228
1229static int __init hvsi_console_setup(struct console *console, char *options)
1230{
1231 struct hvsi_struct *hp;
1232 int ret;
1233
1234 if (console->index < 0 || console->index >= hvsi_count)
1235 return -1;
1236 hp = &hvsi_ports[console->index];
1237
1238 /* give the FSP a chance to change the baud rate when we re-open */
1239 hvsi_close_protocol(hp);
1240
1241 ret = hvsi_handshake(hp);
1242 if (ret < 0)
1243 return ret;
1244
1245 ret = hvsi_get_mctrl(hp);
1246 if (ret < 0)
1247 return ret;
1248
1249 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR);
1250 if (ret < 0)
1251 return ret;
1252
1253 hp->flags |= HVSI_CONSOLE;
1254
1255 return 0;
1256}
1257
1258static struct console hvsi_console = {
1259 .name = "hvsi",
1260 .write = hvsi_console_print,
1261 .device = hvsi_console_device,
1262 .setup = hvsi_console_setup,
1263 .flags = CON_PRINTBUFFER,
1264 .index = -1,
1265};
1266
1267static int __init hvsi_console_init(void)
1268{
1269 struct device_node *vty;
1270
1271 hvsi_wait = poll_for_state; /* no irqs yet; must poll */
1272
1273 /* search device tree for vty nodes */
1274 for (vty = of_find_compatible_node(NULL, "serial", "hvterm-protocol");
1275 vty != NULL;
1276 vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) {
1277 struct hvsi_struct *hp;
1278 const uint32_t *vtermno, *irq;
1279
1280 vtermno = of_get_property(vty, "reg", NULL);
1281 irq = of_get_property(vty, "interrupts", NULL);
1282 if (!vtermno || !irq)
1283 continue;
1284
1285 if (hvsi_count >= MAX_NR_HVSI_CONSOLES) {
1286 of_node_put(vty);
1287 break;
1288 }
1289
1290 hp = &hvsi_ports[hvsi_count];
1291 INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker);
1292 INIT_WORK(&hp->handshaker, hvsi_handshaker);
1293 init_waitqueue_head(&hp->emptyq);
1294 init_waitqueue_head(&hp->stateq);
1295 spin_lock_init(&hp->lock);
1296 hp->index = hvsi_count;
1297 hp->inbuf_end = hp->inbuf;
1298 hp->state = HVSI_CLOSED;
1299 hp->vtermno = *vtermno;
1300 hp->virq = irq_create_mapping(NULL, irq[0]);
1301 if (hp->virq == NO_IRQ) {
1302 printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
1303 __func__, irq[0]);
1304 continue;
1305 }
1306
1307 hvsi_count++;
1308 }
1309
1310 if (hvsi_count)
1311 register_console(&hvsi_console);
1312 return 0;
1313}
1314console_initcall(hvsi_console_init);