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