void * vbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, int level, int flags, int (*handler)(void *), void *arg, const char *what) { uint64_t sysino = INTVEC(ihandle); struct intrhand *ih; int err; ih = bus_intr_allocate(t0, handler, arg, ihandle, level, NULL, NULL, what); if (ih == NULL) return (NULL); if (flags & BUS_INTR_ESTABLISH_MPSAFE) ih->ih_mpsafe = 1; intr_establish(ih->ih_pil, ih); ih->ih_ack = vbus_intr_ack; err = hv_intr_settarget(sysino, ih->ih_cpu->ci_upaid); if (err != H_EOK) return (NULL); /* Clear pending interrupts. */ err = hv_intr_setstate(sysino, INTR_IDLE); if (err != H_EOK) return (NULL); err = hv_intr_setenabled(sysino, INTR_ENABLED); if (err != H_EOK) return (NULL); return (ih); }
static int vnex_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt,driver_intr_t *intr, void *arg, void **cookiep) { uint64_t reg, nreg; uint64_t ihdl, cfg; uint64_t ino, nino; int error, cpuid; if (res == NULL) panic("%s: NULL interrupt resource!", __func__); if ((error = bus_get_resource(dev, SYS_RES_MEMORY, 0, ®, &nreg))) goto fail; if ((error = bus_get_resource(child, SYS_RES_IRQ, 0, &ino, &nino))) goto fail; cfg = SUN4V_REG_SPEC2CFG_HDL(reg); if (hv_intr_devino_to_sysino(cfg, (uint32_t)ino, &ihdl) != H_EOK) { error = ENXIO; goto fail; } cpuid = 0; if (hv_intr_settarget(ihdl, cpuid) != H_EOK) { error = ENXIO; goto fail; } if (hv_intr_setstate(ihdl, HV_INTR_IDLE_STATE) != H_EOK) { error = ENXIO; goto fail; } if (hv_intr_setenabled(ihdl, HV_INTR_ENABLED) != H_EOK) { error = ENXIO; goto fail; } if ((rman_get_flags(res) & RF_SHAREABLE) == 0) flags |= INTR_EXCL; /* We depend here on rman_activate_resource() being idempotent. */ if ((error = rman_activate_resource(res))) goto fail; error = inthand_add(device_get_nameunit(child), ihdl, filt, intr, arg, flags, cookiep); printf("inthandler added\n"); fail: return (error); }
void * vbus_intr_establish(bus_space_tag_t t, int ihandle, int level, int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */) { uint64_t sysino = INTVEC(ihandle); struct intrhand *ih; int ino; int err; DPRINTF(VBUS_INTR, ("vbus_intr_establish()\n")); ino = INTINO(ihandle); ih = intrhand_alloc(); ih->ih_ivec = ihandle; ih->ih_fun = handler; ih->ih_arg = arg; ih->ih_pil = level; ih->ih_number = ino; ih->ih_pending = 0; intr_establish(ih->ih_pil, level != IPL_VM, ih); ih->ih_ack = vbus_intr_ack; err = hv_intr_settarget(sysino, cpus->ci_cpuid); if (err != H_EOK) { printf("hv_intr_settarget(%lu, %u) failed - err = %d\n", (long unsigned int)sysino, cpus->ci_cpuid, err); return (NULL); } /* Clear pending interrupts. */ err = hv_intr_setstate(sysino, INTR_IDLE); if (err != H_EOK) { printf("hv_intr_setstate(%lu, INTR_IDLE) failed - err = %d\n", (long unsigned int)sysino, err); return (NULL); } err = hv_intr_setenabled(sysino, INTR_ENABLED); if (err != H_EOK) { printf("hv_intr_setenabled(%lu) failed - err = %d\n", (long unsigned int)sysino, err); return (NULL); } return (ih); }