1  // SPDX-License-Identifier: GPL-2.0
2  /* vcc.c: sun4v virtual channel concentrator
3   *
4   * Copyright (C) 2017 Oracle. All rights reserved.
5   */
6  
7  #include <linux/delay.h>
8  #include <linux/interrupt.h>
9  #include <linux/module.h>
10  #include <linux/slab.h>
11  #include <linux/sysfs.h>
12  #include <linux/tty.h>
13  #include <linux/tty_flip.h>
14  #include <linux/termios_internal.h>
15  #include <asm/vio.h>
16  #include <asm/ldc.h>
17  
18  MODULE_DESCRIPTION("Sun LDOM virtual console concentrator driver");
19  MODULE_LICENSE("GPL");
20  MODULE_VERSION("1.1");
21  
22  struct vcc_port {
23  	struct vio_driver_state vio;
24  
25  	spinlock_t lock;
26  	char *domain;
27  	struct tty_struct *tty;	/* only populated while dev is open */
28  	unsigned long index;	/* index into the vcc_table */
29  
30  	u64 refcnt;
31  	bool excl_locked;
32  
33  	bool removed;
34  
35  	/* This buffer is required to support the tty write_room interface
36  	 * and guarantee that any characters that the driver accepts will
37  	 * be eventually sent, either immediately or later.
38  	 */
39  	size_t chars_in_buffer;
40  	struct vio_vcc buffer;
41  
42  	struct timer_list rx_timer;
43  	struct timer_list tx_timer;
44  };
45  
46  /* Microseconds that thread will delay waiting for a vcc port ref */
47  #define VCC_REF_DELAY		100
48  
49  #define VCC_MAX_PORTS		1024
50  #define VCC_MINOR_START		0	/* must be zero */
51  #define VCC_BUFF_LEN		VIO_VCC_MTU_SIZE
52  
53  #define VCC_CTL_BREAK		-1
54  #define VCC_CTL_HUP		-2
55  
56  static struct tty_driver *vcc_tty_driver;
57  
58  static struct vcc_port *vcc_table[VCC_MAX_PORTS];
59  static DEFINE_SPINLOCK(vcc_table_lock);
60  
61  static unsigned int vcc_dbg;
62  static unsigned int vcc_dbg_ldc;
63  static unsigned int vcc_dbg_vio;
64  
65  module_param(vcc_dbg, uint, 0664);
66  module_param(vcc_dbg_ldc, uint, 0664);
67  module_param(vcc_dbg_vio, uint, 0664);
68  
69  #define VCC_DBG_DRV	0x1
70  #define VCC_DBG_LDC	0x2
71  #define VCC_DBG_PKT	0x4
72  
73  #define vccdbg(f, a...)						\
74  	do {							\
75  		if (vcc_dbg & VCC_DBG_DRV)			\
76  			pr_info(f, ## a);			\
77  	} while (0)						\
78  
79  #define vccdbgl(l)						\
80  	do {							\
81  		if (vcc_dbg & VCC_DBG_LDC)			\
82  			ldc_print(l);				\
83  	} while (0)						\
84  
85  #define vccdbgp(pkt)						\
86  	do {							\
87  		if (vcc_dbg & VCC_DBG_PKT) {			\
88  			int i;					\
89  			for (i = 0; i < pkt.tag.stype; i++)	\
90  				pr_info("[%c]", pkt.data[i]);	\
91  		}						\
92  	} while (0)						\
93  
94  /* Note: Be careful when adding flags to this line discipline.  Don't
95   * add anything that will cause echoing or we'll go into recursive
96   * loop echoing chars back and forth with the console drivers.
97   */
98  static const struct ktermios vcc_tty_termios = {
99  	.c_iflag = IGNBRK | IGNPAR,
100  	.c_oflag = OPOST,
101  	.c_cflag = B38400 | CS8 | CREAD | HUPCL,
102  	.c_cc = INIT_C_CC,
103  	.c_ispeed = 38400,
104  	.c_ospeed = 38400
105  };
106  
107  /**
108   * vcc_table_add() - Add VCC port to the VCC table
109   * @port: pointer to the VCC port
110   *
111   * Return: index of the port in the VCC table on success,
112   *	   -1 on failure
113   */
vcc_table_add(struct vcc_port * port)114  static int vcc_table_add(struct vcc_port *port)
115  {
116  	unsigned long flags;
117  	int i;
118  
119  	spin_lock_irqsave(&vcc_table_lock, flags);
120  	for (i = VCC_MINOR_START; i < VCC_MAX_PORTS; i++) {
121  		if (!vcc_table[i]) {
122  			vcc_table[i] = port;
123  			break;
124  		}
125  	}
126  	spin_unlock_irqrestore(&vcc_table_lock, flags);
127  
128  	if (i < VCC_MAX_PORTS)
129  		return i;
130  	else
131  		return -1;
132  }
133  
134  /**
135   * vcc_table_remove() - Removes a VCC port from the VCC table
136   * @index: Index into the VCC table
137   */
vcc_table_remove(unsigned long index)138  static void vcc_table_remove(unsigned long index)
139  {
140  	unsigned long flags;
141  
142  	if (WARN_ON(index >= VCC_MAX_PORTS))
143  		return;
144  
145  	spin_lock_irqsave(&vcc_table_lock, flags);
146  	vcc_table[index] = NULL;
147  	spin_unlock_irqrestore(&vcc_table_lock, flags);
148  }
149  
150  /**
151   * vcc_get() - Gets a reference to VCC port
152   * @index: Index into the VCC table
153   * @excl: Indicates if an exclusive access is requested
154   *
155   * Return: reference to the VCC port, if found
156   *	   NULL, if port not found
157   */
vcc_get(unsigned long index,bool excl)158  static struct vcc_port *vcc_get(unsigned long index, bool excl)
159  {
160  	struct vcc_port *port;
161  	unsigned long flags;
162  
163  try_again:
164  	spin_lock_irqsave(&vcc_table_lock, flags);
165  
166  	port = vcc_table[index];
167  	if (!port) {
168  		spin_unlock_irqrestore(&vcc_table_lock, flags);
169  		return NULL;
170  	}
171  
172  	if (!excl) {
173  		if (port->excl_locked) {
174  			spin_unlock_irqrestore(&vcc_table_lock, flags);
175  			udelay(VCC_REF_DELAY);
176  			goto try_again;
177  		}
178  		port->refcnt++;
179  		spin_unlock_irqrestore(&vcc_table_lock, flags);
180  		return port;
181  	}
182  
183  	if (port->refcnt) {
184  		spin_unlock_irqrestore(&vcc_table_lock, flags);
185  		/* Threads wanting exclusive access will wait half the time,
186  		 * probably giving them higher priority in the case of
187  		 * multiple waiters.
188  		 */
189  		udelay(VCC_REF_DELAY/2);
190  		goto try_again;
191  	}
192  
193  	port->refcnt++;
194  	port->excl_locked = true;
195  	spin_unlock_irqrestore(&vcc_table_lock, flags);
196  
197  	return port;
198  }
199  
200  /**
201   * vcc_put() - Returns a reference to VCC port
202   * @port: pointer to VCC port
203   * @excl: Indicates if the returned reference is an exclusive reference
204   *
205   * Note: It's the caller's responsibility to ensure the correct value
206   *	 for the excl flag
207   */
vcc_put(struct vcc_port * port,bool excl)208  static void vcc_put(struct vcc_port *port, bool excl)
209  {
210  	unsigned long flags;
211  
212  	if (!port)
213  		return;
214  
215  	spin_lock_irqsave(&vcc_table_lock, flags);
216  
217  	/* check if caller attempted to put with the wrong flags */
218  	if (WARN_ON((excl && !port->excl_locked) ||
219  		    (!excl && port->excl_locked)))
220  		goto done;
221  
222  	port->refcnt--;
223  
224  	if (excl)
225  		port->excl_locked = false;
226  
227  done:
228  	spin_unlock_irqrestore(&vcc_table_lock, flags);
229  }
230  
231  /**
232   * vcc_get_ne() - Get a non-exclusive reference to VCC port
233   * @index: Index into the VCC table
234   *
235   * Gets a non-exclusive reference to VCC port, if it's not removed
236   *
237   * Return: pointer to the VCC port, if found
238   *	   NULL, if port not found
239   */
vcc_get_ne(unsigned long index)240  static struct vcc_port *vcc_get_ne(unsigned long index)
241  {
242  	struct vcc_port *port;
243  
244  	port = vcc_get(index, false);
245  
246  	if (port && port->removed) {
247  		vcc_put(port, false);
248  		return NULL;
249  	}
250  
251  	return port;
252  }
253  
vcc_kick_rx(struct vcc_port * port)254  static void vcc_kick_rx(struct vcc_port *port)
255  {
256  	struct vio_driver_state *vio = &port->vio;
257  
258  	assert_spin_locked(&port->lock);
259  
260  	if (!timer_pending(&port->rx_timer) && !port->removed) {
261  		disable_irq_nosync(vio->vdev->rx_irq);
262  		port->rx_timer.expires = (jiffies + 1);
263  		add_timer(&port->rx_timer);
264  	}
265  }
266  
vcc_kick_tx(struct vcc_port * port)267  static void vcc_kick_tx(struct vcc_port *port)
268  {
269  	assert_spin_locked(&port->lock);
270  
271  	if (!timer_pending(&port->tx_timer) && !port->removed) {
272  		port->tx_timer.expires = (jiffies + 1);
273  		add_timer(&port->tx_timer);
274  	}
275  }
276  
vcc_rx_check(struct tty_struct * tty,int size)277  static int vcc_rx_check(struct tty_struct *tty, int size)
278  {
279  	if (WARN_ON(!tty || !tty->port))
280  		return 1;
281  
282  	/* tty_buffer_request_room won't sleep because it uses
283  	 * GFP_ATOMIC flag to allocate buffer
284  	 */
285  	if (test_bit(TTY_THROTTLED, &tty->flags) ||
286  	    (tty_buffer_request_room(tty->port, VCC_BUFF_LEN) < VCC_BUFF_LEN))
287  		return 0;
288  
289  	return 1;
290  }
291  
vcc_rx(struct tty_struct * tty,char * buf,int size)292  static int vcc_rx(struct tty_struct *tty, char *buf, int size)
293  {
294  	int len = 0;
295  
296  	if (WARN_ON(!tty || !tty->port))
297  		return len;
298  
299  	len = tty_insert_flip_string(tty->port, buf, size);
300  	if (len)
301  		tty_flip_buffer_push(tty->port);
302  
303  	return len;
304  }
305  
vcc_ldc_read(struct vcc_port * port)306  static int vcc_ldc_read(struct vcc_port *port)
307  {
308  	struct vio_driver_state *vio = &port->vio;
309  	struct tty_struct *tty;
310  	struct vio_vcc pkt;
311  	int rv = 0;
312  
313  	tty = port->tty;
314  	if (!tty) {
315  		rv = ldc_rx_reset(vio->lp);
316  		vccdbg("VCC: reset rx q: rv=%d\n", rv);
317  		goto done;
318  	}
319  
320  	/* Read as long as LDC has incoming data. */
321  	while (1) {
322  		if (!vcc_rx_check(tty, VIO_VCC_MTU_SIZE)) {
323  			vcc_kick_rx(port);
324  			break;
325  		}
326  
327  		vccdbgl(vio->lp);
328  
329  		rv = ldc_read(vio->lp, &pkt, sizeof(pkt));
330  		if (rv <= 0)
331  			break;
332  
333  		vccdbg("VCC: ldc_read()=%d\n", rv);
334  		vccdbg("TAG [%02x:%02x:%04x:%08x]\n",
335  		       pkt.tag.type, pkt.tag.stype,
336  		       pkt.tag.stype_env, pkt.tag.sid);
337  
338  		if (pkt.tag.type == VIO_TYPE_DATA) {
339  			vccdbgp(pkt);
340  			/* vcc_rx_check ensures memory availability */
341  			vcc_rx(tty, pkt.data, pkt.tag.stype);
342  		} else {
343  			pr_err("VCC: unknown msg [%02x:%02x:%04x:%08x]\n",
344  			       pkt.tag.type, pkt.tag.stype,
345  			       pkt.tag.stype_env, pkt.tag.sid);
346  			rv = -ECONNRESET;
347  			break;
348  		}
349  
350  		WARN_ON(rv != LDC_PACKET_SIZE);
351  	}
352  
353  done:
354  	return rv;
355  }
356  
vcc_rx_timer(struct timer_list * t)357  static void vcc_rx_timer(struct timer_list *t)
358  {
359  	struct vcc_port *port = from_timer(port, t, rx_timer);
360  	struct vio_driver_state *vio;
361  	unsigned long flags;
362  	int rv;
363  
364  	spin_lock_irqsave(&port->lock, flags);
365  	port->rx_timer.expires = 0;
366  
367  	vio = &port->vio;
368  
369  	enable_irq(vio->vdev->rx_irq);
370  
371  	if (!port->tty || port->removed)
372  		goto done;
373  
374  	rv = vcc_ldc_read(port);
375  	if (rv == -ECONNRESET)
376  		vio_conn_reset(vio);
377  
378  done:
379  	spin_unlock_irqrestore(&port->lock, flags);
380  	vcc_put(port, false);
381  }
382  
vcc_tx_timer(struct timer_list * t)383  static void vcc_tx_timer(struct timer_list *t)
384  {
385  	struct vcc_port *port = from_timer(port, t, tx_timer);
386  	struct vio_vcc *pkt;
387  	unsigned long flags;
388  	size_t tosend = 0;
389  	int rv;
390  
391  	spin_lock_irqsave(&port->lock, flags);
392  	port->tx_timer.expires = 0;
393  
394  	if (!port->tty || port->removed)
395  		goto done;
396  
397  	tosend = min(VCC_BUFF_LEN, port->chars_in_buffer);
398  	if (!tosend)
399  		goto done;
400  
401  	pkt = &port->buffer;
402  	pkt->tag.type = VIO_TYPE_DATA;
403  	pkt->tag.stype = tosend;
404  	vccdbgl(port->vio.lp);
405  
406  	rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend));
407  	WARN_ON(!rv);
408  
409  	if (rv < 0) {
410  		vccdbg("VCC: ldc_write()=%d\n", rv);
411  		vcc_kick_tx(port);
412  	} else {
413  		struct tty_struct *tty = port->tty;
414  
415  		port->chars_in_buffer = 0;
416  		if (tty)
417  			tty_wakeup(tty);
418  	}
419  
420  done:
421  	spin_unlock_irqrestore(&port->lock, flags);
422  	vcc_put(port, false);
423  }
424  
425  /**
426   * vcc_event() - LDC event processing engine
427   * @arg: VCC private data
428   * @event: LDC event
429   *
430   * Handles LDC events for VCC
431   */
vcc_event(void * arg,int event)432  static void vcc_event(void *arg, int event)
433  {
434  	struct vio_driver_state *vio;
435  	struct vcc_port *port;
436  	unsigned long flags;
437  	int rv;
438  
439  	port = arg;
440  	vio = &port->vio;
441  
442  	spin_lock_irqsave(&port->lock, flags);
443  
444  	switch (event) {
445  	case LDC_EVENT_RESET:
446  	case LDC_EVENT_UP:
447  		vio_link_state_change(vio, event);
448  		break;
449  
450  	case LDC_EVENT_DATA_READY:
451  		rv = vcc_ldc_read(port);
452  		if (rv == -ECONNRESET)
453  			vio_conn_reset(vio);
454  		break;
455  
456  	default:
457  		pr_err("VCC: unexpected LDC event(%d)\n", event);
458  	}
459  
460  	spin_unlock_irqrestore(&port->lock, flags);
461  }
462  
463  static struct ldc_channel_config vcc_ldc_cfg = {
464  	.event		= vcc_event,
465  	.mtu		= VIO_VCC_MTU_SIZE,
466  	.mode		= LDC_MODE_RAW,
467  	.debug		= 0,
468  };
469  
470  /* Ordered from largest major to lowest */
471  static struct vio_version vcc_versions[] = {
472  	{ .major = 1, .minor = 0 },
473  };
474  
475  static struct tty_port_operations vcc_port_ops = { 0 };
476  
domain_show(struct device * dev,struct device_attribute * attr,char * buf)477  static ssize_t domain_show(struct device *dev,
478  			   struct device_attribute *attr,
479  			   char *buf)
480  {
481  	struct vcc_port *port;
482  	int rv;
483  
484  	port = dev_get_drvdata(dev);
485  	if (!port)
486  		return -ENODEV;
487  
488  	rv = scnprintf(buf, PAGE_SIZE, "%s\n", port->domain);
489  
490  	return rv;
491  }
492  
vcc_send_ctl(struct vcc_port * port,int ctl)493  static int vcc_send_ctl(struct vcc_port *port, int ctl)
494  {
495  	struct vio_vcc pkt;
496  	int rv;
497  
498  	pkt.tag.type = VIO_TYPE_CTRL;
499  	pkt.tag.sid = ctl;
500  	pkt.tag.stype = 0;
501  
502  	rv = ldc_write(port->vio.lp, &pkt, sizeof(pkt.tag));
503  	WARN_ON(!rv);
504  	vccdbg("VCC: ldc_write(%ld)=%d\n", sizeof(pkt.tag), rv);
505  
506  	return rv;
507  }
508  
break_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)509  static ssize_t break_store(struct device *dev,
510  			   struct device_attribute *attr,
511  			   const char *buf, size_t count)
512  {
513  	struct vcc_port *port;
514  	unsigned long flags;
515  	int rv = count;
516  	int brk;
517  
518  	port = dev_get_drvdata(dev);
519  	if (!port)
520  		return -ENODEV;
521  
522  	spin_lock_irqsave(&port->lock, flags);
523  
524  	if (sscanf(buf, "%ud", &brk) != 1 || brk != 1)
525  		rv = -EINVAL;
526  	else if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0)
527  		vcc_kick_tx(port);
528  
529  	spin_unlock_irqrestore(&port->lock, flags);
530  
531  	return rv;
532  }
533  
534  static DEVICE_ATTR_ADMIN_RO(domain);
535  static DEVICE_ATTR_WO(break);
536  
537  static struct attribute *vcc_sysfs_entries[] = {
538  	&dev_attr_domain.attr,
539  	&dev_attr_break.attr,
540  	NULL
541  };
542  
543  static struct attribute_group vcc_attribute_group = {
544  	.name = NULL,
545  	.attrs = vcc_sysfs_entries,
546  };
547  
548  /**
549   * vcc_probe() - Initialize VCC port
550   * @vdev: Pointer to VIO device of the new VCC port
551   * @id: VIO device ID
552   *
553   * Initializes a VCC port to receive serial console data from
554   * the guest domain. Sets up a TTY end point on the control
555   * domain. Sets up VIO/LDC link between the guest & control
556   * domain endpoints.
557   *
558   * Return: status of the probe
559   */
vcc_probe(struct vio_dev * vdev,const struct vio_device_id * id)560  static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
561  {
562  	struct mdesc_handle *hp;
563  	struct vcc_port *port;
564  	struct device *dev;
565  	const char *domain;
566  	char *name;
567  	u64 node;
568  	int rv;
569  
570  	vccdbg("VCC: name=%s\n", dev_name(&vdev->dev));
571  
572  	if (!vcc_tty_driver) {
573  		pr_err("VCC: TTY driver not registered\n");
574  		return -ENODEV;
575  	}
576  
577  	port = kzalloc(sizeof(struct vcc_port), GFP_KERNEL);
578  	if (!port)
579  		return -ENOMEM;
580  
581  	name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL);
582  	if (!name) {
583  		rv = -ENOMEM;
584  		goto free_port;
585  	}
586  
587  	rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions,
588  			     ARRAY_SIZE(vcc_versions), NULL, name);
589  	if (rv)
590  		goto free_name;
591  
592  	port->vio.debug = vcc_dbg_vio;
593  	vcc_ldc_cfg.debug = vcc_dbg_ldc;
594  
595  	rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port);
596  	if (rv)
597  		goto free_name;
598  
599  	spin_lock_init(&port->lock);
600  
601  	port->index = vcc_table_add(port);
602  	if (port->index == -1) {
603  		pr_err("VCC: no more TTY indices left for allocation\n");
604  		rv = -ENOMEM;
605  		goto free_ldc;
606  	}
607  
608  	/* Register the device using VCC table index as TTY index */
609  	dev = tty_register_device(vcc_tty_driver, port->index, &vdev->dev);
610  	if (IS_ERR(dev)) {
611  		rv = PTR_ERR(dev);
612  		goto free_table;
613  	}
614  
615  	hp = mdesc_grab();
616  
617  	node = vio_vdev_node(hp, vdev);
618  	if (node == MDESC_NODE_NULL) {
619  		rv = -ENXIO;
620  		mdesc_release(hp);
621  		goto unreg_tty;
622  	}
623  
624  	domain = mdesc_get_property(hp, node, "vcc-domain-name", NULL);
625  	if (!domain) {
626  		rv = -ENXIO;
627  		mdesc_release(hp);
628  		goto unreg_tty;
629  	}
630  	port->domain = kstrdup(domain, GFP_KERNEL);
631  	if (!port->domain) {
632  		rv = -ENOMEM;
633  		goto unreg_tty;
634  	}
635  
636  
637  	mdesc_release(hp);
638  
639  	rv = sysfs_create_group(&vdev->dev.kobj, &vcc_attribute_group);
640  	if (rv)
641  		goto free_domain;
642  
643  	timer_setup(&port->rx_timer, vcc_rx_timer, 0);
644  	timer_setup(&port->tx_timer, vcc_tx_timer, 0);
645  
646  	dev_set_drvdata(&vdev->dev, port);
647  
648  	/* It's possible to receive IRQs in the middle of vio_port_up. Disable
649  	 * IRQs until the port is up.
650  	 */
651  	disable_irq_nosync(vdev->rx_irq);
652  	vio_port_up(&port->vio);
653  	enable_irq(vdev->rx_irq);
654  
655  	return 0;
656  
657  free_domain:
658  	kfree(port->domain);
659  unreg_tty:
660  	tty_unregister_device(vcc_tty_driver, port->index);
661  free_table:
662  	vcc_table_remove(port->index);
663  free_ldc:
664  	vio_ldc_free(&port->vio);
665  free_name:
666  	kfree(name);
667  free_port:
668  	kfree(port);
669  
670  	return rv;
671  }
672  
673  /**
674   * vcc_remove() - Terminate a VCC port
675   * @vdev: Pointer to VIO device of the VCC port
676   *
677   * Terminates a VCC port. Sets up the teardown of TTY and
678   * VIO/LDC link between guest and primary domains.
679   *
680   * Return: status of removal
681   */
vcc_remove(struct vio_dev * vdev)682  static void vcc_remove(struct vio_dev *vdev)
683  {
684  	struct vcc_port *port = dev_get_drvdata(&vdev->dev);
685  
686  	del_timer_sync(&port->rx_timer);
687  	del_timer_sync(&port->tx_timer);
688  
689  	/* If there's a process with the device open, do a synchronous
690  	 * hangup of the TTY. This *may* cause the process to call close
691  	 * asynchronously, but it's not guaranteed.
692  	 */
693  	if (port->tty)
694  		tty_vhangup(port->tty);
695  
696  	/* Get exclusive reference to VCC, ensures that there are no other
697  	 * clients to this port. This cannot fail.
698  	 */
699  	vcc_get(port->index, true);
700  
701  	tty_unregister_device(vcc_tty_driver, port->index);
702  
703  	del_timer_sync(&port->vio.timer);
704  	vio_ldc_free(&port->vio);
705  	sysfs_remove_group(&vdev->dev.kobj, &vcc_attribute_group);
706  	dev_set_drvdata(&vdev->dev, NULL);
707  	if (port->tty) {
708  		port->removed = true;
709  		vcc_put(port, true);
710  	} else {
711  		vcc_table_remove(port->index);
712  
713  		kfree(port->vio.name);
714  		kfree(port->domain);
715  		kfree(port);
716  	}
717  }
718  
719  static const struct vio_device_id vcc_match[] = {
720  	{
721  		.type = "vcc-port",
722  	},
723  	{},
724  };
725  MODULE_DEVICE_TABLE(vio, vcc_match);
726  
727  static struct vio_driver vcc_driver = {
728  	.id_table	= vcc_match,
729  	.probe		= vcc_probe,
730  	.remove		= vcc_remove,
731  	.name		= "vcc",
732  };
733  
vcc_open(struct tty_struct * tty,struct file * vcc_file)734  static int vcc_open(struct tty_struct *tty, struct file *vcc_file)
735  {
736  	struct vcc_port *port;
737  
738  	if (tty->count > 1)
739  		return -EBUSY;
740  
741  	port = vcc_get_ne(tty->index);
742  	if (unlikely(!port)) {
743  		pr_err("VCC: open: Failed to find VCC port\n");
744  		return -ENODEV;
745  	}
746  
747  	if (unlikely(!port->vio.lp)) {
748  		pr_err("VCC: open: LDC channel not configured\n");
749  		vcc_put(port, false);
750  		return -EPIPE;
751  	}
752  	vccdbgl(port->vio.lp);
753  
754  	vcc_put(port, false);
755  
756  	if (unlikely(!tty->port)) {
757  		pr_err("VCC: open: TTY port not found\n");
758  		return -ENXIO;
759  	}
760  
761  	if (unlikely(!tty->port->ops)) {
762  		pr_err("VCC: open: TTY ops not defined\n");
763  		return -ENXIO;
764  	}
765  
766  	return tty_port_open(tty->port, tty, vcc_file);
767  }
768  
vcc_close(struct tty_struct * tty,struct file * vcc_file)769  static void vcc_close(struct tty_struct *tty, struct file *vcc_file)
770  {
771  	if (unlikely(tty->count > 1))
772  		return;
773  
774  	if (unlikely(!tty->port)) {
775  		pr_err("VCC: close: TTY port not found\n");
776  		return;
777  	}
778  
779  	tty_port_close(tty->port, tty, vcc_file);
780  }
781  
vcc_ldc_hup(struct vcc_port * port)782  static void vcc_ldc_hup(struct vcc_port *port)
783  {
784  	unsigned long flags;
785  
786  	spin_lock_irqsave(&port->lock, flags);
787  
788  	if (vcc_send_ctl(port, VCC_CTL_HUP) < 0)
789  		vcc_kick_tx(port);
790  
791  	spin_unlock_irqrestore(&port->lock, flags);
792  }
793  
vcc_hangup(struct tty_struct * tty)794  static void vcc_hangup(struct tty_struct *tty)
795  {
796  	struct vcc_port *port;
797  
798  	port = vcc_get_ne(tty->index);
799  	if (unlikely(!port)) {
800  		pr_err("VCC: hangup: Failed to find VCC port\n");
801  		return;
802  	}
803  
804  	if (unlikely(!tty->port)) {
805  		pr_err("VCC: hangup: TTY port not found\n");
806  		vcc_put(port, false);
807  		return;
808  	}
809  
810  	vcc_ldc_hup(port);
811  
812  	vcc_put(port, false);
813  
814  	tty_port_hangup(tty->port);
815  }
816  
vcc_write(struct tty_struct * tty,const u8 * buf,size_t count)817  static ssize_t vcc_write(struct tty_struct *tty, const u8 *buf, size_t count)
818  {
819  	struct vcc_port *port;
820  	struct vio_vcc *pkt;
821  	unsigned long flags;
822  	size_t total_sent = 0;
823  	size_t tosend = 0;
824  	int rv = -EINVAL;
825  
826  	port = vcc_get_ne(tty->index);
827  	if (unlikely(!port)) {
828  		pr_err("VCC: write: Failed to find VCC port");
829  		return -ENODEV;
830  	}
831  
832  	spin_lock_irqsave(&port->lock, flags);
833  
834  	pkt = &port->buffer;
835  	pkt->tag.type = VIO_TYPE_DATA;
836  
837  	while (count > 0) {
838  		/* Minimum of data to write and space available */
839  		tosend = min_t(size_t, count,
840  			       (VCC_BUFF_LEN - port->chars_in_buffer));
841  
842  		if (!tosend)
843  			break;
844  
845  		memcpy(&pkt->data[port->chars_in_buffer], &buf[total_sent],
846  		       tosend);
847  		port->chars_in_buffer += tosend;
848  		pkt->tag.stype = tosend;
849  
850  		vccdbg("TAG [%02x:%02x:%04x:%08x]\n", pkt->tag.type,
851  		       pkt->tag.stype, pkt->tag.stype_env, pkt->tag.sid);
852  		vccdbg("DATA [%s]\n", pkt->data);
853  		vccdbgl(port->vio.lp);
854  
855  		/* Since we know we have enough room in VCC buffer for tosend
856  		 * we record that it was sent regardless of whether the
857  		 * hypervisor actually took it because we have it buffered.
858  		 */
859  		rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend));
860  		vccdbg("VCC: write: ldc_write(%zu)=%d\n",
861  		       (VIO_TAG_SIZE + tosend), rv);
862  
863  		total_sent += tosend;
864  		count -= tosend;
865  		if (rv < 0) {
866  			vcc_kick_tx(port);
867  			break;
868  		}
869  
870  		port->chars_in_buffer = 0;
871  	}
872  
873  	spin_unlock_irqrestore(&port->lock, flags);
874  
875  	vcc_put(port, false);
876  
877  	vccdbg("VCC: write: total=%zu rv=%d", total_sent, rv);
878  
879  	return total_sent ? total_sent : rv;
880  }
881  
vcc_write_room(struct tty_struct * tty)882  static unsigned int vcc_write_room(struct tty_struct *tty)
883  {
884  	struct vcc_port *port;
885  	unsigned int num;
886  
887  	port = vcc_get_ne(tty->index);
888  	if (unlikely(!port)) {
889  		pr_err("VCC: write_room: Failed to find VCC port\n");
890  		return 0;
891  	}
892  
893  	num = VCC_BUFF_LEN - port->chars_in_buffer;
894  
895  	vcc_put(port, false);
896  
897  	return num;
898  }
899  
vcc_chars_in_buffer(struct tty_struct * tty)900  static unsigned int vcc_chars_in_buffer(struct tty_struct *tty)
901  {
902  	struct vcc_port *port;
903  	unsigned int num;
904  
905  	port = vcc_get_ne(tty->index);
906  	if (unlikely(!port)) {
907  		pr_err("VCC: chars_in_buffer: Failed to find VCC port\n");
908  		return 0;
909  	}
910  
911  	num = port->chars_in_buffer;
912  
913  	vcc_put(port, false);
914  
915  	return num;
916  }
917  
vcc_break_ctl(struct tty_struct * tty,int state)918  static int vcc_break_ctl(struct tty_struct *tty, int state)
919  {
920  	struct vcc_port *port;
921  	unsigned long flags;
922  
923  	port = vcc_get_ne(tty->index);
924  	if (unlikely(!port)) {
925  		pr_err("VCC: break_ctl: Failed to find VCC port\n");
926  		return -ENODEV;
927  	}
928  
929  	/* Turn off break */
930  	if (state == 0) {
931  		vcc_put(port, false);
932  		return 0;
933  	}
934  
935  	spin_lock_irqsave(&port->lock, flags);
936  
937  	if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0)
938  		vcc_kick_tx(port);
939  
940  	spin_unlock_irqrestore(&port->lock, flags);
941  
942  	vcc_put(port, false);
943  
944  	return 0;
945  }
946  
vcc_install(struct tty_driver * driver,struct tty_struct * tty)947  static int vcc_install(struct tty_driver *driver, struct tty_struct *tty)
948  {
949  	struct vcc_port *port_vcc;
950  	struct tty_port *port_tty;
951  	int ret;
952  
953  	if (tty->index >= VCC_MAX_PORTS)
954  		return -EINVAL;
955  
956  	ret = tty_standard_install(driver, tty);
957  	if (ret)
958  		return ret;
959  
960  	port_tty = kzalloc(sizeof(struct tty_port), GFP_KERNEL);
961  	if (!port_tty)
962  		return -ENOMEM;
963  
964  	port_vcc = vcc_get(tty->index, true);
965  	if (!port_vcc) {
966  		pr_err("VCC: install: Failed to find VCC port\n");
967  		tty->port = NULL;
968  		kfree(port_tty);
969  		return -ENODEV;
970  	}
971  
972  	tty_port_init(port_tty);
973  	port_tty->ops = &vcc_port_ops;
974  	tty->port = port_tty;
975  
976  	port_vcc->tty = tty;
977  
978  	vcc_put(port_vcc, true);
979  
980  	return 0;
981  }
982  
vcc_cleanup(struct tty_struct * tty)983  static void vcc_cleanup(struct tty_struct *tty)
984  {
985  	struct vcc_port *port;
986  
987  	port = vcc_get(tty->index, true);
988  	if (port) {
989  		port->tty = NULL;
990  
991  		if (port->removed) {
992  			vcc_table_remove(tty->index);
993  			kfree(port->vio.name);
994  			kfree(port->domain);
995  			kfree(port);
996  		} else {
997  			vcc_put(port, true);
998  		}
999  	}
1000  
1001  	tty_port_destroy(tty->port);
1002  	kfree(tty->port);
1003  	tty->port = NULL;
1004  }
1005  
1006  static const struct tty_operations vcc_ops = {
1007  	.open			= vcc_open,
1008  	.close			= vcc_close,
1009  	.hangup			= vcc_hangup,
1010  	.write			= vcc_write,
1011  	.write_room		= vcc_write_room,
1012  	.chars_in_buffer	= vcc_chars_in_buffer,
1013  	.break_ctl		= vcc_break_ctl,
1014  	.install		= vcc_install,
1015  	.cleanup		= vcc_cleanup,
1016  };
1017  
1018  #define VCC_TTY_FLAGS   (TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_REAL_RAW)
1019  
vcc_tty_init(void)1020  static int vcc_tty_init(void)
1021  {
1022  	int rv;
1023  
1024  	vcc_tty_driver = tty_alloc_driver(VCC_MAX_PORTS, VCC_TTY_FLAGS);
1025  	if (IS_ERR(vcc_tty_driver)) {
1026  		pr_err("VCC: TTY driver alloc failed\n");
1027  		return PTR_ERR(vcc_tty_driver);
1028  	}
1029  
1030  	vcc_tty_driver->driver_name = "vcc";
1031  	vcc_tty_driver->name = "vcc";
1032  
1033  	vcc_tty_driver->minor_start = VCC_MINOR_START;
1034  	vcc_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
1035  	vcc_tty_driver->init_termios = vcc_tty_termios;
1036  
1037  	tty_set_operations(vcc_tty_driver, &vcc_ops);
1038  
1039  	rv = tty_register_driver(vcc_tty_driver);
1040  	if (rv) {
1041  		pr_err("VCC: TTY driver registration failed\n");
1042  		tty_driver_kref_put(vcc_tty_driver);
1043  		vcc_tty_driver = NULL;
1044  		return rv;
1045  	}
1046  
1047  	vccdbg("VCC: TTY driver registered\n");
1048  
1049  	return 0;
1050  }
1051  
vcc_tty_exit(void)1052  static void vcc_tty_exit(void)
1053  {
1054  	tty_unregister_driver(vcc_tty_driver);
1055  	tty_driver_kref_put(vcc_tty_driver);
1056  	vccdbg("VCC: TTY driver unregistered\n");
1057  
1058  	vcc_tty_driver = NULL;
1059  }
1060  
vcc_init(void)1061  static int __init vcc_init(void)
1062  {
1063  	int rv;
1064  
1065  	rv = vcc_tty_init();
1066  	if (rv) {
1067  		pr_err("VCC: TTY init failed\n");
1068  		return rv;
1069  	}
1070  
1071  	rv = vio_register_driver(&vcc_driver);
1072  	if (rv) {
1073  		pr_err("VCC: VIO driver registration failed\n");
1074  		vcc_tty_exit();
1075  	} else {
1076  		vccdbg("VCC: VIO driver registered successfully\n");
1077  	}
1078  
1079  	return rv;
1080  }
1081  
vcc_exit(void)1082  static void __exit vcc_exit(void)
1083  {
1084  	vio_unregister_driver(&vcc_driver);
1085  	vccdbg("VCC: VIO driver unregistered\n");
1086  	vcc_tty_exit();
1087  	vccdbg("VCC: TTY driver unregistered\n");
1088  }
1089  
1090  module_init(vcc_init);
1091  module_exit(vcc_exit);
1092