Beispiel #1
0
/*
 * Timer interrupt handler.
 * Should be called (and return) with interrupts disabled.
 */
void
linux_timer_intr()
{
	unsigned long mask;
	struct timer_struct *tp;

	osenv_assert(osenv_intr_enabled() == 0);

	for (mask = 1, tp = timer_table; mask; tp++, mask += mask) {
		if (mask > timer_active)
			break;
		if (!(mask & timer_active))
			continue;
		if (tp->expires > jiffies)
			continue;
		mark_bh(TIMER_BH);
	}
	if (timer_head.next->expires <= jiffies)
		mark_bh(TIMER_BH);

	if (tq_timer)
		mark_bh(TQUEUE_BH);

	/* If any linux software handlers pending, schedule a softirq */
	if (bh_mask & bh_active)
		osenv_softirq_schedule(softintr_vector);

	osenv_assert(osenv_intr_enabled() == 0);
}
Beispiel #2
0
static oskit_error_t
recv(void *param, oskit_bufio_t *b, oskit_size_t pkt_size)
{
	oskit_pd_t *pd = (oskit_pd_t *)param;
	oskit_netio_t *netio;
	oskit_s32_t fid;
	oskit_s32_t err;
	char *pkt;

	osenv_assert(param);
	osenv_assert(b);

	err = oskit_bufio_map(b, (void **)&pkt, 0, pkt_size);
	if (err) {
		return OSKIT_E_UNEXPECTED;
	}

	switch (pd->ft) {
	case OSKIT_PD_FILTER_DPF_INTERP:
		fid = oskit_dpf_iptr(pkt, pkt_size);
		break;
	default:
		return OSKIT_E_NOTIMPL;
	}

	if (fid != 0) {
		netio = (oskit_netio_t *)hashtab_search(pd->ht, (hashtab_key_t)fid);
		osenv_assert(netio);
		oskit_netio_push(netio, b, pkt_size);
	} else {
		oskit_netio_push(pd->default_netio, b, pkt_size);
	}
	
	return 0;
}
Beispiel #3
0
oskit_s32_t
oskit_packet_dispatcher_register(oskit_pd_t *pd,
				 oskit_s32_t *pfid, 
				 oskit_netio_t *out_netio,
				 void *pdescr,
				 oskit_s32_t sz)
{
	oskit_s32_t hterr;

	osenv_assert(pd);
	osenv_assert(pfid);
	osenv_assert(out_netio);
	osenv_assert(pdescr);

	switch (pd->ft) {
	case OSKIT_PD_FILTER_DPF_INTERP:
		*pfid = oskit_dpf_insert(pdescr, sz);
		osenv_assert(*pfid);
		break;
	default:
		return OSKIT_E_NOTIMPL;
	}


	hterr = hashtab_insert(pd->ht, (hashtab_key_t) *pfid, 
                               (hashtab_datum_t)out_netio);
	if (hterr != HASHTAB_SUCCESS) {
		oskit_dpf_delete(*pfid);
		*pfid = 0;
		return OSKIT_E_UNEXPECTED;
	}
     
	return 0;
}
Beispiel #4
0
oskit_s32_t
oskit_packet_dispatcher_create(oskit_pd_t **ppd,
			       oskit_u32_t ft,
	                       oskit_netio_t **push_netio,
			       oskit_netio_t *default_outgoing)
{
	oskit_netio_t *pnetio;
	oskit_pd_t *pd;
	oskit_s32_t err;

	osenv_assert(ppd);
	osenv_assert(push_netio);
	osenv_assert(default_outgoing);

	/* create a new oskit_pd_t struct. */
	if ((*ppd = (oskit_pd_t *)malloc(sizeof *pd)) == NULL) {
		return OSKIT_ENOMEM;
	}
	pd = *ppd; /* for tidiness */

	/* create the PID table */
	if ((pd->ht = hashtab_create(hashfunc, keycmpfunc, HASHTAB_SIZE)) == NULL) {
		err = OSKIT_ENOMEM;
		goto error;
	}		

	pd->default_netio = default_outgoing;
	pd->ft = ft;

	/*
	 * Set up the filter netio.
	 * Probably all types will use this same code.
	 */
	switch (ft) {
	case OSKIT_PD_FILTER_DPF_INTERP:
		pnetio = oskit_netio_create_cleanup(recv, pd, cleanup);
		if (!pnetio) {
			err = OSKIT_E_UNEXPECTED;
			goto error;
		}
		*push_netio = pnetio;
		break;
	default:
		err = OSKIT_E_NOTIMPL;
		goto error;
	}
	
	return 0;

error:
	*ppd = 0;
	free(*ppd);
	return err;
}
Beispiel #5
0
oskit_error_t
osenv_driver_unregister(oskit_driver_t *driver,
		       const struct oskit_guid *iids, unsigned iid_count)
{
	oskit_error_t rc;
	int i;

#ifdef KNIT
	osenv_assert(driver_registry);
#endif

	/* Unregister the basic driver interface */
	oskit_services_remservice(driver_registry, &oskit_driver_iid, driver);

	/* Unregister the other supported interfaces */
	for (i = 0; i < iid_count; i++) {
		oskit_iunknown_t *iu;
		rc = driver->ops->query(driver, &iids[i], (void**)&iu);
		if (rc)
			return rc;
		rc = oskit_services_remservice(driver_registry, &iids[i], iu);
		if (rc)
			return rc;
		iu->ops->release(iu);
	}

	return 0;
}
Beispiel #6
0
void
osenv_wakeup(osenv_sleeprec_t *sr, int wakeup_status) 
{
	osenv_assert(sr);
	sr->data[0] = (void *)wakeup_status;
	sr->data[1] = (void *)0;
}
Beispiel #7
0
void
osenv_sleep_init(osenv_sleeprec_t *sr) 
{
	osenv_assert(sr);

	sr->data[0] = OSENV_SLEEP_WAKEUP;   /* Return code for osenv_sleep() */
	sr->data[1] = sr;	   /* Just a flag; anything non-null will do */
}
Beispiel #8
0
void
osenv_wakeup(osenv_sleeprec_t *sr, int wakeup_status) 
{
	osenv_assert(sr);
	printf("inside osenv_sleep\n");
	panic("inside wakeup\n");
	sr->data[0] = (void *)wakeup_status;
	sr->data[1] = (void *)0;
}
Beispiel #9
0
oskit_error_t
osenv_rootbus_addchild(oskit_device_t *dev)
{
	struct node *n, *nn;
	oskit_devinfo_t info;
	oskit_error_t err;
	int pos_n;

	/* XXX check already present */

	/*
	 * Find the device's short name;
	 * we'll use that to generate the position string.
	 */
	err = oskit_device_getinfo(dev, &info);
	if (err)
		return err;

	/* Create a new device node */
	n = osenv_mem_alloc(sizeof(*n), OSENV_PHYS_WIRED, 0);
	if (n == NULL)
		return OSKIT_E_OUTOFMEMORY;
	n->next = nodes; nodes = n;
	n->dev = dev; oskit_device_addref(dev);

	/*
	 * Produce a unique position string for this device node.
	 * If there are multiple nodes with the same name,
	 * tack on an integer to make them unique.
	 */
	osenv_assert(OSKIT_DEVNAME_MAX < OSKIT_BUS_POS_MAX);
	osenv_assert(strlen(info.name) <= OSKIT_DEVNAME_MAX);
	pos_n = 0;
	strcpy(n->pos, info.name);
	retry:
	for (nn = n->next; nn; nn = nn->next) {
		if (strcmp(n->pos, nn->pos) == 0) {
			sprintf(n->pos, "%s%d", info.name, ++pos_n);
			goto retry;
		}
	}

	return 0;
}
Beispiel #10
0
oskit_error_t
osenv_driver_lookup(const struct oskit_guid *iid, void ***out_interface_array)
{
#ifdef KNIT
	osenv_assert(driver_registry);
#endif

	return oskit_services_lookup(driver_registry,
				     iid, out_interface_array);
}
Beispiel #11
0
/*
 * Timer software interrupt handler.
 * Should be called (and return) with interrupts enabled.
 */
void
timer_bh()
{
	unsigned long mask;
	struct timer_struct *tp;
	struct timer_list * timer;

	osenv_assert(osenv_intr_enabled() != 0);

	linux_cli();

	while ((timer = timer_head.next) != &timer_head
	       && timer->expires <= jiffies) {
		void (*fn)(unsigned long) = timer->function;
		unsigned long data = timer->data;

		timer->next->prev = timer->prev;
		timer->prev->next = timer->next;
		timer->next = timer->prev = NULL;
		linux_sti();
		fn(data);
		linux_cli();
	}
	linux_sti();

	for (mask = 1, tp = timer_table; mask; tp++, mask <<= 1) {
		if (mask > timer_active)
			break;
		if ((mask & timer_active)
		    && tp->expires > jiffies) {
			timer_active &= ~mask;
			(*tp->fn)();
			linux_sti();
		}
	}

	osenv_assert(osenv_intr_enabled() != 0);
}
Beispiel #12
0
int
osenv_sleep(osenv_sleeprec_t *sr) 
{
	volatile osenv_sleeprec_t *vsr = sr;
	int was_enabled = osenv_intr_enabled();
	printf("inside osenv_sleep\n");
	osenv_assert(sr);

	/* We won't get anywhere if interrupts aren't enabled! */
	osenv_intr_enable();

	/* Busy-wait until osenv_wakeup() clears the flag in the sleeprec */
	while (vsr->data[1])
		/* NOTHING */;

	/* Restore the original interrupt enable state */
	if (!was_enabled)
		osenv_intr_disable();

	return (int) vsr->data[0];
}
Beispiel #13
0
oskit_s32_t
oskit_packet_dispatcher_delete(oskit_pd_t *pd,
			       oskit_s32_t fid)
{
	oskit_s32_t hterr;

	osenv_assert(pd);

	switch (pd->ft) {
	case OSKIT_PD_FILTER_DPF_INTERP:
		oskit_dpf_delete(fid);
		break;
	default:
		return OSKIT_E_NOTIMPL;
	}

	hterr = hashtab_remove(pd->ht, (hashtab_key_t) fid, hashremove, 0);
	if (hterr != HASHTAB_SUCCESS) {
		return OSKIT_E_UNEXPECTED;
	}
	
	return 0;
}
Beispiel #14
0
/*
 * Open a Linux block device given its Linux device number.
 * The gendisk parameter need only be non-NULL if opening a partition;
 * it can be NULL when opening the entire disk ("partition 0").
 */
oskit_error_t
oskit_linux_block_open_kdev(int kdev, struct gendisk *gd,
		     unsigned flags, oskit_blkio_t **out_io)
{
	int err, i, mode;
	struct file file;
	struct peropen *po;
	struct task_struct ts;

	OSKIT_LINUX_CREATE_CURRENT(ts);

	if (flags & ~OSKIT_DEV_OPEN_ALL) {
		err = OSKIT_E_DEV_BADPARAM;
		goto finish;
	}

	switch (flags & (OSKIT_DEV_OPEN_READ|OSKIT_DEV_OPEN_WRITE)) {

	case OSKIT_DEV_OPEN_READ:
		mode = O_RDONLY;
		break;

	case OSKIT_DEV_OPEN_WRITE:
		mode = O_WRONLY;
		break;

	case OSKIT_DEV_OPEN_READ|OSKIT_DEV_OPEN_WRITE:
		mode = O_RDWR;
		break;

	default:
		err = OSKIT_E_DEV_BADPARAM;
		goto finish;
	}

	/*
	 * Linux uses 1k blocks by default.
	 * We WANT sector-sized blocks in all cases.
	 */
	if (!hardsect_size[MAJOR(kdev)]) {
		osenv_log(OSENV_LOG_DEBUG,
			"default sector size = 512b on %d,%d\n",
			MAJOR(kdev), MINOR(kdev));
		blksize_size[MAJOR(kdev)][MINOR(kdev)] = 512;

	} else if (blksize_size[MAJOR(kdev)][MINOR(kdev)]!=
	    hardsect_size[MAJOR(kdev)][MINOR(kdev)]) {
		osenv_log(OSENV_LOG_DEBUG,
			"setting block size to sector size on %d,%d\n",
			MAJOR(kdev), MINOR(kdev));
		blksize_size[MAJOR(kdev)][MINOR(kdev)] =
		    hardsect_size[MAJOR(kdev)][MINOR(kdev)];

		/* this is a Linux limitation: */
		if (hardsect_size[MAJOR(kdev)][MINOR(kdev)] < 512) {
			err = OSKIT_E_DEV_BADOP;	/* XXX */
			goto finish;
		}
	}

	/*
	 * Search the open list.
	 */
	while (1) {
		for (po = open_list; po; po = po->next)
			if (po->inode.i_rdev == kdev && po->mode == mode)
				break;
		if (po) {
			if (po->busy) {
				po->want = 1;
				sleep_on(&po->waitq);
				continue;
			}
			po->count++;
			*out_io = &po->ioi;
			err = 0;
			goto finish;
		}
		break;
	}

	/*
	 * Allocate and initialize a device structure.
	 */
	po = oskit_linux_mem_alloc(sizeof(struct peropen),
				  OSENV_PHYS_WIRED, 0);
	if (!po) {
		err = OSKIT_E_OUTOFMEMORY;
		goto finish;
	}
	po->ioi.ops = &block_io_ops;
	po->fops = blkdevs[MAJOR(kdev)].fops;
	po->count = 1;
	po->busy = 1;
	po->want = 0;
	po->mode = mode;
	init_waitqueue(&po->waitq);

	po->inode.i_rdev = kdev;

	po->inode.i_emul_data = po;

	po->next = open_list;
	open_list = po->next;

	if (!po->fops->open)
		err = 0;
	else {
		struct dentry dentry;
		file.f_mode = mode;
		file.f_flags = 0;
		file.f_dentry = &dentry;
		dentry.d_inode = &po->inode;

		err = (*po->fops->open)(&po->inode, &file);
	}

	if (err) {
		open_list_remove(po);
		if (po->want) {
			po->want = 0;
			wake_up(&po->waitq);
		}
		err = linux_to_oskit_error(err);
		oskit_linux_mem_free(po, OSENV_PHYS_WIRED,
				    sizeof(struct peropen));
	} else {
		/*
		 * Now that the device has been opened,
		 * we can extract its size.  This might
		 * not have been set properly in blk_size
		 * before the open call, e.g. for the floppy driver.
		 */
		if (gd)
			po->size = gd->part[MINOR(kdev)].nr_sects;
		else {
			osenv_assert(blk_size[MAJOR(kdev)] &&
				     blk_size[MAJOR(kdev)][MINOR(kdev)]);
			po->size = (blk_size[MAJOR(kdev)][MINOR(kdev)]
				    << (BLOCK_SIZE_BITS - DISK_BLOCK_BITS));
		}

		if (blksize_size[MAJOR(kdev)]
		    && blksize_size[MAJOR(kdev)][MINOR(kdev)]) {
			int bshift = DISK_BLOCK_BITS;
			po->bsize = blksize_size[MAJOR(kdev)][MINOR(kdev)];
			for (i = po->bsize >> DISK_BLOCK_BITS; i != 1; i >>= 1)
				bshift++;
			po->bshift = bshift;
		}
		else {