Пример #1
0
void
adv_cardbus_attach(struct device *parent, struct device *self,
    void *aux)
{
	struct cardbus_attach_args *ca = aux;
	struct adv_cardbus_softc *csc = device_private(self);
	struct asc_softc *sc = &csc->sc_adv;
	cardbus_devfunc_t ct = ca->ca_ct;
	cardbus_chipset_tag_t cc = ct->ct_cc;
	cardbus_function_tag_t cf = ct->ct_cf;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	pcireg_t reg;
	u_int8_t latency = 0x20;

	sc->sc_flags = 0;

	if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_ADVSYS) {
		switch (PCI_PRODUCT(ca->ca_id)) {
		case PCI_PRODUCT_ADVSYS_1200A:
			printf(": AdvanSys ASC1200A SCSI adapter\n");
			latency = 0;
			break;

		case PCI_PRODUCT_ADVSYS_1200B:
			printf(": AdvanSys ASC1200B SCSI adapter\n");
			latency = 0;
			break;

		case PCI_PRODUCT_ADVSYS_ULTRA:
			switch (PCI_REVISION(ca->ca_class)) {
			case ASC_PCI_REVISION_3050:
				printf(": AdvanSys ABP-9xxUA SCSI adapter\n");
				break;

			case ASC_PCI_REVISION_3150:
				printf(": AdvanSys ABP-9xxU SCSI adapter\n");
				break;
			}
			break;

		default:
			printf(": unknown model!\n");
			return;
		}
	}

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

	/*
	 * Map the device.
	 */
	csc->sc_csr = PCI_COMMAND_MASTER_ENABLE;

#ifdef ADV_CARDBUS_ALLOW_MEMIO
	if (Cardbus_mapreg_map(csc->sc_ct, ADV_CARDBUS_MMBA,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &iot, &ioh, NULL, &csc->sc_size) == 0) {
#ifdef ADV_CARDBUS_DEBUG
		printf("%s: memio enabled\n", DEVNAME(sc));
#endif
		csc->sc_cbenable = CARDBUS_MEM_ENABLE;
		csc->sc_csr |= PCI_COMMAND_MEM_ENABLE;
	} else
#endif
	if (Cardbus_mapreg_map(csc->sc_ct, ADV_CARDBUS_IOBA,
	    PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, &csc->sc_size) == 0) {
#ifdef ADV_CARDBUS_DEBUG
		printf("%s: io enabled\n", DEVNAME(sc));
#endif
		csc->sc_cbenable = CARDBUS_IO_ENABLE;
		csc->sc_csr |= PCI_COMMAND_IO_ENABLE;
	} else {
		aprint_error_dev(&sc->sc_dev, "unable to map device registers\n");
		return;
	}

	/* Make sure the right access type is on the CardBus bridge. */
	(*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cbenable);
	(*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 |= csc->sc_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, PCI_BHLC_REG);
	if (PCI_LATTIMER(reg) < latency) {
		reg &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
		reg |= (latency << PCI_LATTIMER_SHIFT);
		cardbus_conf_write(cc, cf, ca->ca_tag, PCI_BHLC_REG, reg);
	}

	ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
	ASC_SET_CHIP_STATUS(iot, ioh, 0);

	sc->sc_iot = iot;
	sc->sc_ioh = ioh;
	sc->sc_dmat = ca->ca_dmat;
	sc->pci_device_id = ca->ca_id;
	sc->bus_type = ASC_IS_PCI;
	sc->chip_version = ASC_GET_CHIP_VER_NO(iot, ioh);

	/*
	 * Initialize the board
	 */
	if (adv_init(sc)) {
		printf("adv_init failed\n");
		return;
	}

	/*
	 * Establish the interrupt.
	 */
	sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline, IPL_BIO,
	    adv_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(&sc->sc_dev,
				 "unable to establish interrupt\n");
		return;
	}

	/*
	 * Attach.
	 */
	adv_attach(sc);
}
Пример #2
0
int
adv_isa_probe(device_t parent, cfdata_t match, void *aux)
{
	struct isa_attach_args *ia = aux;
	bus_space_tag_t iot = ia->ia_iot;
	bus_space_handle_t ioh;
	int port_index;
	int iobase, irq, drq;
	int rv = 0;

	if (ia->ia_nio < 1)
		return (0);
	if (ia->ia_nirq < 1)
		return (0);
	if (ia->ia_ndrq < 1)
		return (0);

	if (ISA_DIRECT_CONFIG(ia))
		return (0);

	/*
	 * If the I/O address is wildcarded, look for boards
	 * in ascending order.
	 */
	if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) {
		for (port_index = 0; port_index < ASC_IOADR_TABLE_MAX_IX;
		     port_index++) {
			iobase = asc_ioport[port_index];

			if (iobase) {
				if (bus_space_map(iot, iobase, ASC_IOADR_GAP,
				    0, &ioh))
					continue;

				rv = AscFindSignature(iot, ioh);

				if (rv) {
					ia->ia_io[0].ir_addr = iobase;
					break;
				}

				bus_space_unmap(iot, ioh, ASC_IOADR_GAP);
			}
		}
		if (rv == 0)
			return (0);
	} else {
		iobase = ia->ia_io[0].ir_addr;
		if (bus_space_map(iot, iobase, ASC_IOADR_GAP, 0, &ioh))
			return (0);

		rv = AscFindSignature(iot, ioh);

		if (rv == 0) {
			bus_space_unmap(iot, ioh, ASC_IOADR_GAP);
			return (0);
		}
	}

	/* XXXJRT Probe routines should not have side-effects!! */
	ASC_SET_CHIP_CONTROL(iot, ioh, ASC_CC_HALT);
	ASC_SET_CHIP_STATUS(iot, ioh, 0);

	irq = AscGetChipIRQ(iot, ioh, ASC_IS_ISA);
	drq = AscGetIsaDmaChannel(iot, ioh);

	/* Verify that the IRQ/DRQ match (or are wildcarded). */
	if (ia->ia_irq[0].ir_irq != ISA_UNKNOWN_IRQ &&
	    ia->ia_irq[0].ir_irq != irq) {
		rv = 0;
		goto out;
	}
	if (ia->ia_drq[0].ir_drq != ISA_UNKNOWN_DRQ &&
	    ia->ia_drq[0].ir_drq != drq) {
		rv = 0;
		goto out;
	}

	ia->ia_nio = 1;
	ia->ia_io[0].ir_addr = iobase;
	ia->ia_io[0].ir_size = ASC_IOADR_GAP;

	ia->ia_nirq = 1;
	ia->ia_irq[0].ir_irq = irq;

	ia->ia_ndrq = 1;
	ia->ia_drq[0].ir_drq = drq;

	ia->ia_niomem = 0;

 out:
	bus_space_unmap(iot, ioh, ASC_IOADR_GAP);
	return rv;
}