Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/virtio/console/virtio_console.c
| Show First 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | |||||
| static int vtcon_ctrl_event_populate(struct vtcon_softc *); | static int vtcon_ctrl_event_populate(struct vtcon_softc *); | ||||
| static void vtcon_ctrl_event_drain(struct vtcon_softc *); | static void vtcon_ctrl_event_drain(struct vtcon_softc *); | ||||
| static int vtcon_ctrl_init(struct vtcon_softc *); | static int vtcon_ctrl_init(struct vtcon_softc *); | ||||
| static void vtcon_ctrl_deinit(struct vtcon_softc *); | static void vtcon_ctrl_deinit(struct vtcon_softc *); | ||||
| static void vtcon_ctrl_port_add_event(struct vtcon_softc *, int); | static void vtcon_ctrl_port_add_event(struct vtcon_softc *, int); | ||||
| static void vtcon_ctrl_port_remove_event(struct vtcon_softc *, int); | static void vtcon_ctrl_port_remove_event(struct vtcon_softc *, int); | ||||
| static void vtcon_ctrl_port_console_event(struct vtcon_softc *, int); | static void vtcon_ctrl_port_console_event(struct vtcon_softc *, int); | ||||
| static void vtcon_ctrl_port_open_event(struct vtcon_softc *, int); | static void vtcon_ctrl_port_open_event(struct vtcon_softc *, int); | ||||
| static void vtcon_ctrl_port_name_event(struct vtcon_softc *, int, | |||||
| const char *, size_t); | |||||
| static void vtcon_ctrl_process_event(struct vtcon_softc *, | static void vtcon_ctrl_process_event(struct vtcon_softc *, | ||||
| struct virtio_console_control *); | struct virtio_console_control *, void *, size_t); | ||||
| static void vtcon_ctrl_task_cb(void *, int); | static void vtcon_ctrl_task_cb(void *, int); | ||||
| static void vtcon_ctrl_event_intr(void *); | static void vtcon_ctrl_event_intr(void *); | ||||
| static void vtcon_ctrl_poll(struct vtcon_softc *, | static void vtcon_ctrl_poll(struct vtcon_softc *, | ||||
| struct virtio_console_control *control); | struct virtio_console_control *control); | ||||
| static void vtcon_ctrl_send_control(struct vtcon_softc *, uint32_t, | static void vtcon_ctrl_send_control(struct vtcon_softc *, uint32_t, | ||||
| uint16_t, uint16_t); | uint16_t, uint16_t); | ||||
| static int vtcon_port_enqueue_buf(struct vtcon_port *, void *, size_t); | static int vtcon_port_enqueue_buf(struct vtcon_port *, void *, size_t); | ||||
| ▲ Show 20 Lines • Show All 417 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static int | static int | ||||
| vtcon_ctrl_event_create(struct vtcon_softc *sc) | vtcon_ctrl_event_create(struct vtcon_softc *sc) | ||||
| { | { | ||||
| struct virtio_console_control *control; | struct virtio_console_control *control; | ||||
| int error; | int error; | ||||
| control = malloc(sizeof(struct virtio_console_control), M_DEVBUF, | control = malloc( | ||||
| M_ZERO | M_NOWAIT); | sizeof(struct virtio_console_control) + VTCON_BULK_BUFSZ, | ||||
| M_DEVBUF, M_ZERO | M_NOWAIT); | |||||
| if (control == NULL) | if (control == NULL) | ||||
| return (ENOMEM); | return (ENOMEM); | ||||
| error = vtcon_ctrl_event_enqueue(sc, control); | error = vtcon_ctrl_event_enqueue(sc, control); | ||||
| if (error) | if (error) | ||||
| free(control, M_DEVBUF); | free(control, M_DEVBUF); | ||||
| return (error); | return (error); | ||||
| ▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | vtcon_ctrl_port_open_event(struct vtcon_softc *sc, int id) | ||||
| VTCON_PORT_LOCK(port); | VTCON_PORT_LOCK(port); | ||||
| VTCON_UNLOCK(sc); | VTCON_UNLOCK(sc); | ||||
| vtcon_port_enable_intr(port); | vtcon_port_enable_intr(port); | ||||
| VTCON_PORT_UNLOCK(port); | VTCON_PORT_UNLOCK(port); | ||||
| } | } | ||||
| static void | static void | ||||
| vtcon_ctrl_port_name_event(struct vtcon_softc *sc, int id, const char *name, | |||||
| size_t len) | |||||
| { | |||||
| device_t dev; | |||||
| struct vtcon_softc_port *scport; | |||||
| struct vtcon_port *port; | |||||
| dev = sc->vtcon_dev; | |||||
| scport = &sc->vtcon_ports[id]; | |||||
| port = scport->vcsp_port; | |||||
| if (port == NULL) { | |||||
| device_printf(dev, "%s: name port %d, but does not exist\n", | |||||
| __func__, id); | |||||
| return; | |||||
| } | |||||
| tty_makealias(port->vtcport_tty, "vtcon/%*s", (int)len, name); | |||||
| } | |||||
| static void | |||||
| vtcon_ctrl_process_event(struct vtcon_softc *sc, | vtcon_ctrl_process_event(struct vtcon_softc *sc, | ||||
| struct virtio_console_control *control) | struct virtio_console_control *control, void *payload, size_t plen) | ||||
| { | { | ||||
| device_t dev; | device_t dev; | ||||
| int id; | int id; | ||||
| dev = sc->vtcon_dev; | dev = sc->vtcon_dev; | ||||
| id = control->id; | id = control->id; | ||||
| if (id < 0 || id >= sc->vtcon_max_ports) { | if (id < 0 || id >= sc->vtcon_max_ports) { | ||||
| Show All 17 Lines | vtcon_ctrl_process_event(struct vtcon_softc *sc, | ||||
| case VIRTIO_CONSOLE_RESIZE: | case VIRTIO_CONSOLE_RESIZE: | ||||
| break; | break; | ||||
| case VIRTIO_CONSOLE_PORT_OPEN: | case VIRTIO_CONSOLE_PORT_OPEN: | ||||
| vtcon_ctrl_port_open_event(sc, id); | vtcon_ctrl_port_open_event(sc, id); | ||||
| break; | break; | ||||
| case VIRTIO_CONSOLE_PORT_NAME: | case VIRTIO_CONSOLE_PORT_NAME: | ||||
| if (payload != NULL && plen > 0) | |||||
| vtcon_ctrl_port_name_event(sc, id, | |||||
| (const char *)payload, plen); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| static void | static void | ||||
| vtcon_ctrl_task_cb(void *xsc, int pending) | vtcon_ctrl_task_cb(void *xsc, int pending) | ||||
| { | { | ||||
| struct vtcon_softc *sc; | struct vtcon_softc *sc; | ||||
| struct virtqueue *vq; | struct virtqueue *vq; | ||||
| struct virtio_console_control *control; | struct virtio_console_control *control; | ||||
| int detached; | int detached; | ||||
| uint32_t len; | |||||
| size_t plen; | |||||
| void *payload; | |||||
| sc = xsc; | sc = xsc; | ||||
| vq = sc->vtcon_ctrl_rxvq; | vq = sc->vtcon_ctrl_rxvq; | ||||
| VTCON_LOCK(sc); | VTCON_LOCK(sc); | ||||
| while ((detached = (sc->vtcon_flags & VTCON_FLAG_DETACHED)) == 0) { | while ((detached = (sc->vtcon_flags & VTCON_FLAG_DETACHED)) == 0) { | ||||
| control = virtqueue_dequeue(vq, NULL); | control = virtqueue_dequeue(vq, &len); | ||||
| payload = NULL; | |||||
| plen = 0; | |||||
| if (control == NULL) | if (control == NULL) | ||||
| break; | break; | ||||
| if (len > sizeof(control)) { | |||||
| payload = (void *)(control + 1); | |||||
| plen = len - sizeof(control); | |||||
| } | |||||
| VTCON_UNLOCK(sc); | VTCON_UNLOCK(sc); | ||||
| vtcon_ctrl_process_event(sc, control); | vtcon_ctrl_process_event(sc, control, payload, plen); | ||||
| VTCON_LOCK(sc); | VTCON_LOCK(sc); | ||||
| vtcon_ctrl_event_requeue(sc, control); | vtcon_ctrl_event_requeue(sc, control); | ||||
| } | } | ||||
| if (!detached) { | if (!detached) { | ||||
| virtqueue_notify(vq); | virtqueue_notify(vq); | ||||
| if (virtqueue_enable_intr(vq) != 0) | if (virtqueue_enable_intr(vq) != 0) | ||||
| taskqueue_enqueue(taskqueue_thread, | taskqueue_enqueue(taskqueue_thread, | ||||
| ▲ Show 20 Lines • Show All 544 Lines • Show Last 20 Lines | |||||