diff options
author | Toomas Soome <tsoome@me.com> | 2016-03-13 20:45:57 +0200 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2017-09-02 18:37:43 +0000 |
commit | 30c75cb09b4d5e86a94a25a9a7ab7481510b57b0 (patch) | |
tree | aa50bc3e8bcd27478227d790d2f102430886b939 | |
parent | ce1d04bfb4326d1e894811fc63d56219b33f2f7a (diff) | |
download | illumos-joyent-30c75cb09b4d5e86a94a25a9a7ab7481510b57b0.tar.gz |
8093 loader.efi: cleanup loader main and implement comconsole
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r-- | usr/src/boot/sys/boot/common/bootstrap.h | 2 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/loader/comconsole.c | 551 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/loader/main.c | 63 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libfirewire/dconsole.c | 17 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/comconsole.c | 199 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/nullconsole.c | 18 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/spinconsole.c | 18 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/ofw/libofw/ofw_console.c | 17 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c | 17 |
9 files changed, 704 insertions, 198 deletions
diff --git a/usr/src/boot/sys/boot/common/bootstrap.h b/usr/src/boot/sys/boot/common/bootstrap.h index 83495af92c..f963ad5391 100644 --- a/usr/src/boot/sys/boot/common/bootstrap.h +++ b/usr/src/boot/sys/boot/common/bootstrap.h @@ -108,7 +108,7 @@ struct console void (*c_out)(struct console *, int); /* emit c */ int (*c_in)(struct console *); /* wait for and return input */ int (*c_ready)(struct console *); /* return nonzer if input waiting */ - void *private; /* private data */ + void *c_private; /* private data */ }; extern struct console *consoles[]; void cons_probe(void); diff --git a/usr/src/boot/sys/boot/efi/loader/comconsole.c b/usr/src/boot/sys/boot/efi/loader/comconsole.c new file mode 100644 index 0000000000..539637b833 --- /dev/null +++ b/usr/src/boot/sys/boot/efi/loader/comconsole.c @@ -0,0 +1,551 @@ +/* + * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +#include <stand.h> +#include <sys/errno.h> +#include <bootstrap.h> + +#include <efi.h> +#include <efilib.h> + +#include "loader_efi.h" + +static EFI_GUID serial = SERIAL_IO_PROTOCOL; + +#define COMC_TXWAIT 0x40000 /* transmit timeout */ + +#ifndef COMSPEED +#define COMSPEED 9600 +#endif + +struct serial { + uint64_t baudrate; + uint8_t databits; + EFI_PARITY_TYPE parity; + EFI_STOP_BITS_TYPE stopbits; + uint8_t ignore_cd; /* boolean */ + uint8_t rtsdtr_off; /* boolean */ + int ioaddr; /* index in handles array */ + SERIAL_IO_INTERFACE *sio; +}; + +static void comc_probe(struct console *); +static int comc_init(struct console *, int); +static void comc_putchar(struct console *, int); +static int comc_getchar(struct console *); +static int comc_ischar(struct console *); +static void comc_setup(struct console *); +static char *comc_asprint_mode(struct serial *); +static int comc_parse_mode(struct serial *, const char *); +static int comc_mode_set(struct env_var *, int, const void *); +static int comc_cd_set(struct env_var *, int, const void *); +static int comc_rtsdtr_set(struct env_var *, int, const void *); + +struct console ttya = { + .c_name = "ttya", + .c_desc = "serial port a", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL +}; + +struct console ttyb = { + .c_name = "ttyb", + .c_desc = "serial port b", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL +}; + +struct console ttyc = { + .c_name = "ttyc", + .c_desc = "serial port c", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL +}; + +struct console ttyd = { + .c_name = "ttyd", + .c_desc = "serial port d", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL +}; + +EFI_STATUS +efi_serial_init(EFI_HANDLE **handlep, int *nhandles) +{ + UINTN bufsz = 0; + EFI_STATUS status; + EFI_HANDLE *handles; + + /* + * get buffer size + */ + *nhandles = 0; + status = BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, handles); + if (status != EFI_BUFFER_TOO_SMALL) + return (status); + + if ((handles = malloc(bufsz)) == NULL) + return (ENOMEM); + + *nhandles = (int)(bufsz/sizeof (EFI_HANDLE)); + /* + * get handle array + */ + status = BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, handles); + if (EFI_ERROR(status)) { + free(handles); + *nhandles = 0; + } else + *handlep = handles; + return (status); +} + +static void +comc_probe(struct console *cp) +{ + EFI_STATUS status; + struct serial *port; + char name[20]; + char value[20]; + char *cons, *env; + EFI_HANDLE *handles = NULL; /* array of handles */ + int nhandles = 0; /* number of handles in array */ + + /* are we already set up? */ + if (cp->c_private != NULL) + return; + + /* make sure the handles are available */ + status = efi_serial_init(&handles, &nhandles); + + cp->c_private = malloc(sizeof (struct serial)); + port = cp->c_private; + port->baudrate = COMSPEED; + + if (strcmp(cp->c_name, "ttya") == 0) + port->ioaddr = 0; + else if (strcmp(cp->c_name, "ttyb") == 0) + port->ioaddr = 1; + else if (strcmp(cp->c_name, "ttyc") == 0) + port->ioaddr = 2; + else if (strcmp(cp->c_name, "ttyd") == 0) + port->ioaddr = 3; + + if (port->ioaddr >= nhandles) + port->ioaddr = -1; /* invalid port */ + + port->databits = 8; /* 8,n,1 */ + port->parity = NoParity; /* 8,n,1 */ + port->stopbits = OneStopBit; /* 8,n,1 */ + port->ignore_cd = 1; /* ignore cd */ + port->rtsdtr_off = 0; /* rts-dtr is on */ + port->sio = NULL; + + if (port->ioaddr != -1) { + status = BS->OpenProtocol(handles[port->ioaddr], + &serial, (void**)&port->sio, IH, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (EFI_ERROR(status)) + port->ioaddr = -1; /* invalid port */ + } + if (handles != NULL) + free(handles); + + snprintf(name, sizeof (name), "%s-mode", cp->c_name); + env = getenv(name); + + if (env != NULL) + (void) comc_parse_mode(port, env); + + env = comc_asprint_mode(port); + + if (env != NULL) { + unsetenv(name); + env_setenv(name, EV_VOLATILE, env, comc_mode_set, env_nounset); + free(env); + } + + snprintf(name, sizeof (name), "%s-ignore-cd", cp->c_name); + env = getenv(name); + if (env != NULL) { + if (strcmp(env, "true") == 0) + port->ignore_cd = 1; + else if (strcmp(env, "false") == 0) + port->ignore_cd = 0; + } + + snprintf(value, sizeof (value), "%s", + port->ignore_cd? "true" : "false"); + unsetenv(name); + env_setenv(name, EV_VOLATILE, value, comc_cd_set, env_nounset); + + snprintf(name, sizeof (name), "%s-rts-dtr-off", cp->c_name); + env = getenv(name); + if (env != NULL) { + if (strcmp(env, "true") == 0) + port->rtsdtr_off = 1; + else if (strcmp(env, "false") == 0) + port->rtsdtr_off = 0; + } + + snprintf(value, sizeof (value), "%s", + port->rtsdtr_off? "true" : "false"); + unsetenv(name); + env_setenv(name, EV_VOLATILE, value, comc_rtsdtr_set, env_nounset); + comc_setup(cp); +} + +static int +comc_init(struct console *cp, int arg __attribute((unused))) +{ + + comc_setup(cp); + + if ((cp->c_flags & (C_PRESENTIN | C_PRESENTOUT)) == + (C_PRESENTIN | C_PRESENTOUT)) + return (CMD_OK); + return (CMD_ERROR); +} + +static void +comc_putchar(struct console *cp, int c) +{ + int wait; + EFI_STATUS status; + UINTN bufsz = 1; + char cb = c; + struct serial *sp = cp->c_private; + + if (sp->sio == NULL) + return; + + for (wait = COMC_TXWAIT; wait > 0; wait--) { + status = sp->sio->Write(sp->sio, &bufsz, &cb); + if (status != EFI_TIMEOUT) + break; + } +} + +static int +comc_getchar(struct console *cp) +{ + EFI_STATUS status; + UINTN bufsz = 1; + char c; + struct serial *sp = cp->c_private; + + if (sp->sio == NULL || !comc_ischar(cp)) + return (-1); + + status = sp->sio->Read(sp->sio, &bufsz, &c); + if (EFI_ERROR(status) || bufsz == 0) + return (-1); + + return (c); +} + +static int +comc_ischar(struct console *cp) +{ + EFI_STATUS status; + uint32_t control; + struct serial *sp = cp->c_private; + + if (sp->sio == NULL) + return (0); + + status = sp->sio->GetControl(sp->sio, &control); + if (EFI_ERROR(status)) + return (0); + + return (!(status & EFI_SERIAL_INPUT_BUFFER_EMPTY)); +} + +static char * +comc_asprint_mode(struct serial *sp) +{ + char par = 'n', *buf; + int stop = 1; + + if (sp == NULL) + return (NULL); + + switch (sp->parity) { + case NoParity: par = 'n'; + break; + case EvenParity: par = 'e'; + break; + case OddParity: par = 'o'; + break; + } + switch (sp->stopbits) { + case OneStopBit: stop = 1; + break; + case TwoStopBits: stop = 2; + break; + } + + asprintf(&buf, "%ju,%d,%c,%d,-", sp->baudrate, sp->databits, par, stop); + return (buf); +} + +static int +comc_parse_mode(struct serial *sp, const char *value) +{ + unsigned long n; + uint64_t baudrate; + uint8_t databits = 8; + int parity = NoParity; + int stopbits = OneStopBit; + char *ep; + + if (value == NULL || *value == '\0') + return (CMD_ERROR); + + errno = 0; + n = strtoul(value, &ep, 10); + if (errno != 0 || *ep != ',') + return (CMD_ERROR); + baudrate = n; + + ep++; + n = strtoul(ep, &ep, 10); + if (errno != 0 || *ep != ',') + return (CMD_ERROR); + + switch (n) { + case 7: databits = 7; + break; + case 8: databits = 8; + break; + default: + return (CMD_ERROR); + } + + ep++; + switch (*ep++) { + case 'n': parity = NoParity; + break; + case 'e': parity = EvenParity; + break; + case 'o': parity = OddParity; + break; + default: + return (CMD_ERROR); + } + + if (*ep == ',') + ep++; + else + return (CMD_ERROR); + + switch (*ep++) { + case '1': stopbits = OneStopBit; + break; + case '2': stopbits = TwoStopBits; + break; + default: + return (CMD_ERROR); + } + + /* handshake is ignored, but we check syntax anyhow */ + if (*ep == ',') + ep++; + else + return (CMD_ERROR); + + switch (*ep++) { + case '-': + case 'h': + case 's': + break; + default: + return (CMD_ERROR); + } + + if (*ep != '\0') + return (CMD_ERROR); + + sp->baudrate = baudrate; + sp->databits = databits; + sp->parity = parity; + sp->stopbits = stopbits; + return (CMD_OK); +} + +static struct console * +get_console(char *name) +{ + struct console *cp = NULL; + + switch (name[3]) { + case 'a': cp = &ttya; + break; + case 'b': cp = &ttyb; + break; + case 'c': cp = &ttyc; + break; + case 'd': cp = &ttyd; + break; + } + return (cp); +} + +static int +comc_mode_set(struct env_var *ev, int flags, const void *value) +{ + struct console *cp; + + if (value == NULL) + return (CMD_ERROR); + + if ((cp = get_console(ev->ev_name)) == NULL) + return (CMD_ERROR); + + if (comc_parse_mode(cp->c_private, value) == CMD_ERROR) + return (CMD_ERROR); + + comc_setup(cp); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + + return (CMD_OK); +} + +static int +comc_cd_set(struct env_var *ev, int flags, const void *value) +{ + struct console *cp; + struct serial *sp; + + if (value == NULL) + return (CMD_ERROR); + + if ((cp = get_console(ev->ev_name)) == NULL) + return (CMD_ERROR); + + sp = cp->c_private; + if (strcmp(value, "true") == 0) + sp->ignore_cd = 1; + else if (strcmp(value, "false") == 0) + sp->ignore_cd = 0; + else + return (CMD_ERROR); + + comc_setup(cp); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + + return (CMD_OK); +} + +static int +comc_rtsdtr_set(struct env_var *ev, int flags, const void *value) +{ + struct console *cp; + struct serial *sp; + + if (value == NULL) + return (CMD_ERROR); + + if ((cp = get_console(ev->ev_name)) == NULL) + return (CMD_ERROR); + + sp = cp->c_private; + if (strcmp(value, "true") == 0) + sp->rtsdtr_off = 1; + else if (strcmp(value, "false") == 0) + sp->rtsdtr_off = 0; + else + return (CMD_ERROR); + + comc_setup(cp); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + + return (CMD_OK); +} + +static void +comc_setup(struct console *cp) +{ + EFI_STATUS status; + UINT32 control; + struct serial *sp = cp->c_private; + + if ((cp->c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) == 0) + return; + + /* port is not usable */ + if (sp->sio == NULL) { + cp->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT); + return; + } + + cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); + status = sp->sio->Reset(sp->sio); + if (EFI_ERROR(status)) { + cp->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT); + } + + status = sp->sio->SetAttributes(sp->sio, sp->baudrate, 0, 0, sp->parity, + sp->databits, sp->stopbits); + if (EFI_ERROR(status)) { + cp->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT); + } + + if (sp->rtsdtr_off) { + status = sp->sio->GetControl(sp->sio, &control); + if (EFI_ERROR(status)) { + cp->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT); + } + control &= ~(EFI_SERIAL_REQUEST_TO_SEND | + EFI_SERIAL_DATA_TERMINAL_READY); + status = sp->sio->SetControl(sp->sio, control); + if (EFI_ERROR(status)) { + cp->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT); + } + } +} diff --git a/usr/src/boot/sys/boot/efi/loader/main.c b/usr/src/boot/sys/boot/efi/loader/main.c index 472ce86509..3ef635fd91 100644 --- a/usr/src/boot/sys/boot/efi/loader/main.c +++ b/usr/src/boot/sys/boot/efi/loader/main.c @@ -41,7 +41,6 @@ #include <efigpt.h> #include <uuid.h> -#include <stdbool.h> #include <bootstrap.h> #include <smbios.h> @@ -61,10 +60,8 @@ EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; EFI_GUID smbios = SMBIOS_TABLE_GUID; EFI_GUID smbios3 = SMBIOS3_TABLE_GUID; EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL; -EFI_GUID serial_io = SERIAL_IO_PROTOCOL; extern void acpi_detect(void); -void efi_serial_init(void); extern void efi_getsmap(void); #ifdef EFI_ZFS_BOOT static void efi_zfs_probe(void); @@ -415,7 +412,6 @@ main(int argc, CHAR16 *argv[]) ptr = efi_get_table(&smbios); smbios_detect(ptr); - efi_serial_init(); /* detect and set up serial ports */ interact(NULL); /* doesn't return */ return (EFI_SUCCESS); /* keep compiler happy */ @@ -424,8 +420,7 @@ main(int argc, CHAR16 *argv[]) COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); static int -command_reboot(int argc __attribute((unused)), - char *argv[] __attribute((unused))) +command_reboot(int argc __unused, char *argv[] __unused) { int i; @@ -442,8 +437,7 @@ command_reboot(int argc __attribute((unused)), COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); static int -command_memmap(int argc __attribute((unused)), - char *argv[] __attribute((unused))) +command_memmap(int argc __unused, char *argv[] __unused) { UINTN sz; EFI_MEMORY_DESCRIPTOR *map, *p; @@ -523,8 +517,7 @@ COMMAND_SET(configuration, "configuration", "print configuration tables", command_configuration); static int -command_configuration(int argc __attribute((unused)), - char *argv[] __attribute((unused))) +command_configuration(int argc __unused, char *argv[] __unused) { UINTN i; char *name; @@ -608,8 +601,7 @@ command_mode(int argc, char *argv[]) COMMAND_SET(lsefi, "lsefi", "list EFI handles", command_lsefi); static int -command_lsefi(int argc __attribute((unused)), - char *argv[] __attribute((unused))) +command_lsefi(int argc __unused, char *argv[] __unused) { char *name; EFI_HANDLE *buffer = NULL; @@ -730,53 +722,6 @@ command_reloadbe(int argc, char *argv[]) } #endif /* __FreeBSD__ */ -void -efi_serial_init(void) -{ - EFI_HANDLE *buffer = NULL; - UINTN bufsz = 0, i; - EFI_STATUS status; - int serial = 0; - - /* - * get buffer size - */ - status = BS->LocateHandle(ByProtocol, &serial_io, NULL, &bufsz, buffer); - if (status != EFI_BUFFER_TOO_SMALL) { - snprintf(command_errbuf, sizeof (command_errbuf), - "unexpected error: %lld", (long long)status); - return; - } - if ((buffer = malloc(bufsz)) == NULL) { - sprintf(command_errbuf, "out of memory"); - return; - } - - /* - * get handle array - */ - status = BS->LocateHandle(ByProtocol, &serial_io, NULL, &bufsz, buffer); - if (EFI_ERROR(status)) { - free(buffer); - snprintf(command_errbuf, sizeof (command_errbuf), - "LocateHandle() error: %lld", (long long)status); - return; - } - - for (i = 0; i < (bufsz / sizeof (EFI_HANDLE)); i++) { - SERIAL_IO_INTERFACE *sio; - status = BS->OpenProtocol(buffer[i], &serial_io, (void**)&sio, - IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (EFI_ERROR(status)) { - snprintf(command_errbuf, sizeof (command_errbuf), - "OpenProtocol() error: %lld", (long long)status); - } - printf("serial# %d\n", serial++); - } - - free(buffer); -} - #ifdef LOADER_FDT_SUPPORT extern int command_fdt_internal(int argc, char *argv[]); diff --git a/usr/src/boot/sys/boot/i386/libfirewire/dconsole.c b/usr/src/boot/sys/boot/i386/libfirewire/dconsole.c index eccdc77799..a77e4ba098 100644 --- a/usr/src/boot/sys/boot/i386/libfirewire/dconsole.c +++ b/usr/src/boot/sys/boot/i386/libfirewire/dconsole.c @@ -60,14 +60,15 @@ uint32_t dcons_paddr; static char dcons_buffer[DCONS_BUF_SIZE + PAGE_SIZE]; struct console dconsole = { - "dcons", - "dumb console port", - 0, - dconsole_probe, - dconsole_init, - dconsole_putchar, - dconsole_getchar, - dconsole_ischar + .c_name = "dcons", + .c_desc = "dumb console port", + .c_flags = 0, + .c_probe = dconsole_probe, + .c_init = dconsole_init, + .c_out = dconsole_putchar, + .c_in = dconsole_getchar, + .c_ready = dconsole_ischar, + .c_private = NULL }; #define DCONSOLE_AS_MULTI_CONSOLE 1 diff --git a/usr/src/boot/sys/boot/i386/libi386/comconsole.c b/usr/src/boot/sys/boot/i386/libi386/comconsole.c index a8ce7906a0..6f24526ac8 100644 --- a/usr/src/boot/sys/boot/i386/libi386/comconsole.c +++ b/usr/src/boot/sys/boot/i386/libi386/comconsole.c @@ -67,69 +67,68 @@ struct serial { uint32_t locator; }; -static void comc_probe(struct console *cp); -static int comc_init(struct console *cp, int arg); -static void comc_putchar(struct console *cp, int c); -static int comc_getchar(struct console *cp); -static int comc_getspeed(struct serial *sp); -static int comc_ischar(struct console *cp); -static uint32_t comc_parse_pcidev(const char *string); -static int comc_pcidev_set(struct env_var *ev, int flags, - const void *value); -static int comc_pcidev_handle(struct console *cp, uint32_t locator); -static void comc_setup(struct console *cp); -static char *comc_print_mode(struct serial *sp, char *buf); -static int comc_parse_mode(struct serial *sp, const char *value); +static void comc_probe(struct console *); +static int comc_init(struct console *, int); +static void comc_putchar(struct console *, int); +static int comc_getchar(struct console *); +static int comc_getspeed(struct serial *); +static int comc_ischar(struct console *); +static uint32_t comc_parse_pcidev(const char *); +static int comc_pcidev_set(struct env_var *, int, const void *); +static int comc_pcidev_handle(struct console *, uint32_t); +static void comc_setup(struct console *); +static char *comc_asprint_mode(struct serial *); +static int comc_parse_mode(struct serial *, const char *); static int comc_mode_set(struct env_var *, int, const void *); static int comc_cd_set(struct env_var *, int, const void *); static int comc_rtsdtr_set(struct env_var *, int, const void *); struct console ttya = { - "ttya", - "serial port a", - 0, - comc_probe, - comc_init, - comc_putchar, - comc_getchar, - comc_ischar, - NULL + .c_name = "ttya", + .c_desc = "serial port a", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL }; struct console ttyb = { - "ttyb", - "serial port b", - 0, - comc_probe, - comc_init, - comc_putchar, - comc_getchar, - comc_ischar, - NULL + .c_name = "ttyb", + .c_desc = "serial port b", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL }; struct console ttyc = { - "ttyc", - "serial port c", - 0, - comc_probe, - comc_init, - comc_putchar, - comc_getchar, - comc_ischar, - NULL + .c_name = "ttyc", + .c_desc = "serial port c", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL }; struct console ttyd = { - "ttyd", - "serial port d", - 0, - comc_probe, - comc_init, - comc_putchar, - comc_getchar, - comc_ischar, - NULL + .c_name = "ttyd", + .c_desc = "serial port d", + .c_flags = 0, + .c_probe = comc_probe, + .c_init = comc_init, + .c_out = comc_putchar, + .c_in = comc_getchar, + .c_ready = comc_ischar, + .c_private = NULL }; static void @@ -140,9 +139,9 @@ comc_probe(struct console *cp) char value[20]; char *cons, *env; - if (cp->private == NULL) { - cp->private = malloc(sizeof(struct serial)); - port = cp->private; + if (cp->c_private == NULL) { + cp->c_private = malloc(sizeof(struct serial)); + port = cp->c_private; port->speed = COMSPEED; if (strcmp(cp->c_name, "ttya") == 0) @@ -168,18 +167,21 @@ comc_probe(struct console *cp) port->speed = comc_getspeed(port); } - snprintf(name, 20, "%s-mode", cp->c_name); + snprintf(name, sizeof (name), "%s-mode", cp->c_name); env = getenv(name); if (env != NULL) { (void) comc_parse_mode(port, env); } - env = comc_print_mode(port, value); + env = comc_asprint_mode(port); - unsetenv(name); - env_setenv(name, EV_VOLATILE, env, comc_mode_set, env_nounset); + if (env != NULL) { + unsetenv(name); + env_setenv(name, EV_VOLATILE, env, comc_mode_set, env_nounset); + free(env); + } - snprintf(name, 20, "%s-ignore-cd", cp->c_name); + snprintf(name, sizeof (name), "%s-ignore-cd", cp->c_name); env = getenv(name); if (env != NULL) { if (strcmp(env, "true") == 0) @@ -188,11 +190,12 @@ comc_probe(struct console *cp) port->ignore_cd = 0; } - sprintf(value, "%s", port->ignore_cd? "true":"false"); + snprintf(value, sizeof (value), "%s", + port->ignore_cd? "true" : "false"); unsetenv(name); env_setenv(name, EV_VOLATILE, value, comc_cd_set, env_nounset); - snprintf(name, 20, "%s-rts-dtr-off", cp->c_name); + snprintf(name, sizeof (name), "%s-rts-dtr-off", cp->c_name); env = getenv(name); if (env != NULL) { if (strcmp(env, "true") == 0) @@ -201,11 +204,12 @@ comc_probe(struct console *cp) port->rtsdtr_off = 0; } - sprintf(value, "%s", port->rtsdtr_off? "true":"false"); + snprintf(value, sizeof (value), "%s", + port->rtsdtr_off? "true" : "false"); unsetenv(name); env_setenv(name, EV_VOLATILE, value, comc_rtsdtr_set, env_nounset); - snprintf(name, 20, "%s-pcidev", cp->c_name); + snprintf(name, sizeof (name), "%s-pcidev", cp->c_name); env = getenv(name); if (env != NULL) { port->locator = comc_parse_pcidev(env); @@ -235,7 +239,7 @@ static void comc_putchar(struct console *cp, int c) { int wait; - struct serial *sp = cp->private; + struct serial *sp = cp->c_private; for (wait = COMC_TXWAIT; wait > 0; wait--) if (inb(sp->ioaddr + com_lsr) & LSR_TXRDY) { @@ -247,21 +251,24 @@ comc_putchar(struct console *cp, int c) static int comc_getchar(struct console *cp) { - struct serial *sp = cp->private; + struct serial *sp = cp->c_private; return (comc_ischar(cp) ? inb(sp->ioaddr + com_data) : -1); } static int comc_ischar(struct console *cp) { - struct serial *sp = cp->private; + struct serial *sp = cp->c_private; return (inb(sp->ioaddr + com_lsr) & LSR_RXRDY); } static char * -comc_print_mode(struct serial *sp, char *buf) +comc_asprint_mode(struct serial *sp) { - char par; + char par, *buf; + + if (sp == NULL) + return (NULL); if ((sp->lcr & (PAREN|PAREVN)) == (PAREN|PAREVN)) par = 'e'; @@ -270,32 +277,35 @@ comc_print_mode(struct serial *sp, char *buf) else par = 'n'; - sprintf(buf, "%d,%d,%c,%d,-", sp->speed, + asprintf(&buf, "%d,%d,%c,%d,-", sp->speed, (sp->lcr & BITS8) == BITS8? 8:7, - par, (par & STOP2) == STOP2? 2:1); + par, (sp->lcr & STOP2) == STOP2? 2:1); return (buf); } static int comc_parse_mode(struct serial *sp, const char *value) { - int n; + unsigned long n; int speed; int lcr; char *ep; - n = strtol(value, &ep, 0); - if (n > 0) - speed = n; - else + if (value == NULL || *value == '\0') return (CMD_ERROR); - if (*ep == ',') - ep++; - else + errno = 0; + n = strtoul(value, &ep, 10); + if (errno != 0 || *ep != ',') + return (CMD_ERROR); + speed = n; + + ep++; + errno = 0; + n = strtoul(ep, &ep, 10); + if (errno != 0 || *ep != ',') return (CMD_ERROR); - n = strtol(ep, &ep, 0); switch (n) { case 7: lcr = BITS7; break; @@ -305,11 +315,7 @@ comc_parse_mode(struct serial *sp, const char *value) return (CMD_ERROR); } - if (*ep == ',') - ep++; - else - return (CMD_ERROR); - + ep++; switch (*ep++) { case 'n': break; @@ -387,7 +393,7 @@ comc_mode_set(struct env_var *ev, int flags, const void *value) if ((cp = get_console(ev->ev_name)) == NULL) return (CMD_ERROR); - if (comc_parse_mode(cp->private, value) == CMD_ERROR) + if (comc_parse_mode(cp->c_private, value) == CMD_ERROR) return (CMD_ERROR); comc_setup(cp); @@ -409,7 +415,7 @@ comc_cd_set(struct env_var *ev, int flags, const void *value) if ((cp = get_console(ev->ev_name)) == NULL) return (CMD_ERROR); - sp = cp->private; + sp = cp->c_private; if (strcmp(value, "true") == 0) sp->ignore_cd = 1; else if (strcmp(value, "false") == 0) @@ -436,7 +442,7 @@ comc_rtsdtr_set(struct env_var *ev, int flags, const void *value) if ((cp = get_console(ev->ev_name)) == NULL) return (CMD_ERROR); - sp = cp->private; + sp = cp->c_private; if (strcmp(value, "true") == 0) sp->rtsdtr_off = 1; else if (strcmp(value, "false") == 0) @@ -467,27 +473,28 @@ comc_parse_pcidev(const char *string) uint32_t locator; int pres; - pres = strtol(string, &p, 0); - if (p == string || *p != ':' || pres < 0 ) + errno = 0; + pres = strtoul(string, &p, 10); + if (errno != 0 || p == string || *p != ':' || pres < 0 ) return (0); bus = pres; p1 = ++p; - pres = strtol(p1, &p, 0); - if (p == string || *p != ':' || pres < 0 ) + pres = strtoul(p1, &p, 10); + if (errno != 0 || p == string || *p != ':' || pres < 0 ) return (0); dev = pres; p1 = ++p; - pres = strtol(p1, &p, 0); - if (p == string || (*p != ':' && *p != '\0') || pres < 0 ) + pres = strtoul(p1, &p, 10); + if (errno != 0 || p == string || (*p != ':' && *p != '\0') || pres < 0 ) return (0); func = pres; if (*p == ':') { p1 = ++p; - pres = strtol(p1, &p, 0); - if (p == string || *p != '\0' || pres <= 0 ) + pres = strtoul(p1, &p, 10); + if (errno != 0 || p == string || *p != '\0' || pres <= 0 ) return (0); bar = pres; } else @@ -506,7 +513,7 @@ comc_pcidev_handle(struct console *cp, uint32_t locator) (void)locator; return (CMD_ERROR); #else - struct serial *sp = cp->private; + struct serial *sp = cp->c_private; char intbuf[64]; uint32_t port; @@ -538,7 +545,7 @@ comc_pcidev_set(struct env_var *ev, int flags, const void *value) if ((cp = get_console(ev->ev_name)) == NULL) return (CMD_ERROR); - sp = cp->private; + sp = cp->c_private; if (value == NULL || (locator = comc_parse_pcidev(value)) <= 0) { printf("Invalid pcidev\n"); @@ -557,7 +564,7 @@ comc_pcidev_set(struct env_var *ev, int flags, const void *value) static void comc_setup(struct console *cp) { - struct serial *sp = cp->private; + struct serial *sp = cp->c_private; static int TRY_COUNT = 1000000; int tries; diff --git a/usr/src/boot/sys/boot/i386/libi386/nullconsole.c b/usr/src/boot/sys/boot/i386/libi386/nullconsole.c index cd9f3a514a..bef9841ffd 100644 --- a/usr/src/boot/sys/boot/i386/libi386/nullconsole.c +++ b/usr/src/boot/sys/boot/i386/libi386/nullconsole.c @@ -47,15 +47,15 @@ static int nullc_getchar(struct console *); static int nullc_ischar(struct console *); struct console nullconsole = { - "null", - "null port", - 0, - nullc_probe, - nullc_init, - nullc_putchar, - nullc_getchar, - nullc_ischar, - NULL + .c_name = "null", + .c_desc = "null port", + .c_flags = 0, + .c_probe = nullc_probe, + .c_init = nullc_init, + .c_out = nullc_putchar, + .c_in = nullc_getchar, + .c_ready = nullc_ischar, + .c_private = NULL }; static void diff --git a/usr/src/boot/sys/boot/i386/libi386/spinconsole.c b/usr/src/boot/sys/boot/i386/libi386/spinconsole.c index 762b88abd1..47a85da493 100644 --- a/usr/src/boot/sys/boot/i386/libi386/spinconsole.c +++ b/usr/src/boot/sys/boot/i386/libi386/spinconsole.c @@ -55,15 +55,15 @@ static int spinc_getchar(struct console *cp); static int spinc_ischar(struct console *cp); struct console spinconsole = { - "spin", - "spin port", - 0, - spinc_probe, - spinc_init, - spinc_putchar, - spinc_getchar, - spinc_ischar, - NULL + .c_name = "spin", + .c_desc = "spin port", + .c_flags = 0, + .c_probe = spinc_probe, + .c_init = spinc_init, + .c_out = spinc_putchar, + .c_in = spinc_getchar, + .c_ready = spinc_ischar, + .c_private = NULL }; static void diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_console.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_console.c index 59ce9a5067..a46c4a66ae 100644 --- a/usr/src/boot/sys/boot/ofw/libofw/ofw_console.c +++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_console.c @@ -44,14 +44,15 @@ static ihandle_t stdin; static ihandle_t stdout; struct console ofwconsole = { - "ofw", - "Open Firmware console", - 0, - ofw_cons_probe, - ofw_cons_init, - ofw_cons_putchar, - ofw_cons_getchar, - ofw_cons_poll, + .c_name = "ofw", + .c_desc = "Open Firmware console", + .c_flags = 0, + .c_probe = ofw_cons_probe, + .c_init = ofw_cons_init, + .c_out = ofw_cons_putchar, + .c_in = ofw_cons_getchar, + .c_ready = ofw_cons_poll, + .c_private = NULL }; static void diff --git a/usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c b/usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c index 6f73ad5633..9b388e5f08 100644 --- a/usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c +++ b/usr/src/boot/sys/boot/userboot/userboot/userboot_cons.c @@ -44,14 +44,15 @@ static int userboot_cons_getchar(void); static int userboot_cons_poll(void); struct console userboot_console = { - "userboot", - "userboot", - 0, - userboot_cons_probe, - userboot_cons_init, - userboot_cons_putchar, - userboot_cons_getchar, - userboot_cons_poll, + .c_name = "userboot", + .c_desc = "userboot", + .c_flags = 0, + .c_probe = userboot_cons_probe, + .c_init = userboot_cons_init, + .c_out = userboot_cons_putchar, + .c_in = userboot_cons_getchar, + .c_ready = userboot_cons_poll, + .c_private = NULL }; /* |