コード例 #1
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;
	int memh_valid, ioh_valid;
	bus_addr_t ioaddr, memaddr;
	bus_size_t memsize, iosize;

	pci_sc->sc_pp =
	    siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class));
	if (pci_sc->sc_pp == NULL) {
		printf(": 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
	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;
	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) == 0);
		break;
	default:
		memh_valid = 0;
	}

	ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, &ioaddr, &iosize, 0) == 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 {
		printf(": unable to map device registers\n");
		return 0;
	}

	if (pci_intr_map(pa, &intrhandle) != 0) {
		printf(": couldn't map interrupt\n");
		bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
		return 0;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle);
	pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
	    intr, siop_sc, siop_sc->sc_dev.dv_xname);
	if (pci_sc->sc_ih != NULL) {
		printf(": %s",
		    intrstr ? intrstr : "?");
	} else {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
		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:
			printf(": 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, &memsize, 0) == 0) {
			printf(", using %luK of on-board RAM",
			    (u_long)memsize / 1024);
		} else {
			printf(", can't map on-board RAM");
			siop_sc->features &= ~SF_CHIP_RAM;
		}
	}

	printf("\n");

	return 1;
}
コード例 #2
0
ファイル: ubsec.c プロジェクト: mosconi/openbsd
void
ubsec_attach(struct device *parent, struct device *self, void *aux)
{
	struct ubsec_softc *sc = (struct ubsec_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	pcireg_t memtype;
	const char *intrstr = NULL;
	struct ubsec_dma *dmap;
	bus_size_t iosize;
	u_int32_t i;
	int algs[CRYPTO_ALGORITHM_MAX + 1];

	SIMPLEQ_INIT(&sc->sc_queue);
	SIMPLEQ_INIT(&sc->sc_qchip);
	SIMPLEQ_INIT(&sc->sc_queue2);
	SIMPLEQ_INIT(&sc->sc_qchip2);
	SIMPLEQ_INIT(&sc->sc_queue4);
	SIMPLEQ_INIT(&sc->sc_qchip4);

	sc->sc_statmask = BS_STAT_MCR1_DONE | BS_STAT_DMAERR;
	sc->sc_maxaggr = UBS_MIN_AGGR;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BLUESTEEL &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BLUESTEEL_5601)
		sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5802 ||
	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5805))
		sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5820 ||
	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5822))
		sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG |
		    UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY;

	if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5821) ||
	    (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN &&
	     (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SCA1K ||
	      PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_5821))) {
		sc->sc_statmask |= BS_STAT_MCR1_ALLEMPTY |
		    BS_STAT_MCR2_ALLEMPTY;
		sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG |
		    UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY;
	}

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5823 ||
	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5825))
		sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG |
		    UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY |
		    UBS_FLAGS_AES;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5860 ||
	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5861 ||
	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5862)) {
		sc->sc_maxaggr = UBS_MAX_AGGR;
		sc->sc_statmask |=
		    BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY |
		    BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY;
		sc->sc_flags |= UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM |
		    UBS_FLAGS_LONGCTX | UBS_FLAGS_AES |
		    UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY;
#if 0
		/* The RNG is not yet supported */
		sc->sc_flags |= UBS_FLAGS_RNG | UBS_FLAGS_RNG4;
#endif
	}

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BS_BAR);
	if (pci_mapreg_map(pa, BS_BAR, memtype, 0,
	    &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0)) {
		printf(": can't find mem space\n");
		return;
	}
	sc->sc_dmat = pa->pa_dmat;

	if (pci_intr_map(pa, &ih)) {
		printf(": couldn't map interrupt\n");
		bus_space_unmap(sc->sc_st, sc->sc_sh, iosize);
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ubsec_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_st, sc->sc_sh, iosize);
		return;
	}

	sc->sc_cid = crypto_get_driverid(0);
	if (sc->sc_cid < 0) {
		pci_intr_disestablish(pc, sc->sc_ih);
		bus_space_unmap(sc->sc_st, sc->sc_sh, iosize);
		return;
	}

	SIMPLEQ_INIT(&sc->sc_freequeue);
	dmap = sc->sc_dmaa;
	for (i = 0; i < UBS_MAX_NQUEUE; i++, dmap++) {
		struct ubsec_q *q;

		q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q),
		    M_DEVBUF, M_NOWAIT);
		if (q == NULL) {
			printf(": can't allocate queue buffers\n");
			break;
		}

		if (ubsec_dma_malloc(sc, sizeof(struct ubsec_dmachunk),
		    &dmap->d_alloc, 0)) {
			printf(": can't allocate dma buffers\n");
			free(q, M_DEVBUF, 0);
			break;
		}
		dmap->d_dma = (struct ubsec_dmachunk *)dmap->d_alloc.dma_vaddr;

		q->q_dma = dmap;
		sc->sc_queuea[i] = q;

		SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next);
	}

	bzero(algs, sizeof(algs));
	algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
	algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
	algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
	if (sc->sc_flags & UBS_FLAGS_AES)
		algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
	crypto_register(sc->sc_cid, algs, ubsec_newsession,
	    ubsec_freesession, ubsec_process);

	/*
	 * Reset Broadcom chip
	 */
	ubsec_reset_board(sc);

	/*
	 * Init Broadcom specific PCI settings
	 */
	ubsec_init_pciregs(pa);

	/*
	 * Init Broadcom chip
	 */
	ubsec_init_board(sc);

	printf(": 3DES MD5 SHA1");
	if (sc->sc_flags & UBS_FLAGS_AES)
		printf(" AES");

#ifndef UBSEC_NO_RNG
	if (sc->sc_flags & UBS_FLAGS_RNG) {
		if (sc->sc_flags & UBS_FLAGS_RNG4)
			sc->sc_statmask |= BS_STAT_MCR4_DONE;
		else
			sc->sc_statmask |= BS_STAT_MCR2_DONE;

		if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr),
		    &sc->sc_rng.rng_q.q_mcr, 0))
			goto skip_rng;

		if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rngbypass),
		    &sc->sc_rng.rng_q.q_ctx, 0)) {
			ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr);
			goto skip_rng;
		}

		if (ubsec_dma_malloc(sc, sizeof(u_int32_t) *
		    UBSEC_RNG_BUFSIZ, &sc->sc_rng.rng_buf, 0)) {
			ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx);
			ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr);
			goto skip_rng;
		}

		timeout_set(&sc->sc_rngto, ubsec_rng, sc);
		if (hz >= 100)
			sc->sc_rnghz = hz / 100;
		else
			sc->sc_rnghz = 1;
		timeout_add(&sc->sc_rngto, sc->sc_rnghz);
		printf(" RNG");
skip_rng:
	;
	}
#endif /* UBSEC_NO_RNG */

	if (sc->sc_flags & UBS_FLAGS_KEY) {
		sc->sc_statmask |= BS_STAT_MCR2_DONE;
	}

	printf(", %s\n", intrstr);
}
コード例 #3
0
static void
malo_pci_attach(device_t parent, device_t self, void *aux)
{
	struct malo_pci_softc *psc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct malo_softc *sc = &psc->sc_malo;
	const char *intrstr = NULL;
	pci_intr_handle_t ih;
	pcireg_t memtype1, memtype2;
	int error;

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

	aprint_normal("\n");
	aprint_normal_dev(self,"Marvell Libertas Wireless\n");

	/* map control / status registers */
	memtype1 = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MALO_PCI_BAR1);
	switch (memtype1) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		break;
	default:
		aprint_error_dev(self, "invalid base address register\n");
		return;
	}

	error = pci_mapreg_map(pa, MALO_PCI_BAR1,
	    memtype1, 0, &sc->sc_mem1_bt, &sc->sc_mem1_bh,
		NULL, &psc->sc_mapsize1);
	if (error != 0) {
		aprint_error_dev(self, "can't map 1st mem space\n");
		return;
	}

	/* map control / status registers */
	memtype2 = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MALO_PCI_BAR1);
	switch (memtype2) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		break;
	default:
		aprint_error_dev(self, "invalid base address register\n");
		return;
	}

	error = pci_mapreg_map(pa, MALO_PCI_BAR2,
	    memtype2, 0, &sc->sc_mem2_bt, &sc->sc_mem2_bh,
		NULL, &psc->sc_mapsize2);
	if (error != 0) {
		aprint_error_dev(self, "can't map 2nd mem space\n");
		return;
	}

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

	/* establish interrupt */
	intrstr = pci_intr_string(psc->sc_pc, ih);
	psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET, malo_intr, sc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(self, "could not establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	malo_attach(sc);

	if (pmf_device_register(self, malo_pci_suspend, malo_pci_resume))
		pmf_class_network_register(self, &sc->sc_if);
	else
		aprint_error_dev(self, "couldn't establish power handler\n");
}
コード例 #4
0
ファイル: radeon_kms.c プロジェクト: ajinkya93/OpenBSD
/**
 * radeon_driver_load_kms - Main load function for KMS.
 *
 * @dev: drm dev pointer
 * @flags: device flags
 *
 * This is the main load function for KMS (all asics).
 * It calls radeon_device_init() to set up the non-display
 * parts of the chip (asic init, CP, writeback, etc.), and
 * radeon_modeset_init() to set up the display parts
 * (crtcs, encoders, hotplug detect, etc.).
 * Returns 0 on success, error on failure.
 */
void
radeondrm_attach_kms(struct device *parent, struct device *self, void *aux)
{
	struct radeon_device	*rdev = (struct radeon_device *)self;
	struct drm_device	*dev;
	struct pci_attach_args	*pa = aux;
	const struct drm_pcidev *id_entry;
	int			 is_agp;
	pcireg_t		 type;
	uint8_t			 iobar;
#if !defined(__sparc64__)
	pcireg_t		 addr, mask;
	int			 s;
#endif

#if defined(__sparc64__) || defined(__macppc__)
	extern int fbnode;
#endif

	id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
	    PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist);
	rdev->flags = id_entry->driver_data;
	rdev->pc = pa->pa_pc;
	rdev->pa_tag = pa->pa_tag;
	rdev->iot = pa->pa_iot;
	rdev->memt = pa->pa_memt;
	rdev->dmat = pa->pa_dmat;

#if defined(__sparc64__) || defined(__macppc__)
	if (fbnode == PCITAG_NODE(rdev->pa_tag))
		rdev->console = 1;
#else
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA &&
	    (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG)
	    & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE))
	    == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) {
		rdev->console = 1;
#if NVGA > 0
		vga_console_attached = 1;
#endif
	}
#if NEFIFB > 0
	if (efifb_is_console(pa)) {
		rdev->console = 1;
		efifb_cndetach();
	}
#endif
#endif

#define RADEON_PCI_MEM		0x10
#define RADEON_PCI_IO		0x14
#define RADEON_PCI_MMIO		0x18
#define RADEON_PCI_IO2		0x20

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM,
	    type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) {
		printf(": can't get frambuffer info\n");
		return;
	}

	if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT)
		iobar = RADEON_PCI_IO;
	else
		iobar = RADEON_PCI_IO2;
	
	if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0,
	    NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) {
		printf(": can't map IO space\n");
		return;
	}

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL,
	    &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) {
		printf(": can't map mmio space\n");
		return;
	}

#if !defined(__sparc64__)
	/*
	 * Make sure we have a base address for the ROM such that we
	 * can map it later.
	 */
	s = splhigh();
	addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE);
	mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr);
	splx(s);

	if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) {
		bus_size_t size, start, end;
		bus_addr_t base;

		size = PCI_ROM_SIZE(mask);
		start = max(PCI_MEM_START, pa->pa_memex->ex_start);
		end = min(PCI_MEM_END, pa->pa_memex->ex_end);
		if (extent_alloc_subregion(pa->pa_memex, start, end, size,
		    size, 0, 0, 0, &base) == 0)
			pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, base);
	}
#endif

#ifdef notyet
	mtx_init(&rdev->swi_lock, IPL_TTY);
#endif

	/* update BUS flag */
	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) {
		rdev->flags |= RADEON_IS_AGP;
	} else if (pci_get_capability(pa->pa_pc, pa->pa_tag,
	    PCI_CAP_PCIEXPRESS, NULL, NULL)) {
		rdev->flags |= RADEON_IS_PCIE;
	} else {
		rdev->flags |= RADEON_IS_PCI;
	}

	DRM_DEBUG("%s card detected\n",
		 ((rdev->flags & RADEON_IS_AGP) ? "AGP" :
		 (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));

	is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
	    NULL, NULL);

	printf("\n");

	kms_driver.num_ioctls = radeon_max_kms_ioctl;

	dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp,
	    rdev->console, self);
	rdev->ddev = dev;
	rdev->pdev = dev->pdev;

	rdev->family = rdev->flags & RADEON_FAMILY_MASK;
	if (!radeon_msi_ok(rdev))
		pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED;

	rdev->msi_enabled = 0;
	if (pci_intr_map_msi(pa, &rdev->intrh) == 0)
		rdev->msi_enabled = 1;
	else if (pci_intr_map(pa, &rdev->intrh) != 0) {
		printf(": couldn't map interrupt\n");
		return;
	}
	printf("%s: %s\n", rdev->dev.dv_xname,
	    pci_intr_string(pa->pa_pc, rdev->intrh));

	rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY,
	    radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname);
	if (rdev->irqh == NULL) {
		printf("%s: couldn't establish interrupt\n",
		    rdev->dev.dv_xname);
		return;
	}

#ifdef __sparc64__
{
	struct rasops_info *ri;
	int node, console;

	node = PCITAG_NODE(pa->pa_tag);
	console = (fbnode == node);

	fb_setsize(&rdev->sf, 8, 1152, 900, node, 0);

	/*
	 * The firmware sets up the framebuffer such that at starts at
	 * an offset from the start of video memory.
	 */
	rdev->fb_offset =
	    bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET);
	if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset,
	    rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) {
		printf("%s: can't map video memory\n", rdev->dev.dv_xname);
		return;
	}

	ri = &rdev->sf.sf_ro;
	ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh);
	ri->ri_hw = rdev;
	ri->ri_updatecursor = NULL;

	fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console);
	if (console)
		fbwscons_console_init(&rdev->sf, -1);
}
#endif

	rdev->shutdown = true;
	config_mountroot(self, radeondrm_attachhook);
}
コード例 #5
0
void
sili_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct sili_pci_softc		*psc = (void *)self;
	struct sili_softc		*sc = &psc->psc_sili;
	struct pci_attach_args		*pa = aux;
	const struct sili_device	*sd;
	pcireg_t			memtype;
	pci_intr_handle_t		ih;
	const char			*intrstr;

	sd = sili_lookup(pa);

	psc->psc_pc = pa->pa_pc;
	psc->psc_tag = pa->pa_tag;
	psc->psc_ih = NULL;
	sc->sc_dmat = pa->pa_dmat;
	sc->sc_ios_global = 0;
	sc->sc_ios_port = 0;
	sc->sc_nports = sd->sd_nports;

	memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag,
	    SILI_PCI_BAR_GLOBAL);
	if (pci_mapreg_map(pa, SILI_PCI_BAR_GLOBAL, memtype, 0,
	    &sc->sc_iot_global, &sc->sc_ioh_global,
	    NULL, &sc->sc_ios_global, 0) != 0) {
		printf(": unable to map global registers\n");
		return;
	}

	memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag,
	    SILI_PCI_BAR_PORT);
	if (pci_mapreg_map(pa, SILI_PCI_BAR_PORT, memtype, 0,
	    &sc->sc_iot_port, &sc->sc_ioh_port,
	    NULL, &sc->sc_ios_port, 0) != 0) {
		printf(": unable to map port registers\n");
		goto unmap_global;
	}

	/* hook up the interrupt */
	if (pci_intr_map(pa, &ih)) {
		printf(": unable to map interrupt\n");
		goto unmap_port;
	}
	intrstr = pci_intr_string(psc->psc_pc, ih);
	psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
	    sili_intr, sc, sc->sc_dev.dv_xname);
	if (psc->psc_ih == NULL) {
		printf(": unable to map interrupt%s%s\n",
		    intrstr == NULL ? "" : " at ",
		    intrstr == NULL ? "" : intrstr);
		goto unmap_port;
	}
	printf(": %s", intrstr);

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

	return;

deintr:
	pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
	psc->psc_ih = NULL;
unmap_port:
	bus_space_unmap(sc->sc_iot_port, sc->sc_ioh_port, sc->sc_ios_port);
	sc->sc_ios_port = 0;
unmap_global:
	bus_space_unmap(sc->sc_iot_global, sc->sc_ioh_global,
	    sc->sc_ios_global);
	sc->sc_ios_global = 0;
}
コード例 #6
0
ファイル: if_ath_pci.c プロジェクト: orumin/openbsd-efivars
void
ath_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ath_pci_softc *psc = (struct ath_pci_softc *)self;
	struct ath_softc *sc = &psc->sc_sc;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t pt = pa->pa_tag;
	pci_intr_handle_t ih;
	pcireg_t mem_type;
	const char *intrstr = NULL;

	psc->sc_pc = pc;
	psc->sc_pcitag = pt;

	/* 
	 * Setup memory-mapping of PCI registers.
	 */
	mem_type = pci_mapreg_type(pc, pa->pa_tag, ATH_BAR0);
	if (mem_type != PCI_MAPREG_TYPE_MEM &&
	    mem_type != PCI_MAPREG_MEM_TYPE_64BIT) {
		printf(": bad PCI register type %d\n", (int)mem_type);
		goto fail;
	}
	if (pci_mapreg_map(pa, ATH_BAR0, mem_type, 0, &sc->sc_st, &sc->sc_sh,
	    NULL, &sc->sc_ss, 0)) {
		printf(": can't map register space\n");
		goto fail;
	}

	/*
	 * PCI Express check.
	 */
	if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
	    NULL, NULL) != 0)
		sc->sc_pcie = 1;

	sc->sc_invalid = 1;

	/*
	 * Arrange interrupt line.
	 */
	if (pci_intr_map(pa, &ih)) {
		printf(": can't map interrupt\n");
		goto unmap;
	}

	intrstr = pci_intr_string(pc, ih);
	psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ath_intr, sc,
	    sc->sc_dev.dv_xname);
	if (psc->sc_ih == NULL) {
		printf(": can't map interrupt\n");
		goto unmap;
	}

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

	sc->sc_dmat = pa->pa_dmat;

	if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) == 0)
		return;

	pci_intr_disestablish(pc, psc->sc_ih);
unmap:
	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_ss);
fail:
	return;
}
コード例 #7
0
ファイル: siisata_pci.c プロジェクト: lacombar/netbsd-alc
static void
siisata_pci_attach(device_t parent, device_t self, void *aux)
{
    struct pci_attach_args *pa = aux;
    struct siisata_pci_softc *psc = device_private(self);
    struct siisata_softc *sc = &psc->si_sc;
    char devinfo[256];
    const char *intrstr;
    pci_intr_handle_t intrhandle;
    pcireg_t csr, memtype;
    const struct siisata_pci_product *spp;
    void *ih;
    bus_space_tag_t memt;
    bus_space_handle_t memh;
    uint32_t gcreg;
    int memh_valid;
    bus_size_t grsize, prsize;

    sc->sc_atac.atac_dev = self;

    psc->sc_pc = pa->pa_pc;
    psc->sc_pcitag = pa->pa_tag;

    pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo));
    aprint_naive(": SATA-II HBA\n");
    aprint_normal(": %s\n", devinfo);

    /* map bar0 */
#if 1
    memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR0);
#else
    memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT;
#endif
    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, SIISATA_PCI_BAR0,
                                     memtype, 0, &memt, &memh, NULL, &grsize) == 0);
        break;
    default:
        memh_valid = 0;
    }
    if (memh_valid) {
        sc->sc_grt = memt;
        sc->sc_grh = memh;
    } else {
        aprint_error("%s: unable to map device global registers\n",
                     SIISATANAME(sc));
        return;
    }

    /* map bar1 */
#if 1
    memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR1);
#else
    memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT;
#endif
    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, SIISATA_PCI_BAR1,
                                     memtype, 0, &memt, &memh, NULL, &prsize) == 0);
        break;
    default:
        memh_valid = 0;
    }
    if (memh_valid) {
        sc->sc_prt = memt;
        sc->sc_prh = memh;
    } else {
        bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize);
        aprint_error("%s: unable to map device port registers\n",
                     SIISATANAME(sc));
        return;
    }

    if (pci_dma64_available(pa)) {
        sc->sc_dmat = pa->pa_dmat64;
        sc->sc_have_dma64 = 1;
        aprint_debug("64-bit PCI DMA available\n");
    } else {
        sc->sc_dmat = pa->pa_dmat;
        sc->sc_have_dma64 = 0;
    }

    /* map interrupt */
    if (pci_intr_map(pa, &intrhandle) != 0) {
        bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize);
        bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize);
        aprint_error("%s: couldn't map interrupt\n", SIISATANAME(sc));
        return;
    }
    intrstr = pci_intr_string(pa->pa_pc, intrhandle);
    ih = pci_intr_establish(pa->pa_pc, intrhandle,
                            IPL_BIO, siisata_intr, sc);
    if (ih == NULL) {
        bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize);
        bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize);
        aprint_error("%s: couldn't establish interrupt"
                     "at %s\n", SIISATANAME(sc), intrstr);
        return;
    }
    aprint_normal("%s: interrupting at %s\n", SIISATANAME(sc),
                  intrstr ? intrstr : "unknown interrupt");

    /* fill in number of ports on this device */
    spp = siisata_pci_lookup(pa);
    if (spp != NULL) {
        sc->sc_atac.atac_nchannels = spp->spp_ports;
        sc->sc_chip = spp->spp_chip;
    } else
        /* _match() should prevent us from getting here */
        panic("siisata: the universe might be falling apart!\n");

    gcreg = GRREAD(sc, GR_GC);

    aprint_normal("%s: SiI%d on ", SIISATANAME(sc), sc->sc_chip);
    if (sc->sc_chip == 3124) {
        aprint_normal("%d-bit, ", (gcreg & GR_GC_REQ64) ? 64 : 32);
        switch (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) {
        case 0:
            aprint_normal("%d", (gcreg & GR_GC_M66EN) ? 66 : 33);
            break;
        case GR_GC_TRDY:
            aprint_normal("%d", 66);
            break;
        case GR_GC_STOP:
            aprint_normal("%d", 100);
            break;
        case GR_GC_STOP | GR_GC_TRDY:
            aprint_normal("%d", 133);
            break;
        default:
            break;
        }
        aprint_normal("MHz PCI%s bus.", (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) ? "-X" : "");
    } else {
        /* XXX - but only x1 devices so far */
        aprint_normal("PCI-Express x1 port.");
    }
    if (gcreg & GR_GC_3GBPS)
        aprint_normal(" 3.0Gb/s capable.\n");
    else
        aprint_normal("\n");

    /* enable bus mastering in case the firmware didn't */
    csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
    csr |= PCI_COMMAND_MASTER_ENABLE;
    csr |= PCI_COMMAND_MEM_ENABLE;
    pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr);

    siisata_attach(sc);

    if (!pmf_device_register(self, NULL, siisata_pci_resume))
        aprint_error_dev(self, "couldn't establish power handler\n");
}
コード例 #8
0
ファイル: if_rtwn.c プロジェクト: mosconi/openbsd
void
rtwn_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct rtwn_pci_softc *sc = (struct rtwn_pci_softc*)self;
	struct pci_attach_args *pa = aux;
	struct ifnet *ifp;
	int i, error;
	pcireg_t memtype;
	pci_intr_handle_t ih;
	const char *intrstr;

	sc->sc_dmat = pa->pa_dmat;
	sc->sc_pc = pa->pa_pc;
	sc->sc_tag = pa->pa_tag;

	timeout_set(&sc->calib_to, rtwn_calib_to, sc);
	timeout_set(&sc->scan_to, rtwn_scan_to, sc);

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

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

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

	/* Disable PCIe Active State Power Management (ASPM). */
	if (pci_get_capability(sc->sc_pc, sc->sc_tag, PCI_CAP_PCIEXPRESS,
	    &sc->sc_cap_off, NULL)) {
		uint32_t lcsr = pci_conf_read(sc->sc_pc, sc->sc_tag,
		    sc->sc_cap_off + PCI_PCIE_LCSR);
		lcsr &= ~(PCI_PCIE_LCSR_ASPM_L0S | PCI_PCIE_LCSR_ASPM_L1);
		pci_conf_write(sc->sc_pc, sc->sc_tag,
		    sc->sc_cap_off + PCI_PCIE_LCSR, lcsr);
	}

	/* Allocate Tx/Rx buffers. */
	error = rtwn_alloc_rx_list(sc);
	if (error != 0) {
		printf("%s: could not allocate Rx buffers\n",
		    sc->sc_dev.dv_xname);
		return;
	}
	for (i = 0; i < RTWN_NTXQUEUES; i++) {
		error = rtwn_alloc_tx_list(sc, i);
		if (error != 0) {
			printf("%s: could not allocate Tx buffers\n",
			    sc->sc_dev.dv_xname);
			rtwn_free_rx_list(sc);
			return;
		}
	}

	/* Attach the bus-agnostic driver. */
	sc->sc_sc.sc_ops.cookie = sc;
	sc->sc_sc.sc_ops.write_1 = rtwn_pci_write_1;
	sc->sc_sc.sc_ops.write_2 = rtwn_pci_write_2;
	sc->sc_sc.sc_ops.write_4 = rtwn_pci_write_4;
	sc->sc_sc.sc_ops.read_1 = rtwn_pci_read_1;
	sc->sc_sc.sc_ops.read_2 = rtwn_pci_read_2;
	sc->sc_sc.sc_ops.read_4 = rtwn_pci_read_4;
	sc->sc_sc.sc_ops.tx = rtwn_tx;
	sc->sc_sc.sc_ops.power_on = rtwn_power_on;
	sc->sc_sc.sc_ops.dma_init = rtwn_dma_init;
	sc->sc_sc.sc_ops.load_firmware = rtwn_pci_load_firmware;
	sc->sc_sc.sc_ops.fw_loadpage = rtwn_fw_loadpage;
	sc->sc_sc.sc_ops.mac_init = rtwn_mac_init;
	sc->sc_sc.sc_ops.bb_init = rtwn_bb_init;
	sc->sc_sc.sc_ops.alloc_buffers = rtwn_alloc_buffers;
	sc->sc_sc.sc_ops.init = rtwn_pci_init;
	sc->sc_sc.sc_ops.stop = rtwn_pci_stop;
	sc->sc_sc.sc_ops.is_oactive = rtwn_is_oactive;
	sc->sc_sc.sc_ops.next_calib = rtwn_next_calib;
	sc->sc_sc.sc_ops.cancel_calib = rtwn_cancel_calib;
	sc->sc_sc.sc_ops.next_scan = rtwn_pci_next_scan;
	sc->sc_sc.sc_ops.cancel_scan = rtwn_cancel_scan;
	sc->sc_sc.sc_ops.wait_async = rtwn_wait_async;
	error = rtwn_attach(&sc->sc_dev, &sc->sc_sc,
	    RTWN_CHIP_88C | RTWN_CHIP_PCI);
	if (error != 0) {
		rtwn_free_rx_list(sc);
		for (i = 0; i < RTWN_NTXQUEUES; i++)
			rtwn_free_tx_list(sc, i);
		return;
	}

	/* ifp is now valid */
	ifp = &sc->sc_sc.sc_ic.ic_if;
#if NBPFILTER > 0
	bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);

	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
	sc->sc_rxtap.wr_ihdr.it_present = htole32(RTWN_RX_RADIOTAP_PRESENT);

	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
	sc->sc_txtap.wt_ihdr.it_present = htole32(RTWN_TX_RADIOTAP_PRESENT);
#endif
}
コード例 #9
0
void
sf_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct sf_pci_softc *psc = (void *) self;
	struct sf_softc *sc = &psc->sc_starfire;
	struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	int state, ioh_valid, memh_valid;
	bus_size_t iosize, memsize;
	pcireg_t reg;

	state = pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
	if (state == PCI_PMCSR_STATE_D3) {
		printf(": unable to wake up from power state D3, "
		    "reboot required.\n");
		return;
	}

	/*
	 * Map the device.
	 */
	reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SF_PCI_MEMBA);
	switch (reg) {
	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, SF_PCI_MEMBA,
		    reg, 0, &memt, &memh, &memsize, NULL, 0) == 0);
		break;
	default:
		memh_valid = 0;
	}

	ioh_valid = (pci_mapreg_map(pa,
	    (reg == (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) ?
		SF_PCI_IOBA : SF_PCI_IOBA - 0x04,
	    PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, &iosize, NULL, 0) == 0);

	if (memh_valid) {
		sc->sc_st = memt;
		sc->sc_sh = memh;
		sc->sc_iomapped = 0;
	} else if (ioh_valid) {
		sc->sc_st = iot;
		sc->sc_sh = ioh;
		sc->sc_iomapped = 1;
	} else {
		printf(": unable to map device registers\n");
		return;
	}

	sc->sc_dmat = pa->pa_dmat;

	/*
	 * Map and establish our interrupt.
	 */
	if (pci_intr_map(pa, &ih)) {
		printf(": unable to map interrupt\n");
		goto out;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	psc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, sf_intr, sc,
	    self->dv_xname);
	if (psc->sc_ih == NULL) {
		printf(": unable to establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto out;
	}
	printf(": %s", intrstr);

	/*
	 * Finish off the attach.
	 */
	sf_attach(sc);
	return;

 out:
	if (ioh_valid)
		bus_space_unmap(iot, ioh, iosize);
	if (memh_valid)
		bus_space_unmap(memt, memh, memsize);
}
コード例 #10
0
ファイル: if_bwi_pci.c プロジェクト: ryo/netbsd-src
static void
bwi_pci_attach(device_t parent, device_t self, void *aux)
{
	struct bwi_pci_softc *psc = device_private(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;
	int error = 0;
	char intrbuf[PCI_INTRSTR_LEN];

	aprint_naive("\n");
	aprint_normal(": Broadcom Wireless\n");

	sc->sc_dev = self;
	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);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		break;
	default:
		aprint_error_dev(self, "invalid base address register\n");
		return;
	}

	if (pci_mapreg_map(pa, BWI_PCI_BAR0, memtype, 0, &sc->sc_mem_bt,
	    &sc->sc_mem_bh, NULL, &psc->psc_mapsize) != 0) {
		aprint_error_dev(self, "could not map mem space\n");
		return;
	}

	/* map interrupt */
	if (pci_intr_map(pa, &ih) != 0) {
		aprint_error_dev(self, "could not map interrupt\n");
		goto fail;
	}

	/* establish interrupt */
	intrstr = pci_intr_string(psc->psc_pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "could not establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		goto fail;
	}
	aprint_normal_dev(self, "interrupting at %s\n", 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);

	if (!pmf_device_register(self, bwi_suspend, bwi_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");

	error = bwi_attach(sc);
	if (error)
		goto fail;
	return;

fail:
	if (sc->sc_ih) {
		pci_intr_disestablish(psc->psc_pc, sc->sc_ih);
		sc->sc_ih = NULL;
	}
	if (psc->psc_mapsize) {
		bus_space_unmap(sc->sc_mem_bt, sc->sc_mem_bh, psc->psc_mapsize);
		psc->psc_mapsize = 0;
	}
	return;
}
コード例 #11
0
ファイル: if_vte.c プロジェクト: orumin/openbsd-efivars
void
vte_attach(struct device *parent, struct device *self, void *aux)
{
	struct vte_softc *sc = (struct vte_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;
	pcireg_t memtype;
	int error = 0;

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

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

  	/*
	 * Allocate IRQ
	 */
	intrstr = pci_intr_string(pc, ih);
	sc->sc_irq_handle = pci_intr_establish(pc, ih, IPL_NET, vte_intr, sc,
	    sc->sc_dev.dv_xname);
	if (sc->sc_irq_handle == NULL) {
		printf(": could not establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto fail;
	}
	printf(": %s", intrstr);

	sc->sc_dmat = pa->pa_dmat;
	sc->sc_pct = pa->pa_pc;
	sc->sc_pcitag = pa->pa_tag;

	/* Reset the ethernet controller. */
	vte_reset(sc);

	error = vte_dma_alloc(sc);
	if (error)
		goto fail;

	/* Load station address. */
	vte_get_macaddr(sc);

	ifp = &sc->sc_arpcom.ac_if;
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = vte_ioctl;
	ifp->if_start = vte_start;
	ifp->if_watchdog = vte_watchdog;
	IFQ_SET_MAXLEN(&ifp->if_snd, VTE_TX_RING_CNT - 1);
	IFQ_SET_READY(&ifp->if_snd);
	bcopy(sc->vte_eaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);

	ifp->if_capabilities = IFCAP_VLAN_MTU;

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

	/*
	 * Set up MII bus.
	 * BIOS would have initialized VTE_MPSCCR to catch PHY
	 * status changes so driver may be able to extract
	 * configured PHY address.  Since it's common to see BIOS
	 * fails to initialize the register(including the sample
	 * board I have), let mii(4) probe it.  This is more
	 * reliable than relying on BIOS's initialization.
	 *
	 * Advertising flow control capability to mii(4) was
	 * intentionally disabled due to severe problems in TX
	 * pause frame generation.  See vte_rxeof() for more
	 * details.
	 */
	sc->sc_miibus.mii_ifp = ifp;
	sc->sc_miibus.mii_readreg = vte_miibus_readreg;
	sc->sc_miibus.mii_writereg = vte_miibus_writereg;
	sc->sc_miibus.mii_statchg = vte_miibus_statchg;
	
	ifmedia_init(&sc->sc_miibus.mii_media, 0, vte_mediachange,
	    vte_mediastatus);
	mii_attach(self, &sc->sc_miibus, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);

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

	if_attach(ifp);
	ether_ifattach(ifp);

	timeout_set(&sc->vte_tick_ch, vte_tick, sc);
	return;
fail:
	vte_detach(&sc->sc_dev, 0);
}
コード例 #12
0
void
mpi_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct mpi_pci_softc		*psc = (void *)self;
	struct mpi_softc		*sc = &psc->psc_mpi;
	struct pci_attach_args		*pa = aux;
	pcireg_t			memtype;
	int				r;
	pci_intr_handle_t		ih;
	const char			*intrstr;
#ifdef __sparc64__
	int node;
#endif

	psc->psc_pc = pa->pa_pc;
	psc->psc_tag = pa->pa_tag;
	psc->psc_ih = NULL;
	sc->sc_dmat = pa->pa_dmat;
	sc->sc_ios = 0;
	sc->sc_target = -1;

	/* find the appropriate memory base */
	for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) {
		memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, r);
		if ((memtype & PCI_MAPREG_TYPE_MASK) == PCI_MAPREG_TYPE_MEM)
			break;
	}
	if (r >= PCI_MAPREG_END) {
		printf(": unable to locate system interface registers\n");
		return;
	}

	if (pci_mapreg_map(pa, r, memtype, 0, &sc->sc_iot, &sc->sc_ioh,
	    NULL, &sc->sc_ios, 0) != 0) {
		printf(": unable to map system interface registers\n");
		return;
	}

	/* disable the expansion rom */
	PWRITE(psc, PCI_ROM_REG, PREAD(psc, PCI_ROM_REG) & ~PCI_ROM_ENABLE);

	/* hook up the interrupt */
	if (pci_intr_map(pa, &ih)) {
		printf(": unable to map interrupt\n");
		goto unmap;
	}
	intrstr = pci_intr_string(psc->psc_pc, ih);
	psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO,
	    mpi_intr, sc, sc->sc_dev.dv_xname);
	if (psc->psc_ih == NULL) {
		printf(": unable to map interrupt%s%s\n",
		    intrstr == NULL ? "" : " at ",
		    intrstr == NULL ? "" : intrstr);
		goto unmap;
	}
	printf(": %s", intrstr);

	if (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG) ==
	    PCI_ID_CODE(PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_1030)) {
		sc->sc_flags |= MPI_F_SPI;
#ifdef __sparc64__
		/*
		 * Walk up the Open Firmware device tree until we find a
		 * "scsi-initiator-id" property.
		 */
		node = PCITAG_NODE(pa->pa_tag);
		while (node) {
			if (OF_getprop(node, "scsi-initiator-id",
			    &sc->sc_target, sizeof(sc->sc_target)) ==
			    sizeof(sc->sc_target))
				break;
			node = OF_parent(node);
		}
#endif
	}

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

	return;

deintr:
	pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
	psc->psc_ih = NULL;
unmap:
	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
	sc->sc_ios = 0;
}
コード例 #13
0
Static void
athn_pci_attach(device_t parent, device_t self, void *aux)
{
	struct athn_pci_softc *psc = device_private(self);
	struct athn_softc *sc = &psc->psc_sc;
	struct ieee80211com *ic = &sc->sc_ic;
	struct pci_attach_args *pa = aux;
	const char *intrstr;
	pcireg_t memtype, reg;
	pci_product_id_t subsysid;
	int error;

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

	sc->sc_ops.read = athn_pci_read;
	sc->sc_ops.write = athn_pci_write;
	sc->sc_ops.write_barrier = athn_pci_write_barrier;

	/*
	 * Get the offset of the PCI Express Capability Structure in PCI
	 * Configuration Space (Linux hardcodes it as 0x60.)
	 */
	error = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
	    &psc->psc_cap_off, NULL);
	if (error != 0) {	/* Found. */
		sc->sc_disable_aspm = athn_pci_disable_aspm;
		sc->sc_flags |= ATHN_FLAG_PCIE;
	}
	/*
	 * Noone knows why this shit is necessary but there are claims that
	 * not doing this may cause very frequent PCI FATAL interrupts from
	 * the card: http://bugzilla.kernel.org/show_bug.cgi?id=13483
	 */
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
	if (reg & 0xff00)
		pci_conf_write(pa->pa_pc, pa->pa_tag, 0x40, reg & ~0xff00);

	/* Change latency timer; default value yields poor results. */
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
	reg &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
	reg |= 168 << PCI_LATTIMER_SHIFT;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, reg);

	/* Determine if bluetooth is also supported (combo chip.) */
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	subsysid = PCI_PRODUCT(reg);
	if (subsysid == PCI_SUBSYSID_ATHEROS_COEX3WIRE_SA ||
	    subsysid == PCI_SUBSYSID_ATHEROS_COEX3WIRE_DA)
		sc->sc_flags |= ATHN_FLAG_BTCOEX3WIRE;
	else if (subsysid == PCI_SUBSYSID_ATHEROS_COEX2WIRE)
		sc->sc_flags |= ATHN_FLAG_BTCOEX2WIRE;

	/*
	 * Setup memory-mapping of PCI registers.
	 */
	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, ATHN_PCI_MMBA);
	if (memtype != PCI_MAPREG_TYPE_MEM &&
	    memtype != PCI_MAPREG_MEM_TYPE_64BIT) {
		aprint_error_dev(self, "bad pci register type %d\n",
		    (int)memtype);
		goto fail;
	}
	error = pci_mapreg_map(pa, ATHN_PCI_MMBA, memtype, 0, &psc->psc_iot,
	    &psc->psc_ioh, NULL, &psc->psc_mapsz);
	if (error != 0) {
		aprint_error_dev(self, "cannot map register space\n");
		goto fail;
	}

	/*
	 * Arrange interrupt line.
	 */
	if (pci_intr_map(pa, &psc->psc_pih) != 0) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		goto fail1;
	}

	intrstr = pci_intr_string(psc->psc_pc, psc->psc_pih);
	psc->psc_ih = pci_intr_establish(psc->psc_pc, psc->psc_pih, IPL_NET,
	    athn_intr, sc);
	if (psc->psc_ih == NULL) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		goto fail1;
	}

	ic->ic_ifp = &sc->sc_if;
	if (athn_attach(sc) != 0)
		goto fail2;

	aprint_verbose_dev(self, "interrupting at %s\n", intrstr);

	if (pmf_device_register(self, athn_pci_suspend, athn_pci_resume)) {
		pmf_class_network_register(self, &sc->sc_if);
		pmf_device_suspend(self, &sc->sc_qual);
	}
	else
		aprint_error_dev(self, "couldn't establish power handler\n");

	ieee80211_announce(ic);
	return;

 fail2:
	pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
	psc->psc_ih = NULL;
 fail1:
	bus_space_unmap(psc->psc_iot, psc->psc_ioh, psc->psc_mapsz);
	psc->psc_mapsz = 0;
 fail:
	return;
}
コード例 #14
0
ファイル: xhci_pci.c プロジェクト: ryoon/netbsd-xhci
static void
xhci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct xhci_pci_softc * const psc = device_private(self);
	struct xhci_softc * const sc = &psc->sc_xhci;
	struct pci_attach_args *const pa = (struct pci_attach_args *)aux;
	const pci_chipset_tag_t pc = pa->pa_pc;
	const pcitag_t tag = pa->pa_tag;
	char const *intrstr;
	pci_intr_handle_t ih;
	pcireg_t csr, memtype;
	int err;
	//const char *vendor;
	uint32_t hccparams;
	char intrbuf[PCI_INTRSTR_LEN];

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

	pci_aprint_devinfo(pa, "USB Controller");

	/* Check for quirks */
	sc->sc_xhci_quirks = xhci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
						PCI_PRODUCT(pa->pa_id));

	/* check if memory space access is enabled */
	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
#ifdef DEBUG
	printf("csr: %08x\n", csr);
#endif
	if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) {
		aprint_error_dev(self, "memory access is disabled\n");
		return;
	}

	/* map MMIO registers */
	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_CBMEM);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		if (pci_mapreg_map(pa, PCI_CBMEM, memtype, 0,
			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) {
			sc->sc_ios = 0;
			aprint_error_dev(self, "can't map mem space\n");
			return;
		}
		break;
	default:
		aprint_error_dev(self, "BAR not 64 or 32-bit MMIO\n");
		return;
		break;
	}

	psc->sc_pc = pc;
	psc->sc_tag = tag;

	hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0x10);

	if (pci_dma64_available(pa) && ((hccparams&1)==1))
		sc->sc_bus.dmatag = pa->pa_dmat64;
	else
		sc->sc_bus.dmatag = pa->pa_dmat;

	/* Enable the device. */
	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");
		goto fail;
	}

	/*
	 * Allocate IRQ
	 */
	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, xhci_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");
		goto fail;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

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

	err = xhci_init(sc);
	if (err) {
		aprint_error_dev(self, "init failed, error=%d\n", err);
		goto fail;
	}

	/* Intel chipset requires SuperSpeed enable and USB2 port routing */
	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_INTEL:
		xhci_pci_port_route(psc);
		break;
	default:
		break;
	}

	if (!pmf_device_register1(self, xhci_suspend, xhci_resume,
	                          xhci_shutdown))
		aprint_error_dev(self, "couldn't establish power handler\n");

	/* Attach usb device. */
	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
	return;

fail:
	if (sc->sc_ih) {
		pci_intr_disestablish(psc->sc_pc, sc->sc_ih);
		sc->sc_ih = NULL;
	}
	if (sc->sc_ios) {
		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
		sc->sc_ios = 0;
	}
	return;
}