示例#1
0
文件: isa_pci.c 项目: coyizumi/cs111
static struct resource *
isab_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
    u_long start, u_long end, u_long count, u_int flags)
{
	struct isab_pci_softc *sc;
	int bar;

	if (device_get_parent(child) != dev)
		return bus_generic_alloc_resource(dev, child, type, rid, start,
		    end, count, flags);

	switch (type) {
	case SYS_RES_MEMORY:
	case SYS_RES_IOPORT:
		/*
		 * For BARs, we cache the resource so that we only allocate it
		 * from the PCI bus once.
		 */
		bar = PCI_RID2BAR(*rid);
		if (bar < 0 || bar > PCIR_MAX_BAR_0)
			return (NULL);
		sc = device_get_softc(dev);
		if (sc->isab_pci_res[bar].ip_res == NULL)
			sc->isab_pci_res[bar].ip_res = bus_alloc_resource(dev, type,
			    rid, start, end, count, flags);
		if (sc->isab_pci_res[bar].ip_res != NULL)
			sc->isab_pci_res[bar].ip_refs++;
		return (sc->isab_pci_res[bar].ip_res);
	}

	return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid,
		start, end, count, flags));
}
示例#2
0
static struct vga_resource *
lookup_res(struct vga_pci_softc *sc, int rid)
{
	int bar;

	if (rid == PCIR_BIOS)
		return (&sc->vga_bios);
	bar = PCI_RID2BAR(rid);
	if (bar >= 0 && bar <= PCIR_MAX_BAR_0)
		return (&sc->vga_bars[bar]);
	return (NULL);
}
示例#3
0
文件: isa_pci.c 项目: coyizumi/cs111
static int
isab_pci_release_resource(device_t dev, device_t child, int type, int rid,
    struct resource *r)
{
	struct isab_pci_softc *sc;
	int bar, error;

	if (device_get_parent(child) != dev)
		return bus_generic_release_resource(dev, child, type, rid, r);

	switch (type) {
	case SYS_RES_MEMORY:
	case SYS_RES_IOPORT:
		/*
		 * For BARs, we release the resource from the PCI bus
		 * when the last child reference goes away.
		 */
		bar = PCI_RID2BAR(rid);
		if (bar < 0 || bar > PCIR_MAX_BAR_0)
			return (EINVAL);
		sc = device_get_softc(dev);
		if (sc->isab_pci_res[bar].ip_res == NULL)
			return (EINVAL);
		KASSERT(sc->isab_pci_res[bar].ip_res == r,
		    ("isa_pci resource mismatch"));
		if (sc->isab_pci_res[bar].ip_refs > 1) {
			sc->isab_pci_res[bar].ip_refs--;
			return (0);
		}
		KASSERT(sc->isab_pci_res[bar].ip_refs > 0,
		    ("isa_pci resource reference count underflow"));
		error = bus_release_resource(dev, type, rid, r);
		if (error == 0) {
			sc->isab_pci_res[bar].ip_res = NULL;
			sc->isab_pci_res[bar].ip_refs = 0;
		}
		return (error);
	}

	return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type,
		rid, r));
}
示例#4
0
static int
decode_tuple_bar(device_t cbdev, device_t child, int id,
    int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
    struct tuple_callbacks *info, void *argp)
{
	struct cardbus_devinfo *dinfo = device_get_ivars(child);
	int type;
	uint8_t reg;
	uint32_t bar;

	if (len != 6) {
		device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len);
		return (EINVAL);
	}

	reg = *tupledata;
	len = le32toh(*(uint32_t*)(tupledata + 2));
	if (reg & TPL_BAR_REG_AS)
		type = SYS_RES_IOPORT;
	else
		type = SYS_RES_MEMORY;

	bar = reg & TPL_BAR_REG_ASI_MASK;
	if (bar == 0) {
		device_printf(cbdev, "Invalid BAR type 0 in CIS\n");
		return (EINVAL);	/* XXX Return an error? */
	} else if (bar == 7) {
		/* XXX Should we try to map in Option ROMs? */
		return (0);
	}

	/* Convert from BAR type to BAR offset */
	bar = PCIR_BAR(bar - 1);

	if (type == SYS_RES_MEMORY) {
		if (reg & TPL_BAR_REG_PREFETCHABLE)
			dinfo->mprefetchable |= (1 << PCI_RID2BAR(bar));
		/*
		 * The PC Card spec says we're only supposed to honor this
		 * hint when the cardbus bridge is a child of pci0 (the main
		 * bus).  The PC Card spec seems to indicate that this should
		 * only be done on x86 based machines, which suggests that on
		 * non-x86 machines the addresses can be anywhere.  Since the
		 * hardware can do it on non-x86 machines, it should be able
		 * to do it on x86 machines too.  Therefore, we can and should
		 * ignore this hint.  Furthermore, the PC Card spec recommends
		 * always allocating memory above 1MB, contradicting the other
		 * part of the PC Card spec, it seems.  We make note of it,
		 * but otherwise don't use this information.
		 *
		 * Some Realtek cards have this set in their CIS, but fail
		 * to actually work when mapped this way, and experience
		 * has shown ignoring this big to be a wise choice.
		 *
		 * XXX We should cite chapter and verse for standard refs.
		 */
		if (reg & TPL_BAR_REG_BELOW1MB)
			dinfo->mbelow1mb |= (1 << PCI_RID2BAR(bar));
	}

	return (0);
}