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