void update_owner__rx_handler(struct intermon_binding *b, intermon_caprep_t caprep, genvaddr_t st) { errval_t err; struct intermon_state *inter_st = (struct intermon_state*)b->st; coreid_t from = inter_st->core_id; struct capref capref; struct capability cap; caprep_to_capability(&caprep, &cap); err = slot_alloc(&capref); if (err_is_fail(err)) { USER_PANIC_ERR(err, "failed to allocate slot for owner update"); } err = monitor_copy_if_exists(&cap, capref); if (err_is_ok(err)) { err = monitor_set_cap_owner(cap_root, get_cap_addr(capref), get_cap_valid_bits(capref), from); } if (err_no(err) == SYS_ERR_CAP_NOT_FOUND) { err = SYS_ERR_OK; } if (err_is_fail(err)) { USER_PANIC_ERR(err, "failed to update cap ownership"); } cap_destroy(capref); err = owner_updated(from, st); if (err_is_fail(err)) { USER_PANIC_ERR(err, "failed to send ownership update response"); } }
void retrieve_request__rx(struct intermon_binding *b, intermon_caprep_t caprep, genvaddr_t st) { errval_t err, err2; struct intermon_state *inter_st = (struct intermon_state*)b->st; struct retrieve_response_st *rst; err = calloce(1, sizeof(*rst), &rst); PANIC_IF_ERR(err, "allocating retrieve respones state"); rst->st = st; rst->from = inter_st->core_id; struct capability rawcap; caprep_to_capability(&caprep, &rawcap); struct capref cap; err = slot_alloc(&cap); GOTO_IF_ERR(err, respond_err); err = monitor_copy_if_exists(&rawcap, cap); GOTO_IF_ERR(err, free_slot); distcap_state_t state; err = dom_cnode_get_state(get_cap_domref(cap), &state); GOTO_IF_ERR(err, delete_cap); if (distcap_state_is_busy(state)) { err = MON_ERR_REMOTE_CAP_RETRY; goto delete_cap; } if (distcap_state_is_foreign(state)) { err = MON_ERR_CAP_FOREIGN; goto delete_cap; } uint8_t relations, remote_relations; err = monitor_cap_has_relations(cap, 0xFF, &relations); GOTO_IF_ERR(err, delete_cap); err = monitor_remote_relations(cap, 0, 0, &remote_relations); GOTO_IF_ERR(err, delete_cap); rst->relations = relations | remote_relations | RRELS_COPY_BIT; err = monitor_set_cap_owner(cap_root, get_cap_addr(cap), get_cap_valid_bits(cap), rst->from); delete_cap: err2 = cap_delete(cap); DEBUG_IF_ERR(err2, "while deleting temp cap for retrieve"); free_slot: err2 = slot_free(cap); DEBUG_IF_ERR(err2, "freeing temp cap slot for retrieve"); respond_err: retrieve_result__enq(err, rst); }
int ifcvf_init_hw(struct ifcvf_hw *hw, PCI_DEV *dev) { int ret; u8 pos; struct ifcvf_pci_cap cap; ret = PCI_READ_CONFIG_BYTE(dev, &pos, PCI_CAPABILITY_LIST); if (ret < 0) { DEBUGOUT("failed to read pci capability list\n"); return -1; } while (pos) { ret = PCI_READ_CONFIG_RANGE(dev, (u32 *)&cap, sizeof(cap), pos); if (ret < 0) { DEBUGOUT("failed to read cap at pos: %x", pos); break; } if (cap.cap_vndr != PCI_CAP_ID_VNDR) goto next; DEBUGOUT("cfg type: %u, bar: %u, offset: %u, " "len: %u\n", cap.cfg_type, cap.bar, cap.offset, cap.length); switch (cap.cfg_type) { case IFCVF_PCI_CAP_COMMON_CFG: hw->common_cfg = get_cap_addr(hw, &cap); break; case IFCVF_PCI_CAP_NOTIFY_CFG: PCI_READ_CONFIG_DWORD(dev, &hw->notify_off_multiplier, pos + sizeof(cap)); hw->notify_base = get_cap_addr(hw, &cap); hw->notify_region = cap.bar; break; case IFCVF_PCI_CAP_ISR_CFG: hw->isr = get_cap_addr(hw, &cap); break; case IFCVF_PCI_CAP_DEVICE_CFG: hw->dev_cfg = get_cap_addr(hw, &cap); break; } next: pos = cap.cap_next; } hw->lm_cfg = hw->mem_resource[4].addr; if (hw->common_cfg == NULL || hw->notify_base == NULL || hw->isr == NULL || hw->dev_cfg == NULL) { DEBUGOUT("capability incomplete\n"); return -1; } DEBUGOUT("capability mapping:\ncommon cfg: %p\n" "notify base: %p\nisr cfg: %p\ndevice cfg: %p\n" "multiplier: %u\n", hw->common_cfg, hw->dev_cfg, hw->isr, hw->notify_base, hw->notify_off_multiplier); return 0; }