static void net_io_flush(void) { int n; char *bp = out_buf; #ifdef DEBUG_TCP if (show_tcp) { int old_console; old_console = start_console(); diag_printf("%s.%d\n", __FUNCTION__, __LINE__); diag_dump_buf(out_buf, out_buflen); end_console(old_console); } #endif // SHOW_TCP n = __tcp_write_block(&tcp_sock, bp, out_buflen); if (n < 0) { // The connection is gone! net_io_revert_console(); } else { out_buflen -= n; bp += n; } out_bufp = out_buf; out_buflen = 0; // Check interrupt flag if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); cyg_hal_user_break(0); } }
// // This function is called from the hardware driver when an output operation // has completed - i.e. the packet has been sent. // static void eth_drv_tx_done(struct eth_drv_sc *sc, CYG_ADDRWORD key, int status) { CYGARC_HAL_SAVE_GP(); if ((int *)key == &packet_sent) { *(int *)key = 1; } else { // It's possible that this acknowledgement is for a different // [logical] driver. Try and pass it on. #if defined(CYGDBG_IO_ETH_DRIVERS_DEBUG) && \ (CYGDBG_IO_ETH_DRIVERS_DEBUG_VERBOSITY >=2 ) // Note: not normally enabled - too verbose if (cyg_io_eth_net_debug > 1) { int old_console; old_console = start_console(); diag_printf("tx_done for other key: %x\n", key); end_console(old_console); } #endif LOCK_APPLICATION_SCHEDULER(); if (sc->funs->eth_drv_old) { (sc->funs->eth_drv_old->tx_done)(sc, key, status); } else { (sc->funs->eth_drv->tx_done)(sc, key, status); } UNLOCK_APPLICATION_SCHEDULER(); } CYGARC_HAL_RESTORE_GP(); }
static void net_io_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) { int old_console; old_console = start_console(); diag_printf("%s.%d\n", __FUNCTION__, __LINE__); end_console(old_console); #if 0 CYGARC_HAL_SAVE_GP(); while(__len-- > 0) *__buf++ = net_io_getc(__ch_data); CYGARC_HAL_RESTORE_GP(); #endif }
int main(void) { int err; int stage = 0; err = start_console(&theconsole, &stage); if(err < 0) { int console_fd = open("/dev/console", 0); if(console_fd >= 0) { char buf[128]; sprintf(buf, "consoled: error %d at stage %d starting console\n", err, stage); write(console_fd, buf, strlen(buf)); } return err; } // we're a session leader setsid(); // move our stdin and stdout to the console dup2(theconsole.tty_slave_fd, 0); dup2(theconsole.tty_slave_fd, 1); dup2(theconsole.tty_slave_fd, 2); for(;;) { proc_id shell_process; int retcode; char *argv[3]; #if 1 argv[0] = "/boot/bin/shell"; argv[1] = "-s"; argv[2] = "/boot/loginscript"; shell_process = start_process("/boot/bin/shell", "shell", argv, 3, &theconsole); #else argv[0] = "/boot/bin/vmstat"; shell_process = start_process("/boot/bin/vmstat", "vmstat", argv, 1, &theconsole); #endif _kern_proc_wait_on_proc(shell_process, &retcode); } _kern_sem_acquire(theconsole.wait_sem, 1); return 0; }
static cyg_bool _net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch) { if (in_buflen == 0) { __tcp_poll(); if (tcp_sock.state == _CLOSE_WAIT) { // This connection is breaking if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) { __tcp_close(&tcp_sock); return false; } } if (tcp_sock.state == _CLOSED) { // The connection is gone net_io_revert_console(); *ch = '\n'; return true; } in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf)); in_bufp = in_buf; #ifdef DEBUG_TCP if (show_tcp && (in_buflen > 0)) { int old_console; old_console = start_console(); diag_printf("%s:%d\n", __FUNCTION__, __LINE__); diag_dump_buf(in_buf, in_buflen); end_console(old_console); } #endif // DEBUG_TCP } if (in_buflen) { *ch = *in_bufp++; in_buflen--; return true; } else { return false; } }
int main(int argc, char **argv) { char *consoletty, *p; char **dmargv, **xargv, **consoleargv = NULL, **loginargv; char xpidf[256], line[16], buf[256]; fd_set readfds; int pgrp, file, tries, count, redir = TRUE; char dpyacl[40]; Display *dpy; XHostAddress *hosts, localhost; int nhosts, dpynum = 0; struct stat hostsinfo; Bool state; time_t now, last_console_failure = 0; struct sigaction sigact; sigset_t mask; #if defined(SRIOCSREDIR) || defined(TIOCCONS) int on; #endif int fd; int conspipe[2]; XIOErrorHandler xioerror_handler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; (void) sigemptyset(&sig_zero); /* Create a localhost entity for access control purposes. */ localhost.family = FamilyLocalHost; localhost.length = 0; localhost.address = ""; /* * Note about setting environment variables in dm: * * All environment variables passed to dm and set in dm are * subsequently passed to any children of dm. This is usually * true of processes that exec in children, so that's not a * big surprise. * * However, xlogin is one of the children dm forks, and it goes * to lengths to ensure that the environments of users logging in * are ISOLATED from xlogin's own environment. Therefore, do not * expect that setting an environment variable here will reach the * user unless you have gone to lengths to make sure that xlogin * passes it on. Put another way, if you set a new environment * variable here, consider whether or not it should be seen by the * user. If it should, go modify verify.c as well. Consider also * whether the variable should be seen _only_ by the user. If so, * make the change only in xlogin, and not here. * * As an added complication, xlogin _does_ pass environment variables * on to the pre-login options. Therefore, if you set an environment * variable that should _not_ be seen, you must filter it in xlogin.c. * * Confused? Too bad. I'm in a nasty, if verbose, mood this year. * * General summary: * * If you add an environment variable here there are three likely * possibilities: * * 1. It's for the user only, not needed by any of dm's children. * --> Don't set it here. Set it in verify.c for users and in * --> xlogin.c for the pre-login options, if appropriate. * * 2. It's for dm and its children only, and _should not_ be seen * by the user or pre-login options. * --> You must filter the option from the pre-login options * --> in xlogin.c. No changes to verify.c are required. * * 3. It's for dm and the user and the pre-login options. * --> You must pass the option explicitly to the user in * --> verify.c. No changes to xlogin.c are required. * * --- cfields */ #ifdef notdef putenv("LD_LIBRARY_PATH=/usr/openwin/lib"); putenv("OPENWINHOME=/usr/openwin"); #endif if (argc < 2) { fprintf(stderr, "dm: first argument must be configuration file\n"); sleep(60); exit(1); } conf = argv[1]; if (argc != 4 && (argc != 5 || strcmp(argv[3], "-noconsole"))) { fprintf(stderr, "usage: %s configfile logintty [-noconsole] consoletty\n", argv[0]); console_login(conf, NULL); } if (argc == 5) redir = FALSE; /* parse argument lists */ /* ignore argv[2] */ consoletty = argv[argc - 1]; #ifdef SOLARIS /* On Solaris, use the console tty name for the utmp line field, * as the Solaris finger requires an actual device name there. * Elsewhere, we will use the display name (see below). */ utmp_line = consoletty; #endif openlog("dm", 0, LOG_USER); /* We use options from the config file rather than taking * them from the command line because the current command * line form is gross (why???), and I don't see a good way * to extend it without making things grosser or breaking * backwards compatibility. So, we take a line from the * config file and use real parsing. */ p = getconf(conf, "dm"); if (p != NULL) { dmargv = parseargs(p, NULL, NULL, NULL); while (*dmargv) { if (!strcmp(*dmargv, "-display")) { dmargv++; if (*dmargv) { dpynum = atoi(*(dmargv) + 1); dmargv++; } } else dmargv++; } } p = getconf(conf, "X"); if (p == NULL) console_login(conf, "\ndm: Can't find X command line\n"); xargv = parseargs(p, NULL, NULL, NULL); p = getconf(conf, "console"); if (p == NULL) console_login(conf, "\ndm: Can't find console command line\n"); /* We will pass the read side of the pipe created below to console * on descriptor 3. */ consoleargv = parseargs(p, "-inputfd", "3", NULL); /* Signal Setup */ sigact.sa_handler = SIG_IGN; sigaction(SIGTSTP, &sigact, NULL); sigaction(SIGTTIN, &sigact, NULL); sigaction(SIGTTOU, &sigact, NULL); /* so that X pipe errors don't nuke us */ sigaction(SIGPIPE, &sigact, NULL); sigact.sa_handler = shutdown; sigaction(SIGFPE, &sigact, NULL); sigact.sa_handler = die; sigaction(SIGHUP, &sigact, NULL); sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigact.sa_handler = child; sigaction(SIGCHLD, &sigact, NULL); sigact.sa_handler = catchalarm; sigaction(SIGALRM, &sigact, NULL); strcpy(line, "/dev/"); strcat(line, consoletty); fd = open(line, O_RDWR); if (fd == -1) { syslog(LOG_ERR, "Cannot open %s: %m", line); /* This probably won't work, but it seems to be the appropriate punt location. */ console_login(conf, "Cannot open tty.\n"); } if (login_tty(fd) == -1) syslog(LOG_ERR, "Cannot set the console as a login terminal (%s)", strerror(errno)); else { /* Set the console characteristics so we don't lose later */ setpgid(0, pgrp = getpid()); /* Reset the tty pgrp */ if (tcsetpgrp(0, pgrp) == -1) syslog(LOG_ERR, "tcsetpgrp failed for console terminal (%s)", strerror(errno)); } /* save our pid file */ writepid(dmpidf, getpid()); /* Fire up X */ xpid = 0; for (tries = 0; tries < 3; tries++) { syslog(LOG_DEBUG, "Starting X, try #%d", tries + 1); x_running = STARTUP; sigact.sa_handler = xready; sigaction(SIGUSR1, &sigact, NULL); switch (fork_and_store(&xpid)) { case 0: if (fcntl(2, F_SETFD, 1) == -1) close(2); (void) sigprocmask(SIG_SETMASK, &sig_zero, (sigset_t *) 0); /* ignoring SIGUSR1 will cause the server to send us a SIGUSR1 * when it is ready to accept connections */ sigact.sa_handler = SIG_IGN; sigaction(SIGUSR1, &sigact, NULL); p = *xargv; *xargv = "X"; execv(p, xargv); fprintf(stderr, "dm: X server failed exec: %s\n", strerror(errno)); _exit(1); case -1: fprintf(stderr, "dm: Unable to fork to start X server: %s\n", strerror(errno)); break; default: sprintf(xpidf, xpids, dpynum); writepid(xpidf, xpid); if (x_running == STARTUP) { alarm(X_START_WAIT); alarm_running = RUNNING; sigsuspend(&sig_zero); } if (x_running != RUNNING) { syslog(LOG_DEBUG, "X failed to start; alarm_running=%d", alarm_running); if (alarm_running == NONEXISTENT) fprintf(stderr, "dm: Unable to start X\n"); else fprintf(stderr, "dm: X failed to become ready\n"); /* If X wouldn't run, it could be that an existing X * process hasn't shut down. Wait X_STOP_WAIT seconds * for that to happen. */ x_stop_wait(); } sigact.sa_handler = SIG_IGN; sigaction(SIGUSR1, &sigact, NULL); } if (x_running == RUNNING) break; } alarm(0); if (x_running != RUNNING) { syslog(LOG_DEBUG, "Giving up on starting X."); console_login(conf, "\nUnable to start X, doing console login " "instead.\n"); } /* Tighten up security a little bit. Remove all hosts from X's * access control list, assuming /etc/X0.hosts does not exist or * has zero length. If it does exist with nonzero length, this * behavior is not wanted. The desired effect of removing all hosts * is that only connections from the Unix domain socket will be * allowed. * More secure code using Xau also exists, but there wasn't * time to completely flesh it out and resolve a couple of * issues. This code is probably good enough, but we'll see. * Maybe next time. * This code has the added benefit of leaving an X display * connection open, owned by dm. This provides a less-hacky * solution to the config_console problem, where if config_console * is the first program run on user login, it causes the only * X app running at the time, console, to exit, thus resetting * the X server. Thus this code also allows the removal of the * hack in xlogin that attempts to solve the same problem, but * fails on the RS/6000 for reasons unexplored. * P.S. Don't run this code under Solaris 2.2- (2.3 is safe). * Removing all hosts from the acl on that server results in * no connections, not even from the Unix domain socket, being * allowed. --- cfields */ sprintf(dpyacl, xhosts, dpynum); sprintf(dpyname, ":%d", dpynum); #ifndef SOLARIS /* Use the display name for the utmp line field, except on Solaris. */ utmp_line = dpyname; #endif /* Put in our own error handler, open the display, then reset the handler. */ xioerror_handler = XSetIOErrorHandler(handle_xioerror); dpy = XOpenDisplay(dpyname); XSetIOErrorHandler(xioerror_handler); if (dpy != NULL && (stat(dpyacl, &hostsinfo) || hostsinfo.st_size == 0)) { hosts = XListHosts(dpy, &nhosts, &state); if (hosts != NULL) { XRemoveHosts(dpy, hosts, nhosts); XFree(hosts); } XAddHost(dpy, &localhost); XFlush(dpy); } /* else if (dpy == NULL) * Could've sworn the X server was running now. * Follow the original code path. No need introducing new bugs * to this hairy code, just preserve the old behavior as though * this code had never been added. */ /* set up the console pty */ if (openpty(&console_master_fd, &console_slave_fd, NULL, NULL, NULL) == -1) console_login(conf, "Cannot allocate pseudo-terminal\n"); if (redir) { /* Redirect /dev/console output to the pty slave. */ #ifdef SRIOCSREDIR on = open("/dev/console", O_RDONLY); if (on >= 0) { ioctl(on, SRIOCSREDIR, console_slave_fd); close(on); } #else #ifdef TIOCCONS on = 1; ioctl(console_slave_fd, TIOCCONS, &on); #endif #endif } /* Set up the console pipe. */ if (pipe(conspipe) == -1) console_login(conf, "Cannot create pipe for console\n"); /* start up console */ start_console(console_master_fd, conspipe[0], consoleargv); /* Set up to invoke xlogin. */ p = getconf(conf, "login"); if (p == NULL) console_login(conf, "\ndm: Can't find login command line\n"); loginargv = parseargs(p, "-line", utmp_line, NULL); /* Fire up the X login */ for (tries = 0; tries < 3; tries++) { syslog(LOG_DEBUG, "Starting xlogin, try #%d", tries + 1); login_running = STARTUP; sigact.sa_handler = loginready; sigaction(SIGUSR1, &sigact, NULL); switch (fork_and_store(&loginpid)) { case 0: max_fd = sysconf(_SC_OPEN_MAX); for (file = 3; file < max_fd; file++) { if (file != conspipe[1]) close(file); } setsid(); file = open("/dev/null", O_RDONLY); if (file >= 0) { dup2(file, 0); if (file != 0) close(file); } file = conspipe[1]; if (file == -1) file = open("/dev/null", O_WRONLY); if (file >= 0) { if (file != 1) dup2(file, 1); if (file != 2) dup2(file, 2); if (file != 1 && file != 2) close(file); } (void) sigprocmask(SIG_SETMASK, &sig_zero, (sigset_t *) 0); /* ignoring SIGUSR1 will cause xlogin to send us a SIGUSR1 * when it is ready */ sigact.sa_handler = SIG_IGN; sigaction(SIGUSR1, &sigact, NULL); /* dm ignores sigpipe; because of this, all of the children (ie, */ /* the entire session) inherit this unless we fix it now */ sigact.sa_handler = SIG_DFL; sigaction(SIGPIPE, &sigact, NULL); execv(loginargv[0], loginargv); fprintf(stderr, "dm: X login failed exec: %s\n", strerror(errno)); _exit(1); case -1: fprintf(stderr, "dm: Unable to fork to start X login: %s\n", strerror(errno)); break; default: alarm(LOGIN_START_WAIT); alarm_running = RUNNING; while (login_running == STARTUP && alarm_running == RUNNING) sigsuspend(&sig_zero); if (login_running != RUNNING) { syslog(LOG_DEBUG, "xlogin failed to start; alarm_running=%d", alarm_running); kill(loginpid, SIGKILL); if (alarm_running != NONEXISTENT) fprintf(stderr, "dm: Unable to start Xlogin\n"); else fprintf(stderr, "dm: Xlogin failed to become ready\n"); } } if (login_running == RUNNING) break; } sigact.sa_handler = SIG_IGN; sigaction(SIGUSR1, &sigact, NULL); alarm(0); if (login_running != RUNNING) { syslog(LOG_DEBUG, "Giving up on starting xlogin."); console_login(conf, "\nUnable to start xlogin, doing console login " "instead.\n"); } /* main loop. Wait for SIGCHLD, waking up every minute anyway. */ (void) sigemptyset(&sig_cur); (void) sigaddset(&sig_cur, SIGCHLD); (void) sigprocmask(SIG_BLOCK, &sig_cur, NULL); while (1) { /* Wait for something to hapen */ if (console_failed) { /* if no console is running, we must copy bits from the console * (master side of pty) to the real console to appear as black * bar messages. */ FD_ZERO(&readfds); FD_SET(console_master_fd, &readfds); (void) sigprocmask(SIG_SETMASK, &sig_zero, &mask); count = select(console_master_fd + 1, &readfds, NULL, NULL, NULL); (void) sigprocmask(SIG_BLOCK, &mask, NULL); if (count > 0 && FD_ISSET(console_master_fd, &readfds)) { file = read(console_master_fd, buf, sizeof(buf)); if (file != -1) write(1, buf, file); } } else { alarm(60); sigsuspend(&sig_zero); } if (login_running == STARTUP) { (void) sigprocmask(SIG_SETMASK, &sig_zero, NULL); console_login(conf, "\nConsole login requested.\n"); } if (console_running == FAILED) { console_running = NONEXISTENT; time(&now); if (now - last_console_failure <= 3) { /* Give up on console. Set the console characteristics so * we don't lose later. */ syslog(LOG_ERR, "Giving up on the console"); setpgid(0, pgrp = getpid()); /* Reset the tty pgrp */ tcsetpgrp(0, pgrp); console_failed = TRUE; } else last_console_failure = now; } if (console_running == NONEXISTENT && !console_failed) start_console(console_master_fd, conspipe[0], consoleargv); if (login_running == NONEXISTENT || x_running == NONEXISTENT) { syslog(LOG_DEBUG, "login_running=%d, x_running=%d, quitting", login_running, x_running); (void) sigprocmask(SIG_SETMASK, &sig_zero, NULL); cleanup(utmp_line); _exit(0); } } }
void ConsoleReset() { start_console("Console has been reset"); }
int main(int argc, char *argv[]) { const char *cmdline; struct menu *m; int rows, cols; int i; (void)argc; parse_configs(argv + 1); /* * We don't start the console until we have parsed the configuration * file, since the configuration file might impact the console * configuration, e.g. MENU RESOLUTION. */ start_console(); if (getscreensize(1, &rows, &cols)) { /* Unknown screen size? */ rows = 24; cols = 80; } /* Some postprocessing for all menus */ for (m = menu_list; m; m = m->next) { if (!m->mparm[P_WIDTH]) m->mparm[P_WIDTH] = cols; /* If anyone has specified negative parameters, consider them relative to the bottom row of the screen. */ for (i = 0; i < NPARAMS; i++) if (m->mparm[i] < 0) m->mparm[i] = max(m->mparm[i] + rows, 0); } cm = start_menu; if (!cm->nentries) { fputs("Initial menu has no LABEL entries!\n", stdout); return 1; /* Error! */ } for (;;) { local_cursor_enable(true); cmdline = run_menu(); if (clearmenu) clear_screen(); local_cursor_enable(false); printf("\033[?25h\033[%d;1H\033[0m", END_ROW); if (cmdline) { uint32_t type = parse_image_type(cmdline); execute(cmdline, type, false); if (cm->onerror) { type = parse_image_type(cm->onerror); execute(cm->onerror, type, true); } } else { return 0; /* Exit */ } } }
// // This function is called from a hardware driver to indicate that an input // packet has arrived. The routine will set up appropriate network resources // to hold the data and call back into the driver to retrieve the data. // static void eth_drv_recv(struct eth_drv_sc *sc, int total_len) { struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; int sg_len = 0; struct eth_msg *msg; unsigned char *buf; CYGARC_HAL_SAVE_GP(); if ((total_len > MAX_ETH_MSG) || (total_len < 0)) { #ifdef CYGSEM_IO_ETH_DRIVERS_WARN int old_console; old_console = start_console(); diag_printf("%s: packet of %d bytes truncated\n", __FUNCTION__, total_len); end_console(old_console); #endif total_len = MAX_ETH_MSG; } msg = eth_drv_msg_get(ð_msg_free); if (msg) { buf = msg->data; } else { #ifdef CYGSEM_IO_ETH_DRIVERS_WARN int old_console; old_console = start_console(); diag_printf("%s: packet of %d bytes dropped\n", __FUNCTION__, total_len); end_console(old_console); #endif buf = (unsigned char *)0; // Drivers know this means "the bit bucket" } sg_list[0].buf = (CYG_ADDRESS)buf; sg_list[0].len = total_len; sg_len = 1; (sc->funs->recv)(sc, sg_list, sg_len); #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG if (cyg_io_eth_net_debug) { int old_console; old_console = start_console(); diag_printf("Ethernet recv:\n"); if ( buf ) { DIAG_DUMP_BUF_HDR(buf, 14); DIAG_DUMP_BUF_BDY(buf+14, total_len-14); } else diag_printf(" ...NULL buffer.\n"); end_console(old_console); } #endif #ifdef CYGSEM_IO_ETH_DRIVERS_PASS_PACKETS if ((unsigned char *)0 != buf && // Only pass on a packet we actually got! sc->funs->eth_drv_old != (struct eth_drv_funs *)0) { void (*hold_recv)(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len); // See if this packet was for us. If not, pass it upwards // This is a major layering violation!! if (memcmp(&__local_ip_addr, &buf[14+16], 4)) { hold_recv = sc->funs->recv; sc->funs->recv = eth_drv_copy_recv; eth_drv_copy_recv_buf = buf; // This calls into the 'other' driver, giving it a chance to // do something with this data (since it wasn't for us) LOCK_APPLICATION_SCHEDULER(); (sc->funs->eth_drv_old->recv)(sc, total_len); UNLOCK_APPLICATION_SCHEDULER(); sc->funs->recv = hold_recv; } } #endif if (msg) { msg->len = total_len; eth_drv_msg_put(ð_msg_full, msg); #ifdef CYGSEM_IO_ETH_DRIVERS_WARN // there was an else with a dump_buf() here but it's // meaningless; sg_list[0].buf is NULL! #endif } CYGARC_HAL_RESTORE_GP(); }
void eth_drv_write(char *eth_hdr, char *buf, int len) { struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; struct eth_drv_sc *sc = __local_enet_sc; int sg_len = 2; void *dbg = CYGACC_CALL_IF_DBG_DATA(); int old_state; int wait_time = 5; // Timeout before giving up void *eth_drv_old = 0; if (dbg) { sc = (struct eth_drv_sc *)dbg; // Use control from installed driver eth_drv_old = sc->funs->eth_drv_old; if (eth_drv_old == 0) { sc->funs->eth_drv_old = sc->funs->eth_drv; sc->funs->eth_drv = ð_drv_funs; // Substitute stand-alone driver old_state = sc->state; if (!old_state & ETH_DRV_STATE_ACTIVE) { // This interface not fully initialized, do it now (sc->funs->start)(sc, (unsigned char *)&__local_enet_addr, 0); sc->state |= ETH_DRV_STATE_ACTIVE; } } } while (!(sc->funs->can_send)(sc)) { // Give driver a chance to service hardware (sc->funs->poll)(sc); CYGACC_CALL_IF_DELAY_US(2*100000); if (--wait_time <= 0) goto reset_and_out; // Give up on sending packet } sg_list[0].buf = (CYG_ADDRESS)eth_hdr; sg_list[0].len = 14; // FIXME sg_list[1].buf = (CYG_ADDRESS)buf; sg_list[1].len = len; packet_sent = 0; #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG if (cyg_io_eth_net_debug) { int old_console; old_console = start_console(); diag_printf("Ethernet send:\n"); DIAG_DUMP_BUF_HDR(eth_hdr, 14); DIAG_DUMP_BUF_BDY(buf, len); end_console(old_console); } #endif (sc->funs->send)(sc, sg_list, sg_len, len+14, (CYG_ADDRWORD)&packet_sent); wait_time = 50000; while (1) { (sc->funs->poll)(sc); if(packet_sent) break; CYGACC_CALL_IF_DELAY_US(2*10); if (--wait_time <= 0) goto reset_and_out; // Give up on sending packet } reset_and_out: if (dbg) { // if (!old_state & ETH_DRV_STATE_ACTIVE) { // // This interface was not fully initialized, shut it back down // (sc->funs->stop)(sc); // } if (eth_drv_old == 0) { sc->funs->eth_drv = sc->funs->eth_drv_old; sc->funs->eth_drv_old = (struct eth_drv_funs *)0; } } }