Exemplo n.º 1
0
static int
ofw_pcibus_assign_interrupt(device_t dev, device_t child)
{
	ofw_pci_intr_t intr;
	int isz;

	isz = OF_getprop(ofw_bus_get_node(child), "interrupts", &intr,
	    sizeof(intr));
	if (isz != sizeof(intr)) {
		/* No property; our best guess is the intpin. */
		intr = pci_get_intpin(child);
#ifndef SUN4V
	} else if (intr >= 255) {
		/*
		 * A fully specified interrupt (including IGN), as present on
		 * SPARCengine Ultra AX and E450.  Extract the INO and return
		 * it.
		 */
		return (INTINO(intr));
#endif
	}
	/*
	 * If we got intr from a property, it may or may not be an intpin.
	 * For on-board devices, it frequently is not, and is completely out
	 * of the valid intpin range.  For PCI slots, it hopefully is,
	 * otherwise we will have trouble interfacing with non-OFW buses
	 * such as cardbus.
	 * Since we cannot tell which it is without violating layering, we
	 * will always use the route_interrupt method, and treat exceptions
	 * on the level they become apparent.
	 */
	return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr));
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
Arquivo: fhc.c Projeto: MarginC/kame
struct resource *
fhc_alloc_resource(device_t bus, device_t child, int type, int *rid,
    u_long start, u_long end, u_long count, u_int flags)
{
	struct resource_list_entry *rle;
	struct fhc_devinfo *fdi;
	struct fhc_softc *sc;
	struct resource *res;
	bus_addr_t coffset;
	bus_addr_t cend;
	bus_addr_t phys;
	int isdefault;
	uint32_t map;
	uint32_t vec;
	int i;

	isdefault = (start == 0UL && end == ~0UL);
	res = NULL;
	sc = device_get_softc(bus);
	switch (type) {
	case SYS_RES_IRQ:
		if (!isdefault || count != 1 || *rid < FHC_FANFAIL ||
		    *rid > FHC_TOD)
			break;

		map = bus_space_read_4(sc->sc_bt[*rid], sc->sc_bh[*rid],
		    FHC_IMAP);
		vec = INTINO(map) | (sc->sc_ign << INTMAP_IGN_SHIFT);
		bus_space_write_4(sc->sc_bt[*rid], sc->sc_bh[*rid],
		    FHC_IMAP, vec);
		bus_space_read_4(sc->sc_bt[*rid], sc->sc_bh[*rid], FHC_IMAP);

		res = bus_generic_alloc_resource(bus, child, type, rid,
		    vec, vec, 1, flags);
		if (res != NULL)
			rman_set_rid(res, *rid);
		break;
	case SYS_RES_MEMORY:
		fdi = device_get_ivars(child);
		rle = resource_list_find(&fdi->fdi_rl, type, *rid);
		if (rle == NULL)
			return (NULL);
		if (rle->res != NULL)
			panic("fhc_alloc_resource: resource entry is busy");
		if (isdefault) {
			start = rle->start;
			count = ulmax(count, rle->count);
			end = ulmax(rle->end, start + count - 1);
		}
		for (i = 0; i < sc->sc_nrange; i++) {
			coffset = sc->sc_ranges[i].coffset;
			cend = coffset + sc->sc_ranges[i].size - 1;
			if (start >= coffset && end <= cend) {
				start -= coffset;
				end -= coffset;
				phys = sc->sc_ranges[i].poffset |
				    ((bus_addr_t)sc->sc_ranges[i].pspace << 32);
				res = bus_generic_alloc_resource(bus, child,
				    type, rid, phys + start, phys + end,
				    count, flags);
				rle->res = res;
				break;
			}
		}
		break;
	default:
		break;
	}
	return (res);
}