Home | History | Annotate | Line # | Download | only in pci
if_ne_pci.c revision 1.14.10.3
      1  1.14.10.3    bouyer /*	$NetBSD: if_ne_pci.c,v 1.14.10.3 2001/03/12 13:31:07 bouyer Exp $	*/
      2        1.2   thorpej 
      3        1.2   thorpej /*-
      4        1.5   thorpej  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
      5        1.2   thorpej  * All rights reserved.
      6        1.2   thorpej  *
      7        1.2   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8        1.2   thorpej  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9        1.2   thorpej  * NASA Ames Research Center.
     10        1.2   thorpej  *
     11        1.2   thorpej  * Redistribution and use in source and binary forms, with or without
     12        1.2   thorpej  * modification, are permitted provided that the following conditions
     13        1.2   thorpej  * are met:
     14        1.2   thorpej  * 1. Redistributions of source code must retain the above copyright
     15        1.2   thorpej  *    notice, this list of conditions and the following disclaimer.
     16        1.2   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     17        1.2   thorpej  *    notice, this list of conditions and the following disclaimer in the
     18        1.2   thorpej  *    documentation and/or other materials provided with the distribution.
     19        1.2   thorpej  * 3. All advertising materials mentioning features or use of this software
     20        1.2   thorpej  *    must display the following acknowledgement:
     21        1.2   thorpej  *	This product includes software developed by the NetBSD
     22        1.2   thorpej  *	Foundation, Inc. and its contributors.
     23        1.2   thorpej  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24        1.2   thorpej  *    contributors may be used to endorse or promote products derived
     25        1.2   thorpej  *    from this software without specific prior written permission.
     26        1.2   thorpej  *
     27        1.2   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28        1.2   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29        1.2   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30        1.2   thorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31        1.2   thorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32        1.2   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33        1.2   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34        1.2   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35        1.2   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36        1.2   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37        1.2   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     38        1.2   thorpej  */
     39        1.2   thorpej 
     40  1.14.10.1    bouyer #include "opt_ipkdb.h"
     41        1.8  jonathan #include "opt_inet.h"
     42        1.2   thorpej #include "bpfilter.h"
     43        1.2   thorpej 
     44        1.2   thorpej #include <sys/param.h>
     45        1.2   thorpej #include <sys/systm.h>
     46        1.2   thorpej #include <sys/mbuf.h>
     47        1.2   thorpej #include <sys/syslog.h>
     48        1.2   thorpej #include <sys/socket.h>
     49        1.2   thorpej #include <sys/device.h>
     50        1.2   thorpej 
     51        1.2   thorpej #include <net/if.h>
     52        1.2   thorpej #include <net/if_ether.h>
     53        1.2   thorpej #include <net/if_media.h>
     54        1.2   thorpej 
     55        1.2   thorpej #ifdef INET
     56        1.2   thorpej #include <netinet/in.h>
     57        1.2   thorpej #include <netinet/if_inarp.h>
     58        1.2   thorpej #endif
     59        1.2   thorpej 
     60        1.2   thorpej #include <machine/bus.h>
     61        1.2   thorpej #include <machine/intr.h>
     62        1.2   thorpej 
     63  1.14.10.1    bouyer #ifdef IPKDB_NE_PCI
     64  1.14.10.1    bouyer #include <ipkdb/ipkdb.h>
     65  1.14.10.1    bouyer #endif
     66  1.14.10.1    bouyer 
     67        1.2   thorpej #include <dev/pci/pcireg.h>
     68        1.2   thorpej #include <dev/pci/pcivar.h>
     69        1.2   thorpej #include <dev/pci/pcidevs.h>
     70        1.2   thorpej 
     71        1.2   thorpej #include <dev/ic/dp8390reg.h>
     72        1.2   thorpej #include <dev/ic/dp8390var.h>
     73        1.2   thorpej 
     74        1.2   thorpej #include <dev/ic/ne2000reg.h>
     75        1.2   thorpej #include <dev/ic/ne2000var.h>
     76       1.10   thorpej 
     77       1.12   thorpej #include <dev/ic/rtl80x9reg.h>
     78       1.13   thorpej #include <dev/ic/rtl80x9var.h>
     79        1.2   thorpej 
     80        1.2   thorpej struct ne_pci_softc {
     81        1.2   thorpej 	struct ne2000_softc sc_ne2000;		/* real "ne2000" softc */
     82        1.2   thorpej 
     83        1.2   thorpej 	/* PCI-specific goo */
     84        1.2   thorpej 	void *sc_ih;				/* interrupt handle */
     85        1.2   thorpej };
     86        1.2   thorpej 
     87        1.2   thorpej int ne_pci_match __P((struct device *, struct cfdata *, void *));
     88        1.2   thorpej void ne_pci_attach __P((struct device *, struct device *, void *));
     89        1.2   thorpej 
     90        1.2   thorpej struct cfattach ne_pci_ca = {
     91        1.2   thorpej 	sizeof(struct ne_pci_softc), ne_pci_match, ne_pci_attach
     92        1.2   thorpej };
     93        1.2   thorpej 
     94  1.14.10.1    bouyer #ifdef IPKDB_NE_PCI
     95  1.14.10.1    bouyer static struct ne_pci_softc ipkdb_softc;
     96  1.14.10.1    bouyer static pci_chipset_tag_t ipkdb_pc;
     97  1.14.10.1    bouyer static pcitag_t ipkdb_tag;
     98  1.14.10.1    bouyer static struct ipkdb_if *ne_kip;
     99  1.14.10.1    bouyer 
    100  1.14.10.1    bouyer int ne_pci_ipkdb_attach __P((struct ipkdb_if *, bus_space_tag_t,       /* XXX */
    101  1.14.10.1    bouyer 			pci_chipset_tag_t, int, int));
    102  1.14.10.1    bouyer 
    103  1.14.10.1    bouyer static int ne_pci_isipkdb __P((pci_chipset_tag_t, pcitag_t));
    104  1.14.10.1    bouyer #endif
    105  1.14.10.1    bouyer 
    106        1.9   thorpej const struct ne_pci_product {
    107        1.9   thorpej 	pci_vendor_id_t npp_vendor;
    108        1.9   thorpej 	pci_product_id_t npp_product;
    109       1.11   thorpej 	int (*npp_mediachange) __P((struct dp8390_softc *));
    110       1.11   thorpej 	void (*npp_mediastatus) __P((struct dp8390_softc *,
    111       1.11   thorpej 	    struct ifmediareq *));
    112       1.11   thorpej 	void (*npp_init_card) __P((struct dp8390_softc *));
    113  1.14.10.3    bouyer 	void (*npp_media_init) __P((struct dp8390_softc *));
    114        1.9   thorpej 	const char *npp_name;
    115        1.9   thorpej } ne_pci_products[] = {
    116       1.11   thorpej 	{ PCI_VENDOR_REALTEK,		PCI_PRODUCT_REALTEK_RT8029,
    117       1.13   thorpej 	  rtl80x9_mediachange,		rtl80x9_mediastatus,
    118  1.14.10.3    bouyer 	  rtl80x9_init_card,		rtl80x9_media_init,
    119       1.11   thorpej 	  "RealTek 8029" },
    120       1.11   thorpej 
    121       1.11   thorpej 	{ PCI_VENDOR_WINBOND,		PCI_PRODUCT_WINBOND_W89C940F,
    122       1.11   thorpej 	  NULL,				NULL,
    123       1.11   thorpej 	  NULL,				NULL,
    124        1.9   thorpej 	  "Winbond 89C940F" },
    125        1.9   thorpej 
    126  1.14.10.1    bouyer 	{ PCI_VENDOR_WINBOND,		PCI_PRODUCT_WINBOND_W89C940F_1,
    127  1.14.10.1    bouyer 	  NULL,				NULL,
    128  1.14.10.1    bouyer 	  NULL,				NULL,
    129  1.14.10.1    bouyer 	  "Winbond 89C940F" },
    130  1.14.10.1    bouyer 
    131       1.11   thorpej 	{ PCI_VENDOR_VIATECH,		PCI_PRODUCT_VIATECH_VT86C926,
    132       1.11   thorpej 	  NULL,				NULL,
    133       1.11   thorpej 	  NULL,				NULL,
    134        1.9   thorpej 	  "VIA Technologies VT86C926" },
    135        1.9   thorpej 
    136       1.11   thorpej 	{ PCI_VENDOR_SURECOM,		PCI_PRODUCT_SURECOM_NE34,
    137       1.11   thorpej 	  NULL,				NULL,
    138       1.11   thorpej 	  NULL,				NULL,
    139        1.9   thorpej 	  "Surecom NE-34" },
    140        1.9   thorpej 
    141       1.11   thorpej 	{ PCI_VENDOR_NETVIN,		PCI_PRODUCT_NETVIN_5000,
    142       1.11   thorpej 	  NULL,				NULL,
    143       1.11   thorpej 	  NULL,				NULL,
    144        1.9   thorpej 	  "NetVin 5000" },
    145        1.5   thorpej 
    146        1.6   thorpej 	/* XXX The following entries need sanity checking in pcidevs */
    147       1.11   thorpej 	{ PCI_VENDOR_COMPEX,		PCI_PRODUCT_COMPEX_NE2KETHER,
    148       1.11   thorpej 	  NULL,				NULL,
    149       1.11   thorpej 	  NULL,				NULL,
    150        1.9   thorpej 	  "Compex" },
    151        1.9   thorpej 
    152       1.11   thorpej 	{ PCI_VENDOR_PROLAN,		PCI_PRODUCT_PROLAN_NE2KETHER,
    153       1.11   thorpej 	  NULL,				NULL,
    154       1.11   thorpej 	  NULL,				NULL,
    155        1.9   thorpej 	  "ProLAN" },
    156        1.9   thorpej 
    157       1.11   thorpej 	{ PCI_VENDOR_KTI,		PCI_PRODUCT_KTI_NE2KETHER,
    158       1.11   thorpej 	  NULL,				NULL,
    159       1.11   thorpej 	  NULL,				NULL,
    160        1.9   thorpej 	  "KTI" },
    161        1.9   thorpej 
    162       1.11   thorpej 	{ 0,				0,
    163       1.11   thorpej 	  NULL,				NULL,
    164       1.11   thorpej 	  NULL,				NULL,
    165        1.9   thorpej 	  NULL },
    166        1.5   thorpej };
    167        1.5   thorpej 
    168       1.14   thorpej const struct ne_pci_product *ne_pci_lookup
    169       1.14   thorpej     __P((const struct pci_attach_args *));
    170        1.5   thorpej 
    171        1.9   thorpej const struct ne_pci_product *
    172        1.9   thorpej ne_pci_lookup(pa)
    173       1.14   thorpej 	const struct pci_attach_args *pa;
    174        1.5   thorpej {
    175        1.9   thorpej 	const struct ne_pci_product *npp;
    176        1.5   thorpej 
    177        1.9   thorpej 	for (npp = ne_pci_products; npp->npp_name != NULL; npp++) {
    178        1.9   thorpej 		if (PCI_VENDOR(pa->pa_id) == npp->npp_vendor &&
    179        1.9   thorpej 		    PCI_PRODUCT(pa->pa_id) == npp->npp_product)
    180        1.9   thorpej 			return (npp);
    181        1.5   thorpej 	}
    182        1.5   thorpej 	return (NULL);
    183        1.5   thorpej }
    184        1.5   thorpej 
    185        1.2   thorpej /*
    186        1.2   thorpej  * PCI constants.
    187        1.2   thorpej  * XXX These should be in a common file!
    188        1.2   thorpej  */
    189        1.2   thorpej #define PCI_CBIO	0x10		/* Configuration Base IO Address */
    190        1.2   thorpej 
    191        1.2   thorpej int
    192        1.2   thorpej ne_pci_match(parent, match, aux)
    193        1.2   thorpej 	struct device *parent;
    194        1.2   thorpej 	struct cfdata *match;
    195        1.2   thorpej 	void *aux;
    196        1.2   thorpej {
    197        1.2   thorpej 	struct pci_attach_args *pa = aux;
    198        1.2   thorpej 
    199        1.9   thorpej 	if (ne_pci_lookup(pa) != NULL)
    200        1.5   thorpej 		return (1);
    201        1.2   thorpej 
    202        1.2   thorpej 	return (0);
    203        1.2   thorpej }
    204        1.2   thorpej 
    205        1.2   thorpej void
    206        1.2   thorpej ne_pci_attach(parent, self, aux)
    207        1.2   thorpej 	struct device *parent, *self;
    208        1.2   thorpej 	void *aux;
    209        1.2   thorpej {
    210        1.2   thorpej 	struct ne_pci_softc *psc = (struct ne_pci_softc *)self;
    211        1.2   thorpej 	struct ne2000_softc *nsc = &psc->sc_ne2000;
    212        1.2   thorpej 	struct dp8390_softc *dsc = &nsc->sc_dp8390;
    213        1.2   thorpej 	struct pci_attach_args *pa = aux;
    214        1.2   thorpej 	pci_chipset_tag_t pc = pa->pa_pc;
    215        1.2   thorpej 	bus_space_tag_t nict;
    216        1.2   thorpej 	bus_space_handle_t nich;
    217        1.2   thorpej 	bus_space_tag_t asict;
    218        1.2   thorpej 	bus_space_handle_t asich;
    219        1.9   thorpej 	const char *intrstr;
    220        1.9   thorpej 	const struct ne_pci_product *npp;
    221        1.2   thorpej 	pci_intr_handle_t ih;
    222        1.2   thorpej 	pcireg_t csr;
    223        1.2   thorpej 
    224        1.9   thorpej 	npp = ne_pci_lookup(pa);
    225        1.9   thorpej 	if (npp == NULL) {
    226        1.9   thorpej 		printf("\n");
    227        1.9   thorpej 		panic("ne_pci_attach: impossible");
    228        1.2   thorpej 	}
    229        1.2   thorpej 
    230        1.9   thorpej 	printf(": %s Ethernet\n", npp->npp_name);
    231        1.2   thorpej 
    232  1.14.10.1    bouyer #ifdef IPKDB_NE_PCI
    233  1.14.10.1    bouyer 	if (ne_pci_isipkdb(pc, pa->pa_tag)) {
    234  1.14.10.1    bouyer 		nict = ipkdb_softc.sc_ne2000.sc_dp8390.sc_regt;
    235  1.14.10.1    bouyer 		nich = ipkdb_softc.sc_ne2000.sc_dp8390.sc_regh;
    236  1.14.10.1    bouyer 		ne_kip->port = nsc;
    237  1.14.10.1    bouyer 	} else
    238  1.14.10.1    bouyer #endif
    239        1.2   thorpej 	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
    240        1.2   thorpej 	    &nict, &nich, NULL, NULL)) {
    241        1.2   thorpej 		printf("%s: can't map i/o space\n", dsc->sc_dev.dv_xname);
    242        1.2   thorpej 		return;
    243        1.2   thorpej 	}
    244        1.2   thorpej 
    245        1.2   thorpej 	asict = nict;
    246        1.2   thorpej 	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
    247        1.2   thorpej 	    NE2000_ASIC_NPORTS, &asich)) {
    248        1.2   thorpej 		printf("%s: can't subregion i/o space\n", dsc->sc_dev.dv_xname);
    249        1.2   thorpej 		return;
    250        1.2   thorpej 	}
    251        1.2   thorpej 
    252        1.2   thorpej 	dsc->sc_regt = nict;
    253        1.2   thorpej 	dsc->sc_regh = nich;
    254        1.2   thorpej 
    255        1.2   thorpej 	nsc->sc_asict = asict;
    256        1.2   thorpej 	nsc->sc_asich = asich;
    257        1.2   thorpej 
    258        1.2   thorpej 	/* Enable the card. */
    259        1.2   thorpej 	csr = pci_conf_read(pc, pa->pa_tag,
    260        1.2   thorpej 	    PCI_COMMAND_STATUS_REG);
    261        1.2   thorpej 	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
    262        1.2   thorpej 	    csr | PCI_COMMAND_MASTER_ENABLE);
    263        1.2   thorpej 
    264        1.2   thorpej 	/* This interface is always enabled. */
    265        1.2   thorpej 	dsc->sc_enabled = 1;
    266        1.2   thorpej 
    267  1.14.10.3    bouyer 	dsc->sc_mediachange = npp->npp_mediachange;
    268  1.14.10.3    bouyer 	dsc->sc_mediastatus = npp->npp_mediastatus;
    269  1.14.10.3    bouyer 	dsc->sc_media_init = npp->npp_media_init;
    270       1.11   thorpej 	dsc->init_card = npp->npp_init_card;
    271       1.11   thorpej 
    272        1.2   thorpej 	/*
    273        1.2   thorpej 	 * Do generic NE2000 attach.  This will read the station address
    274        1.2   thorpej 	 * from the EEPROM.
    275        1.2   thorpej 	 */
    276  1.14.10.3    bouyer 	ne2000_attach(nsc, NULL);
    277        1.2   thorpej 
    278        1.2   thorpej 	/* Map and establish the interrupt. */
    279  1.14.10.2    bouyer 	if (pci_intr_map(pa, &ih)) {
    280        1.2   thorpej 		printf("%s: couldn't map interrupt\n", dsc->sc_dev.dv_xname);
    281        1.2   thorpej 		return;
    282        1.2   thorpej 	}
    283        1.2   thorpej 	intrstr = pci_intr_string(pc, ih);
    284        1.2   thorpej 	psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, dp8390_intr, dsc);
    285        1.2   thorpej 	if (psc->sc_ih == NULL) {
    286        1.2   thorpej 		printf("%s: couldn't establish interrupt",
    287        1.2   thorpej 		    dsc->sc_dev.dv_xname);
    288        1.2   thorpej 		if (intrstr != NULL)
    289        1.2   thorpej 			printf(" at %s", intrstr);
    290        1.2   thorpej 		printf("\n");
    291        1.2   thorpej 		return;
    292        1.2   thorpej 	}
    293        1.2   thorpej 	printf("%s: interrupting at %s\n", dsc->sc_dev.dv_xname, intrstr);
    294        1.2   thorpej }
    295  1.14.10.1    bouyer 
    296  1.14.10.1    bouyer #ifdef IPKDB_NE_PCI
    297  1.14.10.1    bouyer static int
    298  1.14.10.1    bouyer ne_pci_isipkdb(pc, tag)
    299  1.14.10.1    bouyer 	pci_chipset_tag_t pc;
    300  1.14.10.1    bouyer 	pcitag_t tag;
    301  1.14.10.1    bouyer {
    302  1.14.10.1    bouyer 	return !memcmp(&pc, &ipkdb_pc, sizeof pc)
    303  1.14.10.1    bouyer 		&& !memcmp(&tag, &ipkdb_tag, sizeof tag);
    304  1.14.10.1    bouyer }
    305  1.14.10.1    bouyer 
    306  1.14.10.1    bouyer int
    307  1.14.10.1    bouyer ne_pci_ipkdb_attach(kip, iot, pc, bus, dev)
    308  1.14.10.1    bouyer 	struct ipkdb_if *kip;
    309  1.14.10.1    bouyer 	bus_space_tag_t iot;
    310  1.14.10.1    bouyer 	pci_chipset_tag_t pc;
    311  1.14.10.1    bouyer 	int bus, dev;
    312  1.14.10.1    bouyer {
    313  1.14.10.1    bouyer 	struct pci_attach_args pa;
    314  1.14.10.1    bouyer 	bus_space_tag_t nict, asict;
    315  1.14.10.1    bouyer 	bus_space_handle_t nich, asich;
    316  1.14.10.1    bouyer 	u_int32_t csr;
    317  1.14.10.1    bouyer 
    318  1.14.10.1    bouyer 	pa.pa_iot = iot;
    319  1.14.10.1    bouyer 	pa.pa_pc = pc;
    320  1.14.10.1    bouyer 	pa.pa_device = dev;
    321  1.14.10.1    bouyer 	pa.pa_function = 0;
    322  1.14.10.1    bouyer 	pa.pa_flags = PCI_FLAGS_IO_ENABLED;
    323  1.14.10.1    bouyer 	pa.pa_tag = pci_make_tag(pc, bus, dev, /*func*/0);
    324  1.14.10.1    bouyer 	pa.pa_id = pci_conf_read(pc, pa.pa_tag, PCI_ID_REG);
    325  1.14.10.1    bouyer 	pa.pa_class = pci_conf_read(pc, pa.pa_tag, PCI_CLASS_REG);
    326  1.14.10.1    bouyer 	if (ne_pci_lookup(&pa) == NULL)
    327  1.14.10.1    bouyer 		return -1;
    328  1.14.10.1    bouyer 
    329  1.14.10.1    bouyer 	if (pci_mapreg_map(&pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
    330  1.14.10.1    bouyer 			&nict, &nich, NULL, NULL))
    331  1.14.10.1    bouyer 		return -1;
    332  1.14.10.1    bouyer 
    333  1.14.10.1    bouyer 	asict = nict;
    334  1.14.10.1    bouyer 	if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
    335  1.14.10.1    bouyer 				NE2000_ASIC_NPORTS, &asich)) {
    336  1.14.10.1    bouyer 		bus_space_unmap(nict, nich, NE2000_NPORTS);
    337  1.14.10.1    bouyer 		return -1;
    338  1.14.10.1    bouyer 	}
    339  1.14.10.1    bouyer 
    340  1.14.10.1    bouyer 	/* Enable card */
    341  1.14.10.1    bouyer 	csr = pci_conf_read(pc, pa.pa_tag, PCI_COMMAND_STATUS_REG);
    342  1.14.10.1    bouyer 	pci_conf_write(pc, pa.pa_tag, PCI_COMMAND_STATUS_REG,
    343  1.14.10.1    bouyer 			csr | PCI_COMMAND_MASTER_ENABLE);
    344  1.14.10.1    bouyer 
    345  1.14.10.1    bouyer 	ipkdb_softc.sc_ne2000.sc_dp8390.sc_regt = nict;
    346  1.14.10.1    bouyer 	ipkdb_softc.sc_ne2000.sc_dp8390.sc_regh = nich;
    347  1.14.10.1    bouyer 	ipkdb_softc.sc_ne2000.sc_asict = asict;
    348  1.14.10.1    bouyer 	ipkdb_softc.sc_ne2000.sc_asich = asich;
    349  1.14.10.1    bouyer 
    350  1.14.10.1    bouyer 	kip->port = &ipkdb_softc;
    351  1.14.10.1    bouyer 	ipkdb_pc = pc;
    352  1.14.10.1    bouyer 	ipkdb_tag = pa.pa_tag;
    353  1.14.10.1    bouyer 	ne_kip = kip;
    354  1.14.10.1    bouyer 
    355  1.14.10.1    bouyer 	if (ne2000_ipkdb_attach(kip) < 0) {
    356  1.14.10.1    bouyer 		bus_space_unmap(nict, nich, NE2000_NPORTS);
    357  1.14.10.1    bouyer 		return -1;
    358  1.14.10.1    bouyer 	}
    359  1.14.10.1    bouyer 
    360  1.14.10.1    bouyer 	return 0;
    361  1.14.10.1    bouyer }
    362  1.14.10.1    bouyer #endif
    363