Blame view

drivers/char/virtio_console.c 56.5 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>
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
27
28
  #include <linux/splice.h>
  #include <linux/pagemap.h>
31610434b   Rusty Russell   Virtio console dr...
29
  #include <linux/init.h>
38edf58d7   Amit Shah   virtio: console: ...
30
  #include <linux/list.h>
2030fa496   Amit Shah   virtio: console: ...
31
32
  #include <linux/poll.h>
  #include <linux/sched.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
33
  #include <linux/slab.h>
38edf58d7   Amit Shah   virtio: console: ...
34
  #include <linux/spinlock.h>
31610434b   Rusty Russell   Virtio console dr...
35
36
  #include <linux/virtio.h>
  #include <linux/virtio_console.h>
2030fa496   Amit Shah   virtio: console: ...
37
  #include <linux/wait.h>
17634ba25   Amit Shah   virtio: console: ...
38
  #include <linux/workqueue.h>
c22405c98   Paul Gortmaker   drivers/char: Add...
39
  #include <linux/module.h>
1b6370463   Sjur Brændeland   virtio_console: A...
40
  #include <linux/dma-mapping.h>
51df0acc3   Amit Shah   virtio: console: ...
41
  #include "../tty/hvc/hvc_console.h"
31610434b   Rusty Russell   Virtio console dr...
42

1b6370463   Sjur Brændeland   virtio_console: A...
43
  #define is_rproc_enabled IS_ENABLED(CONFIG_REMOTEPROC)
38edf58d7   Amit Shah   virtio: console: ...
44
45
46
47
48
49
50
51
52
  /*
   * 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: ...
53
54
  	/* Used for registering chardevs */
  	struct class *class;
d99393eff   Amit Shah   virtio: console: ...
55
56
  	/* Used for exporting per-port information to debugfs */
  	struct dentry *debugfs_dir;
6bdf2afd0   Amit Shah   virtio: console: ...
57
58
  	/* List of all the devices we're handling */
  	struct list_head portdevs;
d8a02bd58   Rusty Russell   virtio: console: ...
59
60
61
62
63
64
65
66
67
68
69
  	/*
  	 * 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: ...
70
71
72
73
  	/* All the console devices handled by this driver */
  	struct list_head consoles;
  };
  static struct ports_driver_data pdrvdata;
3826835ab   Wei Yongjun   virtio_console: m...
74
75
  static DEFINE_SPINLOCK(pdrvdata_lock);
  static DECLARE_COMPLETION(early_console_added);
38edf58d7   Amit Shah   virtio: console: ...
76

4f23c573c   Amit Shah   virtio: console: ...
77
78
79
80
81
82
83
  /* 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: ...
84
85
  	/* The size of the console */
  	struct winsize ws;
4f23c573c   Amit Shah   virtio: console: ...
86
87
88
89
90
91
92
93
94
  	/*
  	 * 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: ...
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;
276a3e954   Sjur Brændeland   virtio_console: M...
105

1b6370463   Sjur Brændeland   virtio_console: A...
106
107
108
109
110
111
112
113
  	/* DMA address of buffer */
  	dma_addr_t dma;
  
  	/* Device we got DMA memory from */
  	struct device *dev;
  
  	/* List of pending dma buffers to free */
  	struct list_head list;
276a3e954   Sjur Brændeland   virtio_console: M...
114
115
116
117
118
  	/* If sgpages == 0 then buf is used */
  	unsigned int sgpages;
  
  	/* sg is used if spages > 0. sg must be the last in is struct */
  	struct scatterlist sg[0];
fdb9a0545   Amit Shah   virtio: console: ...
119
  };
17634ba25   Amit Shah   virtio: console: ...
120
121
122
123
124
  /*
   * 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: ...
125
126
  	/* Next portdev in the list, head is in the pdrvdata struct */
  	struct list_head list;
17634ba25   Amit Shah   virtio: console: ...
127
128
129
130
131
  	/*
  	 * Workqueue handlers where we process deferred work after
  	 * notification
  	 */
  	struct work_struct control_work;
eeb8a7e8b   Michael S. Tsirkin   virtio_console: a...
132
  	struct work_struct config_work;
17634ba25   Amit Shah   virtio: console: ...
133
134
135
136
137
138
139
  
  	struct list_head ports;
  
  	/* To protect the list of ports */
  	spinlock_t ports_lock;
  
  	/* To protect the vq operations for the control channel */
165b1b8bb   Amit Shah   virtio: console: ...
140
  	spinlock_t c_ivq_lock;
9ba5c80b1   Amit Shah   virtio: console: ...
141
  	spinlock_t c_ovq_lock;
17634ba25   Amit Shah   virtio: console: ...
142
143
  
  	/* The current config space is stored here */
b99fa815d   Amit Shah   virtio: Revert "v...
144
  	struct virtio_console_config config;
17634ba25   Amit Shah   virtio: console: ...
145
146
147
148
149
150
151
152
153
  
  	/* 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;
5e59d9a1a   Andy Lutomirski   virtio_console: S...
154
155
156
157
158
  	/*
  	 * A control packet buffer for guest->host requests, protected
  	 * by c_ovq_lock.
  	 */
  	struct virtio_console_control cpkt;
17634ba25   Amit Shah   virtio: console: ...
159
160
  	/* Array of per-port IO virtqueues */
  	struct virtqueue **in_vqs, **out_vqs;
fb08bd274   Amit Shah   virtio: console: ...
161

fb08bd274   Amit Shah   virtio: console: ...
162
163
  	/* Major number for this device.  Ports will be created as minors. */
  	int chr_major;
17634ba25   Amit Shah   virtio: console: ...
164
  };
17e5b4f20   Amit Shah   virtio: console: ...
165
166
167
  struct port_stats {
  	unsigned long bytes_sent, bytes_received, bytes_discarded;
  };
1c85bf354   Amit Shah   virtio: console: ...
168
  /* This struct holds the per-port data */
21206ede8   Rusty Russell   virtio: console: ...
169
  struct port {
17634ba25   Amit Shah   virtio: console: ...
170
171
  	/* Next port in the list, head is in the ports_device */
  	struct list_head list;
1c85bf354   Amit Shah   virtio: console: ...
172
173
  	/* Pointer to the parent virtio_console device */
  	struct ports_device *portdev;
fdb9a0545   Amit Shah   virtio: console: ...
174
175
176
  
  	/* The current buffer from which data has to be fed to readers */
  	struct port_buffer *inbuf;
21206ede8   Rusty Russell   virtio: console: ...
177

203baab8b   Amit Shah   virtio: console: ...
178
179
180
181
182
183
  	/*
  	 * 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: ...
184
185
  	/* Protect the operations on the out_vq. */
  	spinlock_t outvq_lock;
1c85bf354   Amit Shah   virtio: console: ...
186
187
  	/* The IO vqs for this port */
  	struct virtqueue *in_vq, *out_vq;
d99393eff   Amit Shah   virtio: console: ...
188
189
  	/* File in the debugfs directory that exposes this port's information */
  	struct dentry *debugfs_file;
4f23c573c   Amit Shah   virtio: console: ...
190
  	/*
17e5b4f20   Amit Shah   virtio: console: ...
191
192
193
194
195
196
197
  	 * 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: ...
198
199
200
201
  	 * 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: ...
202

fb08bd274   Amit Shah   virtio: console: ...
203
  	/* Each port associates with a separate char device */
d22a69892   Amit Shah   virtio: console: ...
204
  	struct cdev *cdev;
fb08bd274   Amit Shah   virtio: console: ...
205
  	struct device *dev;
b353a6b82   Amit Shah   virtio: console: ...
206
207
  	/* Reference-counting to handle port hot-unplugs and file operations */
  	struct kref kref;
2030fa496   Amit Shah   virtio: console: ...
208
209
  	/* A waitqueue for poll() or blocking read operations */
  	wait_queue_head_t waitqueue;
431edb8a8   Amit Shah   virtio: console: ...
210
211
  	/* The 'name' of the port that we expose via sysfs properties */
  	char *name;
3eae0adea   Amit Shah   virtio: console: ...
212
213
  	/* We can notify apps of host connect / disconnect events via SIGIO */
  	struct fasync_struct *async_queue;
17634ba25   Amit Shah   virtio: console: ...
214
215
  	/* The 'id' to identify the port with the Host */
  	u32 id;
2030fa496   Amit Shah   virtio: console: ...
216

cdfadfc1a   Amit Shah   virtio: console: ...
217
  	bool outvq_full;
2030fa496   Amit Shah   virtio: console: ...
218
219
  	/* Is the host device open */
  	bool host_connected;
3c7969ccb   Amit Shah   virtio: console: ...
220
221
222
  
  	/* We should allow only one process to open a port */
  	bool guest_connected;
21206ede8   Rusty Russell   virtio: console: ...
223
  };
31610434b   Rusty Russell   Virtio console dr...
224

971f33900   Rusty Russell   virtio: console: ...
225
226
  /* This is the very early arch-specified put chars function. */
  static int (*early_put_chars)(u32, const char *, int);
38edf58d7   Amit Shah   virtio: console: ...
227
228
229
  static struct port *find_port_by_vtermno(u32 vtermno)
  {
  	struct port *port;
4f23c573c   Amit Shah   virtio: console: ...
230
  	struct console *cons;
38edf58d7   Amit Shah   virtio: console: ...
231
232
233
  	unsigned long flags;
  
  	spin_lock_irqsave(&pdrvdata_lock, flags);
4f23c573c   Amit Shah   virtio: console: ...
234
235
236
  	list_for_each_entry(cons, &pdrvdata.consoles, list) {
  		if (cons->vtermno == vtermno) {
  			port = container_of(cons, struct port, cons);
38edf58d7   Amit Shah   virtio: console: ...
237
  			goto out;
4f23c573c   Amit Shah   virtio: console: ...
238
  		}
38edf58d7   Amit Shah   virtio: console: ...
239
240
241
242
243
244
  	}
  	port = NULL;
  out:
  	spin_unlock_irqrestore(&pdrvdata_lock, flags);
  	return port;
  }
04950cdf0   Amit Shah   virtio: console: ...
245
246
247
248
249
250
251
  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);
057b82be3   Amit Shah   virtio: console: ...
252
253
254
  	list_for_each_entry(port, &portdev->ports, list) {
  		if (port->cdev->dev == dev) {
  			kref_get(&port->kref);
04950cdf0   Amit Shah   virtio: console: ...
255
  			goto out;
057b82be3   Amit Shah   virtio: console: ...
256
257
  		}
  	}
04950cdf0   Amit Shah   virtio: console: ...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
  	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: ...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
  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: ...
297
298
299
300
  static struct port *find_port_by_vq(struct ports_device *portdev,
  				    struct virtqueue *vq)
  {
  	struct port *port;
203baab8b   Amit Shah   virtio: console: ...
301
  	unsigned long flags;
17634ba25   Amit Shah   virtio: console: ...
302
303
  	spin_lock_irqsave(&portdev->ports_lock, flags);
  	list_for_each_entry(port, &portdev->ports, list)
203baab8b   Amit Shah   virtio: console: ...
304
305
  		if (port->in_vq == vq || port->out_vq == vq)
  			goto out;
203baab8b   Amit Shah   virtio: console: ...
306
307
  	port = NULL;
  out:
17634ba25   Amit Shah   virtio: console: ...
308
  	spin_unlock_irqrestore(&portdev->ports_lock, flags);
203baab8b   Amit Shah   virtio: console: ...
309
310
  	return port;
  }
17634ba25   Amit Shah   virtio: console: ...
311
312
313
314
315
316
  static bool is_console_port(struct port *port)
  {
  	if (port->cons.hvc)
  		return true;
  	return false;
  }
1b6370463   Sjur Brændeland   virtio_console: A...
317
318
319
320
  static bool is_rproc_serial(const struct virtio_device *vdev)
  {
  	return is_rproc_enabled && vdev->id.device == VIRTIO_ID_RPROC_SERIAL;
  }
17634ba25   Amit Shah   virtio: console: ...
321
322
323
324
325
326
327
  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)
f580d730c   Joe Perches   virtio_console: U...
328
  		return false;
e16e12be3   Michael S. Tsirkin   virtio: use u32, ...
329
  	return __virtio_test_bit(portdev->vdev, VIRTIO_CONSOLE_F_MULTIPORT);
17634ba25   Amit Shah   virtio: console: ...
330
  }
1b6370463   Sjur Brændeland   virtio_console: A...
331
332
333
334
  static DEFINE_SPINLOCK(dma_bufs_lock);
  static LIST_HEAD(pending_free_dma_bufs);
  
  static void free_buf(struct port_buffer *buf, bool can_sleep)
fdb9a0545   Amit Shah   virtio: console: ...
335
  {
276a3e954   Sjur Brændeland   virtio_console: M...
336
  	unsigned int i;
276a3e954   Sjur Brændeland   virtio_console: M...
337
338
339
340
341
342
  	for (i = 0; i < buf->sgpages; i++) {
  		struct page *page = sg_page(&buf->sg[i]);
  		if (!page)
  			break;
  		put_page(page);
  	}
1b6370463   Sjur Brændeland   virtio_console: A...
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
  	if (!buf->dev) {
  		kfree(buf->buf);
  	} else if (is_rproc_enabled) {
  		unsigned long flags;
  
  		/* dma_free_coherent requires interrupts to be enabled. */
  		if (!can_sleep) {
  			/* queue up dma-buffers to be freed later */
  			spin_lock_irqsave(&dma_bufs_lock, flags);
  			list_add_tail(&buf->list, &pending_free_dma_bufs);
  			spin_unlock_irqrestore(&dma_bufs_lock, flags);
  			return;
  		}
  		dma_free_coherent(buf->dev, buf->size, buf->buf, buf->dma);
  
  		/* Release device refcnt and allow it to be freed */
  		put_device(buf->dev);
  	}
fdb9a0545   Amit Shah   virtio: console: ...
361
362
  	kfree(buf);
  }
1b6370463   Sjur Brændeland   virtio_console: A...
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
  static void reclaim_dma_bufs(void)
  {
  	unsigned long flags;
  	struct port_buffer *buf, *tmp;
  	LIST_HEAD(tmp_list);
  
  	if (list_empty(&pending_free_dma_bufs))
  		return;
  
  	/* Create a copy of the pending_free_dma_bufs while holding the lock */
  	spin_lock_irqsave(&dma_bufs_lock, flags);
  	list_cut_position(&tmp_list, &pending_free_dma_bufs,
  			  pending_free_dma_bufs.prev);
  	spin_unlock_irqrestore(&dma_bufs_lock, flags);
  
  	/* Release the dma buffers, without irqs enabled */
  	list_for_each_entry_safe(buf, tmp, &tmp_list, list) {
  		list_del(&buf->list);
  		free_buf(buf, true);
  	}
  }
276a3e954   Sjur Brændeland   virtio_console: M...
384
385
  static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
  				     int pages)
fdb9a0545   Amit Shah   virtio: console: ...
386
387
  {
  	struct port_buffer *buf;
1b6370463   Sjur Brændeland   virtio_console: A...
388
  	reclaim_dma_bufs();
276a3e954   Sjur Brændeland   virtio_console: M...
389
390
391
392
393
394
  	/*
  	 * Allocate buffer and the sg list. The sg list array is allocated
  	 * directly after the port_buffer struct.
  	 */
  	buf = kmalloc(sizeof(*buf) + sizeof(struct scatterlist) * pages,
  		      GFP_KERNEL);
fdb9a0545   Amit Shah   virtio: console: ...
395
396
  	if (!buf)
  		goto fail;
276a3e954   Sjur Brændeland   virtio_console: M...
397
398
399
  
  	buf->sgpages = pages;
  	if (pages > 0) {
1b6370463   Sjur Brændeland   virtio_console: A...
400
  		buf->dev = NULL;
276a3e954   Sjur Brændeland   virtio_console: M...
401
402
403
  		buf->buf = NULL;
  		return buf;
  	}
1b6370463   Sjur Brændeland   virtio_console: A...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
  	if (is_rproc_serial(vq->vdev)) {
  		/*
  		 * Allocate DMA memory from ancestor. When a virtio
  		 * device is created by remoteproc, the DMA memory is
  		 * associated with the grandparent device:
  		 * vdev => rproc => platform-dev.
  		 * The code here would have been less quirky if
  		 * DMA_MEMORY_INCLUDES_CHILDREN had been supported
  		 * in dma-coherent.c
  		 */
  		if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
  			goto free_buf;
  		buf->dev = vq->vdev->dev.parent->parent;
  
  		/* Increase device refcnt to avoid freeing it */
  		get_device(buf->dev);
  		buf->buf = dma_alloc_coherent(buf->dev, buf_size, &buf->dma,
  					      GFP_KERNEL);
  	} else {
  		buf->dev = NULL;
  		buf->buf = kmalloc(buf_size, GFP_KERNEL);
  	}
fdb9a0545   Amit Shah   virtio: console: ...
426
427
428
429
430
431
432
433
434
435
436
437
  	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: ...
438
  /* Callers should take appropriate locks */
defde6699   Amit Shah   virtio: console: ...
439
  static struct port_buffer *get_inbuf(struct port *port)
a3cde4490   Amit Shah   virtio: console: ...
440
441
  {
  	struct port_buffer *buf;
a3cde4490   Amit Shah   virtio: console: ...
442
  	unsigned int len;
d25a9ddae   Amit Shah   virtio: console: ...
443
444
445
446
  	if (port->inbuf)
  		return port->inbuf;
  
  	buf = virtqueue_get_buf(port->in_vq, &len);
a3cde4490   Amit Shah   virtio: console: ...
447
448
449
  	if (buf) {
  		buf->len = len;
  		buf->offset = 0;
17e5b4f20   Amit Shah   virtio: console: ...
450
  		port->stats.bytes_received += len;
a3cde4490   Amit Shah   virtio: console: ...
451
452
453
  	}
  	return buf;
  }
a23ea9247   Rusty Russell   virtio: console: ...
454
  /*
e27b51980   Amit Shah   virtio: console: ...
455
456
457
458
459
   * 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: ...
460
  static int add_inbuf(struct virtqueue *vq, struct port_buffer *buf)
e27b51980   Amit Shah   virtio: console: ...
461
462
  {
  	struct scatterlist sg[1];
203baab8b   Amit Shah   virtio: console: ...
463
  	int ret;
1c85bf354   Amit Shah   virtio: console: ...
464

e27b51980   Amit Shah   virtio: console: ...
465
  	sg_init_one(sg, buf->buf, buf->size);
6797999d9   Rusty Russell   virtio_console: u...
466
  	ret = virtqueue_add_inbuf(vq, sg, 1, buf, GFP_ATOMIC);
505b0451c   Michael S. Tsirkin   virtio_console: u...
467
  	virtqueue_kick(vq);
49e86f168   Amit Shah   virtio: console: ...
468
469
  	if (!ret)
  		ret = vq->num_free;
203baab8b   Amit Shah   virtio: console: ...
470
471
  	return ret;
  }
88f251ac5   Amit Shah   virtio: console: ...
472
473
474
475
  /* 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: ...
476
  	unsigned int err;
88f251ac5   Amit Shah   virtio: console: ...
477

d7a62cd03   Amit Shah   virtio: console: ...
478
479
480
481
  	if (!port->portdev) {
  		/* Device has been unplugged.  vqs are already gone. */
  		return;
  	}
2d24cdaa6   Amit Shah   virtio: console: ...
482
  	buf = get_inbuf(port);
88f251ac5   Amit Shah   virtio: console: ...
483

ce072a0ce   Amit Shah   virtio: console: ...
484
  	err = 0;
d69335619   Amit Shah   virtio: console: ...
485
  	while (buf) {
17e5b4f20   Amit Shah   virtio: console: ...
486
  		port->stats.bytes_discarded += buf->len - buf->offset;
2d24cdaa6   Amit Shah   virtio: console: ...
487
  		if (add_inbuf(port->in_vq, buf) < 0) {
ce072a0ce   Amit Shah   virtio: console: ...
488
  			err++;
1b6370463   Sjur Brændeland   virtio_console: A...
489
  			free_buf(buf, false);
d69335619   Amit Shah   virtio: console: ...
490
  		}
2d24cdaa6   Amit Shah   virtio: console: ...
491
492
  		port->inbuf = NULL;
  		buf = get_inbuf(port);
88f251ac5   Amit Shah   virtio: console: ...
493
  	}
ce072a0ce   Amit Shah   virtio: console: ...
494
  	if (err)
d69335619   Amit Shah   virtio: console: ...
495
496
  		dev_warn(port->dev, "Errors adding %d buffers back to vq
  ",
ce072a0ce   Amit Shah   virtio: console: ...
497
  			 err);
88f251ac5   Amit Shah   virtio: console: ...
498
  }
203baab8b   Amit Shah   virtio: console: ...
499
500
501
502
  static bool port_has_data(struct port *port)
  {
  	unsigned long flags;
  	bool ret;
d25a9ddae   Amit Shah   virtio: console: ...
503
  	ret = false;
203baab8b   Amit Shah   virtio: console: ...
504
  	spin_lock_irqsave(&port->inbuf_lock, flags);
d69335619   Amit Shah   virtio: console: ...
505
  	port->inbuf = get_inbuf(port);
d25a9ddae   Amit Shah   virtio: console: ...
506
  	if (port->inbuf)
d69335619   Amit Shah   virtio: console: ...
507
  		ret = true;
d25a9ddae   Amit Shah   virtio: console: ...
508

203baab8b   Amit Shah   virtio: console: ...
509
  	spin_unlock_irqrestore(&port->inbuf_lock, flags);
203baab8b   Amit Shah   virtio: console: ...
510
511
  	return ret;
  }
3425e706b   Amit Shah   virtio: console: ...
512
513
  static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id,
  				  unsigned int event, unsigned int value)
17634ba25   Amit Shah   virtio: console: ...
514
515
  {
  	struct scatterlist sg[1];
17634ba25   Amit Shah   virtio: console: ...
516
  	struct virtqueue *vq;
604b2ad7c   Amit Shah   virtio: console: ...
517
  	unsigned int len;
17634ba25   Amit Shah   virtio: console: ...
518

3425e706b   Amit Shah   virtio: console: ...
519
  	if (!use_multiport(portdev))
17634ba25   Amit Shah   virtio: console: ...
520
  		return 0;
3425e706b   Amit Shah   virtio: console: ...
521
  	vq = portdev->c_ovq;
17634ba25   Amit Shah   virtio: console: ...
522

9ba5c80b1   Amit Shah   virtio: console: ...
523
  	spin_lock(&portdev->c_ovq_lock);
5e59d9a1a   Andy Lutomirski   virtio_console: S...
524
525
526
527
528
529
530
531
  
  	portdev->cpkt.id = cpu_to_virtio32(portdev->vdev, port_id);
  	portdev->cpkt.event = cpu_to_virtio16(portdev->vdev, event);
  	portdev->cpkt.value = cpu_to_virtio16(portdev->vdev, value);
  
  	sg_init_one(sg, &portdev->cpkt, sizeof(struct virtio_console_control));
  
  	if (virtqueue_add_outbuf(vq, sg, 1, &portdev->cpkt, GFP_ATOMIC) == 0) {
505b0451c   Michael S. Tsirkin   virtio_console: u...
532
  		virtqueue_kick(vq);
40e4dc530   Heinz Graalfs   virtio_console: v...
533
534
  		while (!virtqueue_get_buf(vq, &len)
  			&& !virtqueue_is_broken(vq))
17634ba25   Amit Shah   virtio: console: ...
535
536
  			cpu_relax();
  	}
5e59d9a1a   Andy Lutomirski   virtio_console: S...
537

9ba5c80b1   Amit Shah   virtio: console: ...
538
  	spin_unlock(&portdev->c_ovq_lock);
17634ba25   Amit Shah   virtio: console: ...
539
540
  	return 0;
  }
3425e706b   Amit Shah   virtio: console: ...
541
542
543
  static ssize_t send_control_msg(struct port *port, unsigned int event,
  				unsigned int value)
  {
84ec06c59   Amit Shah   virtio: console: ...
544
545
546
547
  	/* 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: ...
548
  }
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
549

cdfadfc1a   Amit Shah   virtio: console: ...
550
551
552
  /* Callers must take the port->outvq_lock */
  static void reclaim_consumed_buffers(struct port *port)
  {
276a3e954   Sjur Brændeland   virtio_console: M...
553
  	struct port_buffer *buf;
cdfadfc1a   Amit Shah   virtio: console: ...
554
  	unsigned int len;
d7a62cd03   Amit Shah   virtio: console: ...
555
556
557
558
  	if (!port->portdev) {
  		/* Device has been unplugged.  vqs are already gone. */
  		return;
  	}
276a3e954   Sjur Brændeland   virtio_console: M...
559
  	while ((buf = virtqueue_get_buf(port->out_vq, &len))) {
1b6370463   Sjur Brændeland   virtio_console: A...
560
  		free_buf(buf, false);
cdfadfc1a   Amit Shah   virtio: console: ...
561
562
563
  		port->outvq_full = false;
  	}
  }
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
564
565
  static ssize_t __send_to_port(struct port *port, struct scatterlist *sg,
  			      int nents, size_t in_count,
276a3e954   Sjur Brændeland   virtio_console: M...
566
  			      void *data, bool nonblock)
f997f00bf   Amit Shah   virtio: console: ...
567
  {
f997f00bf   Amit Shah   virtio: console: ...
568
  	struct virtqueue *out_vq;
589575a23   Rusty Russell   virtio: console: ...
569
  	int err;
cdfadfc1a   Amit Shah   virtio: console: ...
570
  	unsigned long flags;
f997f00bf   Amit Shah   virtio: console: ...
571
572
573
  	unsigned int len;
  
  	out_vq = port->out_vq;
cdfadfc1a   Amit Shah   virtio: console: ...
574
575
576
  	spin_lock_irqsave(&port->outvq_lock, flags);
  
  	reclaim_consumed_buffers(port);
6797999d9   Rusty Russell   virtio_console: u...
577
  	err = virtqueue_add_outbuf(out_vq, sg, nents, data, GFP_ATOMIC);
f997f00bf   Amit Shah   virtio: console: ...
578
579
  
  	/* Tell Host to go! */
505b0451c   Michael S. Tsirkin   virtio_console: u...
580
  	virtqueue_kick(out_vq);
f997f00bf   Amit Shah   virtio: console: ...
581

589575a23   Rusty Russell   virtio: console: ...
582
  	if (err) {
9ff4cfab8   Rusty Russell   virtio: console m...
583
  		in_count = 0;
cdfadfc1a   Amit Shah   virtio: console: ...
584
  		goto done;
f997f00bf   Amit Shah   virtio: console: ...
585
  	}
589575a23   Rusty Russell   virtio: console: ...
586
  	if (out_vq->num_free == 0)
cdfadfc1a   Amit Shah   virtio: console: ...
587
588
589
590
591
592
593
  		port->outvq_full = true;
  
  	if (nonblock)
  		goto done;
  
  	/*
  	 * Wait till the host acknowledges it pushed out the data we
531295e63   Amit Shah   virtio: console: ...
594
595
596
597
598
599
  	 * 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: ...
600
  	 */
40e4dc530   Heinz Graalfs   virtio_console: v...
601
602
  	while (!virtqueue_get_buf(out_vq, &len)
  		&& !virtqueue_is_broken(out_vq))
f997f00bf   Amit Shah   virtio: console: ...
603
  		cpu_relax();
cdfadfc1a   Amit Shah   virtio: console: ...
604
605
  done:
  	spin_unlock_irqrestore(&port->outvq_lock, flags);
17e5b4f20   Amit Shah   virtio: console: ...
606
607
  
  	port->stats.bytes_sent += in_count;
cdfadfc1a   Amit Shah   virtio: console: ...
608
609
610
611
  	/*
  	 * We're expected to return the amount of data we wrote -- all
  	 * of it
  	 */
9ff4cfab8   Rusty Russell   virtio: console m...
612
  	return in_count;
f997f00bf   Amit Shah   virtio: console: ...
613
  }
203baab8b   Amit Shah   virtio: console: ...
614
615
616
617
  /*
   * Give out the data that's requested from the buffer that we have
   * queued up.
   */
48b36066b   Michael S. Tsirkin   virtio_console: f...
618
619
  static ssize_t fill_readbuf(struct port *port, char __user *out_buf,
  			    size_t out_count, bool to_user)
203baab8b   Amit Shah   virtio: console: ...
620
621
622
623
624
625
626
627
  {
  	struct port_buffer *buf;
  	unsigned long flags;
  
  	if (!out_count || !port_has_data(port))
  		return 0;
  
  	buf = port->inbuf;
b766ceed5   Amit Shah   virtio: console: ...
628
  	out_count = min(out_count, buf->len - buf->offset);
203baab8b   Amit Shah   virtio: console: ...
629

b766ceed5   Amit Shah   virtio: console: ...
630
631
632
633
634
635
636
  	if (to_user) {
  		ssize_t ret;
  
  		ret = copy_to_user(out_buf, buf->buf + buf->offset, out_count);
  		if (ret)
  			return -EFAULT;
  	} else {
48b36066b   Michael S. Tsirkin   virtio_console: f...
637
638
  		memcpy((__force char *)out_buf, buf->buf + buf->offset,
  		       out_count);
b766ceed5   Amit Shah   virtio: console: ...
639
  	}
203baab8b   Amit Shah   virtio: console: ...
640

203baab8b   Amit Shah   virtio: console: ...
641
642
643
644
645
646
647
648
649
650
651
  	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: ...
652
653
  			dev_warn(port->dev, "failed add_buf
  ");
203baab8b   Amit Shah   virtio: console: ...
654
655
656
  
  		spin_unlock_irqrestore(&port->inbuf_lock, flags);
  	}
b766ceed5   Amit Shah   virtio: console: ...
657
  	/* Return the number of bytes actually copied */
203baab8b   Amit Shah   virtio: console: ...
658
  	return out_count;
e27b51980   Amit Shah   virtio: console: ...
659
  }
2030fa496   Amit Shah   virtio: console: ...
660
  /* The condition that must be true for polling to end */
60caacd3e   Amit Shah   virtio: console: ...
661
  static bool will_read_block(struct port *port)
2030fa496   Amit Shah   virtio: console: ...
662
  {
3709ea7ae   Amit Shah   virtio: console: ...
663
664
665
666
  	if (!port->guest_connected) {
  		/* Port got hot-unplugged. Let's exit. */
  		return false;
  	}
60caacd3e   Amit Shah   virtio: console: ...
667
  	return !port_has_data(port) && port->host_connected;
2030fa496   Amit Shah   virtio: console: ...
668
  }
cdfadfc1a   Amit Shah   virtio: console: ...
669
670
671
  static bool will_write_block(struct port *port)
  {
  	bool ret;
60e5e0b84   Amit Shah   virtio: console: ...
672
673
674
675
  	if (!port->guest_connected) {
  		/* Port got hot-unplugged. Let's exit. */
  		return false;
  	}
cdfadfc1a   Amit Shah   virtio: console: ...
676
677
678
679
680
681
682
683
684
685
686
687
688
689
  	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: ...
690
691
692
693
694
695
696
  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;
96f97a839   Amit Shah   virtio: console: ...
697
698
699
  	/* Port is hot-unplugged. */
  	if (!port->guest_connected)
  		return -ENODEV;
2030fa496   Amit Shah   virtio: console: ...
700
701
702
703
704
705
706
707
708
709
  	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: ...
710
711
  		ret = wait_event_freezable(port->waitqueue,
  					   !will_read_block(port));
2030fa496   Amit Shah   virtio: console: ...
712
713
714
  		if (ret < 0)
  			return ret;
  	}
96f97a839   Amit Shah   virtio: console: ...
715
  	/* Port got hot-unplugged while we were waiting above. */
b3dddb9e6   Amit Shah   virtio: console: ...
716
717
  	if (!port->guest_connected)
  		return -ENODEV;
2030fa496   Amit Shah   virtio: console: ...
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
  	/*
  	 * 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);
  }
efe75d24a   Masami Hiramatsu   virtio/console: W...
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
  static int wait_port_writable(struct port *port, bool nonblock)
  {
  	int ret;
  
  	if (will_write_block(port)) {
  		if (nonblock)
  			return -EAGAIN;
  
  		ret = wait_event_freezable(port->waitqueue,
  					   !will_write_block(port));
  		if (ret < 0)
  			return ret;
  	}
  	/* Port got hot-unplugged. */
  	if (!port->guest_connected)
  		return -ENODEV;
  
  	return 0;
  }
2030fa496   Amit Shah   virtio: console: ...
752
753
754
755
  static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
  			       size_t count, loff_t *offp)
  {
  	struct port *port;
276a3e954   Sjur Brændeland   virtio_console: M...
756
  	struct port_buffer *buf;
2030fa496   Amit Shah   virtio: console: ...
757
  	ssize_t ret;
cdfadfc1a   Amit Shah   virtio: console: ...
758
  	bool nonblock;
276a3e954   Sjur Brændeland   virtio_console: M...
759
  	struct scatterlist sg[1];
2030fa496   Amit Shah   virtio: console: ...
760

65745422a   Amit Shah   virtio: console: ...
761
762
763
  	/* Userspace could be out to fool us */
  	if (!count)
  		return 0;
2030fa496   Amit Shah   virtio: console: ...
764
  	port = filp->private_data;
cdfadfc1a   Amit Shah   virtio: console: ...
765
  	nonblock = filp->f_flags & O_NONBLOCK;
efe75d24a   Masami Hiramatsu   virtio/console: W...
766
767
768
  	ret = wait_port_writable(port, nonblock);
  	if (ret < 0)
  		return ret;
cdfadfc1a   Amit Shah   virtio: console: ...
769

2030fa496   Amit Shah   virtio: console: ...
770
  	count = min((size_t)(32 * 1024), count);
276a3e954   Sjur Brændeland   virtio_console: M...
771
  	buf = alloc_buf(port->out_vq, count, 0);
2030fa496   Amit Shah   virtio: console: ...
772
773
  	if (!buf)
  		return -ENOMEM;
276a3e954   Sjur Brændeland   virtio_console: M...
774
  	ret = copy_from_user(buf->buf, ubuf, count);
2030fa496   Amit Shah   virtio: console: ...
775
776
777
778
  	if (ret) {
  		ret = -EFAULT;
  		goto free_buf;
  	}
531295e63   Amit Shah   virtio: console: ...
779
780
781
782
783
784
785
786
  	/*
  	 * 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;
276a3e954   Sjur Brændeland   virtio_console: M...
787
788
  	sg_init_one(sg, buf->buf, count);
  	ret = __send_to_port(port, sg, 1, count, buf, nonblock);
cdfadfc1a   Amit Shah   virtio: console: ...
789
790
791
  
  	if (nonblock && ret > 0)
  		goto out;
2030fa496   Amit Shah   virtio: console: ...
792
  free_buf:
1b6370463   Sjur Brændeland   virtio_console: A...
793
  	free_buf(buf, true);
cdfadfc1a   Amit Shah   virtio: console: ...
794
  out:
2030fa496   Amit Shah   virtio: console: ...
795
796
  	return ret;
  }
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
797
798
  struct sg_list {
  	unsigned int n;
8ca84a50e   Masami Hiramatsu   virtio/console: A...
799
  	unsigned int size;
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
800
801
802
803
804
805
806
807
  	size_t len;
  	struct scatterlist *sg;
  };
  
  static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
  			struct splice_desc *sd)
  {
  	struct sg_list *sgl = sd->u.data;
ec8fc8701   Masami Hiramatsu   virtio/console: A...
808
  	unsigned int offset, len;
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
809

8ca84a50e   Masami Hiramatsu   virtio/console: A...
810
  	if (sgl->n == sgl->size)
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
811
812
813
  		return 0;
  
  	/* Try lock this page */
ca76f5b6b   Miklos Szeredi   pipe: add pipe_bu...
814
  	if (pipe_buf_steal(pipe, buf) == 0) {
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
815
816
817
818
819
820
  		/* Get reference and unlock page for moving */
  		get_page(buf->page);
  		unlock_page(buf->page);
  
  		len = min(buf->len, sd->len);
  		sg_set_page(&(sgl->sg[sgl->n]), buf->page, len, buf->offset);
ec8fc8701   Masami Hiramatsu   virtio/console: A...
821
822
823
  	} else {
  		/* Failback to copying a page */
  		struct page *page = alloc_page(GFP_KERNEL);
c9efe5116   Al Viro   fix a kmap leak i...
824
  		char *src;
ec8fc8701   Masami Hiramatsu   virtio/console: A...
825
826
827
  
  		if (!page)
  			return -ENOMEM;
ec8fc8701   Masami Hiramatsu   virtio/console: A...
828
829
830
831
832
833
  
  		offset = sd->pos & ~PAGE_MASK;
  
  		len = sd->len;
  		if (len + offset > PAGE_SIZE)
  			len = PAGE_SIZE - offset;
fbb32750a   Al Viro   pipe: kill ->map(...
834
  		src = kmap_atomic(buf->page);
c9efe5116   Al Viro   fix a kmap leak i...
835
  		memcpy(page_address(page) + offset, src + buf->offset, len);
fbb32750a   Al Viro   pipe: kill ->map(...
836
  		kunmap_atomic(src);
ec8fc8701   Masami Hiramatsu   virtio/console: A...
837
838
  
  		sg_set_page(&(sgl->sg[sgl->n]), page, len, offset);
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
839
  	}
ec8fc8701   Masami Hiramatsu   virtio/console: A...
840
841
  	sgl->n++;
  	sgl->len += len;
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
842
843
844
845
846
847
848
849
850
851
852
853
  
  	return len;
  }
  
  /* Faster zero-copy write by splicing */
  static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
  				      struct file *filp, loff_t *ppos,
  				      size_t len, unsigned int flags)
  {
  	struct port *port = filp->private_data;
  	struct sg_list sgl;
  	ssize_t ret;
276a3e954   Sjur Brændeland   virtio_console: M...
854
  	struct port_buffer *buf;
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
855
856
857
858
859
860
  	struct splice_desc sd = {
  		.total_len = len,
  		.flags = flags,
  		.pos = *ppos,
  		.u.data = &sgl,
  	};
1b6370463   Sjur Brændeland   virtio_console: A...
861
862
863
864
865
866
867
868
  	/*
  	 * Rproc_serial does not yet support splice. To support splice
  	 * pipe_to_sg() must allocate dma-buffers and copy content from
  	 * regular pages to dma pages. And alloc_buf and free_buf must
  	 * support allocating and freeing such a list of dma-buffers.
  	 */
  	if (is_rproc_serial(port->out_vq->vdev))
  		return -EINVAL;
68c034fef   Yoshihiro YUNOMAE   virtio/console: Q...
869
870
871
872
  	/*
  	 * pipe->nrbufs == 0 means there are no data to transfer,
  	 * so this returns just 0 for no data.
  	 */
2b4fbf029   Yoshihiro YUNOMAE   virtio/console: A...
873
874
875
876
877
  	pipe_lock(pipe);
  	if (!pipe->nrbufs) {
  		ret = 0;
  		goto error_out;
  	}
68c034fef   Yoshihiro YUNOMAE   virtio/console: Q...
878

efe75d24a   Masami Hiramatsu   virtio/console: W...
879
880
  	ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
  	if (ret < 0)
2b4fbf029   Yoshihiro YUNOMAE   virtio/console: A...
881
  		goto error_out;
efe75d24a   Masami Hiramatsu   virtio/console: W...
882

276a3e954   Sjur Brændeland   virtio_console: M...
883
  	buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
2b4fbf029   Yoshihiro YUNOMAE   virtio/console: A...
884
885
886
887
  	if (!buf) {
  		ret = -ENOMEM;
  		goto error_out;
  	}
276a3e954   Sjur Brændeland   virtio_console: M...
888

eb5e89fc7   Masami Hiramatsu   virtio/console: A...
889
890
  	sgl.n = 0;
  	sgl.len = 0;
8ca84a50e   Masami Hiramatsu   virtio/console: A...
891
  	sgl.size = pipe->nrbufs;
276a3e954   Sjur Brændeland   virtio_console: M...
892
  	sgl.sg = buf->sg;
8ca84a50e   Masami Hiramatsu   virtio/console: A...
893
  	sg_init_table(sgl.sg, sgl.size);
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
894
  	ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
2b4fbf029   Yoshihiro YUNOMAE   virtio/console: A...
895
  	pipe_unlock(pipe);
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
896
  	if (likely(ret > 0))
276a3e954   Sjur Brændeland   virtio_console: M...
897
  		ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
898

fe5295374   Sjur Brændeland   virtio_console: F...
899
  	if (unlikely(ret <= 0))
1b6370463   Sjur Brændeland   virtio_console: A...
900
  		free_buf(buf, true);
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
901
  	return ret;
2b4fbf029   Yoshihiro YUNOMAE   virtio/console: A...
902
903
904
905
  
  error_out:
  	pipe_unlock(pipe);
  	return ret;
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
906
  }
2030fa496   Amit Shah   virtio: console: ...
907
908
909
910
911
912
913
  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: ...
914
915
916
917
  	if (!port->guest_connected) {
  		/* Port got unplugged */
  		return POLLHUP;
  	}
2030fa496   Amit Shah   virtio: console: ...
918
  	ret = 0;
6df7aadcd   Hans de Goede   virtio: console: ...
919
  	if (!will_read_block(port))
2030fa496   Amit Shah   virtio: console: ...
920
  		ret |= POLLIN | POLLRDNORM;
cdfadfc1a   Amit Shah   virtio: console: ...
921
  	if (!will_write_block(port))
2030fa496   Amit Shah   virtio: console: ...
922
923
924
925
926
927
  		ret |= POLLOUT;
  	if (!port->host_connected)
  		ret |= POLLHUP;
  
  	return ret;
  }
b353a6b82   Amit Shah   virtio: console: ...
928
  static void remove_port(struct kref *kref);
2030fa496   Amit Shah   virtio: console: ...
929
930
931
932
933
934
935
936
  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: ...
937
  	spin_lock_irq(&port->inbuf_lock);
3c7969ccb   Amit Shah   virtio: console: ...
938
  	port->guest_connected = false;
88f251ac5   Amit Shah   virtio: console: ...
939
940
941
  	discard_port_data(port);
  
  	spin_unlock_irq(&port->inbuf_lock);
cdfadfc1a   Amit Shah   virtio: console: ...
942
943
944
  	spin_lock_irq(&port->outvq_lock);
  	reclaim_consumed_buffers(port);
  	spin_unlock_irq(&port->outvq_lock);
1b6370463   Sjur Brændeland   virtio_console: A...
945
  	reclaim_dma_bufs();
b353a6b82   Amit Shah   virtio: console: ...
946
947
948
949
950
951
952
953
954
  	/*
  	 * 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: ...
955
956
957
958
959
960
961
  	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: ...
962
  	int ret;
2030fa496   Amit Shah   virtio: console: ...
963

057b82be3   Amit Shah   virtio: console: ...
964
  	/* We get the port with a kref here */
04950cdf0   Amit Shah   virtio: console: ...
965
  	port = find_port_by_devt(cdev->dev);
671bdea2b   Amit Shah   virtio: console: ...
966
967
968
969
  	if (!port) {
  		/* Port was unplugged before we could proceed */
  		return -ENXIO;
  	}
2030fa496   Amit Shah   virtio: console: ...
970
971
972
973
974
975
  	filp->private_data = port;
  
  	/*
  	 * Don't allow opening of console port devices -- that's done
  	 * via /dev/hvc
  	 */
8ad37e83c   Amit Shah   virtio: console: ...
976
977
978
979
  	if (is_console_port(port)) {
  		ret = -ENXIO;
  		goto out;
  	}
2030fa496   Amit Shah   virtio: console: ...
980

3c7969ccb   Amit Shah   virtio: console: ...
981
982
983
984
  	/* 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);
74ff582cd   Amit Shah   virtio: console: ...
985
  		ret = -EBUSY;
8ad37e83c   Amit Shah   virtio: console: ...
986
  		goto out;
3c7969ccb   Amit Shah   virtio: console: ...
987
988
989
990
  	}
  
  	port->guest_connected = true;
  	spin_unlock_irq(&port->inbuf_lock);
cdfadfc1a   Amit Shah   virtio: console: ...
991
992
993
994
995
996
997
998
  	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: ...
999
  	nonseekable_open(inode, filp);
2030fa496   Amit Shah   virtio: console: ...
1000
1001
1002
1003
  	/* Notify host of port being opened */
  	send_control_msg(filp->private_data, VIRTIO_CONSOLE_PORT_OPEN, 1);
  
  	return 0;
8ad37e83c   Amit Shah   virtio: console: ...
1004
  out:
b353a6b82   Amit Shah   virtio: console: ...
1005
  	kref_put(&port->kref, remove_port);
8ad37e83c   Amit Shah   virtio: console: ...
1006
  	return ret;
2030fa496   Amit Shah   virtio: console: ...
1007
  }
3eae0adea   Amit Shah   virtio: console: ...
1008
1009
1010
1011
1012
1013
1014
  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: ...
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
  /*
   * 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,
eb5e89fc7   Masami Hiramatsu   virtio/console: A...
1026
  	.splice_write = port_fops_splice_write,
2030fa496   Amit Shah   virtio: console: ...
1027
1028
  	.poll  = port_fops_poll,
  	.release = port_fops_release,
3eae0adea   Amit Shah   virtio: console: ...
1029
  	.fasync = port_fops_fasync,
299fb61c0   Amit Shah   virtio: console: ...
1030
  	.llseek = no_llseek,
2030fa496   Amit Shah   virtio: console: ...
1031
  };
e27b51980   Amit Shah   virtio: console: ...
1032
  /*
a23ea9247   Rusty Russell   virtio: console: ...
1033
   * The put_chars() callback is pretty straightforward.
31610434b   Rusty Russell   Virtio console dr...
1034
   *
a23ea9247   Rusty Russell   virtio: console: ...
1035
1036
1037
1038
1039
   * 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...
1040
1041
  static int put_chars(u32 vtermno, const char *buf, int count)
  {
21206ede8   Rusty Russell   virtio: console: ...
1042
  	struct port *port;
276a3e954   Sjur Brændeland   virtio_console: M...
1043
  	struct scatterlist sg[1];
38edf58d7   Amit Shah   virtio: console: ...
1044

162a689a1   François Diakhaté   virtio: console: ...
1045
1046
  	if (unlikely(early_put_chars))
  		return early_put_chars(vtermno, buf, count);
38edf58d7   Amit Shah   virtio: console: ...
1047
1048
  	port = find_port_by_vtermno(vtermno);
  	if (!port)
6dc69f970   Amit Shah   virtio: console: ...
1049
  		return -EPIPE;
31610434b   Rusty Russell   Virtio console dr...
1050

276a3e954   Sjur Brændeland   virtio_console: M...
1051
1052
  	sg_init_one(sg, buf, count);
  	return __send_to_port(port, sg, 1, count, (void *)buf, false);
31610434b   Rusty Russell   Virtio console dr...
1053
  }
a23ea9247   Rusty Russell   virtio: console: ...
1054
  /*
a23ea9247   Rusty Russell   virtio: console: ...
1055
1056
   * get_chars() is the callback from the hvc_console infrastructure
   * when an interrupt is received.
31610434b   Rusty Russell   Virtio console dr...
1057
   *
203baab8b   Amit Shah   virtio: console: ...
1058
1059
   * We call out to fill_readbuf that gets us the required data from the
   * buffers that are queued up.
a23ea9247   Rusty Russell   virtio: console: ...
1060
   */
31610434b   Rusty Russell   Virtio console dr...
1061
1062
  static int get_chars(u32 vtermno, char *buf, int count)
  {
21206ede8   Rusty Russell   virtio: console: ...
1063
  	struct port *port;
6dc69f970   Amit Shah   virtio: console: ...
1064
1065
1066
  	/* 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: ...
1067
1068
  	port = find_port_by_vtermno(vtermno);
  	if (!port)
6dc69f970   Amit Shah   virtio: console: ...
1069
  		return -EPIPE;
21206ede8   Rusty Russell   virtio: console: ...
1070

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

48b36066b   Michael S. Tsirkin   virtio_console: f...
1074
  	return fill_readbuf(port, (__force char __user *)buf, count, false);
31610434b   Rusty Russell   Virtio console dr...
1075
  }
31610434b   Rusty Russell   Virtio console dr...
1076

cb06e3676   Amit Shah   virtio: console: ...
1077
  static void resize_console(struct port *port)
c29834584   Christian Borntraeger   virtio_console: s...
1078
  {
cb06e3676   Amit Shah   virtio: console: ...
1079
  	struct virtio_device *vdev;
c29834584   Christian Borntraeger   virtio_console: s...
1080

2de16a493   Amit Shah   virtio: console: ...
1081
  	/* The port could have been hot-unplugged */
9778829cf   Amit Shah   virtio: console: ...
1082
  	if (!port || !is_console_port(port))
2de16a493   Amit Shah   virtio: console: ...
1083
  		return;
cb06e3676   Amit Shah   virtio: console: ...
1084
  	vdev = port->portdev->vdev;
1b6370463   Sjur Brændeland   virtio_console: A...
1085
1086
1087
1088
  
  	/* Don't test F_SIZE at all if we're rproc: not a valid feature! */
  	if (!is_rproc_serial(vdev) &&
  	    virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE))
9778829cf   Amit Shah   virtio: console: ...
1089
  		hvc_resize(port->cons.hvc, port->cons.ws);
c29834584   Christian Borntraeger   virtio_console: s...
1090
  }
38edf58d7   Amit Shah   virtio: console: ...
1091
  /* We set the configuration at this point, since we now have a tty */
91fcad19d   Christian Borntraeger   virtio_console: u...
1092
1093
  static int notifier_add_vio(struct hvc_struct *hp, int data)
  {
38edf58d7   Amit Shah   virtio: console: ...
1094
1095
1096
1097
1098
  	struct port *port;
  
  	port = find_port_by_vtermno(hp->vtermno);
  	if (!port)
  		return -EINVAL;
91fcad19d   Christian Borntraeger   virtio_console: u...
1099
  	hp->irq_requested = 1;
cb06e3676   Amit Shah   virtio: console: ...
1100
  	resize_console(port);
c29834584   Christian Borntraeger   virtio_console: s...
1101

91fcad19d   Christian Borntraeger   virtio_console: u...
1102
1103
1104
1105
1106
1107
1108
  	return 0;
  }
  
  static void notifier_del_vio(struct hvc_struct *hp, int data)
  {
  	hp->irq_requested = 0;
  }
17634ba25   Amit Shah   virtio: console: ...
1109
  /* The operations for console ports. */
1dff39961   Rusty Russell   hvc_console: make...
1110
  static const struct hv_ops hv_ops = {
971f33900   Rusty Russell   virtio: console: ...
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
  	.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);
  }
3826835ab   Wei Yongjun   virtio_console: m...
1132
  static int init_port_console(struct port *port)
cfa6d3792   Amit Shah   virtio: console: ...
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
  {
  	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: ...
1158
1159
1160
  		dev_err(port->dev,
  			"error %d allocating hvc for port
  ", ret);
cfa6d3792   Amit Shah   virtio: console: ...
1161
1162
1163
1164
1165
1166
1167
  		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: ...
1168
  	port->guest_connected = true;
cfa6d3792   Amit Shah   virtio: console: ...
1169

1d05160be   Amit Shah   virtio: console: ...
1170
1171
1172
1173
1174
1175
  	/*
  	 * 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: ...
1176
1177
  	/* Notify host of port being opened */
  	send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
cfa6d3792   Amit Shah   virtio: console: ...
1178
1179
  	return 0;
  }
431edb8a8   Amit Shah   virtio: console: ...
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
  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: ...
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
  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: ...
1226
1227
1228
  			       "outvq_full: %d
  ", port->outvq_full);
  	out_offset += snprintf(buf + out_offset, out_count - out_offset,
17e5b4f20   Amit Shah   virtio: console: ...
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
  			       "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: ...
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
  			       "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,
234e34058   Stephen Boyd   simple_open: auto...
1254
  	.open  = simple_open,
d99393eff   Amit Shah   virtio: console: ...
1255
1256
  	.read  = debugfs_read,
  };
9778829cf   Amit Shah   virtio: console: ...
1257
1258
1259
1260
1261
1262
1263
1264
  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: ...
1265
1266
1267
1268
1269
1270
1271
1272
  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 {
276a3e954   Sjur Brændeland   virtio_console: M...
1273
  		buf = alloc_buf(vq, PAGE_SIZE, 0);
c446f8fcc   Amit Shah   virtio: console: ...
1274
1275
1276
1277
1278
1279
1280
  		if (!buf)
  			break;
  
  		spin_lock_irq(lock);
  		ret = add_inbuf(vq, buf);
  		if (ret < 0) {
  			spin_unlock_irq(lock);
1b6370463   Sjur Brændeland   virtio_console: A...
1281
  			free_buf(buf, true);
c446f8fcc   Amit Shah   virtio: console: ...
1282
1283
1284
1285
1286
1287
1288
1289
  			break;
  		}
  		nr_added_bufs++;
  		spin_unlock_irq(lock);
  	} while (ret > 0);
  
  	return nr_added_bufs;
  }
3eae0adea   Amit Shah   virtio: console: ...
1290
1291
1292
1293
1294
  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: ...
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
  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: ...
1309
  	kref_init(&port->kref);
c446f8fcc   Amit Shah   virtio: console: ...
1310
1311
1312
1313
1314
1315
1316
  
  	port->portdev = portdev;
  	port->id = id;
  
  	port->name = NULL;
  	port->inbuf = NULL;
  	port->cons.hvc = NULL;
3eae0adea   Amit Shah   virtio: console: ...
1317
  	port->async_queue = NULL;
c446f8fcc   Amit Shah   virtio: console: ...
1318

9778829cf   Amit Shah   virtio: console: ...
1319
  	port->cons.ws.ws_row = port->cons.ws.ws_col = 0;
c446f8fcc   Amit Shah   virtio: console: ...
1320
  	port->host_connected = port->guest_connected = false;
17e5b4f20   Amit Shah   virtio: console: ...
1321
  	port->stats = (struct port_stats) { 0 };
c446f8fcc   Amit Shah   virtio: console: ...
1322

cdfadfc1a   Amit Shah   virtio: console: ...
1323
  	port->outvq_full = false;
c446f8fcc   Amit Shah   virtio: console: ...
1324
1325
  	port->in_vq = portdev->in_vqs[port->id];
  	port->out_vq = portdev->out_vqs[port->id];
d22a69892   Amit Shah   virtio: console: ...
1326
1327
1328
1329
1330
1331
1332
1333
  	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: ...
1334
1335
  
  	devt = MKDEV(portdev->chr_major, id);
d22a69892   Amit Shah   virtio: console: ...
1336
  	err = cdev_add(port->cdev, devt, 1);
c446f8fcc   Amit Shah   virtio: console: ...
1337
1338
1339
1340
  	if (err < 0) {
  		dev_err(&port->portdev->vdev->dev,
  			"Error %d adding cdev for port %u
  ", err, id);
d22a69892   Amit Shah   virtio: console: ...
1341
  		goto free_cdev;
c446f8fcc   Amit Shah   virtio: console: ...
1342
1343
1344
  	}
  	port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
  				  devt, port, "vport%up%u",
dc18f0800   Sjur Brændeland   virtio_console: U...
1345
  				  port->portdev->vdev->index, id);
c446f8fcc   Amit Shah   virtio: console: ...
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
  	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: ...
1356
  	spin_lock_init(&port->outvq_lock);
c446f8fcc   Amit Shah   virtio: console: ...
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
  	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;
  	}
1b6370463   Sjur Brændeland   virtio_console: A...
1367
1368
1369
1370
1371
1372
  	if (is_rproc_serial(port->portdev->vdev))
  		/*
  		 * For rproc_serial assume remote processor is connected.
  		 * rproc_serial does not want the console port, only
  		 * the generic port implementation.
  		 */
aabd6a8fa   Sjur Brændeland   Revert "virtio_co...
1373
  		port->host_connected = true;
1b6370463   Sjur Brændeland   virtio_console: A...
1374
1375
1376
1377
1378
  	else if (!use_multiport(port->portdev)) {
  		/*
  		 * If we're not using multiport support,
  		 * this has to be a console port.
  		 */
c446f8fcc   Amit Shah   virtio: console: ...
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
  		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
  		 */
db1700685   Dan Carpenter   virtio_console: s...
1400
1401
  		snprintf(debugfs_name, sizeof(debugfs_name), "vport%up%u",
  			 port->portdev->vdev->index, id);
c446f8fcc   Amit Shah   virtio: console: ...
1402
1403
1404
1405
1406
1407
1408
1409
1410
  		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)))
1b6370463   Sjur Brændeland   virtio_console: A...
1411
  		free_buf(buf, true);
c446f8fcc   Amit Shah   virtio: console: ...
1412
1413
1414
  free_device:
  	device_destroy(pdrvdata.class, port->dev->devt);
  free_cdev:
d22a69892   Amit Shah   virtio: console: ...
1415
  	cdev_del(port->cdev);
c446f8fcc   Amit Shah   virtio: console: ...
1416
1417
1418
1419
  free_port:
  	kfree(port);
  fail:
  	/* The host might want to notify management sw about port add failure */
0643e4c6e   Julia Lawall   drivers/char: Eli...
1420
  	__send_control_msg(portdev, id, VIRTIO_CONSOLE_PORT_READY, 0);
c446f8fcc   Amit Shah   virtio: console: ...
1421
1422
  	return err;
  }
b353a6b82   Amit Shah   virtio: console: ...
1423
1424
1425
1426
1427
1428
  /* 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);
b353a6b82   Amit Shah   virtio: console: ...
1429
1430
  	kfree(port);
  }
a0e2dbfc2   Amit Shah   virtio: console: ...
1431
1432
1433
  static void remove_port_data(struct port *port)
  {
  	struct port_buffer *buf;
c6017e793   Amit Shah   virtio: console: ...
1434
  	spin_lock_irq(&port->inbuf_lock);
a0e2dbfc2   Amit Shah   virtio: console: ...
1435
1436
  	/* Remove unused data this port might have received. */
  	discard_port_data(port);
34563769e   Matt Redfearn   virtio: console: ...
1437
  	spin_unlock_irq(&port->inbuf_lock);
a0e2dbfc2   Amit Shah   virtio: console: ...
1438

a0e2dbfc2   Amit Shah   virtio: console: ...
1439
  	/* Remove buffers we queued up for the Host to send us data in. */
34563769e   Matt Redfearn   virtio: console: ...
1440
1441
1442
1443
1444
1445
1446
  	do {
  		spin_lock_irq(&port->inbuf_lock);
  		buf = virtqueue_detach_unused_buf(port->in_vq);
  		spin_unlock_irq(&port->inbuf_lock);
  		if (buf)
  			free_buf(buf, true);
  	} while (buf);
c6017e793   Amit Shah   virtio: console: ...
1447
1448
1449
  
  	spin_lock_irq(&port->outvq_lock);
  	reclaim_consumed_buffers(port);
34563769e   Matt Redfearn   virtio: console: ...
1450
  	spin_unlock_irq(&port->outvq_lock);
eb34f12b5   sjur.brandeland@stericsson.com   virtio_console: F...
1451
1452
  
  	/* Free pending buffers from the out-queue. */
34563769e   Matt Redfearn   virtio: console: ...
1453
1454
1455
1456
1457
1458
1459
  	do {
  		spin_lock_irq(&port->outvq_lock);
  		buf = virtqueue_detach_unused_buf(port->out_vq);
  		spin_unlock_irq(&port->outvq_lock);
  		if (buf)
  			free_buf(buf, true);
  	} while (buf);
a0e2dbfc2   Amit Shah   virtio: console: ...
1460
  }
b353a6b82   Amit Shah   virtio: console: ...
1461
1462
1463
1464
1465
1466
  /*
   * 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: ...
1467
  {
b353a6b82   Amit Shah   virtio: console: ...
1468
1469
1470
  	spin_lock_irq(&port->portdev->ports_lock);
  	list_del(&port->list);
  	spin_unlock_irq(&port->portdev->ports_lock);
5549fb258   Amit Shah   virtio: console: ...
1471
  	spin_lock_irq(&port->inbuf_lock);
0047634d3   Amit Shah   virtio: console: ...
1472
  	if (port->guest_connected) {
92d345381   Amit Shah   virtio: console: ...
1473
1474
1475
1476
  		/* Let the app know the port is going down. */
  		send_sigio_to_port(port);
  
  		/* Do this after sigio is actually sent */
0047634d3   Amit Shah   virtio: console: ...
1477
1478
  		port->guest_connected = false;
  		port->host_connected = false;
a461e11e7   Amit Shah   virtio: console: ...
1479

92d345381   Amit Shah   virtio: console: ...
1480
  		wake_up_interruptible(&port->waitqueue);
0047634d3   Amit Shah   virtio: console: ...
1481
  	}
5549fb258   Amit Shah   virtio: console: ...
1482
  	spin_unlock_irq(&port->inbuf_lock);
0047634d3   Amit Shah   virtio: console: ...
1483

1f7aa42d1   Amit Shah   virtio: console: ...
1484
1485
1486
1487
1488
1489
  	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: ...
1490

a0e2dbfc2   Amit Shah   virtio: console: ...
1491
  	remove_port_data(port);
a9cdd4855   Amit Shah   virtio: console: ...
1492

b353a6b82   Amit Shah   virtio: console: ...
1493
1494
1495
1496
1497
1498
  	/*
  	 * 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: ...
1499

ea3768b43   Amit Shah   virtio: console: ...
1500
1501
1502
  	sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
  	device_destroy(pdrvdata.class, port->dev->devt);
  	cdev_del(port->cdev);
ea3768b43   Amit Shah   virtio: console: ...
1503
  	debugfs_remove(port->debugfs_file);
3b868a407   Amit Shah   virtio: console: ...
1504
  	kfree(port->name);
ea3768b43   Amit Shah   virtio: console: ...
1505

b353a6b82   Amit Shah   virtio: console: ...
1506
1507
1508
1509
1510
1511
  	/*
  	 * 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: ...
1512
  }
17634ba25   Amit Shah   virtio: console: ...
1513
  /* Any private messages that the Host and Guest want to share */
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1514
1515
  static void handle_control_message(struct virtio_device *vdev,
  				   struct ports_device *portdev,
17634ba25   Amit Shah   virtio: console: ...
1516
1517
1518
1519
  				   struct port_buffer *buf)
  {
  	struct virtio_console_control *cpkt;
  	struct port *port;
431edb8a8   Amit Shah   virtio: console: ...
1520
1521
  	size_t name_size;
  	int err;
17634ba25   Amit Shah   virtio: console: ...
1522
1523
  
  	cpkt = (struct virtio_console_control *)(buf->buf + buf->offset);
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1524
1525
1526
  	port = find_port_by_id(portdev, virtio32_to_cpu(vdev, cpkt->id));
  	if (!port &&
  	    cpkt->event != cpu_to_virtio16(vdev, VIRTIO_CONSOLE_PORT_ADD)) {
17634ba25   Amit Shah   virtio: console: ...
1527
1528
1529
1530
1531
1532
  		/* No valid header at start of buffer.  Drop it. */
  		dev_dbg(&portdev->vdev->dev,
  			"Invalid index %u in control packet
  ", cpkt->id);
  		return;
  	}
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1533
  	switch (virtio16_to_cpu(vdev, cpkt->event)) {
f909f850d   Amit Shah   virtio: console: ...
1534
1535
  	case VIRTIO_CONSOLE_PORT_ADD:
  		if (port) {
1d05160be   Amit Shah   virtio: console: ...
1536
1537
1538
  			dev_dbg(&portdev->vdev->dev,
  				"Port %u already added
  ", port->id);
f909f850d   Amit Shah   virtio: console: ...
1539
1540
1541
  			send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
  			break;
  		}
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1542
1543
  		if (virtio32_to_cpu(vdev, cpkt->id) >=
  		    portdev->config.max_nr_ports) {
f909f850d   Amit Shah   virtio: console: ...
1544
  			dev_warn(&portdev->vdev->dev,
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1545
1546
1547
  				"Request for adding port with "
  				"out-of-bound id %u, max. supported id: %u
  ",
f909f850d   Amit Shah   virtio: console: ...
1548
1549
1550
  				cpkt->id, portdev->config.max_nr_ports - 1);
  			break;
  		}
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1551
  		add_port(portdev, virtio32_to_cpu(vdev, cpkt->id));
f909f850d   Amit Shah   virtio: console: ...
1552
1553
  		break;
  	case VIRTIO_CONSOLE_PORT_REMOVE:
b353a6b82   Amit Shah   virtio: console: ...
1554
  		unplug_port(port);
f909f850d   Amit Shah   virtio: console: ...
1555
  		break;
17634ba25   Amit Shah   virtio: console: ...
1556
1557
1558
1559
1560
1561
1562
  	case VIRTIO_CONSOLE_CONSOLE_PORT:
  		if (!cpkt->value)
  			break;
  		if (is_console_port(port))
  			break;
  
  		init_port_console(port);
5e38483b3   Christian Borntraeger   virtio: console: ...
1563
  		complete(&early_console_added);
17634ba25   Amit Shah   virtio: console: ...
1564
1565
1566
1567
1568
  		/*
  		 * Could remove the port here in case init fails - but
  		 * have to notify the host first.
  		 */
  		break;
8345adbf9   Amit Shah   virtio: console: ...
1569
1570
1571
1572
1573
  	case VIRTIO_CONSOLE_RESIZE: {
  		struct {
  			__u16 rows;
  			__u16 cols;
  		} size;
17634ba25   Amit Shah   virtio: console: ...
1574
1575
  		if (!is_console_port(port))
  			break;
8345adbf9   Amit Shah   virtio: console: ...
1576
1577
1578
1579
  
  		memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt),
  		       sizeof(size));
  		set_console_size(port, size.rows, size.cols);
17634ba25   Amit Shah   virtio: console: ...
1580
1581
1582
  		port->cons.hvc->irq_requested = 1;
  		resize_console(port);
  		break;
8345adbf9   Amit Shah   virtio: console: ...
1583
  	}
2030fa496   Amit Shah   virtio: console: ...
1584
  	case VIRTIO_CONSOLE_PORT_OPEN:
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1585
  		port->host_connected = virtio16_to_cpu(vdev, cpkt->value);
2030fa496   Amit Shah   virtio: console: ...
1586
  		wake_up_interruptible(&port->waitqueue);
cdfadfc1a   Amit Shah   virtio: console: ...
1587
1588
1589
1590
1591
1592
1593
1594
  		/*
  		 * 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: ...
1595
1596
1597
1598
1599
  
  		/*
  		 * If the guest is connected, it'll be interested in
  		 * knowing the host connection state changed.
  		 */
314081f10   Amit Shah   virtio: console: ...
1600
  		spin_lock_irq(&port->inbuf_lock);
3eae0adea   Amit Shah   virtio: console: ...
1601
  		send_sigio_to_port(port);
314081f10   Amit Shah   virtio: console: ...
1602
  		spin_unlock_irq(&port->inbuf_lock);
2030fa496   Amit Shah   virtio: console: ...
1603
  		break;
431edb8a8   Amit Shah   virtio: console: ...
1604
1605
  	case VIRTIO_CONSOLE_PORT_NAME:
  		/*
291024ef3   Amit Shah   virtio: console: ...
1606
1607
1608
1609
1610
1611
1612
  		 * 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: ...
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
  		 * 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: ...
1635
  		if (err) {
431edb8a8   Amit Shah   virtio: console: ...
1636
1637
1638
1639
  			dev_err(port->dev,
  				"Error %d creating sysfs device attributes
  ",
  				err);
ec64213c4   Amit Shah   virtio: console: ...
1640
1641
1642
1643
1644
1645
1646
1647
  		} 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: ...
1648
  		break;
17634ba25   Amit Shah   virtio: console: ...
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
  	}
  }
  
  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;
165b1b8bb   Amit Shah   virtio: console: ...
1661
  	spin_lock(&portdev->c_ivq_lock);
505b0451c   Michael S. Tsirkin   virtio_console: u...
1662
  	while ((buf = virtqueue_get_buf(vq, &len))) {
165b1b8bb   Amit Shah   virtio: console: ...
1663
  		spin_unlock(&portdev->c_ivq_lock);
17634ba25   Amit Shah   virtio: console: ...
1664
1665
1666
  
  		buf->len = len;
  		buf->offset = 0;
1f0f9106f   Michael S. Tsirkin   virtio_console: v...
1667
  		handle_control_message(vq->vdev, portdev, buf);
17634ba25   Amit Shah   virtio: console: ...
1668

165b1b8bb   Amit Shah   virtio: console: ...
1669
  		spin_lock(&portdev->c_ivq_lock);
17634ba25   Amit Shah   virtio: console: ...
1670
1671
1672
1673
  		if (add_inbuf(portdev->c_ivq, buf) < 0) {
  			dev_warn(&portdev->vdev->dev,
  				 "Error adding buffer to queue
  ");
1b6370463   Sjur Brændeland   virtio_console: A...
1674
  			free_buf(buf, false);
17634ba25   Amit Shah   virtio: console: ...
1675
1676
  		}
  	}
165b1b8bb   Amit Shah   virtio: console: ...
1677
  	spin_unlock(&portdev->c_ivq_lock);
17634ba25   Amit Shah   virtio: console: ...
1678
  }
2770c5ea5   Amit Shah   virtio: console: ...
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
  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: ...
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
  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: ...
1699
  	port->inbuf = get_inbuf(port);
17634ba25   Amit Shah   virtio: console: ...
1700

88f251ac5   Amit Shah   virtio: console: ...
1701
  	/*
aabd6a8fa   Sjur Brændeland   Revert "virtio_co...
1702
1703
1704
  	 * Normally the port should not accept data when the port is
  	 * closed. For generic serial ports, the host won't (shouldn't)
  	 * send data till the guest is connected. But this condition
88f251ac5   Amit Shah   virtio: console: ...
1705
  	 * can be reached when a console port is not yet connected (no
aabd6a8fa   Sjur Brændeland   Revert "virtio_co...
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
  	 * tty is spawned) and the other side sends out data over the
  	 * vring, or when a remote devices start sending data before
  	 * the ports are opened.
  	 *
  	 * A generic serial port will discard data if not connected,
  	 * while console ports and rproc-serial ports accepts data at
  	 * any time. rproc-serial is initiated with guest_connected to
  	 * false because port_fops_open expects this. Console ports are
  	 * hooked up with an HVC console and is initialized with
  	 * guest_connected to true.
88f251ac5   Amit Shah   virtio: console: ...
1716
  	 */
aabd6a8fa   Sjur Brændeland   Revert "virtio_co...
1717
1718
  
  	if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev))
88f251ac5   Amit Shah   virtio: console: ...
1719
  		discard_port_data(port);
314081f10   Amit Shah   virtio: console: ...
1720
1721
  	/* Send a SIGIO indicating new data in case the process asked for it */
  	send_sigio_to_port(port);
17634ba25   Amit Shah   virtio: console: ...
1722
  	spin_unlock_irqrestore(&port->inbuf_lock, flags);
2030fa496   Amit Shah   virtio: console: ...
1723
  	wake_up_interruptible(&port->waitqueue);
17634ba25   Amit Shah   virtio: console: ...
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
  	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: ...
1735
1736
1737
1738
1739
  static void config_intr(struct virtio_device *vdev)
  {
  	struct ports_device *portdev;
  
  	portdev = vdev->priv;
99f905f88   Amit Shah   virtio: console: ...
1740

eeb8a7e8b   Michael S. Tsirkin   virtio_console: a...
1741
1742
1743
1744
1745
1746
1747
1748
1749
  	if (!use_multiport(portdev))
  		schedule_work(&portdev->config_work);
  }
  
  static void config_work_handler(struct work_struct *work)
  {
  	struct ports_device *portdev;
  
  	portdev = container_of(work, struct ports_device, control_work);
4038f5b76   Amit Shah   virtio: console: ...
1750
  	if (!use_multiport(portdev)) {
eeb8a7e8b   Michael S. Tsirkin   virtio_console: a...
1751
  		struct virtio_device *vdev;
9778829cf   Amit Shah   virtio: console: ...
1752
1753
  		struct port *port;
  		u16 rows, cols;
eeb8a7e8b   Michael S. Tsirkin   virtio_console: a...
1754
  		vdev = portdev->vdev;
855e0c528   Rusty Russell   virtio: use size-...
1755
1756
  		virtio_cread(vdev, struct virtio_console_config, cols, &cols);
  		virtio_cread(vdev, struct virtio_console_config, rows, &rows);
9778829cf   Amit Shah   virtio: console: ...
1757
1758
1759
  
  		port = find_port_by_id(portdev, 0);
  		set_console_size(port, rows, cols);
4038f5b76   Amit Shah   virtio: console: ...
1760
1761
1762
1763
1764
1765
1766
  		/*
  		 * 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: ...
1767
  		resize_console(port);
4038f5b76   Amit Shah   virtio: console: ...
1768
  	}
7f5d810da   Amit Shah   virtio: console: ...
1769
  }
2658a79ac   Amit Shah   virtio: console: ...
1770
1771
1772
1773
1774
  static int init_vqs(struct ports_device *portdev)
  {
  	vq_callback_t **io_callbacks;
  	char **io_names;
  	struct virtqueue **vqs;
17634ba25   Amit Shah   virtio: console: ...
1775
  	u32 i, j, nr_ports, nr_queues;
2658a79ac   Amit Shah   virtio: console: ...
1776
  	int err;
17634ba25   Amit Shah   virtio: console: ...
1777
1778
  	nr_ports = portdev->config.max_nr_ports;
  	nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;
2658a79ac   Amit Shah   virtio: console: ...
1779
1780
  
  	vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1781
  	io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1782
  	io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1783
1784
  	portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
  				  GFP_KERNEL);
2658a79ac   Amit Shah   virtio: console: ...
1785
1786
  	portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
  				   GFP_KERNEL);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1787
  	if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs ||
286f9a226   Amit Shah   virtio: console: ...
1788
  	    !portdev->out_vqs) {
2658a79ac   Amit Shah   virtio: console: ...
1789
  		err = -ENOMEM;
22e132ff2   Jiri Slaby   Char: virtio_cons...
1790
  		goto free;
2658a79ac   Amit Shah   virtio: console: ...
1791
  	}
17634ba25   Amit Shah   virtio: console: ...
1792
1793
1794
1795
1796
1797
1798
  	/*
  	 * 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: ...
1799
  	io_callbacks[j + 1] = out_intr;
17634ba25   Amit Shah   virtio: console: ...
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
  	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: ...
1813
  			io_callbacks[j + 1] = out_intr;
17634ba25   Amit Shah   virtio: console: ...
1814
1815
1816
1817
  			io_names[j] = "input";
  			io_names[j + 1] = "output";
  		}
  	}
2658a79ac   Amit Shah   virtio: console: ...
1818
1819
1820
1821
1822
  	/* 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...
1823
  		goto free;
2658a79ac   Amit Shah   virtio: console: ...
1824

17634ba25   Amit Shah   virtio: console: ...
1825
  	j = 0;
2658a79ac   Amit Shah   virtio: console: ...
1826
1827
  	portdev->in_vqs[0] = vqs[0];
  	portdev->out_vqs[0] = vqs[1];
17634ba25   Amit Shah   virtio: console: ...
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
  	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: ...
1839
  	kfree(io_names);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1840
  	kfree(io_callbacks);
2658a79ac   Amit Shah   virtio: console: ...
1841
1842
1843
  	kfree(vqs);
  
  	return 0;
22e132ff2   Jiri Slaby   Char: virtio_cons...
1844
  free:
2658a79ac   Amit Shah   virtio: console: ...
1845
  	kfree(portdev->out_vqs);
2658a79ac   Amit Shah   virtio: console: ...
1846
  	kfree(portdev->in_vqs);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1847
1848
  	kfree(io_names);
  	kfree(io_callbacks);
2658a79ac   Amit Shah   virtio: console: ...
1849
  	kfree(vqs);
22e132ff2   Jiri Slaby   Char: virtio_cons...
1850

2658a79ac   Amit Shah   virtio: console: ...
1851
1852
  	return err;
  }
fb08bd274   Amit Shah   virtio: console: ...
1853
1854
1855
  static const struct file_operations portdev_fops = {
  	.owner = THIS_MODULE,
  };
a0e2dbfc2   Amit Shah   virtio: console: ...
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
  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)))
1b6370463   Sjur Brændeland   virtio_console: A...
1872
  		free_buf(buf, true);
a0e2dbfc2   Amit Shah   virtio: console: ...
1873
1874
  
  	while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq)))
1b6370463   Sjur Brændeland   virtio_console: A...
1875
  		free_buf(buf, true);
a0e2dbfc2   Amit Shah   virtio: console: ...
1876
  }
1c85bf354   Amit Shah   virtio: console: ...
1877
1878
1879
  /*
   * Once we're further in boot, we get probed like any other virtio
   * device.
17634ba25   Amit Shah   virtio: console: ...
1880
1881
1882
1883
   *
   * 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: ...
1884
   */
2223cbec3   Bill Pemberton   char: remove use ...
1885
  static int virtcons_probe(struct virtio_device *vdev)
1c85bf354   Amit Shah   virtio: console: ...
1886
  {
1c85bf354   Amit Shah   virtio: console: ...
1887
1888
  	struct ports_device *portdev;
  	int err;
17634ba25   Amit Shah   virtio: console: ...
1889
  	bool multiport;
5e38483b3   Christian Borntraeger   virtio: console: ...
1890
  	bool early = early_put_chars != NULL;
be8ff5952   Rusty Russell   virtio: don't req...
1891
1892
1893
1894
  	/* We only need a config space if features are offered */
  	if (!vdev->config->get &&
  	    (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)
  	     || virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT))) {
011f0e7a6   Michael S. Tsirkin   virtio/console: v...
1895
1896
1897
1898
1899
  		dev_err(&vdev->dev, "%s failure: config access disabled
  ",
  			__func__);
  		return -EINVAL;
  	}
5e38483b3   Christian Borntraeger   virtio: console: ...
1900
1901
  	/* Ensure to read early_put_chars now */
  	barrier();
1c85bf354   Amit Shah   virtio: console: ...
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
  
  	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: ...
1912
1913
1914
1915
1916
1917
  	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
  ",
dc18f0800   Sjur Brændeland   virtio_console: U...
1918
  			portdev->chr_major, vdev->index);
fb08bd274   Amit Shah   virtio: console: ...
1919
1920
1921
  		err = portdev->chr_major;
  		goto free;
  	}
17634ba25   Amit Shah   virtio: console: ...
1922
  	multiport = false;
17634ba25   Amit Shah   virtio: console: ...
1923
  	portdev->config.max_nr_ports = 1;
1b6370463   Sjur Brændeland   virtio_console: A...
1924
1925
1926
  
  	/* Don't test MULTIPORT at all if we're rproc: not a valid feature! */
  	if (!is_rproc_serial(vdev) &&
855e0c528   Rusty Russell   virtio: use size-...
1927
1928
1929
  	    virtio_cread_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT,
  				 struct virtio_console_config, max_nr_ports,
  				 &portdev->config.max_nr_ports) == 0) {
17634ba25   Amit Shah   virtio: console: ...
1930
  		multiport = true;
1b6370463   Sjur Brændeland   virtio_console: A...
1931
  	}
17634ba25   Amit Shah   virtio: console: ...
1932

2658a79ac   Amit Shah   virtio: console: ...
1933
1934
1935
1936
  	err = init_vqs(portdev);
  	if (err < 0) {
  		dev_err(&vdev->dev, "Error %d initializing vqs
  ", err);
fb08bd274   Amit Shah   virtio: console: ...
1937
  		goto free_chrdev;
2658a79ac   Amit Shah   virtio: console: ...
1938
  	}
1c85bf354   Amit Shah   virtio: console: ...
1939

17634ba25   Amit Shah   virtio: console: ...
1940
1941
  	spin_lock_init(&portdev->ports_lock);
  	INIT_LIST_HEAD(&portdev->ports);
65eca3a20   Cornelia Huck   virtio_console: m...
1942
  	virtio_device_ready(portdev->vdev);
eeb8a7e8b   Michael S. Tsirkin   virtio_console: a...
1943
  	INIT_WORK(&portdev->config_work, &config_work_handler);
4f6e24ed9   Michael S. Tsirkin   virtio_console: i...
1944
  	INIT_WORK(&portdev->control_work, &control_work_handler);
17634ba25   Amit Shah   virtio: console: ...
1945
  	if (multiport) {
335a64a5c   Amit Shah   virtio: console: ...
1946
  		unsigned int nr_added_bufs;
165b1b8bb   Amit Shah   virtio: console: ...
1947
  		spin_lock_init(&portdev->c_ivq_lock);
9ba5c80b1   Amit Shah   virtio: console: ...
1948
  		spin_lock_init(&portdev->c_ovq_lock);
17634ba25   Amit Shah   virtio: console: ...
1949

165b1b8bb   Amit Shah   virtio: console: ...
1950
1951
  		nr_added_bufs = fill_queue(portdev->c_ivq,
  					   &portdev->c_ivq_lock);
335a64a5c   Amit Shah   virtio: console: ...
1952
  		if (!nr_added_bufs) {
22a29eacd   Amit Shah   virtio: console: ...
1953
1954
1955
1956
1957
1958
  			dev_err(&vdev->dev,
  				"Error allocating buffers for control queue
  ");
  			err = -ENOMEM;
  			goto free_vqs;
  		}
1d05160be   Amit Shah   virtio: console: ...
1959
1960
1961
1962
1963
1964
  	} else {
  		/*
  		 * For backward compatibility: Create a console port
  		 * if we're running on older host.
  		 */
  		add_port(portdev, 0);
17634ba25   Amit Shah   virtio: console: ...
1965
  	}
6bdf2afd0   Amit Shah   virtio: console: ...
1966
1967
1968
  	spin_lock_irq(&pdrvdata_lock);
  	list_add_tail(&portdev->list, &pdrvdata.portdevs);
  	spin_unlock_irq(&pdrvdata_lock);
f909f850d   Amit Shah   virtio: console: ...
1969
1970
  	__send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
  			   VIRTIO_CONSOLE_DEVICE_READY, 1);
5e38483b3   Christian Borntraeger   virtio: console: ...
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
  
  	/*
  	 * 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...
1983
  	return 0;
22a29eacd   Amit Shah   virtio: console: ...
1984
  free_vqs:
0643e4c6e   Julia Lawall   drivers/char: Eli...
1985
1986
1987
  	/* 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: ...
1988
  	remove_vqs(portdev);
fb08bd274   Amit Shah   virtio: console: ...
1989
1990
  free_chrdev:
  	unregister_chrdev(portdev->chr_major, "virtio-portsdev");
31610434b   Rusty Russell   Virtio console dr...
1991
  free:
1c85bf354   Amit Shah   virtio: console: ...
1992
  	kfree(portdev);
31610434b   Rusty Russell   Virtio console dr...
1993
1994
1995
  fail:
  	return err;
  }
7177876fe   Amit Shah   virtio: console: ...
1996
1997
1998
1999
  static void virtcons_remove(struct virtio_device *vdev)
  {
  	struct ports_device *portdev;
  	struct port *port, *port2;
7177876fe   Amit Shah   virtio: console: ...
2000
2001
  
  	portdev = vdev->priv;
6bdf2afd0   Amit Shah   virtio: console: ...
2002
2003
2004
  	spin_lock_irq(&pdrvdata_lock);
  	list_del(&portdev->list);
  	spin_unlock_irq(&pdrvdata_lock);
022389599   Amit Shah   virtio: console: ...
2005
2006
2007
  	/* Disable interrupts for vqs */
  	vdev->config->reset(vdev);
  	/* Finish up work that's lined up */
aded024a1   Sjur Brændeland   virtio_console: D...
2008
2009
  	if (use_multiport(portdev))
  		cancel_work_sync(&portdev->control_work);
eeb8a7e8b   Michael S. Tsirkin   virtio_console: a...
2010
2011
  	else
  		cancel_work_sync(&portdev->config_work);
7177876fe   Amit Shah   virtio: console: ...
2012
2013
  
  	list_for_each_entry_safe(port, port2, &portdev->ports, list)
b353a6b82   Amit Shah   virtio: console: ...
2014
  		unplug_port(port);
7177876fe   Amit Shah   virtio: console: ...
2015
2016
  
  	unregister_chrdev(portdev->chr_major, "virtio-portsdev");
e062013c7   Amit Shah   virtio: console: ...
2017
2018
2019
2020
2021
2022
2023
2024
  	/*
  	 * 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: ...
2025
2026
  	remove_controlq_data(portdev);
  	remove_vqs(portdev);
7177876fe   Amit Shah   virtio: console: ...
2027
2028
  	kfree(portdev);
  }
31610434b   Rusty Russell   Virtio console dr...
2029
2030
2031
2032
  static struct virtio_device_id id_table[] = {
  	{ VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
  	{ 0 },
  };
c29834584   Christian Borntraeger   virtio_console: s...
2033
2034
  static unsigned int features[] = {
  	VIRTIO_CONSOLE_F_SIZE,
b99fa815d   Amit Shah   virtio: Revert "v...
2035
  	VIRTIO_CONSOLE_F_MULTIPORT,
c29834584   Christian Borntraeger   virtio_console: s...
2036
  };
1b6370463   Sjur Brændeland   virtio_console: A...
2037
2038
2039
2040
2041
2042
2043
2044
2045
  static struct virtio_device_id rproc_serial_id_table[] = {
  #if IS_ENABLED(CONFIG_REMOTEPROC)
  	{ VIRTIO_ID_RPROC_SERIAL, VIRTIO_DEV_ANY_ID },
  #endif
  	{ 0 },
  };
  
  static unsigned int rproc_serial_features[] = {
  };
891070003   Aaron Lu   virtio: pm: use C...
2046
  #ifdef CONFIG_PM_SLEEP
2b8f41d84   Amit Shah   virtio: console: ...
2047
2048
2049
2050
2051
2052
2053
2054
  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: ...
2055
  	virtqueue_disable_cb(portdev->c_ivq);
2b8f41d84   Amit Shah   virtio: console: ...
2056
  	cancel_work_sync(&portdev->control_work);
eeb8a7e8b   Michael S. Tsirkin   virtio_console: a...
2057
  	cancel_work_sync(&portdev->config_work);
c743d09db   Amit Shah   virtio: console: ...
2058
2059
2060
2061
2062
  	/*
  	 * 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: ...
2063
2064
2065
  	remove_controlq_data(portdev);
  
  	list_for_each_entry(port, &portdev->ports, list) {
c743d09db   Amit Shah   virtio: console: ...
2066
2067
  		virtqueue_disable_cb(port->in_vq);
  		virtqueue_disable_cb(port->out_vq);
2b8f41d84   Amit Shah   virtio: console: ...
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
  		/*
  		 * 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;
401bbdc90   Michael S. Tsirkin   virtio_console: e...
2091
  	virtio_device_ready(portdev->vdev);
2b8f41d84   Amit Shah   virtio: console: ...
2092
  	if (use_multiport(portdev))
165b1b8bb   Amit Shah   virtio: console: ...
2093
  		fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
2b8f41d84   Amit Shah   virtio: console: ...
2094
2095
2096
2097
2098
2099
2100
2101
2102
  
  	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);
fa8b66ccd   Amit Shah   virtio: console: ...
2103
2104
2105
2106
2107
2108
2109
  
  		/*
  		 * If a port was open at the time of suspending, we
  		 * have to let the host know that it's still open.
  		 */
  		if (port->guest_connected)
  			send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
2b8f41d84   Amit Shah   virtio: console: ...
2110
2111
2112
2113
  	}
  	return 0;
  }
  #endif
31610434b   Rusty Russell   Virtio console dr...
2114
  static struct virtio_driver virtio_console = {
c29834584   Christian Borntraeger   virtio_console: s...
2115
2116
  	.feature_table = features,
  	.feature_table_size = ARRAY_SIZE(features),
31610434b   Rusty Russell   Virtio console dr...
2117
2118
2119
2120
  	.driver.name =	KBUILD_MODNAME,
  	.driver.owner =	THIS_MODULE,
  	.id_table =	id_table,
  	.probe =	virtcons_probe,
7177876fe   Amit Shah   virtio: console: ...
2121
  	.remove =	virtcons_remove,
7f5d810da   Amit Shah   virtio: console: ...
2122
  	.config_changed = config_intr,
891070003   Aaron Lu   virtio: pm: use C...
2123
  #ifdef CONFIG_PM_SLEEP
2b8f41d84   Amit Shah   virtio: console: ...
2124
2125
2126
  	.freeze =	virtcons_freeze,
  	.restore =	virtcons_restore,
  #endif
31610434b   Rusty Russell   Virtio console dr...
2127
  };
bcd2982a0   Greg Kroah-Hartman   Drivers: char: re...
2128
  static struct virtio_driver virtio_rproc_serial = {
1b6370463   Sjur Brændeland   virtio_console: A...
2129
2130
2131
2132
2133
2134
2135
2136
  	.feature_table = rproc_serial_features,
  	.feature_table_size = ARRAY_SIZE(rproc_serial_features),
  	.driver.name =	"virtio_rproc_serial",
  	.driver.owner =	THIS_MODULE,
  	.id_table =	rproc_serial_id_table,
  	.probe =	virtcons_probe,
  	.remove =	virtcons_remove,
  };
31610434b   Rusty Russell   Virtio console dr...
2137
2138
  static int __init init(void)
  {
fb08bd274   Amit Shah   virtio: console: ...
2139
2140
2141
2142
2143
2144
2145
2146
2147
  	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: ...
2148
2149
  
  	pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
3f0d0c9b4   Dan Carpenter   virtio: console: ...
2150
2151
2152
  	if (!pdrvdata.debugfs_dir)
  		pr_warning("Error creating debugfs dir for virtio-ports
  ");
38edf58d7   Amit Shah   virtio: console: ...
2153
  	INIT_LIST_HEAD(&pdrvdata.consoles);
6bdf2afd0   Amit Shah   virtio: console: ...
2154
  	INIT_LIST_HEAD(&pdrvdata.portdevs);
38edf58d7   Amit Shah   virtio: console: ...
2155

33e1afc3d   Alexey Khoroshilov   virtio: console: ...
2156
2157
2158
2159
2160
2161
  	err = register_virtio_driver(&virtio_console);
  	if (err < 0) {
  		pr_err("Error %d registering virtio driver
  ", err);
  		goto free;
  	}
1b6370463   Sjur Brændeland   virtio_console: A...
2162
2163
2164
2165
2166
2167
2168
  	err = register_virtio_driver(&virtio_rproc_serial);
  	if (err < 0) {
  		pr_err("Error %d registering virtio rproc serial driver
  ",
  		       err);
  		goto unregister;
  	}
33e1afc3d   Alexey Khoroshilov   virtio: console: ...
2169
  	return 0;
1b6370463   Sjur Brændeland   virtio_console: A...
2170
2171
  unregister:
  	unregister_virtio_driver(&virtio_console);
33e1afc3d   Alexey Khoroshilov   virtio: console: ...
2172
  free:
5885e48e4   Fabian Frederick   virtio: console: ...
2173
  	debugfs_remove_recursive(pdrvdata.debugfs_dir);
33e1afc3d   Alexey Khoroshilov   virtio: console: ...
2174
2175
  	class_destroy(pdrvdata.class);
  	return err;
31610434b   Rusty Russell   Virtio console dr...
2176
  }
7177876fe   Amit Shah   virtio: console: ...
2177
2178
2179
  
  static void __exit fini(void)
  {
1b6370463   Sjur Brændeland   virtio_console: A...
2180
  	reclaim_dma_bufs();
7177876fe   Amit Shah   virtio: console: ...
2181
  	unregister_virtio_driver(&virtio_console);
1b6370463   Sjur Brændeland   virtio_console: A...
2182
  	unregister_virtio_driver(&virtio_rproc_serial);
7177876fe   Amit Shah   virtio: console: ...
2183
2184
  
  	class_destroy(pdrvdata.class);
5885e48e4   Fabian Frederick   virtio: console: ...
2185
  	debugfs_remove_recursive(pdrvdata.debugfs_dir);
7177876fe   Amit Shah   virtio: console: ...
2186
  }
31610434b   Rusty Russell   Virtio console dr...
2187
  module_init(init);
7177876fe   Amit Shah   virtio: console: ...
2188
  module_exit(fini);
31610434b   Rusty Russell   Virtio console dr...
2189
2190
2191
2192
  
  MODULE_DEVICE_TABLE(virtio, id_table);
  MODULE_DESCRIPTION("Virtio console driver");
  MODULE_LICENSE("GPL");