summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-08-29 21:12:56 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-08-29 21:12:56 +0000
commit6bed2bd2bebb3bc2213623236ef2874fc2fb9141 (patch)
tree317a2723279afbc8469e3f5a171eb42572736f36
parentbd1d57e1e7d32857956f0496b2bc2f60338a7a0a (diff)
Split the ti(4) driver into mostly bus-agnostic code and PCI-specific
attachment. Add SBus support to the bus-agnostic code.
-rw-r--r--sys/conf/files5
-rw-r--r--sys/dev/ic/ti.c (renamed from sys/dev/pci/if_ti.c)177
-rw-r--r--sys/dev/ic/tireg.h (renamed from sys/dev/pci/if_tireg.h)3
-rw-r--r--sys/dev/ic/tivar.h (renamed from sys/dev/pci/if_tivar.h)5
-rw-r--r--sys/dev/pci/files.pci7
-rw-r--r--sys/dev/pci/if_ti_pci.c181
6 files changed, 255 insertions, 123 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 2278bd9c91b..7b5b5741fd6 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.472 2009/08/25 16:16:34 jsg Exp $
+# $OpenBSD: files,v 1.473 2009/08/29 21:12:55 kettenis Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -301,6 +301,9 @@ file dev/ic/i82596.c ie & (ie_pci | ie_eisa | ie_gsc)
device gem: ether, ifnet, ifmedia, mii
file dev/ic/gem.c gem
+device ti: ether, ifnet, ifmedia, mii, firmload
+file dev/ic/ti.c ti
+
# 8250/16[45]50-based "com" ports
device com: tty
file dev/ic/com.c com & (com | com_cardbus | com_gsc |
diff --git a/sys/dev/pci/if_ti.c b/sys/dev/ic/ti.c
index 187dd8b25ef..996071fb1c0 100644
--- a/sys/dev/pci/if_ti.c
+++ b/sys/dev/ic/ti.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ti.c,v 1.98 2009/08/13 14:24:47 jasper Exp $ */
+/* $OpenBSD: ti.c,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -107,19 +107,11 @@
#include <net/if_vlan_var.h>
#endif
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcidevs.h>
-
-#include <dev/pci/if_tireg.h>
-#include <dev/pci/if_tivar.h>
-
-int ti_probe(struct device *, void *, void *);
-void ti_attach(struct device *, struct device *, void *);
+#include <machine/bus.h>
-struct cfattach ti_ca = {
- sizeof(struct ti_softc), ti_probe, ti_attach
-};
+#include <dev/ic/tireg.h>
+#include <dev/ic/tivar.h>
+#include <dev/pci/pcireg.h>
struct cfdriver ti_cd = {
NULL, "ti", DV_IFNET
@@ -177,18 +169,10 @@ int ti_init_tx_ring(struct ti_softc *);
int ti_64bitslot_war(struct ti_softc *);
int ti_chipinit(struct ti_softc *);
+void ti_chipinit_pci(struct ti_softc *);
+void ti_chipinit_sbus(struct ti_softc *);
int ti_gibinit(struct ti_softc *);
-const struct pci_matchid ti_devices[] = {
- { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620 },
- { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620T },
- { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENIC },
- { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENICT },
- { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C985 },
- { PCI_VENDOR_SGI, PCI_PRODUCT_SGI_TIGON },
- { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PN9000SX }
-};
-
/*
* Send an instruction or address to the EEPROM, check for ACK.
*/
@@ -1261,8 +1245,6 @@ ti_64bitslot_war(struct ti_softc *sc)
int
ti_chipinit(struct ti_softc *sc)
{
- u_int32_t cacheline;
- u_int32_t pci_writemax = 0;
u_int32_t chip_rev;
/* Initialize link to down state. */
@@ -1305,8 +1287,32 @@ ti_chipinit(struct ti_softc *sc)
TI_SETBIT(sc, TI_MISC_CONF, TI_MCR_SRAM_SYNCHRONOUS);
}
+ if (sc->ti_sbus)
+ ti_chipinit_sbus(sc);
+ else
+ ti_chipinit_pci(sc);
+
+ /* Recommended settings from Tigon manual. */
+ CSR_WRITE_4(sc, TI_GCR_DMA_WRITECFG, TI_DMA_STATE_THRESH_8W);
+ CSR_WRITE_4(sc, TI_GCR_DMA_READCFG, TI_DMA_STATE_THRESH_8W);
+
+ if (ti_64bitslot_war(sc)) {
+ printf("%s: bios thinks we're in a 64 bit slot, "
+ "but we aren't", sc->sc_dv.dv_xname);
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+void
+ti_chipinit_pci(struct ti_softc *sc)
+{
+ u_int32_t cacheline;
+ u_int32_t pci_writemax = 0;
+
/* Set up the PCI state register. */
- CSR_WRITE_4(sc, TI_PCI_STATE, TI_PCI_READ_CMD|TI_PCI_WRITE_CMD);
+ CSR_WRITE_4(sc, TI_PCI_STATE, TI_PCI_READ_CMD | TI_PCI_WRITE_CMD);
if (sc->ti_hwrev == TI_HWREV_TIGON_II)
TI_SETBIT(sc, TI_PCI_STATE, TI_PCISTATE_USE_MEM_RD_MULT);
@@ -1360,18 +1366,22 @@ ti_chipinit(struct ti_softc *sc)
CSR_WRITE_4(sc, TI_GCR_OPMODE, TI_DMA_SWAP_OPTIONS |
TI_OPMODE_WARN_ENB | TI_OPMODE_FATAL_ENB |
TI_OPMODE_DONT_FRAG_JUMBO);
+}
- /* Recommended settings from Tigon manual. */
- CSR_WRITE_4(sc, TI_GCR_DMA_WRITECFG, TI_DMA_STATE_THRESH_8W);
- CSR_WRITE_4(sc, TI_GCR_DMA_READCFG, TI_DMA_STATE_THRESH_8W);
-
- if (ti_64bitslot_war(sc)) {
- printf("%s: bios thinks we're in a 64 bit slot, "
- "but we aren't", sc->sc_dv.dv_xname);
- return (EINVAL);
- }
+void
+ti_chipinit_sbus(struct ti_softc *sc)
+{
+ /* Set up the PCI state register. */
+ CSR_WRITE_4(sc, TI_PCI_STATE, TI_PCI_READ_CMD | TI_PCI_WRITE_CMD |
+ TI_PCISTATE_NO_SWAP_READ_DMA | TI_PCISTATE_NO_SWAP_WRITE_DMA |
+ TI_PCI_WRITEMAX_64 | TI_PCI_READMAX_64 |
+ TI_PCISTATE_PROVIDE_LEN);
- return (0);
+ /* Configure DMA variables. */
+ CSR_WRITE_4(sc, TI_GCR_OPMODE, TI_OPMODE_WORDSWAP_BD |
+ TI_OPMODE_1_DMA_ACTIVE | TI_OPMODE_SBUS |
+ TI_OPMODE_WARN_ENB | TI_OPMODE_FATAL_ENB |
+ TI_OPMODE_DONT_FRAG_JUMBO);
}
/*
@@ -1539,60 +1549,17 @@ ti_gibinit(struct ti_softc *sc)
return (0);
}
-/*
- * Probe for a Tigon chip. Check the PCI vendor and device IDs
- * against our list and return its name if we find a match.
- */
int
-ti_probe(struct device *parent, void *match, void *aux)
+ti_attach(struct ti_softc *sc)
{
- return (pci_matchbyid((struct pci_attach_args *)aux, ti_devices,
- sizeof(ti_devices)/sizeof(ti_devices[0])));
-}
-
-void
-ti_attach(struct device *parent, struct device *self, void *aux)
-{
- struct ti_softc *sc = (struct ti_softc *)self;
- struct pci_attach_args *pa = aux;
- pci_chipset_tag_t pc = pa->pa_pc;
- pci_intr_handle_t ih;
- const char *intrstr = NULL;
- bus_size_t size;
bus_dma_segment_t seg;
int rseg;
struct ifnet *ifp;
caddr_t kva;
- /*
- * Map control/status registers.
- */
-
- if (pci_mapreg_map(pa, TI_PCI_LOMEM,
- PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
- &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) {
- printf(": can't map mem space\n");
- return;
- }
-
- if (pci_intr_map(pa, &ih)) {
- printf(": couldn't map interrupt\n");
- goto fail_1;
- }
- intrstr = pci_intr_string(pc, ih);
- sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc,
- self->dv_xname);
- if (sc->ti_intrhand == NULL) {
- printf(": couldn't establish interrupt");
- if (intrstr != NULL)
- printf(" at %s", intrstr);
- printf("\n");
- goto fail_1;
- }
-
if (ti_chipinit(sc)) {
printf("%s: chip initialization failed\n", sc->sc_dv.dv_xname);
- goto fail_2;
+ return (1);
}
/* Zero out the NIC's on-board SRAM. */
@@ -1601,7 +1568,7 @@ ti_attach(struct device *parent, struct device *self, void *aux)
/* Init again -- zeroing memory may have clobbered some registers. */
if (ti_chipinit(sc)) {
printf("%s: chip initialization failed\n", sc->sc_dv.dv_xname);
- goto fail_2;
+ return (1);
}
/*
@@ -1615,38 +1582,35 @@ ti_attach(struct device *parent, struct device *self, void *aux)
TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) {
printf("%s: failed to read station address\n",
sc->sc_dv.dv_xname);
- free(sc, M_DEVBUF);
- goto fail_2;
+ return (1);
}
/*
* A Tigon chip was detected. Inform the world.
*/
- printf(": %s, address %s\n", intrstr,
- ether_sprintf(sc->arpcom.ac_enaddr));
+ printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
/* Allocate the general information block and ring buffers. */
- sc->sc_dmatag = pa->pa_dmat;
if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct ti_ring_data),
PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
printf("%s: can't alloc rx buffers\n", sc->sc_dv.dv_xname);
- goto fail_2;
+ return (1);
}
if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
sizeof(struct ti_ring_data), &kva, BUS_DMA_NOWAIT)) {
printf("%s: can't map dma buffers (%d bytes)\n",
sc->sc_dv.dv_xname, sizeof(struct ti_ring_data));
- goto fail_3;
+ goto fail_1;
}
if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct ti_ring_data), 1,
sizeof(struct ti_ring_data), 0, BUS_DMA_NOWAIT,
&sc->ti_ring_map)) {
printf("%s: can't create dma map\n", sc->sc_dv.dv_xname);
- goto fail_4;
+ goto fail_2;
}
if (bus_dmamap_load(sc->sc_dmatag, sc->ti_ring_map, kva,
sizeof(struct ti_ring_data), NULL, BUS_DMA_NOWAIT)) {
- goto fail_5;
+ goto fail_3;
}
sc->ti_rdata = (struct ti_ring_data *)kva;
bzero(sc->ti_rdata, sizeof(struct ti_ring_data));
@@ -1655,24 +1619,9 @@ ti_attach(struct device *parent, struct device *self, void *aux)
if (ti_alloc_jumbo_mem(sc)) {
printf("%s: jumbo buffer allocation failed\n",
sc->sc_dv.dv_xname);
- goto fail_5;
+ goto fail_3;
}
- /*
- * We really need a better way to tell a 1000baseTX card
- * from a 1000baseSX one, since in theory there could be
- * OEMed 1000baseTX cards from lame vendors who aren't
- * clever enough to change the PCI ID. For the moment
- * though, the AceNIC is the only copper card available.
- */
- if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT)
- sc->ti_copper = 1;
- /* Ok, it's not the only copper card available */
- if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T)
- sc->ti_copper = 1;
-
/* Set default tuneable values. */
sc->ti_stat_ticks = 2 * TI_TICKS_PER_SEC;
sc->ti_rx_coal_ticks = TI_TICKS_PER_SEC / 5000;
@@ -1735,23 +1684,19 @@ ti_attach(struct device *parent, struct device *self, void *aux)
ether_ifattach(ifp);
shutdownhook_establish(ti_shutdown, sc);
- return;
+ return (0);
-fail_5:
+fail_3:
bus_dmamap_destroy(sc->sc_dmatag, sc->ti_ring_map);
-fail_4:
+fail_2:
bus_dmamem_unmap(sc->sc_dmatag, kva,
sizeof(struct ti_ring_data));
-fail_3:
+fail_1:
bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
-fail_2:
- pci_intr_disestablish(pc, sc->ti_intrhand);
-
-fail_1:
- bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size);
+ return (1);
}
/*
diff --git a/sys/dev/pci/if_tireg.h b/sys/dev/ic/tireg.h
index c76b1a99fb0..1b2a8ff1a28 100644
--- a/sys/dev/pci/if_tireg.h
+++ b/sys/dev/ic/tireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tireg.h,v 1.25 2006/08/16 02:37:00 brad Exp $ */
+/* $OpenBSD: tireg.h,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -1113,6 +1113,7 @@ struct ti_softc {
void * ti_intrhand;
struct ifmedia ifmedia; /* media info */
u_int8_t ti_hwrev; /* Tigon rev (1 or 2) */
+ u_int8_t ti_sbus; /* SBus card */
u_int8_t ti_copper; /* 1000baseTX card */
u_int8_t ti_linkstat; /* Link state */
bus_dma_tag_t sc_dmatag;
diff --git a/sys/dev/pci/if_tivar.h b/sys/dev/ic/tivar.h
index 5c3c37e943e..492c0a63f23 100644
--- a/sys/dev/pci/if_tivar.h
+++ b/sys/dev/ic/tivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tivar.h,v 1.2 2004/11/22 21:23:57 deraadt Exp $ */
+/* $OpenBSD: tivar.h,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */
/*
* Copyright (c) 2004 Theo de Raadt <deraadt@openbsd.org>
@@ -41,3 +41,6 @@ struct tigon_firmware {
u_char data[1];
};
+
+int ti_attach(struct ti_softc *sc);
+int ti_intr(void *);
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 0e25bdbee70..930e01243cd 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.262 2009/08/08 09:31:13 kevlo Exp $
+# $OpenBSD: files.pci,v 1.263 2009/08/29 21:12:55 kettenis Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -400,9 +400,8 @@ attach epic at pci with epic_pci
file dev/pci/if_epic_pci.c epic_pci
# Alteon Tigon I & II
-device ti: ether, ifnet, ifmedia, firmload
-attach ti at pci
-file dev/pci/if_ti.c ti
+attach ti at pci with ti_pci
+file dev/pci/if_ti_pci.c ti_pci
# NE2000-compatible PCI Ethernet cards
attach ne at pci with ne_pci: rtl80x9
diff --git a/sys/dev/pci/if_ti_pci.c b/sys/dev/pci/if_ti_pci.c
new file mode 100644
index 00000000000..12260f686a3
--- /dev/null
+++ b/sys/dev/pci/if_ti_pci.c
@@ -0,0 +1,181 @@
+/* $OpenBSD: if_ti_pci.c,v 1.1 2009/08/29 21:12:55 kettenis Exp $ */
+
+/*
+ * Copyright (c) 1997, 1998, 1999
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/pci/if_ti.c,v 1.25 2000/01/18 00:26:29 wpaul Exp $
+ */
+
+/*
+ * Alteon Networks Tigon PCI gigabit ethernet driver for OpenBSD.
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Electrical Engineering Department
+ * Columbia University, New York City
+ */
+
+/*
+ * The Alteon Networks Tigon chip contains an embedded R4000 CPU,
+ * gigabit MAC, dual DMA channels and a PCI interface unit. NICs
+ * using the Tigon may have anywhere from 512K to 2MB of SRAM. The
+ * Tigon supports hardware IP, TCP and UCP checksumming, multicast
+ * filtering and jumbo (9014 byte) frames. The hardware is largely
+ * controlled by firmware, which must be loaded into the NIC during
+ * initialization.
+ *
+ * The Tigon 2 contains 2 R4000 CPUs and requires a newer firmware
+ * revision, which supports new features such as extended commands,
+ * extended jumbo receive ring desciptors and a mini receive ring.
+ *
+ * Alteon Networks is to be commended for releasing such a vast amount
+ * of development material for the Tigon NIC without requiring an NDA
+ * (although they really should have done it a long time ago). With
+ * any luck, the other vendors will finally wise up and follow Alteon's
+ * stellar example.
+ *
+ * The following people deserve special thanks:
+ * - Terry Murphy of 3Com, for providing a 3c985 Tigon 1 board
+ * for testing
+ * - Raymond Lee of Netgear, for providing a pair of Netgear
+ * GA620 Tigon 2 boards for testing
+ * - Ulf Zimmermann, for bringing the GA260 to my attention and
+ * convincing me to write this driver.
+ * - Andrew Gallatin for providing FreeBSD/Alpha support.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#endif
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/ic/tireg.h>
+#include <dev/ic/tivar.h>
+
+int ti_pci_match(struct device *, void *, void *);
+void ti_pci_attach(struct device *, struct device *, void *);
+
+struct cfattach ti_pci_ca = {
+ sizeof(struct ti_softc), ti_pci_match, ti_pci_attach
+};
+
+const struct pci_matchid ti_devices[] = {
+ { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620 },
+ { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620T },
+ { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENIC },
+ { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENICT },
+ { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C985 },
+ { PCI_VENDOR_SGI, PCI_PRODUCT_SGI_TIGON },
+ { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PN9000SX }
+};
+
+int
+ti_pci_match(struct device *parent, void *match, void *aux)
+{
+ return (pci_matchbyid(aux, ti_devices, nitems(ti_devices)));
+}
+
+void
+ti_pci_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct ti_softc *sc = (struct ti_softc *)self;
+ struct pci_attach_args *pa = aux;
+ pci_chipset_tag_t pc = pa->pa_pc;
+ pci_intr_handle_t ih;
+ const char *intrstr = NULL;
+ bus_size_t size;
+
+ /*
+ * Map control/status registers.
+ */
+ if (pci_mapreg_map(pa, TI_PCI_LOMEM,
+ PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
+ &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) {
+ printf(": can't map registers\n");
+ return;
+ }
+
+ sc->sc_dmatag = pa->pa_dmat;
+
+ if (pci_intr_map(pa, &ih)) {
+ printf(": can't map interrupt\n");
+ goto unmap;
+ }
+ intrstr = pci_intr_string(pc, ih);
+ sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc,
+ self->dv_xname);
+ if (sc->ti_intrhand == NULL) {
+ printf(": can't establish interrupt");
+ if (intrstr != NULL)
+ printf(" at %s", intrstr);
+ printf("\n");
+ goto unmap;
+ }
+ printf(": %s", intrstr);
+
+ /*
+ * We really need a better way to tell a 1000baseTX card
+ * from a 1000baseSX one, since in theory there could be
+ * OEMed 1000baseTX cards from lame vendors who aren't
+ * clever enough to change the PCI ID. For the moment
+ * though, the AceNIC is the only copper card available.
+ */
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT)
+ sc->ti_copper = 1;
+ /* Ok, it's not the only copper card available */
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T)
+ sc->ti_copper = 1;
+
+ if (ti_attach(sc) == 0)
+ return;
+
+ pci_intr_disestablish(pc, sc->ti_intrhand);
+
+unmap:
+ bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size);
+}