Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* vcc.c: sun4v virtual channel concentrator
0003  *
0004  * Copyright (C) 2017 Oracle. All rights reserved.
0005  */
0006 
0007 #include <linux/delay.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/module.h>
0010 #include <linux/slab.h>
0011 #include <linux/sysfs.h>
0012 #include <linux/tty.h>
0013 #include <linux/tty_flip.h>
0014 #include <asm/vio.h>
0015 #include <asm/ldc.h>
0016 
0017 MODULE_DESCRIPTION("Sun LDOM virtual console concentrator driver");
0018 MODULE_LICENSE("GPL");
0019 MODULE_VERSION("1.1");
0020 
0021 struct vcc_port {
0022     struct vio_driver_state vio;
0023 
0024     spinlock_t lock;
0025     char *domain;
0026     struct tty_struct *tty; /* only populated while dev is open */
0027     unsigned long index;    /* index into the vcc_table */
0028 
0029     u64 refcnt;
0030     bool excl_locked;
0031 
0032     bool removed;
0033 
0034     /* This buffer is required to support the tty write_room interface
0035      * and guarantee that any characters that the driver accepts will
0036      * be eventually sent, either immediately or later.
0037      */
0038     int chars_in_buffer;
0039     struct vio_vcc buffer;
0040 
0041     struct timer_list rx_timer;
0042     struct timer_list tx_timer;
0043 };
0044 
0045 /* Microseconds that thread will delay waiting for a vcc port ref */
0046 #define VCC_REF_DELAY       100
0047 
0048 #define VCC_MAX_PORTS       1024
0049 #define VCC_MINOR_START     0   /* must be zero */
0050 #define VCC_BUFF_LEN        VIO_VCC_MTU_SIZE
0051 
0052 #define VCC_CTL_BREAK       -1
0053 #define VCC_CTL_HUP     -2
0054 
0055 static struct tty_driver *vcc_tty_driver;
0056 
0057 static struct vcc_port *vcc_table[VCC_MAX_PORTS];
0058 static DEFINE_SPINLOCK(vcc_table_lock);
0059 
0060 static unsigned int vcc_dbg;
0061 static unsigned int vcc_dbg_ldc;
0062 static unsigned int vcc_dbg_vio;
0063 
0064 module_param(vcc_dbg, uint, 0664);
0065 module_param(vcc_dbg_ldc, uint, 0664);
0066 module_param(vcc_dbg_vio, uint, 0664);
0067 
0068 #define VCC_DBG_DRV 0x1
0069 #define VCC_DBG_LDC 0x2
0070 #define VCC_DBG_PKT 0x4
0071 
0072 #define vccdbg(f, a...)                     \
0073     do {                            \
0074         if (vcc_dbg & VCC_DBG_DRV)          \
0075             pr_info(f, ## a);           \
0076     } while (0)                     \
0077 
0078 #define vccdbgl(l)                      \
0079     do {                            \
0080         if (vcc_dbg & VCC_DBG_LDC)          \
0081             ldc_print(l);               \
0082     } while (0)                     \
0083 
0084 #define vccdbgp(pkt)                        \
0085     do {                            \
0086         if (vcc_dbg & VCC_DBG_PKT) {            \
0087             int i;                  \
0088             for (i = 0; i < pkt.tag.stype; i++) \
0089                 pr_info("[%c]", pkt.data[i]);   \
0090         }                       \
0091     } while (0)                     \
0092 
0093 /* Note: Be careful when adding flags to this line discipline.  Don't
0094  * add anything that will cause echoing or we'll go into recursive
0095  * loop echoing chars back and forth with the console drivers.
0096  */
0097 static const struct ktermios vcc_tty_termios = {
0098     .c_iflag = IGNBRK | IGNPAR,
0099     .c_oflag = OPOST,
0100     .c_cflag = B38400 | CS8 | CREAD | HUPCL,
0101     .c_cc = INIT_C_CC,
0102     .c_ispeed = 38400,
0103     .c_ospeed = 38400
0104 };
0105 
0106 /**
0107  * vcc_table_add() - Add VCC port to the VCC table
0108  * @port: pointer to the VCC port
0109  *
0110  * Return: index of the port in the VCC table on success,
0111  *     -1 on failure
0112  */
0113 static int vcc_table_add(struct vcc_port *port)
0114 {
0115     unsigned long flags;
0116     int i;
0117 
0118     spin_lock_irqsave(&vcc_table_lock, flags);
0119     for (i = VCC_MINOR_START; i < VCC_MAX_PORTS; i++) {
0120         if (!vcc_table[i]) {
0121             vcc_table[i] = port;
0122             break;
0123         }
0124     }
0125     spin_unlock_irqrestore(&vcc_table_lock, flags);
0126 
0127     if (i < VCC_MAX_PORTS)
0128         return i;
0129     else
0130         return -1;
0131 }
0132 
0133 /**
0134  * vcc_table_remove() - Removes a VCC port from the VCC table
0135  * @index: Index into the VCC table
0136  */
0137 static void vcc_table_remove(unsigned long index)
0138 {
0139     unsigned long flags;
0140 
0141     if (WARN_ON(index >= VCC_MAX_PORTS))
0142         return;
0143 
0144     spin_lock_irqsave(&vcc_table_lock, flags);
0145     vcc_table[index] = NULL;
0146     spin_unlock_irqrestore(&vcc_table_lock, flags);
0147 }
0148 
0149 /**
0150  * vcc_get() - Gets a reference to VCC port
0151  * @index: Index into the VCC table
0152  * @excl: Indicates if an exclusive access is requested
0153  *
0154  * Return: reference to the VCC port, if found
0155  *     NULL, if port not found
0156  */
0157 static struct vcc_port *vcc_get(unsigned long index, bool excl)
0158 {
0159     struct vcc_port *port;
0160     unsigned long flags;
0161 
0162 try_again:
0163     spin_lock_irqsave(&vcc_table_lock, flags);
0164 
0165     port = vcc_table[index];
0166     if (!port) {
0167         spin_unlock_irqrestore(&vcc_table_lock, flags);
0168         return NULL;
0169     }
0170 
0171     if (!excl) {
0172         if (port->excl_locked) {
0173             spin_unlock_irqrestore(&vcc_table_lock, flags);
0174             udelay(VCC_REF_DELAY);
0175             goto try_again;
0176         }
0177         port->refcnt++;
0178         spin_unlock_irqrestore(&vcc_table_lock, flags);
0179         return port;
0180     }
0181 
0182     if (port->refcnt) {
0183         spin_unlock_irqrestore(&vcc_table_lock, flags);
0184         /* Threads wanting exclusive access will wait half the time,
0185          * probably giving them higher priority in the case of
0186          * multiple waiters.
0187          */
0188         udelay(VCC_REF_DELAY/2);
0189         goto try_again;
0190     }
0191 
0192     port->refcnt++;
0193     port->excl_locked = true;
0194     spin_unlock_irqrestore(&vcc_table_lock, flags);
0195 
0196     return port;
0197 }
0198 
0199 /**
0200  * vcc_put() - Returns a reference to VCC port
0201  * @port: pointer to VCC port
0202  * @excl: Indicates if the returned reference is an exclusive reference
0203  *
0204  * Note: It's the caller's responsibility to ensure the correct value
0205  *   for the excl flag
0206  */
0207 static void vcc_put(struct vcc_port *port, bool excl)
0208 {
0209     unsigned long flags;
0210 
0211     if (!port)
0212         return;
0213 
0214     spin_lock_irqsave(&vcc_table_lock, flags);
0215 
0216     /* check if caller attempted to put with the wrong flags */
0217     if (WARN_ON((excl && !port->excl_locked) ||
0218             (!excl && port->excl_locked)))
0219         goto done;
0220 
0221     port->refcnt--;
0222 
0223     if (excl)
0224         port->excl_locked = false;
0225 
0226 done:
0227     spin_unlock_irqrestore(&vcc_table_lock, flags);
0228 }
0229 
0230 /**
0231  * vcc_get_ne() - Get a non-exclusive reference to VCC port
0232  * @index: Index into the VCC table
0233  *
0234  * Gets a non-exclusive reference to VCC port, if it's not removed
0235  *
0236  * Return: pointer to the VCC port, if found
0237  *     NULL, if port not found
0238  */
0239 static struct vcc_port *vcc_get_ne(unsigned long index)
0240 {
0241     struct vcc_port *port;
0242 
0243     port = vcc_get(index, false);
0244 
0245     if (port && port->removed) {
0246         vcc_put(port, false);
0247         return NULL;
0248     }
0249 
0250     return port;
0251 }
0252 
0253 static void vcc_kick_rx(struct vcc_port *port)
0254 {
0255     struct vio_driver_state *vio = &port->vio;
0256 
0257     assert_spin_locked(&port->lock);
0258 
0259     if (!timer_pending(&port->rx_timer) && !port->removed) {
0260         disable_irq_nosync(vio->vdev->rx_irq);
0261         port->rx_timer.expires = (jiffies + 1);
0262         add_timer(&port->rx_timer);
0263     }
0264 }
0265 
0266 static void vcc_kick_tx(struct vcc_port *port)
0267 {
0268     assert_spin_locked(&port->lock);
0269 
0270     if (!timer_pending(&port->tx_timer) && !port->removed) {
0271         port->tx_timer.expires = (jiffies + 1);
0272         add_timer(&port->tx_timer);
0273     }
0274 }
0275 
0276 static int vcc_rx_check(struct tty_struct *tty, int size)
0277 {
0278     if (WARN_ON(!tty || !tty->port))
0279         return 1;
0280 
0281     /* tty_buffer_request_room won't sleep because it uses
0282      * GFP_ATOMIC flag to allocate buffer
0283      */
0284     if (test_bit(TTY_THROTTLED, &tty->flags) ||
0285         (tty_buffer_request_room(tty->port, VCC_BUFF_LEN) < VCC_BUFF_LEN))
0286         return 0;
0287 
0288     return 1;
0289 }
0290 
0291 static int vcc_rx(struct tty_struct *tty, char *buf, int size)
0292 {
0293     int len = 0;
0294 
0295     if (WARN_ON(!tty || !tty->port))
0296         return len;
0297 
0298     len = tty_insert_flip_string(tty->port, buf, size);
0299     if (len)
0300         tty_flip_buffer_push(tty->port);
0301 
0302     return len;
0303 }
0304 
0305 static int vcc_ldc_read(struct vcc_port *port)
0306 {
0307     struct vio_driver_state *vio = &port->vio;
0308     struct tty_struct *tty;
0309     struct vio_vcc pkt;
0310     int rv = 0;
0311 
0312     tty = port->tty;
0313     if (!tty) {
0314         rv = ldc_rx_reset(vio->lp);
0315         vccdbg("VCC: reset rx q: rv=%d\n", rv);
0316         goto done;
0317     }
0318 
0319     /* Read as long as LDC has incoming data. */
0320     while (1) {
0321         if (!vcc_rx_check(tty, VIO_VCC_MTU_SIZE)) {
0322             vcc_kick_rx(port);
0323             break;
0324         }
0325 
0326         vccdbgl(vio->lp);
0327 
0328         rv = ldc_read(vio->lp, &pkt, sizeof(pkt));
0329         if (rv <= 0)
0330             break;
0331 
0332         vccdbg("VCC: ldc_read()=%d\n", rv);
0333         vccdbg("TAG [%02x:%02x:%04x:%08x]\n",
0334                pkt.tag.type, pkt.tag.stype,
0335                pkt.tag.stype_env, pkt.tag.sid);
0336 
0337         if (pkt.tag.type == VIO_TYPE_DATA) {
0338             vccdbgp(pkt);
0339             /* vcc_rx_check ensures memory availability */
0340             vcc_rx(tty, pkt.data, pkt.tag.stype);
0341         } else {
0342             pr_err("VCC: unknown msg [%02x:%02x:%04x:%08x]\n",
0343                    pkt.tag.type, pkt.tag.stype,
0344                    pkt.tag.stype_env, pkt.tag.sid);
0345             rv = -ECONNRESET;
0346             break;
0347         }
0348 
0349         WARN_ON(rv != LDC_PACKET_SIZE);
0350     }
0351 
0352 done:
0353     return rv;
0354 }
0355 
0356 static void vcc_rx_timer(struct timer_list *t)
0357 {
0358     struct vcc_port *port = from_timer(port, t, rx_timer);
0359     struct vio_driver_state *vio;
0360     unsigned long flags;
0361     int rv;
0362 
0363     spin_lock_irqsave(&port->lock, flags);
0364     port->rx_timer.expires = 0;
0365 
0366     vio = &port->vio;
0367 
0368     enable_irq(vio->vdev->rx_irq);
0369 
0370     if (!port->tty || port->removed)
0371         goto done;
0372 
0373     rv = vcc_ldc_read(port);
0374     if (rv == -ECONNRESET)
0375         vio_conn_reset(vio);
0376 
0377 done:
0378     spin_unlock_irqrestore(&port->lock, flags);
0379     vcc_put(port, false);
0380 }
0381 
0382 static void vcc_tx_timer(struct timer_list *t)
0383 {
0384     struct vcc_port *port = from_timer(port, t, tx_timer);
0385     struct vio_vcc *pkt;
0386     unsigned long flags;
0387     int tosend = 0;
0388     int rv;
0389 
0390     spin_lock_irqsave(&port->lock, flags);
0391     port->tx_timer.expires = 0;
0392 
0393     if (!port->tty || port->removed)
0394         goto done;
0395 
0396     tosend = min(VCC_BUFF_LEN, port->chars_in_buffer);
0397     if (!tosend)
0398         goto done;
0399 
0400     pkt = &port->buffer;
0401     pkt->tag.type = VIO_TYPE_DATA;
0402     pkt->tag.stype = tosend;
0403     vccdbgl(port->vio.lp);
0404 
0405     rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend));
0406     WARN_ON(!rv);
0407 
0408     if (rv < 0) {
0409         vccdbg("VCC: ldc_write()=%d\n", rv);
0410         vcc_kick_tx(port);
0411     } else {
0412         struct tty_struct *tty = port->tty;
0413 
0414         port->chars_in_buffer = 0;
0415         if (tty)
0416             tty_wakeup(tty);
0417     }
0418 
0419 done:
0420     spin_unlock_irqrestore(&port->lock, flags);
0421     vcc_put(port, false);
0422 }
0423 
0424 /**
0425  * vcc_event() - LDC event processing engine
0426  * @arg: VCC private data
0427  * @event: LDC event
0428  *
0429  * Handles LDC events for VCC
0430  */
0431 static void vcc_event(void *arg, int event)
0432 {
0433     struct vio_driver_state *vio;
0434     struct vcc_port *port;
0435     unsigned long flags;
0436     int rv;
0437 
0438     port = arg;
0439     vio = &port->vio;
0440 
0441     spin_lock_irqsave(&port->lock, flags);
0442 
0443     switch (event) {
0444     case LDC_EVENT_RESET:
0445     case LDC_EVENT_UP:
0446         vio_link_state_change(vio, event);
0447         break;
0448 
0449     case LDC_EVENT_DATA_READY:
0450         rv = vcc_ldc_read(port);
0451         if (rv == -ECONNRESET)
0452             vio_conn_reset(vio);
0453         break;
0454 
0455     default:
0456         pr_err("VCC: unexpected LDC event(%d)\n", event);
0457     }
0458 
0459     spin_unlock_irqrestore(&port->lock, flags);
0460 }
0461 
0462 static struct ldc_channel_config vcc_ldc_cfg = {
0463     .event      = vcc_event,
0464     .mtu        = VIO_VCC_MTU_SIZE,
0465     .mode       = LDC_MODE_RAW,
0466     .debug      = 0,
0467 };
0468 
0469 /* Ordered from largest major to lowest */
0470 static struct vio_version vcc_versions[] = {
0471     { .major = 1, .minor = 0 },
0472 };
0473 
0474 static struct tty_port_operations vcc_port_ops = { 0 };
0475 
0476 static ssize_t domain_show(struct device *dev,
0477                struct device_attribute *attr,
0478                char *buf)
0479 {
0480     struct vcc_port *port;
0481     int rv;
0482 
0483     port = dev_get_drvdata(dev);
0484     if (!port)
0485         return -ENODEV;
0486 
0487     rv = scnprintf(buf, PAGE_SIZE, "%s\n", port->domain);
0488 
0489     return rv;
0490 }
0491 
0492 static int vcc_send_ctl(struct vcc_port *port, int ctl)
0493 {
0494     struct vio_vcc pkt;
0495     int rv;
0496 
0497     pkt.tag.type = VIO_TYPE_CTRL;
0498     pkt.tag.sid = ctl;
0499     pkt.tag.stype = 0;
0500 
0501     rv = ldc_write(port->vio.lp, &pkt, sizeof(pkt.tag));
0502     WARN_ON(!rv);
0503     vccdbg("VCC: ldc_write(%ld)=%d\n", sizeof(pkt.tag), rv);
0504 
0505     return rv;
0506 }
0507 
0508 static ssize_t break_store(struct device *dev,
0509                struct device_attribute *attr,
0510                const char *buf, size_t count)
0511 {
0512     struct vcc_port *port;
0513     unsigned long flags;
0514     int rv = count;
0515     int brk;
0516 
0517     port = dev_get_drvdata(dev);
0518     if (!port)
0519         return -ENODEV;
0520 
0521     spin_lock_irqsave(&port->lock, flags);
0522 
0523     if (sscanf(buf, "%ud", &brk) != 1 || brk != 1)
0524         rv = -EINVAL;
0525     else if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0)
0526         vcc_kick_tx(port);
0527 
0528     spin_unlock_irqrestore(&port->lock, flags);
0529 
0530     return rv;
0531 }
0532 
0533 static DEVICE_ATTR_ADMIN_RO(domain);
0534 static DEVICE_ATTR_WO(break);
0535 
0536 static struct attribute *vcc_sysfs_entries[] = {
0537     &dev_attr_domain.attr,
0538     &dev_attr_break.attr,
0539     NULL
0540 };
0541 
0542 static struct attribute_group vcc_attribute_group = {
0543     .name = NULL,
0544     .attrs = vcc_sysfs_entries,
0545 };
0546 
0547 /**
0548  * vcc_probe() - Initialize VCC port
0549  * @vdev: Pointer to VIO device of the new VCC port
0550  * @id: VIO device ID
0551  *
0552  * Initializes a VCC port to receive serial console data from
0553  * the guest domain. Sets up a TTY end point on the control
0554  * domain. Sets up VIO/LDC link between the guest & control
0555  * domain endpoints.
0556  *
0557  * Return: status of the probe
0558  */
0559 static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
0560 {
0561     struct mdesc_handle *hp;
0562     struct vcc_port *port;
0563     struct device *dev;
0564     const char *domain;
0565     char *name;
0566     u64 node;
0567     int rv;
0568 
0569     vccdbg("VCC: name=%s\n", dev_name(&vdev->dev));
0570 
0571     if (!vcc_tty_driver) {
0572         pr_err("VCC: TTY driver not registered\n");
0573         return -ENODEV;
0574     }
0575 
0576     port = kzalloc(sizeof(struct vcc_port), GFP_KERNEL);
0577     if (!port)
0578         return -ENOMEM;
0579 
0580     name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL);
0581 
0582     rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions,
0583                  ARRAY_SIZE(vcc_versions), NULL, name);
0584     if (rv)
0585         goto free_port;
0586 
0587     port->vio.debug = vcc_dbg_vio;
0588     vcc_ldc_cfg.debug = vcc_dbg_ldc;
0589 
0590     rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port);
0591     if (rv)
0592         goto free_port;
0593 
0594     spin_lock_init(&port->lock);
0595 
0596     port->index = vcc_table_add(port);
0597     if (port->index == -1) {
0598         pr_err("VCC: no more TTY indices left for allocation\n");
0599         rv = -ENOMEM;
0600         goto free_ldc;
0601     }
0602 
0603     /* Register the device using VCC table index as TTY index */
0604     dev = tty_register_device(vcc_tty_driver, port->index, &vdev->dev);
0605     if (IS_ERR(dev)) {
0606         rv = PTR_ERR(dev);
0607         goto free_table;
0608     }
0609 
0610     hp = mdesc_grab();
0611 
0612     node = vio_vdev_node(hp, vdev);
0613     if (node == MDESC_NODE_NULL) {
0614         rv = -ENXIO;
0615         mdesc_release(hp);
0616         goto unreg_tty;
0617     }
0618 
0619     domain = mdesc_get_property(hp, node, "vcc-domain-name", NULL);
0620     if (!domain) {
0621         rv = -ENXIO;
0622         mdesc_release(hp);
0623         goto unreg_tty;
0624     }
0625     port->domain = kstrdup(domain, GFP_KERNEL);
0626 
0627     mdesc_release(hp);
0628 
0629     rv = sysfs_create_group(&vdev->dev.kobj, &vcc_attribute_group);
0630     if (rv)
0631         goto free_domain;
0632 
0633     timer_setup(&port->rx_timer, vcc_rx_timer, 0);
0634     timer_setup(&port->tx_timer, vcc_tx_timer, 0);
0635 
0636     dev_set_drvdata(&vdev->dev, port);
0637 
0638     /* It's possible to receive IRQs in the middle of vio_port_up. Disable
0639      * IRQs until the port is up.
0640      */
0641     disable_irq_nosync(vdev->rx_irq);
0642     vio_port_up(&port->vio);
0643     enable_irq(vdev->rx_irq);
0644 
0645     return 0;
0646 
0647 free_domain:
0648     kfree(port->domain);
0649 unreg_tty:
0650     tty_unregister_device(vcc_tty_driver, port->index);
0651 free_table:
0652     vcc_table_remove(port->index);
0653 free_ldc:
0654     vio_ldc_free(&port->vio);
0655 free_port:
0656     kfree(name);
0657     kfree(port);
0658 
0659     return rv;
0660 }
0661 
0662 /**
0663  * vcc_remove() - Terminate a VCC port
0664  * @vdev: Pointer to VIO device of the VCC port
0665  *
0666  * Terminates a VCC port. Sets up the teardown of TTY and
0667  * VIO/LDC link between guest and primary domains.
0668  *
0669  * Return: status of removal
0670  */
0671 static void vcc_remove(struct vio_dev *vdev)
0672 {
0673     struct vcc_port *port = dev_get_drvdata(&vdev->dev);
0674 
0675     del_timer_sync(&port->rx_timer);
0676     del_timer_sync(&port->tx_timer);
0677 
0678     /* If there's a process with the device open, do a synchronous
0679      * hangup of the TTY. This *may* cause the process to call close
0680      * asynchronously, but it's not guaranteed.
0681      */
0682     if (port->tty)
0683         tty_vhangup(port->tty);
0684 
0685     /* Get exclusive reference to VCC, ensures that there are no other
0686      * clients to this port. This cannot fail.
0687      */
0688     vcc_get(port->index, true);
0689 
0690     tty_unregister_device(vcc_tty_driver, port->index);
0691 
0692     del_timer_sync(&port->vio.timer);
0693     vio_ldc_free(&port->vio);
0694     sysfs_remove_group(&vdev->dev.kobj, &vcc_attribute_group);
0695     dev_set_drvdata(&vdev->dev, NULL);
0696     if (port->tty) {
0697         port->removed = true;
0698         vcc_put(port, true);
0699     } else {
0700         vcc_table_remove(port->index);
0701 
0702         kfree(port->vio.name);
0703         kfree(port->domain);
0704         kfree(port);
0705     }
0706 }
0707 
0708 static const struct vio_device_id vcc_match[] = {
0709     {
0710         .type = "vcc-port",
0711     },
0712     {},
0713 };
0714 MODULE_DEVICE_TABLE(vio, vcc_match);
0715 
0716 static struct vio_driver vcc_driver = {
0717     .id_table   = vcc_match,
0718     .probe      = vcc_probe,
0719     .remove     = vcc_remove,
0720     .name       = "vcc",
0721 };
0722 
0723 static int vcc_open(struct tty_struct *tty, struct file *vcc_file)
0724 {
0725     struct vcc_port *port;
0726 
0727     if (tty->count > 1)
0728         return -EBUSY;
0729 
0730     port = vcc_get_ne(tty->index);
0731     if (unlikely(!port)) {
0732         pr_err("VCC: open: Failed to find VCC port\n");
0733         return -ENODEV;
0734     }
0735 
0736     if (unlikely(!port->vio.lp)) {
0737         pr_err("VCC: open: LDC channel not configured\n");
0738         vcc_put(port, false);
0739         return -EPIPE;
0740     }
0741     vccdbgl(port->vio.lp);
0742 
0743     vcc_put(port, false);
0744 
0745     if (unlikely(!tty->port)) {
0746         pr_err("VCC: open: TTY port not found\n");
0747         return -ENXIO;
0748     }
0749 
0750     if (unlikely(!tty->port->ops)) {
0751         pr_err("VCC: open: TTY ops not defined\n");
0752         return -ENXIO;
0753     }
0754 
0755     return tty_port_open(tty->port, tty, vcc_file);
0756 }
0757 
0758 static void vcc_close(struct tty_struct *tty, struct file *vcc_file)
0759 {
0760     if (unlikely(tty->count > 1))
0761         return;
0762 
0763     if (unlikely(!tty->port)) {
0764         pr_err("VCC: close: TTY port not found\n");
0765         return;
0766     }
0767 
0768     tty_port_close(tty->port, tty, vcc_file);
0769 }
0770 
0771 static void vcc_ldc_hup(struct vcc_port *port)
0772 {
0773     unsigned long flags;
0774 
0775     spin_lock_irqsave(&port->lock, flags);
0776 
0777     if (vcc_send_ctl(port, VCC_CTL_HUP) < 0)
0778         vcc_kick_tx(port);
0779 
0780     spin_unlock_irqrestore(&port->lock, flags);
0781 }
0782 
0783 static void vcc_hangup(struct tty_struct *tty)
0784 {
0785     struct vcc_port *port;
0786 
0787     port = vcc_get_ne(tty->index);
0788     if (unlikely(!port)) {
0789         pr_err("VCC: hangup: Failed to find VCC port\n");
0790         return;
0791     }
0792 
0793     if (unlikely(!tty->port)) {
0794         pr_err("VCC: hangup: TTY port not found\n");
0795         vcc_put(port, false);
0796         return;
0797     }
0798 
0799     vcc_ldc_hup(port);
0800 
0801     vcc_put(port, false);
0802 
0803     tty_port_hangup(tty->port);
0804 }
0805 
0806 static int vcc_write(struct tty_struct *tty, const unsigned char *buf,
0807              int count)
0808 {
0809     struct vcc_port *port;
0810     struct vio_vcc *pkt;
0811     unsigned long flags;
0812     int total_sent = 0;
0813     int tosend = 0;
0814     int rv = -EINVAL;
0815 
0816     port = vcc_get_ne(tty->index);
0817     if (unlikely(!port)) {
0818         pr_err("VCC: write: Failed to find VCC port");
0819         return -ENODEV;
0820     }
0821 
0822     spin_lock_irqsave(&port->lock, flags);
0823 
0824     pkt = &port->buffer;
0825     pkt->tag.type = VIO_TYPE_DATA;
0826 
0827     while (count > 0) {
0828         /* Minimum of data to write and space available */
0829         tosend = min(count, (VCC_BUFF_LEN - port->chars_in_buffer));
0830 
0831         if (!tosend)
0832             break;
0833 
0834         memcpy(&pkt->data[port->chars_in_buffer], &buf[total_sent],
0835                tosend);
0836         port->chars_in_buffer += tosend;
0837         pkt->tag.stype = tosend;
0838 
0839         vccdbg("TAG [%02x:%02x:%04x:%08x]\n", pkt->tag.type,
0840                pkt->tag.stype, pkt->tag.stype_env, pkt->tag.sid);
0841         vccdbg("DATA [%s]\n", pkt->data);
0842         vccdbgl(port->vio.lp);
0843 
0844         /* Since we know we have enough room in VCC buffer for tosend
0845          * we record that it was sent regardless of whether the
0846          * hypervisor actually took it because we have it buffered.
0847          */
0848         rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend));
0849         vccdbg("VCC: write: ldc_write(%d)=%d\n",
0850                (VIO_TAG_SIZE + tosend), rv);
0851 
0852         total_sent += tosend;
0853         count -= tosend;
0854         if (rv < 0) {
0855             vcc_kick_tx(port);
0856             break;
0857         }
0858 
0859         port->chars_in_buffer = 0;
0860     }
0861 
0862     spin_unlock_irqrestore(&port->lock, flags);
0863 
0864     vcc_put(port, false);
0865 
0866     vccdbg("VCC: write: total=%d rv=%d", total_sent, rv);
0867 
0868     return total_sent ? total_sent : rv;
0869 }
0870 
0871 static unsigned int vcc_write_room(struct tty_struct *tty)
0872 {
0873     struct vcc_port *port;
0874     unsigned int num;
0875 
0876     port = vcc_get_ne(tty->index);
0877     if (unlikely(!port)) {
0878         pr_err("VCC: write_room: Failed to find VCC port\n");
0879         return 0;
0880     }
0881 
0882     num = VCC_BUFF_LEN - port->chars_in_buffer;
0883 
0884     vcc_put(port, false);
0885 
0886     return num;
0887 }
0888 
0889 static unsigned int vcc_chars_in_buffer(struct tty_struct *tty)
0890 {
0891     struct vcc_port *port;
0892     unsigned int num;
0893 
0894     port = vcc_get_ne(tty->index);
0895     if (unlikely(!port)) {
0896         pr_err("VCC: chars_in_buffer: Failed to find VCC port\n");
0897         return 0;
0898     }
0899 
0900     num = port->chars_in_buffer;
0901 
0902     vcc_put(port, false);
0903 
0904     return num;
0905 }
0906 
0907 static int vcc_break_ctl(struct tty_struct *tty, int state)
0908 {
0909     struct vcc_port *port;
0910     unsigned long flags;
0911 
0912     port = vcc_get_ne(tty->index);
0913     if (unlikely(!port)) {
0914         pr_err("VCC: break_ctl: Failed to find VCC port\n");
0915         return -ENODEV;
0916     }
0917 
0918     /* Turn off break */
0919     if (state == 0) {
0920         vcc_put(port, false);
0921         return 0;
0922     }
0923 
0924     spin_lock_irqsave(&port->lock, flags);
0925 
0926     if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0)
0927         vcc_kick_tx(port);
0928 
0929     spin_unlock_irqrestore(&port->lock, flags);
0930 
0931     vcc_put(port, false);
0932 
0933     return 0;
0934 }
0935 
0936 static int vcc_install(struct tty_driver *driver, struct tty_struct *tty)
0937 {
0938     struct vcc_port *port_vcc;
0939     struct tty_port *port_tty;
0940     int ret;
0941 
0942     if (tty->index >= VCC_MAX_PORTS)
0943         return -EINVAL;
0944 
0945     ret = tty_standard_install(driver, tty);
0946     if (ret)
0947         return ret;
0948 
0949     port_tty = kzalloc(sizeof(struct tty_port), GFP_KERNEL);
0950     if (!port_tty)
0951         return -ENOMEM;
0952 
0953     port_vcc = vcc_get(tty->index, true);
0954     if (!port_vcc) {
0955         pr_err("VCC: install: Failed to find VCC port\n");
0956         tty->port = NULL;
0957         kfree(port_tty);
0958         return -ENODEV;
0959     }
0960 
0961     tty_port_init(port_tty);
0962     port_tty->ops = &vcc_port_ops;
0963     tty->port = port_tty;
0964 
0965     port_vcc->tty = tty;
0966 
0967     vcc_put(port_vcc, true);
0968 
0969     return 0;
0970 }
0971 
0972 static void vcc_cleanup(struct tty_struct *tty)
0973 {
0974     struct vcc_port *port;
0975 
0976     port = vcc_get(tty->index, true);
0977     if (port) {
0978         port->tty = NULL;
0979 
0980         if (port->removed) {
0981             vcc_table_remove(tty->index);
0982             kfree(port->vio.name);
0983             kfree(port->domain);
0984             kfree(port);
0985         } else {
0986             vcc_put(port, true);
0987         }
0988     }
0989 
0990     tty_port_destroy(tty->port);
0991     kfree(tty->port);
0992     tty->port = NULL;
0993 }
0994 
0995 static const struct tty_operations vcc_ops = {
0996     .open           = vcc_open,
0997     .close          = vcc_close,
0998     .hangup         = vcc_hangup,
0999     .write          = vcc_write,
1000     .write_room     = vcc_write_room,
1001     .chars_in_buffer    = vcc_chars_in_buffer,
1002     .break_ctl      = vcc_break_ctl,
1003     .install        = vcc_install,
1004     .cleanup        = vcc_cleanup,
1005 };
1006 
1007 #define VCC_TTY_FLAGS   (TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_REAL_RAW)
1008 
1009 static int vcc_tty_init(void)
1010 {
1011     int rv;
1012 
1013     vcc_tty_driver = tty_alloc_driver(VCC_MAX_PORTS, VCC_TTY_FLAGS);
1014     if (IS_ERR(vcc_tty_driver)) {
1015         pr_err("VCC: TTY driver alloc failed\n");
1016         return PTR_ERR(vcc_tty_driver);
1017     }
1018 
1019     vcc_tty_driver->driver_name = "vcc";
1020     vcc_tty_driver->name = "vcc";
1021 
1022     vcc_tty_driver->minor_start = VCC_MINOR_START;
1023     vcc_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
1024     vcc_tty_driver->init_termios = vcc_tty_termios;
1025 
1026     tty_set_operations(vcc_tty_driver, &vcc_ops);
1027 
1028     rv = tty_register_driver(vcc_tty_driver);
1029     if (rv) {
1030         pr_err("VCC: TTY driver registration failed\n");
1031         tty_driver_kref_put(vcc_tty_driver);
1032         vcc_tty_driver = NULL;
1033         return rv;
1034     }
1035 
1036     vccdbg("VCC: TTY driver registered\n");
1037 
1038     return 0;
1039 }
1040 
1041 static void vcc_tty_exit(void)
1042 {
1043     tty_unregister_driver(vcc_tty_driver);
1044     tty_driver_kref_put(vcc_tty_driver);
1045     vccdbg("VCC: TTY driver unregistered\n");
1046 
1047     vcc_tty_driver = NULL;
1048 }
1049 
1050 static int __init vcc_init(void)
1051 {
1052     int rv;
1053 
1054     rv = vcc_tty_init();
1055     if (rv) {
1056         pr_err("VCC: TTY init failed\n");
1057         return rv;
1058     }
1059 
1060     rv = vio_register_driver(&vcc_driver);
1061     if (rv) {
1062         pr_err("VCC: VIO driver registration failed\n");
1063         vcc_tty_exit();
1064     } else {
1065         vccdbg("VCC: VIO driver registered successfully\n");
1066     }
1067 
1068     return rv;
1069 }
1070 
1071 static void __exit vcc_exit(void)
1072 {
1073     vio_unregister_driver(&vcc_driver);
1074     vccdbg("VCC: VIO driver unregistered\n");
1075     vcc_tty_exit();
1076     vccdbg("VCC: TTY driver unregistered\n");
1077 }
1078 
1079 module_init(vcc_init);
1080 module_exit(vcc_exit);