/* this makes a new connection side for a sun_obie: */ static int _tme_sun_obie_connections_new(struct tme_element *element, const char * const *args, struct tme_connection **_conns, char **_output) { struct tme_sun_obie *sun_obie; struct tme_sun_obie_connection *conn_sun_obie; struct tme_bus_connection *conn_bus; struct tme_connection *conn; unsigned int i825x6; tme_uint8_t regs; int usage; int rc; /* recover our data structure: */ sun_obie = (struct tme_sun_obie *) element->tme_element_private; /* we don't bother locking the mutex simply to check if connections already exist: */ /* check our arguments: */ usage = FALSE; rc = 0; i825x6 = FALSE; regs = FALSE; /* if this connection is for the registers: */ if (TME_ARG_IS(args[1], "csr")) { /* if we already have a register connection, complain: */ if (sun_obie->tme_sun_obie_conn_regs != NULL) { rc = EEXIST; } /* otherwise, make the new connection: */ else { regs = TRUE; } } /* else, if this connection is for the memory: */ else if (TME_ARG_IS(args[1], "memory")) { /* if we already have a memory connection, complain: */ if (sun_obie->tme_sun_obie_conn_memory != NULL) { rc = EEXIST; } } /* else, the connection must be for the i825x6: */ else if (args[1] == NULL) { /* if we already have an i825x6 connection, complain: */ if (sun_obie->tme_sun_obie_conn_i825x6 != NULL) { rc = EEXIST; } /* otherwise, make the new conection: */ else { i825x6 = TRUE; } } /* otherwise, this is a bad argument: */ else { tme_output_append_error(_output, "%s %s, ", args[1], _("unexpected")); usage = TRUE; } if (usage) { tme_output_append_error(_output, "%s %s [ csr | memory ]", _("usage:"), args[0]); rc = EINVAL; } if (rc) { return (rc); } /* make a new connection: */ conn_sun_obie = tme_new0(struct tme_sun_obie_connection, 1); conn_bus = &conn_sun_obie->tme_sun_obie_connection; conn = &conn_bus->tme_bus_connection; /* fill in the generic connection: */ conn->tme_connection_next = *_conns; conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC; conn->tme_connection_score = _tme_sun_obie_connection_score; conn->tme_connection_make = _tme_sun_obie_connection_make; conn->tme_connection_break = _tme_sun_obie_connection_break; /* fill in the generic bus connection: */ conn_bus->tme_bus_subregions.tme_bus_subregion_address_first = 0; conn_bus->tme_bus_subregions.tme_bus_subregion_next = NULL; if (i825x6) { conn_bus->tme_bus_subregions.tme_bus_subregion_address_last = 0xffffff; conn_bus->tme_bus_signals_add = _tme_sun_obie_bus_signals_add; conn_bus->tme_bus_signal = _tme_sun_obie_bus_signal; conn_bus->tme_bus_tlb_set_add = _tme_sun_obie_tlb_set_add; conn_bus->tme_bus_tlb_fill = _tme_sun_obie_tlb_fill; } else if (regs) { conn_bus->tme_bus_subregions.tme_bus_subregion_address_last = TME_SUN_OBIE_SIZ_REGS - 1; conn_bus->tme_bus_signal = _tme_sun_obie_bus_signal; conn_bus->tme_bus_tlb_fill = _tme_sun_obie_tlb_fill_regs; } else { conn_bus->tme_bus_subregions.tme_bus_subregion_address_last = 0; } /* fill in the internal information: */ conn_sun_obie->tme_sun_obie_connection_regs = regs; /* return the connection side possibility: */ *_conns = conn; return (TME_OK); }
/* the new serial function: */ TME_ELEMENT_SUB_NEW_DECL(tme_host_posix,serial) { struct tme_posix_serial *serial; const char *filename_in; const char *filename_out; int fd_in, fd_out; int usage; int arg_i; int saved_errno; int emulate_break; /* initialize: */ filename_in = NULL; filename_out = NULL; emulate_break = FALSE; arg_i = 1; usage = FALSE; /* loop reading our arguments: */ for (;;) { /* the device we're supposed to use for input: */ if (TME_ARG_IS(args[arg_i + 0], "device-input") && args[arg_i + 1] != NULL && filename_in == NULL) { filename_in = args[arg_i + 1]; arg_i += 2; } /* the device we're supposed to use for output: */ else if (TME_ARG_IS(args[arg_i + 0], "device-output") && args[arg_i + 1] != NULL && filename_out == NULL) { filename_out = args[arg_i + 1]; arg_i += 2; } /* the device we're supposed to use for input and output: */ else if (TME_ARG_IS(args[arg_i + 0], "device") && args[arg_i + 1] != NULL && filename_in == NULL && filename_out == NULL) { filename_in = filename_out = args[arg_i + 1]; arg_i += 2; } /* if we're supposed to emulate break: */ else if (TME_ARG_IS(args[arg_i + 0], "break-carats")) { emulate_break = TRUE; arg_i++; } /* if we've run out of arguments: */ else if (args[arg_i + 0] == NULL) { /* we must have been given input and output devices: */ if (filename_in == NULL || filename_out == NULL) { usage = TRUE; } break; } /* this is a bad argument: */ else { tme_output_append_error(_output, "%s %s", args[arg_i], _("unexpected")); usage = TRUE; break; } } if (usage) { tme_output_append_error(_output, "%s %s { device %s | { device-input %s device-output %s } } [break-carats]", _("usage:"), args[0], _("DEVICE"), _("DEVICE"), _("DEVICE")); return (EINVAL); } /* open the devices: */ fd_in = fd_out = -1; if (fd_in < 0 && !strcmp(filename_in, "-")) { fd_in = STDIN_FILENO; } if (fd_out < 0 && !strcmp(filename_out, "-")) { fd_out = STDOUT_FILENO; } if (fd_in < 0) { if (strcmp(filename_in, filename_out) == 0) { if (strcmp(filename_in, "pty") == 0) { fd_in = fd_out = posix_openpt(O_RDWR | O_NONBLOCK); if (fd_in != -1) { int serrno; if (grantpt(fd_in) == -1) { bad: serrno = errno; (void)close(fd_in); (void)close(fd_out); errno = serrno; } else { filename_in = filename_out = ptsname(fd_in); if (filename_in) { tme_output_append(_output, "Using %s as console\n", filename_in); } else { goto bad; } } } } else { fd_in = fd_out = open(filename_in, O_RDWR | O_NONBLOCK); } } else { fd_in = open(filename_in, O_RDONLY | O_NONBLOCK); } if (fd_in < 0) { tme_output_append_error(_output, "%s", filename_in); return (errno); } } if (fd_out < 0) { fd_out = open(filename_out, O_WRONLY | O_NONBLOCK); if (fd_out < 0) { saved_errno = errno; close(fd_in); tme_output_append_error(_output, "%s", filename_out); return (saved_errno); } } /* start the serial structure: */ serial = tme_new0(struct tme_posix_serial, 1); serial->tme_posix_serial_element = element; serial->tme_posix_serial_fd_in = fd_in; serial->tme_posix_serial_fd_out = fd_out; serial->tme_posix_serial_emulate_break = emulate_break; serial->tme_posix_serial_ctrl_callout = 0; serial->tme_posix_serial_ctrl_callout_last = 0; tme_serial_buffer_init(&serial->tme_posix_serial_buffer_in, TME_POSIX_SERIAL_BUFFER_SIZE); tme_serial_buffer_init(&serial->tme_posix_serial_buffer_out, TME_POSIX_SERIAL_BUFFER_SIZE); /* start the threads: */ tme_mutex_init(&serial->tme_posix_serial_mutex); tme_cond_init(&serial->tme_posix_serial_cond_writer); tme_thread_create((tme_thread_t) _tme_posix_serial_th_writer, serial); tme_thread_create((tme_thread_t) _tme_posix_serial_th_reader, serial); tme_thread_create((tme_thread_t) _tme_posix_serial_th_ctrl, serial); /* fill the element: */ element->tme_element_private = serial; element->tme_element_connections_new = _tme_posix_serial_connections_new; return (TME_OK); }