Lines Matching +full:port +full:-
1 /*-
93 #define VTCON_PORT_LOCK(_port) mtx_lock(&(_port)->vtcport_mtx)
94 #define VTCON_PORT_UNLOCK(_port) mtx_unlock(&(_port)->vtcport_mtx)
116 * indexed by the port ID.
126 #define VTCON_LOCK(_sc) mtx_lock(&(_sc)->vtcon_mtx)
127 #define VTCON_UNLOCK(_sc) mtx_unlock(&(_sc)->vtcon_mtx)
129 mtx_assert(&(_sc)->vtcon_mtx, MA_OWNED)
131 mtx_assert(&(_sc)->vtcon_mtx, MA_NOTOWNED)
133 #define VTCON_CTRL_TX_LOCK(_sc) mtx_lock(&(_sc)->vtcon_ctrl_tx_mtx)
134 #define VTCON_CTRL_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->vtcon_ctrl_tx_mtx)
137 KASSERT((_id) >= 0 && (_id) < (_sc)->vtcon_max_ports, \
138 ("%s: port ID %d out of range", __func__, _id))
226 #define vtcon_modern(_sc) (((_sc)->vtcon_features & VIRTIO_F_VERSION_1) != 0)
324 sc->vtcon_dev = dev; in vtcon_attach()
327 mtx_init(&sc->vtcon_mtx, "vtconmtx", NULL, MTX_DEF); in vtcon_attach()
328 mtx_init(&sc->vtcon_ctrl_tx_mtx, "vtconctrlmtx", NULL, MTX_DEF); in vtcon_attach()
341 device_printf(dev, "cannot allocate softc port structures\n"); in vtcon_attach()
351 if (sc->vtcon_flags & VTCON_FLAG_MULTIPORT) { in vtcon_attach()
352 TASK_INIT(&sc->vtcon_ctrl_task, 0, vtcon_ctrl_task_cb, sc); in vtcon_attach()
360 if (sc->vtcon_flags & VTCON_FLAG_SIZE) in vtcon_attach()
390 sc->vtcon_flags |= VTCON_FLAG_DETACHED; in vtcon_detach()
395 if (sc->vtcon_flags & VTCON_FLAG_MULTIPORT) { in vtcon_detach()
396 taskqueue_drain(taskqueue_thread, &sc->vtcon_ctrl_task); in vtcon_detach()
401 mtx_destroy(&sc->vtcon_mtx); in vtcon_detach()
402 mtx_destroy(&sc->vtcon_ctrl_tx_mtx); in vtcon_detach()
418 if ((sc->vtcon_flags & VTCON_FLAG_MULTIPORT) == 0) { in vtcon_config_change()
419 if (sc->vtcon_flags & VTCON_FLAG_SIZE) in vtcon_config_change()
432 dev = sc->vtcon_dev; in vtcon_negotiate_features()
435 sc->vtcon_features = virtio_negotiate_features(dev, features); in vtcon_negotiate_features()
445 dev = sc->vtcon_dev; in vtcon_setup_features()
452 sc->vtcon_flags |= VTCON_FLAG_SIZE; in vtcon_setup_features()
454 sc->vtcon_flags |= VTCON_FLAG_MULTIPORT; in vtcon_setup_features()
463 &(_cfg)->_field, sizeof((_cfg)->_field)); \
471 dev = sc->vtcon_dev; in vtcon_read_config()
488 max = sc->vtcon_max_ports; in vtcon_alloc_scports()
490 sc->vtcon_ports = malloc(sizeof(struct vtcon_softc_port) * max, in vtcon_alloc_scports()
492 if (sc->vtcon_ports == NULL) in vtcon_alloc_scports()
496 scport = &sc->vtcon_ports[i]; in vtcon_alloc_scports()
497 scport->vcsp_sc = sc; in vtcon_alloc_scports()
511 dev = sc->vtcon_dev; in vtcon_alloc_virtqueues()
513 nvqs = sc->vtcon_max_ports * 2; in vtcon_alloc_virtqueues()
514 if (sc->vtcon_flags & VTCON_FLAG_MULTIPORT) in vtcon_alloc_virtqueues()
523 /* The control virtqueues are after the first port. */ in vtcon_alloc_virtqueues()
525 vtcon_ctrl_event_intr, sc, &sc->vtcon_ctrl_rxvq, in vtcon_alloc_virtqueues()
526 "%s-control rx", device_get_nameunit(dev)); in vtcon_alloc_virtqueues()
528 NULL, sc, &sc->vtcon_ctrl_txvq, in vtcon_alloc_virtqueues()
529 "%s-control tx", device_get_nameunit(dev)); in vtcon_alloc_virtqueues()
533 scport = &sc->vtcon_ports[portidx]; in vtcon_alloc_virtqueues()
536 scport, &scport->vcsp_invq, "%s-port%d in", in vtcon_alloc_virtqueues()
539 NULL, &scport->vcsp_outvq, "%s-port%d out", in vtcon_alloc_virtqueues()
556 if (sc->vtcon_flags & VTCON_FLAG_MULTIPORT) { in vtcon_determine_max_ports()
557 sc->vtcon_max_ports = in vtcon_determine_max_ports()
558 min(concfg->max_nr_ports, VTCON_MAX_PORTS); in vtcon_determine_max_ports()
559 if (sc->vtcon_max_ports == 0) in vtcon_determine_max_ports()
560 sc->vtcon_max_ports = 1; in vtcon_determine_max_ports()
562 sc->vtcon_max_ports = 1; in vtcon_determine_max_ports()
569 struct vtcon_port *port; in vtcon_destroy_ports() local
573 if (sc->vtcon_ports == NULL) in vtcon_destroy_ports()
577 for (i = 0; i < sc->vtcon_max_ports; i++) { in vtcon_destroy_ports()
578 scport = &sc->vtcon_ports[i]; in vtcon_destroy_ports()
580 port = scport->vcsp_port; in vtcon_destroy_ports()
581 if (port != NULL) { in vtcon_destroy_ports()
582 scport->vcsp_port = NULL; in vtcon_destroy_ports()
583 VTCON_PORT_LOCK(port); in vtcon_destroy_ports()
585 vtcon_port_teardown(port); in vtcon_destroy_ports()
589 vq = scport->vcsp_invq; in vtcon_destroy_ports()
595 free(sc->vtcon_ports, M_DEVBUF); in vtcon_destroy_ports()
596 sc->vtcon_ports = NULL; in vtcon_destroy_ports()
604 virtio_stop(sc->vtcon_dev); in vtcon_stop()
616 vq = sc->vtcon_ctrl_rxvq; in vtcon_ctrl_event_enqueue()
662 vq = sc->vtcon_ctrl_rxvq; in vtcon_ctrl_event_populate()
686 vq = sc->vtcon_ctrl_rxvq; in vtcon_ctrl_event_drain()
721 dev = sc->vtcon_dev; in vtcon_ctrl_port_add_event()
724 if (sc->vtcon_ports[id].vcsp_port != NULL) { in vtcon_ctrl_port_add_event()
725 device_printf(dev, "%s: adding port %d, but already exists\n", in vtcon_ctrl_port_add_event()
732 device_printf(dev, "%s: cannot create port %d: %d\n", in vtcon_ctrl_port_add_event()
744 struct vtcon_port *port; in vtcon_ctrl_port_remove_event() local
746 dev = sc->vtcon_dev; in vtcon_ctrl_port_remove_event()
747 scport = &sc->vtcon_ports[id]; in vtcon_ctrl_port_remove_event()
750 port = scport->vcsp_port; in vtcon_ctrl_port_remove_event()
751 if (port == NULL) { in vtcon_ctrl_port_remove_event()
753 device_printf(dev, "%s: remove port %d, but does not exist\n", in vtcon_ctrl_port_remove_event()
758 scport->vcsp_port = NULL; in vtcon_ctrl_port_remove_event()
759 VTCON_PORT_LOCK(port); in vtcon_ctrl_port_remove_event()
761 vtcon_port_teardown(port); in vtcon_ctrl_port_remove_event()
769 struct vtcon_port *port; in vtcon_ctrl_port_console_event() local
771 dev = sc->vtcon_dev; in vtcon_ctrl_port_console_event()
772 scport = &sc->vtcon_ports[id]; in vtcon_ctrl_port_console_event()
775 port = scport->vcsp_port; in vtcon_ctrl_port_console_event()
776 if (port == NULL) { in vtcon_ctrl_port_console_event()
778 device_printf(dev, "%s: console port %d, but does not exist\n", in vtcon_ctrl_port_console_event()
783 VTCON_PORT_LOCK(port); in vtcon_ctrl_port_console_event()
785 port->vtcport_flags |= VTCON_PORT_FLAG_CONSOLE; in vtcon_ctrl_port_console_event()
786 vtcon_port_submit_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1); in vtcon_ctrl_port_console_event()
787 VTCON_PORT_UNLOCK(port); in vtcon_ctrl_port_console_event()
795 struct vtcon_port *port; in vtcon_ctrl_port_open_event() local
797 dev = sc->vtcon_dev; in vtcon_ctrl_port_open_event()
798 scport = &sc->vtcon_ports[id]; in vtcon_ctrl_port_open_event()
801 port = scport->vcsp_port; in vtcon_ctrl_port_open_event()
802 if (port == NULL) { in vtcon_ctrl_port_open_event()
804 device_printf(dev, "%s: open port %d, but does not exist\n", in vtcon_ctrl_port_open_event()
809 VTCON_PORT_LOCK(port); in vtcon_ctrl_port_open_event()
811 vtcon_port_enable_intr(port); in vtcon_ctrl_port_open_event()
812 VTCON_PORT_UNLOCK(port); in vtcon_ctrl_port_open_event()
821 struct vtcon_port *port; in vtcon_ctrl_port_name_event() local
823 dev = sc->vtcon_dev; in vtcon_ctrl_port_name_event()
824 scport = &sc->vtcon_ports[id]; in vtcon_ctrl_port_name_event()
832 if (name[len - 1] == '\0') { in vtcon_ctrl_port_name_event()
833 len--; in vtcon_ctrl_port_name_event()
839 port = scport->vcsp_port; in vtcon_ctrl_port_name_event()
840 if (port == NULL) { in vtcon_ctrl_port_name_event()
842 device_printf(dev, "%s: name port %d, but does not exist\n", in vtcon_ctrl_port_name_event()
847 VTCON_PORT_LOCK(port); in vtcon_ctrl_port_name_event()
849 vtcon_port_dev_alias(port, name, len); in vtcon_ctrl_port_name_event()
850 VTCON_PORT_UNLOCK(port); in vtcon_ctrl_port_name_event()
861 dev = sc->vtcon_dev; in vtcon_ctrl_process_event()
862 id = vtcon_htog32(sc, control->id); in vtcon_ctrl_process_event()
863 event = vtcon_htog16(sc, control->event); in vtcon_ctrl_process_event()
865 if (id >= sc->vtcon_max_ports) { in vtcon_ctrl_process_event()
866 device_printf(dev, "%s: event %d invalid port ID %d\n", in vtcon_ctrl_process_event()
909 vq = sc->vtcon_ctrl_rxvq; in vtcon_ctrl_task_cb()
913 while ((detached = (sc->vtcon_flags & VTCON_FLAG_DETACHED)) == 0) { in vtcon_ctrl_task_cb()
920 data_len = len - sizeof(struct virtio_console_control); in vtcon_ctrl_task_cb()
936 &sc->vtcon_ctrl_task); in vtcon_ctrl_task_cb()
953 taskqueue_enqueue(taskqueue_thread, &sc->vtcon_ctrl_task); in vtcon_ctrl_event_intr()
965 vq = sc->vtcon_ctrl_txvq; in vtcon_ctrl_poll()
976 * port lock held. Acquiring the softc would violate our lock in vtcon_ctrl_poll()
996 if ((sc->vtcon_flags & VTCON_FLAG_MULTIPORT) == 0) in vtcon_ctrl_send_control()
1007 vtcon_port_enqueue_buf(struct vtcon_port *port, void *buf, size_t len) in vtcon_port_enqueue_buf() argument
1014 vq = port->vtcport_invq; in vtcon_port_enqueue_buf()
1027 vtcon_port_create_buf(struct vtcon_port *port) in vtcon_port_create_buf() argument
1036 error = vtcon_port_enqueue_buf(port, buf, VTCON_BULK_BUFSZ); in vtcon_port_create_buf()
1044 vtcon_port_requeue_buf(struct vtcon_port *port, void *buf) in vtcon_port_requeue_buf() argument
1048 error = vtcon_port_enqueue_buf(port, buf, VTCON_BULK_BUFSZ); in vtcon_port_requeue_buf()
1054 vtcon_port_populate(struct vtcon_port *port) in vtcon_port_populate() argument
1059 vq = port->vtcport_invq; in vtcon_port_populate()
1063 error = vtcon_port_create_buf(port); in vtcon_port_populate()
1077 vtcon_port_destroy(struct vtcon_port *port) in vtcon_port_destroy() argument
1080 port->vtcport_sc = NULL; in vtcon_port_destroy()
1081 port->vtcport_scport = NULL; in vtcon_port_destroy()
1082 port->vtcport_invq = NULL; in vtcon_port_destroy()
1083 port->vtcport_outvq = NULL; in vtcon_port_destroy()
1084 port->vtcport_id = -1; in vtcon_port_destroy()
1085 mtx_destroy(&port->vtcport_mtx); in vtcon_port_destroy()
1086 free(port, M_DEVBUF); in vtcon_port_destroy()
1090 vtcon_port_init_vqs(struct vtcon_port *port) in vtcon_port_init_vqs() argument
1095 scport = port->vtcport_scport; in vtcon_port_init_vqs()
1097 port->vtcport_invq = scport->vcsp_invq; in vtcon_port_init_vqs()
1098 port->vtcport_outvq = scport->vcsp_outvq; in vtcon_port_init_vqs()
1102 * prior port. We have not yet notified the host that the port is in vtcon_port_init_vqs()
1105 vtcon_port_drain(port); in vtcon_port_init_vqs()
1107 KASSERT(virtqueue_empty(port->vtcport_invq), in vtcon_port_init_vqs()
1109 KASSERT(virtqueue_empty(port->vtcport_outvq), in vtcon_port_init_vqs()
1112 error = vtcon_port_populate(port); in vtcon_port_init_vqs()
1124 struct vtcon_port *port; in vtcon_port_create() local
1127 dev = sc->vtcon_dev; in vtcon_port_create()
1128 scport = &sc->vtcon_ports[id]; in vtcon_port_create()
1131 MPASS(scport->vcsp_port == NULL); in vtcon_port_create()
1133 port = malloc(sizeof(struct vtcon_port), M_DEVBUF, M_NOWAIT | M_ZERO); in vtcon_port_create()
1134 if (port == NULL) in vtcon_port_create()
1137 port->vtcport_sc = sc; in vtcon_port_create()
1138 port->vtcport_scport = scport; in vtcon_port_create()
1139 port->vtcport_id = id; in vtcon_port_create()
1140 mtx_init(&port->vtcport_mtx, "vtcpmtx", NULL, MTX_DEF); in vtcon_port_create()
1141 port->vtcport_tty = tty_alloc_mutex(&vtcon_tty_class, port, in vtcon_port_create()
1142 &port->vtcport_mtx); in vtcon_port_create()
1144 error = vtcon_port_init_vqs(port); in vtcon_port_create()
1146 VTCON_PORT_LOCK(port); in vtcon_port_create()
1147 vtcon_port_teardown(port); in vtcon_port_create()
1152 VTCON_PORT_LOCK(port); in vtcon_port_create()
1153 scport->vcsp_port = port; in vtcon_port_create()
1154 vtcon_port_enable_intr(port); in vtcon_port_create()
1155 vtcon_port_submit_event(port, VIRTIO_CONSOLE_PORT_READY, 1); in vtcon_port_create()
1156 VTCON_PORT_UNLOCK(port); in vtcon_port_create()
1159 tty_makedev(port->vtcport_tty, NULL, "%s%r.%r", VTCON_TTY_PREFIX, in vtcon_port_create()
1166 vtcon_port_dev_alias(struct vtcon_port *port, const char *name, size_t len) in vtcon_port_dev_alias() argument
1173 sc = port->vtcport_sc; in vtcon_port_dev_alias()
1174 tp = port->vtcport_tty; in vtcon_port_dev_alias()
1176 if (port->vtcport_flags & VTCON_PORT_FLAG_ALIAS) in vtcon_port_dev_alias()
1179 /* Port name is UTF-8, but we can only handle ASCII. */ in vtcon_port_dev_alias()
1186 * Port name may not conform to the devfs requirements so we cannot use in vtcon_port_dev_alias()
1190 tp->t_dev, "%s/%*s", VTCON_TTY_ALIAS_PREFIX, (int)len, name); in vtcon_port_dev_alias()
1192 device_printf(sc->vtcon_dev, in vtcon_port_dev_alias()
1196 port->vtcport_flags |= VTCON_PORT_FLAG_ALIAS; in vtcon_port_dev_alias()
1212 vtcon_port_drain(struct vtcon_port *port) in vtcon_port_drain() argument
1215 vtcon_port_drain_bufs(port->vtcport_invq); in vtcon_port_drain()
1219 vtcon_port_teardown(struct vtcon_port *port) in vtcon_port_teardown() argument
1223 tp = port->vtcport_tty; in vtcon_port_teardown()
1225 port->vtcport_flags |= VTCON_PORT_FLAG_GONE; in vtcon_port_teardown()
1231 vtcon_port_destroy(port); in vtcon_port_teardown()
1235 vtcon_port_change_size(struct vtcon_port *port, uint16_t cols, uint16_t rows) in vtcon_port_change_size() argument
1240 tp = port->vtcport_tty; in vtcon_port_change_size()
1255 struct vtcon_port *port; in vtcon_port_update_console_size() local
1262 * For now, assume the first (only) port is the console. Note in vtcon_port_update_console_size()
1265 scport = &sc->vtcon_ports[0]; in vtcon_port_update_console_size()
1268 port = scport->vcsp_port; in vtcon_port_update_console_size()
1270 if (port != NULL) { in vtcon_port_update_console_size()
1271 VTCON_PORT_LOCK(port); in vtcon_port_update_console_size()
1273 vtcon_port_change_size(port, cols, rows); in vtcon_port_update_console_size()
1274 VTCON_PORT_UNLOCK(port); in vtcon_port_update_console_size()
1280 vtcon_port_enable_intr(struct vtcon_port *port) in vtcon_port_enable_intr() argument
1287 virtqueue_enable_intr(port->vtcport_invq); in vtcon_port_enable_intr()
1291 vtcon_port_disable_intr(struct vtcon_port *port) in vtcon_port_disable_intr() argument
1294 if (port->vtcport_invq != NULL) in vtcon_port_disable_intr()
1295 virtqueue_disable_intr(port->vtcport_invq); in vtcon_port_disable_intr()
1296 if (port->vtcport_outvq != NULL) in vtcon_port_disable_intr()
1297 virtqueue_disable_intr(port->vtcport_outvq); in vtcon_port_disable_intr()
1301 vtcon_port_in(struct vtcon_port *port) in vtcon_port_in() argument
1309 tp = port->vtcport_tty; in vtcon_port_in()
1310 vq = port->vtcport_invq; in vtcon_port_in()
1318 if (port->vtcport_flags & VTCON_PORT_FLAG_CONSOLE) in vtcon_port_in()
1320 &port->vtcport_alt_break_state); in vtcon_port_in()
1324 vtcon_port_requeue_buf(port, buf); in vtcon_port_in()
1341 struct vtcon_port *port; in vtcon_port_intr() local
1344 sc = scport->vcsp_sc; in vtcon_port_intr()
1347 port = scport->vcsp_port; in vtcon_port_intr()
1348 if (port == NULL) { in vtcon_port_intr()
1352 VTCON_PORT_LOCK(port); in vtcon_port_intr()
1354 if ((port->vtcport_flags & VTCON_PORT_FLAG_GONE) == 0) in vtcon_port_intr()
1355 vtcon_port_in(port); in vtcon_port_intr()
1356 VTCON_PORT_UNLOCK(port); in vtcon_port_intr()
1360 vtcon_port_out(struct vtcon_port *port, void *buf, int bufsize) in vtcon_port_out() argument
1367 vq = port->vtcport_outvq; in vtcon_port_out()
1369 ("%s: port %p out virtqueue not empty", __func__, port)); in vtcon_port_out()
1384 vtcon_port_submit_event(struct vtcon_port *port, uint16_t event, in vtcon_port_submit_event() argument
1389 sc = port->vtcport_sc; in vtcon_port_submit_event()
1391 vtcon_ctrl_send_control(sc, port->vtcport_id, event, value); in vtcon_port_submit_event()
1397 struct vtcon_port *port; in vtcon_tty_open() local
1399 port = tty_softc(tp); in vtcon_tty_open()
1401 if (port->vtcport_flags & VTCON_PORT_FLAG_GONE) in vtcon_tty_open()
1404 vtcon_port_submit_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1); in vtcon_tty_open()
1412 struct vtcon_port *port; in vtcon_tty_close() local
1414 port = tty_softc(tp); in vtcon_tty_close()
1416 if (port->vtcport_flags & VTCON_PORT_FLAG_GONE) in vtcon_tty_close()
1419 vtcon_port_submit_event(port, VIRTIO_CONSOLE_PORT_OPEN, 0); in vtcon_tty_close()
1425 struct vtcon_port *port; in vtcon_tty_outwakeup() local
1429 port = tty_softc(tp); in vtcon_tty_outwakeup()
1431 if (port->vtcport_flags & VTCON_PORT_FLAG_GONE) in vtcon_tty_outwakeup()
1435 vtcon_port_out(port, buf, len); in vtcon_tty_outwakeup()
1441 struct vtcon_port *port; in vtcon_tty_free() local
1443 port = xport; in vtcon_tty_free()
1445 vtcon_port_destroy(port); in vtcon_tty_free()
1454 KASSERT(sc->vtcon_flags & VTCON_FLAG_SIZE, in vtcon_get_console_size()
1467 struct vtcon_port *port; in vtcon_enable_interrupts() local
1472 if (sc->vtcon_flags & VTCON_FLAG_MULTIPORT) in vtcon_enable_interrupts()
1473 virtqueue_enable_intr(sc->vtcon_ctrl_rxvq); in vtcon_enable_interrupts()
1475 for (i = 0; i < sc->vtcon_max_ports; i++) { in vtcon_enable_interrupts()
1476 scport = &sc->vtcon_ports[i]; in vtcon_enable_interrupts()
1478 port = scport->vcsp_port; in vtcon_enable_interrupts()
1479 if (port == NULL) in vtcon_enable_interrupts()
1482 VTCON_PORT_LOCK(port); in vtcon_enable_interrupts()
1483 vtcon_port_enable_intr(port); in vtcon_enable_interrupts()
1484 VTCON_PORT_UNLOCK(port); in vtcon_enable_interrupts()
1494 struct vtcon_port *port; in vtcon_disable_interrupts() local
1499 if (sc->vtcon_flags & VTCON_FLAG_MULTIPORT) in vtcon_disable_interrupts()
1500 virtqueue_disable_intr(sc->vtcon_ctrl_rxvq); in vtcon_disable_interrupts()
1502 for (i = 0; i < sc->vtcon_max_ports; i++) { in vtcon_disable_interrupts()
1503 scport = &sc->vtcon_ports[i]; in vtcon_disable_interrupts()
1505 port = scport->vcsp_port; in vtcon_disable_interrupts()
1506 if (port == NULL) in vtcon_disable_interrupts()
1509 VTCON_PORT_LOCK(port); in vtcon_disable_interrupts()
1510 vtcon_port_disable_intr(port); in vtcon_disable_interrupts()
1511 VTCON_PORT_UNLOCK(port); in vtcon_disable_interrupts()