Example #1
0
static int
vga_pci_enable_io(device_t dev, device_t child, int space)
{

	device_printf(dev, "child %s requested pci_enable_io\n",
	    device_get_nameunit(child));
	return (pci_enable_io(dev, space));
}
Example #2
0
static int
atiixp_pci_resume(device_t dev)
{
	struct atiixp_info *sc = pcm_getdevinfo(dev);

	atiixp_lock(sc);
	/* power up pci bus */
	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
	pci_enable_io(dev, SYS_RES_MEMORY);
	pci_enable_busmaster(dev);
	/* reset / power up aclink */
	atiixp_reset_aclink(sc);
	atiixp_unlock(sc);

	if (mixer_reinit(dev) == -1) {
		device_printf(dev, "unable to reinitialize the mixer\n");
		return ENXIO;
	}

	/*
	 * Resume channel activities. Reset channel format regardless
	 * of its previous state.
	 */
	if (sc->pch.channel) {
		if (sc->pch.fmt)
			atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt);
		if (sc->pch.active)
			atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START);
	}
	if (sc->rch.channel) {
		if (sc->rch.fmt)
			atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt);
		if (sc->rch.active)
			atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
	}

	/* enable interrupts */
	atiixp_lock(sc);
	atiixp_enable_interrupts(sc);
	atiixp_unlock(sc);

	return 0;
}
Example #3
0
static void
cbb_chipinit(struct cbb_softc *sc)
{
	uint32_t mux, sysctrl, reg;

	/* Set CardBus latency timer */
	if (pci_read_config(sc->dev, PCIR_SECLAT_2, 1) < 0x20)
		pci_write_config(sc->dev, PCIR_SECLAT_2, 0x20, 1);

	/* Set PCI latency timer */
	if (pci_read_config(sc->dev, PCIR_LATTIMER, 1) < 0x20)
		pci_write_config(sc->dev, PCIR_LATTIMER, 0x20, 1);

	/* Enable DMA, memory access for this card and I/O acces for children */
	pci_enable_busmaster(sc->dev);
	pci_enable_io(sc->dev, SYS_RES_IOPORT);
	pci_enable_io(sc->dev, SYS_RES_MEMORY);

	/* disable Legacy IO */
	switch (sc->chipset) {
	case CB_RF5C46X:
		PCI_MASK_CONFIG(sc->dev, CBBR_BRIDGECTRL,
		    & ~(CBBM_BRIDGECTRL_RL_3E0_EN |
		    CBBM_BRIDGECTRL_RL_3E2_EN), 2);
		break;
	default:
		pci_write_config(sc->dev, CBBR_LEGACY, 0x0, 4);
		break;
	}

	/* Use PCI interrupt for interrupt routing */
	PCI_MASK2_CONFIG(sc->dev, CBBR_BRIDGECTRL,
	    & ~(CBBM_BRIDGECTRL_MASTER_ABORT |
	    CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN),
	    | CBBM_BRIDGECTRL_WRITE_POST_EN,
	    2);

	/*
	 * XXX this should be a function table, ala OLDCARD.  This means
	 * that we could more easily support ISA interrupts for pccard
	 * cards if we had to.
	 */
	switch (sc->chipset) {
	case CB_TI113X:
		/*
		 * The TI 1031, TI 1130 and TI 1131 all require another bit
		 * be set to enable PCI routing of interrupts, and then
		 * a bit for each of the CSC and Function interrupts we
		 * want routed.
		 */
		PCI_MASK_CONFIG(sc->dev, CBBR_CBCTRL,
		    | CBBM_CBCTRL_113X_PCI_INTR |
		    CBBM_CBCTRL_113X_PCI_CSC | CBBM_CBCTRL_113X_PCI_IRQ_EN,
		    1);
		PCI_MASK_CONFIG(sc->dev, CBBR_DEVCTRL,
		    & ~(CBBM_DEVCTRL_INT_SERIAL |
		    CBBM_DEVCTRL_INT_PCI), 1);
		break;
	case CB_TI12XX:
		/*
		 * Some TI 12xx (and [14][45]xx) based pci cards
		 * sometimes have issues with the MFUNC register not
		 * being initialized due to a bad EEPROM on board.
		 * Laptops that this matters on have this register
		 * properly initialized.
		 *
		 * The TI125X parts have a different register.
		 *
		 * Note: Only the lower two nibbles matter. When set
		 * to 0, the MFUNC{0,1} pins are GPIO, which isn't
		 * going to work out too well because we specifically
		 * program these parts to parallel interrupt signalling
		 * elsewhere. We preserve the upper bits of this
		 * register since changing them have subtle side effects
		 * for different variants of the card and are
		 * extremely difficult to exaustively test.
		 *
		 * Also, the TI 1510/1520 changed the default for the MFUNC
		 * register from 0x0 to 0x1000 to enable IRQSER by default.
		 * We want to be careful to avoid overriding that, and the
		 * below test will do that. Should this check prove to be
		 * too permissive, we should just check against 0 and 0x1000
		 * and not touch it otherwise.
		 */
		mux = pci_read_config(sc->dev, CBBR_MFUNC, 4);
		sysctrl = pci_read_config(sc->dev, CBBR_SYSCTRL, 4);
		if ((mux & (CBBM_MFUNC_PIN0 | CBBM_MFUNC_PIN1)) == 0) {
			mux = (mux & ~CBBM_MFUNC_PIN0) |
			    CBBM_MFUNC_PIN0_INTA;
			if ((sysctrl & CBBM_SYSCTRL_INTRTIE) == 0)
				mux = (mux & ~CBBM_MFUNC_PIN1) |
				    CBBM_MFUNC_PIN1_INTB;
			pci_write_config(sc->dev, CBBR_MFUNC, mux, 4);
		}
		/*FALLTHROUGH*/
	case CB_TI125X:
		/*
		 * Disable zoom video.  Some machines initialize this
		 * improperly and exerpience has shown that this helps
		 * prevent strange behavior. We don't support zoom
		 * video anyway, so no harm can come from this.
		 */
		pci_write_config(sc->dev, CBBR_MMCTRL, 0, 4);
		break;
	case CB_O2MICRO:
		/*
		 * Issue #1: INT# generated at the same time as
		 * selected ISA IRQ.  When IREQ# or STSCHG# is active,
		 * in addition to the ISA IRQ being generated, INT#
		 * will also be generated at the same time.
		 *
		 * Some of the older controllers have an issue in
		 * which the slot's PCI INT# will be asserted whenever
		 * IREQ# or STSCGH# is asserted even if ExCA registers
		 * 03h or 05h have an ISA IRQ selected.
		 *
		 * The fix for this issue, which will work for any
		 * controller (old or new), is to set ExCA registers
		 * 3Ah (slot 0) & 7Ah (slot 1) bits 7:4 = 1010b.
		 * These bits are undocumented.  By setting this
		 * register (of each slot) to '1010xxxxb' a routing of
		 * IREQ# to INTC# and STSCHG# to INTC# is selected.
		 * Since INTC# isn't connected there will be no
		 * unexpected PCI INT when IREQ# or STSCHG# is active.
		 * However, INTA# (slot 0) or INTB# (slot 1) will
		 * still be correctly generated if NO ISA IRQ is
		 * selected (ExCA regs 03h or 05h are cleared).
		 */
		reg = exca_getb(&sc->exca[0], EXCA_O2MICRO_CTRL_C);
		reg = (reg & 0x0f) |
		    EXCA_O2CC_IREQ_INTC | EXCA_O2CC_STSCHG_INTC;
		exca_putb(&sc->exca[0], EXCA_O2MICRO_CTRL_C, reg);
		break;
	case CB_TOPIC97:
		/*
		 * Disable Zoom Video, ToPIC 97, 100.
		 */
		pci_write_config(sc->dev, TOPIC97_ZV_CONTROL, 0, 1);
		/*
		 * ToPIC 97, 100
		 * At offset 0xa1: INTERRUPT CONTROL register
		 * 0x1: Turn on INT interrupts.
		 */
		PCI_MASK_CONFIG(sc->dev, TOPIC_INTCTRL,
		    | TOPIC97_INTCTRL_INTIRQSEL, 1);
		/*
		 * ToPIC97, 100
		 * Need to assert support for low voltage cards
		 */
		exca_setb(&sc->exca[0], EXCA_TOPIC97_CTRL,
		    EXCA_TOPIC97_CTRL_LV_MASK);
		goto topic_common;
	case CB_TOPIC95:
		/*
		 * SOCKETCTRL appears to be TOPIC 95/B specific
		 */
		PCI_MASK_CONFIG(sc->dev, TOPIC95_SOCKETCTRL,
		    | TOPIC95_SOCKETCTRL_SCR_IRQSEL, 4);

	topic_common:;
		/*
		 * At offset 0xa0: SLOT CONTROL
		 * 0x80 Enable CardBus Functionality
		 * 0x40 Enable CardBus and PC Card registers
		 * 0x20 Lock ID in exca regs
		 * 0x10 Write protect ID in config regs
		 * Clear the rest of the bits, which defaults the slot
		 * in legacy mode to 0x3e0 and offset 0. (legacy
		 * mode is determined elsewhere)
		 */
		pci_write_config(sc->dev, TOPIC_SLOTCTRL,
		    TOPIC_SLOTCTRL_SLOTON |
		    TOPIC_SLOTCTRL_SLOTEN |
		    TOPIC_SLOTCTRL_ID_LOCK |
		    TOPIC_SLOTCTRL_ID_WP, 1);

		/*
		 * At offset 0xa3 Card Detect Control Register
		 * 0x80 CARDBUS enbale
		 * 0x01 Cleared for hardware change detect
		 */
		PCI_MASK2_CONFIG(sc->dev, TOPIC_CDC,
		    | TOPIC_CDC_CARDBUS, & ~TOPIC_CDC_SWDETECT, 4);
		break;
	}

	/*
	 * Need to tell ExCA registers to CSC interrupts route via PCI
	 * interrupts.  There are two ways to do this.  One is to set
	 * INTR_ENABLE and the other is to set CSC to 0.  Since both
	 * methods are mutually compatible, we do both.
	 */
	exca_putb(&sc->exca[0], EXCA_INTR, EXCA_INTR_ENABLE);
	exca_putb(&sc->exca[0], EXCA_CSC_INTR, 0);

	cbb_disable_func_intr(sc);

	/* close all memory and io windows */
	pci_write_config(sc->dev, CBBR_MEMBASE0, 0xffffffff, 4);
	pci_write_config(sc->dev, CBBR_MEMLIMIT0, 0, 4);
	pci_write_config(sc->dev, CBBR_MEMBASE1, 0xffffffff, 4);
	pci_write_config(sc->dev, CBBR_MEMLIMIT1, 0, 4);
	pci_write_config(sc->dev, CBBR_IOBASE0, 0xffffffff, 4);
	pci_write_config(sc->dev, CBBR_IOLIMIT0, 0, 4);
	pci_write_config(sc->dev, CBBR_IOBASE1, 0xffffffff, 4);
	pci_write_config(sc->dev, CBBR_IOLIMIT1, 0, 4);
}
Example #4
0
File: ptx.c Project: Piro77/fbsdpt3
static int
ptx_attach(device_t device)
{
	struct ptx_softc *scp = (struct ptx_softc *) device_get_softc(device);

	int tuner;
	int i;

	uint32_t command;
        int error;

	memset(scp, 0, sizeof(struct ptx_softc));

	scp->unit = device_get_unit(device);
	scp->device = device;

	// Enable bus mastering and memory mapped I/O.
	pci_enable_busmaster(device);
	pci_enable_io(device, SYS_RES_MEMORY);
	command = pci_read_config(device, PCIR_COMMAND, 2);
	if (! (command & PCIM_CMD_BUSMASTEREN)) {
		device_printf(device, "Can't enable PCI busmaster\n");
		return ENXIO;
	}
	if (! (command & PCIM_CMD_MEMEN)) {
		device_printf(device, "failed to enable memory mappings\n");
		return ENXIO;
	}

	switch (pci_get_device(device)) {
	case PCI_PT1_ID:
		scp->cardtype = PT1;
		break;
	case PCI_PT2_ID:
		scp->cardtype = PT2;
		break;
	case PCI_PT3_ID:
		scp->cardtype = PT3;
		break;
	default:
		device_printf(device, "unknown device (0x%04x)\n",
		    pci_get_device(device));
		return ENXIO;
	}

	// PCIアドレスをマップする
	scp->rid_memory = PCIR_BARS;
	scp->res_memory = bus_alloc_resource_any(device, SYS_RES_MEMORY,
	    &scp->rid_memory, RF_ACTIVE);
	if (! scp->res_memory) {
		device_printf(device, "could not map memory\n");
		return ENXIO;
	}
	scp->bt = rman_get_bustag(scp->res_memory);
	scp->bh = rman_get_bushandle(scp->res_memory);

	if (scp->cardtype == PT3) {
		if (pt3_init(scp)) {
			device_printf(device, "Error pt3_init\n");
			goto out_err;
		}
	}
	else {
		if (xc3s_init(scp)) {
			device_printf(device, "Error xc3s_init\n");
			goto out_err;
		}

		// チューナリセット
		scp->lnb = 0;

		settuner_reset(scp, LNB_OFF, TUNER_POWER_ON_RESET_ENABLE);
		ptx_pause("ptxini", MSTOTICK(50));

		settuner_reset(scp, LNB_OFF, TUNER_POWER_ON_RESET_DISABLE);
		ptx_pause("ptxini", MSTOTICK(10));

		mtx_init(&scp->lock, "ptxiic", NULL, MTX_DEF);
		scp->i2c_state = STATE_STOP;
		scp->i2c_progress = 0;

		// Tuner/Stream 初期化処理
		for (tuner = 0; tuner < 2; ++tuner) {
			if (ptx_tuner_init(scp, tuner))
				goto out_err;

			// |  1 | チューナー番号0 ISDB-S |
			// |  2 | チューナー番号0 ISDB-T |
			// |  3 | チューナー番号1 ISDB-S |
			// |  4 | チューナー番号1 ISDB-T |
			for (i = 0; i < 2; ++i) {
				// 0=ISDB-S 1=ISDB-T
				struct ptx_stream *s = &scp->stream[tuner*2+i];

				s->id = tuner*2+i + 1;

				s->wp = 0;
				s->chunk_filled = 0;
				s->rp = 0;
				s->chunk_used = 0;

				s->buf = malloc(DATA_CHUNK_SIZE * DATA_CHUNK_NUM,
				    M_DEVBUF, M_NOWAIT);
				if (s->buf == NULL) {
					device_printf(scp->device, "malloc failed\n");
					goto out_err;
				}
				mtx_init(&s->lock, "ptxstream", NULL, MTX_DEF);
				cv_init(&s->not_full, "ptxful");
				cv_init(&s->not_empty, "ptxemp");

				scp->dev[s->id - 1] = ptx_make_tuner(scp->unit, tuner, i);
				scp->dev[s->id - 1]->si_drv1 = scp;
				scp->dev[s->id - 1]->si_drv2 = s;

				set_sleepmode(scp, s, TYPE_SLEEP);
			}
			ptx_pause("ptxini", MSTOTICK(50));
		}

		/*
		 * Allocate a DMA tag for the parent bus.
		 */
		error = bus_dma_tag_create(NULL,
		    4, 0, // alignment=4byte, boundary=norestriction
		    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
		    NULL, NULL, // no filtfunc/arg
		    DMA_PAGE_SIZE, 1, DMA_PAGE_SIZE, // maxsize, 1segs, segsize
		    0,
		    NULL, NULL, // no lockfunc/arg
		    &scp->dmat);
		if (error) {
			device_printf(device, "could not create bus DMA tag(%d)\n", error);
			goto out_err;
		}

		ptx_sysctl_init(device, scp);

		if (ptx_dma_init(scp)) {
			goto out_err;
		}

		if (ptx_proc_start(scp)) {
			goto out_err;
		}
	}

	return 0;

	// ----------------
out_err:
	ptx_detach(device);
	return ENXIO;
}
Example #5
0
static int
le_pci_attach(device_t dev)
{
	struct le_pci_softc *lesc;
	struct lance_softc *sc;
	int error, i;

	lesc = device_get_softc(dev);
	sc = &lesc->sc_am79900.lsc;

	pci_enable_busmaster(dev);
	pci_enable_io(dev, PCIM_CMD_PORTEN);

	lesc->sc_rrid = PCIR_BAR(0);
	lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
	    &lesc->sc_rrid, RF_ACTIVE);
	if (lesc->sc_rres == NULL) {
		device_printf(dev, "cannot allocate registers\n");
		error = ENXIO;
		goto fail_mtx;
	}
	lesc->sc_regt = rman_get_bustag(lesc->sc_rres);
	lesc->sc_regh = rman_get_bushandle(lesc->sc_rres);

	lesc->sc_irid = 0;
	if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "cannot allocate interrupt\n");
		error = ENXIO;
		goto fail_rres;
	}

	error = bus_dma_tag_create(
	    NULL,			/* parent */
	    1, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
	    0,				/* nsegments */
	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_pdmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate parent DMA tag\n");
		goto fail_ires;
	}

	sc->sc_memsize = PCNET_MEMSIZE;
	/*
	 * For Am79C970A, Am79C971 and Am79C978 the init block must be 2-byte
	 * aligned and the ring descriptors must be 16-byte aligned when using
	 * a 32-bit software style.
	 */
	error = bus_dma_tag_create(
	    lesc->sc_pdmat,		/* parent */
	    16, 0,			/* alignment, boundary */
	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->sc_memsize,		/* maxsize */
	    1,				/* nsegments */
	    sc->sc_memsize,		/* maxsegsize */
	    BUS_DMA_WAITOK,		/* flags */
	    &lesc->sc_dmat);
	if (error != 0) {
		device_printf(dev, "cannot allocate buffer DMA tag\n");
		goto fail_pdtag;
	}

	error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem,
	    BUS_DMA_WAITOK | BUS_DMA_COHERENT, &lesc->sc_dmam);
	if (error != 0) {
		device_printf(dev, "cannot allocate DMA buffer memory\n");
		goto fail_dtag;
	}

	sc->sc_addr = 0;
	error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem,
	    sc->sc_memsize, le_pci_dma_callback, sc, 0);
	if (error != 0 || sc->sc_addr == 0) {
                device_printf(dev, "cannot load DMA buffer map\n");
		goto fail_dmem;
	}

	sc->sc_flags = LE_BSWAP;
	sc->sc_conf3 = 0;

	sc->sc_mediastatus = NULL;
	switch (pci_get_device(dev)) {
	case AMD_PCNET_HOME:
		sc->sc_mediachange = le_pci_mediachange;
		sc->sc_supmedia = le_home_supmedia;
		sc->sc_nsupmedia = sizeof(le_home_supmedia) / sizeof(int);
		sc->sc_defaultmedia = le_home_supmedia[0];
		break;
	default:
		sc->sc_mediachange = le_pci_mediachange;
		sc->sc_supmedia = le_pci_supmedia;
		sc->sc_nsupmedia = sizeof(le_pci_supmedia) / sizeof(int);
		sc->sc_defaultmedia = le_pci_supmedia[0];
	}

	/*
	 * Extract the physical MAC address from the ROM.
	 */
	for (i = 0; i < sizeof(sc->sc_enaddr); i++)
		sc->sc_enaddr[i] =
		    bus_space_read_1(lesc->sc_regt, lesc->sc_regh, i);

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	sc->sc_rdcsr = le_pci_rdcsr;
	sc->sc_wrcsr = le_pci_wrcsr;
	sc->sc_hwreset = le_pci_hwreset;
	sc->sc_hwinit = NULL;
	sc->sc_hwintr = NULL;
	sc->sc_nocarrier = NULL;

	error = am79900_config(&lesc->sc_am79900, device_get_name(dev),
	    device_get_unit(dev));
	if (error != 0) {
		device_printf(dev, "cannot attach Am79900\n");
		goto fail_dmap;
	}

	error = bus_setup_intr(dev, lesc->sc_ires, INTR_MPSAFE,
	    am79900_intr, sc, &lesc->sc_ih, sc->ifp->if_serializer);
	if (error != 0) {
		device_printf(dev, "cannot set up interrupt\n");
		goto fail_am79900;
	}

	sc->ifp->if_cpuid = rman_get_cpuid(lesc->sc_ires);
	KKASSERT(sc->ifp->if_cpuid >= 0 && sc->ifp->if_cpuid < ncpus);

	return (0);

 fail_am79900:
	am79900_detach(&lesc->sc_am79900);
 fail_dmap:
	bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam);
 fail_dmem:
	bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam);
 fail_dtag:
	bus_dma_tag_destroy(lesc->sc_dmat);
 fail_pdtag:
	bus_dma_tag_destroy(lesc->sc_pdmat);
 fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires);
 fail_rres:
	bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres);
 fail_mtx:
	return (error);
}