/* * 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); }
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; }
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; }
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; }
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; }
void osenv_wakeup(osenv_sleeprec_t *sr, int wakeup_status) { osenv_assert(sr); sr->data[0] = (void *)wakeup_status; sr->data[1] = (void *)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 */ }
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; }
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; }
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); }
/* * 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); }
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]; }
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; }
/* * 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 {