u_int32_t command;
skc_attach(struct device *parent, struct device *self, void *aux){	struct sk_softc *sc = (struct sk_softc *)self;	struct pci_attach_args *pa = aux;	struct skc_attach_args skca;	pci_chipset_tag_t pc = pa->pa_pc;	pci_intr_handle_t ih;	const char *intrstr = NULL;	bus_size_t size;	u_int8_t skrs;	u_int32_t command;	char *revstr = NULL;	DPRINTFN(2, ("begin skc_attach\n"));	/*	 * Handle power management nonsense.	 */	command = pci_conf_read(pc, pa->pa_tag, SK_PCI_CAPID) & 0x000000FF;	if (command == 0x01) {		command = pci_conf_read(pc, pa->pa_tag, SK_PCI_PWRMGMTCTRL);		if (command & SK_PSTATE_MASK) {			u_int32_t		iobase, membase, irq;			/* Save important PCI config data. */			iobase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOIO);			membase = pci_conf_read(pc, pa->pa_tag, SK_PCI_LOMEM);			irq = pci_conf_read(pc, pa->pa_tag, SK_PCI_INTLINE);			/* Reset the power state. */			printf("%s chip is in D%d power mode "			    "-- setting to D0\n", sc->sk_dev.dv_xname,			    command & SK_PSTATE_MASK);			command &= 0xFFFFFFFC;			pci_conf_write(pc, pa->pa_tag,			    SK_PCI_PWRMGMTCTRL, command);			/* Restore PCI config data. */			pci_conf_write(pc, pa->pa_tag, SK_PCI_LOIO, iobase);			pci_conf_write(pc, pa->pa_tag, SK_PCI_LOMEM, membase);			pci_conf_write(pc, pa->pa_tag, SK_PCI_INTLINE, irq);		}	}	/*	 * Map control/status registers.	 */#ifdef SK_USEIOSPACE	if (pci_mapreg_map(pa, SK_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0,	    &sc->sk_btag, &sc->sk_bhandle, NULL, &size, 0)) {		printf(": can't map i/o space\n");		return; 	}#else	if (pci_mapreg_map(pa, SK_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0,	    &sc->sk_btag, &sc->sk_bhandle, NULL, &size, 0)) { 		printf(": can't map mem space\n");		return; 	}#endif	sc->sc_dmatag = pa->pa_dmat;	sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);	sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);	/* bail out here if chip is not recognized */	if (sc->sk_type != SK_GENESIS && ! SK_YUKON_FAMILY(sc->sk_type)) {		printf("%s: unknown chip type\n",sc->sk_dev.dv_xname);		goto fail_1;	}	DPRINTFN(2, ("skc_attach: allocate interrupt\n"));	/* Allocate interrupt */	if (pci_intr_map(pa, &ih)) {		printf(": couldn't map interrupt\n");		goto fail_1;	}	intrstr = pci_intr_string(pc, ih);	sc->sk_intrhand = pci_intr_establish(pc, ih, IPL_NET, sk_intr, sc,	    self->dv_xname);	if (sc->sk_intrhand == NULL) {		printf(": couldn't establish interrupt");		if (intrstr != NULL)			printf(" at %s", intrstr);		goto fail_1;	}	printf(": %s\n", intrstr);	/* Reset the adapter. */	sk_reset(sc);	/* Read and save vital product data from EEPROM. */	sk_vpd_read(sc);	skrs = sk_win_read_1(sc, SK_EPROM0);	if (sc->sk_type == SK_GENESIS) {		/* Read and save RAM size and RAMbuffer offset */		switch(skrs) {		case SK_RAMSIZE_512K_64:			sc->sk_ramsize = 0x80000;			sc->sk_rboff = SK_RBOFF_0;			break;		case SK_RAMSIZE_1024K_64:			sc->sk_ramsize = 0x100000;			sc->sk_rboff = SK_RBOFF_80000;			break;		case SK_RAMSIZE_1024K_128:			sc->sk_ramsize = 0x100000;			sc->sk_rboff = SK_RBOFF_0;			break;		case SK_RAMSIZE_2048K_128:			sc->sk_ramsize = 0x200000;			sc->sk_rboff = SK_RBOFF_0;			break;		default:			printf("%s: unknown ram size: %d\n",			    sc->sk_dev.dv_xname, skrs);			goto fail_2;			break;		}	} else {		if (skrs == 0x00)			sc->sk_ramsize = 0x20000;		else			sc->sk_ramsize = skrs * (1<<12);		sc->sk_rboff = SK_RBOFF_0;	}	DPRINTFN(2, ("skc_attach: ramsize=%d (%dk), rboff=%d\n",		     sc->sk_ramsize, sc->sk_ramsize / 1024,		     sc->sk_rboff));	/* Read and save physical media type */	switch(sk_win_read_1(sc, SK_PMDTYPE)) {	case SK_PMD_1000BASESX:		sc->sk_pmd = IFM_1000_SX;		break;	case SK_PMD_1000BASELX:		sc->sk_pmd = IFM_1000_LX;		break;	case SK_PMD_1000BASECX:		sc->sk_pmd = IFM_1000_CX;		break;	case SK_PMD_1000BASETX:		sc->sk_pmd = IFM_1000_T;		break;	default:		printf("%s: unknown media type: 0x%x\n",		    sc->sk_dev.dv_xname, sk_win_read_1(sc, SK_PMDTYPE));		goto fail_2;	}	switch (sc->sk_type) {	case SK_GENESIS:		sc->sk_name = "SysKonnect GEnesis";		break;	case SK_YUKON:		sc->sk_name = "Marvell Yukon";		break;	case SK_YUKON_LITE:		sc->sk_name = "Marvell Yukon Lite";		break;	case SK_YUKON_LP:		sc->sk_name = "Marvell Yukon LP";		break;	case SK_YUKON_XL:		sc->sk_name = "Marvell Yukon-2 XL";		break;	case SK_YUKON_EC:		sc->sk_name = "Marvell Yukon-2 EC";		break;	case SK_YUKON_FE:		sc->sk_name = "Marvell Yukon-2 FE";		break;	default:		sc->sk_name = "Marvell Yukon (Unknown)";	}	/* Yukon Lite Rev A0 needs special test, from sk98lin driver */	if (sc->sk_type == SK_YUKON || sc->sk_type == SK_YUKON_LP) {		uint32_t flashaddr;		uint8_t testbyte;		flashaddr = sk_win_read_4(sc, SK_EP_ADDR);		/* test Flash-Address Register */		sk_win_write_1(sc, SK_EP_ADDR+3, 0xff);		testbyte = sk_win_read_1(sc, SK_EP_ADDR+3);		if (testbyte != 0) {			/* This is a Yukon Lite Rev A0 */			sc->sk_type = SK_YUKON_LITE;			sc->sk_rev = SK_YUKON_LITE_REV_A0;			/* restore Flash-Address Register */			sk_win_write_4(sc, SK_EP_ADDR, flashaddr);		}	}	if (sc->sk_type == SK_YUKON_LITE) {		switch (sc->sk_rev) {		case SK_YUKON_LITE_REV_A0:			revstr = "A0";			break;		case SK_YUKON_LITE_REV_A1:			revstr = "A1";			break;		case SK_YUKON_LITE_REV_A3:			revstr = "A3";			break;		default:			;		}	}	/* Announce the product name. */	printf("%s: %s", sc->sk_dev.dv_xname, sc->sk_name);	if (revstr != NULL)		printf(" rev. %s", revstr);	printf(" (0x%x)\n", sc->sk_rev);	skca.skc_port = SK_PORT_A;	(void)config_found(&sc->sk_dev, &skca, skcprint);	if (!(sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC)) {		skca.skc_port = SK_PORT_B;		(void)config_found(&sc->sk_dev, &skca, skcprint);	}	/* Turn on the 'driver is loaded' LED. */	CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);	return;fail_2:	pci_intr_disestablish(pc, sc->sk_intrhand);fail_1:	bus_space_unmap(sc->sk_btag, sc->sk_bhandle, size);}