1 /* $NetBSD: if_lc_isa.c,v 1.32 2009/05/12 08:44:19 cegger Exp $ */
4 * Copyright (c) 1994, 1995, 1997 Matt Thomas <matt@3am-software.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * DEC EtherWORKS 3 Ethernet Controllers
30 * Written by Matt Thomas
32 * This driver supports the LEMAC (DE203, DE204, and DE205) cards.
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: if_lc_isa.c,v 1.32 2009/05/12 08:44:19 cegger Exp $");
38 #include <sys/param.h>
39 #include <sys/systm.h>
41 #include <sys/socket.h>
42 #include <sys/ioctl.h>
43 #include <sys/errno.h>
44 #include <sys/syslog.h>
45 #include <sys/select.h>
46 #include <sys/device.h>
47 #include <sys/queue.h>
50 #include <net/if_dl.h>
51 #include <net/if_ether.h>
52 #include <net/if_media.h>
58 #include <dev/ic/lemacreg.h>
59 #include <dev/ic/lemacvar.h>
61 #include <dev/isa/isavar.h>
63 extern struct cfdriver lc_cd
;
65 static int lemac_isa_find(lemac_softc_t
*, struct isa_attach_args
*, int);
66 static int lemac_isa_probe(device_t
, cfdata_t
, void *);
67 static void lemac_isa_attach(device_t
, device_t
, void *);
69 CFATTACH_DECL(lc_isa
, sizeof(lemac_softc_t
),
70 lemac_isa_probe
, lemac_isa_attach
, NULL
, NULL
);
73 lemac_isa_find(lemac_softc_t
*sc
, struct isa_attach_args
*ia
, int attach
)
81 if (ia
->ia_niomem
< 1)
86 if (ISA_DIRECT_CONFIG(ia
))
90 * Disallow wildcarded i/o addresses.
92 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
96 * Make sure this is a valid LEMAC address.
98 if (ia
->ia_io
[0].ir_addr
& (LEMAC_IOSIZE
- 1))
101 sc
->sc_iot
= ia
->ia_iot
;
103 if (bus_space_map(sc
->sc_iot
, ia
->ia_io
[0].ir_addr
, LEMAC_IOSIZE
, 0,
106 printf(": can't map i/o space\n");
111 * Read the Ethernet address from the EEPROM.
112 * It must start with one of the DEC OUIs and pass the
113 * DEC ethernet checksum test.
115 if (lemac_port_check(sc
->sc_iot
, sc
->sc_ioh
) == 0)
119 * Get information about memory space and attempt to map it.
121 lemac_info_get(sc
->sc_iot
, sc
->sc_ioh
, &maddr
, &msiz
, &irq
);
123 if (ia
->ia_iomem
[0].ir_addr
!= ISA_UNKNOWN_IOMEM
&&
124 ia
->ia_iomem
[0].ir_addr
!= maddr
)
129 printf(": memory configuration is invalid\n");
133 sc
->sc_memt
= ia
->ia_memt
;
134 if (bus_space_map(ia
->ia_memt
, maddr
, msiz
, 0, &sc
->sc_memh
)) {
135 printf(": can't map mem space\n");
141 * Double-check IRQ configuration.
143 if (ia
->ia_irq
[0].ir_irq
!= ISA_UNKNOWN_IRQ
&&
144 ia
->ia_irq
[0].ir_irq
!= irq
)
145 printf("%s: overriding IRQ %d to %d\n", device_xname(&sc
->sc_dv
),
146 ia
->ia_irq
[0].ir_irq
, irq
);
149 sc
->sc_ats
= shutdownhook_establish(lemac_shutdown
, sc
);
150 if (sc
->sc_ats
== NULL
) {
152 aprint_error_dev(&sc
->sc_dv
, "warning: can't establish shutdown hook\n");
157 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, irq
, IST_EDGE
,
158 IPL_NET
, lemac_intr
, sc
);
162 * I guess we've found one.
167 ia
->ia_io
[0].ir_size
= LEMAC_IOSIZE
;
170 ia
->ia_iomem
[0].ir_addr
= maddr
;
171 ia
->ia_iomem
[0].ir_size
= msiz
;
174 ia
->ia_irq
[0].ir_irq
= irq
;
179 if (rv
== 0 || !attach
)
180 bus_space_unmap(sc
->sc_iot
, sc
->sc_ioh
, LEMAC_IOSIZE
);
185 lemac_isa_probe(device_t parent
, cfdata_t match
, void *aux
)
187 struct isa_attach_args
*ia
= aux
;
190 snprintf(sc
.sc_dv
.dv_xname
, sizeof(sc
.sc_dv
.dv_xname
), "%s%d",
191 lc_cd
.cd_name
, cf
->cf_unit
);
193 return lemac_isa_find(&sc
, ia
, 0);
197 lemac_isa_attach(device_t parent
, device_t self
, void *aux
)
199 lemac_softc_t
*sc
= (void *)self
;
200 struct isa_attach_args
*ia
= aux
;
202 (void) lemac_isa_find(sc
, ia
, 1);