Blame view

drivers/char/virtio_console.c 46.8 KB
a23ea9247   Rusty Russell   virtio: console: ...
1
2
  /*
   * Copyright (C) 2006, 2007, 2009 Rusty Russell, IBM Corporation
5084f8930   Amit Shah   virtio: console: ...
3
4
   * Copyright (C) 2009, 2010, 2011 Red Hat, Inc.
   * Copyright (C) 2009, 2010, 2011 Amit Shah <amit.shah@redhat.com>
31610434b   Rusty Russell   Virtio console dr...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
fb08bd274   Amit Shah   virtio: console: ...
20
  #include <linux/cdev.h>
d99393eff   Amit Shah   virtio: console: ...
21
  #include <linux/debugfs.h>
5e38483b3   Christian Borntraeger   virtio: console: ...
22
  #include <linux/completion.h>
fb08bd274   Amit Shah   virtio: console: ...
23
  #include <linux/device.h>
31610434b   Rusty Russell   Virtio console dr...
24
  #include <linux/err.h>
a08fa92d1   Amit Shah   virtio: console: ...
25
  #include <linux/freezer.h>
2030fa496   Amit Shah   virtio: console: ...
26
  #include <linux/fs.h>
31610434b   Rusty Russell   Virtio console dr...
27
  #include <linux/init.h>
38edf58d7   Amit Shah   virtio: console: ...
28
  #include <linux/list.h>
2030fa496   Amit Shah   virtio: console: ...
29
30
  #include <linux/poll.h>
  #include <linux/sched.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
31
  #include <linux/slab.h>
38edf58d7   Amit Shah   virtio: console: ...
32
  #include <linux/spinlock.h>
31610434b   Rusty Russell   Virtio console dr...
33
34
  #include <linux/virtio.h>
  #include <linux/virtio_console.h>
2030fa496   Amit Shah   virtio: console: ...
35
  #include <linux/wait.h>
17634ba25   Amit Shah   virtio: console: ...
36
  #include <linux/workqueue.h>
c22405c98   Paul Gortmaker   drivers/char: Add...
37
  #include <linux/module.h>
51df0acc3   Amit Shah   virtio: console: ...
38
  #include "../tty/hvc/hvc_console.h"
31610434b   Rusty Russell   Virtio console dr...
39

38edf58d7   Amit Shah   virtio: console: ...
40
41
42
43
44
45
46
47
48
  /*
   * This is a global struct for storing common data for all the devices
   * this driver handles.
   *
   * Mainly, it has a linked list for all the consoles in one place so
   * that callbacks from hvc for get_chars(), put_chars() work properly
   * across multiple devices and multiple ports per device.
   */
  struct ports_driver_data {
fb08bd274   Amit Shah   virtio: console: ...
49
50
  	/* Used for registering chardevs */
  	struct class *class;
d99393eff   Amit Shah   virtio: console: ...
51
52
  	/* Used for exporting per-port information to debugfs */
  	struct dentry *debugfs_dir;
6bdf2afd0   Amit Shah   virtio: console: ...
53
54
  	/* List of all the devices we're handling */
  	struct list_head portdevs;
fb08bd274   Amit Shah   virtio: console: ...
55
56
  	/* Number of devices this driver is handling */
  	unsigned int index;
d8a02bd58   Rusty Russell   virtio: console: ...
57
58
59
60
61
62
63
64
65
66
67
  	/*
  	 * This is used to keep track of the number of hvc consoles
  	 * spawned by this driver.  This number is given as the first
  	 * argument to hvc_alloc().  To correctly map an initial
  	 * console spawned via hvc_instantiate to the console being
  	 * hooked up via hvc_alloc, we need to pass the same vtermno.
  	 *
  	 * We also just assume the first console being initialised was
  	 * the first one that got used as the initial console.
  	 */
  	unsigned int next_vtermno;
38edf58d7   Amit Shah   virtio: console: ...
68
69
70
71
72
73
  	/* All the console devices handled by this driver */
  	struct list_head consoles;
  };
  static struct ports_driver_data pdrvdata;
  
  DEFINE_SPINLOCK(pdrvdata_lock);
5e38483b3   Christian Borntraeger   virtio: console: ...
74
  DECLARE_COMPLETION(early_console_added);
38edf58d7   Amit Shah   virtio: console: ...
75

4f23c573c   Amit Shah   virtio: console: ...
76
77
78
79
80
81
82
  /* This struct holds information that's relevant only for console ports */
  struct console {
  	/* We'll place all consoles in a list in the pdrvdata struct */
  	struct list_head list;
  
  	/* The hvc device associated with this console port */
  	struct hvc_struct *hvc;
9778829cf   Amit Shah   virtio: console: ...
83
84
  	/* The size of the console */
  	struct winsize ws;
4f23c573c   Amit Shah   virtio: console: ...
85
86
87
88
89
90
91
92
93
  	/*
  	 * This number identifies the number that we used to register
  	 * with hvc in hvc_instantiate() and hvc_alloc(); this is the
  	 * number passed on by the hvc callbacks to us to
  	 * differentiate between the other console ports handled by
  	 * this driver
  	 */
  	u32 vtermno;
  };
fdb9a0545   Amit Shah   virtio: console: ...
94
95
96
97
98
99
100
101
102
103
104
  struct port_buffer {
  	char *buf;
  
  	/* size of the buffer in *buf above */
  	size_t size;
  
  	/* used length of the buffer */
  	size_t len;
  	/* offset in the buf from which to consume data */
  	size_t offset;
  };
17634ba25   Amit Shah   virtio: console: ...
105
106
107
108
109
  /*
   * This is a per-device struct that stores data common to all the
   * ports for that device (vdev->priv).
   */
  struct ports_device {
6bdf2afd0   Amit Shah   virtio: console: ...
110
111
  	/* Next portdev in the list, head is in the pdrvdata struct */
  	struct list_head list;
17634ba25   Amit Shah   virtio: console: ...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  	/*
  	 * Workqueue handlers where we process deferred work after
  	 * notification
  	 */
  	struct work_struct control_work;
  
  	struct list_head ports;
  
  	/* To protect the list of ports */
  	spinlock_t ports_lock;
  
  	/* To protect the vq operations for the control channel */
  	spinlock_t cvq_lock;
  
  	/* The current config space is stored here */
b99fa815d   Amit Shah   virtio: Revert "v...
127
  	struct virtio_console_config config;
17634ba25   Amit Shah   virtio: console: ...
128
129
130
131
132
133
134
135
136
137
138
139
  
  	/* The virtio device we're associated with */
  	struct virtio_device *vdev;
  
  	/*
  	 * A couple of virtqueues for the control channel: one for
  	 * guest->host transfers, one for host->guest transfers
  	 */
  	struct virtqueue *c_ivq, *c_ovq;
  
  	/* Array of per-port IO virtqueues */
  	struct virtqueue **in_vqs, **out_vqs;
fb08bd274   Amit Shah   virtio: console: ...
140
141
142
143
144
145
  
  	/* Used for numbering devices for sysfs and debugfs */
  	unsigned int drv_index;
  
  	/* Major number for this device.  Ports will be created as minors. */
  	int chr_major;
17634ba25   Amit Shah   virtio: console: ...
146
  };
17e5b4f20   Amit Shah   virtio: console: ...
147
148
149
  struct port_stats {
  	unsigned long bytes_sent, bytes_received, bytes_discarded;
  };
1c85bf354   Amit Shah   virtio: console: ...
150
  /* This struct holds the per-port data */
21206ede8   Rusty Russell   virtio: console: ...
151
  struct port {
17634ba25   Amit Shah   virtio: console: ...
152
153
  	/* Next port in the list, head is in the ports_device */
  	struct list_head list;
1c85bf354   Amit Shah   virtio: console: ...
154
155
  	/* Pointer to the parent virtio_console device */
  	struct ports_device *portdev;
fdb9a0545   Amit Shah   virtio: console: ...
156
157
158
  
  	/* The current buffer from which data has to be fed to readers */
  	struct port_buffer *inbuf;
21206ede8   Rusty Russell   virtio: console: ...
159

203baab8b   Amit Shah   virtio: console: ...
160
161
162
163
164
165
  	/*
  	 * To protect the operations on the in_vq associated with this
  	 * port.  Has to be a spinlock because it can be called from
  	 * interrupt context (get_char()).
  	 */
  	spinlock_t inbuf_lock;
cdfadfc1a   Amit Shah   virtio: console: ...
166
167
  	/* Protect the operations on the out_vq. */
  	spinlock_t outvq_lock;
1c85bf354   Amit Shah   virtio: console: ...
168
169
  	/* The IO vqs for this port */
  	struct virtqueue *in_vq, *out_vq;
d99393eff   Amit Shah   virtio: console: ...
170
171
  	/* File in the debugfs directory that exposes this port's information */
  	struct dentry *debugfs_file;
4f23c573c   Amit Shah   virtio: console: ...
172
  	/*
17e5b4f20   Amit Shah   virtio: console: ...
173
174
175
176
177
178
179
  	 * Keep count of the bytes sent, received and discarded for
  	 * this port for accounting and debugging purposes.  These
  	 * counts are not reset across port open / close events.
  	 */
  	struct port_stats stats;
  
  	/*
4f23c573c   Amit Shah   virtio: console: ...
180
181
182
183
  	 * The entries in this struct will be valid if this port is
  	 * hooked up to an hvc console
  	 */
  	struct console cons;
17634ba25   Amit Shah   virtio: console: ...
184

fb08bd274   Amit Shah   virtio: console: ...
185
  	/* Each port associates with a separate char device */
d22a69892   Amit Shah   virtio: console: ...
186
  	struct cdev *cdev;
fb08bd274   Amit Shah   virtio: console: ...
187
  	struct device *dev;
b353a6b82   Amit Shah   virtio: console: ...
188
189
  	/* Reference-counting to handle port hot-unplugs and file operations */
  	struct kref kref;
2030fa496   Amit Shah   virtio: console: ...
190
191
  	/* A waitqueue for poll() or blocking read operations */
  	wait_queue_head_t waitqueue;
431edb8a8   Amit Shah   virtio: console: ...
192
193
  	/* The 'name' of the port that we expose via sysfs properties */
  	char *name;
3eae0adea   Amit Shah   virtio: console: ...
194
195
  	/* We can notify apps of host connect / disconnect events via SIGIO */
  	struct fasync_struct *async_queue;
17634ba25   Amit Shah   virtio: console: ...
196
197
  	/* The 'id' to identify the port with the Host */
  	u32 id;
2030fa496   Amit Shah   virtio: console: ...
198

cdfadfc1a   Amit Shah   virtio: console: ...
199
  	bool outvq_full;
2030fa496   Amit Shah   virtio: console: ...
200
201
  	/* Is the host device open */
  	bool host_connected;
3c7969ccb   Amit Shah   virtio: console: ...
202
203
204
  
  	/* We should allow only one process to open a port */
  	bool guest_connected;
21206ede8   Rusty Russell   virtio: console: ...
205
  };
31610434b   Rusty Russell   Virtio console dr...
206

971f33900   Rusty Russell   virtio: console: ...
207
208
  /* This is the very early arch-specified put chars function. */
  static int (*early_put_chars)(u32, const char *, int);
38edf58d7   Amit Shah   virtio: console: ...
209
210
211
  static struct port *find_port_by_vtermno(u32 vtermno)
  {
  	struct port *port;
4f23c573c   Amit Shah   virtio: console: ...
212
  	struct console *cons;
38edf58d7   Amit Shah   virtio: console: ...
213
214
215
  	unsigned long flags;
  
  	spin_lock_irqsave(&pdrvdata_lock, flags);
4f23c573c   Amit Shah   virtio: console: ...
216
217
218
  	list_for_each_entry(cons, &pdrvdata.consoles, list) {
  		if (cons->vtermno == vtermno) {
  			port = container_of(cons, struct port, cons);
38edf58d7   Amit Shah   virtio: console: ...
219
  			goto out;
4f23c573c   Amit Shah   virtio: console: ...
220
  		}
38edf58d7   Amit Shah   virtio: console: ...
221
222
223
224
225
226
  	}
  	port = NULL;
  out:
  	spin_unlock_irqrestore(&pdrvdata_lock, flags);
  	return port;
  }
04950cdf0   Amit Shah   virtio: console: ...
227
228
229
230
231
232
233
234
  static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev,
  						 dev_t dev)
  {
  	struct port *port;
  	unsigned long flags;
  
  	spin_lock_irqsave(&portdev->ports_lock, flags);
  	list_for_each_entry(port, &portdev->ports, list)
d22a69892   Amit Shah   virtio: console: ...
235
  		if (port->cdev->dev == dev)
04950cdf0   Amit Shah   virtio: console: ...
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  			goto out;
  	port = NULL;
  out:
  	spin_unlock_irqrestore(&portdev->ports_lock, flags);
  
  	return port;
  }
  
  static struct port *find_port_by_devt(dev_t dev)
  {
  	struct ports_device *portdev;
  	struct port *port;
  	unsigned long flags;
  
  	spin_lock_irqsave(&pdrvdata_lock, flags);
  	list_for_each_entry(portdev, &pdrvdata.portdevs, list) {
  		port = find_port_by_devt_in_portdev(portdev, dev);
  		if (port)
  			goto out;
  	}
  	port = NULL;
  out:
  	spin_unlock_irqrestore(&pdrvdata_lock, flags);
  	return port;
  }
17634ba25   Amit Shah   virtio: console: ...
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  static struct port *find_port_by_id(struct ports_device *portdev, u32 id)
  {
  	struct port *port;
  	unsigned long flags;
  
  	spin_lock_irqsave(&portdev->ports_lock, flags);
  	list_for_each_entry(port, &portdev->ports, list)
  		if (port->id == id)
  			goto out;
  	port = NULL;
  out:
  	spin_unlock_irqrestore(&portdev->ports_lock, flags);
  
  	return port;
  }
203baab8b   Amit Shah   virtio: console: ...
276
277
278
279
  static struct port *find_port_by_vq(struct ports_device *portdev,
  				    struct virtqueue *vq)
  {
  	struct port *port;
203baab8b   Amit Shah   virtio: console: ...
280
  	unsigned long flags;
17634ba25   Amit Shah   virtio: console: ...
281
282
  	spin_lock_irqsave(&portdev->ports_lock, flags);
  	list_for_each_entry(port, &portdev->ports, list)
203baab8b   Amit Shah   virtio: console: ...
283
284
  		if (port->in_vq == vq || port->out_vq == vq)
  			goto out;
203baab8b   Amit Shah   virtio: console: ...
285
286
  	port = NULL;
  out:
17634ba25   Amit Shah   virtio: console: ...
287
  	spin_unlock_irqrestore(&portdev->ports_lock, flags);
203baab8b   Amit Shah   virtio: console: ...
288
289
  	return port;
  }
17634ba25   Amit Shah   virtio: console: ...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
  static bool is_console_port(struct port *port)
  {
  	if (port->cons.hvc)
  		return true;
  	return false;
  }
  
  static inline bool use_multiport(struct ports_device *portdev)
  {
  	/*
  	 * This condition can be true when put_chars is called from
  	 * early_init
  	 */
  	if (!portdev->vdev)
  		return 0;
  	return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
  }
fdb9a0545   Amit Shah   virtio: console: ...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
  static void free_buf(struct port_buffer *buf)
  {
  	kfree(buf->buf);
  	kfree(buf);
  }
  
  static struct port_buffer *alloc_buf(size_t buf_size)
  {
  	struct port_buffer *buf;
  
  	buf = kmalloc(sizeof(*buf), GFP_KERNEL);
  	if (!buf)
  		goto fail;
  	buf->buf = kzalloc(buf_size, GFP_KERNEL);
  	if (!buf->buf)
  		goto free_buf;
  	buf->len = 0;
  	buf->offset = 0;
  	buf->size = buf_size;
  	return buf;
  
  free_buf:
  	kfree(buf);
  fail:
  	return NULL;
  }
a3cde4490   Amit Shah   virtio: console: ...
333
  /* Callers should take appropriate locks */
defde6699   Amit Shah   virtio: console: ...
334
  static struct port_buffer *get_inbuf(struct port *port)
a3cde4490   Amit Shah   virtio: console: ...
335
336
  {
  	struct port_buffer *buf;
a3cde4490   Amit Shah   virtio: console: ...
337
  	unsigned int len;
d25a9ddae   Amit Shah   virtio: console: ...
338
339
340
341
  	if (port->inbuf)
  		return port->inbuf;
  
  	buf = virtqueue_get_buf(port->in_vq, &len);
a3cde4490   Amit Shah   virtio: console: ...
342
343
344
  	if (buf) {
  		buf->len = len;
  		buf->offset = 0;
17e5b4f20   Amit Shah   virtio: console: ...
345
  		port->stats.bytes_received += len;
a3cde4490   Amit Shah   virtio: console: ...
346
347
348
  	}
  	return buf;
  }
a23ea9247   Rusty Russell   virtio: console: ...
349
  /*
e27b51980   Amit Shah   virtio: console: ...
350
351
352
353
354
   * Create a scatter-gather list representing our input buffer and put
   * it in the queue.
   *
   * Callers should take appropriate locks.
   */
203baab8b   Amit Shah   virtio: console: ...
355
  static int add_inbuf(struct virtqueue *vq, struct port_buffer *buf)
e27b51980   Amit Shah   virtio: console: ...
356
357
  {
  	struct scatterlist sg[1];
203baab8b   Amit Shah   virtio: console: ...
358
  	int ret;
1c85bf354   Amit Shah   virtio: console: ...
359

e27b51980   Amit Shah   virtio: console: ...
360
  	sg_init_one(sg, buf->buf, buf->size);
f96fde41f   Rusty Russell   virtio: rename vi...
361
  	ret = virtqueue_add_buf(vq, sg, 0, 1, buf, GFP_ATOMIC);
505b0451c   Michael S. Tsirkin   virtio_console: u...
362
  	virtqueue_kick(vq);
203baab8b   Amit Shah   virtio: console: ...
363
364
  	return ret;
  }
88f251ac5   Amit Shah   virtio: console: ...
365
366
367
368
  /* Discard any unread data this port has. Callers lockers. */
  static void discard_port_data(struct port *port)
  {
  	struct port_buffer *buf;
2d24cdaa6   Amit Shah   virtio: console: ...
369
  	unsigned int err;
88f251ac5   Amit Shah   virtio: console: ...
370

d7a62cd03   Amit Shah   virtio: console: ...
371
372
373
374
  	if (!port->portdev) {
  		/* Device has been unplugged.  vqs are already gone. */
  		return;
  	}
2d24cdaa6   Amit Shah   virtio: console: ...
375
  	buf = get_inbuf(port);
88f251ac5   Amit Shah   virtio: console: ...
376

ce072a0ce   Amit Shah   virtio: console: ...
377
  	err = 0;
d69335619   Amit Shah   virtio: console: ...
378
  	while (buf) {
17e5b4f20   Amit Shah   virtio: console: ...
379
  		port->stats.bytes_discarded += buf->len - buf->offset;
2d24cdaa6   Amit Shah   virtio: console: ...
380
  		if (add_inbuf(port->in_vq, buf) < 0) {
ce072a0ce   Amit Shah   virtio: console: ...
381
  			err++;
d69335619   Amit Shah   virtio: console: ...
382
383
  			free_buf(buf);
  		}
2d24cdaa6   Amit Shah   virtio: console: ...
384
385
  		port->inbuf = NULL;
  		buf = get_inbuf(port);
88f251ac5   Amit Shah   virtio: console: ...
386
  	}
ce072a0ce   Amit Shah   virtio: console: ...
387
  	if (err)
d69335619   Amit Shah   virtio: console: ...
388
389
  		dev_warn(port->dev, "Errors adding %d buffers back to vq
  ",
ce072a0ce   Amit Shah   virtio: console: ...
390
  			 err);
88f251ac5   Amit Shah   virtio: console: ...
391
  }
203baab8b   Amit Shah   virtio: console: ...
392
393
394
395
  static bool port_has_data(struct port *port)
  {
  	unsigned long flags;
  	bool ret;
d25a9ddae   Amit Shah   virtio: console: ...
396
  	ret = false;
203baab8b   Amit Shah   virtio: console: ...
397
  	spin_lock_irqsave(&port->inbuf_lock, flags);
d69335619   Amit Shah   virtio: console: ...
398
  	port->inbuf = get_inbuf(port);
d25a9ddae   Amit Shah   virtio: console: ...
399
  	if (port->inbuf)
d69335619   Amit Shah   virtio: console: ...
400
  		ret = true;
d25a9ddae   Amit Shah   virtio: console: ...
401

203baab8b   Amit Shah   virtio: console: ...
402
  	spin_unlock_irqrestore(&port->inbuf_lock, flags);
203baab8b   Amit Shah   virtio: console: ...
403
404
  	return ret;
  }
3425e706b   Amit Shah   virtio: console: ...
405
406
  static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id,
  				  unsigned int event, unsigned int value)
17634ba25   Amit Shah   virtio: console: ...
407
408
409
410
  {
  	struct scatterlist sg[1];
  	struct virtio_console_control cpkt;
  	struct virtqueue *vq;
604b2ad7c   Amit Shah   virtio: console: ...
411
  	unsigned int len;
17634ba25   Amit Shah   virtio: console: ...
412

3425e706b   Amit Shah   virtio: console: ...
413
  	if (!use_multiport(portdev))
17634ba25   Amit Shah   virtio: console: ...
414
  		return 0;
3425e706b   Amit Shah   virtio: console: ...
415
  	cpkt.id = port_id;
17634ba25   Amit Shah   virtio: console: ...
416
417
  	cpkt.event = event;
  	cpkt.value = value;
3425e706b   Amit Shah   virtio: console: ...
418
  	vq = portdev->c_ovq;
17634ba25   Amit Shah   virtio: console: ...
419
420
  
  	sg_init_one(sg, &cpkt, sizeof(cpkt));
f96fde41f   Rusty Russell   virtio: rename vi...
421
  	if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) >= 0) {
505b0451c   Michael S. Tsirkin   virtio_console: u...
422
423
  		virtqueue_kick(vq);
  		while (!virtqueue_get_buf(vq, &len))
17634ba25   Amit Shah   virtio: console: ...
424
425
426
427
  			cpu_relax();
  	}
  	return 0;
  }
3425e706b   Amit Shah   virtio: console: ...
428
429
430
  static ssize_t send_control_msg(struct port *port, unsigned int event,
  				unsigned int value)
  {
84ec06c59   Amit Shah   virtio: console: ...
431
432
433
434
  	/* Did the port get unplugged before userspace closed it? */
  	if (port->portdev)
  		return __send_control_msg(port->portdev, port->id, event, value);
  	return 0;
3425e706b   Amit Shah   virtio: console: ...
435
  }
cdfadfc1a   Amit Shah   virtio: console: ...
436
437
438
439
440
  /* Callers must take the port->outvq_lock */
  static void reclaim_consumed_buffers(struct port *port)
  {
  	void *buf;
  	unsigned int len;
d7a62cd03   Amit Shah   virtio: console: ...
441
442
443
444
  	if (!port->portdev) {
  		/* Device has been unplugged.  vqs are already gone. */
  		return;
  	}
cdfadfc1a   Amit Shah   virtio: console: ...
445
446
447
448
449
450
451
452
  	while ((buf = virtqueue_get_buf(port->out_vq, &len))) {
  		kfree(buf);
  		port->outvq_full = false;
  	}
  }
  
  static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
  			bool nonblock)
f997f00bf   Amit Shah   virtio: console: ...
453
454
455
456
  {
  	struct scatterlist sg[1];
  	struct virtqueue *out_vq;
  	ssize_t ret;
cdfadfc1a   Amit Shah   virtio: console: ...
457
  	unsigned long flags;
f997f00bf   Amit Shah   virtio: console: ...
458
459
460
  	unsigned int len;
  
  	out_vq = port->out_vq;
cdfadfc1a   Amit Shah   virtio: console: ...
461
462
463
  	spin_lock_irqsave(&port->outvq_lock, flags);
  
  	reclaim_consumed_buffers(port);
f997f00bf   Amit Shah   virtio: console: ...
464
  	sg_init_one(sg, in_buf, in_count);
f96fde41f   Rusty Russell   virtio: rename vi...
465
  	ret = virtqueue_add_buf(out_vq, sg, 1, 0, in_buf, GFP_ATOMIC);
f997f00bf   Amit Shah   virtio: console: ...
466
467
  
  	/* Tell Host to go! */
505b0451c   Michael S. Tsirkin   virtio_console: u...
468
  	virtqueue_kick(out_vq);
f997f00bf   Amit Shah   virtio: console: ...
469
470
  
  	if (ret < 0) {
9ff4cfab8   Rusty Russell   virtio: console m...
471
  		in_count = 0;
cdfadfc1a   Amit Shah   virtio: console: ...
472
  		goto done;
f997f00bf   Amit Shah   virtio: console: ...
473
  	}
cdfadfc1a   Amit Shah   virtio: console: ...
474
475
476
477
478
479
480
481
  	if (ret == 0)
  		port->outvq_full = true;
  
  	if (nonblock)
  		goto done;
  
  	/*
  	 * Wait till the host acknowledges it pushed out the data we
531295e63   Amit Shah   virtio: console: ...
482
483
484
485
486
487
  	 * sent.  This is done for data from the hvc_console; the tty
  	 * operations are performed with spinlocks held so we can't
  	 * sleep here.  An alternative would be to copy the data to a
  	 * buffer and relax the spinning requirement.  The downside is
  	 * we need to kmalloc a GFP_ATOMIC buffer each time the
  	 * console driver writes something out.
cdfadfc1a   Amit Shah   virtio: console: ...
488
  	 */
505b0451c   Michael S. Tsirkin   virtio_console: u...
489
  	while (!virtqueue_get_buf(out_vq, &len))
f997f00bf   Amit Shah   virtio: console: ...
490
  		cpu_relax();
cdfadfc1a   Amit Shah   virtio: console: ...
491
492
  done:
  	spin_unlock_irqrestore(&port->outvq_lock, flags);
17e5b4f20   Amit Shah   virtio: console: ...
493
494
  
  	port->stats.bytes_sent += in_count;
cdfadfc1a   Amit Shah   virtio: console: ...
495
496
497
498
  	/*
  	 * We're expected to return the amount of data we wrote -- all
  	 * of it
  	 */
9ff4cfab8   Rusty Russell   virtio: console m...
499
  	return in_count;
f997f00bf   Amit Shah   virtio: console: ...
500
  }
203baab8b   Amit Shah   virtio: console: ...
501
502
503
504
  /*
   * Give out the data that's requested from the buffer that we have
   * queued up.
   */
b766ceed5   Amit Shah   virtio: console: ...
505
506
  static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count,
  			    bool to_user)
203baab8b   Amit Shah   virtio: console: ...
507
508
509
510
511
512
513
514
  {
  	struct port_buffer *buf;
  	unsigned long flags;
  
  	if (!out_count || !port_has_data(port))
  		return 0;
  
  	buf = port->inbuf;
b766ceed5   Amit Shah   virtio: console: ...
515
  	out_count = min(out_count, buf->len - buf->offset);
203baab8b   Amit Shah   virtio: console: ...
516

b766ceed5   Amit Shah   virtio: console: ...
517
518
519
520
521
522
523
524
525
  	if (to_user) {
  		ssize_t ret;
  
  		ret = copy_to_user(out_buf, buf->buf + buf->offset, out_count);
  		if (ret)
  			return -EFAULT;
  	} else {
  		memcpy(out_buf, buf->buf + buf->offset, out_count);
  	}
203baab8b   Amit Shah   virtio: console: ...
526

203baab8b   Amit Shah   virtio: console: ...
527
528
529
530
531
532
533
534
535
536
537
  	buf->offset += out_count;
  
  	if (buf->offset == buf->len) {
  		/*
  		 * We're done using all the data in this buffer.
  		 * Re-queue so that the Host can send us more data.
  		 */
  		spin_lock_irqsave(&port->inbuf_lock, flags);
  		port->inbuf = NULL;
  
  		if (add_inbuf(port->in_vq, buf) < 0)
fb08bd274   Amit Shah   virtio: console: ...
538
539
  			dev_warn(port->dev, "failed add_buf
  ");
203baab8b   Amit Shah   virtio: console: ...
540
541
542
  
  		spin_unlock_irqrestore(&port->inbuf_lock, flags);
  	}
b766ceed5   Amit Shah   virtio: console: ...
543
  	/* Return the number of bytes actually copied */
203baab8b   Amit Shah   virtio: console: ...
544
  	return out_count;
e27b51980   Amit Shah   virtio: console: ...
545
  }
2030fa496   Amit Shah   virtio: console: ...
546
  /* The condition that must be true for polling to end */
60caacd3e   Amit Shah   virtio: console: ...
547
  static bool will_read_block(struct port *port)
2030fa496   Amit Shah   virtio: console: ...
548
  {
3709ea7ae   Amit Shah   virtio: console: ...
549
550
551
552
  	if (!port->guest_connected) {
  		/* Port got hot-unplugged. Let's exit. */
  		return false;
  	}
60caacd3e   Amit Shah   virtio: console: ...
553
  	return !port_has_data(port) && port->host_connected;
2030fa496   Amit Shah   virtio: console: ...
554
  }
cdfadfc1a   Amit Shah   virtio: console: ...
555
556
557
  static bool will_write_block(struct port *port)
  {
  	bool ret;
60e5e0b84   Amit Shah   virtio: console: ...
558
559
560
561
  	if (!port->guest_connected) {
  		/* Port got hot-unplugged. Let's exit. */
  		return false;
  	}
cdfadfc1a   Amit Shah   virtio: console: ...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
  	if (!port->host_connected)
  		return true;
  
  	spin_lock_irq(&port->outvq_lock);
  	/*
  	 * Check if the Host has consumed any buffers since we last
  	 * sent data (this is only applicable for nonblocking ports).
  	 */
  	reclaim_consumed_buffers(port);
  	ret = port->outvq_full;
  	spin_unlock_irq(&port->outvq_lock);
  
  	return ret;
  }
2030fa496   Amit Shah   virtio: console: ...
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
  static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
  			      size_t count, loff_t *offp)
  {
  	struct port *port;
  	ssize_t ret;
  
  	port = filp->private_data;
  
  	if (!port_has_data(port)) {
  		/*
  		 * If nothing's connected on the host just return 0 in
  		 * case of list_empty; this tells the userspace app
  		 * that there's no connection
  		 */
  		if (!port->host_connected)
  			return 0;
  		if (filp->f_flags & O_NONBLOCK)
  			return -EAGAIN;
a08fa92d1   Amit Shah   virtio: console: ...
594
595
  		ret = wait_event_freezable(port->waitqueue,
  					   !will_read_block(port));
2030fa496   Amit Shah   virtio: console: ...
596
597
598
  		if (ret < 0)
  			return ret;
  	}
b3dddb9e6   Amit Shah   virtio: console: ...
599
600
601
  	/* Port got hot-unplugged. */
  	if (!port->guest_connected)
  		return -ENODEV;
2030fa496   Amit Shah   virtio: console: ...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
  	/*
  	 * We could've received a disconnection message while we were
  	 * waiting for more data.
  	 *
  	 * This check is not clubbed in the if() statement above as we
  	 * might receive some data as well as the host could get
  	 * disconnected after we got woken up from our wait.  So we
  	 * really want to give off whatever data we have and only then
  	 * check for host_connected.
  	 */
  	if (!port_has_data(port) && !port->host_connected)
  		return 0;
  
  	return fill_readbuf(port, ubuf, count, true);
  }
  
  static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
  			       size_t count, loff_t *offp)
  {
  	struct port *port;
  	char *buf;
  	ssize_t ret;
cdfadfc1a   Amit Shah   virtio: console: ...
624
  	bool nonblock;
2030fa496   Amit Shah   virtio: console: ...
625

65745422a   Amit Shah   virtio: console: ...
626
627
628
  	/* Userspace could be out to fool us */
  	if (!count)
  		return 0;
2030fa496   Amit Shah   virtio: console: ...
629
  	port = filp->private_data;
cdfadfc1a   Amit Shah   virtio: console: ...
630
631
632
633
634
  	nonblock = filp->f_flags & O_NONBLOCK;
  
  	if (will_write_block(port)) {
  		if (nonblock)
  			return -EAGAIN;
a08fa92d1   Amit Shah   virtio: console: ...
635
636
  		ret = wait_event_freezable(port->waitqueue,
  					   !will_write_block(port));
cdfadfc1a   Amit Shah   virtio: console: ...
637
638
639
  		if (ret < 0)
  			return ret;
  	}
f40281197   Amit Shah   virtio: console: ...
640
641
642
  	/* Port got hot-unplugged. */
  	if (!port->guest_connected)
  		return -ENODEV;
cdfadfc1a   Amit Shah   virtio: console: ...
643

2030fa496   Amit Shah   virtio: console: ...
644
645
646
647
648
649
650
651
652
653
654
  	count = min((size_t)(32 * 1024), count);
  
  	buf = kmalloc(count, GFP_KERNEL);
  	if (!buf)
  		return -ENOMEM;
  
  	ret = copy_from_user(buf, ubuf, count);
  	if (ret) {
  		ret = -EFAULT;
  		goto free_buf;
  	}
531295e63   Amit Shah   virtio: console: ...
655
656
657
658
659
660
661
662
  	/*
  	 * We now ask send_buf() to not spin for generic ports -- we
  	 * can re-use the same code path that non-blocking file
  	 * descriptors take for blocking file descriptors since the
  	 * wait is already done and we're certain the write will go
  	 * through to the host.
  	 */
  	nonblock = true;
cdfadfc1a   Amit Shah   virtio: console: ...
663
664
665
666
  	ret = send_buf(port, buf, count, nonblock);
  
  	if (nonblock && ret > 0)
  		goto out;
2030fa496   Amit Shah   virtio: console: ...
667
668
  free_buf:
  	kfree(buf);
cdfadfc1a   Amit Shah   virtio: console: ...
669
  out:
2030fa496   Amit Shah   virtio: console: ...
670
671
672
673
674
675
676
677
678
679
  	return ret;
  }
  
  static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
  {
  	struct port *port;
  	unsigned int ret;
  
  	port = filp->private_data;
  	poll_wait(filp, &port->waitqueue, wait);
8529a5042   Amit Shah   virtio: console: ...
680
681
682
683
  	if (!port->guest_connected) {
  		/* Port got unplugged */
  		return POLLHUP;
  	}
2030fa496   Amit Shah   virtio: console: ...
684
  	ret = 0;
6df7aadcd   Hans de Goede   virtio: console: ...
685
  	if (!will_read_block(port))
2030fa496   Amit Shah   virtio: console: ...
686
  		ret |= POLLIN | POLLRDNORM;
cdfadfc1a   Amit Shah   virtio: console: ...
687
  	if (!will_write_block(port))
2030fa496   Amit Shah   virtio: console: ...
688
689
690
691
692
693
  		ret |= POLLOUT;
  	if (!port->host_connected)
  		ret |= POLLHUP;
  
  	return ret;
  }
b353a6b82   Amit Shah   virtio: console: ...
694
  static void remove_port(struct kref *kref);
2030fa496   Amit Shah   virtio: console: ...
695
696
697
698
699
700
701
702
  static int port_fops_release(struct inode *inode, struct file *filp)
  {
  	struct port *port;
  
  	port = filp->private_data;
  
  	/* Notify host of port being closed */
  	send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
88f251ac5   Amit Shah   virtio: console: ...
703
  	spin_lock_irq(&port->inbuf_lock);
3c7969ccb   Amit Shah   virtio: console: ...
704
  	port->guest_connected = false;
88f251ac5   Amit Shah   virtio: console: ...
705
706
707
  	discard_port_data(port);
  
  	spin_unlock_irq(&port->inbuf_lock);
cdfadfc1a   Amit Shah   virtio: console: ...
708
709
710
  	spin_lock_irq(&port->outvq_lock);
  	reclaim_consumed_buffers(port);
  	spin_unlock_irq(&port->outvq_lock);
b353a6b82   Amit Shah   virtio: console: ...
711
712
713
714
715
716
717
718
719
  	/*
  	 * Locks aren't necessary here as a port can't be opened after
  	 * unplug, and if a port isn't unplugged, a kref would already
  	 * exist for the port.  Plus, taking ports_lock here would
  	 * create a dependency on other locks taken by functions
  	 * inside remove_port if we're the last holder of the port,
  	 * creating many problems.
  	 */
  	kref_put(&port->kref, remove_port);
2030fa496   Amit Shah   virtio: console: ...
720
721
722
723
724
725
726
  	return 0;
  }
  
  static int port_fops_open(struct inode *inode, struct file *filp)
  {
  	struct cdev *cdev = inode->i_cdev;
  	struct port *port;
8ad37e83c   Amit Shah   virtio: console: ...
727
  	int ret;
2030fa496   Amit Shah   virtio: console: ...
728

04950cdf0   Amit Shah   virtio: console: ...
729
  	port = find_port_by_devt(cdev->dev);
2030fa496   Amit Shah   virtio: console: ...
730
  	filp->private_data = port;
b353a6b82   Amit Shah   virtio: console: ...
731
732
733
734
  	/* Prevent against a port getting hot-unplugged at the same time */
  	spin_lock_irq(&port->portdev->ports_lock);
  	kref_get(&port->kref);
  	spin_unlock_irq(&port->portdev->ports_lock);
2030fa496   Amit Shah   virtio: console: ...
735
736
737
738
  	/*
  	 * Don't allow opening of console port devices -- that's done
  	 * via /dev/hvc
  	 */
8ad37e83c   Amit Shah   virtio: console: ...
739
740
741
742
  	if (is_console_port(port)) {
  		ret = -ENXIO;
  		goto out;
  	}
2030fa496   Amit Shah   virtio: console: ...
743

3c7969ccb   Amit Shah   virtio: console: ...
744
745
746
747
  	/* Allow only one process to open a particular port at a time */
  	spin_lock_irq(&port->inbuf_lock);
  	if (port->guest_connected) {
  		spin_unlock_irq(&port->inbuf_lock);
8ad37e83c   Amit Shah   virtio: console: ...
748
749
  		ret = -EMFILE;
  		goto out;
3c7969ccb   Amit Shah   virtio: console: ...
750
751
752
753
  	}
  
  	port->guest_connected = true;
  	spin_unlock_irq(&port->inbuf_lock);
cdfadfc1a   Amit Shah   virtio: console: ...
754
755
756
757
758
759
760
761
  	spin_lock_irq(&port->outvq_lock);
  	/*
  	 * There might be a chance that we missed reclaiming a few
  	 * buffers in the window of the port getting previously closed
  	 * and opening now.
  	 */
  	reclaim_consumed_buffers(port);
  	spin_unlock_irq(&port->outvq_lock);
299fb61c0   Amit Shah   virtio: console: ...
762
  	nonseekable_open(inode, filp);
2030fa496   Amit Shah   virtio: console: ...
763
764
765
766
  	/* Notify host of port being opened */
  	send_control_msg(filp->private_data, VIRTIO_CONSOLE_PORT_OPEN, 1);
  
  	return 0;
8ad37e83c   Amit Shah   virtio: console: ...
767
  out:
b353a6b82   Amit Shah   virtio: console: ...
768
  	kref_put(&port->kref, remove_port);
8ad37e83c   Amit Shah   virtio: console: ...
769
  	return ret;
2030fa496   Amit Shah   virtio: console: ...
770
  }
3eae0adea   Amit Shah   virtio: console: ...
771
772
773
774
775
776
777
  static int port_fops_fasync(int fd, struct file *filp, int mode)
  {
  	struct port *port;
  
  	port = filp->private_data;
  	return fasync_helper(fd, filp, mode, &port->async_queue);
  }
2030fa496   Amit Shah   virtio: console: ...
778
779
780
781
782
783
784
785
786
787
788
789
790
  /*
   * The file operations that we support: programs in the guest can open
   * a console device, read from it, write to it, poll for data and
   * close it.  The devices are at
   *   /dev/vport<device number>p<port number>
   */
  static const struct file_operations port_fops = {
  	.owner = THIS_MODULE,
  	.open  = port_fops_open,
  	.read  = port_fops_read,
  	.write = port_fops_write,
  	.poll  = port_fops_poll,
  	.release = port_fops_release,
3eae0adea   Amit Shah   virtio: console: ...
791
  	.fasync = port_fops_fasync,
299fb61c0   Amit Shah   virtio: console: ...
792
  	.llseek = no_llseek,
2030fa496   Amit Shah   virtio: console: ...
793
  };
e27b51980   Amit Shah   virtio: console: ...
794
  /*
a23ea9247   Rusty Russell   virtio: console: ...
795
   * The put_chars() callback is pretty straightforward.
31610434b   Rusty Russell   Virtio console dr...
796
   *
a23ea9247   Rusty Russell   virtio: console: ...
797
798
799
800
801
   * We turn the characters into a scatter-gather list, add it to the
   * output queue and then kick the Host.  Then we sit here waiting for
   * it to finish: inefficient in theory, but in practice
   * implementations will do it immediately (lguest's Launcher does).
   */
31610434b   Rusty Russell   Virtio console dr...
802
803
  static int put_chars(u32 vtermno, const char *buf, int count)
  {
21206ede8   Rusty Russell   virtio: console: ...
804
  	struct port *port;
38edf58d7   Amit Shah   virtio: console: ...
805

162a689a1   François Diakhaté   virtio: console: ...
806
807
  	if (unlikely(early_put_chars))
  		return early_put_chars(vtermno, buf, count);
38edf58d7   Amit Shah   virtio: console: ...
808
809
  	port = find_port_by_vtermno(vtermno);
  	if (!port)
6dc69f970   Amit Shah   virtio: console: ...
810
  		return -EPIPE;
31610434b   Rusty Russell   Virtio console dr...
811

cdfadfc1a   Amit Shah   virtio: console: ...
812
  	return send_buf(port, (void *)buf, count, false);
31610434b   Rusty Russell   Virtio console dr...
813
  }
a23ea9247   Rusty Russell   virtio: console: ...
814
  /*
a23ea9247   Rusty Russell   virtio: console: ...
815
816
   * get_chars() is the callback from the hvc_console infrastructure
   * when an interrupt is received.
31610434b   Rusty Russell   Virtio console dr...
817
   *
203baab8b   Amit Shah   virtio: console: ...
818
819
   * We call out to fill_readbuf that gets us the required data from the
   * buffers that are queued up.
a23ea9247   Rusty Russell   virtio: console: ...
820
   */
31610434b   Rusty Russell   Virtio console dr...
821
822
  static int get_chars(u32 vtermno, char *buf, int count)
  {
21206ede8   Rusty Russell   virtio: console: ...
823
  	struct port *port;
6dc69f970   Amit Shah   virtio: console: ...
824
825
826
  	/* If we've not set up the port yet, we have no input to give. */
  	if (unlikely(early_put_chars))
  		return 0;
38edf58d7   Amit Shah   virtio: console: ...
827
828
  	port = find_port_by_vtermno(vtermno);
  	if (!port)
6dc69f970   Amit Shah   virtio: console: ...
829
  		return -EPIPE;
21206ede8   Rusty Russell   virtio: console: ...
830

31610434b   Rusty Russell   Virtio console dr...
831
  	/* If we don't have an input queue yet, we can't get input. */
21206ede8   Rusty Russell   virtio: console: ...
832
  	BUG_ON(!port->in_vq);
31610434b   Rusty Russell   Virtio console dr...
833

b766ceed5   Amit Shah   virtio: console: ...
834
  	return fill_readbuf(port, buf, count, false);
31610434b   Rusty Russell   Virtio console dr...
835
  }
31610434b   Rusty Russell   Virtio console dr...
836

cb06e3676   Amit Shah   virtio: console: ...
837
  static void resize_console(struct port *port)
c29834584   Christian Borntraeger   virtio_console: s...
838
  {
cb06e3676   Amit Shah   virtio: console: ...
839
  	struct virtio_device *vdev;
c29834584   Christian Borntraeger   virtio_console: s...
840

2de16a493   Amit Shah   virtio: console: ...
841
  	/* The port could have been hot-unplugged */
9778829cf   Amit Shah   virtio: console: ...
842
  	if (!port || !is_console_port(port))
2de16a493   Amit Shah   virtio: console: ...
843
  		return;
cb06e3676   Amit Shah   virtio: console: ...
844
  	vdev = port->portdev->vdev;
9778829cf   Amit Shah   virtio: console: ...
845
846
  	if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE))
  		hvc_resize(port->cons.hvc, port->cons.ws);
c29834584   Christian Borntraeger   virtio_console: s...
847
  }
38edf58d7   Amit Shah   virtio: console: ...
848
  /* We set the configuration at this point, since we now have a tty */
91fcad19d   Christian Borntraeger   virtio_console: u...
849
850
  static int notifier_add_vio(struct hvc_struct *hp, int data)
  {
38edf58d7   Amit Shah   virtio: console: ...
851
852
853
854
855
  	struct port *port;
  
  	port = find_port_by_vtermno(hp->vtermno);
  	if (!port)
  		return -EINVAL;
91fcad19d   Christian Borntraeger   virtio_console: u...
856
  	hp->irq_requested = 1;
cb06e3676   Amit Shah   virtio: console: ...
857
  	resize_console(port);
c29834584   Christian Borntraeger   virtio_console: s...
858

91fcad19d   Christian Borntraeger   virtio_console: u...
859
860
861
862
863
864
865
  	return 0;
  }
  
  static void notifier_del_vio(struct hvc_struct *hp, int data)
  {
  	hp->irq_requested = 0;
  }
17634ba25   Amit Shah   virtio: console: ...
866
  /* The operations for console ports. */
1dff39961   Rusty Russell   hvc_console: make...
867
  static const struct hv_ops hv_ops = {
971f33900   Rusty Russell   virtio: console: ...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
  	.get_chars = get_chars,
  	.put_chars = put_chars,
  	.notifier_add = notifier_add_vio,
  	.notifier_del = notifier_del_vio,
  	.notifier_hangup = notifier_del_vio,
  };
  
  /*
   * Console drivers are initialized very early so boot messages can go
   * out, so we do things slightly differently from the generic virtio
   * initialization of the net and block drivers.
   *
   * At this stage, the console is output-only.  It's too early to set
   * up a virtqueue, so we let the drivers do some boutique early-output
   * thing.
   */
  int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
  {
  	early_put_chars = put_chars;
  	return hvc_instantiate(0, 0, &hv_ops);
  }
17634ba25   Amit Shah   virtio: console: ...
889
  int init_port_console(struct port *port)
cfa6d3792   Amit Shah   virtio: console: ...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
  {
  	int ret;
  
  	/*
  	 * The Host's telling us this port is a console port.  Hook it
  	 * up with an hvc console.
  	 *
  	 * To set up and manage our virtual console, we call
  	 * hvc_alloc().
  	 *
  	 * The first argument of hvc_alloc() is the virtual console
  	 * number.  The second argument is the parameter for the
  	 * notification mechanism (like irq number).  We currently
  	 * leave this as zero, virtqueues have implicit notifications.
  	 *
  	 * The third argument is a "struct hv_ops" containing the
  	 * put_chars() get_chars(), notifier_add() and notifier_del()
  	 * pointers.  The final argument is the output buffer size: we
  	 * can do any size, so we put PAGE_SIZE here.
  	 */
  	port->cons.vtermno = pdrvdata.next_vtermno;
  
  	port->cons.hvc = hvc_alloc(port->cons.vtermno, 0, &hv_ops, PAGE_SIZE);
  	if (IS_ERR(port->cons.hvc)) {
  		ret = PTR_ERR(port->cons.hvc);
298add723   Amit Shah   virtio: console: ...
915
916
917
  		dev_err(port->dev,
  			"error %d allocating hvc for port
  ", ret);
cfa6d3792   Amit Shah   virtio: console: ...
918
919
920
921
922
923
924
  		port->cons.hvc = NULL;
  		return ret;
  	}
  	spin_lock_irq(&pdrvdata_lock);
  	pdrvdata.next_vtermno++;
  	list_add_tail(&port->cons.list, &pdrvdata.consoles);
  	spin_unlock_irq(&pdrvdata_lock);
3c7969ccb   Amit Shah   virtio: console: ...
925
  	port->guest_connected = true;
cfa6d3792   Amit Shah   virtio: console: ...
926

1d05160be   Amit Shah   virtio: console: ...
927
928
929
930
931
932
  	/*
  	 * Start using the new console output if this is the first
  	 * console to come up.
  	 */
  	if (early_put_chars)
  		early_put_chars = NULL;
2030fa496   Amit Shah   virtio: console: ...
933
934
  	/* Notify host of port being opened */
  	send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
cfa6d3792   Amit Shah   virtio: console: ...
935
936
  	return 0;
  }
431edb8a8   Amit Shah   virtio: console: ...
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
  static ssize_t show_port_name(struct device *dev,
  			      struct device_attribute *attr, char *buffer)
  {
  	struct port *port;
  
  	port = dev_get_drvdata(dev);
  
  	return sprintf(buffer, "%s
  ", port->name);
  }
  
  static DEVICE_ATTR(name, S_IRUGO, show_port_name, NULL);
  
  static struct attribute *port_sysfs_entries[] = {
  	&dev_attr_name.attr,
  	NULL
  };
  
  static struct attribute_group port_attribute_group = {
  	.name = NULL,		/* put in device directory */
  	.attrs = port_sysfs_entries,
  };
d99393eff   Amit Shah   virtio: console: ...
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
  static int debugfs_open(struct inode *inode, struct file *filp)
  {
  	filp->private_data = inode->i_private;
  	return 0;
  }
  
  static ssize_t debugfs_read(struct file *filp, char __user *ubuf,
  			    size_t count, loff_t *offp)
  {
  	struct port *port;
  	char *buf;
  	ssize_t ret, out_offset, out_count;
  
  	out_count = 1024;
  	buf = kmalloc(out_count, GFP_KERNEL);
  	if (!buf)
  		return -ENOMEM;
  
  	port = filp->private_data;
  	out_offset = 0;
  	out_offset += snprintf(buf + out_offset, out_count,
  			       "name: %s
  ", port->name ? port->name : "");
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
  			       "guest_connected: %d
  ", port->guest_connected);
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
  			       "host_connected: %d
  ", port->host_connected);
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
cdfadfc1a   Amit Shah   virtio: console: ...
989
990
991
  			       "outvq_full: %d
  ", port->outvq_full);
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
17e5b4f20   Amit Shah   virtio: console: ...
992
993
994
995
996
997
998
999
1000
1001
1002
  			       "bytes_sent: %lu
  ", port->stats.bytes_sent);
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
  			       "bytes_received: %lu
  ",
  			       port->stats.bytes_received);
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
  			       "bytes_discarded: %lu
  ",
  			       port->stats.bytes_discarded);
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
d99393eff   Amit Shah   virtio: console: ...
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
  			       "is_console: %s
  ",
  			       is_console_port(port) ? "yes" : "no");
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
  			       "console_vtermno: %u
  ", port->cons.vtermno);
  
  	ret = simple_read_from_buffer(ubuf, count, offp, buf, out_offset);
  	kfree(buf);
  	return ret;
  }
  
  static const struct file_operations port_debugfs_ops = {
  	.owner = THIS_MODULE,
  	.open  = debugfs_open,
  	.read  = debugfs_read,
  };
9778829cf   Amit Shah   virtio: console: ...
1020
1021
1022
1023
1024
1025
1026
1027
  static void set_console_size(struct port *port, u16 rows, u16 cols)
  {
  	if (!port || !is_console_port(port))
  		return;
  
  	port->cons.ws.ws_row = rows;
  	port->cons.ws.ws_col = cols;
  }
c446f8fcc   Amit Shah   virtio: console: ...
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
  static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
  {
  	struct port_buffer *buf;
  	unsigned int nr_added_bufs;
  	int ret;
  
  	nr_added_bufs = 0;
  	do {
  		buf = alloc_buf(PAGE_SIZE);
  		if (!buf)
  			break;
  
  		spin_lock_irq(lock);
  		ret = add_inbuf(vq, buf);
  		if (ret < 0) {
  			spin_unlock_irq(lock);
  			free_buf(buf);
  			break;
  		}
  		nr_added_bufs++;
  		spin_unlock_irq(lock);
  	} while (ret > 0);
  
  	return nr_added_bufs;
  }
3eae0adea   Amit Shah   virtio: console: ...
1053
1054
1055
1056
1057
  static void send_sigio_to_port(struct port *port)
  {
  	if (port->async_queue && port->guest_connected)
  		kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
  }
c446f8fcc   Amit Shah   virtio: console: ...
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
  static int add_port(struct ports_device *portdev, u32 id)
  {
  	char debugfs_name[16];
  	struct port *port;
  	struct port_buffer *buf;
  	dev_t devt;
  	unsigned int nr_added_bufs;
  	int err;
  
  	port = kmalloc(sizeof(*port), GFP_KERNEL);
  	if (!port) {
  		err = -ENOMEM;
  		goto fail;
  	}
b353a6b82   Amit Shah   virtio: console: ...
1072
  	kref_init(&port->kref);
c446f8fcc   Amit Shah   virtio: console: ...
1073
1074
1075
1076
1077
1078
1079
  
  	port->portdev = portdev;
  	port->id = id;
  
  	port->name = NULL;
  	port->inbuf = NULL;
  	port->cons.hvc = NULL;
3eae0adea   Amit Shah   virtio: console: ...
1080
  	port->async_queue = NULL;
c446f8fcc   Amit Shah   virtio: console: ...
1081

9778829cf   Amit Shah   virtio: console: ...
1082
  	port->cons.ws.ws_row = port->cons.ws.ws_col = 0;
c446f8fcc   Amit Shah   virtio: console: ...
1083
  	port->host_connected = port->guest_connected = false;
17e5b4f20   Amit Shah   virtio: console: ...
1084
  	port->stats = (struct port_stats) { 0 };
c446f8fcc   Amit Shah   virtio: console: ...
1085

cdfadfc1a   Amit Shah   virtio: console: ...
1086
  	port->outvq_full = false;
c446f8fcc   Amit Shah   virtio: console: ...
1087
1088
  	port->in_vq = portdev->in_vqs[port->id];
  	port->out_vq = portdev->out_vqs[port->id];
d22a69892   Amit Shah   virtio: console: ...
1089
1090
1091
1092
1093
1094
1095
1096
  	port->cdev = cdev_alloc();
  	if (!port->cdev) {
  		dev_err(&port->portdev->vdev->dev, "Error allocating cdev
  ");
  		err = -ENOMEM;
  		goto free_port;
  	}
  	port->cdev->ops = &port_fops;
c446f8fcc   Amit Shah   virtio: console: ...
1097
1098
  
  	devt = MKDEV(portdev->chr_major, id);
d22a69892   Amit Shah   virtio: console: ...
1099
  	err = cdev_add(port->cdev, devt, 1);
c446f8fcc   Amit Shah   virtio: console: ...
1100
1101
1102
1103
  	if (err < 0) {
  		dev_err(&port->portdev->vdev->dev,
  			"Error %d adding cdev for port %u
  ", err, id);
d22a69892   Amit Shah   virtio: console: ...
1104
  		goto free_cdev;
c446f8fcc   Amit Shah   virtio: console: ...
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
  	}
  	port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
  				  devt, port, "vport%up%u",
  				  port->portdev->drv_index, id);
  	if (IS_ERR(port->dev)) {
  		err = PTR_ERR(port->dev);
  		dev_err(&port->portdev->vdev->dev,
  			"Error %d creating device for port %u
  ",
  			err, id);
  		goto free_cdev;
  	}
  
  	spin_lock_init(&port->inbuf_lock);
cdfadfc1a   Amit Shah   virtio: console: ...
1119
  	spin_lock_init(&port->outvq_lock);
c446f8fcc   Amit Shah   virtio: console: ...
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
  	init_waitqueue_head(&port->waitqueue);
  
  	/* Fill the in_vq with buffers so the host can send us data. */
  	nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
  	if (!nr_added_bufs) {
  		dev_err(port->dev, "Error allocating inbufs
  ");
  		err = -ENOMEM;
  		goto free_device;
  	}
  
  	/*
  	 * If we're not using multiport support, this has to be a console port
  	 */
  	if (!use_multiport(port->portdev)) {
  		err = init_port_console(port);
  		if (err)
  			goto free_inbufs;
  	}
  
  	spin_lock_irq(&portdev->ports_lock);
  	list_add_tail(&port->list, &port->portdev->ports);
  	spin_unlock_irq(&portdev->ports_lock);
  
  	/*
  	 * Tell the Host we're set so that it can send us various
  	 * configuration parameters for this port (eg, port name,
  	 * caching, whether this is a console port, etc.)
  	 */
  	send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
  
  	if (pdrvdata.debugfs_dir) {
  		/*
  		 * Finally, create the debugfs file that we can use to
  		 * inspect a port's state at any time
  		 */
  		sprintf(debugfs_name, "vport%up%u",
  			port->portdev->drv_index, id);
  		port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
  							 pdrvdata.debugfs_dir,
  							 port,
  							 &port_debugfs_ops);
  	}
  	return 0;
  
  free_inbufs:
  	while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
  		free_buf(buf);
  free_device:
  	device_destroy(pdrvdata.class, port->dev->devt);
  free_cdev:
d22a69892   Amit Shah   virtio: console: ...
1171
  	cdev_del(port->cdev);
c446f8fcc   Amit Shah   virtio: console: ...
1172
1173
1174
1175
  free_port:
  	kfree(port);
  fail:
  	/* The host might want to notify management sw about port add failure */
0643e4c6e   Julia Lawall   drivers/char: Eli...
1176
  	__send_control_msg(portdev, id, VIRTIO_CONSOLE_PORT_READY, 0);
c446f8fcc   Amit Shah   virtio: console: ...
1177
1178
  	return err;
  }
b353a6b82   Amit Shah   virtio: console: ...
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
  /* No users remain, remove all port-specific data. */
  static void remove_port(struct kref *kref)
  {
  	struct port *port;
  
  	port = container_of(kref, struct port, kref);
  
  	sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
  	device_destroy(pdrvdata.class, port->dev->devt);
  	cdev_del(port->cdev);
  
  	kfree(port->name);
  
  	debugfs_remove(port->debugfs_file);
  
  	kfree(port);
  }
a0e2dbfc2   Amit Shah   virtio: console: ...
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
  static void remove_port_data(struct port *port)
  {
  	struct port_buffer *buf;
  
  	/* Remove unused data this port might have received. */
  	discard_port_data(port);
  
  	reclaim_consumed_buffers(port);
  
  	/* Remove buffers we queued up for the Host to send us data in. */
  	while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
  		free_buf(buf);
  }
b353a6b82   Amit Shah   virtio: console: ...
1209
1210
1211
1212
1213
1214
  /*
   * Port got unplugged.  Remove port from portdev's list and drop the
   * kref reference.  If no userspace has this port opened, it will
   * result in immediate removal the port.
   */
  static void unplug_port(struct port *port)
1f7aa42d1   Amit Shah   virtio: console: ...
1215
  {
b353a6b82   Amit Shah   virtio: console: ...
1216
1217
1218
  	spin_lock_irq(&port->portdev->ports_lock);
  	list_del(&port->list);
  	spin_unlock_irq(&port->portdev->ports_lock);
0047634d3   Amit Shah   virtio: console: ...
1219
1220
1221
1222
  	if (port->guest_connected) {
  		port->guest_connected = false;
  		port->host_connected = false;
  		wake_up_interruptible(&port->waitqueue);
a461e11e7   Amit Shah   virtio: console: ...
1223
1224
1225
  
  		/* Let the app know the port is going down. */
  		send_sigio_to_port(port);
0047634d3   Amit Shah   virtio: console: ...
1226
  	}
1f7aa42d1   Amit Shah   virtio: console: ...
1227
1228
1229
1230
1231
1232
  	if (is_console_port(port)) {
  		spin_lock_irq(&pdrvdata_lock);
  		list_del(&port->cons.list);
  		spin_unlock_irq(&pdrvdata_lock);
  		hvc_remove(port->cons.hvc);
  	}
1f7aa42d1   Amit Shah   virtio: console: ...
1233

a0e2dbfc2   Amit Shah   virtio: console: ...
1234
  	remove_port_data(port);
a9cdd4855   Amit Shah   virtio: console: ...
1235

b353a6b82   Amit Shah   virtio: console: ...
1236
1237
1238
1239
1240
1241
  	/*
  	 * We should just assume the device itself has gone off --
  	 * else a close on an open port later will try to send out a
  	 * control message.
  	 */
  	port->portdev = NULL;
d99393eff   Amit Shah   virtio: console: ...
1242

b353a6b82   Amit Shah   virtio: console: ...
1243
1244
1245
1246
1247
1248
  	/*
  	 * Locks around here are not necessary - a port can't be
  	 * opened after we removed the port struct from ports_list
  	 * above.
  	 */
  	kref_put(&port->kref, remove_port);
1f7aa42d1   Amit Shah   virtio: console: ...
1249
  }
17634ba25   Amit Shah   virtio: console: ...
1250
1251
1252
1253
1254
1255
  /* Any private messages that the Host and Guest want to share */
  static void handle_control_message(struct ports_device *portdev,
  				   struct port_buffer *buf)
  {
  	struct virtio_console_control *cpkt;
  	struct port *port;
431edb8a8   Amit Shah   virtio: console: ...
1256
1257
  	size_t name_size;
  	int err;
17634ba25   Amit Shah   virtio: console: ...
1258
1259
1260
1261
  
  	cpkt = (struct virtio_console_control *)(buf->buf + buf->offset);
  
  	port = find_port_by_id(portdev, cpkt->id);
f909f850d   Amit Shah   virtio: console: ...
1262
  	if (!port && cpkt->event != VIRTIO_CONSOLE_PORT_ADD) {
17634ba25   Amit Shah   virtio: console: ...
1263
1264
1265
1266
1267
1268
1269
1270
  		/* No valid header at start of buffer.  Drop it. */
  		dev_dbg(&portdev->vdev->dev,
  			"Invalid index %u in control packet
  ", cpkt->id);
  		return;
  	}
  
  	switch (cpkt->event) {
f909f850d   Amit Shah   virtio: console: ...
1271
1272
  	case VIRTIO_CONSOLE_PORT_ADD:
  		if (port) {
1d05160be   Amit Shah   virtio: console: ...
1273
1274
1275
  			dev_dbg(&portdev->vdev->dev,
  				"Port %u already added
  ", port->id);
f909f850d   Amit Shah   virtio: console: ...
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
  			send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
  			break;
  		}
  		if (cpkt->id >= portdev->config.max_nr_ports) {
  			dev_warn(&portdev->vdev->dev,
  				"Request for adding port with out-of-bound id %u, max. supported id: %u
  ",
  				cpkt->id, portdev->config.max_nr_ports - 1);
  			break;
  		}
  		add_port(portdev, cpkt->id);
  		break;
  	case VIRTIO_CONSOLE_PORT_REMOVE:
b353a6b82   Amit Shah   virtio: console: ...
1289
  		unplug_port(port);
f909f850d   Amit Shah   virtio: console: ...
1290
  		break;
17634ba25   Amit Shah   virtio: console: ...
1291
1292
1293
1294
1295
1296
1297
  	case VIRTIO_CONSOLE_CONSOLE_PORT:
  		if (!cpkt->value)
  			break;
  		if (is_console_port(port))
  			break;
  
  		init_port_console(port);
5e38483b3   Christian Borntraeger   virtio: console: ...
1298
  		complete(&early_console_added);
17634ba25   Amit Shah   virtio: console: ...
1299
1300
1301
1302
1303
  		/*
  		 * Could remove the port here in case init fails - but
  		 * have to notify the host first.
  		 */
  		break;
8345adbf9   Amit Shah   virtio: console: ...
1304
1305
1306
1307
1308
  	case VIRTIO_CONSOLE_RESIZE: {
  		struct {
  			__u16 rows;
  			__u16 cols;
  		} size;
17634ba25   Amit Shah   virtio: console: ...
1309
1310
  		if (!is_console_port(port))
  			break;
8345adbf9   Amit Shah   virtio: console: ...
1311
1312
1313
1314
  
  		memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt),
  		       sizeof(size));
  		set_console_size(port, size.rows, size.cols);
17634ba25   Amit Shah   virtio: console: ...
1315
1316
1317
  		port->cons.hvc->irq_requested = 1;
  		resize_console(port);
  		break;
8345adbf9   Amit Shah   virtio: console: ...
1318
  	}
2030fa496   Amit Shah   virtio: console: ...
1319
1320
1321
  	case VIRTIO_CONSOLE_PORT_OPEN:
  		port->host_connected = cpkt->value;
  		wake_up_interruptible(&port->waitqueue);
cdfadfc1a   Amit Shah   virtio: console: ...
1322
1323
1324
1325
1326
1327
1328
1329
  		/*
  		 * If the host port got closed and the host had any
  		 * unconsumed buffers, we'll be able to reclaim them
  		 * now.
  		 */
  		spin_lock_irq(&port->outvq_lock);
  		reclaim_consumed_buffers(port);
  		spin_unlock_irq(&port->outvq_lock);
3eae0adea   Amit Shah   virtio: console: ...
1330
1331
1332
1333
1334
1335
  
  		/*
  		 * If the guest is connected, it'll be interested in
  		 * knowing the host connection state changed.
  		 */
  		send_sigio_to_port(port);
2030fa496   Amit Shah   virtio: console: ...
1336
  		break;
431edb8a8   Amit Shah   virtio: console: ...
1337
1338
  	case VIRTIO_CONSOLE_PORT_NAME:
  		/*
291024ef3   Amit Shah   virtio: console: ...
1339
1340
1341
1342
1343
1344
1345
  		 * If we woke up after hibernation, we can get this
  		 * again.  Skip it in that case.
  		 */
  		if (port->name)
  			break;
  
  		/*
431edb8a8   Amit Shah   virtio: console: ...
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
  		 * Skip the size of the header and the cpkt to get the size
  		 * of the name that was sent
  		 */
  		name_size = buf->len - buf->offset - sizeof(*cpkt) + 1;
  
  		port->name = kmalloc(name_size, GFP_KERNEL);
  		if (!port->name) {
  			dev_err(port->dev,
  				"Not enough space to store port name
  ");
  			break;
  		}
  		strncpy(port->name, buf->buf + buf->offset + sizeof(*cpkt),
  			name_size - 1);
  		port->name[name_size - 1] = 0;
  
  		/*
  		 * Since we only have one sysfs attribute, 'name',
  		 * create it only if we have a name for the port.
  		 */
  		err = sysfs_create_group(&port->dev->kobj,
  					 &port_attribute_group);
ec64213c4   Amit Shah   virtio: console: ...
1368
  		if (err) {
431edb8a8   Amit Shah   virtio: console: ...
1369
1370
1371
1372
  			dev_err(port->dev,
  				"Error %d creating sysfs device attributes
  ",
  				err);
ec64213c4   Amit Shah   virtio: console: ...
1373
1374
1375
1376
1377
1378
1379
1380
  		} else {
  			/*
  			 * Generate a udev event so that appropriate
  			 * symlinks can be created based on udev
  			 * rules.
  			 */
  			kobject_uevent(&port->dev->kobj, KOBJ_CHANGE);
  		}
431edb8a8   Amit Shah   virtio: console: ...
1381
  		break;
17634ba25   Amit Shah   virtio: console: ...
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
  	}
  }
  
  static void control_work_handler(struct work_struct *work)
  {
  	struct ports_device *portdev;
  	struct virtqueue *vq;
  	struct port_buffer *buf;
  	unsigned int len;
  
  	portdev = container_of(work, struct ports_device, control_work);
  	vq = portdev->c_ivq;
  
  	spin_lock(&portdev->cvq_lock);
505b0451c   Michael S. Tsirkin   virtio_console: u...
1396
  	while ((buf = virtqueue_get_buf(vq, &len))) {
17634ba25   Amit Shah   virtio: console: ...
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
  		spin_unlock(&portdev->cvq_lock);
  
  		buf->len = len;
  		buf->offset = 0;
  
  		handle_control_message(portdev, buf);
  
  		spin_lock(&portdev->cvq_lock);
  		if (add_inbuf(portdev->c_ivq, buf) < 0) {
  			dev_warn(&portdev->vdev->dev,
  				 "Error adding buffer to queue
  ");
  			free_buf(buf);
  		}
  	}
  	spin_unlock(&portdev->cvq_lock);
  }
2770c5ea5   Amit Shah   virtio: console: ...
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
  static void out_intr(struct virtqueue *vq)
  {
  	struct port *port;
  
  	port = find_port_by_vq(vq->vdev->priv, vq);
  	if (!port)
  		return;
  
  	wake_up_interruptible(&port->waitqueue);
  }
17634ba25   Amit Shah   virtio: console: ...
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
  static void in_intr(struct virtqueue *vq)
  {
  	struct port *port;
  	unsigned long flags;
  
  	port = find_port_by_vq(vq->vdev->priv, vq);
  	if (!port)
  		return;
  
  	spin_lock_irqsave(&port->inbuf_lock, flags);
d25a9ddae   Amit Shah   virtio: console: ...
1434
  	port->inbuf = get_inbuf(port);
17634ba25   Amit Shah   virtio: console: ...
1435

88f251ac5   Amit Shah   virtio: console: ...
1436
1437
1438
1439
1440
1441
1442
1443
1444
  	/*
  	 * Don't queue up data when port is closed.  This condition
  	 * can be reached when a console port is not yet connected (no
  	 * tty is spawned) and the host sends out data to console
  	 * ports.  For generic serial ports, the host won't
  	 * (shouldn't) send data till the guest is connected.
  	 */
  	if (!port->guest_connected)
  		discard_port_data(port);
17634ba25   Amit Shah   virtio: console: ...
1445
  	spin_unlock_irqrestore(&port->inbuf_lock, flags);
2030fa496   Amit Shah   virtio: console: ...
1446
  	wake_up_interruptible(&port->waitqueue);
55f6bcce3   Amit Shah   virtio: console: ...
1447
1448
  	/* Send a SIGIO indicating new data in case the process asked for it */
  	send_sigio_to_port(port);
17634ba25   Amit Shah   virtio: console: ...
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
  	if (is_console_port(port) && hvc_poll(port->cons.hvc))
  		hvc_kick();
  }
  
  static void control_intr(struct virtqueue *vq)
  {
  	struct ports_device *portdev;
  
  	portdev = vq->vdev->priv;
  	schedule_work(&portdev->control_work);
  }
7f5d810da   Amit Shah   virtio: console: ...
1460
1461
1462
1463
1464
  static void config_intr(struct virtio_device *vdev)
  {
  	struct ports_device *portdev;
  
  	portdev = vdev->priv;
99f905f88   Amit Shah   virtio: console: ...
1465

4038f5b76   Amit Shah   virtio: console: ...
1466
  	if (!use_multiport(portdev)) {
9778829cf   Amit Shah   virtio: console: ...
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
  		struct port *port;
  		u16 rows, cols;
  
  		vdev->config->get(vdev,
  				  offsetof(struct virtio_console_config, cols),
  				  &cols, sizeof(u16));
  		vdev->config->get(vdev,
  				  offsetof(struct virtio_console_config, rows),
  				  &rows, sizeof(u16));
  
  		port = find_port_by_id(portdev, 0);
  		set_console_size(port, rows, cols);
4038f5b76   Amit Shah   virtio: console: ...
1479
1480
1481
1482
1483
1484
1485
  		/*
  		 * We'll use this way of resizing only for legacy
  		 * support.  For newer userspace
  		 * (VIRTIO_CONSOLE_F_MULTPORT+), use control messages
  		 * to indicate console size changes so that it can be
  		 * done per-port.
  		 */
9778829cf   Amit Shah   virtio: console: ...
1486
  		resize_console(port);
4038f5b76   Amit Shah   virtio: console: ...
1487
  	}
7f5d810da   Amit Shah   virtio: console: ...
1488
  }
2658a79ac   Amit Shah   virtio: console: ...
1489
1490
1491
1492
1493
  static int init_vqs(struct ports_device *portdev)
  {
  	vq_callback_t **io_callbacks;
  	char **io_names;
  	struct virtqueue **vqs;
17634ba25   Amit Shah   virtio: console: ...
1494
  	u32 i, j, nr_ports, nr_queues;
2658a79ac   Amit Shah   virtio: console: ...
1495
  	int err;
17634ba25   Amit Shah   virtio: console: ...
1496
1497
  	nr_ports = portdev->config.max_nr_ports;
  	nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;
2658a79ac   Amit Shah   virtio: console: ...
1498
1499
  
  	vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1500
  	io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1501
  	io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1502
1503
  	portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
  				  GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1504
1505
  	portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
  				   GFP_KERNEL);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1506
  	if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs ||
286f9a226   Amit Shah   virtio: console: ...
1507
  	    !portdev->out_vqs) {
2658a79ac   Amit Shah   virtio: console: ...
1508
  		err = -ENOMEM;
22e132ff2   Jiri Slaby   Char: virtio_cons...
1509
  		goto free;
2658a79ac   Amit Shah   virtio: console: ...
1510
  	}
17634ba25   Amit Shah   virtio: console: ...
1511
1512
1513
1514
1515
1516
1517
  	/*
  	 * For backward compat (newer host but older guest), the host
  	 * spawns a console port first and also inits the vqs for port
  	 * 0 before others.
  	 */
  	j = 0;
  	io_callbacks[j] = in_intr;
2770c5ea5   Amit Shah   virtio: console: ...
1518
  	io_callbacks[j + 1] = out_intr;
17634ba25   Amit Shah   virtio: console: ...
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
  	io_names[j] = "input";
  	io_names[j + 1] = "output";
  	j += 2;
  
  	if (use_multiport(portdev)) {
  		io_callbacks[j] = control_intr;
  		io_callbacks[j + 1] = NULL;
  		io_names[j] = "control-i";
  		io_names[j + 1] = "control-o";
  
  		for (i = 1; i < nr_ports; i++) {
  			j += 2;
  			io_callbacks[j] = in_intr;
2770c5ea5   Amit Shah   virtio: console: ...
1532
  			io_callbacks[j + 1] = out_intr;
17634ba25   Amit Shah   virtio: console: ...
1533
1534
1535
1536
  			io_names[j] = "input";
  			io_names[j + 1] = "output";
  		}
  	}
2658a79ac   Amit Shah   virtio: console: ...
1537
1538
1539
1540
1541
  	/* Find the queues. */
  	err = portdev->vdev->config->find_vqs(portdev->vdev, nr_queues, vqs,
  					      io_callbacks,
  					      (const char **)io_names);
  	if (err)
22e132ff2   Jiri Slaby   Char: virtio_cons...
1542
  		goto free;
2658a79ac   Amit Shah   virtio: console: ...
1543

17634ba25   Amit Shah   virtio: console: ...
1544
  	j = 0;
2658a79ac   Amit Shah   virtio: console: ...
1545
1546
  	portdev->in_vqs[0] = vqs[0];
  	portdev->out_vqs[0] = vqs[1];
17634ba25   Amit Shah   virtio: console: ...
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
  	j += 2;
  	if (use_multiport(portdev)) {
  		portdev->c_ivq = vqs[j];
  		portdev->c_ovq = vqs[j + 1];
  
  		for (i = 1; i < nr_ports; i++) {
  			j += 2;
  			portdev->in_vqs[i] = vqs[j];
  			portdev->out_vqs[i] = vqs[j + 1];
  		}
  	}
2658a79ac   Amit Shah   virtio: console: ...
1558
  	kfree(io_names);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1559
  	kfree(io_callbacks);
2658a79ac   Amit Shah   virtio: console: ...
1560
1561
1562
  	kfree(vqs);
  
  	return 0;
22e132ff2   Jiri Slaby   Char: virtio_cons...
1563
  free:
2658a79ac   Amit Shah   virtio: console: ...
1564
  	kfree(portdev->out_vqs);
2658a79ac   Amit Shah   virtio: console: ...
1565
  	kfree(portdev->in_vqs);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1566
1567
  	kfree(io_names);
  	kfree(io_callbacks);
2658a79ac   Amit Shah   virtio: console: ...
1568
  	kfree(vqs);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1569

2658a79ac   Amit Shah   virtio: console: ...
1570
1571
  	return err;
  }
fb08bd274   Amit Shah   virtio: console: ...
1572
1573
1574
  static const struct file_operations portdev_fops = {
  	.owner = THIS_MODULE,
  };
a0e2dbfc2   Amit Shah   virtio: console: ...
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
  static void remove_vqs(struct ports_device *portdev)
  {
  	portdev->vdev->config->del_vqs(portdev->vdev);
  	kfree(portdev->in_vqs);
  	kfree(portdev->out_vqs);
  }
  
  static void remove_controlq_data(struct ports_device *portdev)
  {
  	struct port_buffer *buf;
  	unsigned int len;
  
  	if (!use_multiport(portdev))
  		return;
  
  	while ((buf = virtqueue_get_buf(portdev->c_ivq, &len)))
  		free_buf(buf);
  
  	while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq)))
  		free_buf(buf);
  }
1c85bf354   Amit Shah   virtio: console: ...
1596
1597
1598
  /*
   * Once we're further in boot, we get probed like any other virtio
   * device.
17634ba25   Amit Shah   virtio: console: ...
1599
1600
1601
1602
   *
   * If the host also supports multiple console ports, we check the
   * config space to see how many ports the host has spawned.  We
   * initialize each port found.
1c85bf354   Amit Shah   virtio: console: ...
1603
1604
1605
   */
  static int __devinit virtcons_probe(struct virtio_device *vdev)
  {
1c85bf354   Amit Shah   virtio: console: ...
1606
1607
  	struct ports_device *portdev;
  	int err;
17634ba25   Amit Shah   virtio: console: ...
1608
  	bool multiport;
5e38483b3   Christian Borntraeger   virtio: console: ...
1609
1610
1611
1612
  	bool early = early_put_chars != NULL;
  
  	/* Ensure to read early_put_chars now */
  	barrier();
1c85bf354   Amit Shah   virtio: console: ...
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
  
  	portdev = kmalloc(sizeof(*portdev), GFP_KERNEL);
  	if (!portdev) {
  		err = -ENOMEM;
  		goto fail;
  	}
  
  	/* Attach this portdev to this virtio_device, and vice-versa. */
  	portdev->vdev = vdev;
  	vdev->priv = portdev;
fb08bd274   Amit Shah   virtio: console: ...
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
  	spin_lock_irq(&pdrvdata_lock);
  	portdev->drv_index = pdrvdata.index++;
  	spin_unlock_irq(&pdrvdata_lock);
  
  	portdev->chr_major = register_chrdev(0, "virtio-portsdev",
  					     &portdev_fops);
  	if (portdev->chr_major < 0) {
  		dev_err(&vdev->dev,
  			"Error %d registering chrdev for device %u
  ",
  			portdev->chr_major, portdev->drv_index);
  		err = portdev->chr_major;
  		goto free;
  	}
17634ba25   Amit Shah   virtio: console: ...
1637
  	multiport = false;
17634ba25   Amit Shah   virtio: console: ...
1638
  	portdev->config.max_nr_ports = 1;
51c6d61ac   Sasha Levin   virtio-console: U...
1639
1640
1641
1642
  	if (virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT,
  			      offsetof(struct virtio_console_config,
  				       max_nr_ports),
  			      &portdev->config.max_nr_ports) == 0)
17634ba25   Amit Shah   virtio: console: ...
1643
  		multiport = true;
17634ba25   Amit Shah   virtio: console: ...
1644

2658a79ac   Amit Shah   virtio: console: ...
1645
1646
1647
1648
  	err = init_vqs(portdev);
  	if (err < 0) {
  		dev_err(&vdev->dev, "Error %d initializing vqs
  ", err);
fb08bd274   Amit Shah   virtio: console: ...
1649
  		goto free_chrdev;
2658a79ac   Amit Shah   virtio: console: ...
1650
  	}
1c85bf354   Amit Shah   virtio: console: ...
1651

17634ba25   Amit Shah   virtio: console: ...
1652
1653
1654
1655
  	spin_lock_init(&portdev->ports_lock);
  	INIT_LIST_HEAD(&portdev->ports);
  
  	if (multiport) {
335a64a5c   Amit Shah   virtio: console: ...
1656
  		unsigned int nr_added_bufs;
17634ba25   Amit Shah   virtio: console: ...
1657
1658
  		spin_lock_init(&portdev->cvq_lock);
  		INIT_WORK(&portdev->control_work, &control_work_handler);
335a64a5c   Amit Shah   virtio: console: ...
1659
1660
  		nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
  		if (!nr_added_bufs) {
22a29eacd   Amit Shah   virtio: console: ...
1661
1662
1663
1664
1665
1666
  			dev_err(&vdev->dev,
  				"Error allocating buffers for control queue
  ");
  			err = -ENOMEM;
  			goto free_vqs;
  		}
1d05160be   Amit Shah   virtio: console: ...
1667
1668
1669
1670
1671
1672
  	} else {
  		/*
  		 * For backward compatibility: Create a console port
  		 * if we're running on older host.
  		 */
  		add_port(portdev, 0);
17634ba25   Amit Shah   virtio: console: ...
1673
  	}
6bdf2afd0   Amit Shah   virtio: console: ...
1674
1675
1676
  	spin_lock_irq(&pdrvdata_lock);
  	list_add_tail(&portdev->list, &pdrvdata.portdevs);
  	spin_unlock_irq(&pdrvdata_lock);
f909f850d   Amit Shah   virtio: console: ...
1677
1678
  	__send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
  			   VIRTIO_CONSOLE_DEVICE_READY, 1);
5e38483b3   Christian Borntraeger   virtio: console: ...
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
  
  	/*
  	 * If there was an early virtio console, assume that there are no
  	 * other consoles. We need to wait until the hvc_alloc matches the
  	 * hvc_instantiate, otherwise tty_open will complain, resulting in
  	 * a "Warning: unable to open an initial console" boot failure.
  	 * Without multiport this is done in add_port above. With multiport
  	 * this might take some host<->guest communication - thus we have to
  	 * wait.
  	 */
  	if (multiport && early)
  		wait_for_completion(&early_console_added);
31610434b   Rusty Russell   Virtio console dr...
1691
  	return 0;
22a29eacd   Amit Shah   virtio: console: ...
1692
  free_vqs:
0643e4c6e   Julia Lawall   drivers/char: Eli...
1693
1694
1695
  	/* The host might want to notify mgmt sw about device add failure */
  	__send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
  			   VIRTIO_CONSOLE_DEVICE_READY, 0);
a0e2dbfc2   Amit Shah   virtio: console: ...
1696
  	remove_vqs(portdev);
fb08bd274   Amit Shah   virtio: console: ...
1697
1698
  free_chrdev:
  	unregister_chrdev(portdev->chr_major, "virtio-portsdev");
31610434b   Rusty Russell   Virtio console dr...
1699
  free:
1c85bf354   Amit Shah   virtio: console: ...
1700
  	kfree(portdev);
31610434b   Rusty Russell   Virtio console dr...
1701
1702
1703
  fail:
  	return err;
  }
7177876fe   Amit Shah   virtio: console: ...
1704
1705
1706
1707
  static void virtcons_remove(struct virtio_device *vdev)
  {
  	struct ports_device *portdev;
  	struct port *port, *port2;
7177876fe   Amit Shah   virtio: console: ...
1708
1709
  
  	portdev = vdev->priv;
6bdf2afd0   Amit Shah   virtio: console: ...
1710
1711
1712
  	spin_lock_irq(&pdrvdata_lock);
  	list_del(&portdev->list);
  	spin_unlock_irq(&pdrvdata_lock);
022389599   Amit Shah   virtio: console: ...
1713
1714
1715
  	/* Disable interrupts for vqs */
  	vdev->config->reset(vdev);
  	/* Finish up work that's lined up */
7177876fe   Amit Shah   virtio: console: ...
1716
  	cancel_work_sync(&portdev->control_work);
7177876fe   Amit Shah   virtio: console: ...
1717
1718
  
  	list_for_each_entry_safe(port, port2, &portdev->ports, list)
b353a6b82   Amit Shah   virtio: console: ...
1719
  		unplug_port(port);
7177876fe   Amit Shah   virtio: console: ...
1720
1721
  
  	unregister_chrdev(portdev->chr_major, "virtio-portsdev");
e062013c7   Amit Shah   virtio: console: ...
1722
1723
1724
1725
1726
1727
1728
1729
  	/*
  	 * When yanking out a device, we immediately lose the
  	 * (device-side) queues.  So there's no point in keeping the
  	 * guest side around till we drop our final reference.  This
  	 * also means that any ports which are in an open state will
  	 * have to just stop using the port, as the vqs are going
  	 * away.
  	 */
a0e2dbfc2   Amit Shah   virtio: console: ...
1730
1731
  	remove_controlq_data(portdev);
  	remove_vqs(portdev);
7177876fe   Amit Shah   virtio: console: ...
1732
1733
  	kfree(portdev);
  }
31610434b   Rusty Russell   Virtio console dr...
1734
1735
1736
1737
  static struct virtio_device_id id_table[] = {
  	{ VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
  	{ 0 },
  };
c29834584   Christian Borntraeger   virtio_console: s...
1738
1739
  static unsigned int features[] = {
  	VIRTIO_CONSOLE_F_SIZE,
b99fa815d   Amit Shah   virtio: Revert "v...
1740
  	VIRTIO_CONSOLE_F_MULTIPORT,
c29834584   Christian Borntraeger   virtio_console: s...
1741
  };
2b8f41d84   Amit Shah   virtio: console: ...
1742
1743
1744
1745
1746
1747
1748
1749
1750
  #ifdef CONFIG_PM
  static int virtcons_freeze(struct virtio_device *vdev)
  {
  	struct ports_device *portdev;
  	struct port *port;
  
  	portdev = vdev->priv;
  
  	vdev->config->reset(vdev);
c743d09db   Amit Shah   virtio: console: ...
1751
  	virtqueue_disable_cb(portdev->c_ivq);
2b8f41d84   Amit Shah   virtio: console: ...
1752
  	cancel_work_sync(&portdev->control_work);
c743d09db   Amit Shah   virtio: console: ...
1753
1754
1755
1756
1757
  	/*
  	 * Once more: if control_work_handler() was running, it would
  	 * enable the cb as the last step.
  	 */
  	virtqueue_disable_cb(portdev->c_ivq);
2b8f41d84   Amit Shah   virtio: console: ...
1758
1759
1760
  	remove_controlq_data(portdev);
  
  	list_for_each_entry(port, &portdev->ports, list) {
c743d09db   Amit Shah   virtio: console: ...
1761
1762
  		virtqueue_disable_cb(port->in_vq);
  		virtqueue_disable_cb(port->out_vq);
2b8f41d84   Amit Shah   virtio: console: ...
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
  		/*
  		 * We'll ask the host later if the new invocation has
  		 * the port opened or closed.
  		 */
  		port->host_connected = false;
  		remove_port_data(port);
  	}
  	remove_vqs(portdev);
  
  	return 0;
  }
  
  static int virtcons_restore(struct virtio_device *vdev)
  {
  	struct ports_device *portdev;
  	struct port *port;
  	int ret;
  
  	portdev = vdev->priv;
  
  	ret = init_vqs(portdev);
  	if (ret)
  		return ret;
  
  	if (use_multiport(portdev))
  		fill_queue(portdev->c_ivq, &portdev->cvq_lock);
  
  	list_for_each_entry(port, &portdev->ports, list) {
  		port->in_vq = portdev->in_vqs[port->id];
  		port->out_vq = portdev->out_vqs[port->id];
  
  		fill_queue(port->in_vq, &port->inbuf_lock);
  
  		/* Get port open/close status on the host */
  		send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
  	}
  	return 0;
  }
  #endif
31610434b   Rusty Russell   Virtio console dr...
1802
  static struct virtio_driver virtio_console = {
c29834584   Christian Borntraeger   virtio_console: s...
1803
1804
  	.feature_table = features,
  	.feature_table_size = ARRAY_SIZE(features),
31610434b   Rusty Russell   Virtio console dr...
1805
1806
1807
1808
  	.driver.name =	KBUILD_MODNAME,
  	.driver.owner =	THIS_MODULE,
  	.id_table =	id_table,
  	.probe =	virtcons_probe,
7177876fe   Amit Shah   virtio: console: ...
1809
  	.remove =	virtcons_remove,
7f5d810da   Amit Shah   virtio: console: ...
1810
  	.config_changed = config_intr,
2b8f41d84   Amit Shah   virtio: console: ...
1811
1812
1813
1814
  #ifdef CONFIG_PM
  	.freeze =	virtcons_freeze,
  	.restore =	virtcons_restore,
  #endif
31610434b   Rusty Russell   Virtio console dr...
1815
1816
1817
1818
  };
  
  static int __init init(void)
  {
fb08bd274   Amit Shah   virtio: console: ...
1819
1820
1821
1822
1823
1824
1825
1826
1827
  	int err;
  
  	pdrvdata.class = class_create(THIS_MODULE, "virtio-ports");
  	if (IS_ERR(pdrvdata.class)) {
  		err = PTR_ERR(pdrvdata.class);
  		pr_err("Error %d creating virtio-ports class
  ", err);
  		return err;
  	}
d99393eff   Amit Shah   virtio: console: ...
1828
1829
1830
1831
1832
1833
1834
  
  	pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
  	if (!pdrvdata.debugfs_dir) {
  		pr_warning("Error %ld creating debugfs dir for virtio-ports
  ",
  			   PTR_ERR(pdrvdata.debugfs_dir));
  	}
38edf58d7   Amit Shah   virtio: console: ...
1835
  	INIT_LIST_HEAD(&pdrvdata.consoles);
6bdf2afd0   Amit Shah   virtio: console: ...
1836
  	INIT_LIST_HEAD(&pdrvdata.portdevs);
38edf58d7   Amit Shah   virtio: console: ...
1837

31610434b   Rusty Russell   Virtio console dr...
1838
1839
  	return register_virtio_driver(&virtio_console);
  }
7177876fe   Amit Shah   virtio: console: ...
1840
1841
1842
1843
1844
1845
1846
1847
1848
  
  static void __exit fini(void)
  {
  	unregister_virtio_driver(&virtio_console);
  
  	class_destroy(pdrvdata.class);
  	if (pdrvdata.debugfs_dir)
  		debugfs_remove_recursive(pdrvdata.debugfs_dir);
  }
31610434b   Rusty Russell   Virtio console dr...
1849
  module_init(init);
7177876fe   Amit Shah   virtio: console: ...
1850
  module_exit(fini);
31610434b   Rusty Russell   Virtio console dr...
1851
1852
1853
1854
  
  MODULE_DEVICE_TABLE(virtio, id_table);
  MODULE_DESCRIPTION("Virtio console driver");
  MODULE_LICENSE("GPL");