static void
ahd_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args	*pa = aux;
	struct ahd_softc       	*ahd = device_private(self);

	const struct ahd_pci_identity *entry;

	uint32_t	   	devconfig;
	pcireg_t	   	command;
	int		   	error;
	pcireg_t	   	subid;
	uint16_t	   	subvendor;
	pcireg_t           	reg;
	int		   	ioh_valid, ioh2_valid, memh_valid;
	pcireg_t           	memtype;
	pci_intr_handle_t  	ih;
	const char         	*intrstr;
	struct ahd_pci_busdata 	*bd;

	ahd->sc_dev = self;
	ahd_set_name(ahd, device_xname(self));
	ahd->parent_dmat = pa->pa_dmat;

	command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	entry = ahd_find_pci_device(pa->pa_id, subid);
	if (entry == NULL)
		return;

	/* Keep information about the PCI bus */
	bd = malloc(sizeof (struct ahd_pci_busdata), M_DEVBUF, M_NOWAIT);
	if (bd == NULL) {
		aprint_error("%s: unable to allocate bus-specific data\n",
		    ahd_name(ahd));
		return;
	}
	memset(bd, 0, sizeof(struct ahd_pci_busdata));

	bd->pc = pa->pa_pc;
	bd->tag = pa->pa_tag;
	bd->func = pa->pa_function;
	bd->dev = pa->pa_device;

	ahd->bus_data = bd;

	ahd->description = entry->name;

	ahd->seep_config = malloc(sizeof(*ahd->seep_config),
				  M_DEVBUF, M_NOWAIT);
	if (ahd->seep_config == NULL) {
		aprint_error("%s: cannot malloc seep_config!\n", ahd_name(ahd));
		return;
	}
	memset(ahd->seep_config, 0, sizeof(*ahd->seep_config));

	LIST_INIT(&ahd->pending_scbs);
	ahd_timer_init(&ahd->reset_timer);
	ahd_timer_init(&ahd->stat_timer);
	ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A
	    | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
	ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
	ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
	ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
	ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT;
	ahd->int_coalescing_stop_threshold =
	    AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT;

	if (ahd_platform_alloc(ahd, NULL) != 0) {
                ahd_free(ahd);
                return;
        }

	/*
	 * Record if this is an HP board.
	 */
	subvendor = PCI_VENDOR(subid);
	if (subvendor == SUBID_HP)
		ahd->flags |= AHD_HP_BOARD;

	error = entry->setup(ahd, pa);
	if (error != 0)
		return;

	devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
	if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
		ahd->chip |= AHD_PCI;
		/* Disable PCIX workarounds when running in PCI mode. */
		ahd->bugs &= ~AHD_PCIX_BUG_MASK;
	} else {
		ahd->chip |= AHD_PCIX;
	}
	ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];

	memh_valid = ioh_valid = ioh2_valid = 0;

	if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
	    &bd->pcix_off, NULL)) {
		if (ahd->chip & AHD_PCIX)
			aprint_error_dev(self,
			    "warning: can't find PCI-X capability\n");
		ahd->chip &= ~AHD_PCIX;
		ahd->chip |= AHD_PCI;
		ahd->bugs &= ~AHD_PCIX_BUG_MASK;
	}

	/*
	 * Map PCI Registers
	 */
	if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) {
		memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
					  AHD_PCI_MEMADDR);
		switch (memtype) {
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
			memh_valid = (pci_mapreg_map(pa, AHD_PCI_MEMADDR,
						     memtype, 0, &ahd->tags[0],
						     &ahd->bshs[0],
						     NULL, NULL) == 0);
			if (memh_valid) {
				ahd->tags[1] = ahd->tags[0];
				bus_space_subregion(ahd->tags[0], ahd->bshs[0],
						    /*offset*/0x100,
						    /*size*/0x100,
						    &ahd->bshs[1]);
				if (ahd_pci_test_register_access(ahd) != 0)
					memh_valid = 0;
			}
			break;
		default:
			memh_valid = 0;
			aprint_error("%s: unknown memory type: 0x%x\n",
			       ahd_name(ahd), memtype);
			break;
		}

		if (memh_valid) {
			command &= ~PCI_COMMAND_IO_ENABLE;
                        pci_conf_write(pa->pa_pc, pa->pa_tag,
                        	       PCI_COMMAND_STATUS_REG, command);
		}
#ifdef AHD_DEBUG
		printf("%s: doing memory mapping shs0 0x%lx, shs1 0x%lx\n",
		    ahd_name(ahd), ahd->bshs[0], ahd->bshs[1]);
#endif
	}

	if (command & PCI_COMMAND_IO_ENABLE) {
		/* First BAR */
		ioh_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR,
					    PCI_MAPREG_TYPE_IO, 0,
					    &ahd->tags[0], &ahd->bshs[0],
					    NULL, NULL) == 0);

		/* 2nd BAR */
		ioh2_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR1,
					     PCI_MAPREG_TYPE_IO, 0,
					     &ahd->tags[1], &ahd->bshs[1],
					     NULL, NULL) == 0);

		if (ioh_valid && ioh2_valid) {
			KASSERT(memh_valid == 0);
			command &= ~PCI_COMMAND_MEM_ENABLE;
                        pci_conf_write(pa->pa_pc, pa->pa_tag,
                        	       PCI_COMMAND_STATUS_REG, command);
		}
#ifdef AHD_DEBUG
		printf("%s: doing io mapping shs0 0x%lx, shs1 0x%lx\n",
		    ahd_name(ahd), ahd->bshs[0], ahd->bshs[1]);
#endif

	}

	if (memh_valid == 0 && (ioh_valid == 0 || ioh2_valid == 0)) {
		aprint_error("%s: unable to map registers\n", ahd_name(ahd));
		return;
	}

	aprint_normal("\n");
	aprint_naive("\n");

	/* power up chip */
	if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self,
	    pci_activate_null)) && error != EOPNOTSUPP) {
		aprint_error_dev(self, "cannot activate %d\n", error);
		return;
	}
	/*
         * Should we bother disabling 39Bit addressing
         * based on installed memory?
         */
        if (sizeof(bus_addr_t) > 4)
        	ahd->flags |= AHD_39BIT_ADDRESSING;

	/*
	 * If we need to support high memory, enable dual
	 * address cycles.  This bit must be set to enable
	 * high address bit generation even if we are on a
	 * 64bit bus (PCI64BIT set in devconfig).
	 */
	if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
		uint32_t dvconfig;

		aprint_normal("%s: Enabling 39Bit Addressing\n", ahd_name(ahd));
		dvconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
		dvconfig |= DACEN;
		pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, dvconfig);
	}

	/* Ensure busmastering is enabled */
        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);

	ahd_softc_init(ahd);

	/*
	 * Map the interrupt routines
	 */
	ahd->bus_intr = ahd_pci_intr;

	error = ahd_reset(ahd, /*reinit*/FALSE);
	if (error != 0) {
		ahd_free(ahd);
		return;
	}

	if (pci_intr_map(pa, &ih)) {
		aprint_error("%s: couldn't map interrupt\n", ahd_name(ahd));
		ahd_free(ahd);
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	ahd->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahd_intr, ahd);
	if (ahd->ih == NULL) {
		aprint_error("%s: couldn't establish interrupt",
		       ahd_name(ahd));
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		ahd_free(ahd);
		return;
	}
	if (intrstr != NULL)
		aprint_normal("%s: interrupting at %s\n", ahd_name(ahd),
		       intrstr);

	/* Get the size of the cache */
	ahd->pci_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
	ahd->pci_cachesize *= 4;

 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
	/* See if we have a SEEPROM and perform auto-term */
	error = ahd_check_extport(ahd);
	if (error != 0)
		return;

	/* Core initialization */
	error = ahd_init(ahd);
	if (error != 0)
		return;

	/*
	 * Link this softc in with all other ahd instances.
	 */
	ahd_attach(ahd);
}
Beispiel #2
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");
}
static void
sf_pci_attach(device_t parent, device_t self, void *aux)
{
	struct sf_pci_softc *psc = device_private(self);
	struct sf_softc *sc = &psc->sc_starfire;
	struct pci_attach_args *pa = aux;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	const struct sf_pci_product *spp;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	pcireg_t reg;
	int error, ioh_valid, memh_valid;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc_dev = self;
	spp = sf_pci_lookup(pa);
	if (spp == NULL) {
		printf("\n");
		panic("sf_pci_attach: impossible");
	}

	printf(": %s, rev. %d\n", spp->spp_name, PCI_REVISION(pa->pa_class));

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

	/*
	 * Map the device.
	 */
	reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SF_PCI_MEMBA);
	switch (reg) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		memh_valid = (pci_mapreg_map(pa, SF_PCI_MEMBA,
		    reg, 0, &memt, &memh, NULL, NULL) == 0);
		break;
	default:
		memh_valid = 0;
	}

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

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

	sc->sc_dmat = pa->pa_dmat;

	/* Make sure bus mastering is enabled. */
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);

	/*
	 * Map and establish our interrupt.
	 */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "unable to map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
	psc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, sf_intr, sc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(self, "unable to establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	/*
	 * Finish off the attach.
	 */
	sf_attach(sc);
}
static void
epic_pci_attach(device_t parent, device_t self, void *aux)
{
	struct epic_pci_softc *psc = device_private(self);
	struct epic_softc *sc = &psc->sc_epic;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	const struct epic_pci_product *epp;
	const struct epic_pci_subsys_info *esp;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	int ioh_valid, memh_valid;
	int error;

	sc->sc_dev = self;

	epp = epic_pci_lookup(pa);
	if (epp == NULL) {
		aprint_normal("\n");
		panic("%s: impossible", __func__);
	}

	pci_aprint_devinfo_fancy(pa, "Ethernet controller", epp->epp_name, 1);

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

	/*
	 * Map the device.
	 */
	ioh_valid = (pci_mapreg_map(pa, EPIC_PCI_IOBA,
	    PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, NULL, NULL) == 0);
	memh_valid = (pci_mapreg_map(pa, EPIC_PCI_MMBA,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &memt, &memh, NULL, NULL) == 0);

	if (memh_valid) {
		sc->sc_st = memt;
		sc->sc_sh = memh;
	} else if (ioh_valid) {
		sc->sc_st = iot;
		sc->sc_sh = ioh;
	} else {
		aprint_error_dev(self, "unable to map device registers\n");
		return;
	}

	sc->sc_dmat = pa->pa_dmat;

	/* Make sure bus mastering is enabled. */
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);

	/*
	 * Map and establish our interrupt.
	 */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "unable to map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, epic_intr, sc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(self, "unable to establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	esp = epic_pci_subsys_lookup(pa);
	if (esp)
		sc->sc_hwflags = esp->flags;

	/*
	 * Finish off the attach.
	 */
	epic_attach(sc);
}
static void
ste_attach(device_t parent, device_t self, void *aux)
{
	struct ste_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	bus_dma_segment_t seg;
	int ioh_valid, memh_valid;
	int i, rseg, error;
	const struct ste_product *sp;
	uint8_t enaddr[ETHER_ADDR_LEN];
	uint16_t myea[ETHER_ADDR_LEN / 2];

	callout_init(&sc->sc_tick_ch, 0);

	sp = ste_lookup(pa);
	if (sp == NULL) {
		printf("\n");
		panic("ste_attach: impossible");
	}

	printf(": %s\n", sp->ste_name);

	/*
	 * Map the device.
	 */
	ioh_valid = (pci_mapreg_map(pa, STE_PCI_IOBA,
	    PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, NULL, NULL) == 0);
	memh_valid = (pci_mapreg_map(pa, STE_PCI_MMBA,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &memt, &memh, NULL, NULL) == 0);

	if (memh_valid) {
		sc->sc_st = memt;
		sc->sc_sh = memh;
	} else if (ioh_valid) {
		sc->sc_st = iot;
		sc->sc_sh = ioh;
	} else {
		aprint_error_dev(&sc->sc_dev, "unable to map device registers\n");
		return;
	}

	sc->sc_dmat = pa->pa_dmat;

	/* Enable bus mastering. */
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);

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

	/*
	 * Map and establish our interrupt.
	 */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(&sc->sc_dev, "unable to map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ste_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(&sc->sc_dev, "unable to establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf("%s: interrupting at %s\n", device_xname(&sc->sc_dev), intrstr);

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct ste_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
	    0)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to allocate control data, error = %d\n",
		    error);
		goto fail_0;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
	    sizeof(struct ste_control_data), (void **)&sc->sc_control_data,
	    BUS_DMA_COHERENT)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to map control data, error = %d\n",
		    error);
		goto fail_1;
	}

	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct ste_control_data), 1,
	    sizeof(struct ste_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to create control data DMA map, "
		    "error = %d\n", error);
		goto fail_2;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct ste_control_data), NULL,
	    0)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to load control data DMA map, error = %d\n",
		    error);
		goto fail_3;
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < STE_NTXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		    STE_NTXFRAGS, MCLBYTES, 0, 0,
		    &sc->sc_txsoft[i].ds_dmamap)) != 0) {
			aprint_error_dev(&sc->sc_dev, "unable to create tx DMA map %d, "
			    "error = %d\n", i, error);
			goto fail_4;
		}
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < STE_NRXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
			aprint_error_dev(&sc->sc_dev, "unable to create rx DMA map %d, "
			    "error = %d\n", i, error);
			goto fail_5;
		}
		sc->sc_rxsoft[i].ds_mbuf = NULL;
	}

	/*
	 * Reset the chip to a known state.
	 */
	ste_reset(sc, AC_GlobalReset | AC_RxReset | AC_TxReset | AC_DMA |
	    AC_FIFO | AC_Network | AC_Host | AC_AutoInit | AC_RstOut);

	/*
	 * Read the Ethernet address from the EEPROM.
	 */
	for (i = 0; i < 3; i++) {
		ste_read_eeprom(sc, STE_EEPROM_StationAddress0 + i, &myea[i]);
		myea[i] = le16toh(myea[i]);
	}
	memcpy(enaddr, myea, sizeof(enaddr));

	printf("%s: Ethernet address %s\n", device_xname(&sc->sc_dev),
	    ether_sprintf(enaddr));

	/*
	 * Initialize our media structures and probe the MII.
	 */
	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = ste_mii_readreg;
	sc->sc_mii.mii_writereg = ste_mii_writereg;
	sc->sc_mii.mii_statchg = ste_mii_statchg;
	sc->sc_ethercom.ec_mii = &sc->sc_mii;
	ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange,
	    ether_mediastatus);
	mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);
	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);

	ifp = &sc->sc_ethercom.ec_if;
	strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = ste_ioctl;
	ifp->if_start = ste_start;
	ifp->if_watchdog = ste_watchdog;
	ifp->if_init = ste_init;
	ifp->if_stop = ste_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * Default the transmit threshold to 128 bytes.
	 */
	sc->sc_txthresh = 128;

	/*
	 * Disable MWI if the PCI layer tells us to.
	 */
	sc->sc_DMACtrl = 0;
	if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0)
		sc->sc_DMACtrl |= DC_MWIDisable;

	/*
	 * We can support 802.1Q VLAN-sized frames.
	 */
	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, enaddr);

	/*
	 * Make sure the interface is shutdown during reboot.
	 */
	sc->sc_sdhook = shutdownhook_establish(ste_shutdown, sc);
	if (sc->sc_sdhook == NULL)
		printf("%s: WARNING: unable to establish shutdown hook\n",
		    device_xname(&sc->sc_dev));
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_5:
	for (i = 0; i < STE_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].ds_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_rxsoft[i].ds_dmamap);
	}
 fail_4:
	for (i = 0; i < STE_NTXDESC; i++) {
		if (sc->sc_txsoft[i].ds_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].ds_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
	    sizeof(struct ste_control_data));
 fail_1:
	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
 fail_0:
	return;
}
static void
tlp_pci_attach(device_t parent, device_t self, void *aux)
{
	struct tulip_pci_softc *psc = device_private(self);
	struct tulip_softc *sc = &psc->sc_tulip;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	int ioh_valid, memh_valid, i, j;
	const struct tulip_pci_product *tpp;
	prop_data_t ea;
	uint8_t enaddr[ETHER_ADDR_LEN];
	uint32_t val = 0;
	pcireg_t reg;
	int error;
	bus_size_t iosize = 0, memsize = 0;

	sc->sc_dev = self;
	sc->sc_devno = pa->pa_device;
	psc->sc_pc = pa->pa_pc;
	psc->sc_pcitag = pa->pa_tag;

	LIST_INIT(&psc->sc_intrslaves);

	tpp = tlp_pci_lookup(pa);
	if (tpp == NULL) {
		printf("\n");
		panic("tlp_pci_attach: impossible");
	}
	sc->sc_chip = tpp->tpp_chip;

	/*
	 * By default, Tulip registers are 8 bytes long (4 bytes
	 * followed by a 4 byte pad).
	 */
	sc->sc_regshift = 3;

	/*
	 * No power management hooks.
	 * XXX Maybe we should add some!
	 */
	sc->sc_flags |= TULIPF_ENABLED;

	/*
	 * Get revision info, and set some chip-specific variables.
	 */
	sc->sc_rev = PCI_REVISION(pa->pa_class);
	switch (sc->sc_chip) {
	case TULIP_CHIP_21140:
		if (sc->sc_rev >= 0x20)
			sc->sc_chip = TULIP_CHIP_21140A;
		break;

	case TULIP_CHIP_21142:
		if (sc->sc_rev >= 0x20)
			sc->sc_chip = TULIP_CHIP_21143;
		break;

	case TULIP_CHIP_82C168:
		if (sc->sc_rev >= 0x20)
			sc->sc_chip = TULIP_CHIP_82C169;
		break;

	case TULIP_CHIP_MX98713:
		if (sc->sc_rev >= 0x10)
			sc->sc_chip = TULIP_CHIP_MX98713A;
		break;

	case TULIP_CHIP_MX98715:
		if (sc->sc_rev >= 0x20)
			sc->sc_chip = TULIP_CHIP_MX98715A;
		if (sc->sc_rev >= 0x25)
			sc->sc_chip = TULIP_CHIP_MX98715AEC_X;
		if (sc->sc_rev >= 0x30)
			sc->sc_chip = TULIP_CHIP_MX98725;
		break;

	case TULIP_CHIP_WB89C840F:
		sc->sc_regshift = 2;
		break;

	case TULIP_CHIP_AN985:
		/*
		 * The AN983 and AN985 are very similar, and are
		 * differentiated by a "signature" register that
		 * is like, but not identical, to a PCI ID register.
		 */
		reg = pci_conf_read(pc, pa->pa_tag, 0x80);
		switch (reg) {
		case 0x09811317:
			sc->sc_chip = TULIP_CHIP_AN985;
			break;

		case 0x09851317:
			sc->sc_chip = TULIP_CHIP_AN983;
			break;

		default:
			/* Unknown -- use default. */
			break;
		}
		break;

	case TULIP_CHIP_AX88140:
		if (sc->sc_rev >= 0x10)
			sc->sc_chip = TULIP_CHIP_AX88141;
		break;

	case TULIP_CHIP_DM9102:
		if (sc->sc_rev >= 0x30)
			sc->sc_chip = TULIP_CHIP_DM9102A;
		break;

	default:
		/* Nothing. */
		break;
	}

	aprint_normal(": %s Ethernet, pass %d.%d\n",
	    tlp_chip_name(sc->sc_chip),
	    (sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf);

	switch (sc->sc_chip) {
	case TULIP_CHIP_21040:
		if (sc->sc_rev < 0x20) {
			aprint_normal_dev(self,
			    "21040 must be at least pass 2.0\n");
			return;
		}
		break;

	case TULIP_CHIP_21140:
		if (sc->sc_rev < 0x11) {
			aprint_normal_dev(self,
			    "21140 must be at least pass 1.1\n");
			return;
		}
		break;

	default:
		/* Nothing. */
		break;
	}

	/*
	 * Check to see if the device is in power-save mode, and
	 * being it out if necessary.
	 */
	switch (sc->sc_chip) {
	case TULIP_CHIP_21140:
	case TULIP_CHIP_21140A:
	case TULIP_CHIP_21142:
	case TULIP_CHIP_21143:
	case TULIP_CHIP_MX98713A:
	case TULIP_CHIP_MX98715:
	case TULIP_CHIP_MX98715A:
	case TULIP_CHIP_MX98715AEC_X:
	case TULIP_CHIP_MX98725:
	case TULIP_CHIP_DM9102:
	case TULIP_CHIP_DM9102A:
	case TULIP_CHIP_AX88140:
	case TULIP_CHIP_AX88141:
	case TULIP_CHIP_RS7112:
		/*
		 * Clear the "sleep mode" bit in the CFDA register.
		 */
		reg = pci_conf_read(pc, pa->pa_tag, TULIP_PCI_CFDA);
		if (reg & (CFDA_SLEEP|CFDA_SNOOZE))
			pci_conf_write(pc, pa->pa_tag, TULIP_PCI_CFDA,
			    reg & ~(CFDA_SLEEP|CFDA_SNOOZE));
		break;

	default:
		/* Nothing. */
		break;
	}

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

	/*
	 * Map the device.
	 */

	ioh_valid = (pci_mapreg_map(pa, TULIP_PCI_IOBA,
	    PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, NULL, &iosize) == 0);
	memh_valid = (pci_mapreg_map(pa, TULIP_PCI_MMBA,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &memt, &memh, NULL, &memsize) == 0);
	if (memh_valid) {
		sc->sc_st = memt;
		sc->sc_sh = memh;
		psc->sc_mapsize = memsize;
		if (ioh_valid) {
			bus_space_unmap(iot, ioh, iosize);
			ioh_valid = 0;
		}
	} else if (ioh_valid) {
		sc->sc_st = iot;
		sc->sc_sh = ioh;
		psc->sc_mapsize = iosize;
		if (memh_valid) {
			bus_space_unmap(memt, memh, memsize);
			memh_valid = 0;
		}
	} else {
		aprint_error_dev(self, "unable to map device registers\n");
		goto fail;
	}

	sc->sc_dmat = pa->pa_dmat;

	/*
	 * Make sure bus mastering is enabled.
	 */
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);

	/*
	 * Get the cacheline size.
	 */
	sc->sc_cacheline = PCI_CACHELINE(pci_conf_read(pc, pa->pa_tag,
	    PCI_BHLC_REG));

	/*
	 * Get PCI data moving command info.
	 */
	if (pa->pa_flags & PCI_FLAGS_MRL_OKAY)
		sc->sc_flags |= TULIPF_MRL;
	if (pa->pa_flags & PCI_FLAGS_MRM_OKAY)
		sc->sc_flags |= TULIPF_MRM;
	if (pa->pa_flags & PCI_FLAGS_MWI_OKAY)
		sc->sc_flags |= TULIPF_MWI;

	/*
	 * Read the contents of the Ethernet Address ROM/SROM.
	 */
	switch (sc->sc_chip) {
	case TULIP_CHIP_21040:
		sc->sc_srom_addrbits = 6;
		sc->sc_srom = malloc(TULIP_ROM_SIZE(6), M_DEVBUF, M_NOWAIT);
		TULIP_WRITE(sc, CSR_MIIROM, MIIROM_SROMCS);
		for (i = 0; i < TULIP_ROM_SIZE(6); i++) {
			for (j = 0; j < 10000; j++) {
				val = TULIP_READ(sc, CSR_MIIROM);
				if ((val & MIIROM_DN) == 0)
					break;
			}
			sc->sc_srom[i] = val & MIIROM_DATA;
		}
		break;

	case TULIP_CHIP_82C168:
	case TULIP_CHIP_82C169:
	    {
		sc->sc_srom_addrbits = 2;
		sc->sc_srom = malloc(TULIP_ROM_SIZE(2), M_DEVBUF, M_NOWAIT);

		/*
		 * The Lite-On PNIC stores the Ethernet address in
		 * the first 3 words of the EEPROM.  EEPROM access
		 * is not like the other Tulip chips.
		 */
		for (i = 0; i < 6; i += 2) {
			TULIP_WRITE(sc, CSR_PNIC_SROMCTL,
			    PNIC_SROMCTL_READ | (i >> 1));
			for (j = 0; j < 500; j++) {
				delay(2);
				val = TULIP_READ(sc, CSR_MIIROM);
				if ((val & PNIC_MIIROM_BUSY) == 0)
					break;
			}
			if (val & PNIC_MIIROM_BUSY) {
				aprint_error_dev(self, "EEPROM timed out\n");
				goto fail;
			}
			val &= PNIC_MIIROM_DATA;
			sc->sc_srom[i] = val >> 8;
			sc->sc_srom[i + 1] = val & 0xff;
		}
		break;
	    }

	default:
		/*
		 * XXX This isn't quite the right way to do this; we should
		 * XXX be attempting to fetch the mac-addr property in the
		 * XXX bus-agnostic part of the driver independently.  But
		 * XXX that requires a larger change in the SROM handling
		 * XXX logic, and for now we can at least remove a machine-
		 * XXX dependent wart from the PCI front-end.
		 */
		ea = prop_dictionary_get(device_properties(self),
					 "mac-address");
		if (ea != NULL) {
			extern int tlp_srom_debug;
			KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
			KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);

			memcpy(enaddr, prop_data_data_nocopy(ea),
			       ETHER_ADDR_LEN);

			sc->sc_srom_addrbits = 6;
			sc->sc_srom = malloc(TULIP_ROM_SIZE(6), M_DEVBUF,
			    M_NOWAIT|M_ZERO);
			memcpy(sc->sc_srom, enaddr, sizeof(enaddr));
			if (tlp_srom_debug) {
				aprint_normal("SROM CONTENTS:");
				for (i = 0; i < TULIP_ROM_SIZE(6); i++) {
					if ((i % 8) == 0)
						aprint_normal("\n\t");
					aprint_normal("0x%02x ", sc->sc_srom[i]);
				}
				aprint_normal("\n");
			}
			break;
		}

		/* Check for a slaved ROM on a multi-port board. */
		tlp_pci_check_slaved(psc, TULIP_PCI_SHAREDROM,
		    TULIP_PCI_SLAVEROM);
		if (psc->sc_flags & TULIP_PCI_SLAVEROM) {
			sc->sc_srom_addrbits =
			    psc->sc_master->sc_tulip.sc_srom_addrbits;
			sc->sc_srom = psc->sc_master->sc_tulip.sc_srom;
			enaddr[5] +=
			    sc->sc_devno - psc->sc_master->sc_tulip.sc_devno;
		}
		else if (tlp_read_srom(sc) == 0)
			goto cant_cope;
		break;
	}

	/*
	 * Deal with chip/board quirks.  This includes setting up
	 * the mediasw, and extracting the Ethernet address from
	 * the rombuf.
	 */
	switch (sc->sc_chip) {
	case TULIP_CHIP_21040:
		/*
		 * Parse the Ethernet Address ROM.
		 */
		if (tlp_parse_old_srom(sc, enaddr) == 0)
			goto cant_cope;


		/*
		 * All 21040 boards start out with the same
		 * media switch.
		 */
		sc->sc_mediasw = &tlp_21040_mediasw;

		/*
		 * Deal with any quirks this board might have.
		 */
		tlp_pci_get_quirks(psc, enaddr, tlp_pci_21040_quirks);
		break;

	case TULIP_CHIP_21041:
		/* Check for new format SROM. */
		if (tlp_isv_srom_enaddr(sc, enaddr) == 0) {
			/*
			 * Not an ISV SROM; try the old DEC Ethernet Address
			 * ROM format.
			 */
			if (tlp_parse_old_srom(sc, enaddr) == 0)
				goto cant_cope;
		}

		/*
		 * All 21041 boards use the same media switch; they all
		 * work basically the same!  Yippee!
		 */
		sc->sc_mediasw = &tlp_21041_mediasw;

		/*
		 * Deal with any quirks this board might have.
		 */
		tlp_pci_get_quirks(psc, enaddr, tlp_pci_21041_quirks);
		break;

	case TULIP_CHIP_21140:
	case TULIP_CHIP_21140A:
		/* Check for new format SROM. */
		if (tlp_isv_srom_enaddr(sc, enaddr) == 0) {
			/*
			 * Not an ISV SROM; try the old DEC Ethernet Address
			 * ROM format.
			 */
			if (tlp_parse_old_srom(sc, enaddr) == 0)
				goto cant_cope;
		} else {
			/*
			 * We start out with the 2114x ISV media switch.
			 * When we search for quirks, we may change to
			 * a different switch.
			 */
			sc->sc_mediasw = &tlp_2114x_isv_mediasw;
		}

		/*
		 * Deal with any quirks this board might have.
		 */
		tlp_pci_get_quirks(psc, enaddr, tlp_pci_21140_quirks);

		/*
		 * Bail out now if we can't deal with this board.
		 */
		if (sc->sc_mediasw == NULL)
			goto cant_cope;
		break;

	case TULIP_CHIP_21142:
	case TULIP_CHIP_21143:
		/* Check for new format SROM. */
		if (tlp_isv_srom_enaddr(sc, enaddr) == 0) {
			/*
			 * Not an ISV SROM; try the old DEC Ethernet Address
			 * ROM format.
			 */
			if (tlp_parse_old_srom(sc, enaddr) == 0) {
				/*
				 * One last try: just copy the address
				 * from offset 20 and try to look
				 * up quirks.
				 */
				memcpy(enaddr, &sc->sc_srom[20],
				    ETHER_ADDR_LEN);
			}
		} else {
			/*
			 * We start out with the 2114x ISV media switch.
			 * When we search for quirks, we may change to
			 * a different switch.
			 */
			sc->sc_mediasw = &tlp_2114x_isv_mediasw;
		}

		/*
		 * Deal with any quirks this board might have.
		 */
		tlp_pci_get_quirks(psc, enaddr, tlp_pci_21142_quirks);

		/*
		 * Bail out now if we can't deal with this board.
		 */
		if (sc->sc_mediasw == NULL)
			goto cant_cope;
		break;

	case TULIP_CHIP_82C168:
	case TULIP_CHIP_82C169:
		/*
		 * Lite-On PNIC's Ethernet address is the first 6
		 * bytes of its EEPROM.
		 */
		memcpy(enaddr, sc->sc_srom, ETHER_ADDR_LEN);

		/*
		 * Lite-On PNICs always use the same mediasw; we
		 * select MII vs. internal NWAY automatically.
		 */
		sc->sc_mediasw = &tlp_pnic_mediasw;
		break;

	case TULIP_CHIP_MX98713:
		/*
		 * The Macronix MX98713 has an MII and GPIO, but no
		 * internal Nway block.  This chip is basically a
		 * perfect 21140A clone, with the exception of the
		 * a magic register frobbing in order to make the
		 * interface function.
		 */
		if (tlp_isv_srom_enaddr(sc, enaddr)) {
			sc->sc_mediasw = &tlp_2114x_isv_mediasw;
			break;
		}
		/* FALLTHROUGH */

	case TULIP_CHIP_82C115:
		/*
		 * Yippee!  The Lite-On 82C115 is a clone of
		 * the MX98725 (the data sheet even says `MXIC'
		 * on it)!  Imagine that, a clone of a clone.
		 *
		 * The differences are really minimal:
		 *
		 *	- Wake-On-LAN support
		 *	- 128-bit multicast hash table, rather than
		 *	  the standard 512-bit hash table
		 */
		/* FALLTHROUGH */

	case TULIP_CHIP_MX98713A:
	case TULIP_CHIP_MX98715A:
	case TULIP_CHIP_MX98715AEC_X:
	case TULIP_CHIP_MX98725:
		/*
		 * The MX98713A has an MII as well as an internal Nway block,
		 * but no GPIO.  The MX98715 and MX98725 have an internal
		 * Nway block only.
		 *
		 * The internal Nway block, unlike the Lite-On PNIC's, does
		 * just that - performs Nway.  Once autonegotiation completes,
		 * we must program the GPR media information into the chip.
		 *
		 * The byte offset of the Ethernet address is stored at
		 * offset 0x70.
		 */
		memcpy(enaddr, &sc->sc_srom[sc->sc_srom[0x70]], ETHER_ADDR_LEN);
		sc->sc_mediasw = &tlp_pmac_mediasw;
		break;

	case TULIP_CHIP_WB89C840F:
		/*
		 * Winbond 89C840F's Ethernet address is the first
		 * 6 bytes of its EEPROM.
		 */
		memcpy(enaddr, sc->sc_srom, ETHER_ADDR_LEN);

		/*
		 * Winbond 89C840F has an MII attached to the SIO.
		 */
		sc->sc_mediasw = &tlp_sio_mii_mediasw;
		break;

	case TULIP_CHIP_AL981:
		/*
		 * The ADMtek AL981's Ethernet address is located
		 * at offset 8 of its EEPROM.
		 */
		memcpy(enaddr, &sc->sc_srom[8], ETHER_ADDR_LEN);

		/*
		 * ADMtek AL981 has a built-in PHY accessed through
		 * special registers.
		 */
		sc->sc_mediasw = &tlp_al981_mediasw;
		break;

	case TULIP_CHIP_AN983:
	case TULIP_CHIP_AN985:
		/*
		 * The ADMtek AN985's Ethernet address is located
		 * at offset 8 of its EEPROM.
		 */
		memcpy(enaddr, &sc->sc_srom[8], ETHER_ADDR_LEN);

		/*
		 * The ADMtek AN985 can be configured in Single-Chip
		 * mode or MAC-only mode.  Single-Chip uses the built-in
		 * PHY, MAC-only has an external PHY (usually HomePNA).
		 * The selection is based on an EEPROM setting, and both
		 * PHYs are accessed via MII attached to SIO.
		 *
		 * The AN985 "ghosts" the internal PHY onto all
		 * MII addresses, so we have to use a media init
		 * routine that limits the search.
		 * XXX How does this work with MAC-only mode?
		 */
		sc->sc_mediasw = &tlp_an985_mediasw;
		break;

	case TULIP_CHIP_DM9102:
	case TULIP_CHIP_DM9102A:
		/*
		 * Some boards with the Davicom chip have an ISV
		 * SROM (mostly DM9102A boards -- trying to describe
		 * the HomePNA PHY, probably) although the data in
		 * them is generally wrong.  Check for ISV format
		 * and grab the Ethernet address that way, and if
		 * that fails, fall back on grabbing it from an
		 * observed offset of 20 (which is where it would
		 * be in an ISV SROM anyhow, tho ISV can cope with
		 * multi-port boards).
		 */
		if (!tlp_isv_srom_enaddr(sc, enaddr)) {

			prop_data_t eaddrprop;

			eaddrprop = prop_dictionary_get(
				device_properties(self), "mac-address");

			if (eaddrprop != NULL
			    && prop_data_size(eaddrprop) == ETHER_ADDR_LEN)
				memcpy(enaddr,
				    prop_data_data_nocopy(eaddrprop),
				    ETHER_ADDR_LEN);
			else
				memcpy(enaddr, &sc->sc_srom[20],
				    ETHER_ADDR_LEN);
		}

		/*
		 * Davicom chips all have an internal MII interface
		 * and a built-in PHY.  DM9102A also has a an external
		 * MII interface, usually with a HomePNA PHY attached
		 * to it.
		 */
		sc->sc_mediasw = &tlp_dm9102_mediasw;
		break;

	case TULIP_CHIP_AX88140:
	case TULIP_CHIP_AX88141:
		/*
		 * ASIX AX88140/AX88141 Ethernet Address is located at offset
		 * 20 of the SROM.
		 */
		memcpy(enaddr, &sc->sc_srom[20], ETHER_ADDR_LEN);

		/*
		 * ASIX AX88140A/AX88141 chip can have a built-in PHY or
		 * an external MII interface.
		 */
		sc->sc_mediasw = &tlp_asix_mediasw;
		break;

	case TULIP_CHIP_RS7112:
		/*
		 * RS7112 Ethernet Address is located of offset 0x19a
		 * of the SROM
		 */
		memcpy(enaddr, &sc->sc_srom[0x19a], ETHER_ADDR_LEN);

		/* RS7112 chip has a PHY at MII address 1 */
		sc->sc_mediasw = &tlp_rs7112_mediasw;
		break;

	default:
 cant_cope:
		aprint_error_dev(self, "sorry, unable to handle your board\n");
		goto fail;
	}

	/*
	 * Handle shared interrupts.
	 */
	if (psc->sc_flags & TULIP_PCI_SHAREDINTR) {
		if (psc->sc_master)
			psc->sc_flags |= TULIP_PCI_SLAVEINTR;
		else {
			tlp_pci_check_slaved(psc, TULIP_PCI_SHAREDINTR,
			    TULIP_PCI_SLAVEINTR);
			if (psc->sc_master == NULL)
				psc->sc_master = psc;
		}
		LIST_INSERT_HEAD(&psc->sc_master->sc_intrslaves,
		    psc, sc_intrq);
	}

	if (psc->sc_flags & TULIP_PCI_SLAVEINTR) {
		aprint_normal_dev(self, "sharing interrupt with %s\n",
		    device_xname(psc->sc_master->sc_tulip.sc_dev));
	} else {
		/*
		 * Map and establish our interrupt.
		 */
		if (pci_intr_map(pa, &ih)) {
			aprint_error_dev(self, "unable to map interrupt\n");
			goto fail;
		}
		intrstr = pci_intr_string(pc, ih);
		psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET,
		    (psc->sc_flags & TULIP_PCI_SHAREDINTR) ?
		    tlp_pci_shared_intr : tlp_intr, sc);
		if (psc->sc_ih == NULL) {
			aprint_error_dev(self, "unable to establish interrupt");
			if (intrstr != NULL)
				aprint_error(" at %s", intrstr);
			aprint_error("\n");
			goto fail;
		}
		aprint_normal_dev(self, "interrupting at %s\n",
		    intrstr);
	}

	/*
	 * Finish off the attach.
	 */
	error = tlp_attach(sc, enaddr);
	if (error)
		goto fail;
	return;

fail:
	if (psc->sc_ih != NULL) {
		pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
		psc->sc_ih = NULL;
	}

	if (ioh_valid)
		bus_space_unmap(iot, ioh, iosize);
	if (memh_valid)
		bus_space_unmap(memt, memh, memsize);
	psc->sc_mapsize = 0;
	return;
}
static void
atw_pci_attach(device_t parent, device_t self, void *aux)
{
	struct atw_pci_softc *psc = device_private(self);
	struct atw_softc *sc = &psc->psc_atw;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	const char *intrstr = NULL;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	int ioh_valid, memh_valid;
	const struct atw_pci_product *app;
	int error;

	sc->sc_dev = self;

	psc->psc_pc = pa->pa_pc;
	psc->psc_pcitag = pa->pa_tag;

	app = atw_pci_lookup(pa);
	if (app == NULL) {
		printf("\n");
		panic("atw_pci_attach: impossible");
	}

	/*
	 * Get revision info, and set some chip-specific variables.
	 */
	sc->sc_rev = PCI_REVISION(pa->pa_class);
	printf(": %s, revision %d.%d\n", app->app_product_name,
	    (sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf);

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

	/*
	 * Map the device.
	 */
	ioh_valid = (pci_mapreg_map(pa, ATW_PCI_IOBA,
	    PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, NULL, NULL) == 0);
	memh_valid = (pci_mapreg_map(pa, ATW_PCI_MMBA,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &memt, &memh, NULL, NULL) == 0);

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

	sc->sc_dmat = pa->pa_dmat;

	/*
	 * Make sure bus mastering is enabled.
	 */
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);

	/*
	 * Get the cacheline size.
	 */
	sc->sc_cacheline = PCI_CACHELINE(pci_conf_read(pc, pa->pa_tag,
	    PCI_BHLC_REG));

	/*
	 * Get PCI data moving command info.
	 */
	if (pa->pa_flags & PCI_FLAGS_MRL_OKAY) /* read line */
		sc->sc_flags |= ATWF_MRL;
	if (pa->pa_flags & PCI_FLAGS_MRM_OKAY) /* read multiple */
		sc->sc_flags |= ATWF_MRM;
	if (pa->pa_flags & PCI_FLAGS_MWI_OKAY) /* write invalidate */
		sc->sc_flags |= ATWF_MWI;

	/*
	 * Map and establish our interrupt.
	 */
	if (pci_intr_map(pa, &psc->psc_ih)) {
		aprint_error_dev(self, "unable to map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, psc->psc_ih);
	psc->psc_intrcookie = pci_intr_establish(pc, psc->psc_ih, IPL_NET,
	    atw_intr, sc);
	if (psc->psc_intrcookie == NULL) {
		aprint_error_dev(self, "unable to establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}

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

	/*
	 * Bus-independent attach.
	 */
	atw_attach(sc);

	if (pmf_device_register1(sc->sc_dev, atw_pci_suspend, atw_pci_resume,
	    atw_shutdown))
		pmf_class_network_register(sc->sc_dev, &sc->sc_if);
	else
		aprint_error_dev(sc->sc_dev,
		    "couldn't establish power handler\n");

	/*
	 * Power down the socket.
	 */
	pmf_device_suspend(sc->sc_dev, &sc->sc_qual);
}