0001
0002
0003
0004
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;
0027 unsigned long index;
0028
0029 u64 refcnt;
0030 bool excl_locked;
0031
0032 bool removed;
0033
0034
0035
0036
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
0046 #define VCC_REF_DELAY 100
0047
0048 #define VCC_MAX_PORTS 1024
0049 #define VCC_MINOR_START 0
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
0094
0095
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
0108
0109
0110
0111
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
0135
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
0151
0152
0153
0154
0155
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
0185
0186
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
0201
0202
0203
0204
0205
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
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
0232
0233
0234
0235
0236
0237
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
0282
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
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
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
0426
0427
0428
0429
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
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
0549
0550
0551
0552
0553
0554
0555
0556
0557
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
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
0639
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
0664
0665
0666
0667
0668
0669
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
0679
0680
0681
0682 if (port->tty)
0683 tty_vhangup(port->tty);
0684
0685
0686
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
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
0845
0846
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
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);