Beispiel #1
0
void
rl_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct rl_pci_softc	*psc = (void *)self;
	struct rl_softc		*sc = &psc->psc_softc;
	struct pci_attach_args	*pa = aux;
	pci_chipset_tag_t	pc = pa->pa_pc;
	pci_intr_handle_t	ih;
	const char		*intrstr = NULL;

	/*
	 * Map control/status registers.
	 */

#ifdef RL_USEIOSPACE
	if (pci_mapreg_map(pa, RL_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
	    &sc->rl_btag, &sc->rl_bhandle, NULL, &psc->psc_mapsize, 0)) {
		printf(": can't map i/o space\n");
		return;
	}
#else
	if (pci_mapreg_map(pa, RL_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
	    &sc->rl_btag, &sc->rl_bhandle, NULL, &psc->psc_mapsize, 0)){
		printf(": can't map mem space\n");
		return;
	}
#endif

	/*
	 * Allocate our interrupt.
	 */
	if (pci_intr_map(pa, &ih)) {
		printf(": couldn't map interrupt\n");
		bus_space_unmap(sc->rl_btag, sc->rl_bhandle, psc->psc_mapsize);
		return;
	}

	psc->psc_pc = pa->pa_pc;
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, rl_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->rl_btag, sc->rl_bhandle, psc->psc_mapsize);
		return;
	}
	printf(": %s", intrstr);

	sc->sc_dmat = pa->pa_dmat;

	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RT8129)
		sc->rl_type = RL_8129;
	else
		sc->rl_type = RL_8139;

	rl_attach(sc);
}
Beispiel #2
0
void
ral_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ral_pci_softc *psc = (struct ral_pci_softc *)self;
	struct rt2560_softc *sc = &psc->sc_sc;
	struct pci_attach_args *pa = aux;
	const char *intrstr;
	pci_intr_handle_t ih;
	pcireg_t memtype;
	int error;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RALINK) {
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_RALINK_RT2560:
			psc->sc_opns = &ral_rt2560_opns;
			break;
		case PCI_PRODUCT_RALINK_RT2561:
		case PCI_PRODUCT_RALINK_RT2561S:
		case PCI_PRODUCT_RALINK_RT2661:
			psc->sc_opns = &ral_rt2661_opns;
			break;
		default:
			psc->sc_opns = &ral_rt2860_opns;
			break;
		}
	} else {
		/* all other vendors are RT2860 only */
		psc->sc_opns = &ral_rt2860_opns;
	}
	sc->sc_dmat = pa->pa_dmat;
	psc->sc_pc = pa->pa_pc;

	/* map control/status registers */
	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RAL_PCI_BAR0);
	error = pci_mapreg_map(pa, RAL_PCI_BAR0, memtype, 0, &sc->sc_st,
	    &sc->sc_sh, NULL, &psc->sc_mapsize, 0);
	if (error != 0) {
		printf(": can't map mem space\n");
		return;
	}

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

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

	(*psc->sc_opns->attach)(sc, PCI_PRODUCT(pa->pa_id));
}
Beispiel #3
0
void
amdiic_attach(struct device *parent, struct device *self, void *aux)
{
	struct amdiic_softc *sc = (struct amdiic_softc *)self;
	struct pci_attach_args *pa = aux;
	struct i2cbus_attach_args iba;
	pcireg_t conf;
	bus_size_t iosize;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;

	/* Map I/O space */
	if (pci_mapreg_map(pa, AMD8111_SMB_BASE, PCI_MAPREG_TYPE_IO, 0,
	    &sc->sc_iot, &sc->sc_ioh, NULL, &iosize, 0)) {
		printf(": can't map i/o space\n");
		return;
	}

	/* Read configuration */
	conf = pci_conf_read(pa->pa_pc, pa->pa_tag, AMD8111_SMB_MISC);
	DPRINTF((": conf 0x%08x", conf));

	sc->sc_poll = 1;
	if (conf & AMD8111_SMB_MISC_SCIEN) {
		/* No PCI IRQ */
		printf(": SCI");
	} else if (conf & AMD8111_SMB_MISC_INTEN) {
		/* Install interrupt handler */
		if (pci_intr_map(pa, &ih) == 0) {
			intrstr = pci_intr_string(pa->pa_pc, ih);
			sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
			    amdiic_intr, sc, sc->sc_dev.dv_xname);
			if (sc->sc_ih != NULL) {
				printf(": %s", intrstr);
				sc->sc_poll = 0;
			}
		}
		if (sc->sc_poll)
			printf(": polling");
	}

	printf("\n");

	/* Attach I2C bus */
	rw_init(&sc->sc_i2c_lock, "iiclk");
	sc->sc_i2c_tag.ic_cookie = sc;
	sc->sc_i2c_tag.ic_acquire_bus = amdiic_i2c_acquire_bus;
	sc->sc_i2c_tag.ic_release_bus = amdiic_i2c_release_bus;
	sc->sc_i2c_tag.ic_exec = amdiic_i2c_exec;

	bzero(&iba, sizeof(iba));
	iba.iba_name = "iic";
	iba.iba_tag = &sc->sc_i2c_tag;
	config_found(self, &iba, iicbus_print);

	return;
}
void
ral_pci_attach(device_t parent, device_t self, void *aux)
{
	struct ral_pci_softc *psc = device_private(self);
	struct rt2560_softc *sc = &psc->sc_sc;
	const struct pci_attach_args *pa = aux;
	const char *intrstr;
	bus_addr_t base;
	pci_intr_handle_t ih;
	pcireg_t reg;
	int error;

	pci_aprint_devinfo(pa, NULL);

	psc->sc_opns = (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RALINK_RT2560) ?
	    &ral_rt2560_opns : &ral_rt2661_opns;

	sc->sc_dev = self;
	sc->sc_dmat = pa->pa_dmat;
	psc->sc_pc = pa->pa_pc;

	/* enable the appropriate bits in the PCI CSR */
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);

	/* map control/status registers */
	error = pci_mapreg_map(pa, RAL_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
	    PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_st, &sc->sc_sh, &base,
	    &psc->sc_mapsize);

	if (error != 0) {
		aprint_error(": could not map memory space\n");
		return;
	}

	if (pci_intr_map(pa, &ih) != 0) {
		aprint_error(": could not map interrupt\n");
		return;
	}

	intrstr = pci_intr_string(psc->sc_pc, ih);
	psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET,
	    psc->sc_opns->intr, sc);

	if (psc->sc_ih == NULL) {
		aprint_error(": could not establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	(*psc->sc_opns->attach)(sc, PCI_PRODUCT(pa->pa_id));
}
Beispiel #5
0
void
mfi_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct mfi_softc	*sc = (struct mfi_softc *)self;
	struct pci_attach_args	*pa = aux;
	const struct mfi_pci_device *mpd;
	pci_intr_handle_t	ih;
	bus_size_t		size;
	pcireg_t		reg;
	int			regbar;

	mpd = mfi_pci_find_device(pa);
	if (mpd == NULL) {
		printf(": can't find matching pci device\n");
		return;
	}

	if (mpd->mpd_iop == MFI_IOP_GEN2 || mpd->mpd_iop == MFI_IOP_SKINNY)
		regbar = MFI_BAR_GEN2;
	else
		regbar = MFI_BAR;

	reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, regbar);
	if (pci_mapreg_map(pa, regbar, reg, 0,
	    &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) {
		printf(": can't map controller pci space\n");
		return;
	}

	sc->sc_dmat = pa->pa_dmat;

	if (pci_intr_map(pa, &ih) != 0) {
		printf(": can't map interrupt\n");
		goto unmap;
	}
	printf(": %s\n", pci_intr_string(pa->pa_pc, ih));

	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc,
	    sc->sc_dev.dv_xname);
	if (!sc->sc_ih) {
		printf("%s: can't establish interrupt\n", DEVNAME(sc));
		goto unmap;
	}

	if (mfi_attach(sc, mpd->mpd_iop)) {
		printf("%s: can't attach\n", DEVNAME(sc));
		goto unintr;
	}

	return;
unintr:
	pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
	sc->sc_ih = NULL;
unmap:
	bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
}
Beispiel #6
0
void
pgt_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct pgt_pci_softc *psc = (struct pgt_pci_softc *)self;
	struct pgt_softc *sc = &psc->sc_pgt;
	struct pci_attach_args *pa = aux;
	const char *intrstr = NULL;
	pci_intr_handle_t ih;
	int error;

	sc->sc_dmat = pa->pa_dmat;
	psc->sc_pc = pa->pa_pc;

	/* remember chipset */
	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTERSIL_ISL3877)
		sc->sc_flags |= SC_ISL3877;

	/* map control / status registers */
	error = pci_mapreg_map(pa, PGT_PCI_BAR0,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->sc_iotag, &sc->sc_iohandle, NULL, &psc->sc_mapsize, 0);
	if (error != 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;
	}

	/* disable all interrupts */
	bus_space_write_4(sc->sc_iotag, sc->sc_iohandle, PGT_REG_INT_EN, 0);
	(void)bus_space_read_4(sc->sc_iotag, sc->sc_iohandle, PGT_REG_INT_EN);
	DELAY(PGT_WRITEIO_DELAY);

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

	if (rootvp == NULL)
		mountroothook_establish(pgt_attach, sc);
	else
		pgt_attach(sc);
}
Beispiel #7
0
void
mfi_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct mfi_softc	*sc = (struct mfi_softc *)self;
	struct pci_attach_args	*pa = aux;
	const char		*intrstr;
	pci_intr_handle_t	ih;
	bus_size_t		size;
	pcireg_t		csr;
	uint32_t		subsysid, i;

	subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	for (i = 0; mfi_pci_devices[i].mpd_vendor; i++)
		if (mfi_pci_devices[i].mpd_subvendor == PCI_VENDOR(subsysid) &&
		    mfi_pci_devices[i].mpd_subproduct == PCI_PRODUCT(subsysid)){
				printf(", %s", mfi_pci_devices[i].mpd_model);
				break;
		}

	csr = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MFI_BAR);
	csr |= PCI_MAPREG_MEM_TYPE_32BIT;
	if (pci_mapreg_map(pa, MFI_BAR, csr, 0,
	    &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) {
		printf(": can't map controller pci space\n");
		return;
	}

	sc->sc_dmat = pa->pa_dmat;

	if (pci_intr_map(pa, &ih)) {
		printf(": can't map interrupt\n");
		bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc,
	    sc->sc_dev.dv_xname);
	if (!sc->sc_ih) {
		printf(": can't establish interrupt");
		if (intrstr)
			printf(" at %s", intrstr);
		printf("\n");
		bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
		return;
	}

	printf(": %s\n", intrstr);

	if (mfi_attach(sc)) {
		printf("%s: can't attach", DEVNAME(sc));
		pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
		sc->sc_ih = NULL;
		bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
	}
}
Beispiel #8
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);
}
Beispiel #9
0
void
rtsx_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct rtsx_pci_softc *sc = (struct rtsx_pci_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	char const *intrstr;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	bus_size_t size;
	int flags;

	if ((pci_conf_read(pa->pa_pc, pa->pa_tag, RTSX_CFG_PCI)
	    & RTSX_CFG_ASIC) != 0) {
		printf("%s: no asic\n", sc->sc.sc_dev.dv_xname);
		return;
	}

	if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) {
		printf(": can't map interrupt\n");
		return;
	}

	intrstr = pci_intr_string(pa->pa_pc, ih);
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_SDMMC,
	    rtsx_intr, sc, sc->sc.sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": can't establish interrupt\n");
		return;
	}
	printf(": %s\n", intrstr);

	if (pci_mem_find(pa->pa_pc, pa->pa_tag, RTSX_PCI_BAR,
	    NULL, NULL, NULL) != 0) {
		printf("%s: can't find registers\n", sc->sc.sc_dev.dv_xname);
	    	return;
	}

	if (pci_mapreg_map(pa, RTSX_PCI_BAR, PCI_MAPREG_TYPE_MEM, 0,
	    &iot, &ioh, NULL, &size, 0)) {
		printf("%s: can't map registers\n", sc->sc.sc_dev.dv_xname);
		return;
	}

	pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);

	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RTS5209)
		flags = RTSX_F_5209;
	else
		flags = RTSX_F_5229;

	if (rtsx_attach(&sc->sc, iot, ioh, size, pa->pa_dmat, flags) != 0)
		printf("%s: can't initialize chip\n", sc->sc.sc_dev.dv_xname);
}
static void
ahci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct ahci_pci_softc *psc = device_private(self);
	struct ahci_softc *sc = &psc->ah_sc;
	bus_size_t size;
	char devinfo[256];
	const char *intrstr;
	pci_intr_handle_t intrhandle;
	void *ih;

	sc->sc_atac.atac_dev = self;

	if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->sc_ahcit, &sc->sc_ahcih, NULL, &size) != 0) {
		aprint_error_dev(self, "can't map ahci registers\n");
		return;
	}
	psc->sc_pc = pa->pa_pc;
	psc->sc_pcitag = pa->pa_tag;

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	aprint_naive(": AHCI disk controller\n");
	aprint_normal(": %s\n", devinfo);
	
	if (pci_intr_map(pa, &intrhandle) != 0) {
		aprint_error("%s: couldn't map interrupt\n", AHCINAME(sc));
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle);
	ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc);
	if (ih == NULL) {
		aprint_error("%s: couldn't establish interrupt", AHCINAME(sc));
		return;
	}
	aprint_normal("%s: interrupting at %s\n", AHCINAME(sc),
	    intrstr ? intrstr : "unknown interrupt");
	sc->sc_dmat = pa->pa_dmat;

	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) {
		AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE);
		sc->sc_atac_capflags = ATAC_CAP_RAID;
	} else {
		AHCIDEBUG_PRINT(("%s: SATA mode\n", AHCINAME(sc)), DEBUG_PROBE);
	}

	ahci_attach(sc);

	if (!pmf_device_register(self, NULL, ahci_pci_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Beispiel #11
0
void
ahci_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ahci_pci_softc		*psc = (struct ahci_pci_softc *)self;
	struct ahci_softc		*sc = &psc->psc_ahci;
	struct pci_attach_args		*pa = aux;
	const struct ahci_device	*ad;
	pci_intr_handle_t		ih;
	int				mapped = 0;

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

	ad = ahci_lookup_device(pa);
	if (ad != NULL && ad->ad_attach != NULL) {
		if (ad->ad_attach(sc, pa) != 0) {
			/* error should be printed by ad_attach */
			return;
		}
	}

	if (!(sc->sc_flags & AHCI_F_NO_MSI))
		mapped = pci_intr_map_msi(pa, &ih) != 0 ? 0 : 1;
	
	if (!mapped && pci_intr_map(pa, &ih) != 0) {
		printf(": unable to map interrupt\n");
		return;
	}
	printf(": %s,", pci_intr_string(pa->pa_pc, ih));

	if (ahci_map_regs(psc, pa) != 0) {
		/* error already printed by ahci_map_regs */
		return;
	}

	if (ahci_map_intr(psc, pa, ih) != 0) {
		/* error already printed by ahci_map_intr */
		goto unmap;
	}

	if (ahci_attach(sc) != 0) {
		/* error printed by ahci_attach */
		goto unmap;
	}

	return;

unmap:
	ahci_unmap_regs(psc);
	return;
}
static void
mtd_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args * const pa = aux;
	struct mtd_softc * const sc = device_private(self);
	pci_intr_handle_t ih;
	const char *intrstring = NULL;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	int io_valid, mem_valid;

	sc->dev = self;
	pci_aprint_devinfo(pa, NULL);

	io_valid = (pci_mapreg_map(pa, PCI_IO_MAP_REG, PCI_MAPREG_TYPE_IO,
			0, &iot, &ioh, NULL, NULL) == 0);
	mem_valid = (pci_mapreg_map(pa, PCI_MEM_MAP_REG, PCI_MAPREG_TYPE_MEM
			| PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh,
			NULL, NULL) == 0);

	if (mem_valid) {
		sc->bus_tag = memt;
		sc->bus_handle = memh;
	} else if (io_valid) {
		sc->bus_tag = iot;
		sc->bus_handle = ioh;
	} else {
		aprint_error_dev(sc->dev, "could not map memory or i/o space\n");
		return;
	}
	sc->dma_tag = pa->pa_dmat;

	/* Do generic attach. Seems this must be done before setting IRQ */
	mtd_config(sc);

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(sc->dev, "could not map interrupt\n");
		return;
	}
	intrstring = pci_intr_string(pa->pa_pc, ih);

	if (pci_intr_establish(pa->pa_pc, ih, IPL_NET, mtd_irq_h, sc) == NULL) {
		aprint_error_dev(sc->dev, "could not establish interrupt");
		if (intrstring != NULL)
			aprint_error(" at %s", intrstring);
		aprint_error("\n");
		return;
	} else {
		aprint_normal_dev(sc->dev, "using %s for interrupt\n",
			intrstring ? intrstring : "unknown interrupt");
	}
}
Beispiel #13
0
static void
mtd_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct mtd_softc *sc = (void *)self;
	struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	bus_size_t iosize;

#ifndef MTD_USE_IO
	if (pci_mapreg_map(pa, MTD_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
	    &sc->bus_tag, &sc->bus_handle, NULL, &iosize, 0)) {
		printf(": can't map mem space\n");
		return;
	}
#else	/* MTD_USE_IO */
	if (pci_mapreg_map(pa, MTD_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
	    &sc->bus_tag, &sc->bus_handle, NULL, &iosize, 0)) {
		printf(": can't map io space\n");
		return;
	}
#endif	/* MTD_USE_IO */

	/*
	 * Allocate our interrupt.
	 */
	if (pci_intr_map(pa, &ih)) {
		printf(": couldn't map interrupt\n");
		bus_space_unmap(sc->bus_tag, sc->bus_handle, iosize);
		return;
	}

	intrstr = pci_intr_string(pa->pa_pc, ih);
	if (pci_intr_establish(pa->pa_pc, ih, IPL_NET, mtd_irq_h, sc,
	    self->dv_xname) == NULL) {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		bus_space_unmap(sc->bus_tag, sc->bus_handle, iosize);
		return;
	}
	printf(": %s", intrstr);

	sc->dma_tag = pa->pa_dmat;
	mtd_config(sc);
}
Beispiel #14
0
int
pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihpp)
{
    pci_intr_handle_t *ihp;

    ihp = kmem_alloc(sizeof(*ihp), KM_SLEEP);
    if (ihp == NULL)
        return ENOMEM;

    if (pci_intr_map(pa, ihp)) {
        kmem_free(ihp, sizeof(*ihp));
        return EINVAL;
    }

    *ihpp = ihp;
    return 0;
}
Beispiel #15
0
void
an_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct an_softc *sc = (struct an_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	bus_space_handle_t ioh;
	bus_space_tag_t iot = pa->pa_iot;
	pci_chipset_tag_t pc = pa->pa_pc;
	const char *intrstr;

	/* Map the I/O ports. */
	if (pci_mapreg_map(pa, AN_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, NULL, NULL, 0) != 0) {
		printf(": can't map i/o space\n");
		return;
	}
	sc->sc_iot = iot;
	sc->sc_ioh = ioh;

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		printf("\n%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, an_intr, sc,
	    sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf("\n%s: couldn't establish interrupt",
		    sc->sc_dev.dv_xname);
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf(": %s", intrstr);

	sc->sc_enabled = 1;

	an_attach(sc);
}
Beispiel #16
0
int
genppc_pci_intx_alloc(const struct pci_attach_args *pa,
    pci_intr_handle_t **ihps)
{
	pci_intr_handle_t *handle;
	int error;

	handle = kmem_zalloc(sizeof(*handle), KM_SLEEP);
	if (handle == NULL)
		return ENOMEM;

	error = pci_intr_map(pa, handle);
	if (error != 0) {
		kmem_free(handle, sizeof(*handle));
		return error;
	}

	*ihps = handle;
	return 0;
}
Beispiel #17
0
int
pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihp)
{
	pci_intr_handle_t *pih;

	if (ihp == NULL)
		return EINVAL;

	pih = kmem_alloc(sizeof(*pih), KM_SLEEP);
	if (pih == NULL)
		return ENOMEM;

	if (pci_intr_map(pa, pih)) {
		kmem_free(pih, sizeof(*pih));
		return EINVAL;
	}

	*ihp = pih;
	return 0;
}
Beispiel #18
0
int
genppc_pci_intr_alloc(const struct pci_attach_args *pa,
    pci_intr_handle_t **ihps, int *counts, pci_intr_type_t max_type)
{
	pci_intr_handle_t *ihp;

	if (counts != NULL && counts[PCI_INTR_TYPE_INTX] == 0)
		return EINVAL;

	ihp = kmem_alloc(sizeof(*ihp), KM_SLEEP);
	if (ihp == NULL)
		return ENOMEM;

	if (pci_intr_map(pa, ihp)) {
		kmem_free(ihp, sizeof(*ihp));
		return EINVAL;
	}

	*ihps = ihp;
	return 0;
}
int
pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **pih)
{
	struct intrsource *isp;
	pci_intr_handle_t *handle;
	int error;
	char intrstr_buf[INTRIDBUF];
	const char *intrstr;

	handle = kmem_zalloc(sizeof(*handle), KM_SLEEP);
	if (handle == NULL) {
		aprint_normal("cannot allocate pci_intr_handle_t\n");
		return ENOMEM;
	}

	if (pci_intr_map(pa, handle) != 0) {
		aprint_normal("cannot set up pci_intr_handle_t\n");
		error = EINVAL;
		goto error;
	}

	intrstr = pci_intr_string(pa->pa_pc, *handle,
	    intrstr_buf, sizeof(intrstr_buf));
	mutex_enter(&cpu_lock);
	isp = intr_allocate_io_intrsource(intrstr);
	mutex_exit(&cpu_lock);
	if (isp == NULL) {
		aprint_normal("can't allocate io_intersource\n");
		error = ENOMEM;
		goto error;
	}

	*pih = handle;
	return 0;

error:
	kmem_free(handle, sizeof(*handle));
	return error;
}
/*
 * Attach a supported board.
 *
 * XXX This doesn't fail gracefully.
 */
static void
twe_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa;
	struct twe_softc *sc;
	pci_chipset_tag_t pc;
	pci_intr_handle_t ih;
	pcireg_t csr;
	const char *intrstr;
	int s, size, i, rv, rseg;
	size_t max_segs, max_xfer;
	bus_dma_segment_t seg;
	const struct sysctlnode *node;
	struct twe_cmd *tc;
	struct twe_ccb *ccb;

	sc = device_private(self);
	sc->sc_dev = self;
	pa = aux;
	pc = pa->pa_pc;
	sc->sc_dmat = pa->pa_dmat;
	SIMPLEQ_INIT(&sc->sc_ccb_queue);
	SLIST_INIT(&sc->sc_ccb_freelist);

	aprint_naive(": RAID controller\n");
	aprint_normal(": 3ware Escalade\n");


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

	/* Enable the device. */
	csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    csr | PCI_COMMAND_MASTER_ENABLE);

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "can't map interrupt\n");
		return;
	}

	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, twe_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "can't establish interrupt%s%s\n",
			(intrstr) ? " at " : "",
			(intrstr) ? intrstr : "");
		return;
	}

	if (intrstr != NULL)
		aprint_normal_dev(self, "interrupting at %s\n",
			intrstr);

	/*
	 * Allocate and initialise the command blocks and CCBs.
	 */
	size = sizeof(struct twe_cmd) * TWE_MAX_QUEUECNT;

	if ((rv = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1,
	    &rseg, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(self, "unable to allocate commands, rv = %d\n", rv);
		return;
	}

	if ((rv = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
	    (void **)&sc->sc_cmds,
	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
		aprint_error_dev(self, "unable to map commands, rv = %d\n", rv);
		return;
	}

	if ((rv = bus_dmamap_create(sc->sc_dmat, size, size, 1, 0,
	    BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
		aprint_error_dev(self, "unable to create command DMA map, rv = %d\n", rv);
		return;
	}

	if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_cmds,
	    size, NULL, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(self, "unable to load command DMA map, rv = %d\n", rv);
		return;
	}

	ccb = malloc(sizeof(*ccb) * TWE_MAX_QUEUECNT, M_DEVBUF, M_NOWAIT);
	if (ccb == NULL) {
		aprint_error_dev(self, "unable to allocate memory for ccbs\n");
		return;
	}

	sc->sc_cmds_paddr = sc->sc_dmamap->dm_segs[0].ds_addr;
	memset(sc->sc_cmds, 0, size);

	sc->sc_ccbs = ccb;
	tc = (struct twe_cmd *)sc->sc_cmds;
	max_segs = twe_get_maxsegs();
	max_xfer = twe_get_maxxfer(max_segs);

	for (i = 0; i < TWE_MAX_QUEUECNT; i++, tc++, ccb++) {
		ccb->ccb_cmd = tc;
		ccb->ccb_cmdid = i;
		ccb->ccb_flags = 0;
		rv = bus_dmamap_create(sc->sc_dmat, max_xfer,
		    max_segs, PAGE_SIZE, 0,
		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
		    &ccb->ccb_dmamap_xfer);
		if (rv != 0) {
			aprint_error_dev(self, "can't create dmamap, rv = %d\n", rv);
			return;
		}

		/* Save the first CCB for AEN retrieval. */
		if (i != 0)
			SLIST_INSERT_HEAD(&sc->sc_ccb_freelist, ccb,
			    ccb_chain.slist);
	}

	/* Wait for the controller to become ready. */
	if (twe_status_wait(sc, TWE_STS_MICROCONTROLLER_READY, 6)) {
		aprint_error_dev(self, "microcontroller not ready\n");
		return;
	}

	twe_outl(sc, TWE_REG_CTL, TWE_CTL_DISABLE_INTRS);

	/* Reset the controller. */
	s = splbio();
	rv = twe_reset(sc);
	splx(s);
	if (rv) {
		aprint_error_dev(self, "reset failed\n");
		return;
	}

	/* Initialise connection with controller. */
	twe_init_connection(sc);

	twe_describe_controller(sc);

	/* Find and attach RAID array units. */
	sc->sc_nunits = 0;
	for (i = 0; i < TWE_MAX_UNITS; i++)
		(void) twe_add_unit(sc, i);

	/* ...and finally, enable interrupts. */
	twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR |
	    TWE_CTL_UNMASK_RESP_INTR |
	    TWE_CTL_ENABLE_INTRS);

	/* sysctl set-up for 3ware cli */
	if (sysctl_createv(NULL, 0, NULL, NULL,
				CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw",
				NULL, NULL, 0, NULL, 0,
				CTL_HW, CTL_EOL) != 0) {
		aprint_error_dev(self, "could not create %s sysctl node\n",
			"hw");
		return;
	}
	if (sysctl_createv(NULL, 0, NULL, &node,
				0, CTLTYPE_NODE, device_xname(self),
				SYSCTL_DESCR("twe driver information"),
				NULL, 0, NULL, 0,
				CTL_HW, CTL_CREATE, CTL_EOL) != 0) {
		aprint_error_dev(self, "could not create %s.%s sysctl node\n",
			"hw", device_xname(self));
		return;
	}
	if ((i = sysctl_createv(NULL, 0, NULL, NULL,
				0, CTLTYPE_STRING, "driver_version",
				SYSCTL_DESCR("twe0 driver version"),
				NULL, 0, __UNCONST(&twever), 0,
				CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
				!= 0) {
		aprint_error_dev(self, "could not create %s.%s.driver_version sysctl\n",
			"hw", device_xname(self));
		return;
	}
}
Beispiel #21
0
void
nfe_attach(struct device *parent, struct device *self, void *aux)
{
	struct nfe_softc *sc = (struct nfe_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr;
	struct ifnet *ifp;
	bus_size_t memsize;
	pcireg_t memtype;

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA);
	if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt,
	    &sc->sc_memh, NULL, &memsize, 0)) {
		printf(": can't map mem space\n");
		return;
	}

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

	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc,
	    sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": could not establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf(": %s", intrstr);

	sc->sc_dmat = pa->pa_dmat;
	sc->sc_flags = 0;

	switch (PCI_PRODUCT(pa->pa_id)) {
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP51_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP51_LAN2:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP61_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN4:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_CORRECT_MACADDR |
		    NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP77_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN4:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP79_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP89_LAN:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_CK804_LAN1:
	case PCI_PRODUCT_NVIDIA_CK804_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP65_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN4:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP55_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP55_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_HW_VLAN | NFE_PWR_MGMT;
		break;
	}

	if (sc->sc_flags & NFE_PWR_MGMT) {
		NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_RESET | NFE_RXTX_BIT2);
		NFE_WRITE(sc, NFE_MAC_RESET, NFE_MAC_RESET_MAGIC);
		DELAY(100);
		NFE_WRITE(sc, NFE_MAC_RESET, 0);
		DELAY(100);
		NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT2);
		NFE_WRITE(sc, NFE_PWR2_CTL,
		    NFE_READ(sc, NFE_PWR2_CTL) & ~NFE_PWR2_WAKEUP_MASK);
	}

	nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr);
	printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));

	/*
	 * Allocate Tx and Rx rings.
	 */
	if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) {
		printf("%s: could not allocate Tx ring\n",
		    sc->sc_dev.dv_xname);
		return;
	}

	if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) {
		printf("%s: could not allocate Rx ring\n",
		    sc->sc_dev.dv_xname);
		nfe_free_tx_ring(sc, &sc->txq);
		return;
	}

	ifp = &sc->sc_arpcom.ac_if;
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = nfe_ioctl;
	ifp->if_start = nfe_start;
	ifp->if_watchdog = nfe_watchdog;
	IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);
	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);

	ifp->if_capabilities = IFCAP_VLAN_MTU;

#ifndef SMALL_KERNEL
	ifp->if_capabilities |= IFCAP_WOL;
	ifp->if_wol = nfe_wol;
	nfe_wol(ifp, 0);
#endif

#if NVLAN > 0
	if (sc->sc_flags & NFE_HW_VLAN)
		ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
#endif

	if (sc->sc_flags & NFE_HW_CSUM) {
		ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
		    IFCAP_CSUM_UDPv4;
	}

	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = nfe_miibus_readreg;
	sc->sc_mii.mii_writereg = nfe_miibus_writereg;
	sc->sc_mii.mii_statchg = nfe_miibus_statchg;

	ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd,
	    nfe_ifmedia_sts);
	mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 0, 0);
	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL,
		    0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);

	if_attach(ifp);
	ether_ifattach(ifp);

	timeout_set(&sc->sc_tick_ch, nfe_tick, sc);
}
Beispiel #22
0
static void
iavc_pci_attach(device_t parent, device_t self, void *aux)
{
	struct iavc_pci_softc *psc = device_private(self);
	struct iavc_softc *sc = &psc->sc_iavc;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	const struct iavc_pci_product *pp;
	pci_intr_handle_t ih;
	const char *intrstr;
	int ret;
	char intrbuf[PCI_INTRSTR_LEN];

	pp = find_cardname(pa);
	if (pp == NULL)
		return;

	sc->sc_dev = self;
	sc->sc_t1 = 0;
	sc->sc_dma = 0;
	sc->dmat = pa->pa_dmat;

	if (pci_mapreg_map(pa, IAVC_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0,
		&sc->sc_io_bt, &sc->sc_io_bh, &psc->io_base, &psc->io_size)) {
		aprint_error(": unable to map i/o registers\n");
		return;
	}

	if (pci_mapreg_map(pa, IAVC_PCI_MMBA, PCI_MAPREG_TYPE_MEM, 0,
	     &sc->sc_mem_bt, &sc->sc_mem_bh, &psc->mem_base, &psc->mem_size)) {
		aprint_error(": unable to map mem registers\n");
		return;
	}
	aprint_normal(": %s\n", pp->name);

	iavc_b1dma_reset(sc);

	if (pp->npp_product == PCI_PRODUCT_AVM_T1) {
		aprint_error_dev(sc->sc_dev, "sorry, PRI not yet supported\n");
		return;

#if 0
		sc->sc_capi.card_type = CARD_TYPEC_AVM_T1_PCI;
		sc->sc_capi.sc_nbch = NBCH_PRI;
		ret = iavc_t1_detect(sc);
		if (ret) {
			if (ret < 6) {
				aprint_error_dev(sc->sc_dev, "no card detected?\n");
			} else {
				aprint_error_dev(sc->sc_dev, "black box not on\n");
			}
			return;
		} else {
			sc->sc_dma = 1;
			sc->sc_t1 = 1;
		}
#endif

	} else if (pp->npp_product == PCI_PRODUCT_AVM_B1) {
		sc->sc_capi.card_type = CARD_TYPEC_AVM_B1_PCI;
		sc->sc_capi.sc_nbch = NBCH_BRI;
		ret = iavc_b1dma_detect(sc);
		if (ret) {
			ret = iavc_b1_detect(sc);
			if (ret) {
				aprint_error_dev(sc->sc_dev, "no card detected?\n");
				return;
			}
		} else {
			sc->sc_dma = 1;
		}
	}
	if (sc->sc_dma)
		iavc_b1dma_reset(sc);

#if 0
	/*
         * XXX: should really be done this way, but this freezes the card
         */
	if (sc->sc_t1)
		iavc_t1_reset(sc);
	else
		iavc_b1_reset(sc);
#endif

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
		return;
	}

	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, iavc_pci_intr, psc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	psc->sc_pc = pc;
	aprint_normal("%s: interrupting at %s\n", device_xname(sc->sc_dev), intrstr);

	memset(&sc->sc_txq, 0, sizeof(struct ifqueue));
	sc->sc_txq.ifq_maxlen = sc->sc_capi.sc_nbch * 4;

	sc->sc_intr = 0;
	sc->sc_state = IAVC_DOWN;
	sc->sc_blocked = 0;

	/* setup capi link */
	sc->sc_capi.load = iavc_load;
	sc->sc_capi.reg_appl = iavc_register;
	sc->sc_capi.rel_appl = iavc_release;
	sc->sc_capi.send = iavc_send;
	sc->sc_capi.ctx = (void *) sc;

	/* lock & load DMA for TX */
	if ((ret = bus_dmamem_alloc(sc->dmat, IAVC_DMA_SIZE, PAGE_SIZE, 0,
	    &sc->txseg, 1, &sc->ntxsegs, BUS_DMA_ALLOCNOW)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't allocate tx DMA memory, error = %d\n",
		    ret);
		goto fail1;
	}

	if ((ret = bus_dmamem_map(sc->dmat, &sc->txseg, sc->ntxsegs,
	    IAVC_DMA_SIZE, &sc->sc_sendbuf, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't map tx DMA memory, error = %d\n",
		    ret);
		goto fail2;
	}

	if ((ret = bus_dmamap_create(sc->dmat, IAVC_DMA_SIZE, 1,
	    IAVC_DMA_SIZE, 0, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT,
	    &sc->tx_map)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't create tx DMA map, error = %d\n",
		    ret);
		goto fail3;
	}

	if ((ret = bus_dmamap_load(sc->dmat, sc->tx_map, sc->sc_sendbuf,
	    IAVC_DMA_SIZE, NULL, BUS_DMA_WRITE | BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't load tx DMA map, error = %d\n",
		    ret);
		goto fail4;
	}

	/* do the same for RX */
	if ((ret = bus_dmamem_alloc(sc->dmat, IAVC_DMA_SIZE, PAGE_SIZE, 0,
	    &sc->rxseg, 1, &sc->nrxsegs, BUS_DMA_ALLOCNOW)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't allocate rx DMA memory, error = %d\n",
		    ret);
		goto fail5;
	}

	if ((ret = bus_dmamem_map(sc->dmat, &sc->rxseg, sc->nrxsegs,
	    IAVC_DMA_SIZE, &sc->sc_recvbuf, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't map rx DMA memory, error = %d\n",
		    ret);
		goto fail6;
	}

	if ((ret = bus_dmamap_create(sc->dmat, IAVC_DMA_SIZE, 1, IAVC_DMA_SIZE,
	    0, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, &sc->rx_map)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't create rx DMA map, error = %d\n",
		    ret);
		goto fail7;
	}

	if ((ret = bus_dmamap_load(sc->dmat, sc->rx_map, sc->sc_recvbuf,
	    IAVC_DMA_SIZE, NULL, BUS_DMA_READ | BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "can't load rx DMA map, error = %d\n",
		    ret);
		goto fail8;
	}

	if (capi_ll_attach(&sc->sc_capi, device_xname(sc->sc_dev), pp->name)) {
		aprint_error_dev(sc->sc_dev, "capi attach failed\n");
		goto fail9;
	}
	return;

	/* release resources in case of failed attach */
fail9:
	bus_dmamap_unload(sc->dmat, sc->rx_map);
fail8:
	bus_dmamap_destroy(sc->dmat, sc->rx_map);
fail7:
	bus_dmamem_unmap(sc->dmat, sc->sc_recvbuf, IAVC_DMA_SIZE);
fail6:
	bus_dmamem_free(sc->dmat, &sc->rxseg, sc->nrxsegs);
fail5:
	bus_dmamap_unload(sc->dmat, sc->tx_map);
fail4:
	bus_dmamap_destroy(sc->dmat, sc->tx_map);
fail3:
	bus_dmamem_unmap(sc->dmat, sc->sc_sendbuf, IAVC_DMA_SIZE);
fail2:
	bus_dmamem_free(sc->dmat, &sc->txseg, sc->ntxsegs);
fail1:
	pci_intr_disestablish(psc->sc_pc, psc->sc_ih);

	return;
}
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;
}
int
univ_pci_attach(struct univ_pci_data *d, struct pci_attach_args *pa, const char *name, void (*inthdl)(void *, int, int), void *intcookie)
{
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	u_int32_t reg;
	int i;

	d->pc = pc;
	strncpy(d->devname, name, sizeof(d->devname));
	d->devname[sizeof(d->devname) - 1] = '\0';

	if (pci_mapreg_map(pa, 0x10,
			   PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
			   0, &d->csrt, &d->csrh, NULL, NULL) &&
	    pci_mapreg_map(pa, 0x14,
			   PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
			   0, &d->csrt, &d->csrh, NULL, NULL) &&
	    pci_mapreg_map(pa, 0x10,
			   PCI_MAPREG_TYPE_IO,
			   0, &d->csrt, &d->csrh, NULL, NULL) &&
	    pci_mapreg_map(pa, 0x14,
			   PCI_MAPREG_TYPE_IO,
			   0, &d->csrt, &d->csrh, NULL, NULL))
		return (-1);

	/* name sure the chip is in a sane state */
	write_csr_4(d, lint_en, 0); /* mask all PCI interrupts */
	write_csr_4(d, vint_en, 0); /* mask all VME interrupts */
	write_csr_4(d, dgcs, 0x40000000); /* stop DMA activity */
	for (i = 0; i < 8; i++) {
		univ_pci_unmapvme(d, i);
		univ_pci_unmappci(d, i);
	}
	write_csr_4(d, slsi, 0); /* disable "special PCI slave image" */

	/* enable DMA */
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);

	reg = read_csr_4(d, misc_ctl);
	aprint_normal("%s: ", name);
	if (reg & 0x00020000) /* SYSCON */
		aprint_normal("VME bus controller, ");
	reg = read_csr_4(d, mast_ctl);
	aprint_normal("requesting at VME bus level %d\n", (reg >> 22) & 3);

	/* Map and establish the PCI interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error("%s: couldn't map interrupt\n", name);
		return (-1);
	}
	intrstr = pci_intr_string(pc, ih);
	/*
	 * Use a low interrupt level (the lowest?).
	 * We will raise before calling a subdevice's handler.
	 */
	d->ih = pci_intr_establish(pc, ih, IPL_BIO, univ_pci_intr, d);
	if (d->ih == NULL) {
		aprint_error("%s: couldn't establish interrupt", name);
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return (-1);
	}
	aprint_normal("%s: interrupting at %s\n", name, intrstr);

	/* handle all VME interrupts (XXX should be configurable) */
	d->vmeinthandler = inthdl;
	d->vmeintcookie = intcookie;
	write_csr_4(d, lint_stat, 0x00ff37ff); /* ack all pending IRQs */
	write_csr_4(d, lint_en, 0x000000fe); /* enable VME IRQ 1..7 */

	return (0);
}
Beispiel #25
0
/*
 * Attach this instance, and then all the sub-devices
 */
void
pcscp_attach(struct device *parent, struct device *self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct pcscp_softc *esc = (void *)self;
	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	pci_intr_handle_t ih;
	const char *intrstr;
	bus_dma_segment_t seg;
	int error, rseg;

	if (pci_mapreg_map(pa, IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0,
	     &iot, &ioh, NULL, NULL, 0)) {
		printf("%s: unable to map registers\n", sc->sc_dev.dv_xname);
		return;
	}

	sc->sc_glue = &pcscp_glue;

	esc->sc_st = iot;
	esc->sc_sh = ioh;
	esc->sc_dmat = pa->pa_dmat;

	/*
	 * XXX More of this should be in ncr53c9x_attach(), but
	 * XXX should we really poke around the chip that much in
	 * XXX the MI code?  Think about this more...
	 */

	/*
	 * Set up static configuration info.
	 */

	/*
	 * XXX should read configuration from EEPROM?
	 *
	 * MI ncr53c9x driver does not support configuration
	 * per each target device, though...
	 */
	sc->sc_id = 7;
	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
	sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE;
	sc->sc_cfg3 = NCRAMDCFG3_IDM | NCRAMDCFG3_FCLK;
	sc->sc_cfg4 = NCRAMDCFG4_GE12NS | NCRAMDCFG4_RADE;
	sc->sc_rev = NCR_VARIANT_AM53C974;
	sc->sc_features = NCR_F_FASTSCSI;
	sc->sc_cfg3_fscsi = NCRAMDCFG3_FSCSI;
	sc->sc_freq = 40; /* MHz */

	/*
	 * XXX minsync and maxxfer _should_ be set up in MI code,
	 * XXX but it appears to have some dependency on what sort
	 * XXX of DMA we're hooked up to, etc.
	 */

	/*
	 * This is the value used to start sync negotiations
	 * Note that the NCR register "SYNCTP" is programmed
	 * in "clocks per byte", and has a minimum value of 4.
	 * The SCSI period used in negotiation is one-fourth
	 * of the time (in nanoseconds) needed to transfer one byte.
	 * Since the chip's clock is given in MHz, we have the following
	 * formula: 4 * period = (1000 / freq) * 4
	 */

	sc->sc_minsync = 1000 / sc->sc_freq; 

	/* Really no limit, but since we want to fit into the TCR... */
	sc->sc_maxxfer = 16 * 1024 * 1024;

	/*
	 * Create the DMA maps for the data transfers.
         */

#define MDL_SEG_SIZE	0x1000 /* 4kbyte per segment */
#define MDL_SEG_OFFSET	0x0FFF
#define MDL_SIZE	(MAXPHYS / MDL_SEG_SIZE + 1) /* no hardware limit? */

	if (bus_dmamap_create(esc->sc_dmat, MAXPHYS, MDL_SIZE, MDL_SEG_SIZE,
	    MDL_SEG_SIZE, BUS_DMA_NOWAIT, &esc->sc_xfermap)) {
		printf("%s: can't create dma maps\n", sc->sc_dev.dv_xname);
		return;
	}

	/*
	 * Allocate and map memory for the MDL.
	 */

	if ((error = bus_dmamem_alloc(esc->sc_dmat,
	    sizeof(u_int32_t) * MDL_SIZE, PAGE_SIZE, 0, &seg, 1, &rseg,
	    BUS_DMA_NOWAIT)) != 0) {
		printf("%s: unable to allocate memory for the MDL, "
		    "error = %d\n", sc->sc_dev.dv_xname, error);
		goto fail_0;
	}
	if ((error = bus_dmamem_map(esc->sc_dmat, &seg, rseg,
	    sizeof(u_int32_t) * MDL_SIZE , (caddr_t *)&esc->sc_mdladdr,
	    BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
		printf("%s: unable to map the MDL memory, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_1;
	}
	if ((error = bus_dmamap_create(esc->sc_dmat, 
	    sizeof(u_int32_t) * MDL_SIZE, 1, sizeof(u_int32_t) * MDL_SIZE,
	    0, BUS_DMA_NOWAIT, &esc->sc_mdldmap)) != 0) {
		printf("%s: unable to map_create for the MDL, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_2;
	}
	if ((error = bus_dmamap_load(esc->sc_dmat, esc->sc_mdldmap,
	     esc->sc_mdladdr, sizeof(u_int32_t) * MDL_SIZE,
	     NULL, BUS_DMA_NOWAIT)) != 0) {
		printf("%s: unable to load for the MDL, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_3;
	}

	/* map and establish interrupt */
	if (pci_intr_map(pa, &ih)) {
		printf(": couldn't map interrupt\n");
		goto fail_4;
	}

	intrstr = pci_intr_string(pa->pa_pc, ih);
	esc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
	    ncr53c9x_intr, esc, sc->sc_dev.dv_xname);
	if (esc->sc_ih == NULL) {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto fail_4;
	}
	if (intrstr != NULL)
		printf(": %s\n", intrstr);

	/* Do the common parts of attachment. */
	printf("%s", sc->sc_dev.dv_xname);

	ncr53c9x_attach(sc, &pcscp_adapter);

	/* Turn on target selection using the `dma' method */
	sc->sc_features |= NCR_F_DMASELECT;

	return;

fail_4:
	bus_dmamap_unload(esc->sc_dmat, esc->sc_mdldmap);
fail_3:
	bus_dmamap_destroy(esc->sc_dmat, esc->sc_mdldmap);
fail_2:
	bus_dmamem_unmap(esc->sc_dmat, (caddr_t)esc->sc_mdldmap,
	    sizeof(uint32_t) * MDL_SIZE);
fail_1:
	bus_dmamem_free(esc->sc_dmat, &seg, rseg);
fail_0:
	bus_dmamap_destroy(esc->sc_dmat, esc->sc_xfermap);
}
Beispiel #26
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);
}
static void
ahci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct ahci_pci_softc *psc = device_private(self);
	struct ahci_softc *sc = &psc->ah_sc;
	const char *intrstr;
	bool ahci_cap_64bit;
	bool ahci_bad_64bit;
	pci_intr_handle_t intrhandle;

	sc->sc_atac.atac_dev = self;

	if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->sc_ahcit, &sc->sc_ahcih, NULL, &sc->sc_ahcis) != 0) {
		aprint_error_dev(self, "can't map ahci registers\n");
		return;
	}
	psc->sc_pc = pa->pa_pc;
	psc->sc_pcitag = pa->pa_tag;

	pci_aprint_devinfo(pa, "AHCI disk controller");
	
	if (pci_intr_map(pa, &intrhandle) != 0) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle);
	psc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n",
	    intrstr ? intrstr : "unknown interrupt");

	sc->sc_dmat = pa->pa_dmat;

	sc->sc_ahci_quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
					    PCI_PRODUCT(pa->pa_id));

	ahci_cap_64bit = (AHCI_READ(sc, AHCI_CAP) & AHCI_CAP_64BIT) != 0;
	ahci_bad_64bit = ((sc->sc_ahci_quirks & AHCI_PCI_QUIRK_BAD64) != 0);

	if (pci_dma64_available(pa) && ahci_cap_64bit) {
		if (!ahci_bad_64bit)
			sc->sc_dmat = pa->pa_dmat64;
		aprint_verbose_dev(self, "64-bit DMA%s\n",
		    (sc->sc_dmat == pa->pa_dmat) ? " unavailable" : "");
	}

	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) {
		AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE);
		sc->sc_atac_capflags = ATAC_CAP_RAID;
	} else {
		AHCIDEBUG_PRINT(("%s: SATA mode\n", AHCINAME(sc)), DEBUG_PROBE);
	}

	ahci_attach(sc);

	if (!pmf_device_register(self, NULL, ahci_pci_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Beispiel #28
0
void
ti_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ti_softc *sc = (struct ti_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	bus_size_t size;

	/*
	 * Map control/status registers.
	 */
	if (pci_mapreg_map(pa, TI_PCI_LOMEM,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) {
 		printf(": can't map registers\n");
		return;
 	}

	sc->sc_dmatag = pa->pa_dmat;

	if (pci_intr_map(pa, &ih)) {
		printf(": can't map interrupt\n");
		goto unmap;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc,
	    self->dv_xname);
	if (sc->ti_intrhand == NULL) {
		printf(": can't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto unmap;
	}
	printf(": %s", intrstr);

	/*
	 * We really need a better way to tell a 1000baseTX card
	 * from a 1000baseSX one, since in theory there could be
	 * OEMed 1000baseTX cards from lame vendors who aren't
	 * clever enough to change the PCI ID. For the moment
	 * though, the AceNIC is the only copper card available.
	 */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT)
		sc->ti_copper = 1;
	/* Ok, it's not the only copper card available */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T)
		sc->ti_copper = 1;

	if (ti_attach(sc) == 0)
		return;

	pci_intr_disestablish(pc, sc->ti_intrhand);

unmap:
	bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size);
}
Beispiel #29
0
static void
uhci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct uhci_pci_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;
	char const *intrstr;
	pci_intr_handle_t ih;
	pcireg_t csr;
	usbd_status r;
	int s;
	char intrbuf[PCI_INTRSTR_LEN];

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

	pci_aprint_devinfo(pa, NULL);

	/* Map I/O registers */
	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
			   &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

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

	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->sc.sc_bus.dmatag = pa->pa_dmat;

	/* Enable the device. */
	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
		       csr | PCI_COMMAND_MASTER_ENABLE);

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, uhci_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");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	/*
	 * Set LEGSUP register to its default value.
	 * This can re-enable or trigger interrupts, so protect against
	 * them and explicitly disable and ACK them afterwards.
	 */
	s = splhardusb();
	pci_conf_write(pc, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN);
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_STS,
	    bus_space_read_2(sc->sc.iot, sc->sc.ioh, UHCI_STS));
	splx(s);

	switch(pci_conf_read(pc, 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. */
	sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
	pci_findvendor(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
	    sc->sc.sc_id_vendor);
	r = uhci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		aprint_error_dev(self, "init failed, error=%d\n", r);
		return;
	}
	sc->sc_initialized = SC_INIT_UHCI;

#if NEHCI > 0
	usb_pci_add(&sc->sc_pci, pa, self);
#endif

	if (!pmf_device_register(self, uhci_suspend, uhci_pci_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
	else
		sc->sc_initialized |= SC_INIT_PMF;

	/* Attach usb device. */
	sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);
}
Beispiel #30
0
static void
cy_pci_attach(device_t parent, device_t self, void *aux)
{
	struct cy_pci_softc *psc = device_private(self);
	struct cy_softc *sc = &psc->sc_cy;
	struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	const struct cy_pci_product *cp;
	const char *intrstr;
	int plx_ver;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc_dev = self;

	aprint_naive(": Multi-port serial controller\n");

	sc->sc_bustype = CY_BUSTYPE_PCI;

	cp = cy_pci_lookup(pa);
	if (cp == NULL)
		panic("cy_pci_attach: impossible");

	aprint_normal(": Cyclades-Y multiport serial\n");

	if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_IO, 0,
	    &psc->sc_iot, &psc->sc_ioh, NULL, NULL) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to map PLX registers\n");
		return;
	}

	if (pci_mapreg_map(pa, 0x18, cp->cp_memtype, 0,
	    &sc->sc_memt, &sc->sc_bsh, NULL, NULL) != 0) {
		aprint_error_dev(sc->sc_dev,"unable to map device registers\n");
		return;
	}

	if (cy_find(sc) == 0) {
		aprint_error_dev(sc->sc_dev, "unable to find CD1400s\n");
		return;
	}

	/*
	 * XXX Like the Cyclades-Z, we should really check the EEPROM to
	 * determine the "poll or interrupt" setting.  For now, we always
	 * map the interrupt and enable it in the PLX.
	 */

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY, cy_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(sc->sc_dev, "unable to establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	cy_attach(sc);

	plx_ver = bus_space_read_1(sc->sc_memt, sc->sc_bsh, CY_PLX_VER) & 0x0f;

	/* Enable PCI card interrupts */
	switch (plx_ver) {
	case CY_PLX_9050:
		bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA_9050,
		    bus_space_read_2(psc->sc_iot, psc->sc_ioh,
		    CY_PCI_INTENA_9050) | 0x40);
		break;

	case CY_PLX_9060:
	case CY_PLX_9080:
	default:
		bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA,
		    bus_space_read_2(psc->sc_iot, psc->sc_ioh,
		    CY_PCI_INTENA) | 0x900);
	}
}