Lines Matching +full:mux +full:- +full:add +full:- +full:data
10 * http://www.apache.org/licenses/LICENSE-2.0
41 #include "console-mux.h"
43 #include "console-server.h"
60 " --config <FILE>\tUse FILE for configuration\n" in usage()
61 " --console-id <NAME>\tUse NAME in the UNIX domain socket address\n" in usage()
68 return p->fd == -1 && p->events == 0 && p->revents == ~0; in console_server_pollfd_reclaimable()
74 for (size_t i = 0; i < server->capacity_pollfds; i++) { in console_server_find_released_pollfd()
75 struct pollfd *p = &server->pollfds[i]; in console_server_find_released_pollfd()
80 return -1; in console_server_find_released_pollfd()
83 // returns the index of that pollfd in server->pollfds
84 // we cannot return a pointer because 'realloc' may move server->pollfds
94 const size_t newcap = server->capacity_pollfds + 1; in console_server_request_pollfd()
96 struct pollfd *newarr = reallocarray(server->pollfds, newcap, in console_server_request_pollfd()
99 return -1; in console_server_request_pollfd()
101 server->pollfds = newarr; in console_server_request_pollfd()
103 index = (ssize_t)server->capacity_pollfds; in console_server_request_pollfd()
105 server->capacity_pollfds = newcap; in console_server_request_pollfd()
108 pollfd = &server->pollfds[index]; in console_server_request_pollfd()
109 pollfd->fd = fd; in console_server_request_pollfd()
110 pollfd->events = events; in console_server_request_pollfd()
111 pollfd->revents = 0; in console_server_request_pollfd()
119 if (pollfd_index >= server->capacity_pollfds) { in console_server_release_pollfd()
120 return -1; in console_server_release_pollfd()
123 struct pollfd *pfd = &server->pollfds[pollfd_index]; in console_server_release_pollfd()
128 // https://www.man7.org/linux/man-pages/man2/poll.2.html in console_server_release_pollfd()
129 pfd->fd = -1; in console_server_release_pollfd()
130 pfd->events = 0; in console_server_release_pollfd()
131 pfd->revents = ~0; in console_server_release_pollfd()
136 /* populates server->tty.dev and server->tty.sysfs_devnode, using the tty kernel name */
149 server->tty.type = TTY_DEVICE_UNDEFINED; in tty_find_device()
151 assert(server->tty.kname); in tty_find_device()
152 if (!strlen(server->tty.kname)) { in tty_find_device()
154 rc = -1; in tty_find_device()
158 if (server->tty.kname[0] == '/') { in tty_find_device()
159 tty_path_input = strdup(server->tty.kname); in tty_find_device()
161 rc = -1; in tty_find_device()
165 rc = asprintf(&tty_path_input, "/dev/%s", server->tty.kname); in tty_find_device()
175 rc = -1; in tty_find_device()
180 * Allow hooking obmc-console-server up to PTYs for testing in tty_find_device()
182 * https://amboar.github.io/notes/2023/05/02/testing-obmc-console-with-socat.html in tty_find_device()
185 server->tty.type = TTY_DEVICE_PTY; in tty_find_device()
186 server->tty.dev = strdup(server->tty.kname); in tty_find_device()
187 rc = server->tty.dev ? 0 : -1; in tty_find_device()
193 warn("Can't find real name for %s", server->tty.kname); in tty_find_device()
194 rc = -1; in tty_find_device()
207 rc = -1; in tty_find_device()
211 rc = asprintf(&server->tty.dev, "/dev/%s", tty_kname_real); in tty_find_device()
216 // Default to non-VUART in tty_find_device()
217 server->tty.type = TTY_DEVICE_UART; in tty_find_device()
231 * - so we need to check for both in tty_find_device()
270 server->tty.type = TTY_DEVICE_VUART; in tty_find_device()
271 server->tty.vuart.sysfs_devnode = in tty_find_device()
297 assert(server->tty.type == TTY_DEVICE_VUART); in tty_set_sysfs_attr()
299 if (!server->tty.vuart.sysfs_devnode) { in tty_set_sysfs_attr()
300 return -1; in tty_set_sysfs_attr()
303 rc = asprintf(&path, "%s/%s", server->tty.vuart.sysfs_devnode, name); in tty_set_sysfs_attr()
305 return -1; in tty_set_sysfs_attr()
311 server->tty.kname); in tty_set_sysfs_attr()
312 rc = -1; in tty_set_sysfs_attr()
320 server->tty.kname); in tty_set_sysfs_attr()
337 rc = tcgetattr(server->tty.fd, &termios); in tty_init_termios()
343 if (server->tty.type == TTY_DEVICE_UART && server->tty.uart.baud) { in tty_init_termios()
344 if (cfsetspeed(&termios, server->tty.uart.baud) < 0) { in tty_init_termios()
345 warn("Couldn't set speeds for %s", server->tty.kname); in tty_init_termios()
354 rc = tcsetattr(server->tty.fd, TCSANOW, &termios); in tty_init_termios()
356 warn("Can't set terminal options for %s", server->tty.kname); in tty_init_termios()
365 assert(server->tty.type == TTY_DEVICE_VUART); in tty_init_vuart_io()
367 if (server->tty.vuart.sirq) { in tty_init_vuart_io()
368 tty_set_sysfs_attr(server, "sirq", server->tty.vuart.sirq); in tty_init_vuart_io()
371 if (server->tty.vuart.lpc_addr) { in tty_init_vuart_io()
373 server->tty.vuart.lpc_addr); in tty_init_vuart_io()
379 server->tty.fd = open(server->tty.dev, O_RDWR); in tty_init_io()
380 if (server->tty.fd <= 0) { in tty_init_io()
381 warn("Can't open tty %s", server->tty.dev); in tty_init_io()
382 return -1; in tty_init_io()
386 * we detect larger amounts of data in tty_init_io()
388 fcntl(server->tty.fd, F_SETFL, FNDELAY); in tty_init_io()
393 console_server_request_pollfd(server, server->tty.fd, POLLIN); in tty_init_io()
396 return -1; in tty_init_io()
399 server->tty_pollfd_index = (size_t)index; in tty_init_io()
410 assert(server->tty.type == TTY_DEVICE_VUART); in tty_init_vuart()
412 val = config_get_value(config, "lpc-address"); in tty_init_vuart()
417 warn("Cannot interpret 'lpc-address' value as an unsigned long: '%s'", in tty_init_vuart()
419 return -1; in tty_init_vuart()
424 return -1; in tty_init_vuart()
427 server->tty.vuart.lpc_addr = (uint16_t)parsed; in tty_init_vuart()
430 return -1; in tty_init_vuart()
447 server->tty.vuart.sirq = (int)parsed; in tty_init_vuart()
463 server->tty.kname = tty_arg; in tty_init()
464 } else if ((val = config_get_value(config, "upstream-tty"))) { in tty_init()
465 server->tty.kname = val; in tty_init()
468 return -1; in tty_init()
476 switch (server->tty.type) { in tty_init()
488 if (config_parse_baud(&server->tty.uart.baud, val)) { in tty_init()
498 return -1; in tty_init()
506 if (server->tty_pollfd_index < server->capacity_pollfds) { in tty_fini()
507 console_server_release_pollfd(server, server->tty_pollfd_index); in tty_fini()
508 server->tty_pollfd_index = SIZE_MAX; in tty_fini()
511 if (server->tty.type == TTY_DEVICE_VUART) { in tty_fini()
512 free(server->tty.vuart.sysfs_devnode); in tty_fini()
515 free(server->tty.dev); in tty_fini()
518 static int write_to_path(const char *path, const char *data) in write_to_path() argument
523 return -1; in write_to_path()
526 if (fprintf(f, "%s", data) < 0) { in write_to_path()
527 rc = -1; in write_to_path()
531 rc = -1; in write_to_path()
538 "/sys/bus/platform/drivers/aspeed-uart-routing/*.uart-routing"
551 muxcfg = config_get_value(config, "aspeed-uart-routing"); in uart_routing_init()
559 warn("Couldn't find uart-routing driver directory, cannot apply config"); in uart_routing_init()
563 warnx("Found %zd uart-routing driver directories, cannot apply config", in uart_routing_init()
571 * just use one (worst-case) size for all of them -- +2 for a trailing in uart_routing_init()
611 warn("Failed to apply uart-routing config '%s:%s'", in uart_routing_init()
624 int console_data_out(struct console *console, const uint8_t *data, size_t len) in console_data_out() argument
626 return write_buf_to_fd(console->server->tty.fd, data, len); in console_data_out()
636 console->console_id = config_resolve_console_id(config, console_id); in set_socket_info()
639 len = console_socket_path(console->socket_name, console->console_id); in set_socket_info()
646 console->socket_name_len = len; in set_socket_info()
653 /* NOLINTBEGIN(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */ in handlers_init()
656 /* NOLINTEND(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */ in handlers_init()
661 n_types = __stop_handlers - __start_handlers; in handlers_init()
662 console->handlers = calloc(n_types, sizeof(struct handler *)); in handlers_init()
663 if (!console->handlers) { in handlers_init()
676 if (!type->init || !type->fini) { in handlers_init()
679 type->name); in handlers_init()
682 handler = type->init(type, console, config); in handlers_init()
685 console->console_id, type->name, handler ? "" : "in"); in handlers_init()
688 handler->type = type; in handlers_init()
689 console->handlers[j++] = handler; in handlers_init()
693 console->n_handlers = j; in handlers_init()
701 for (i = 0; i < console->n_handlers; i++) { in handlers_fini()
702 handler = console->handlers[i]; in handlers_fini()
703 handler->type->fini(handler); in handlers_fini()
706 free(console->handlers); in handlers_fini()
707 console->handlers = NULL; in handlers_fini()
708 console->n_handlers = 0; in handlers_fini()
726 tv->tv_sec = t.tv_sec; in get_current_time()
727 tv->tv_usec = t.tv_nsec / 1000; in get_current_time()
734 ringbuffer_poll_fn_t poll_fn, void *data) in console_ringbuffer_consumer_register() argument
736 return ringbuffer_consumer_register(console->rb, poll_fn, data); in console_ringbuffer_consumer_register()
743 int events, void *data) in console_poller_register() argument
749 console->server, fd, (short)(events & 0x7fff)); in console_poller_register()
757 poller->remove = false; in console_poller_register()
758 poller->handler = handler; in console_poller_register()
759 poller->event_fn = poller_fn; in console_poller_register()
760 poller->timeout_fn = timeout_fn; in console_poller_register()
761 timerclear(&poller->timeout); in console_poller_register()
762 poller->data = data; in console_poller_register()
763 poller->pollfd_index = index; in console_poller_register()
765 /* add one to our pollers array */ in console_poller_register()
766 n = console->n_pollers++; in console_poller_register()
771 /* NOLINTBEGIN(bugprone-sizeof-expression) */ in console_poller_register()
772 console->pollers = reallocarray(console->pollers, console->n_pollers, in console_poller_register()
773 sizeof(*console->pollers)); in console_poller_register()
775 /* NOLINTEND(bugprone-sizeof-expression) */ in console_poller_register()
777 console->pollers[n] = poller; in console_poller_register()
787 for (i = 0; i < console->n_pollers; i++) { in console_poller_unregister()
788 if (console->pollers[i] == poller) { in console_poller_unregister()
793 assert(i < console->n_pollers); in console_poller_unregister()
795 console->n_pollers--; in console_poller_unregister()
803 /* NOLINTBEGIN(bugprone-sizeof-expression) */ in console_poller_unregister()
804 memmove(&console->pollers[i], &console->pollers[i + 1], in console_poller_unregister()
805 sizeof(*console->pollers) * (console->n_pollers - i)); in console_poller_unregister()
807 if (console->n_pollers == 0) { in console_poller_unregister()
808 free(console->pollers); in console_poller_unregister()
809 console->pollers = NULL; in console_poller_unregister()
811 console->pollers = reallocarray(console->pollers, in console_poller_unregister()
812 console->n_pollers, in console_poller_unregister()
813 sizeof(*console->pollers)); in console_poller_unregister()
815 /* NOLINTEND(bugprone-sizeof-expression) */ in console_poller_unregister()
817 console_server_release_pollfd(console->server, poller->pollfd_index); in console_poller_unregister()
825 console->server->pollfds[poller->pollfd_index].events = in console_poller_set_events()
840 timeradd(&now, tv, &poller->timeout); in console_poller_set_timeout()
852 for (i = 0; i < console->n_pollers; i++) { in get_poll_timeout()
853 poller = console->pollers[i]; in get_poll_timeout()
855 if (poller->timeout_fn && timerisset(&poller->timeout) && in get_poll_timeout()
857 (earliest && timercmp(&poller->timeout, earliest, <)))) { in get_poll_timeout()
858 // poller is buffering data and needs the poll in get_poll_timeout()
860 earliest = &poller->timeout; in get_poll_timeout()
875 return -1; in get_poll_timeout()
890 * in-step, calling any pollers that we've found revents for. in call_pollers()
892 for (i = 0; i < console->n_pollers; i++) { in call_pollers()
893 poller = console->pollers[i]; in call_pollers()
894 pollfd = &console->server->pollfds[poller->pollfd_index]; in call_pollers()
895 if (pollfd->fd < 0) { in call_pollers()
903 if (pollfd->revents) { in call_pollers()
904 prc = poller->event_fn(poller->handler, pollfd->revents, in call_pollers()
905 poller->data); in call_pollers()
907 rc = -1; in call_pollers()
909 poller->remove = true; in call_pollers()
913 if ((prc == POLLER_OK) && poller->timeout_fn && in call_pollers()
914 timerisset(&poller->timeout) && in call_pollers()
915 timercmp(&poller->timeout, cur_time, <=)) { in call_pollers()
917 data stream. The amount of idle time the consumer in call_pollers()
918 desired has expired. Process the buffered data for in call_pollers()
920 timerclear(&poller->timeout); in call_pollers()
921 prc = poller->timeout_fn(poller->handler, poller->data); in call_pollers()
923 rc = -1; in call_pollers()
925 poller->remove = true; in call_pollers()
937 for (i = 0; i < console->n_pollers; i++) { in call_pollers()
938 poller = console->pollers[i]; in call_pollers()
939 if (poller->remove) { in call_pollers()
965 if (console->rb->size < buf_size) { in run_console_per_console()
968 return -1; in run_console_per_console()
973 return -1; in run_console_per_console()
979 return -1; in run_console_per_console()
995 return -1; in run_console_iteration()
998 timeout = get_poll_timeout(server->active, &tv); in run_console_iteration()
1000 rc = poll(server->pollfds, server->capacity_pollfds, (int)timeout); in run_console_iteration()
1004 return -1; in run_console_iteration()
1012 return -1; in run_console_iteration()
1016 if (server->pollfds[server->tty_pollfd_index].revents) { in run_console_iteration()
1017 rc = read(server->tty.fd, buf, sizeof(buf)); in run_console_iteration()
1020 return -1; in run_console_iteration()
1023 rc = ringbuffer_queue(server->active->rb, buf, rc); in run_console_iteration()
1025 return -1; in run_console_iteration()
1031 &(server->pollfds[server->dbus_pollfd_index]); in run_console_iteration()
1032 if (dbus_pollfd->revents) { in run_console_iteration()
1033 sd_bus_process(server->bus, NULL); in run_console_iteration()
1036 for (size_t i = 0; i < server->n_consoles; i++) { in run_console_iteration()
1037 struct console *console = server->consoles[i]; in run_console_iteration()
1041 return -1; in run_console_iteration()
1053 if (server->n_consoles == 0) { in run_server()
1055 return -1; in run_server()
1067 return rc ? -1 : 0; in run_server()
1072 { "console-id", required_argument, 0, 'i' },
1089 console->server = server; in console_init()
1090 console->console_id = console_id; in console_init()
1093 config_get_section_value(config, console_id, "ringbuffer-size"); in console_init()
1096 buffer_size_str = config_get_value(config, "ringbuffer-size"); in console_init()
1102 warn("Invalid ringbuffer-size. Default to %zukB", in console_init()
1107 console->rb = ringbuffer_init(buffer_size); in console_init()
1108 if (!console->rb) { in console_init()
1114 warnx("could not set mux gpios from config, exiting"); in console_init()
1133 free(console->rb); in console_init()
1143 ringbuffer_fini(console->rb); in console_fini()
1144 free(console->pollers); in console_fini()
1158 struct console **tmp = reallocarray(server->consoles, in console_server_add_console()
1159 server->n_consoles + 1, in console_server_add_console()
1162 warnx("could not realloc server->consoles"); in console_server_add_console()
1163 return -1; in console_server_add_console()
1165 server->consoles = tmp; in console_server_add_console()
1170 return -1; in console_server_add_console()
1173 server->consoles[server->n_consoles++] = console; in console_server_add_console()
1185 const int nsections = config_count_sections(server->config); in console_server_add_consoles()
1193 rc = console_server_add_console(server, server->config, in console_server_add_consoles()
1202 config_get_section_name(server->config, i); in console_server_add_consoles()
1209 rc = console_server_add_console(server, server->config, in console_server_add_consoles()
1217 config_get_value(server->config, "active-console"); in console_server_add_consoles()
1219 return server->consoles[0]; in console_server_add_consoles()
1222 printf("setting console-id '%s' as the initially active console\n", in console_server_add_consoles()
1225 for (size_t i = 0; i < server->n_consoles; i++) { in console_server_add_consoles()
1226 struct console *console = server->consoles[i]; in console_server_add_consoles()
1228 if (strcmp(console->console_id, initially_active) == 0) { in console_server_add_consoles()
1233 warnx("'active-console' '%s' not found among console ids\n", in console_server_add_consoles()
1246 server->tty_pollfd_index = -1; in console_server_init()
1248 server->config = config_init(config_filename); in console_server_init()
1249 if (server->config == NULL) { in console_server_init()
1250 return -1; in console_server_init()
1255 return -1; in console_server_init()
1258 uart_routing_init(server->config); in console_server_init()
1260 rc = tty_init(server, server->config, config_tty_kname); in console_server_init()
1263 return -1; in console_server_init()
1269 return -1; in console_server_init()
1275 return -1; in console_server_init()
1280 return -1; in console_server_init()
1288 for (size_t i = 0; i < server->n_consoles; i++) { in console_server_fini()
1289 console_fini(server->consoles[i]); in console_server_fini()
1292 free(server->consoles); in console_server_fini()
1295 free(server->pollfds); in console_server_fini()
1297 config_fini(server->config); in console_server_fini()
1313 if (c == -1) { in main()