示例#1
0
文件: net_io.c 项目: perryhg/terkos
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);
    }
}
示例#2
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();
}
示例#3
0
文件: net_io.c 项目: perryhg/terkos
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
}
示例#4
0
文件: main.c 项目: travisg/newos
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;
}
示例#5
0
文件: net_io.c 项目: perryhg/terkos
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;
    }
}
示例#6
0
文件: dm.c 项目: mit-athena/dm
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);
	}
    }
}
示例#7
0
文件: kbd.c 项目: Earlz/ancientstuff
void ConsoleReset() {
    start_console("Console has been reset");
}
示例#8
0
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 */
	}
    }
}
示例#9
0
//
// 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(&eth_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(&eth_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();
}
示例#10
0
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 = &eth_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;
        }
    }
}