/*
 * Cancel the timer 'tp'.  The timer object must have been initialized with
 * init_timer(3) first.  If the timer was not set before, the call is a no-op.
 */
void
cancel_timer(minix_timer_t * tp)
{
	clock_t next_time, prev_time;
	int r, have_timers;

	if (!tmr_is_set(tp))
		return;

	have_timers = tmrs_clrtimer(&timers, tp, &prev_time, &next_time);

	/*
	 * If the earliest timer has been removed, we have to set the alarm to
	 * the next timer, or cancel the alarm altogether if the last timer
	 * has been canceled.
	 */
        if (!expiring) {
		if (!have_timers)
			r = sys_setalarm(0, FALSE /*abs_time*/);
		else if (prev_time != next_time)
			r = sys_setalarm(next_time, TRUE /*abs_time*/);
		else
			r = OK;

		if (r != OK)
                        panic("cancel_timer: couldn't set alarm: %d", r);
        }
}
Пример #2
0
/*****************************************************************************
 *    _ddekit_timer_update                                                   *
 ****************************************************************************/
void _ddekit_timer_update()
{
	lock_timer();

	static myclock_t next_timout;
	if(list.next)
	{
		if(!_ddekit_timer_pending || list.next->exp < next_timout) {
			
			unsigned to = list.next->exp - jiffies;
			
			_ddekit_timer_pending = 1;
			
			if (list.next->exp <= jiffies) {
				DDEBUG_MSG_WARN("Timeout lies in past to %d, now: %d",
					list.next->exp, jiffies);
				to = 1;
			}
			
			sys_setalarm(to, 0 /* REL */);

			DDEBUG_MSG_VERBOSE("requesting alarm for clock tick %d , now %d",
				list.next->exp, jiffies);
		}
		next_timout = list.next->exp;
	}
	unlock_timer(); 
}
Пример #3
0
/*===========================================================================*
 *				flt_alarm				     *
 *===========================================================================*/
clock_t flt_alarm(clock_t dt)
{
	int r;

	if(dt < 0)
		return next_alarm;

	r = sys_setalarm(dt, 0);

	if(r != OK)
		panic("sys_setalarm failed: %d", r);

	if(dt == 0) {
		if(!next_alarm)
			panic("clearing unset alarm: %d", r);
		next_alarm = 0;
	} else {
		if(next_alarm)
			panic("overwriting alarm: %d", r);
		if ((r = getuptime(&next_alarm)) != OK)
			panic("getuptime failed: %d", r);
		next_alarm += dt;
	}

	return next_alarm;
}
Пример #4
0
/*===========================================================================*
 *				vbox_init				     *
 *===========================================================================*/
static int vbox_init(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
	/* Initialize the device. */
	int devind;
	u16_t vid, did;
	struct VMMDevReportGuestInfo *req;
	int r;

	interval = DEFAULT_INTERVAL;
	drift = DEFAULT_DRIFT;

	if (env_argc > 1)
		optset_parse(optset_table, env_argv[1]);

	pci_init();

	r = pci_first_dev(&devind, &vid, &did);

	for (;;) {
		if (r != 1)
			panic("backdoor device not found");

		if (vid == VMMDEV_PCI_VID && did == VMMDEV_PCI_DID)
			break;

		r = pci_next_dev(&devind, &vid, &did);
	}

	pci_reserve(devind);

	port = pci_attr_r32(devind, PCI_BAR) & PCI_BAR_IO_MASK;

	irq = pci_attr_r8(devind, PCI_ILR);
	hook_id = 0;

	if ((r = sys_irqsetpolicy(irq, 0 /* IRQ_REENABLE */, &hook_id)) != OK)
		panic("unable to register IRQ: %d", r);

	if ((r = sys_irqenable(&hook_id)) != OK)
		panic("unable to enable IRQ: %d", r);

	if ((vir_ptr = alloc_contig(VMMDEV_BUF_SIZE, 0, &phys_ptr)) == NULL)
		panic("unable to allocate memory");

	req = (struct VMMDevReportGuestInfo *) vir_ptr;
	req->add_version = VMMDEV_GUEST_VERSION;
	req->os_type = VMMDEV_GUEST_OS_OTHER;

	if ((r = vbox_request(&req->header, phys_ptr,
			VMMDEV_REQ_REPORTGUESTINFO, sizeof(*req))) !=
			VMMDEV_ERR_OK)
		panic("backdoor device not functioning");

	ticks = sys_hz() * interval;

	sys_setalarm(ticks, 0);

	return OK;
}
/*===========================================================================*
 *				init_scheduling				     *
 *===========================================================================*/
void init_scheduling(void)
{
	int r;

	balance_timeout = BALANCE_TIMEOUT * sys_hz();

	if ((r = sys_setalarm(balance_timeout, 0)) != OK)
		panic("sys_setalarm failed: %d", r);
}
Пример #6
0
/*===========================================================================*
 *				pm_expire_timers			     *
 *===========================================================================*/
PUBLIC void pm_expire_timers(clock_t now)
{
	clock_t next_time;

	/* Check for expired timers and possibly reschedule an alarm. */
	tmrs_exptimers(&pm_timers, now, &next_time);
	if (next_time > 0) {
		if (sys_setalarm(next_time, 1) != OK)
			panic(__FILE__, "PM expire timer couldn't set alarm.", NO_NUM);
	}
}
Пример #7
0
/*===========================================================================*
 *				pm_cancel_timer				     *
 *===========================================================================*/
PUBLIC void pm_cancel_timer(timer_t *tp)
{
	clock_t next_time, prev_time;
	prev_time = tmrs_clrtimer(&pm_timers, tp, &next_time);

	/* If the earliest timer has been removed, we have to set the alarm to  
     * the next timer, or cancel the alarm altogether if the last timer has 
     * been cancelled (next_time will be 0 then).
	 */
	if (prev_time < next_time || ! next_time) {
		if (sys_setalarm(next_time, 1) != OK)
			panic(__FILE__, "PM expire timer couldn't set alarm.", NO_NUM);
	}
}
Пример #8
0
/*===========================================================================*
 *                              cancel_timer                                 *
 *===========================================================================*/
void cancel_timer(timer_t *tp)
{
        clock_t next_time, prev_time;
        prev_time = tmrs_clrtimer(&timers, tp, &next_time);

        /* If the earliest timer has been removed, we have to set the alarm to
         * the next timer, or cancel the alarm altogether if the last timer
         * has been cancelled (next_time will be 0 then).
         */
        if (expiring == 0 && (prev_time < next_time || ! next_time)) {
                if (sys_setalarm(next_time, 1) != OK)
                        panic("cancel_timer: couldn't set alarm");
        }
}
Пример #9
0
/*===========================================================================*
 *				init_server                                  *
 *===========================================================================*/
PRIVATE void init_server(void)
{
/* Initialize the reincarnation server. */
  struct sigaction sa;
  struct boot_image *ip;
  int s,t;

  /* Install signal handlers. Ask PM to transform signal into message. */
  sa.sa_handler = SIG_MESS;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  if (sigaction(SIGCHLD,&sa,NULL)<0) panic("RS","sigaction failed", errno);
  if (sigaction(SIGTERM,&sa,NULL)<0) panic("RS","sigaction failed", errno);

  /* Initialize the system process table. Use the boot image from the kernel
   * and the device map from the FS to gather all needed information.
   */
  if ((s = sys_getimage(image)) != OK) 
      panic("RS","warning: couldn't get copy of image table", s);
  if ((s = getsysinfo(FS_PROC_NR, SI_DMAP_TAB, dmap)) < 0)
      panic("RS","warning: couldn't get copy of dmap table", errno);
  
  /* Now initialize the table with the processes in the system image. 
   * Prepend /sbin/ to the binaries so that we can actually find them. 
   */
  for (s=0; s< NR_BOOT_PROCS; s++) {
      ip = &image[s];
      if (ip->proc_nr >= 0) {
          nr_in_use ++;
          rproc[s].r_flags = RS_IN_USE;
          rproc[s].r_proc_nr_e = ip->endpoint;
          rproc[s].r_pid = getnpid(ip->proc_nr);
	  for(t=0; t< NR_DEVICES; t++)
	      if (dmap[t].dmap_driver == ip->proc_nr)
                  rproc[s].r_dev_nr = t;
	  strcpy(rproc[s].r_cmd, "/sbin/");
          strcpy(rproc[s].r_cmd+6, ip->proc_name);
          rproc[s].r_argc = 1;
          rproc[s].r_argv[0] = rproc[s].r_cmd;
          rproc[s].r_argv[1] = NULL;
      }
  }

  /* Set alarm to periodically check driver status. */
  if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
      panic("RS", "couldn't set alarm", s);

}
/* This function in called every N ticks to rebalance the queues. The current
 * scheduler bumps processes down one priority when ever they run out of
 * quantum. This function will find all proccesses that have been bumped down,
 * and pulls them back up. This default policy will soon be changed.
 */
void balance_queues(void)
{
	struct schedproc *rmp;
	int r, proc_nr;

	for (proc_nr=0, rmp=schedproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
		if (rmp->flags & IN_USE) {
			if (rmp->priority > rmp->max_priority) {
				rmp->priority -= 1; /* increase priority */
				schedule_process_local(rmp);
			}
		}
	}

	if ((r = sys_setalarm(balance_timeout, 0)) != OK)
		panic("sys_setalarm failed: %d", r);
}
/*===========================================================================*
 *		            sef_cb_init_restart                              *
 *===========================================================================*/
static int sef_cb_init_restart(int type, sef_init_info_t *info)
{
/* Restart the reincarnation server. */
  int r;
  struct rproc *old_rs_rp, *new_rs_rp;

  assert(info->endpoint == RS_PROC_NR);

  /* Perform default state transfer first. */
  r = SEF_CB_INIT_RESTART_STATEFUL(type, info);
  if(r != OK) {
      printf("SEF_CB_INIT_RESTART_STATEFUL failed: %d\n", r);
      return r;
  }

  /* New RS takes over. */
  old_rs_rp = rproc_ptr[_ENDPOINT_P(RS_PROC_NR)];
  new_rs_rp = rproc_ptr[_ENDPOINT_P(info->old_endpoint)];
  if(rs_verbose)
      printf("RS: %s is the new RS after restart\n", srv_to_string(new_rs_rp));

  /* If an update was in progress, end it. */
  if(SRV_IS_UPDATING(old_rs_rp)) {
      end_update(ERESTART, RS_REPLY);
  }

  /* Update the service into the replica. */
  r = update_service(&old_rs_rp, &new_rs_rp, RS_DONTSWAP, 0);
  if(r != OK) {
      printf("update_service failed: %d\n", r);
      return r;
  }

  /* Initialize the new RS instance. */
  r = init_service(new_rs_rp, SEF_INIT_RESTART, 0);
  if(r != OK) {
      printf("init_service failed: %d\n", r);
      return r;
  }

  /* Reschedule a synchronous alarm for the next period. */
  if (OK != (r=sys_setalarm(RS_DELTA_T, 0)))
      panic("couldn't set alarm: %d", r);

  return OK;
}
Пример #12
0
/*===========================================================================*
 *                              expire_timers                                *
 *===========================================================================*/
void expire_timers(clock_t now)
{
        clock_t next_time;

        /* Check for expired timers. Use a global variable to indicate that
         * watchdog functions are called, so that sys_setalarm() isn't called
         * more often than necessary when set_timer or cancel_timer are called
         * from these watchdog functions. */
        expiring = 1;
        tmrs_exptimers(&timers, now, &next_time);
        expiring = 0;

        /* Reschedule an alarm if necessary. */
        if (next_time > 0) {
                if (sys_setalarm(next_time, 1) != OK)
                        panic("expire_timers: couldn't set alarm");
        }
}
Пример #13
0
/*===========================================================================*
 *                              set_timer                                    *
 *===========================================================================*/
void set_timer(timer_t *tp, int ticks, tmr_func_t watchdog, int arg)
{
        int r;
        clock_t now, prev_time = 0, next_time;

        if ((r = getuptime(&now)) != OK)
                panic("set_timer: couldn't get uptime");

        /* Set timer argument and add timer to the list. */
        tmr_arg(tp)->ta_int = arg;
        prev_time = tmrs_settimer(&timers, tp, now+ticks, watchdog, &next_time);

        /* Reschedule our synchronous alarm if necessary. */
        if (expiring == 0 && (! prev_time || prev_time > next_time)) {
                if (sys_setalarm(next_time, 1) != OK)
                        panic("set_timer: couldn't set alarm");
        }
}
/*
 * Set the timer 'tp' to trigger 'ticks' clock ticks in the future.  When it
 * triggers, call function 'watchdog' with argument 'arg'.  The given timer
 * object must have been initialized with init_timer(3) already.  The given
 * number of ticks must be between 0 and TMRDIFF_MAX inclusive.  A ticks value
 * of zero will cause the alarm to trigger on the next clock tick.  If the
 * timer was already set, it will be canceled first.
 */
void
set_timer(minix_timer_t *tp, clock_t ticks, tmr_func_t watchdog, int arg)
{
	clock_t prev_time, next_time;
	int r, had_timers;

	if (ticks > TMRDIFF_MAX)
		panic("set_timer: ticks value too large: %u", (int)ticks);

	/* Add the timer to the list. */
	had_timers = tmrs_settimer(&timers, tp, getticks() + ticks, watchdog,
	    arg, &prev_time, &next_time);

	/* Reschedule our synchronous alarm if necessary. */
	if (!expiring && (!had_timers || next_time != prev_time)) {
		if ((r = sys_setalarm(next_time, TRUE /*abs_time*/)) != OK)
			panic("set_timer: couldn't set alarm: %d", r);
        }
}
Пример #15
0
/*===========================================================================*
 *				pm_set_timer				     *
 *===========================================================================*/
PUBLIC void pm_set_timer(timer_t *tp, int ticks, tmr_func_t watchdog, int arg)
{
	int r;
	clock_t now, prev_time = 0, next_time;

	if ((r = getuptime(&now)) != OK)
		panic(__FILE__, "PM couldn't get uptime", NO_NUM);

	/* Set timer argument and add timer to the list. */
	tmr_arg(tp)->ta_int = arg;
	prev_time = tmrs_settimer(&pm_timers,tp,now+ticks,watchdog,&next_time);

	/* Reschedule our synchronous alarm if necessary. */
	if (! prev_time || prev_time > next_time) {
		if (sys_setalarm(next_time, 1) != OK)
			panic(__FILE__, "PM set timer couldn't set alarm.", NO_NUM);
	}

	return;
}
/*
 * Expire all timers that were set to expire before/at the given current time.
 */
void
expire_timers(clock_t now)
{
        clock_t next_time;
	int r, have_timers;

	/*
	 * Check for expired timers. Use a global variable to indicate that
	 * watchdog functions are called, so that sys_setalarm() isn't called
	 * more often than necessary when set_timer or cancel_timer are called
	 * from these watchdog functions.
	 */
	expiring = TRUE;
	have_timers = tmrs_exptimers(&timers, now, &next_time);
	expiring = FALSE;

	/* Reschedule an alarm if necessary. */
	if (have_timers) {
		if ((r = sys_setalarm(next_time, TRUE /*abs_time*/)) != OK)
			panic("expire_timers: couldn't set alarm: %d", r);
	}
}
Пример #17
0
/*===========================================================================*
 *				vbox_update_time			     *
 *===========================================================================*/
static void vbox_update_time(void)
{
	/* Update the current time if it has drifted too far. */
	struct VMMDevReqHostTime *req;
	time_t otime, ntime;

	req = (struct VMMDevReqHostTime *) vir_ptr;

	if (vbox_request(&req->header, phys_ptr, VMMDEV_REQ_HOSTTIME,
			sizeof(*req)) == VMMDEV_ERR_OK) {
		time(&otime);				/* old time */

		ntime = (unsigned long)(req->time / 1000);	/* new time */

		/* Make time go forward, if the difference exceeds the drift
		 * threshold. Never make time go backward.
		 */
		if ((int) (ntime - otime) >= drift)
			stime(&ntime);
	}

	sys_setalarm(ticks, 0);
}
Пример #18
0
/*===========================================================================*
 *		            sef_cb_init_fresh                                *
 *===========================================================================*/
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the reincarnation server. */
  struct sigaction sa;
  struct boot_image *ip;
  int s,i,j;
  int nr_image_srvs, nr_image_priv_srvs, nr_uncaught_init_srvs;
  struct rproc *rp;
  struct rprocpub *rpub;
  struct boot_image image[NR_BOOT_PROCS];
  struct mproc mproc[NR_PROCS];
  struct exec header;
  struct boot_image_priv *boot_image_priv;
  struct boot_image_sys *boot_image_sys;
  struct boot_image_dev *boot_image_dev;

  /* See if we run in verbose mode. */
  env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);

  /* Initialize the global init descriptor. */
  rinit.rproctab_gid = cpf_grant_direct(ANY, (vir_bytes) rprocpub,
      sizeof(rprocpub), CPF_READ);
  if(!GRANT_VALID(rinit.rproctab_gid)) {
      panic("RS", "unable to create rprocpub table grant", rinit.rproctab_gid);
  }

  /* Initialize the global update descriptor. */
  rupdate.flags = 0;

  /* Get a copy of the boot image table. */
  if ((s = sys_getimage(image)) != OK) {
      panic("RS", "unable to get copy of boot image table", s);
  }

  /* Determine the number of system services in the boot image table and
   * compute the size required for the boot image buffer.
   */
  nr_image_srvs = 0;
  boot_image_buffer_size = 0;
  for(i=0;i<NR_BOOT_PROCS;i++) {
      ip = &image[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(ip->endpoint))) {
          continue;
      }
      nr_image_srvs++;

      /* Lookup the corresponding entry in the boot image sys table. */
      boot_image_info_lookup(ip->endpoint, image,
          NULL, NULL, &boot_image_sys, NULL);

      /* If we must keep a copy of this system service, read the header
       * and increase the size of the boot image buffer.
       */
      if(boot_image_sys->flags & SF_USE_COPY) {
          if((s = sys_getaoutheader(&header, i)) != OK) {
              panic("RS", "unable to get copy of a.out header", s);
          }
          boot_image_buffer_size += header.a_hdrlen
              + header.a_text + header.a_data;
      }
  }

  /* Determine the number of entries in the boot image priv table and make sure
   * it matches the number of system services in the boot image table.
   */
  nr_image_priv_srvs = 0;
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }
      nr_image_priv_srvs++;
  }
  if(nr_image_srvs != nr_image_priv_srvs) {
      panic("RS", "boot image table and boot image priv table mismatch",
          NO_NUM);
  }

  /* Allocate boot image buffer. */
  if(boot_image_buffer_size > 0) {
      boot_image_buffer = rs_startup_sbrk(boot_image_buffer_size);
      if(boot_image_buffer == (char *) -1) {
          panic("RS", "unable to allocate boot image buffer", NO_NUM);
      }
  }

  /* Reset the system process table. */
  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
      rp->r_flags = 0;
      rp->r_pub = &rprocpub[rp - rproc];
      rp->r_pub->in_use = FALSE;
  }

  /* Initialize the system process table in 4 steps, each of them following
   * the appearance of system services in the boot image priv table.
   * - Step 1: get a copy of the executable image of every system service that
   * requires it while it is not yet running.
   * In addition, set priviliges, sys properties, and dev properties (if any)
   * for every system service.
   */
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }

      /* Lookup the corresponding entries in other tables. */
      boot_image_info_lookup(boot_image_priv->endpoint, image,
          &ip, NULL, &boot_image_sys, &boot_image_dev);
      rp = &rproc[boot_image_priv - boot_image_priv_table];
      rpub = rp->r_pub;

      /*
       * Get a copy of the executable image if required.
       */
      rp->r_exec_len = 0;
      rp->r_exec = NULL;
      if(boot_image_sys->flags & SF_USE_COPY) {
          exec_image_copy(ip - image, ip, rp);
      }

      /*
       * Set privileges.
       */
      /* Get label. */
      strcpy(rpub->label, boot_image_priv->label);

      if(boot_image_priv->endpoint != RS_PROC_NR) {
          /* Force a static priv id for system services in the boot image. */
          rp->r_priv.s_id = static_priv_id(
              _ENDPOINT_P(boot_image_priv->endpoint));

          /* Initialize privilege bitmaps. */
          rp->r_priv.s_flags = boot_image_priv->flags;         /* priv flags */
          rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* traps */
          memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to,
                            sizeof(rp->r_priv.s_ipc_to));      /* targets */

          /* Initialize kernel call mask bitmap from unordered set. */
          fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS,
              rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE);

          /* Set the privilege structure. */
          if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv)))
              != OK) {
              panic("RS", "unable to set privilege structure", s);
          }
      }

      /* Synch the privilege structure with the kernel. */
      if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) {
          panic("RS", "unable to synch privilege structure", s);
      }

      /*
       * Set sys properties.
       */
      rpub->sys_flags = boot_image_sys->flags;        /* sys flags */

      /*
       * Set dev properties.
       */
      rpub->dev_nr = boot_image_dev->dev_nr;          /* major device number */
      rpub->dev_style = boot_image_dev->dev_style;    /* device style */
      rpub->period = boot_image_dev->period;          /* heartbeat period */

      /* Get process name. */
      strcpy(rpub->proc_name, ip->proc_name);

      /* Get command settings. */
      rp->r_cmd[0]= '\0';
      rp->r_argv[0] = rp->r_cmd;
      rp->r_argv[1] = NULL;
      rp->r_argc = 1;
      rp->r_script[0]= '\0';

      /* Initialize vm call mask bitmap from unordered set. */
      fill_call_mask(boot_image_priv->vm_calls, NR_VM_CALLS,
          rpub->vm_call_mask, VM_RQ_BASE, TRUE);

      /* Get some settings from the boot image table. */
      rp->r_nice = ip->priority;
      rpub->endpoint = ip->endpoint;

      /* Set some defaults. */
      rp->r_uid = 0;                           /* root */
      rp->r_check_tm = 0;                      /* not checked yet */
      getuptime(&rp->r_alive_tm);              /* currently alive */
      rp->r_stop_tm = 0;                       /* not exiting yet */
      rp->r_restarts = 0;                      /* no restarts so far */
      rp->r_set_resources = 0;                 /* don't set resources */

      /* Mark as in use. */
      rp->r_flags = RS_IN_USE;
      rproc_ptr[_ENDPOINT_P(rpub->endpoint)]= rp;
      rpub->in_use = TRUE;
  }

  /* - Step 2: allow every system service in the boot image to run.
   */
  nr_uncaught_init_srvs = 0;
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }

      /* Ignore RS. */
      if(boot_image_priv->endpoint == RS_PROC_NR) {
          continue;
      }

      /* Lookup the corresponding slot in the system process table. */
      rp = &rproc[boot_image_priv - boot_image_priv_table];
      rpub = rp->r_pub;

      /* Allow the service to run. */
      if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
          panic("RS", "unable to initialize privileges", s);
      }

      /* Initialize service. We assume every service will always get
       * back to us here at boot time.
       */
      if(boot_image_priv->flags & SYS_PROC) {
          if ((s = init_service(rp, SEF_INIT_FRESH)) != OK) {
              panic("RS", "unable to initialize service", s);
          }
          if(rpub->sys_flags & SF_SYNCH_BOOT) {
              /* Catch init ready message now to synchronize. */
              catch_boot_init_ready(rpub->endpoint);
          }
          else {
              /* Catch init ready message later. */
              nr_uncaught_init_srvs++;
          }
      }
  }

  /* - Step 3: let every system service complete initialization by
   * catching all the init ready messages left.
   */
  while(nr_uncaught_init_srvs) {
      catch_boot_init_ready(ANY);
      nr_uncaught_init_srvs--;
  }

  /* - Step 4: all the system services in the boot image are now running.
   * Complete the initialization of the system process table in collaboration
   * with other system processes.
   */
  if ((s = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc)) != OK) {
      panic("RS", "unable to get copy of PM process table", s);
  }
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }

      /* Lookup the corresponding slot in the system process table. */
      rp = &rproc[boot_image_priv - boot_image_priv_table];
      rpub = rp->r_pub;

      /* Get pid from PM process table. */
      rp->r_pid = NO_PID;
      for (j = 0; j < NR_PROCS; j++) {
          if (mproc[j].mp_endpoint == rpub->endpoint) {
              rp->r_pid = mproc[j].mp_pid;
              break;
          }
      }
      if(j == NR_PROCS) {
          panic("RS", "unable to get pid", NO_NUM);
      }
  }

  /*
   * Now complete RS initialization process in collaboration with other
   * system services.
   */
  /* Let the rest of the system know about our dynamically allocated buffer. */
  if(boot_image_buffer_size > 0) {
      boot_image_buffer = rs_startup_sbrk_synch(boot_image_buffer_size);
      if(boot_image_buffer == (char *) -1) {
          panic("RS", "unable to synch boot image buffer", NO_NUM);
      }
  }

  /* Set alarm to periodically check service status. */
  if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
      panic("RS", "couldn't set alarm", s);

  /* Install signal handlers. Ask PM to transform signal into message. */
  sa.sa_handler = SIG_MESS;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  if (sigaction(SIGCHLD,&sa,NULL)<0) panic("RS","sigaction failed", errno);
  if (sigaction(SIGTERM,&sa,NULL)<0) panic("RS","sigaction failed", errno);

  /* Initialize the exec pipe. */
  if (pipe(exec_pipe) == -1)
	panic("RS", "pipe failed", errno);
  if (fcntl(exec_pipe[0], F_SETFD,
	fcntl(exec_pipe[0], F_GETFD) | FD_CLOEXEC) == -1)
  {
	panic("RS", "fcntl set FD_CLOEXEC on pipe input failed", errno);
  }
  if (fcntl(exec_pipe[1], F_SETFD,
	fcntl(exec_pipe[1], F_GETFD) | FD_CLOEXEC) == -1)
  {
	panic("RS", "fcntl set FD_CLOEXEC on pipe output failed", errno);
  }
  if (fcntl(exec_pipe[0], F_SETFL,
	fcntl(exec_pipe[0], F_GETFL) | O_NONBLOCK) == -1)
  {
	panic("RS", "fcntl set O_NONBLOCK on pipe input failed", errno);
  }

 /* Map out our own text and data. This is normally done in crtso.o
  * but RS is an exception - we don't get to talk to VM so early on.
  * That's why we override munmap() and munmap_text() in utility.c.
  *
  * _minix_unmapzero() is the same code in crtso.o that normally does
  * it on startup. It's best that it's there as crtso.o knows exactly
  * what the ranges are of the filler data.
  */
  unmap_ok = 1;
  _minix_unmapzero();

  return(OK);
}
Пример #19
0
void sys_do_open_midi(int nmidiin, int *midiinvec,
    int nmidiout, int *midioutvec)
{
    int i;
    for (i = 0; i < nmidiout; i++)
        oss_midioutfd[i] = -1;
    for (i = 0, oss_nmidiin = 0; i < nmidiin; i++)
    {
        int fd = -1, j, outdevindex = -1;
        char namebuf[80];
        int devno = midiinvec[i] + oss_onebased;

        for (j = 0; j < nmidiout; j++)
            if (midioutvec[j] == midiinvec[i])
                outdevindex = j;
        
            /* try to open the device for read/write. */
        if (devno == 0 && fd < 0 && outdevindex >= 0)
        {
            sys_setalarm(1000000);
            fd = open("/dev/midi", O_RDWR | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr,
                    "device 1: tried /dev/midi READ/WRITE; returned %d\n", fd);
            if (outdevindex >= 0 && fd >= 0)
                oss_midioutfd[outdevindex] = fd;
        }
        if (fd < 0 && outdevindex >= 0)
        {
            sys_setalarm(1000000);
            sprintf(namebuf, "/dev/midi%2.2d", devno);
            fd = open(namebuf, O_RDWR | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr,
                    "device %d: tried %s READ/WRITE; returned %d\n",
                        devno, namebuf, fd);
            if (outdevindex >= 0 && fd >= 0)
                oss_midioutfd[outdevindex] = fd;
        }
        if (fd < 0 && outdevindex >= 0)
        {
            sys_setalarm(1000000);
            sprintf(namebuf, "/dev/midi%d", devno);
            fd = open(namebuf, O_RDWR | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr, "device %d: tried %s READ/WRITE; returned %d\n",
                    devno, namebuf, fd);
            if (outdevindex >= 0 && fd >= 0)
                oss_midioutfd[outdevindex] = fd;
        }
        if (devno == 0 && fd < 0)
        {
            sys_setalarm(1000000);
            fd = open("/dev/midi", O_RDONLY | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr,
                    "device 1: tried /dev/midi READONLY; returned %d\n", fd);
        }
        if (fd < 0)
        {
            sys_setalarm(1000000);
            sprintf(namebuf, "/dev/midi%2.2d", devno);
            fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
                    devno, namebuf, fd);
        }
        if (fd < 0)
        {
            sys_setalarm(1000000);
            sprintf(namebuf, "/dev/midi%d", devno);
            fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
                    devno, namebuf, fd);
        }
        if (fd >= 0)
            oss_midiinfd[oss_nmidiin++] = fd;       
        else post("couldn't open MIDI input device %d", devno);
    }
    for (i = 0, oss_nmidiout = 0; i < nmidiout; i++)
    {
        int fd = oss_midioutfd[i];
        char namebuf[80];
        int devno = midioutvec[i] + oss_onebased;
        if (devno == 0 && fd < 0)
        {
            sys_setalarm(1000000);
            fd = open("/dev/midi", O_WRONLY | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr,
                    "device 1: tried /dev/midi WRITEONLY; returned %d\n", fd);
        }
        if (fd < 0)
        {
            sys_setalarm(1000000);
            sprintf(namebuf, "/dev/midi%2.2d", devno);
            fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
                    devno, namebuf, fd);
        }
        if (fd < 0)
        {
            sys_setalarm(1000000);
            sprintf(namebuf, "/dev/midi%d", devno);
            fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
            if (sys_verbose)
                fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
                    devno, namebuf, fd);
        }
        if (fd >= 0)
            oss_midioutfd[oss_nmidiout++] = fd;     
        else post("couldn't open MIDI output device %d", devno);
    }

    if (oss_nmidiin < nmidiin || oss_nmidiout < nmidiout || sys_verbose)
        post("opened %d MIDI input device(s) and %d MIDI output device(s).",
            oss_nmidiin, oss_nmidiout);

    sys_setalarm(0);
}
Пример #20
0
/*===========================================================================*
 *		            sef_cb_init_fresh                                *
 *===========================================================================*/
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the reincarnation server. */
  struct boot_image *ip;
  int s,i;
  int nr_image_srvs, nr_image_priv_srvs, nr_uncaught_init_srvs;
  struct rproc *rp;
  struct rproc *replica_rp;
  struct rprocpub *rpub;
  struct boot_image image[NR_BOOT_PROCS];
  struct boot_image_priv *boot_image_priv;
  struct boot_image_sys *boot_image_sys;
  struct boot_image_dev *boot_image_dev;
  int pid, replica_pid;
  endpoint_t replica_endpoint;
  int ipc_to;
  int *calls;
  int all_c[] = { ALL_C, NULL_C };
  int no_c[] = {  NULL_C };

  /* See if we run in verbose mode. */
  env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);

  if ((s = sys_getinfo(GET_HZ, &system_hz, sizeof(system_hz), 0, 0)) != OK)
	  panic("Cannot get system timer frequency\n");

  /* Initialize the global init descriptor. */
  rinit.rproctab_gid = cpf_grant_direct(ANY, (vir_bytes) rprocpub,
      sizeof(rprocpub), CPF_READ);
  if(!GRANT_VALID(rinit.rproctab_gid)) {
      panic("unable to create rprocpub table grant: %d", rinit.rproctab_gid);
  }

  /* Initialize some global variables. */
  rupdate.flags = 0;
  shutting_down = FALSE;

  /* Get a copy of the boot image table. */
  if ((s = sys_getimage(image)) != OK) {
      panic("unable to get copy of boot image table: %d", s);
  }

  /* Determine the number of system services in the boot image table. */
  nr_image_srvs = 0;
  for(i=0;i<NR_BOOT_PROCS;i++) {
      ip = &image[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(ip->endpoint))) {
          continue;
      }
      nr_image_srvs++;
  }

  /* Determine the number of entries in the boot image priv table and make sure
   * it matches the number of system services in the boot image table.
   */
  nr_image_priv_srvs = 0;
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }
      nr_image_priv_srvs++;
  }
  if(nr_image_srvs != nr_image_priv_srvs) {
	panic("boot image table and boot image priv table mismatch");
  }

  /* Reset the system process table. */
  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
      rp->r_flags = 0;
      rp->r_pub = &rprocpub[rp - rproc];
      rp->r_pub->in_use = FALSE;
  }

  /* Initialize the system process table in 4 steps, each of them following
   * the appearance of system services in the boot image priv table.
   * - Step 1: set priviliges, sys properties, and dev properties (if any)
   * for every system service.
   */
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }

      /* Lookup the corresponding entries in other tables. */
      boot_image_info_lookup(boot_image_priv->endpoint, image,
          &ip, NULL, &boot_image_sys, &boot_image_dev);
      rp = &rproc[boot_image_priv - boot_image_priv_table];
      rpub = rp->r_pub;

      /*
       * Set privileges.
       */
      /* Get label. */
      strcpy(rpub->label, boot_image_priv->label);

      /* Force a static priv id for system services in the boot image. */
      rp->r_priv.s_id = static_priv_id(
          _ENDPOINT_P(boot_image_priv->endpoint));
      
      /* Initialize privilege bitmaps and signal manager. */
      rp->r_priv.s_flags = boot_image_priv->flags;          /* priv flags */
      rp->r_priv.s_trap_mask= SRV_OR_USR(rp, SRV_T, USR_T); /* traps */
      ipc_to = SRV_OR_USR(rp, SRV_M, USR_M);                /* targets */
      fill_send_mask(&rp->r_priv.s_ipc_to, ipc_to == ALL_M);
      rp->r_priv.s_sig_mgr= SRV_OR_USR(rp, SRV_SM, USR_SM); /* sig mgr */
      rp->r_priv.s_bak_sig_mgr = NONE;                      /* backup sig mgr */
      
      /* Initialize kernel call mask bitmap. */
      calls = SRV_OR_USR(rp, SRV_KC, USR_KC) == ALL_C ? all_c : no_c;
      fill_call_mask(calls, NR_SYS_CALLS,
          rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE);

      /* Set the privilege structure. */
      if(boot_image_priv->endpoint != RS_PROC_NR) {
          if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv)))
              != OK) {
              panic("unable to set privilege structure: %d", s);
          }
      }

      /* Synch the privilege structure with the kernel. */
      if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) {
          panic("unable to synch privilege structure: %d", s);
      }

      /*
       * Set sys properties.
       */
      rpub->sys_flags = boot_image_sys->flags;        /* sys flags */

      /*
       * Set dev properties.
       */
      rpub->dev_flags = boot_image_dev->flags;        /* device flags */
      rpub->dev_nr = boot_image_dev->dev_nr;          /* major device number */
      rpub->dev_style = boot_image_dev->dev_style;    /* device style */
      rpub->dev_style2 = boot_image_dev->dev_style2;  /* device style 2 */

      /* Get process name. */
      strcpy(rpub->proc_name, ip->proc_name);

      /* Build command settings. */
      rp->r_cmd[0]= '\0';
      rp->r_script[0]= '\0';
      build_cmd_dep(rp);

      /* Initialize vm call mask bitmap. */
      calls = SRV_OR_USR(rp, SRV_VC, USR_VC) == ALL_C ? all_c : no_c;
      fill_call_mask(calls, NR_VM_CALLS, rpub->vm_call_mask, VM_RQ_BASE, TRUE);

      /* Scheduling parameters. */
      rp->r_scheduler = SRV_OR_USR(rp, SRV_SCH, USR_SCH);
      rp->r_priority = SRV_OR_USR(rp, SRV_Q, USR_Q);
      rp->r_quantum = SRV_OR_USR(rp, SRV_QT, USR_QT);

      /* Get some settings from the boot image table. */
      rpub->endpoint = ip->endpoint;

      /* Set some defaults. */
      rp->r_old_rp = NULL;                     /* no old version yet */
      rp->r_new_rp = NULL;                     /* no new version yet */
      rp->r_prev_rp = NULL;                    /* no prev replica yet */
      rp->r_next_rp = NULL;                    /* no next replica yet */
      rp->r_uid = 0;                           /* root */
      rp->r_check_tm = 0;                      /* not checked yet */
      getuptime(&rp->r_alive_tm);              /* currently alive */
      rp->r_stop_tm = 0;                       /* not exiting yet */
      rp->r_restarts = 0;                      /* no restarts so far */
      rp->r_period = 0;                        /* no period yet */
      rp->r_exec = NULL;                       /* no in-memory copy yet */
      rp->r_exec_len = 0;

      /* Mark as in use and active. */
      rp->r_flags = RS_IN_USE | RS_ACTIVE;
      rproc_ptr[_ENDPOINT_P(rpub->endpoint)]= rp;
      rpub->in_use = TRUE;
  }

  /* - Step 2: allow every system service in the boot image to run. */
  nr_uncaught_init_srvs = 0;
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }

      /* Lookup the corresponding slot in the system process table. */
      rp = &rproc[boot_image_priv - boot_image_priv_table];
      rpub = rp->r_pub;

      /* RS is already running as we speak. */
      if(boot_image_priv->endpoint == RS_PROC_NR) {
          if ((s = init_service(rp, SEF_INIT_FRESH)) != OK) {
              panic("unable to initialize RS: %d", s);
          }
          continue;
      }

      /* Allow the service to run. */
      if ((s = sched_init_proc(rp)) != OK) {
          panic("unable to initialize scheduling: %d", s);
      }
      if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
          panic("unable to initialize privileges: %d", s);
      }

      /* Initialize service. We assume every service will always get
       * back to us here at boot time.
       */
      if(boot_image_priv->flags & SYS_PROC) {
          if ((s = init_service(rp, SEF_INIT_FRESH)) != OK) {
              panic("unable to initialize service: %d", s);
          }
          if(rpub->sys_flags & SF_SYNCH_BOOT) {
              /* Catch init ready message now to synchronize. */
              catch_boot_init_ready(rpub->endpoint);
          }
          else {
              /* Catch init ready message later. */
              nr_uncaught_init_srvs++;
          }
      }
  }

  /* - Step 3: let every system service complete initialization by
   * catching all the init ready messages left.
   */
  while(nr_uncaught_init_srvs) {
      catch_boot_init_ready(ANY);
      nr_uncaught_init_srvs--;
  }

  /* - Step 4: all the system services in the boot image are now running.
   * Complete the initialization of the system process table in collaboration
   * with other system services.
   */
  for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
      boot_image_priv = &boot_image_priv_table[i];

      /* System services only. */
      if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
          continue;
      }

      /* Lookup the corresponding slot in the system process table. */
      rp = &rproc[boot_image_priv - boot_image_priv_table];
      rpub = rp->r_pub;

      /* Get pid from PM. */
      rp->r_pid = getnpid(rpub->endpoint);
      if(rp->r_pid == -1) {
          panic("unable to get pid");
      }
  }

  /* Set alarm to periodically check service status. */
  if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
      panic("couldn't set alarm: %d", s);

  /* Now create a new RS instance with a private page table and let the current
   * instance live update into the replica. Clone RS' own slot first.
   */
  rp = rproc_ptr[_ENDPOINT_P(RS_PROC_NR)];
  if((s = clone_slot(rp, &replica_rp)) != OK) {
      panic("unable to clone current RS instance: %d", s);
  }

  /* Fork a new RS instance. */
  pid = srv_fork();
  if(pid == -1) {
      panic("unable to fork a new RS instance");
  }
  replica_pid = pid ? pid : getpid();
  replica_endpoint = getnprocnr(replica_pid);
  replica_rp->r_pid = replica_pid;
  replica_rp->r_pub->endpoint = replica_endpoint;

  if(pid == 0) {
      /* New RS instance running. */

      /* Live update the old instance into the new one. */
      s = update_service(&rp, &replica_rp, RS_SWAP);
      if(s != OK) {
          panic("unable to live update RS: %d", s);
      }
      cpf_reload();

      /* Clean up the old RS instance, the new instance will take over. */
      cleanup_service(rp);

      /* Map out our own text and data. */
      unmap_ok = 1;
      _minix_unmapzero();

      /* Ask VM to pin memory for the new RS instance. */
      if((s = vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN)) != OK) {
          panic("unable to pin memory for the new RS instance: %d", s);
      }
  }
  else {
      /* Old RS instance running. */

      /* Set up privileges for the new instance and let it run. */
      s = sys_privctl(replica_endpoint, SYS_PRIV_SET_SYS, &(replica_rp->r_priv));
      if(s != OK) {
          panic("unable to set privileges for the new RS instance: %d", s);
      }
      if ((s = sched_init_proc(replica_rp)) != OK) {
          panic("unable to initialize RS replica scheduling: %d", s);
      }
      s = sys_privctl(replica_endpoint, SYS_PRIV_YIELD, NULL);
      if(s != OK) {
          panic("unable to yield control to the new RS instance: %d", s);
      }
      NOT_REACHABLE;
  }

  return(OK);
}
Пример #21
0
void sys_alsa_do_open_midi(int nmidiin, int *midiinvec,
    int nmidiout, int *midioutvec)
{

    char portname[50];
    int err = 0;
    int client;
    int i;
    snd_seq_client_info_t *alsainfo;

    alsa_nmidiin = 0;
    alsa_nmidiout = 0;

    if (nmidiout == 0 && nmidiin == 0) return;

    if(nmidiin>MAXMIDIINDEV )
      {
        post("midi input ports reduced to maximum %d", MAXMIDIINDEV);
        nmidiin=MAXMIDIINDEV;
      }
    if(nmidiout>MAXMIDIOUTDEV)
      {
        post("midi output ports reduced to maximum %d", MAXMIDIOUTDEV);
        nmidiout=MAXMIDIOUTDEV;
      }

    if (nmidiin>0 && nmidiout>0)
        err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0);
    else if (nmidiin > 0)
        err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0);
    else if (nmidiout > 0)
        err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0);
    
    if (err!=0)
    {
            sys_setalarm(1000000);
            post("couldn't open alsa sequencer");
            return;
    }
    for (i=0;i<nmidiin;i++)
    {
        int port;
        sprintf(portname,"Pure Data Midi-In %d",i+1);
        port = snd_seq_create_simple_port(midi_handle,portname,
                                          SND_SEQ_PORT_CAP_WRITE |SND_SEQ_PORT_CAP_SUBS_WRITE, 
                                          SND_SEQ_PORT_TYPE_APPLICATION);
        alsa_midiinfd[i] = port;        
        if (port < 0) goto error;        
    }

    for (i=0;i<nmidiout;i++)
    {
        int port;
        sprintf(portname,"Pure Data Midi-Out %d",i+1);
        port = snd_seq_create_simple_port(midi_handle,portname,
                                          SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, 
                                          SND_SEQ_PORT_TYPE_APPLICATION);
        alsa_midioutfd[i] = port;       
        if (port < 0) goto error;        
    }
   
    snd_seq_client_info_malloc(&alsainfo);
    snd_seq_get_client_info(midi_handle,alsainfo);
    snd_seq_client_info_set_name(alsainfo,"Pure Data");
    client = snd_seq_client_info_get_client(alsainfo);
    snd_seq_set_client_info(midi_handle,alsainfo);
    snd_seq_client_info_free(alsainfo);
    post("Opened Alsa Client %d in:%d out:%d",client,nmidiin,nmidiout);
    sys_setalarm(0);
    snd_midi_event_new(ALSA_MAX_EVENT_SIZE,&midiev);
    alsa_nmidiout = nmidiout;
    alsa_nmidiin = nmidiin;

    return;
 error:
    sys_setalarm(1000000);
    post("couldn't open alsa MIDI output device");
    return;
}
void sys_do_open_midi(int nmidiin, int *midiinvec,
    int nmidiout, int *midioutvec)
{
    int i;
    for (i = 0; i < nmidiout; i++)
        oss_midioutfd[i] = -1;
    for (i = 0, oss_nmidiin = 0; i < nmidiin; i++)
    {
        int fd = -1, j, outdevindex = -1;
        char namebuf[80];
        int devno = midiinvec[i];
        if (devno < 0 || devno >= oss_nmidiindevs)
            continue;
        for (j = 0; j < nmidiout; j++)
            if (midioutvec[j] >= 0 && midioutvec[j] <= oss_nmidioutdevs
                && !strcmp(oss_outdevnames[midioutvec[j]],
                oss_indevnames[devno]))
                    outdevindex = j;

        sprintf(namebuf, "/dev/midi%s", oss_indevnames[devno]);

            /* try to open the device for read/write. */
        if (outdevindex >= 0)
        {
            sys_setalarm(1000000);
            fd = open(namebuf, O_RDWR | O_MIDIFLAG);
            if (sys_verbose)
                post("tried to open %s read/write; got %d\n",
                    namebuf, fd);
            if (outdevindex >= 0 && fd >= 0)
                oss_midioutfd[outdevindex] = fd;
        }
            /* OK, try read-only */
        if (fd < 0)
        {
            sys_setalarm(1000000);
            fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
            if (sys_verbose)
                post("tried to open %s read-only; got %d\n",
                    namebuf, fd);
        }
        if (fd >= 0)
            oss_midiinfd[oss_nmidiin++] = fd;       
        else post("couldn't open MIDI input device %s", namebuf);
    }
    for (i = 0, oss_nmidiout = 0; i < nmidiout; i++)
    {
        int fd = oss_midioutfd[i];
        char namebuf[80];
        int devno = midioutvec[i];
        if (devno < 0 || devno >= oss_nmidioutdevs)
            continue;
        sprintf(namebuf, "/dev/midi%s", oss_outdevnames[devno]);
        if (fd < 0)
        {
            sys_setalarm(1000000);
            fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
            if (sys_verbose)
                post("tried to open %s write-only; got %d\n",
                    namebuf, fd);
        }
        if (fd >= 0)
            oss_midioutfd[oss_nmidiout++] = fd;     
        else post("couldn't open MIDI output device %s", namebuf);
    }

    if (oss_nmidiin < nmidiin || oss_nmidiout < nmidiout || sys_verbose)
        post("opened %d MIDI input device(s) and %d MIDI output device(s).",
            oss_nmidiin, oss_nmidiout);

    sys_setalarm(0);
}
Пример #23
0
/*===========================================================================*
 *				w_intr_wait				     *
 *===========================================================================*/
static int
intr_wait(int mask)
{
	long v;
#ifdef USE_INTR
	if (sys_irqenable(&hook_id) != OK)
		printf("Failed to enable irqenable irq\n");
	/* Wait for a task completion interrupt. */
	message m;
	int ipc_status;
	int ticks = SANE_TIMEOUT * sys_hz() / 1000000;

	if (ticks <= 0)
		ticks = 1;
	while (1) {
		int rr;
		sys_setalarm(ticks, 0);
		if ((rr = driver_receive(ANY, &m, &ipc_status)) != OK) {
			panic("driver_receive failed: %d", rr);
		};
		if (is_ipc_notify(ipc_status)) {
			switch (_ENDPOINT_P(m.m_source)) {
			case CLOCK:
				/* Timeout. */
				// w_timeout(); /* a.o. set w_status */
				mmc_log_warn(&log, "TIMEOUT\n");
				return 1;
				break;
			case HARDWARE:
				v = read32(base_address + MMCHS_SD_STAT);
				if (v & mask) {
					sys_setalarm(0, 0);
					return 0;
				} else if (v & (1 << 15)) {
					return 1;	/* error */
				} else {
					mmc_log_debug(&log,
					    "unexpected HW interrupt 0x%08x mask 0X%08x\n",
					    v, mask);
					if (sys_irqenable(&hook_id) != OK)
						printf
						    ("Failed to re-enable irqenable irq\n");
					continue;
					// return 1;
				}
			default:
				/* 
				 * unhandled message.  queue it and
				 * handle it in the blockdriver loop.
				 */
				blockdriver_mq_queue(&m, ipc_status);
			}
		} else {
			mmc_log_debug(&log, "Other\n");
			/* 
			 * unhandled message.  queue it and handle it in the
			 * blockdriver loop.
			 */
			blockdriver_mq_queue(&m, ipc_status);
		}
	}
	sys_setalarm(0, 0);	/* cancel the alarm */

#else
	spin_t spin;
	spin_init(&spin, SANE_TIMEOUT);
	/* Wait for completion */
	int counter = 0;
	while (1 == 1) {
		counter++;
		v = read32(base_address + MMCHS_SD_STAT);
		if (spin_check(&spin) == FALSE) {
			mmc_log_warn(&log,
			    "Timeout waiting for interrupt (%d) value 0x%08x mask 0x%08x\n",
			    counter, v, mask);
			return 1;
		}
		if (v & mask) {
			return 0;
		} else if (v & 0xFF00) {
			mmc_log_debug(&log,
			    "unexpected HW interrupt (%d) 0x%08x mask 0x%08x\n",
			    v, mask);
			return 1;
		}
	}
	return 1;		/* unreached */
#endif /* USE_INTR */
}