Пример #1
0
static void
pchb_attach(struct device *parent, struct device *self, void *aux)
{
	struct pci_attach_args *pa = aux;
	char devinfo[256];

	printf("\n");
	pcifound++;

	/*
	 * All we do is print out a description.  Eventually, we
	 * might want to add code that does something that's
	 * possibly chipset-specific.
	 */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_GALILEO &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_GALILEO_GT64120) {
		/* Bah, same product ID... */

		/*
		 * XXX:	Is the >= 0x10 test correct?  The '120 doco
		 *	lists rev == 0x02 and the '120A doco lists
		 *	rev == 0x10.
		 */
		snprintf(devinfo, sizeof(devinfo),
		    "Galileo Technology GT-64120%s System Controller",
		    PCI_REVISION(pa->pa_class) >= 0x10 ? "A" : "");
	} else {
		pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
	}
	printf("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo,
	    PCI_REVISION(pa->pa_class));
}
Пример #2
0
int
ehci_sb700_match(struct pci_attach_args *pa)
{
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SBX00_SMB &&
	    (PCI_REVISION(pa->pa_class) == 0x3a ||
	     PCI_REVISION(pa->pa_class) == 0x3b))
		return (1);

	return (0);
}
Пример #3
0
/*
 * Compare PCI device parameters (vendor id, device id, subsystem id, etc)
 * with those specified in the struct pci_dev_t. vid and did of the struct
 * must be defined.
 *
 * Return TRUE on match, FALSE if else.
 */
int
pci_device_match(struct pci_entry_t *e, struct pci_dev_t *c) {
	u_int32_t data;

	/* These must be defined */
	data = pci_read_reg(e, PCI_ID_REG);
#ifdef DEBUG
	if (data != 0xFFFFFFFF) {
		printf("bus %u, dev %u, fun %u:", e->bus, e->dev, e->fun);
		printf("\tvendor id 0x%x, product id 0x%x\n", PCI_VENDOR(data), PCI_PRODUCT(data));
	}
#endif /* DEBUG */

	if (PCI_PRODUCT(data) != c->did)
		return 0;
	if (PCI_VENDOR(data) != c->vid)
		return 0;

#ifdef DEBUG
	printf("bus %u, dev %u, fun %u:", e->bus, e->dev, e->fun);
	printf("\tvendor id 0x%x, product id 0x%x\n", PCI_VENDOR(data), PCI_PRODUCT(data));
	data = pci_read_reg(e, PCI_CLASS_REG);
	printf("\tclass multimedia, subclass 0x%x, revision 0x%x\n",
			PCI_SUBCLASS(data), PCI_REVISION(data));
	data = pci_read_reg(e, PCI_SUBSYSVEND_REG);
	printf("\tsubsystem vendor id 0x%x, subsystem id 0x%x\n", PCI_VENDOR(data), PCI_PRODUCT(data));
#endif /* DEBUG */

	data = pci_read_reg(e, PCI_CLASS_REG);
	if (PCI_CLASS(data) != PCI_CLASS_MULTIMEDIA)
		return 0;
	if (c->subclass != PCI_SUBCLASS_ANY)
		if (c->subclass != PCI_SUBCLASS(data))
			return 0;
	if (c->rev != PCI_REVISION_ANY)
		if (c->rev != PCI_REVISION(data))
			return 0;

	data = pci_read_reg(e, PCI_SUBSYSVEND_REG);
	if (c->subvid != PCI_SUBSYS_ID_ANY)
		if (c->subvid != PCI_VENDOR(data))
			return 0;
	if (c->subdid != PCI_SUBSYS_ID_ANY)
		if (c->subdid != PCI_PRODUCT(data))
			return 0;

	return 1;
}
Пример #4
0
static int
sis_hostbr_match(const struct pci_attach_args *pa)
{
	int i;
	pcireg_t id, masqid, reg;

	id = pa->pa_id;

	if (PCI_VENDOR(id) != PCI_VENDOR_SIS)
		return 0;
	if (PCI_PRODUCT(id) == PCI_PRODUCT_SIS_85C503) {
		reg = pci_conf_read(pa->pa_pc, pa->pa_tag, SIS96x_DETECT);
		pci_conf_write(pa->pa_pc, pa->pa_tag, SIS96x_DETECT,
		    reg | SIS96x_DETECT_MASQ);
		masqid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
		if (((PCI_PRODUCT(masqid) & 0xfff0) != 0x0960)
		    && (PCI_PRODUCT(masqid) != 0x0018)) {
			pci_conf_write(pa->pa_pc, pa->pa_tag, SIS96x_DETECT,
			    reg);
		} else {
			id = masqid;
		}
	}

	sis_hostbr_type_match = NULL;
	for (i = 0; i < __arraycount(sis_hostbr_type); i++) {
		if (PCI_PRODUCT(id) == sis_hostbr_type[i].id &&
		    PCI_REVISION(pa->pa_class) >= sis_hostbr_type[i].rev)
			sis_hostbr_type_match = &sis_hostbr_type[i];
	}
	return (sis_hostbr_type_match != NULL);
}
Пример #5
0
/*
 * Probe for a 21143 or clone chip. Check the PCI vendor and device
 * IDs against our list and return a device name if we find a match.
 */
int
dc_pci_match(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	struct dc_type *t;

	/*
	 * Support for the 21140 chip is experimental.  If it works for you,
	 * that's great.  By default, this chip will use de.
	 */
        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140)
		return (1);

	/*
	 * The following chip revision doesn't seem to work so well with dc,
	 * so let's have de handle it.  (de will return a match of 2)
	 */
        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142 &&
	    PCI_REVISION(pa->pa_class) == 0x21)
		return (1);

	for (t = dc_devs; t->dc_vid != 0; t++) {
		if ((PCI_VENDOR(pa->pa_id) == t->dc_vid) &&
		    (PCI_PRODUCT(pa->pa_id) == t->dc_did)) {
			return (3);
		}
	}

	return (0);
}
Пример #6
0
static int
sis_south_match(const struct pci_attach_args *pa)
{

	return (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIS &&
		PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIS_85C503 &&
		PCI_REVISION(pa->pa_class) >= 0x10);
}
Пример #7
0
static void
artisea_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
{
	struct pciide_channel *cp;
	bus_size_t cmdsize, ctlsize;
	pcireg_t interface;
	int channel;

	if (pciide_chipen(sc, pa) == 0)
		return;

	interface = PCI_INTERFACE(pa->pa_class);

	if (interface == 0) {
		artisea_chip_map_dpa (sc, pa);
		return;
	}

	aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
	    "bus-master DMA support present");
#ifdef PCIIDE_I31244_DISABLEDMA
	if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_31244 &&
	    PCI_REVISION(pa->pa_class) == 0) {
		aprint_verbose(" but disabled due to rev. 0");
		sc->sc_dma_ok = 0;
	} else
#endif
		pciide_mapreg_dma(sc, pa);
	aprint_verbose("\n");

	/*
	 * XXX Configure LEDs to show activity.
	 */

	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
	sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
	if (sc->sc_dma_ok) {
		sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA;
		sc->sc_wdcdev.irqack = pciide_irqack;
		sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
		sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
	}
	sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel;

	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
	sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS;

	wdc_allocate_regs(&sc->sc_wdcdev);

	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
	     channel++) {
		cp = &sc->pciide_channels[channel];
		if (pciide_chansetup(sc, channel, interface) == 0)
			continue;
		pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
		    pciide_pci_intr);
	}
}
Пример #8
0
void
pchbattach(struct device *parent, struct device *self, void *aux)
{
	struct pci_attach_args *pa = aux;
	char devinfo[256];
#if NAGP > 0
	struct agpbus_attach_args apa;
#endif
	volatile unsigned char *python;
	uint32_t v;
	
	aprint_normal("\n");

	/*
	 * All we do is print out a description.  Eventually, we
	 * might want to add code that does something that's
	 * possibly chipset-specific.
	 */

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_normal("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo,
	    PCI_REVISION(pa->pa_class));

	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_IBM:
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_IBM_82660:
			ibm82660_print(pa, self);
			break;
		case PCI_PRODUCT_IBM_PYTHON:
			python = mapiodev(0xfeff6000, 0x60);
			v = 0x88b78e01; /* taken from linux */
			out32rb(python+0x30, v);
			v = in32rb(python+0x30);
			aprint_debug("Reset python reg 30 to 0x%x\n", v);
			break;
		}
		break;
	case PCI_VENDOR_MOT:
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_MOT_MPC105:
			mpc105_print(pa, self);
			break;
		case PCI_PRODUCT_MOT_MPC106:
			mpc106_print(pa, self);
			break;
		}
		break;
	}

#if NAGP > 0
	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
			       NULL, NULL) != 0) {
		apa.apa_pci_args = *pa;
		config_found_ia(self, "agpbus", &apa, agpbusprint);
	}
#endif /* NAGP */
}
Пример #9
0
void
bwi_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
	struct pci_attach_args *pa = aux;
	struct bwi_softc *sc = &psc->psc_bwi;
	const char *intrstr = NULL;
	pci_intr_handle_t ih;
	pcireg_t memtype, reg;

	sc->sc_dmat = pa->pa_dmat;
	psc->psc_pc = pa->pa_pc;
	psc->psc_pcitag = pa->pa_tag;

	/* map control / status registers */
	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BWI_PCI_BAR0); 
	if (pci_mapreg_map(pa, BWI_PCI_BAR0, memtype, 0, &sc->sc_mem_bt,
	    &sc->sc_mem_bh, NULL, &psc->psc_mapsize, 0)) {
		printf(": can't map mem space\n");
		return;
	}

	/* map interrupt */
	if (pci_intr_map(pa, &ih) != 0) {
		printf(": can't map interrupt\n");
		return;
	}

	/* establish interrupt */
	intrstr = pci_intr_string(psc->psc_pc, ih);
	psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc,
	    sc->sc_dev.dv_xname);
	if (psc->psc_ih == NULL) {
		printf(": can't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf(": %s", intrstr);

	/* we need to access PCI config space from the driver */
	sc->sc_conf_write = bwi_pci_conf_write;
	sc->sc_conf_read = bwi_pci_conf_read;

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);

	sc->sc_pci_revid = PCI_REVISION(pa->pa_class);
	sc->sc_pci_did = PCI_PRODUCT(pa->pa_id);
	sc->sc_pci_subvid = PCI_VENDOR(reg);
	sc->sc_pci_subdid = PCI_PRODUCT(reg);

	bwi_attach(sc);
}
Пример #10
0
static void
nfsmbc_attach(device_t parent, device_t self, void *aux)
{
	struct nfsmbc_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct nfsmbc_attach_args nfsmbca;
	pcireg_t reg;
	int baseregs[2];
	char devinfo[256];

	aprint_naive("\n");
	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_normal(": %s (rev. 0x%02x)\n", devinfo,
	    PCI_REVISION(pa->pa_class));

	sc->sc_dev = self;
	sc->sc_pc = pa->pa_pc;
	sc->sc_tag = pa->pa_tag;
	sc->sc_pa = pa;
	sc->sc_iot = pa->pa_iot;

	nfsmbca.nfsmb_iot = sc->sc_iot;

	switch (PCI_PRODUCT(pa->pa_id)) {
	case PCI_PRODUCT_NVIDIA_NFORCE2_SMBUS:
	case PCI_PRODUCT_NVIDIA_NFORCE2_400_SMBUS:
	case PCI_PRODUCT_NVIDIA_NFORCE3_SMBUS:
	case PCI_PRODUCT_NVIDIA_NFORCE3_250_SMBUS:
	case PCI_PRODUCT_NVIDIA_NFORCE4_SMBUS:
		baseregs[0] = NFORCE_OLD_SMB1;
		baseregs[1] = NFORCE_OLD_SMB2;
		break;
	default:
		baseregs[0] = NFORCE_SMB1;
		baseregs[1] = NFORCE_SMB2;
		break;
	}

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, baseregs[0]);
	nfsmbca.nfsmb_num = 1;
	nfsmbca.nfsmb_addr = NFORCE_SMBBASE(reg);
	sc->sc_nfsmb[0] = config_found(sc->sc_dev, &nfsmbca, nfsmbc_print);

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, baseregs[1]);
	nfsmbca.nfsmb_num = 2;
	nfsmbca.nfsmb_addr = NFORCE_SMBBASE(reg);
	sc->sc_nfsmb[1] = config_found(sc->sc_dev, &nfsmbca, nfsmbc_print);

	/* This driver is similar to an ISA bridge that doesn't
	 * need any special handling. So registering NULL handlers
	 * are sufficent. */
	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Пример #11
0
static void
pcib_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	char devinfo[256];

	aprint_normal("\n");
	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_normal_dev(self, "%s, rev %d\n", devinfo,
	    PCI_REVISION(pa->pa_class));

}
Пример #12
0
int
siop_pci_match( struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = aux;
	const struct siop_product_desc *pp;

	/* look if it's a known product */
	pp = siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class));
	if (pp)
		return 1;
	return 0;
}
Пример #13
0
static void
artisea_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
{
	struct pciide_channel *cp;
	bus_size_t cmdsize, ctlsize;
	pcireg_t interface;
	int channel;

	if (pciide_chipen(sc, pa) == 0)
		return;

	aprint_normal("%s: bus-master DMA support present",
	    sc->sc_wdcdev.sc_dev.dv_xname);
#ifndef PCIIDE_I31244_ENABLEDMA
	if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_31244 &&
	    PCI_REVISION(pa->pa_class) == 0) {
		aprint_normal(" but disabled due to rev. 0");
		sc->sc_dma_ok = 0;
	} else
#endif
		pciide_mapreg_dma(sc, pa);
	aprint_normal("\n");

	/*
	 * XXX Configure LEDs to show activity.
	 */

	sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
	    WDC_CAPABILITY_MODE;
	sc->sc_wdcdev.PIO_cap = 4;
	if (sc->sc_dma_ok) {
		sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
		sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
		sc->sc_wdcdev.irqack = pciide_irqack;
		sc->sc_wdcdev.DMA_cap = 2;
		sc->sc_wdcdev.UDMA_cap = 6;
	}
	sc->sc_wdcdev.set_modes = sata_setup_channel;

	sc->sc_wdcdev.channels = sc->wdc_chanarray;
	sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;

	interface = PCI_INTERFACE(pa->pa_class);

	for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
		cp = &sc->pciide_channels[channel];
		if (pciide_chansetup(sc, channel, interface) == 0)
			continue;
		pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
		    pciide_pci_intr);
	}
}
Пример #14
0
void
ral_cardbus_attach(struct device *parent, struct device *self,
    void *aux)
{
	struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self;
	struct rt2560_softc *sc = &csc->sc_sc;
	struct cardbus_attach_args *ca = aux;
	cardbus_devfunc_t ct = ca->ca_ct;
	char devinfo[256];
	bus_addr_t base;
	int error, revision;

	pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
	revision = PCI_REVISION(ca->ca_class);
	aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision);

	csc->sc_opns =
	    (CARDBUS_PRODUCT(ca->ca_id) == PCI_PRODUCT_RALINK_RT2560) ?
	    &ral_rt2560_opns : &ral_rt2661_opns;

	sc->sc_dmat = ca->ca_dmat;
	csc->sc_ct = ct;
	csc->sc_tag = ca->ca_tag;
	csc->sc_intrline = ca->ca_intrline;

	/* power management hooks */
	sc->sc_enable = ral_cardbus_enable;
	sc->sc_disable = ral_cardbus_disable;

	/* map control/status registers */
	error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
	    CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base,
	    &csc->sc_mapsize);
	if (error != 0) {
		printf(": could not map memory space\n");
		return;
	}

#if rbus
#else
	(*cf->cardbus_mem_open)(cc, 0, base, base + csc->sc_mapsize);
#endif

	csc->sc_bar_val = base | CARDBUS_MAPREG_TYPE_MEM;

	/* set up the PCI configuration registers */
	ral_cardbus_setup(csc);

	(*csc->sc_opns->attach)(sc, CARDBUS_PRODUCT(ca->ca_id));

	Cardbus_function_disable(ct);
}
Пример #15
0
int
virtio_pci_match(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa;

	pa = (struct pci_attach_args *)aux;
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_QUMRANET &&
	    PCI_PRODUCT(pa->pa_id) >= 0x1000 &&
	    PCI_PRODUCT(pa->pa_id) <= 0x103f &&
	    PCI_REVISION(pa->pa_class) == 0)
		return 1;
	return 0;
}
Пример #16
0
int
rl_pci_match(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = aux;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_REALTEK &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RT8139 &&
	    PCI_REVISION(pa->pa_class) == 0x10)
		return (1);

	return (pci_matchbyid((struct pci_attach_args *)aux, rl_pci_devices,
	    nitems(rl_pci_devices)));
}
Пример #17
0
static void
sis_sata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa)
{
	struct pciide_channel *cp;
	pcireg_t interface = PCI_INTERFACE(pa->pa_class);
	int channel;

	if (pciide_chipen(sc, pa) == 0)
		return;

	if (interface == 0) {
		ATADEBUG_PRINT(("sis_sata_chip_map interface == 0\n"),
		    DEBUG_PROBE);
		interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
		    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
	}

	aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
	    "Silicon Integrated Systems 180/96X SATA controller "
	    "(rev. 0x%02x)\n", PCI_REVISION(pa->pa_class));

	aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
	    "bus-master DMA support present");
	pciide_mapreg_dma(sc, pa);
	aprint_verbose("\n");

	if (sc->sc_dma_ok) {
		sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA | ATAC_CAP_DMA;
		sc->sc_wdcdev.irqack = pciide_irqack;
	}
	sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
	sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
	sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;

	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
	sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS;
	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
	sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel;
	sc->sc_wdcdev.wdc_maxdrives = 2;

	wdc_allocate_regs(&sc->sc_wdcdev);

	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
	     channel++) {
		cp = &sc->pciide_channels[channel];
		if (pciide_chansetup(sc, channel, interface) == 0)
			continue;
		pciide_mapchan(pa, cp, interface, pciide_pci_intr);
	}
}
Пример #18
0
void
ral_cardbus_attach(device_t parent, device_t self, void *aux)
{
	struct ral_cardbus_softc *csc = device_private(self);
	struct rt2560_softc *sc = &csc->sc_sc;
	struct cardbus_attach_args *ca = aux;
	cardbus_devfunc_t ct = ca->ca_ct;
	char devinfo[256];
	bus_addr_t base;
	int error, revision;

	pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
	revision = PCI_REVISION(ca->ca_class);
	aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision);

	csc->sc_opns =
	    (PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_RALINK_RT2560) ?
	    &ral_rt2560_opns : &ral_rt2661_opns;

	sc->sc_dev = self;
	sc->sc_dmat = ca->ca_dmat;
	csc->sc_ct = ct;
	csc->sc_tag = ca->ca_tag;

	/* power management hooks */
	sc->sc_enable = ral_cardbus_enable;
	sc->sc_disable = ral_cardbus_disable;

	/* map control/status registers */
	error = Cardbus_mapreg_map(ct, PCI_BAR0,
	    PCI_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base,
	    &csc->sc_mapsize);
	if (error != 0) {
		aprint_error(": could not map memory space\n");
		return;
	}

	csc->sc_bar_val = base | PCI_MAPREG_TYPE_MEM;

	/* set up the PCI configuration registers */
	ral_cardbus_setup(csc);

	(*csc->sc_opns->attach)(sc, PCI_PRODUCT(ca->ca_id));

	Cardbus_function_disable(ct);
}
Пример #19
0
int
bwi_pci_match(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = aux;

	/*
	 * The second revision of the BCM4311/BCM4312
	 * chips require v4 firmware.
	 */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
            (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM4311 ||
	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM4312) &&
	     PCI_REVISION(pa->pa_class) == 0x02)
		return (0);

	return (pci_matchbyid((struct pci_attach_args *)aux, bwi_pci_devices,
	    sizeof(bwi_pci_devices) / sizeof(bwi_pci_devices[0])));
}
Пример #20
0
void
pcmbattach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	char devinfo[256];

	aprint_naive("\n");
	aprint_normal("\n");

	/*
	 * Just print out a description and defer configuration
	 * until all PCI devices have been attached.
	 */
	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo,
	    PCI_REVISION(pa->pa_class));

	config_defer(self, pcmb_callback);
}
Пример #21
0
void
bonito_mainbus_attach(device_t parent, device_t self, void *aux)
{
	struct bonito_softc *sc = device_private(self);
	struct pcibus_attach_args pba;
	struct bonito_config *bc;
	pcireg_t rev;

	/*
	 * There is only one PCI controller on an Algorithmics board.
	 */
#if defined(ALGOR_P6032)
	bc = &p6032_configuration.ac_bonito;
#endif
	sc->sc_bonito = bc;

	rev = PCI_REVISION(REGVAL(BONITO_PCICLASS));

	printf(": BONITO Memory and PCI controller, %s rev. %d.%d\n",
	    BONITO_REV_FPGA(rev) ? "FPGA" : "ASIC",
	    BONITO_REV_MAJOR(rev), BONITO_REV_MINOR(rev));

	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
	pba.pba_bus = 0;
	pba.pba_bridgetag = NULL;

#if defined(ALGOR_P6032)
	    {
		struct p6032_config *acp = &p6032_configuration;

		pba.pba_iot = &acp->ac_iot;
		pba.pba_memt = &acp->ac_memt;
		pba.pba_dmat = &acp->ac_pci_dmat;
		pba.pba_dmat64 = NULL;
		pba.pba_pc = &acp->ac_pc;
	    }
#endif /* ALGOR_P6032 */

	(void) config_found_ia(self, "pcibus", &pba, pcibusprint);
}
Пример #22
0
void
ahci_ati_sb_idetoahci(struct ahci_softc *sc, struct pci_attach_args *pa)
{
	pcireg_t			magic;

	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
		magic = pci_conf_read(pa->pa_pc, pa->pa_tag,
		    AHCI_PCI_ATI_SB600_MAGIC);
		pci_conf_write(pa->pa_pc, pa->pa_tag,
		    AHCI_PCI_ATI_SB600_MAGIC,
		    magic | AHCI_PCI_ATI_SB600_LOCKED);

		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG,
		    PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT |
		    PCI_SUBCLASS_MASS_STORAGE_SATA << PCI_SUBCLASS_SHIFT |
		    AHCI_PCI_INTERFACE << PCI_INTERFACE_SHIFT |
		    PCI_REVISION(pa->pa_class) << PCI_REVISION_SHIFT);

		pci_conf_write(pa->pa_pc, pa->pa_tag,
		    AHCI_PCI_ATI_SB600_MAGIC, magic);
	}
}
Пример #23
0
static void
joy_pci_attach(device_t parent, device_t self, void *aux)
{
	struct joy_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	char devinfo[256];
	bus_size_t mapsize;
	int reg;

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_normal(": %s (rev 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
	
	for (reg = PCI_MAPREG_START; reg < PCI_MAPREG_END;
	     reg += sizeof(pcireg_t))
		if (bar_is_io(pa->pa_pc, pa->pa_tag, reg))
			break;
	if (reg >= PCI_MAPREG_END) {
		aprint_error_dev(self,
		    "violates PCI spec, no IO region found\n");
		return;
	}

	if (pci_mapreg_map(pa, reg, PCI_MAPREG_TYPE_IO, 0,
	    &sc->sc_iot, &sc->sc_ioh, NULL, &mapsize)) {
		aprint_error_dev(self, "could not map IO space\n");
		return;
	}

	if (mapsize != 2) {
		if (!bus_space_subregion(sc->sc_iot, sc->sc_ioh, 1, 1, &sc->sc_ioh) < 0) {
			aprint_error_dev(self, "error mapping subregion\n");
			return;
		}
	}

	sc->sc_dev = self;

	joyattach(sc);
}
Пример #24
0
/*
 * Set up the chipset's function pointers.
 */
void
irongate_init(struct irongate_config *icp, int mallocsafe)
{
	pcitag_t tag;
	pcireg_t reg;

	icp->ic_mallocsafe = mallocsafe;

	/*
	 * Set up PCI configuration space; we can only read the
	 * revision info through configuration space.
	 */
	irongate_pci_init(&icp->ic_pc, icp);
#if 0
	alpha_pci_chipset = &icp->ic_pc;
#endif

	tag = pci_make_tag(&icp->ic_pc, 0, IRONGATE_PCIHOST_DEV, 0);

	/* Read the revision. */
	reg = irongate_conf_read0(icp, tag, PCI_CLASS_REG);
	icp->ic_rev = PCI_REVISION(reg);

	if (icp->ic_initted == 0) {
		/* Don't do these twice, since they set up extents. */
		icp->ic_iot = irongate_bus_io_init(icp);
		icp->ic_memt = irongate_bus_mem_init(icp);

#if 0
		/* Only one each PCI I/O and MEM window. */
		alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_IO] = 1;
		alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_MEM] = 1;
		
		alpha_bus_get_window = irongate_bus_get_window;
#endif
	}

	icp->ic_initted = 1;
}
Пример #25
0
/*
 * Probe for a Realtek 8169/8110 chip. Check the PCI vendor and device
 * IDs against our list and return a device name if we find a match.
 */
int
re_pci_probe(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcireg_t subid;

	subid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);

	/* C+ mode 8139's */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_REALTEK &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RT8139 &&
	    PCI_REVISION(pa->pa_class) == 0x20)
		return (1);

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LINKSYS &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LINKSYS_EG1032 &&
	    subid == RE_LINKSYS_EG1032_SUBID)
		return (1);

	return (pci_matchbyid((struct pci_attach_args *)aux, re_pci_devices,
	    nitems(re_pci_devices)));
}
Пример #26
0
int
siop_pci_attach_common(struct siop_pci_common_softc *pci_sc,
    struct siop_common_softc *siop_sc, struct pci_attach_args *pa,
    int (*intr)(void *))
{
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	const char *intrstr;
	pci_intr_handle_t intrhandle;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	pcireg_t memtype;
	prop_dictionary_t dict;
	int memh_valid, ioh_valid;
	bus_addr_t ioaddr, memaddr;
	bool use_pciclock;
	char intrbuf[PCI_INTRSTR_LEN];

	aprint_naive(": SCSI controller\n");

	pci_sc->sc_pp =
	    siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class));
	if (pci_sc->sc_pp == NULL) {
		aprint_error("sym: broken match/attach!!\n");
		return 0;
	}
	/* copy interesting infos about the chip */
	siop_sc->features = pci_sc->sc_pp->features;
#ifdef SIOP_SYMLED    /* XXX Should be a devprop! */
	siop_sc->features |= SF_CHIP_LED0;
#endif
	dict = device_properties(siop_sc->sc_dev);
	if (prop_dictionary_get_bool(dict, "use_pciclock", &use_pciclock))
		if (use_pciclock)
			siop_sc->features |= SF_CHIP_USEPCIC;
	siop_sc->maxburst = pci_sc->sc_pp->maxburst;
	siop_sc->maxoff = pci_sc->sc_pp->maxoff;
	siop_sc->clock_div = pci_sc->sc_pp->clock_div;
	siop_sc->clock_period = pci_sc->sc_pp->clock_period;
	siop_sc->ram_size = pci_sc->sc_pp->ram_size;

	siop_sc->sc_reset = siop_pci_reset;
	aprint_normal(": %s\n", pci_sc->sc_pp->name);
	pci_sc->sc_pc = pc;
	pci_sc->sc_tag = tag;
	siop_sc->sc_dmat = pa->pa_dmat;

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x14);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		memh_valid = (pci_mapreg_map(pa, 0x14, memtype, 0,
		    &memt, &memh, &memaddr, NULL) == 0);
		break;
	default:
		memh_valid = 0;
	}

	ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, &ioaddr, NULL) == 0);

	if (memh_valid) {
		siop_sc->sc_rt = memt;
		siop_sc->sc_rh = memh;
		siop_sc->sc_raddr = memaddr;
	} else if (ioh_valid) {
		siop_sc->sc_rt = iot;
		siop_sc->sc_rh = ioh;
		siop_sc->sc_raddr = ioaddr;
	} else {
		aprint_error_dev(siop_sc->sc_dev,
		    "unable to map device registers\n");
		return 0;
	}

	if (siop_sc->features & SF_CHIP_RAM) {
		int bar;
		switch (memtype) {
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
			bar = 0x18;
			break;
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
			bar = 0x1c;
			break;
		default:
			aprint_error_dev(siop_sc->sc_dev,
			    "invalid memory type %d\n",
			    memtype);
			return 0;
		}
		if (pci_mapreg_map(pa, bar, memtype, 0,
                    &siop_sc->sc_ramt, &siop_sc->sc_ramh,
		    &siop_sc->sc_scriptaddr, NULL) == 0) {
			aprint_normal_dev(siop_sc->sc_dev,
			    "using on-board RAM\n");
		} else {
			aprint_error_dev(siop_sc->sc_dev,
			    "can't map on-board RAM\n");
			siop_sc->features &= ~SF_CHIP_RAM;
		}
	}

	if (pci_intr_map(pa, &intrhandle) != 0) {
		aprint_error_dev(siop_sc->sc_dev, "couldn't map interrupt\n");
		return 0;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle, intrbuf, sizeof(intrbuf));
	pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
	    intr, siop_sc);
	if (pci_sc->sc_ih != NULL) {
		aprint_normal_dev(siop_sc->sc_dev, "interrupting at %s\n",
		    intrstr ? intrstr : "unknown interrupt");
	} else {
		aprint_error_dev(siop_sc->sc_dev,
		    "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return 0;
	}
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);
	return 1;
}
Пример #27
0
int
pci_system_openbsd_create(void)
{
	struct pci_device_private *device;
	int domain, bus, dev, func, ndevs, nfuncs;
	char path[MAXPATHLEN];
	uint32_t reg;

	if (ndomains > 0)
		return 0;

	pci_sys = calloc(1, sizeof(struct pci_system));
	if (pci_sys == NULL)
		return ENOMEM;

	pci_sys->methods = &openbsd_pci_methods;

	for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) {
		snprintf(path, sizeof(path), "/dev/pci%d", domain);
	        pcifd[domain] = open(path, O_RDWR | O_CLOEXEC);
		if (pcifd[domain] == -1) {
			pcifd[domain] = open(path, O_RDONLY | O_CLOEXEC);
			if (pcifd[domain] == -1)
				break;
		}
		ndomains++;
	}

	if (ndomains == 0)
		return ENXIO;

	ndevs = 0;
	for (domain = 0; domain < ndomains; domain++) {
		for (bus = 0; bus < 256; bus++) {
			for (dev = 0; dev < 32; dev++) {
				nfuncs = pci_nfuncs(domain, bus, dev);
				for (func = 0; func < nfuncs; func++) {
					if (pci_read(domain, bus, dev, func,
					    PCI_ID_REG, &reg) != 0)
						continue;
					if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
					    PCI_VENDOR(reg) == 0)
						continue;

					ndevs++;
				}
			}
		}
	}

	pci_sys->num_devices = ndevs;
	pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
	if (pci_sys->devices == NULL) {
		free(pci_sys);
		pci_sys = NULL;
		for (domain = 0; domain < ndomains; domain++)
			close(pcifd[domain]);
		ndomains = 0;
		return ENOMEM;
	}

	device = pci_sys->devices;
	for (domain = 0; domain < ndomains; domain++) {
		for (bus = 0; bus < 256; bus++) {
			for (dev = 0; dev < 32; dev++) {
				nfuncs = pci_nfuncs(domain, bus, dev);
				for (func = 0; func < nfuncs; func++) {
					if (pci_read(domain, bus, dev, func,
					    PCI_ID_REG, &reg) != 0)
						continue;
					if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
					    PCI_VENDOR(reg) == 0)
						continue;

					device->base.domain = domain;
					device->base.bus = bus;
					device->base.dev = dev;
					device->base.func = func;
					device->base.vendor_id = PCI_VENDOR(reg);
					device->base.device_id = PCI_PRODUCT(reg);

					if (pci_read(domain, bus, dev, func,
					    PCI_CLASS_REG, &reg) != 0)
						continue;

					device->base.device_class =
					    PCI_INTERFACE(reg) |
					    PCI_CLASS(reg) << 16 |
					    PCI_SUBCLASS(reg) << 8;
					device->base.revision = PCI_REVISION(reg);

					if (pci_read(domain, bus, dev, func,
					    PCI_SUBVEND_0, &reg) != 0)
						continue;

					device->base.subvendor_id = PCI_VENDOR(reg);
					device->base.subdevice_id = PCI_PRODUCT(reg);

					device++;
				}
			}
		}
	}

	return 0;
}
Пример #28
0
void
cas_attach(struct device *parent, struct device *self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct cas_softc *sc = (void *)self;
	pci_intr_handle_t ih;
#ifdef __sparc64__
	/* XXX the following declarations should be elsewhere */
	extern void myetheraddr(u_char *);
#endif
	const char *intrstr = NULL;
	bus_size_t size;
	int gotenaddr = 0;

	sc->sc_rev = PCI_REVISION(pa->pa_class);
	sc->sc_dmatag = pa->pa_dmat;

#define PCI_CAS_BASEADDR	0x10
	if (pci_mapreg_map(pa, PCI_CAS_BASEADDR, PCI_MAPREG_TYPE_MEM, 0,
	    &sc->sc_memt, &sc->sc_memh, NULL, &size, 0) != 0) {
		printf(": could not map registers\n");
		return;
	}

	if (cas_pci_enaddr(sc, pa) == 0)
		gotenaddr = 1;

#ifdef __sparc64__
	if (!gotenaddr) {
		if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
		    sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
			myetheraddr(sc->sc_arpcom.ac_enaddr);
		gotenaddr = 1;
	}
#endif
#ifdef __powerpc__
	if (!gotenaddr) {
		pci_ether_hw_addr(pa->pa_pc, sc->sc_arpcom.ac_enaddr);
		gotenaddr = 1;
	}
#endif

	sc->sc_burst = 16;	/* XXX */

	if (pci_intr_map(pa, &ih) != 0) {
		printf(": couldn't map interrupt\n");
		bus_space_unmap(sc->sc_memt, sc->sc_memh, size);
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	sc->sc_ih = pci_intr_establish(pa->pa_pc,
	    ih, IPL_NET, cas_intr, sc, self->dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		bus_space_unmap(sc->sc_memt, sc->sc_memh, size);
		return;
	}

	printf(": %s", intrstr);

	/*
	 * call the main configure
	 */
	cas_config(sc);
}
Пример #29
0
static void
uhci_cardbus_attach(device_t parent, device_t self,
    void *aux)
{
	struct uhci_cardbus_softc *sc = device_private(self);
	struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux;
	cardbus_devfunc_t ct = ca->ca_ct;
	cardbus_chipset_tag_t cc = ct->ct_cc;
	cardbus_function_tag_t cf = ct->ct_cf;
	pcitag_t tag = ca->ca_tag;
	pcireg_t csr;
	const char *vendor;
	const char *devname = device_xname(self);
	char devinfo[256];
	usbd_status r;

	sc->sc.sc_dev = self;
	sc->sc.sc_bus.hci_private = sc;

	pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
	printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(ca->ca_class));

	/* Map I/O registers */
	if (Cardbus_mapreg_map(ct, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
			   &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
		printf("%s: can't map i/o space\n", devname);
		return;
	}

	sc->sc_cc = cc;
	sc->sc_cf = cf;
	sc->sc_ct = ct;
	sc->sc_tag = tag;
	sc->sc.sc_bus.dmatag = ca->ca_dmat;

	/* Enable the device. */
	csr = Cardbus_conf_read(ct, tag, PCI_COMMAND_STATUS_REG);
	Cardbus_conf_write(ct, tag, PCI_COMMAND_STATUS_REG,
		       csr | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_IO_ENABLE);

	/* Disable interrupts, so we don't get any spurious ones. */
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);

	/* Map and establish the interrupt. */
	sc->sc_ih = Cardbus_intr_establish(ct, IPL_USB, uhci_intr, sc);
	if (sc->sc_ih == NULL) {
		printf("%s: couldn't establish interrupt\n", devname);
		return;
	}

	/* Set LEGSUP register to its default value. */
	Cardbus_conf_write(ct, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN);

	switch(Cardbus_conf_read(ct, tag, PCI_USBREV) & PCI_USBREV_MASK) {
	case PCI_USBREV_PRE_1_0:
		sc->sc.sc_bus.usbrev = USBREV_PRE_1_0;
		break;
	case PCI_USBREV_1_0:
		sc->sc.sc_bus.usbrev = USBREV_1_0;
		break;
	case PCI_USBREV_1_1:
		sc->sc.sc_bus.usbrev = USBREV_1_1;
		break;
	default:
		sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
		break;
	}

	/* Figure out vendor for root hub descriptor. */
	vendor = pci_findvendor(ca->ca_id);
	sc->sc.sc_id_vendor = PCI_VENDOR(ca->ca_id);
	if (vendor)
		strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor));
	else
		snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
		    "vendor 0x%04x", PCI_VENDOR(ca->ca_id));

	r = uhci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n", devname, r);

		/* Avoid spurious interrupts. */
		Cardbus_intr_disestablish(ct, sc->sc_ih);
		sc->sc_ih = NULL;

		return;
	}

#if NEHCI_CARDBUS > 0
	usb_cardbus_add(&sc->sc_cardbus, ca, self);
#endif

	/* Attach usb device. */
	sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);
}
Пример #30
0
static void
virtio_attach(device_t parent, device_t self, void *aux)
{
	struct virtio_softc *sc = device_private(self);
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	int revision;
	pcireg_t id;
	char const *intrstr;
	pci_intr_handle_t ih;

	revision = PCI_REVISION(pa->pa_class);
	if (revision != 0) {
		aprint_normal(": unknown revision 0x%02x; giving up\n",
			      revision);
		return;
	}
	aprint_normal("\n");
	aprint_naive("\n");

	/* subsystem ID shows what I am */
	id = pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG);
	aprint_normal_dev(self, "%s Virtio %s Device (rev. 0x%02x)\n",
			  pci_findvendor(id),
			  (PCI_PRODUCT(id)<NDEVNAMES?
			   virtio_device_name[PCI_PRODUCT(id)]:"Unknown"),
			  revision);

	sc->sc_dev = self;
	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->sc_iot = pa->pa_iot;
	sc->sc_dmat = pa->pa_dmat;
	sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;

	if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0,
			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	virtio_device_reset(sc);
	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);

	/* XXX: use softc as aux... */
	sc->sc_childdevid = PCI_PRODUCT(id);
	sc->sc_child = NULL;
	config_found(self, sc, NULL);
	if (sc->sc_child == NULL) {
		aprint_error_dev(self,
				 "no matching child driver; not configured\n");
		return;
	}
	if (sc->sc_child == (void*)1) { /* this shows error */
		aprint_error_dev(self,
				 "virtio configuration failed\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, sc->sc_ipl, virtio_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);

	return;
}