Пример #1
0
static void
njs_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct njsc32_pci_softc *psc = device_private(self);
	struct njsc32_softc *sc = &psc->sc_njsc32;
	const struct njsc32_pci_product *prod;
	pci_intr_handle_t ih;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcireg_t reg;
	const char *str_intr, *str_at;
	char intrbuf[PCI_INTRSTR_LEN];

	aprint_naive(": SCSI controller\n");
	if ((prod = njs_pci_lookup(pa)) == NULL)
		panic("njs_pci_attach");

	aprint_normal(": Workbit NinjaSCSI-32 SCSI adapter\n");
	sc->sc_dev = self;
	sc->sc_model = prod->p_model;
	sc->sc_clk = prod->p_clk;

	psc->sc_pc = pc;

	/* enable device and DMA */
	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);

	/*
	 * Map registers.
	 * Try memory map first, and then try I/O.
	 */
	if (pci_mapreg_map(pa, NJSC32_PCI_BASEADDR_MEM,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->sc_regt, &psc->sc_regmaph, NULL, &psc->sc_regmap_size) == 0) {
		if (bus_space_subregion(sc->sc_regt, psc->sc_regmaph,
		    NJSC32_MEMOFFSET_REG, NJSC32_REGSIZE, &sc->sc_regh) != 0) {
			/* failed -- undo map and try I/O */
			bus_space_unmap(sc->sc_regt, psc->sc_regmaph,
			    psc->sc_regmap_size);
			goto try_io;
		}
#ifdef NJSC32_DEBUG
		printf("%s: memory space mapped\n", device_xname(self));
#endif
		sc->sc_flags = NJSC32_MEM_MAPPED;
	} else {
	try_io:
		if (pci_mapreg_map(pa, NJSC32_PCI_BASEADDR_IO,
		    PCI_MAPREG_TYPE_IO, 0, &sc->sc_regt, &sc->sc_regh,
		    NULL, &psc->sc_regmap_size) == 0) {
#ifdef NJSC32_DEBUG
			printf("%s: io space mapped\n", device_xname(self));
#endif
			sc->sc_flags = NJSC32_IO_MAPPED;
		} else {
			aprint_error_dev(self, "unable to map device registers\n");
			return;
		}
	}

	sc->sc_dmat = pa->pa_dmat;

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

	str_intr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
	str_at = " at ";
	if (str_intr == NULL)
		str_at = str_intr = "";

	/* setup interrupt handler */
	if ((sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, njsc32_intr, sc))
	    == NULL) {
		aprint_error_dev(self, "unable to establish interrupt%s%s\n",
		    str_at, str_intr);
		return;
	}
	printf("%s: interrupting%s%s\n", device_xname(self), str_at, str_intr);

	/* attach */
	njsc32_attach(sc);
}
Пример #2
0
static void
njs_cardbus_attach(struct device *parent, struct device *self, void *aux)
{
	struct cardbus_attach_args *ca = aux;
	struct njsc32_cardbus_softc *csc = (void *) self;
	struct njsc32_softc *sc = &csc->sc_njsc32;
	const struct njsc32_cardbus_product *prod;
	cardbus_devfunc_t ct = ca->ca_ct;
	cardbus_chipset_tag_t cc = ct->ct_cc;
	cardbus_function_tag_t cf = ct->ct_cf;
	pcireg_t reg;
	int csr;
	u_int8_t latency = 0x20;

	if ((prod = njs_cardbus_lookup(ca)) == NULL)
		panic("njs_cardbus_attach");

	printf(": Workbit NinjaSCSI-32 SCSI adapter\n");
	sc->sc_model = prod->p_model;
	sc->sc_clk = prod->p_clk;

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

	/*
	 * Map the device.
	 */
	csr = PCI_COMMAND_MASTER_ENABLE;

	/*
	 * Map registers.
	 * Try memory map first, and then try I/O.
	 */
	if (Cardbus_mapreg_map(csc->sc_ct, NJSC32_CARDBUS_BASEADDR_MEM,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->sc_regt, &csc->sc_regmaph, NULL, &csc->sc_regmap_size) == 0) {
		if (bus_space_subregion(sc->sc_regt, csc->sc_regmaph,
		    NJSC32_MEMOFFSET_REG, NJSC32_REGSIZE, &sc->sc_regh) != 0) {
			/* failed -- undo map and try I/O */
			Cardbus_mapreg_unmap(csc->sc_ct,
			    NJSC32_CARDBUS_BASEADDR_MEM,
			    sc->sc_regt, csc->sc_regmaph, csc->sc_regmap_size);
			goto try_io;
		}
#ifdef NJSC32_DEBUG
		printf("%s: memory space mapped\n", sc->sc_dev.dv_xname);
#endif
		csr |= PCI_COMMAND_MEM_ENABLE;
		sc->sc_flags = NJSC32_MEM_MAPPED;
		(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
	} else {
	try_io:
		if (Cardbus_mapreg_map(csc->sc_ct, NJSC32_CARDBUS_BASEADDR_IO,
		    PCI_MAPREG_TYPE_IO, 0, &sc->sc_regt, &sc->sc_regh,
		    NULL, &csc->sc_regmap_size) == 0) {
#ifdef NJSC32_DEBUG
			printf("%s: io space mapped\n", sc->sc_dev.dv_xname);
#endif
			csr |= PCI_COMMAND_IO_ENABLE;
			sc->sc_flags = NJSC32_IO_MAPPED;
			(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
		} else {
			printf("%s: unable to map device registers\n",
			    sc->sc_dev.dv_xname);
			return;
		}
	}

	/* Make sure the right access type is on the CardBus bridge. */
	(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);

	/* Enable the appropriate bits in the PCI CSR. */
	reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_COMMAND_STATUS_REG);
	reg &= ~(PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE);
	reg |= csr;
	cardbus_conf_write(cc, cf, ca->ca_tag, PCI_COMMAND_STATUS_REG, reg);

	/*
	 * Make sure the latency timer is set to some reasonable
	 * value.
	 */
	reg = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG);
	if (CARDBUS_LATTIMER(reg) < latency) {
		reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
		reg |= (latency << CARDBUS_LATTIMER_SHIFT);
		cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG, reg);
	}

	sc->sc_dmat = ca->ca_dmat;

	/*
	 * Establish the interrupt.
	 */
	sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline, IPL_BIO,
	    njsc32_intr, sc);
	if (sc->sc_ih == NULL) {
		printf("%s: unable to establish interrupt at %d\n",
		    sc->sc_dev.dv_xname, ca->ca_intrline);
		return;
	}
	printf("%s: interrupting at %d\n",
	    sc->sc_dev.dv_xname, ca->ca_intrline);

	/* CardBus device cannot supply termination power. */
	sc->sc_flags |= NJSC32_CANNOT_SUPPLY_TERMPWR;

	/* attach */
	njsc32_attach(sc);
}