Lines Matching refs:port

185 struct port {  struct
255 static struct port *find_port_by_vtermno(u32 vtermno) in find_port_by_vtermno() argument
257 struct port *port; in find_port_by_vtermno() local
264 port = container_of(cons, struct port, cons); in find_port_by_vtermno()
268 port = NULL; in find_port_by_vtermno()
271 return port; in find_port_by_vtermno()
274 static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev, in find_port_by_devt_in_portdev()
277 struct port *port; in find_port_by_devt_in_portdev() local
281 list_for_each_entry(port, &portdev->ports, list) { in find_port_by_devt_in_portdev()
282 if (port->cdev->dev == dev) { in find_port_by_devt_in_portdev()
283 kref_get(&port->kref); in find_port_by_devt_in_portdev()
287 port = NULL; in find_port_by_devt_in_portdev()
291 return port; in find_port_by_devt_in_portdev()
294 static struct port *find_port_by_devt(dev_t dev) in find_port_by_devt()
297 struct port *port; in find_port_by_devt() local
302 port = find_port_by_devt_in_portdev(portdev, dev); in find_port_by_devt()
303 if (port) in find_port_by_devt()
306 port = NULL; in find_port_by_devt()
309 return port; in find_port_by_devt()
312 static struct port *find_port_by_id(struct ports_device *portdev, u32 id) in find_port_by_id()
314 struct port *port; in find_port_by_id() local
318 list_for_each_entry(port, &portdev->ports, list) in find_port_by_id()
319 if (port->id == id) in find_port_by_id()
321 port = NULL; in find_port_by_id()
325 return port; in find_port_by_id()
328 static struct port *find_port_by_vq(struct ports_device *portdev, in find_port_by_vq()
331 struct port *port; in find_port_by_vq() local
335 list_for_each_entry(port, &portdev->ports, list) in find_port_by_vq()
336 if (port->in_vq == vq || port->out_vq == vq) in find_port_by_vq()
338 port = NULL; in find_port_by_vq()
341 return port; in find_port_by_vq()
344 static bool is_console_port(struct port *port) in is_console_port() argument
346 if (port->cons.hvc) in is_console_port()
481 static struct port_buffer *get_inbuf(struct port *port) in get_inbuf() argument
486 if (port->inbuf) in get_inbuf()
487 return port->inbuf; in get_inbuf()
489 buf = virtqueue_get_buf(port->in_vq, &len); in get_inbuf()
493 port->stats.bytes_received += len; in get_inbuf()
519 static void discard_port_data(struct port *port) in discard_port_data() argument
524 if (!port->portdev) { in discard_port_data()
528 buf = get_inbuf(port); in discard_port_data()
532 port->stats.bytes_discarded += buf->len - buf->offset; in discard_port_data()
533 if (add_inbuf(port->in_vq, buf) < 0) { in discard_port_data()
537 port->inbuf = NULL; in discard_port_data()
538 buf = get_inbuf(port); in discard_port_data()
541 dev_warn(port->dev, "Errors adding %d buffers back to vq\n", in discard_port_data()
545 static bool port_has_data(struct port *port) in port_has_data() argument
551 spin_lock_irqsave(&port->inbuf_lock, flags); in port_has_data()
552 port->inbuf = get_inbuf(port); in port_has_data()
553 if (port->inbuf) in port_has_data()
556 spin_unlock_irqrestore(&port->inbuf_lock, flags); in port_has_data()
591 static ssize_t send_control_msg(struct port *port, unsigned int event, in send_control_msg() argument
595 if (port->portdev) in send_control_msg()
596 return __send_control_msg(port->portdev, port->id, event, value); in send_control_msg()
602 static void reclaim_consumed_buffers(struct port *port) in reclaim_consumed_buffers() argument
607 if (!port->portdev) { in reclaim_consumed_buffers()
611 while ((buf = virtqueue_get_buf(port->out_vq, &len))) { in reclaim_consumed_buffers()
613 port->outvq_full = false; in reclaim_consumed_buffers()
617 static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, in __send_to_port() argument
626 out_vq = port->out_vq; in __send_to_port()
628 spin_lock_irqsave(&port->outvq_lock, flags); in __send_to_port()
630 reclaim_consumed_buffers(port); in __send_to_port()
643 port->outvq_full = true; in __send_to_port()
661 spin_unlock_irqrestore(&port->outvq_lock, flags); in __send_to_port()
663 port->stats.bytes_sent += in_count; in __send_to_port()
675 static ssize_t fill_readbuf(struct port *port, char __user *out_buf, in fill_readbuf() argument
681 if (!out_count || !port_has_data(port)) in fill_readbuf()
684 buf = port->inbuf; in fill_readbuf()
705 spin_lock_irqsave(&port->inbuf_lock, flags); in fill_readbuf()
706 port->inbuf = NULL; in fill_readbuf()
708 if (add_inbuf(port->in_vq, buf) < 0) in fill_readbuf()
709 dev_warn(port->dev, "failed add_buf\n"); in fill_readbuf()
711 spin_unlock_irqrestore(&port->inbuf_lock, flags); in fill_readbuf()
718 static bool will_read_block(struct port *port) in will_read_block() argument
720 if (!port->guest_connected) { in will_read_block()
724 return !port_has_data(port) && port->host_connected; in will_read_block()
727 static bool will_write_block(struct port *port) in will_write_block() argument
731 if (!port->guest_connected) { in will_write_block()
735 if (!port->host_connected) in will_write_block()
738 spin_lock_irq(&port->outvq_lock); in will_write_block()
743 reclaim_consumed_buffers(port); in will_write_block()
744 ret = port->outvq_full; in will_write_block()
745 spin_unlock_irq(&port->outvq_lock); in will_write_block()
753 struct port *port; in port_fops_read() local
756 port = filp->private_data; in port_fops_read()
759 if (!port->guest_connected) in port_fops_read()
762 if (!port_has_data(port)) { in port_fops_read()
768 if (!port->host_connected) in port_fops_read()
773 ret = wait_event_freezable(port->waitqueue, in port_fops_read()
774 !will_read_block(port)); in port_fops_read()
779 if (!port->guest_connected) in port_fops_read()
791 if (!port_has_data(port) && !port->host_connected) in port_fops_read()
794 return fill_readbuf(port, ubuf, count, true); in port_fops_read()
797 static int wait_port_writable(struct port *port, bool nonblock) in wait_port_writable() argument
801 if (will_write_block(port)) { in wait_port_writable()
805 ret = wait_event_freezable(port->waitqueue, in wait_port_writable()
806 !will_write_block(port)); in wait_port_writable()
811 if (!port->guest_connected) in wait_port_writable()
820 struct port *port; in port_fops_write() local
830 port = filp->private_data; in port_fops_write()
834 ret = wait_port_writable(port, nonblock); in port_fops_write()
840 buf = alloc_buf(port->portdev->vdev, count, 0); in port_fops_write()
859 ret = __send_to_port(port, sg, 1, count, buf, nonblock); in port_fops_write()
925 struct port *port = filp->private_data; in port_fops_splice_write() local
942 if (is_rproc_serial(port->out_vq->vdev)) in port_fops_splice_write()
955 ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK); in port_fops_splice_write()
959 buf = alloc_buf(port->portdev->vdev, 0, pipe->nrbufs); in port_fops_splice_write()
973 ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true); in port_fops_splice_write()
986 struct port *port; in port_fops_poll() local
989 port = filp->private_data; in port_fops_poll()
990 poll_wait(filp, &port->waitqueue, wait); in port_fops_poll()
992 if (!port->guest_connected) { in port_fops_poll()
997 if (!will_read_block(port)) in port_fops_poll()
999 if (!will_write_block(port)) in port_fops_poll()
1001 if (!port->host_connected) in port_fops_poll()
1011 struct port *port; in port_fops_release() local
1013 port = filp->private_data; in port_fops_release()
1016 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); in port_fops_release()
1018 spin_lock_irq(&port->inbuf_lock); in port_fops_release()
1019 port->guest_connected = false; in port_fops_release()
1021 discard_port_data(port); in port_fops_release()
1023 spin_unlock_irq(&port->inbuf_lock); in port_fops_release()
1025 spin_lock_irq(&port->outvq_lock); in port_fops_release()
1026 reclaim_consumed_buffers(port); in port_fops_release()
1027 spin_unlock_irq(&port->outvq_lock); in port_fops_release()
1038 kref_put(&port->kref, remove_port); in port_fops_release()
1046 struct port *port; in port_fops_open() local
1050 port = find_port_by_devt(cdev->dev); in port_fops_open()
1051 if (!port) { in port_fops_open()
1055 filp->private_data = port; in port_fops_open()
1061 if (is_console_port(port)) { in port_fops_open()
1067 spin_lock_irq(&port->inbuf_lock); in port_fops_open()
1068 if (port->guest_connected) { in port_fops_open()
1069 spin_unlock_irq(&port->inbuf_lock); in port_fops_open()
1074 port->guest_connected = true; in port_fops_open()
1075 spin_unlock_irq(&port->inbuf_lock); in port_fops_open()
1077 spin_lock_irq(&port->outvq_lock); in port_fops_open()
1083 reclaim_consumed_buffers(port); in port_fops_open()
1084 spin_unlock_irq(&port->outvq_lock); in port_fops_open()
1093 kref_put(&port->kref, remove_port); in port_fops_open()
1099 struct port *port; in port_fops_fasync() local
1101 port = filp->private_data; in port_fops_fasync()
1102 return fasync_helper(fd, filp, mode, &port->async_queue); in port_fops_fasync()
1133 struct port *port; in put_chars() local
1141 port = find_port_by_vtermno(vtermno); in put_chars()
1142 if (!port) in put_chars()
1150 ret = __send_to_port(port, sg, 1, count, data, false); in put_chars()
1164 struct port *port; in get_chars() local
1170 port = find_port_by_vtermno(vtermno); in get_chars()
1171 if (!port) in get_chars()
1175 BUG_ON(!port->in_vq); in get_chars()
1177 return fill_readbuf(port, (__force char __user *)buf, count, false); in get_chars()
1180 static void resize_console(struct port *port) in resize_console() argument
1185 if (!port || !is_console_port(port)) in resize_console()
1188 vdev = port->portdev->vdev; in resize_console()
1193 hvc_resize(port->cons.hvc, port->cons.ws); in resize_console()
1199 struct port *port; in notifier_add_vio() local
1201 port = find_port_by_vtermno(hp->vtermno); in notifier_add_vio()
1202 if (!port) in notifier_add_vio()
1206 resize_console(port); in notifier_add_vio()
1240 static int init_port_console(struct port *port) in init_port_console() argument
1261 port->cons.vtermno = pdrvdata.next_vtermno; in init_port_console()
1263 port->cons.hvc = hvc_alloc(port->cons.vtermno, 0, &hv_ops, PAGE_SIZE); in init_port_console()
1264 if (IS_ERR(port->cons.hvc)) { in init_port_console()
1265 ret = PTR_ERR(port->cons.hvc); in init_port_console()
1266 dev_err(port->dev, in init_port_console()
1268 port->cons.hvc = NULL; in init_port_console()
1273 list_add_tail(&port->cons.list, &pdrvdata.consoles); in init_port_console()
1275 port->guest_connected = true; in init_port_console()
1285 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1); in init_port_console()
1293 struct port *port; in show_port_name() local
1295 port = dev_get_drvdata(dev); in show_port_name()
1297 return sprintf(buffer, "%s\n", port->name); in show_port_name()
1314 struct port *port = s->private; in debugfs_show() local
1316 seq_printf(s, "name: %s\n", port->name ? port->name : ""); in debugfs_show()
1317 seq_printf(s, "guest_connected: %d\n", port->guest_connected); in debugfs_show()
1318 seq_printf(s, "host_connected: %d\n", port->host_connected); in debugfs_show()
1319 seq_printf(s, "outvq_full: %d\n", port->outvq_full); in debugfs_show()
1320 seq_printf(s, "bytes_sent: %lu\n", port->stats.bytes_sent); in debugfs_show()
1321 seq_printf(s, "bytes_received: %lu\n", port->stats.bytes_received); in debugfs_show()
1322 seq_printf(s, "bytes_discarded: %lu\n", port->stats.bytes_discarded); in debugfs_show()
1324 is_console_port(port) ? "yes" : "no"); in debugfs_show()
1325 seq_printf(s, "console_vtermno: %u\n", port->cons.vtermno); in debugfs_show()
1343 static void set_console_size(struct port *port, u16 rows, u16 cols) in set_console_size() argument
1345 if (!port || !is_console_port(port)) in set_console_size()
1348 port->cons.ws.ws_row = rows; in set_console_size()
1349 port->cons.ws.ws_col = cols; in set_console_size()
1378 static void send_sigio_to_port(struct port *port) in send_sigio_to_port() argument
1380 if (port->async_queue && port->guest_connected) in send_sigio_to_port()
1381 kill_fasync(&port->async_queue, SIGIO, POLL_OUT); in send_sigio_to_port()
1387 struct port *port; in add_port() local
1391 port = kmalloc(sizeof(*port), GFP_KERNEL); in add_port()
1392 if (!port) { in add_port()
1396 kref_init(&port->kref); in add_port()
1398 port->portdev = portdev; in add_port()
1399 port->id = id; in add_port()
1401 port->name = NULL; in add_port()
1402 port->inbuf = NULL; in add_port()
1403 port->cons.hvc = NULL; in add_port()
1404 port->async_queue = NULL; in add_port()
1406 port->cons.ws.ws_row = port->cons.ws.ws_col = 0; in add_port()
1407 port->cons.vtermno = 0; in add_port()
1409 port->host_connected = port->guest_connected = false; in add_port()
1410 port->stats = (struct port_stats) { 0 }; in add_port()
1412 port->outvq_full = false; in add_port()
1414 port->in_vq = portdev->in_vqs[port->id]; in add_port()
1415 port->out_vq = portdev->out_vqs[port->id]; in add_port()
1417 port->cdev = cdev_alloc(); in add_port()
1418 if (!port->cdev) { in add_port()
1419 dev_err(&port->portdev->vdev->dev, "Error allocating cdev\n"); in add_port()
1423 port->cdev->ops = &port_fops; in add_port()
1426 err = cdev_add(port->cdev, devt, 1); in add_port()
1428 dev_err(&port->portdev->vdev->dev, in add_port()
1432 port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev, in add_port()
1433 devt, port, "vport%up%u", in add_port()
1434 port->portdev->vdev->index, id); in add_port()
1435 if (IS_ERR(port->dev)) { in add_port()
1436 err = PTR_ERR(port->dev); in add_port()
1437 dev_err(&port->portdev->vdev->dev, in add_port()
1443 spin_lock_init(&port->inbuf_lock); in add_port()
1444 spin_lock_init(&port->outvq_lock); in add_port()
1445 init_waitqueue_head(&port->waitqueue); in add_port()
1451 err = fill_queue(port->in_vq, &port->inbuf_lock); in add_port()
1453 dev_err(port->dev, "Error allocating inbufs\n"); in add_port()
1457 if (is_rproc_serial(port->portdev->vdev)) in add_port()
1463 port->host_connected = true; in add_port()
1464 else if (!use_multiport(port->portdev)) { in add_port()
1469 err = init_port_console(port); in add_port()
1475 list_add_tail(&port->list, &port->portdev->ports); in add_port()
1483 send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); in add_port()
1491 port->portdev->vdev->index, id); in add_port()
1492 port->debugfs_file = debugfs_create_file(debugfs_name, 0444, in add_port()
1494 port, in add_port()
1501 device_destroy(pdrvdata.class, port->dev->devt); in add_port()
1503 cdev_del(port->cdev); in add_port()
1505 kfree(port); in add_port()
1515 struct port *port; in remove_port() local
1517 port = container_of(kref, struct port, kref); in remove_port()
1519 kfree(port); in remove_port()
1522 static void remove_port_data(struct port *port) in remove_port_data() argument
1524 spin_lock_irq(&port->inbuf_lock); in remove_port_data()
1526 discard_port_data(port); in remove_port_data()
1527 spin_unlock_irq(&port->inbuf_lock); in remove_port_data()
1529 spin_lock_irq(&port->outvq_lock); in remove_port_data()
1530 reclaim_consumed_buffers(port); in remove_port_data()
1531 spin_unlock_irq(&port->outvq_lock); in remove_port_data()
1539 static void unplug_port(struct port *port) in unplug_port() argument
1541 spin_lock_irq(&port->portdev->ports_lock); in unplug_port()
1542 list_del(&port->list); in unplug_port()
1543 spin_unlock_irq(&port->portdev->ports_lock); in unplug_port()
1545 spin_lock_irq(&port->inbuf_lock); in unplug_port()
1546 if (port->guest_connected) { in unplug_port()
1548 send_sigio_to_port(port); in unplug_port()
1551 port->guest_connected = false; in unplug_port()
1552 port->host_connected = false; in unplug_port()
1554 wake_up_interruptible(&port->waitqueue); in unplug_port()
1556 spin_unlock_irq(&port->inbuf_lock); in unplug_port()
1558 if (is_console_port(port)) { in unplug_port()
1560 list_del(&port->cons.list); in unplug_port()
1562 hvc_remove(port->cons.hvc); in unplug_port()
1565 remove_port_data(port); in unplug_port()
1572 port->portdev = NULL; in unplug_port()
1574 sysfs_remove_group(&port->dev->kobj, &port_attribute_group); in unplug_port()
1575 device_destroy(pdrvdata.class, port->dev->devt); in unplug_port()
1576 cdev_del(port->cdev); in unplug_port()
1578 debugfs_remove(port->debugfs_file); in unplug_port()
1579 kfree(port->name); in unplug_port()
1586 kref_put(&port->kref, remove_port); in unplug_port()
1595 struct port *port; in handle_control_message() local
1601 port = find_port_by_id(portdev, virtio32_to_cpu(vdev, cpkt->id)); in handle_control_message()
1602 if (!port && in handle_control_message()
1612 if (port) { in handle_control_message()
1614 "Port %u already added\n", port->id); in handle_control_message()
1615 send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); in handle_control_message()
1629 unplug_port(port); in handle_control_message()
1634 if (is_console_port(port)) in handle_control_message()
1637 init_port_console(port); in handle_control_message()
1650 if (!is_console_port(port)) in handle_control_message()
1655 set_console_size(port, size.rows, size.cols); in handle_control_message()
1657 port->cons.hvc->irq_requested = 1; in handle_control_message()
1658 resize_console(port); in handle_control_message()
1662 port->host_connected = virtio16_to_cpu(vdev, cpkt->value); in handle_control_message()
1663 wake_up_interruptible(&port->waitqueue); in handle_control_message()
1669 spin_lock_irq(&port->outvq_lock); in handle_control_message()
1670 reclaim_consumed_buffers(port); in handle_control_message()
1671 spin_unlock_irq(&port->outvq_lock); in handle_control_message()
1677 spin_lock_irq(&port->inbuf_lock); in handle_control_message()
1678 send_sigio_to_port(port); in handle_control_message()
1679 spin_unlock_irq(&port->inbuf_lock); in handle_control_message()
1686 if (port->name) in handle_control_message()
1695 port->name = kmalloc(name_size, GFP_KERNEL); in handle_control_message()
1696 if (!port->name) { in handle_control_message()
1697 dev_err(port->dev, in handle_control_message()
1701 strncpy(port->name, buf->buf + buf->offset + sizeof(*cpkt), in handle_control_message()
1703 port->name[name_size - 1] = 0; in handle_control_message()
1709 err = sysfs_create_group(&port->dev->kobj, in handle_control_message()
1712 dev_err(port->dev, in handle_control_message()
1721 kobject_uevent(&port->dev->kobj, KOBJ_CHANGE); in handle_control_message()
1767 struct port *port; in out_intr() local
1769 port = find_port_by_vq(vq->vdev->priv, vq); in out_intr()
1770 if (!port) { in out_intr()
1775 wake_up_interruptible(&port->waitqueue); in out_intr()
1780 struct port *port; in in_intr() local
1783 port = find_port_by_vq(vq->vdev->priv, vq); in in_intr()
1784 if (!port) { in in_intr()
1789 spin_lock_irqsave(&port->inbuf_lock, flags); in in_intr()
1790 port->inbuf = get_inbuf(port); in in_intr()
1809 if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) in in_intr()
1810 discard_port_data(port); in in_intr()
1813 send_sigio_to_port(port); in in_intr()
1815 spin_unlock_irqrestore(&port->inbuf_lock, flags); in in_intr()
1817 wake_up_interruptible(&port->waitqueue); in in_intr()
1819 if (is_console_port(port) && hvc_poll(port->cons.hvc)) in in_intr()
1848 struct port *port; in config_work_handler() local
1855 port = find_port_by_id(portdev, 0); in config_work_handler()
1856 set_console_size(port, rows, cols); in config_work_handler()
1865 resize_console(port); in config_work_handler()
1980 struct port *port, *port2; in virtcons_remove() local
2003 list_for_each_entry_safe(port, port2, &portdev->ports, list) in virtcons_remove()
2004 unplug_port(port); in virtcons_remove()
2174 struct port *port; in virtcons_freeze() local
2191 list_for_each_entry(port, &portdev->ports, list) { in virtcons_freeze()
2192 virtqueue_disable_cb(port->in_vq); in virtcons_freeze()
2193 virtqueue_disable_cb(port->out_vq); in virtcons_freeze()
2198 port->host_connected = false; in virtcons_freeze()
2199 remove_port_data(port); in virtcons_freeze()
2209 struct port *port; in virtcons_restore() local
2223 list_for_each_entry(port, &portdev->ports, list) { in virtcons_restore()
2224 port->in_vq = portdev->in_vqs[port->id]; in virtcons_restore()
2225 port->out_vq = portdev->out_vqs[port->id]; in virtcons_restore()
2227 fill_queue(port->in_vq, &port->inbuf_lock); in virtcons_restore()
2230 send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); in virtcons_restore()
2236 if (port->guest_connected) in virtcons_restore()
2237 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1); in virtcons_restore()