Lines Matching full:port
41 VirtIOSerialPort *port; in find_port_by_id() local
47 QTAILQ_FOREACH(port, &vser->ports, next) { in find_port_by_id()
48 if (port->id == id) in find_port_by_id()
49 return port; in find_port_by_id()
56 VirtIOSerialPort *port; in find_port_by_vq() local
58 QTAILQ_FOREACH(port, &vser->ports, next) { in find_port_by_vq()
59 if (port->ivq == vq || port->ovq == vq) in find_port_by_vq()
60 return port; in find_port_by_vq()
70 VirtIOSerialPort *port; in find_port_by_name() local
72 QTAILQ_FOREACH(port, &vser->ports, next) { in find_port_by_name()
73 if (port->name && !strcmp(port->name, name)) { in find_port_by_name()
74 return port; in find_port_by_name()
83 VirtIOSerialPort *port; in find_first_connected_console() local
85 QTAILQ_FOREACH(port, &vser->ports, next) { in find_first_connected_console()
86 VirtIOSerialPortClass const *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in find_first_connected_console()
87 if (vsc->is_console && port->host_connected) { in find_first_connected_console()
88 return port; in find_first_connected_console()
100 static size_t write_to_port(VirtIOSerialPort *port, in write_to_port() argument
107 vq = port->ivq; in write_to_port()
129 virtio_notify(VIRTIO_DEVICE(port->vser), vq); in write_to_port()
151 static void discard_throttle_data(VirtIOSerialPort *port) in discard_throttle_data() argument
153 if (port->elem) { in discard_throttle_data()
154 virtqueue_detach_element(port->ovq, port->elem, 0); in discard_throttle_data()
155 g_free(port->elem); in discard_throttle_data()
156 port->elem = NULL; in discard_throttle_data()
160 static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq, in do_flush_queued_data() argument
165 assert(port); in do_flush_queued_data()
168 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in do_flush_queued_data()
170 while (!port->throttled) { in do_flush_queued_data()
174 if (!port->elem) { in do_flush_queued_data()
175 port->elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); in do_flush_queued_data()
176 if (!port->elem) { in do_flush_queued_data()
179 port->iov_idx = 0; in do_flush_queued_data()
180 port->iov_offset = 0; in do_flush_queued_data()
183 for (i = port->iov_idx; i < port->elem->out_num; i++) { in do_flush_queued_data()
187 buf_size = port->elem->out_sg[i].iov_len - port->iov_offset; in do_flush_queued_data()
188 ret = vsc->have_data(port, in do_flush_queued_data()
189 port->elem->out_sg[i].iov_base in do_flush_queued_data()
190 + port->iov_offset, in do_flush_queued_data()
192 if (!port->elem) { /* bail if we got disconnected */ in do_flush_queued_data()
195 if (port->throttled) { in do_flush_queued_data()
196 port->iov_idx = i; in do_flush_queued_data()
198 port->iov_offset += ret; in do_flush_queued_data()
202 port->iov_offset = 0; in do_flush_queued_data()
204 if (port->throttled) { in do_flush_queued_data()
207 virtqueue_push(vq, port->elem, 0); in do_flush_queued_data()
208 g_free(port->elem); in do_flush_queued_data()
209 port->elem = NULL; in do_flush_queued_data()
214 static void flush_queued_data(VirtIOSerialPort *port) in flush_queued_data() argument
216 assert(port); in flush_queued_data()
218 if (!virtio_queue_ready(port->ovq)) { in flush_queued_data()
221 do_flush_queued_data(port, port->ovq, VIRTIO_DEVICE(port->vser)); in flush_queued_data()
264 int virtio_serial_open(VirtIOSerialPort *port) in virtio_serial_open() argument
266 /* Don't allow opening an already-open port */ in virtio_serial_open()
267 if (port->host_connected) { in virtio_serial_open()
270 /* Send port open notification to the guest */ in virtio_serial_open()
271 port->host_connected = true; in virtio_serial_open()
272 send_control_event(port->vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 1); in virtio_serial_open()
277 int virtio_serial_close(VirtIOSerialPort *port) in virtio_serial_close() argument
279 port->host_connected = false; in virtio_serial_close()
284 port->throttled = false; in virtio_serial_close()
285 discard_throttle_data(port); in virtio_serial_close()
286 discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser)); in virtio_serial_close()
288 send_control_event(port->vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 0); in virtio_serial_close()
294 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf, in virtio_serial_write() argument
297 if (!port || !port->host_connected || !port->guest_connected) { in virtio_serial_write()
300 return write_to_port(port, buf, size); in virtio_serial_write()
304 * Readiness of the guest to accept data on a port.
307 size_t virtio_serial_guest_ready(VirtIOSerialPort *port) in virtio_serial_guest_ready() argument
309 VirtIODevice *vdev = VIRTIO_DEVICE(port->vser); in virtio_serial_guest_ready()
310 VirtQueue *vq = port->ivq; in virtio_serial_guest_ready()
318 if (use_multiport(port->vser) && !port->guest_connected) { in virtio_serial_guest_ready()
327 VirtIOSerialPort *port = opaque; in flush_queued_data_bh() local
329 flush_queued_data(port); in flush_queued_data_bh()
332 void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle) in virtio_serial_throttle_port() argument
334 if (!port) { in virtio_serial_throttle_port()
338 trace_virtio_serial_throttle_port(port->id, throttle); in virtio_serial_throttle_port()
339 port->throttled = throttle; in virtio_serial_throttle_port()
343 qemu_bh_schedule(port->bh); in virtio_serial_throttle_port()
350 struct VirtIOSerialPort *port; in handle_control_message() local
378 QTAILQ_FOREACH(port, &vser->ports, next) { in handle_control_message()
379 send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_ADD, 1); in handle_control_message()
384 port = find_port_by_id(vser, virtio_ldl_p(vdev, &gcpkt->id)); in handle_control_message()
385 if (!port) { in handle_control_message()
386 error_report("virtio-serial-bus: Unexpected port id %u for device %s", in handle_control_message()
391 trace_virtio_serial_handle_control_message_port(port->id); in handle_control_message()
393 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in handle_control_message()
398 error_report("virtio-serial-bus: Guest failure in adding port %u for device %s", in handle_control_message()
399 port->id, vser->bus.qbus.name); in handle_control_message()
403 * Now that we know the guest asked for the port name, we're in handle_control_message()
405 * for this port. Now's a good time to let the guest know if in handle_control_message()
406 * this port is a console port so that the guest can hook it in handle_control_message()
410 send_control_event(vser, port->id, VIRTIO_CONSOLE_CONSOLE_PORT, 1); in handle_control_message()
413 if (port->name) { in handle_control_message()
414 virtio_stl_p(vdev, &cpkt.id, port->id); in handle_control_message()
418 buffer_len = sizeof(cpkt) + strlen(port->name) + 1; in handle_control_message()
422 memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name)); in handle_control_message()
429 if (port->host_connected) { in handle_control_message()
430 send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 1); in handle_control_message()
440 vsc->guest_ready(port); in handle_control_message()
445 port->guest_connected = cpkt.value; in handle_control_message()
448 vsc->set_guest_connected(port, cpkt.value); in handle_control_message()
498 /* Guest wrote something to some port. */
502 VirtIOSerialPort *port; in handle_output() local
505 port = find_port_by_vq(vser, vq); in handle_output()
507 if (!port || !port->host_connected) { in handle_output()
512 if (!port->throttled) { in handle_output()
513 do_flush_queued_data(port, vq, vdev); in handle_output()
532 VirtIOSerialPort *port; in handle_input() local
536 port = find_port_by_vq(vser, vq); in handle_input()
538 if (!port) { in handle_input()
541 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in handle_input()
548 if (port->guest_connected && port->host_connected && vsc->guest_writable) { in handle_input()
549 vsc->guest_writable(port); in handle_input()
586 VirtIOSerialPort *port = find_first_connected_console(vser); in set_config() local
599 if (!port) { in set_config()
602 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in set_config()
603 (void)vsc->have_data(port, &emerg_wr_lo, 1); in set_config()
608 VirtIOSerialPort *port; in guest_reset() local
611 QTAILQ_FOREACH(port, &vser->ports, next) { in guest_reset()
612 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in guest_reset()
614 discard_throttle_data(port); in guest_reset()
616 if (port->guest_connected) { in guest_reset()
617 port->guest_connected = false; in guest_reset()
619 vsc->set_guest_connected(port, false); in guest_reset()
628 VirtIOSerialPort *port; in set_status() local
631 port = find_port_by_id(vser, 0); in set_status()
633 if (port && !use_multiport(port->vser) in set_status()
637 * open/close status. Such guests can only have a port at id in set_status()
641 port->guest_connected = true; in set_status()
647 QTAILQ_FOREACH(port, &vser->ports, next) { in set_status()
648 VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in set_status()
650 vsc->enable_backend(port, vdev->vm_running); in set_status()
667 VirtIOSerialPort *port; in virtio_serial_save_device() local
687 QTAILQ_FOREACH(port, &s->ports, next) { in virtio_serial_save_device()
696 QTAILQ_FOREACH(port, &s->ports, next) { in virtio_serial_save_device()
699 qemu_put_be32s(f, &port->id); in virtio_serial_save_device()
700 qemu_put_byte(f, port->guest_connected); in virtio_serial_save_device()
701 qemu_put_byte(f, port->host_connected); in virtio_serial_save_device()
704 if (port->elem) { in virtio_serial_save_device()
709 qemu_put_be32s(f, &port->iov_idx); in virtio_serial_save_device()
710 qemu_put_be64s(f, &port->iov_offset); in virtio_serial_save_device()
711 qemu_put_virtqueue_element(vdev, f, port->elem); in virtio_serial_save_device()
720 VirtIOSerialPort *port; in virtio_serial_post_load_timer_cb() local
728 port = s->post_load->connected[i].port; in virtio_serial_post_load_timer_cb()
730 if (host_connected != port->host_connected) { in virtio_serial_post_load_timer_cb()
735 send_control_event(s, port->id, VIRTIO_CONSOLE_PORT_OPEN, in virtio_serial_post_load_timer_cb()
736 port->host_connected); in virtio_serial_post_load_timer_cb()
738 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in virtio_serial_post_load_timer_cb()
740 vsc->set_guest_connected(port, port->guest_connected); in virtio_serial_post_load_timer_cb()
766 VirtIOSerialPort *port; in fetch_active_ports_list() local
771 port = find_port_by_id(s, id); in fetch_active_ports_list()
772 if (!port) { in fetch_active_ports_list()
776 port->guest_connected = qemu_get_byte(f); in fetch_active_ports_list()
777 s->post_load->connected[i].port = port; in fetch_active_ports_list()
782 qemu_get_be32s(f, &port->iov_idx); in fetch_active_ports_list()
783 qemu_get_be64s(f, &port->iov_offset); in fetch_active_ports_list()
785 port->elem = in fetch_active_ports_list()
789 * Port was throttled on source machine. Let's in fetch_active_ports_list()
792 virtio_serial_throttle_port(port, false); in fetch_active_ports_list()
859 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(qdev); in virtser_bus_dev_print() local
862 indent, "", port->id, in virtser_bus_dev_print()
863 port->guest_connected ? "on" : "off", in virtser_bus_dev_print()
864 port->host_connected ? "on" : "off", in virtser_bus_dev_print()
865 port->throttled ? "on" : "off"); in virtser_bus_dev_print()
868 /* This function is only used if a port id is not provided by the user */
902 VirtIOSerialPort *port; in remove_port() local
905 * Don't mark port 0 removed -- we explicitly reserve it for in remove_port()
916 port = find_port_by_id(vser, port_id); in remove_port()
919 * get a NULL port here, we're in trouble. in remove_port()
921 assert(port); in remove_port()
924 discard_throttle_data(port); in remove_port()
925 discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser)); in remove_port()
927 send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1); in remove_port()
932 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev); in virtser_port_device_realize() local
933 VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); in virtser_port_device_realize()
939 port->vser = bus->vser; in virtser_port_device_realize()
944 * Is the first console port we're seeing? If so, put it up at in virtser_port_device_realize()
948 plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0); in virtser_port_device_realize()
950 if (find_port_by_id(port->vser, port->id)) { in virtser_port_device_realize()
951 error_setg(errp, "virtio-serial-bus: A port already exists at id %u", in virtser_port_device_realize()
952 port->id); in virtser_port_device_realize()
956 if (port->name != NULL && find_port_by_name(port->name)) { in virtser_port_device_realize()
957 error_setg(errp, "virtio-serial-bus: A port already exists by name %s", in virtser_port_device_realize()
958 port->name); in virtser_port_device_realize()
962 if (port->id == VIRTIO_CONSOLE_BAD_ID) { in virtser_port_device_realize()
964 port->id = 0; in virtser_port_device_realize()
966 port->id = find_free_port_id(port->vser); in virtser_port_device_realize()
967 if (port->id == VIRTIO_CONSOLE_BAD_ID) { in virtser_port_device_realize()
968 error_setg(errp, "virtio-serial-bus: Maximum port limit for " in virtser_port_device_realize()
975 max_nr_ports = port->vser->serial.max_virtserial_ports; in virtser_port_device_realize()
976 if (port->id >= max_nr_ports) { in virtser_port_device_realize()
977 error_setg(errp, "virtio-serial-bus: Out-of-range port id specified, " in virtser_port_device_realize()
988 port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port); in virtser_port_device_realize()
989 port->elem = NULL; in virtser_port_device_realize()
995 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev); in virtser_port_device_plug() local
997 QTAILQ_INSERT_TAIL(&port->vser->ports, port, next); in virtser_port_device_plug()
998 port->ivq = port->vser->ivqs[port->id]; in virtser_port_device_plug()
999 port->ovq = port->vser->ovqs[port->id]; in virtser_port_device_plug()
1001 add_port(port->vser, port->id); in virtser_port_device_plug()
1003 /* Send an update to the guest about this new port added */ in virtser_port_device_plug()
1009 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev); in virtser_port_device_unrealize() local
1011 VirtIOSerial *vser = port->vser; in virtser_port_device_unrealize()
1013 qemu_bh_delete(port->bh); in virtser_port_device_unrealize()
1014 remove_port(port->vser, port->id); in virtser_port_device_unrealize()
1016 QTAILQ_REMOVE(&vser->ports, port, next); in virtser_port_device_unrealize()
1035 /* Each port takes 2 queues, and one pair is for the control queue */ in virtio_serial_device_realize()
1060 /* Add a queue for host to guest transfers for port 0 (backward compat) */ in virtio_serial_device_realize()
1062 /* Add a queue for guest to host transfers for port 0 (backward compat) */ in virtio_serial_device_realize()
1077 /* Add a per-port queue for host to guest transfers */ in virtio_serial_device_realize()
1086 * Reserve location 0 for a console port for backward compat in virtio_serial_device_realize()