Beispiel #1
0
static void
ppbattach(device_t parent, device_t self, void *aux)
{
	struct ppb_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	struct pcibus_attach_args pba;
	pcireg_t busdata;

	pci_aprint_devinfo(pa, NULL);

	sc->sc_pc = pc;
	sc->sc_tag = pa->pa_tag;
	sc->sc_dev = self;

	busdata = pci_conf_read(pc, pa->pa_tag, PPB_REG_BUSINFO);

	if (PPB_BUSINFO_SECONDARY(busdata) == 0) {
		aprint_normal_dev(self, "not configured by system firmware\n");
		return;
	}

	ppb_fix_pcie(self);

#if 0
	/*
	 * XXX can't do this, because we're not given our bus number
	 * (we shouldn't need it), and because we've no way to
	 * decompose our tag.
	 */
	/* sanity check. */
	if (pa->pa_bus != PPB_BUSINFO_PRIMARY(busdata))
		panic("ppbattach: bus in tag (%d) != bus in reg (%d)",
		    pa->pa_bus, PPB_BUSINFO_PRIMARY(busdata));
#endif

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

	/*
	 * Attach the PCI bus than hangs off of it.
	 *
	 * XXX Don't pass-through Memory Read Multiple.  Should we?
	 * XXX Consult the spec...
	 */
	pba.pba_iot = pa->pa_iot;
	pba.pba_memt = pa->pa_memt;
	pba.pba_dmat = pa->pa_dmat;
	pba.pba_dmat64 = pa->pa_dmat64;
	pba.pba_pc = pc;
	pba.pba_flags = pa->pa_flags & ~PCI_FLAGS_MRM_OKAY;
	pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata);
	pba.pba_sub = PPB_BUSINFO_SUBORDINATE(busdata);
	pba.pba_bridgetag = &sc->sc_tag;
	pba.pba_intrswiz = pa->pa_intrswiz;
	pba.pba_intrtag = pa->pa_intrtag;

	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
Beispiel #2
0
static int
aprint_devinfo(lua_State *L)
{
  struct pci_attach_args *pa = lua_touserdata(L, -1);
  pci_aprint_devinfo(pa, NULL);
  lua_pop(L, 1);
  return 0;
}
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 #4
0
static void
nca_pci_attach(device_t parent, device_t self, void *aux)
{
	struct ncr5380_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;

	sc->sc_dev = self;

	pci_aprint_devinfo(pa, "SCSI controller");

	if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
            &sc->sc_regt, &sc->sc_regh, NULL, NULL)) {
                aprint_error_dev(self, "could not map IO space\n");
                return;
        }
	
	/* The Domex 536 seems to be driven by polling,
	 * don't bother mapping an interrupt handler.
	 */
	
	sc->sc_rev = NCR_VARIANT_CXD1180;
	sc->sci_r0 = 0;
	sc->sci_r1 = 1;
	sc->sci_r2 = 2;
	sc->sci_r3 = 3;
	sc->sci_r4 = 4;
	sc->sci_r5 = 5;
	sc->sci_r6 = 6;
	sc->sci_r7 = 7;

	sc->sc_pio_out = ncr5380_pio_out;
	sc->sc_pio_in =  ncr5380_pio_in;
	sc->sc_dma_alloc = NULL;
	sc->sc_dma_free  = NULL;
	sc->sc_dma_setup = NULL;
	sc->sc_dma_start = NULL;
	sc->sc_dma_poll  = NULL;
	sc->sc_dma_eop   = NULL;
	sc->sc_dma_stop  = NULL;
	sc->sc_intr_on   = NULL;
	sc->sc_intr_off  = NULL;

	sc->sc_flags |= NCR5380_FORCE_POLLING;

	sc->sc_min_dma_len = 0;

	sc->sc_adapter.adapt_request = ncr5380_scsipi_request;
	sc->sc_adapter.adapt_minphys = minphys;

	sc->sc_channel.chan_id = 7;

	ncr5380_attach(sc);
}
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");
	}
}
static void
igsfb_pci_attach(device_t parent, device_t self, void *aux)
{
	struct igsfb_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	int isconsole;

	sc->sc_dev = self;

	pci_aprint_devinfo(pa, NULL);

#if defined(__sparc__) && !defined(KRUPS_FORCE_SERIAL_CONSOLE)
	/* XXX: this doesn't belong here */
	if (PCITAG_NODE(pa->pa_tag) == prom_instance_to_package(prom_stdout()))
	{
		int b, d, f;

		pci_decompose_tag(pa->pa_pc, pa->pa_tag, &b, &d, &f);
		igsfb_pci_cnattach(pa->pa_iot, pa->pa_memt, pa->pa_pc, b,d,f);
	}
#endif

	isconsole = 0;
	if (igsfb_pci_is_console(pa->pa_pc, pa->pa_tag)) {
		sc->sc_dc = &igsfb_console_dc;
		isconsole = 1;
	} else {
		sc->sc_dc = malloc(sizeof(struct igsfb_devconfig),
				   M_DEVBUF, M_NOWAIT | M_ZERO);
		if (sc->sc_dc == NULL)
			panic("unable to allocate igsfb_devconfig");
		if (igsfb_pci_map_regs(sc->sc_dc,
			    pa->pa_iot, pa->pa_memt, pa->pa_pc,
			    pa->pa_tag, PCI_PRODUCT(pa->pa_id)) != 0)
		{
			printf("unable to map device registers\n");
			free(sc->sc_dc, M_DEVBUF);
			sc->sc_dc = NULL;
			return;
		}

		igsfb_enable(sc->sc_dc->dc_iot, sc->sc_dc->dc_iobase,
			     sc->sc_dc->dc_ioflags);
	}

	igsfb_attach_subr(sc, isconsole);
}
Beispiel #7
0
static void
gtp_attach(device_t parent, device_t self, void *aux)
{
	struct gtp_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	cfdata_t cf = device_cfdata(self);
	pci_chipset_tag_t pc = pa->pa_pc;
	bus_size_t iosize;
	pcireg_t csr;

	pci_aprint_devinfo(pa, "Radio controller");

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

	/* Enable the card */
	csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    csr | PCI_COMMAND_MASTER_ENABLE);

	sc->vol = 0;
	sc->mute = 0;
	sc->freq = MIN_FM_FREQ;
	sc->stereo = TEA5757_STEREO;
	sc->lock = TEA5757_S030;
	sc->tea.offset = 0;
	sc->tea.flags = cf->cf_flags;
	sc->tea.init = gtp_init;
	sc->tea.rset = gtp_rset;
	sc->tea.write_bit = gtp_write_bit;
	sc->tea.read = gtp_hardware_read;

	aprint_normal(": Gemtek PR103\n");

	radio_attach_mi(&gtp_hw_if, sc, self);
}
Beispiel #8
0
static void
igma_attach(device_t parent, device_t self, void *aux)
{
	struct igma_softc *sc = device_private(self);
	const struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	struct igma_attach_args iaa;
	bus_space_tag_t gttmmt, gmt, regt;
	bus_space_handle_t gttmmh, gmh, regh;
	bus_addr_t gttmmb, gmb;

	pci_aprint_devinfo(pa, NULL);

	sc->sc_dev = self;

	/* Initialize according to chip type */
	igma_product_to_chip(pa, &sc->sc_chip);

	if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM,
			BUS_SPACE_MAP_LINEAR,
			&gttmmt, &gttmmh, &gttmmb, NULL)) {
		aprint_error_dev(sc->sc_dev, "unable to map GTTMM\n");
		return;
	}
	sc->sc_chip.mmiot = gttmmt;
	if (bus_space_subregion(gttmmt, gttmmh, 0, 2*1024*1024,
			&sc->sc_chip.mmioh)) {
		aprint_error_dev(sc->sc_dev, "unable to submap MMIO\n");
		return;
	}
	sc->sc_chip.gttt = gttmmt;
	if (bus_space_subregion(gttmmt, gttmmh, 2*1024*1024, 2*1024*1024,
			&sc->sc_chip.gtth)) {
		aprint_error_dev(sc->sc_dev, "unable to submap GTT\n");
		return;
	}

	if (pci_mapreg_map(pa, PCI_BAR2, PCI_MAPREG_TYPE_MEM,
			BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE,
			&gmt, &gmh, &gmb, NULL)) {
		aprint_error_dev(sc->sc_dev, "unable to map aperture\n");
		return;
	}
	sc->sc_chip.gmt = gmt;
	sc->sc_chip.gmh = gmh;
	sc->sc_chip.gmb = gmb;

	if (pci_mapreg_map(pa, PCI_BAR4, PCI_MAPREG_TYPE_IO, 0,
			&regt, &regh, NULL, NULL)) {
		aprint_error_dev(sc->sc_dev, "unable to map IO registers\n");
		return;
	}

#if NVGA > 0
	iaa.iaa_console = vga_cndetach() ? true : false;
#else
	iaa.iaa_console = 0;
#endif
	sc->sc_chip.vgat = regt;
	if (bus_space_map(regt, 0x3c0, 0x10, 0, &sc->sc_chip.vgah)) {
		aprint_error_dev(sc->sc_dev, "unable to map VGA registers\n");
		return;
	}

	/* Check hardware for more information */
	igma_adjust_chip(sc, &sc->sc_chip);

	aprint_normal("%s: VGA_CNTRL: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.vga_cntrl);
	aprint_normal("%s: GPIO_OFFSET: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.gpio_offset);
	aprint_normal("%s: BACKLIGHT_CTRL: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.backlight_cntrl);
	aprint_normal("%s: BACKLIGHT_CTRL2: 0x%x\n",device_xname(sc->sc_dev),
		sc->sc_chip.backlight_cntrl2);

#if NIGMAFB > 0
	strcpy(iaa.iaa_name, "igmafb");
	iaa.iaa_chip = sc->sc_chip;
	config_found_ia(sc->sc_dev, "igmabus", &iaa, igma_print);
#endif

	igma_i2c_attach(sc);
}
static void
ohci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct ohci_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;
	const char *vendor;
	char intrbuf[PCI_INTRSTR_LEN];

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

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_USB) {
		sc->sc.sc_flags = OHCIF_SUPERIO;
	}

	pci_aprint_devinfo(pa, "USB Controller");

	/* 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 I/O registers */
	if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0,
			   &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
		sc->sc.sc_size = 0;
		aprint_error_dev(self, "can't map mem space\n");
		return;
	}

	/* Disable interrupts, so we don't get any spurious ones. */
	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
			  OHCI_ALL_INTRS);

	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->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_SCHED, ohci_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);

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

	r = ohci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		aprint_error_dev(self, "init failed, error=%d\n", r);
		goto fail;
	}

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

	if (!pmf_device_register1(self, ohci_suspend, ohci_resume,
	                          ohci_shutdown))
		aprint_error_dev(self, "couldn't establish power handler\n");

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

fail:
	if (sc->sc_ih) {
		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
		sc->sc_ih = NULL;
	}
	if (sc->sc.sc_size) {
		bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
		sc->sc.sc_size = 0;
	}
	return;
}
Beispiel #10
0
static void
sdhc_pci_attach(device_t parent, device_t self, void *aux)
{
	struct sdhc_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;
	pci_intr_handle_t ih;
	pcireg_t csr;
	pcireg_t slotinfo;
	char const *intrstr;
	int nslots;
	int reg;
	int cnt;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	bus_size_t size;
	uint32_t flags;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc.sc_dev = self;
	sc->sc.sc_dmat = pa->pa_dmat;
	sc->sc.sc_host = NULL;

	sc->sc_pc = pc;

	pci_aprint_devinfo(pa, NULL);

	/* Some controllers needs special treatment. */
	flags = sdhc_pci_lookup_quirk_flags(pa);
	if (ISSET(flags, SDHC_PCI_QUIRK_TI_HACK))
		sdhc_pci_quirk_ti_hack(pa);
	if (ISSET(flags, SDHC_PCI_QUIRK_FORCE_DMA))
		SET(sc->sc.sc_flags, SDHC_FLAG_FORCE_DMA);
	if (ISSET(flags, SDHC_PCI_QUIRK_NO_PWR0))
		SET(sc->sc.sc_flags, SDHC_FLAG_NO_PWR0);
	if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_LOWER_FREQ_HACK))
		sdhc_pci_quirk_ricoh_lower_freq_hack(pa);

	/*
	 * Map and attach all hosts supported by the host controller.
	 */
	slotinfo = pci_conf_read(pc, tag, SDHC_PCI_CONF_SLOT_INFO);
	nslots = SDHC_PCI_NUM_SLOTS(slotinfo);

	/* Allocate an array big enough to hold all the possible hosts */
	sc->sc.sc_host = malloc(sizeof(struct sdhc_host *) * nslots,
	    M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc.sc_host == NULL) {
		aprint_error_dev(self, "couldn't alloc memory\n");
		goto err;
	}

	/* 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");
		goto err;
	}

	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_SDMMC, sdhc_intr, &sc->sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt\n");
		goto err;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	/* Enable use of DMA if supported by the interface. */
	if ((PCI_INTERFACE(pa->pa_class) == SDHC_PCI_INTERFACE_DMA))
		SET(sc->sc.sc_flags, SDHC_FLAG_USE_DMA);

	/* XXX: handle 64-bit BARs */
	cnt = 0;
	for (reg = SDHC_PCI_BAR_START + SDHC_PCI_FIRST_BAR(slotinfo) *
		 sizeof(uint32_t);
	     reg < SDHC_PCI_BAR_END && nslots > 0;
	     reg += sizeof(uint32_t), nslots--) {
		if (pci_mapreg_map(pa, reg, PCI_MAPREG_TYPE_MEM, 0,
		    &iot, &ioh, NULL, &size)) {
			continue;
		}

		cnt++;
		if (sdhc_host_found(&sc->sc, iot, ioh, size) != 0) {
			/* XXX: sc->sc_host leak */
			aprint_error_dev(self,
			    "couldn't initialize host (0x%x)\n", reg);
		}
	}
	if (cnt == 0) {
		aprint_error_dev(self, "couldn't map register\n");
		goto err;
	}

	if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume,
	    sdhc_shutdown)) {
		aprint_error_dev(self, "couldn't establish powerhook\n");
	}

	return;

err:
	if (sc->sc.sc_host != NULL) {
		free(sc->sc.sc_host, M_DEVBUF);
		sc->sc.sc_host = NULL;
	}
}
Beispiel #11
0
static void
wi_pci_attach(device_t parent, device_t self, void *aux)
{
	struct wi_pci_softc *psc = device_private(self);
	struct wi_softc *sc = &psc->psc_wi;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	const char *intrstr;
	const struct wi_pci_product *wpp;
	pci_intr_handle_t ih;
	bus_space_tag_t memt, iot, plxt, tmdt;
	bus_space_handle_t memh, ioh, plxh, tmdh;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc_dev = self;
	psc->psc_pc = pc;
	psc->psc_pcitag = pa->pa_tag;

	wpp = wi_pci_lookup(pa);
#ifdef DIAGNOSTIC
	if (wpp == NULL) {
		printf("\n");
		panic("wi_pci_attach: impossible");
	}
#endif

	switch (wpp->wpp_chip) {
	case CHIP_PLX_OTHER:
	case CHIP_PLX_9052:
		/* Map memory and I/O registers. */
		if (pci_mapreg_map(pa, WI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,
		    &memt, &memh, NULL, NULL) != 0) {
			aprint_error(": can't map mem space\n");
			return;
		}
		if (pci_mapreg_map(pa, WI_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,
		    &iot, &ioh, NULL, NULL) != 0) {
			aprint_error(": can't map I/O space\n");
			return;
		}

		if (wpp->wpp_chip == CHIP_PLX_OTHER) {
			/* The PLX 9052 doesn't have IO at 0x14.  Perhaps
			   other chips have, so we'll make this conditional. */
			if (pci_mapreg_map(pa, WI_PCI_PLX_LOIO,
			    PCI_MAPREG_TYPE_IO, 0, &plxt, &plxh, NULL, NULL)
			    != 0) {
				aprint_error(": can't map PLX\n");
				return;
			}
		}
		break;
	case CHIP_TMD_7160:
		/* Used instead of PLX on at least one revision of
		 * the National Datacomm Corporation NCP130. Values
		 * for registers acquired from OpenBSD, which in
		 * turn got them from a Linux driver.
		 */
		/* Map COR and I/O registers. */
		if (pci_mapreg_map(pa, WI_TMD_COR, PCI_MAPREG_TYPE_IO, 0,
		    &tmdt, &tmdh, NULL, NULL) != 0) {
			aprint_error(": can't map TMD\n");
			return;
		}
		if (pci_mapreg_map(pa, WI_TMD_IO, PCI_MAPREG_TYPE_IO, 0,
		    &iot, &ioh, NULL, NULL) != 0) {
			aprint_error(": can't map I/O space\n");
			return;
		}
		break;
	default:
		if (pci_mapreg_map(pa, WI_PCI_CBMA,
		    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
		    0, &iot, &ioh, NULL, NULL) != 0) {
			aprint_error(": can't map mem space\n");
			return;
		}

		memt = iot;
		memh = ioh;
		sc->sc_pci = 1;
		break;
	}

	pci_aprint_devinfo(pa, NULL);

	sc->sc_enabled = 1;
	sc->sc_enable = wi_pci_enable;

	sc->sc_iot = iot;
	sc->sc_ioh = ioh;
	/* Make sure interrupts are disabled. */
	CSR_WRITE_2(sc, WI_INT_EN, 0);
	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);

	if (wpp->wpp_chip == CHIP_PLX_OTHER) {
		uint32_t command;
#define	WI_LOCAL_INTCSR		0x4c
#define	WI_LOCAL_INTEN		0x40	/* poke this into INTCSR */

		command = bus_space_read_4(plxt, plxh, WI_LOCAL_INTCSR);
		command |= WI_LOCAL_INTEN;
		bus_space_write_4(plxt, plxh, WI_LOCAL_INTCSR, command);
	}

	/* 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));

	psc->psc_ih = ih;
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wi_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);

	switch (wpp->wpp_chip) {
	case CHIP_PLX_OTHER:
	case CHIP_PLX_9052:
		/*
		 * Setup the PLX chip for level interrupts and config index 1
		 * XXX - should really reset the PLX chip too.
		 */
		bus_space_write_1(memt, memh,
		    WI_PLX_COR_OFFSET, WI_PLX_COR_VALUE);
		break;
	case CHIP_TMD_7160:
		/* Enable I/O mode and level interrupts on the embedded
		 * card. The card's COR is the first byte of BAR 0.
		 */
		bus_space_write_1(tmdt, tmdh, 0, WI_COR_IOMODE);
		break;
	default:
		/* reset HFA3842 MAC core */
		wi_pci_reset(sc);
		break;
	}

	printf("%s:", device_xname(self));

	if (wi_attach(sc, 0) != 0) {
		aprint_error_dev(self, "failed to attach controller\n");
		pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
		return;
	}

	if (!wpp->wpp_chip)
		sc->sc_reset = wi_pci_reset;

	if (pmf_device_register(self, NULL, NULL))
		pmf_class_network_register(self, &sc->sc_if);
	else
		aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
piixpm_attach(device_t parent, device_t self, void *aux)
{
	struct piixpm_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct i2cbus_attach_args iba;
	pcireg_t base, conf;
	pcireg_t pmmisc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	int i, numbusses = 1;

	sc->sc_dev = self;
	sc->sc_iot = pa->pa_iot;
	sc->sc_id = pa->pa_id;
	sc->sc_pc = pa->pa_pc;
	sc->sc_pcitag = pa->pa_tag;

	pci_aprint_devinfo(pa, NULL);

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

	/* Read configuration */
	conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC);
	DPRINTF(("%s: conf 0x%x\n", device_xname(self), conf));

	if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) ||
	    (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC))
		goto nopowermanagement;

	/* check whether I/O access to PM regs is enabled */
	pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC);
	if (!(pmmisc & 1))
		goto nopowermanagement;

	/* Map I/O space */
	base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE);
	if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base),
	    PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) {
		aprint_error_dev(self, "can't map power management I/O space\n");
		goto nopowermanagement;
	}

	/*
	 * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M.
	 * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20
	 * in the "Specification update" (document #297738).
	 */
	acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh,
			   PIIX_PM_PMTMR,
		(PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 );

nopowermanagement:

	/* SB800 rev 0x40+ needs special initialization */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_SMB &&
	    PCI_REVISION(pa->pa_class) >= 0x40) {
		if (piixpm_sb800_init(sc) == 0) {
			numbusses = 4;
			goto attach_i2c;
		}
		aprint_normal_dev(self, "SMBus disabled\n");
		return;
	}

	if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) {
		aprint_normal_dev(self, "SMBus disabled\n");
		return;
	}

	/* Map I/O space */
	base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff;
	if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base),
	    PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) {
		aprint_error_dev(self, "can't map smbus I/O space\n");
		return;
	}

	sc->sc_poll = 1;
	aprint_normal_dev(self, "");
	if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) {
		/* No PCI IRQ */
		aprint_normal("interrupting at SMI, ");
	} else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) {
		/* Install interrupt handler */
		if (pci_intr_map(pa, &ih) == 0) {
			intrstr = pci_intr_string(pa->pa_pc, ih);
			sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
			    piixpm_intr, sc);
			if (sc->sc_smb_ih != NULL) {
				aprint_normal("interrupting at %s", intrstr);
				sc->sc_poll = 0;
			}
		}
	}
	if (sc->sc_poll)
		aprint_normal("polling");

	aprint_normal("\n");

attach_i2c:
	/* Attach I2C bus */
	mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE);

	for (i = 0; i < numbusses; i++) {
		sc->sc_busses[i].sda = i;
		sc->sc_busses[i].softc = sc;
		sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i];
		sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus;
		sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus;
		sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec;

		memset(&iba, 0, sizeof(iba));
		iba.iba_type = I2C_TYPE_SMBUS;
		iba.iba_tag = &sc->sc_i2c_tags[i];
		config_found_ia(self, "i2cbus", &iba, iicbus_print);
	}
}
static void
coram_attach(device_t parent, device_t self, void *aux)
{
	struct coram_softc *sc = device_private(self);
	const struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	pcireg_t reg;
	const char *intrstr;
	struct coram_iic_softc *cic;
	uint32_t value;
	int i;
#ifdef CORAM_ATTACH_I2C
	struct i2cbus_attach_args iba;
#endif

	sc->sc_dev = self;

	pci_aprint_devinfo(pa, NULL);

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	sc->sc_board = coram_board_lookup(PCI_VENDOR(reg), PCI_PRODUCT(reg));
	KASSERT(sc->sc_board != NULL);

	if (pci_mapreg_map(pa, CX23885_MMBASE, PCI_MAPREG_TYPE_MEM, 0,
			   &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) {
		aprint_error_dev(self, "couldn't map memory space\n");
		return;
	}

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

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_VM, coram_intr, self);
	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 master */
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	reg |= PCI_COMMAND_MASTER_ENABLE;
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);

	/* I2C */
	for(i = 0; i < I2C_NUM; i++) {
		cic = &sc->sc_iic[i];

		cic->cic_sc = sc;
		if (bus_space_subregion(sc->sc_memt, sc->sc_memh,
		    I2C_BASE + (I2C_SIZE * i), I2C_SIZE, &cic->cic_regh))
			panic("failed to subregion i2c");

		mutex_init(&cic->cic_busmutex, MUTEX_DRIVER, IPL_NONE);
		cic->cic_i2c.ic_cookie = cic;
		cic->cic_i2c.ic_acquire_bus = coram_iic_acquire_bus;
		cic->cic_i2c.ic_release_bus = coram_iic_release_bus;
		cic->cic_i2c.ic_exec = coram_iic_exec;

#ifdef CORAM_ATTACH_I2C
		/* attach iic(4) */
		memset(&iba, 0, sizeof(iba));
		iba.iba_tag = &cic->cic_i2c;
		iba.iba_type = I2C_TYPE_SMBUS;
		cic->cic_i2cdev = config_found_ia(self, "i2cbus", &iba,
		    iicbus_print);
#endif
	}

	/* HVR1250 GPIO */
	value = bus_space_read_4(sc->sc_memt, sc->sc_memh, 0x110010);
#if 1
	value &= ~0x00010001;
	bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value);
	delay(5000);
#endif
	value |= 0x00010001;
	bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value);

#if 0
	int i;
	uint8_t foo[256];
	uint8_t bar;
	bar = 0;
//	seeprom_bootstrap_read(&sc->sc_i2c, 0x50, 0, 256, foo, 256);

	iic_acquire_bus(&sc->sc_i2c, I2C_F_POLL);
	iic_exec(&sc->sc_i2c, I2C_OP_READ_WITH_STOP, 0x50, &bar, 1, foo, 256,
	    I2C_F_POLL);
	iic_release_bus(&sc->sc_i2c, I2C_F_POLL);

	printf("\n");
	for ( i = 0; i < 256; i++) {
		if ( (i % 8) == 0 )
			printf("%02x: ", i);

		printf("%02x", foo[i]);

		if ( (i % 8) == 7 )
			printf("\n");
		else
			printf(" ");
	}
	printf("\n");
#endif

	sc->sc_demod = cx24227_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x19);
	if (sc->sc_demod == NULL)
		aprint_error_dev(self, "couldn't open cx24227\n");
	sc->sc_tuner = mt2131_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x61);
	if (sc->sc_tuner == NULL)
		aprint_error_dev(self, "couldn't open mt2131\n");

	coram_mpeg_attach(sc);

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

	return;
}
Beispiel #14
0
static void
fwohci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = (struct pci_attach_args *) aux;
	struct fwohci_pci_softc *psc = device_private(self);
	char const *intrstr;
	pci_intr_handle_t ih;
	uint32_t csr;
	char intrbuf[PCI_INTRSTR_LEN];

	pci_aprint_devinfo(pa, "IEEE 1394 Controller");

	fwohci_init(&psc->psc_sc);

	psc->psc_sc.fc.dev = self;
	psc->psc_sc.fc.dmat = pa->pa_dmat;
	psc->psc_pc = pa->pa_pc;
	psc->psc_tag = pa->pa_tag;

	/* Map I/O registers */
	if (pci_mapreg_map(pa, PCI_OHCI_MAP_REGISTER, PCI_MAPREG_TYPE_MEM, 0,
	    &psc->psc_sc.bst, &psc->psc_sc.bsh, NULL, &psc->psc_sc.bssize)) {
		aprint_error_dev(self, "can't map OHCI register space\n");
		goto fail;
	}

	/* Disable interrupts, so we don't get any spurious ones. */
	OWRITE(&psc->psc_sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);

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

	/*
	 * Some Sun FireWire controllers have their intpin register
	 * bogusly set to 0, although it should be 3. Correct that.
	 */
	if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN) &&
	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_FIREWIRE))
		if (pa->pa_intrpin == 0)
			pa->pa_intrpin = 3;

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		goto fail;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
	psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwohci_intr,
	    &psc->psc_sc);
	if (psc->psc_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 (fwohci_attach(&psc->psc_sc) != 0)
		goto fail;

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

	return;

fail:
	/* In the event that we fail to attach, register a null pnp handler */
	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");

	return;
}
Beispiel #15
0
static void
cs4280_attach(device_t parent, device_t self, void *aux)
{
	struct cs428x_softc *sc;
	struct pci_attach_args *pa;
	pci_chipset_tag_t pc;
	const struct cs4280_card_t *cs_card;
	char const *intrstr;
	const char *vendor, *product;
	pcireg_t reg;
	uint32_t mem;
	int error;
	char intrbuf[PCI_INTRSTR_LEN];

	sc = device_private(self);
	sc->sc_dev = self;
	pa = (struct pci_attach_args *)aux;
	pc = pa->pa_pc;

	pci_aprint_devinfo(pa, "Audio controller");

	cs_card = cs4280_identify_card(pa);
	if (cs_card != NULL) {
		vendor = pci_findvendor(cs_card->id);
		product = pci_findproduct(cs_card->id); 
		if (vendor == NULL)
			aprint_normal_dev(sc->sc_dev,
					  "vendor 0x%04x product 0x%04x\n",
					  PCI_VENDOR(cs_card->id),
					  PCI_PRODUCT(cs_card->id));
		else if (product == NULL)
			aprint_normal_dev(sc->sc_dev, "%s product 0x%04x\n",
					  vendor, PCI_PRODUCT(cs_card->id));
		else
			aprint_normal_dev(sc->sc_dev, "%s %s\n",
					  vendor, product);
		sc->sc_flags = cs_card->flags;
	} else {
		sc->sc_flags = CS428X_FLAG_NONE;
	}

	sc->sc_pc = pa->pa_pc;
	sc->sc_pt = pa->pa_tag;

	/* Map I/O register */
	if (pci_mapreg_map(pa, PCI_BA0,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->ba0t, &sc->ba0h, NULL, NULL)) {
		aprint_error_dev(sc->sc_dev, "can't map BA0 space\n");
		return;
	}
	if (pci_mapreg_map(pa, PCI_BA1,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->ba1t, &sc->ba1h, NULL, NULL)) {
		aprint_error_dev(sc->sc_dev, "can't map BA1 space\n");
		return;
	}

	sc->sc_dmatag = pa->pa_dmat;

	/* power up chip */
	if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self,
	    pci_activate_null)) && error != EOPNOTSUPP) {
		aprint_error_dev(sc->sc_dev, "cannot activate %d\n", error);
		return;
	}

	/* Enable the device (set bus master flag) */
	reg = 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,
		       reg | PCI_COMMAND_MASTER_ENABLE);

	/* LATENCY_TIMER setting */
	mem = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
	if ( PCI_LATTIMER(mem) < 32 ) {
		mem &= 0xffff00ff;
		mem |= 0x00002000;
		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, mem);
	}

	/* CLKRUN hack initialization */
	cs4280_clkrun_hack_init(sc);

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &sc->intrh)) {
		aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, sc->intrh, intrbuf, sizeof(intrbuf));

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);

	sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->intrh, IPL_AUDIO,
	    cs4280_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		mutex_destroy(&sc->sc_lock);
		mutex_destroy(&sc->sc_intr_lock);
		return;
	}
	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	/* Initialization */
	if(cs4280_init(sc, 1) != 0) {
		mutex_destroy(&sc->sc_lock);
		mutex_destroy(&sc->sc_intr_lock);
		return;
	}

	sc->type = TYPE_CS4280;
	sc->halt_input  = cs4280_halt_input;
	sc->halt_output = cs4280_halt_output;

	/* setup buffer related parameters */
	sc->dma_size     = CS4280_DCHUNK;
	sc->dma_align    = CS4280_DALIGN;
	sc->hw_blocksize = CS4280_ICHUNK;

	/* AC 97 attachment */
	sc->host_if.arg = sc;
	sc->host_if.attach = cs428x_attach_codec;
	sc->host_if.read   = cs4280_read_codec;
	sc->host_if.write  = cs4280_write_codec;
#if 0
	sc->host_if.reset  = cs4280_reset_codec;
#else
	sc->host_if.reset  = NULL;
#endif
	sc->host_if.flags  = cs4280_flags_codec;
	if (ac97_attach(&sc->host_if, self, &sc->sc_lock) != 0) {
		aprint_error_dev(sc->sc_dev, "ac97_attach failed\n");
		return;
	}

	audio_attach_mi(&cs4280_hw_if, sc, sc->sc_dev);

#if NMIDI > 0
	midi_attach_mi(&cs4280_midi_hw_if, sc, sc->sc_dev);
#endif

	if (!pmf_device_register(self, cs4280_suspend, cs4280_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Beispiel #16
0
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 memtype, reg;
	int error;
	char intrbuf[PCI_INTRSTR_LEN];

	pci_aprint_devinfo(pa, NULL);

	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_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 */
	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, &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, intrbuf, sizeof(intrbuf));
	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));
}
/*
 * Attach this instance, and then all the sub-devices
 */
static void
pcscp_attach(device_t parent, device_t self, void *aux)
{
	struct pcscp_softc *esc = device_private(self);
	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
	struct pci_attach_args *pa = aux;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	pci_intr_handle_t ih;
	const char *intrstr;
	pcireg_t csr;
	bus_dma_segment_t seg;
	int error, rseg;

	sc->sc_dev = self;
	pci_aprint_devinfo(pa, NULL);
	aprint_normal("%s", device_xname(sc->sc_dev));

	if (pci_mapreg_map(pa, IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, NULL, NULL)) {
		aprint_error(": unable to map registers\n");
		return;
	}

	sc->sc_glue = &pcscp_glue;

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

	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 | PCI_COMMAND_IO_ENABLE);

	/*
	 * 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)) {
		aprint_error(": can't create DMA maps\n");
		return;
	}

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

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

	/* map and establish interrupt */
	if (pci_intr_map(pa, &ih)) {
		aprint_error(": 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);
	if (esc->sc_ih == NULL) {
		aprint_error(": couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		goto fail_4;
	}
	if (intrstr != NULL) {
		aprint_normal(": interrupting at %s\n", intrstr);
		aprint_normal("%s", device_xname(sc->sc_dev));
	}

	/* Do the common parts of attachment. */
	sc->sc_adapter.adapt_minphys = minphys;
	sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
	ncr53c9x_attach(sc);

	/* 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, (void *)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 #18
0
static void
yds_attach(device_t parent, device_t self, void *aux)
{
	struct yds_softc *sc;
	struct pci_attach_args *pa;
	pci_chipset_tag_t pc;
	char const *intrstr;
	pci_intr_handle_t ih;
	pcireg_t reg;
	struct yds_codec_softc *codec;
	int i, r, to;
	int revision;
	int ac97_id2;
	char intrbuf[PCI_INTRSTR_LEN];

	sc = device_private(self);
	sc->sc_dev = self;
	pa = (struct pci_attach_args *)aux;
	pc = pa->pa_pc;
	revision = PCI_REVISION(pa->pa_class);

	pci_aprint_devinfo(pa, NULL);

	/* Map register to memory */
	if (pci_mapreg_map(pa, YDS_PCI_MBA, PCI_MAPREG_TYPE_MEM, 0,
			   &sc->memt, &sc->memh, NULL, NULL)) {
		aprint_error_dev(self, "can't map memory space\n");
		return;
	}

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

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_AUDIO); /* XXX IPL_NONE? */
	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);

	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, yds_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");
		mutex_destroy(&sc->sc_lock);
		mutex_destroy(&sc->sc_intr_lock);
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	sc->sc_dmatag = pa->pa_dmat;
	sc->sc_pc = pc;
	sc->sc_pcitag = pa->pa_tag;
	sc->sc_id = pa->pa_id;
	sc->sc_revision = revision;
	sc->sc_flags = yds_get_dstype(sc->sc_id);
#ifdef AUDIO_DEBUG
	if (ydsdebug) {
		char bits[80];

		snprintb(bits, sizeof(bits), YDS_CAP_BITS, sc->sc_flags);
		printf("%s: chip has %s\n", device_xname(self), bits);
	}
#endif

	/* Disable legacy mode */
	reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_LEGACY);
	pci_conf_write(pc, pa->pa_tag, YDS_PCI_LEGACY,
		       reg & YDS_PCI_LEGACY_LAD);

	/* Enable the device. */
	reg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	reg |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
		PCI_COMMAND_MASTER_ENABLE);
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);
	reg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);

	/* Mute all volumes */
	for (i = 0x80; i < 0xc0; i += 2)
		YWRITE2(sc, i, 0);

	/* Initialize the device */
	if (yds_init(sc)) {
		aprint_error_dev(self, "initialize failed\n");
		mutex_destroy(&sc->sc_lock);
		mutex_destroy(&sc->sc_intr_lock);
		return;
	}

	/*
	 * Detect primary/secondary AC97
	 *	YMF754 Hardware Specification Rev 1.01 page 24
	 */
	reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_DSCTRL);
	pci_conf_write(pc, pa->pa_tag, YDS_PCI_DSCTRL, reg & ~YDS_DSCTRL_CRST);
	delay(400000);		/* Needed for 740C. */

	/* Primary */
	for (to = 0; to < AC97_TIMEOUT; to++) {
		if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0)
			break;
		delay(1);
	}
	if (to == AC97_TIMEOUT) {
		aprint_error_dev(self, "no AC97 available\n");
		mutex_destroy(&sc->sc_lock);
		mutex_destroy(&sc->sc_intr_lock);
		return;
	}

	/* Secondary */
	/* Secondary AC97 is used for 4ch audio. Currently unused. */
	ac97_id2 = -1;
	if ((YREAD2(sc, YDS_ACTIVITY) & YDS_ACTIVITY_DOCKA) == 0)
		goto detected;
#if 0				/* reset secondary... */
	YWRITE2(sc, YDS_GPIO_OCTRL,
		YREAD2(sc, YDS_GPIO_OCTRL) & ~YDS_GPIO_GPO2);
	YWRITE2(sc, YDS_GPIO_FUNCE,
		(YREAD2(sc, YDS_GPIO_FUNCE)&(~YDS_GPIO_GPC2))|YDS_GPIO_GPE2);
#endif
	for (to = 0; to < AC97_TIMEOUT; to++) {
		if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY) == 0)
			break;
		delay(1);
	}
	if (to < AC97_TIMEOUT) {
		/* detect id */
		for (ac97_id2 = 1; ac97_id2 < 4; ac97_id2++) {
			YWRITE2(sc, AC97_CMD_ADDR,
				AC97_CMD_READ | AC97_ID(ac97_id2) | 0x28);

			for (to = 0; to < AC97_TIMEOUT; to++) {
				if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY)
				    == 0)
					goto detected;
				delay(1);
			}
		}
		if (ac97_id2 == 4)
			ac97_id2 = -1;
detected:
		;
	}

	pci_conf_write(pc, pa->pa_tag, YDS_PCI_DSCTRL, reg | YDS_DSCTRL_CRST);
	delay (20);
	pci_conf_write(pc, pa->pa_tag, YDS_PCI_DSCTRL, reg & ~YDS_DSCTRL_CRST);
	delay (400000);
	for (to = 0; to < AC97_TIMEOUT; to++) {
		if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0)
			break;
		delay(1);
	}

	/*
	 * Attach ac97 codec
	 */
	for (i = 0; i < 2; i++) {
		static struct {
			int data;
			int addr;
		} statregs[] = {
			{AC97_STAT_DATA1, AC97_STAT_ADDR1},
			{AC97_STAT_DATA2, AC97_STAT_ADDR2},
		};

		if (i == 1 && ac97_id2 == -1)
			break;		/* secondary ac97 not available */

		codec = &sc->sc_codec[i];
		codec->sc = sc;
		codec->id = i == 1 ? ac97_id2 : 0;
		codec->status_data = statregs[i].data;
		codec->status_addr = statregs[i].addr;
		codec->host_if.arg = codec;
		codec->host_if.attach = yds_attach_codec;
		codec->host_if.read = yds_read_codec;
		codec->host_if.write = yds_write_codec;
		codec->host_if.reset = yds_reset_codec;

		r = ac97_attach(&codec->host_if, self, &sc->sc_lock);
		if (r != 0) {
			aprint_error_dev(self, "can't attach codec (error 0x%X)\n", r);
			mutex_destroy(&sc->sc_lock);
			mutex_destroy(&sc->sc_intr_lock);
			return;
		}
	}

	if (0 != auconv_create_encodings(yds_formats, YDS_NFORMATS,
	    &sc->sc_encodings)) {
		mutex_destroy(&sc->sc_lock);
		mutex_destroy(&sc->sc_intr_lock);
		return;
	}

	audio_attach_mi(&yds_hw_if, sc, self);

	sc->sc_legacy_iot = pa->pa_iot;
	config_defer(self, yds_configure_legacy);

	if (!pmf_device_register(self, yds_suspend, yds_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
jmide_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct jmide_softc *sc = device_private(self);
	const struct jmide_product *jp;
	const char *intrstr;
        pci_intr_handle_t intrhandle;
	u_int32_t pcictrl0 = pci_conf_read(pa->pa_pc, pa->pa_tag,
	    PCI_JM_CONTROL0);
	u_int32_t pcictrl1 = pci_conf_read(pa->pa_pc, pa->pa_tag,
	    PCI_JM_CONTROL1);
	struct pciide_product_desc *pp;
	int ahci_used = 0;

	sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev = self;

	jp = jmide_lookup(pa->pa_id);
	if (jp == NULL) {
		printf("jmide_attach: WTF?\n");
		return;
	}
	sc->sc_npata = jp->jm_npata;
	sc->sc_nsata = jp->jm_nsata;

        pci_aprint_devinfo(pa, "JMICRON PATA/SATA disk controller");

	aprint_normal("%s: ", JM_NAME(sc));
	if (sc->sc_npata)
		aprint_normal("%d PATA port%s", sc->sc_npata,
		    (sc->sc_npata > 1) ? "s" : "");
	if (sc->sc_nsata)
		aprint_normal("%s%d SATA port%s", sc->sc_npata ? ", " : "",
		    sc->sc_nsata, (sc->sc_nsata > 1) ? "s" : "");
	aprint_normal("\n");

	if (pci_intr_map(pa, &intrhandle) != 0) {
                aprint_error("%s: couldn't map interrupt\n", JM_NAME(sc));
                return;
        }
        intrstr = pci_intr_string(pa->pa_pc, intrhandle);
        sc->sc_pciide.sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle,
	    IPL_BIO, jmide_intr, sc);
        if (sc->sc_pciide.sc_pci_ih == NULL) {
                aprint_error("%s: couldn't establish interrupt", JM_NAME(sc));
                return;
        }
        aprint_normal("%s: interrupting at %s\n", JM_NAME(sc),
            intrstr ? intrstr : "unknown interrupt");

	if (pcictrl0 & JM_CONTROL0_AHCI_EN) {
		bus_size_t size;
		struct jmahci_attach_args jma;
		u_int32_t saved_pcictrl0;
		/*
		 * ahci controller enabled; disable sata on pciide and
		 * enable on ahci
		 */
		saved_pcictrl0 = pcictrl0;
		pcictrl0 |= JM_CONTROL0_SATA0_AHCI | JM_CONTROL0_SATA1_AHCI;
		pcictrl0 &= ~(JM_CONTROL0_SATA0_IDE | JM_CONTROL0_SATA1_IDE);
		pci_conf_write(pa->pa_pc, pa->pa_tag,
		    PCI_JM_CONTROL0, pcictrl0);
		/* attach ahci controller if on the right function */
		if ((pa->pa_function == 0 &&
		      (pcictrl0 & JM_CONTROL0_AHCI_F1) == 0) ||
	    	    (pa->pa_function == 1 &&
		      (pcictrl0 & JM_CONTROL0_AHCI_F1) != 0)) {
			jma.jma_pa = pa;
			/* map registers */
			if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
			    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
			    &jma.jma_ahcit, &jma.jma_ahcih, NULL, &size) != 0) {
				aprint_error("%s: can't map ahci registers\n",
				    JM_NAME(sc));
			} else {
				sc->sc_ahci = config_found_ia(
				    sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev,
				    "jmide_hl", &jma, jmahci_print);
			}
			/*
			 * if we couldn't attach an ahci, try to fall back
			 * to pciide. Note that this will not work if IDE
			 * is on function 0 and AHCI on function 1.
			 */
			if (sc->sc_ahci == NULL) {
				pcictrl0 = saved_pcictrl0 &
				    ~(JM_CONTROL0_SATA0_AHCI |
				      JM_CONTROL0_SATA1_AHCI |
				      JM_CONTROL0_AHCI_EN);
				pcictrl0 |= JM_CONTROL0_SATA1_IDE |
					JM_CONTROL0_SATA0_IDE;
				pci_conf_write(pa->pa_pc, pa->pa_tag,
				    PCI_JM_CONTROL0, pcictrl0);
			} else
				ahci_used = 1;
		}
	}
	sc->sc_chan_swap = ((pcictrl0 & JM_CONTROL0_PCIIDE_CS) != 0);
	/* compute the type of internal primary channel */
	if (pcictrl1 & JM_CONTROL1_PATA1_PRI) {
		if (sc->sc_npata > 1)
			sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_PATA;
		else
			sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE;
	} else if (ahci_used == 0 && sc->sc_nsata > 0)
		sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_SATA;
	else
		sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE;
	/* compute the type of internal secondary channel */
	if (sc->sc_nsata > 1 && ahci_used == 0 &&
	    (pcictrl0 & JM_CONTROL0_PCIIDE0_MS) == 0) {
		sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_SATA;
	} else {
		/* only a drive if first PATA enabled */
		if (sc->sc_npata > 0 && (pcictrl0 & JM_CONTROL0_PATA0_EN)
		    && (pcictrl0 &
		    (sc->sc_chan_swap ? JM_CONTROL0_PATA0_PRI: JM_CONTROL0_PATA0_SEC)))
			sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_PATA;
		else
			sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_NONE;
	}

	if (sc->sc_chan_type[0] == TYPE_NONE &&
	    sc->sc_chan_type[1] == TYPE_NONE)
		return;
	if (pa->pa_function == 0 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1))
		return;
	if (pa->pa_function == 1 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1) == 0)
		return;
	pp = malloc(sizeof(struct pciide_product_desc), M_DEVBUF, M_NOWAIT);
	if (pp == NULL) {
		aprint_error("%s: can't malloc sc_pp\n", JM_NAME(sc));
		return;
	}
	aprint_normal("%s: PCI IDE interface used", JM_NAME(sc));
	pp->ide_product = 0;
	pp->ide_flags = 0;
	pp->ide_name = NULL;
	pp->chip_map = jmpata_chip_map;
	pciide_common_attach(&sc->sc_pciide, pa, pp);
	
}
Beispiel #20
0
static void
rtsx_pci_attach(device_t parent, device_t self, void *aux)
{
	struct rtsx_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;
	pcireg_t reg;
	char const *intrstr;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	bus_size_t size;
	uint32_t flags;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc.sc_dev = self;
	sc->sc_pc = pc;

	pci_aprint_devinfo(pa, NULL);

	if ((pci_conf_read(pc, tag, RTSX_CFG_PCI) & RTSX_CFG_ASIC) != 0) {
		aprint_error_dev(self, "no asic\n");
		return;
	}

	if (pci_mapreg_map(pa, RTSX_PCI_BAR, PCI_MAPREG_TYPE_MEM, 0,
	    &iot, &ioh, NULL, &size)) {
		aprint_error_dev(self, "couldn't map registers\n");
		return;
	}

	if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, sc->sc_pihp[0], intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pc, sc->sc_pihp[0], IPL_SDMMC,
	    rtsx_intr, &sc->sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

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

	/* Power up the device */
	pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D0);

	switch (PCI_PRODUCT(pa->pa_id)) {
	case PCI_PRODUCT_REALTEK_RTS5209:
		flags = RTSX_F_5209;
		break;
	case PCI_PRODUCT_REALTEK_RTS5227:
		flags = RTSX_F_5227;
		break;
	case PCI_PRODUCT_REALTEK_RTS5229:
		flags = RTSX_F_5229;
		break;
	case PCI_PRODUCT_REALTEK_RTL8402:
		flags = RTSX_F_8402;
		break;
	case PCI_PRODUCT_REALTEK_RTL8411:
		flags = RTSX_F_8411;
		break;
	case PCI_PRODUCT_REALTEK_RTL8411B:
		flags = RTSX_F_8411B;
		break;
	default:
		flags = 0;
		break;
	}

	if (rtsx_attach(&sc->sc, iot, ioh, size, pa->pa_dmat, flags) != 0) {
		aprint_error_dev(self, "couldn't initialize chip\n");
		return;
	}

	if (!pmf_device_register1(self, rtsx_suspend, rtsx_resume,
	    rtsx_shutdown))
		aprint_error_dev(self, "couldn't establish powerhook\n");
}
Beispiel #21
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 #22
0
static void
ichsmb_attach(device_t parent, device_t self, void *aux)
{
	struct ichsmb_softc *sc = device_private(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;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc_dev = self;

	pci_aprint_devinfo(pa, NULL);

	/* Read configuration */
	conf = pci_conf_read(pa->pa_pc, pa->pa_tag, LPCIB_SMB_HOSTC);
	DPRINTF(("%s: conf 0x%08x\n", device_xname(sc->sc_dev), conf));

	if ((conf & LPCIB_SMB_HOSTC_HSTEN) == 0) {
		aprint_error_dev(self, "SMBus disabled\n");
		goto out;
	}

	/* Map I/O space */
	if (pci_mapreg_map(pa, LPCIB_SMB_BASE, PCI_MAPREG_TYPE_IO, 0,
	    &sc->sc_iot, &sc->sc_ioh, NULL, &iosize)) {
		aprint_error_dev(self, "can't map I/O space\n");
		goto out;
	}

	sc->sc_poll = 1;
	if (conf & LPCIB_SMB_HOSTC_SMIEN) {
		/* No PCI IRQ */
		aprint_normal_dev(self, "interrupting at SMI\n");
	} else {
		/* Install interrupt handler */
		if (pci_intr_map(pa, &ih) == 0) {
			intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
			sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
			    ichsmb_intr, sc);
			if (sc->sc_ih != NULL) {
				aprint_normal_dev(self, "interrupting at %s\n",
				    intrstr);
				sc->sc_poll = 0;
			}
		}
		if (sc->sc_poll)
			aprint_normal_dev(self, "polling\n");
	}

	/* Attach I2C bus */
	mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE);
	sc->sc_i2c_tag.ic_cookie = sc;
	sc->sc_i2c_tag.ic_acquire_bus = ichsmb_i2c_acquire_bus;
	sc->sc_i2c_tag.ic_release_bus = ichsmb_i2c_release_bus;
	sc->sc_i2c_tag.ic_exec = ichsmb_i2c_exec;

	memset(&iba, 0, sizeof(iba));
	iba.iba_type = I2C_TYPE_SMBUS;
	iba.iba_tag = &sc->sc_i2c_tag;
	config_found(self, &iba, iicbus_print);

out:	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
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 #24
0
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;
}