if_ed_isa.c revision 298307
1254721Semaste/*-
2254721Semaste * Copyright (c) 1995, David Greenman
3254721Semaste * All rights reserved.
4254721Semaste *
5254721Semaste * Redistribution and use in source and binary forms, with or without
6254721Semaste * modification, are permitted provided that the following conditions
7254721Semaste * are met:
8254721Semaste * 1. Redistributions of source code must retain the above copyright
9254721Semaste *    notice unmodified, this list of conditions, and the following
10254721Semaste *    disclaimer.
11254721Semaste * 2. Redistributions in binary form must reproduce the above copyright
12254721Semaste *    notice, this list of conditions and the following disclaimer in the
13254721Semaste *    documentation and/or other materials provided with the distribution.
14254721Semaste *
15254721Semaste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16254721Semaste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17254721Semaste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18254721Semaste * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19254721Semaste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20254721Semaste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21254721Semaste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22254721Semaste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23254721Semaste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24254721Semaste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25254721Semaste * SUCH DAMAGE.
26254721Semaste *
27254721Semaste */
28254721Semaste
29254721Semaste#include <sys/cdefs.h>
30296417Sdim__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed_isa.c 298307 2016-04-19 23:37:24Z pfg $");
31254721Semaste
32296417Sdim#include "opt_ed.h"
33296417Sdim
34254721Semaste#include <sys/param.h>
35296417Sdim#include <sys/systm.h>
36296417Sdim#include <sys/socket.h>
37254721Semaste#include <sys/kernel.h>
38254721Semaste
39254721Semaste#include <sys/module.h>
40254721Semaste#include <sys/bus.h>
41296417Sdim#include <machine/bus.h>
42296417Sdim
43254721Semaste#include <net/ethernet.h>
44296417Sdim#include <net/if.h>
45296417Sdim#include <net/if_arp.h>
46276479Sdim#include <net/if_media.h>
47296417Sdim#include <net/if_mib.h>
48296417Sdim
49254721Semaste#include <isa/isavar.h>
50296417Sdim
51296417Sdim#include <dev/ed/if_edvar.h>
52254721Semaste#include <dev/ed/if_edreg.h>
53296417Sdim
54296417Sdimstatic int ed_isa_probe(device_t);
55254721Semastestatic int ed_isa_attach(device_t);
56254721Semaste
57296417Sdimstatic struct isa_pnp_id ed_ids[] = {
58296417Sdim	{ 0x0131d805,	NULL },		/* ANX3101 */
59254721Semaste	{ 0x4cf48906,	NULL },		/* ATIf44c */
60296417Sdim	{ 0x01200507,	NULL },		/* AXE2001 */
61296417Sdim	{ 0x0115180e,	NULL },		/* CPX1501 */
62254721Semaste	{ 0x0090252a,	NULL },		/* JQE9000 */
63254721Semaste	{ 0x0020832e,	NULL },		/* KTC2000 */
64254721Semaste	{ 0xd680d041,	NULL },		/* PNP80d6 */
65254721Semaste	{ 0x6081d041,	NULL },		/* PNP8160 */
66254721Semaste	{ 0x19808c4a,	NULL },		/* RTL8019 */
67254721Semaste	{ 0x1684a34d,	NULL },		/* SMC8416 */
68254721Semaste	{ 0x1980635e,	NULL },		/* WSC8019 */
69254721Semaste	{ 0,		NULL }
70254721Semaste};
71254721Semaste
72254721Semastestatic int
73254721Semasteed_isa_probe_Novell(device_t dev)
74254721Semaste{
75254721Semaste	struct ed_softc *sc = device_get_softc(dev);
76296417Sdim	int flags = device_get_flags(dev);
77296417Sdim	int err;
78254721Semaste
79254721Semaste	err = ed_probe_Novell(dev, 0, flags);
80254721Semaste	if (err)
81296417Sdim		return err;
82296417Sdim	ed_Novell_read_mac(sc);
83254721Semaste	/*
84296417Sdim	 * Final sanity check for Gateway Ethernet cards before
85296417Sdim	 * believing that they really are Gateway AT.
86254721Semaste	 * XXX I think this is stale.
87254721Semaste	 */
88254721Semaste	if ((ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) &&
89254721Semaste	    (sc->enaddr[2] == 0x86)) {
90296417Sdim		sc->type_str = "Gateway AT";
91296417Sdim	}
92254721Semaste
93296417Sdim	return (0);
94296417Sdim}
95254721Semaste
96296417Sdimstatic int
97296417Sdimed_isa_probe(device_t dev)
98254721Semaste{
99296417Sdim	struct ed_softc *sc = device_get_softc(dev);
100296417Sdim	int flags = device_get_flags(dev);
101254721Semaste	int error = 0;
102296417Sdim
103296417Sdim	/* Check isapnp ids */
104254721Semaste	error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids);
105296417Sdim
106296417Sdim	/* If the card had a PnP ID that didn't match any we know about */
107254721Semaste	if (error == ENXIO)
108254721Semaste		goto end;
109296417Sdim
110296417Sdim	/* If we had some other problem. */
111254721Semaste	if (!(error == 0 || error == ENOENT))
112296417Sdim		goto end;
113296417Sdim
114254721Semaste	/* Heuristic probes */
115254721Semaste
116254721Semaste	error = ed_probe_WD80x3(dev, 0, flags);
117254721Semaste	if (error == 0)
118254721Semaste		goto end;
119254721Semaste	ed_release_resources(dev);
120254721Semaste
121296417Sdim	error = ed_probe_RTL80x9(dev, 0, flags);
122254721Semaste	if (error == 0) {
123254721Semaste		ed_Novell_read_mac(sc);
124254721Semaste		goto end;
125254721Semaste	}
126254721Semaste	ed_release_resources(dev);
127254721Semaste
128254721Semaste#ifdef ED_3C503
129254721Semaste	error = ed_probe_3Com(dev, 0, flags);
130254721Semaste	if (error == 0)
131254721Semaste		goto end;
132254721Semaste	ed_release_resources(dev);
133296417Sdim#endif
134296417Sdim
135254721Semaste#ifdef ED_SIC
136254721Semaste	error = ed_probe_SIC(dev, 0, flags);
137254721Semaste	if (error == 0)
138296417Sdim		goto end;
139296417Sdim	ed_release_resources(dev);
140254721Semaste#endif
141296417Sdim	error = ed_isa_probe_Novell(dev);
142296417Sdim	if (error == 0)
143254721Semaste		goto end;
144254721Semaste	ed_release_resources(dev);
145254721Semaste
146254721Semaste#ifdef ED_HPP
147296417Sdim	error = ed_probe_HP_pclanp(dev, 0, flags);
148296417Sdim	if (error == 0)
149254721Semaste		goto end;
150296417Sdim	ed_release_resources(dev);
151296417Sdim#endif
152254721Semasteend:
153296417Sdim	if (error == 0)
154296417Sdim		error = ed_alloc_irq(dev, 0, 0);
155254721Semaste
156296417Sdim	ed_release_resources(dev);
157296417Sdim	return (error);
158254721Semaste}
159296417Sdim
160296417Sdimstatic int
161254721Semasteed_isa_attach(device_t dev)
162296417Sdim{
163296417Sdim	struct ed_softc *sc = device_get_softc(dev);
164296417Sdim	int error;
165254721Semaste
166254721Semaste	if (sc->port_used > 0)
167296417Sdim		ed_alloc_port(dev, 0, sc->port_used);
168296417Sdim	if (sc->mem_used)
169254721Semaste		ed_alloc_memory(dev, 0, sc->mem_used);
170296417Sdim	ed_alloc_irq(dev, 0, 0);
171296417Sdim
172254721Semaste	if (sc->sc_media_ioctl == NULL)
173254721Semaste		ed_gen_ifmedia_init(sc);
174254721Semaste	error = ed_attach(dev);
175254721Semaste	if (error) {
176254721Semaste		ed_release_resources(dev);
177296417Sdim		return (error);
178254721Semaste	}
179254721Semaste	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
180254721Semaste	    NULL, edintr, sc, &sc->irq_handle);
181254721Semaste	if (error)
182254721Semaste		ed_release_resources(dev);
183254721Semaste	return (error);
184296417Sdim}
185254721Semaste
186254721Semastestatic device_method_t ed_isa_methods[] = {
187254721Semaste	/* Device interface */
188254721Semaste	DEVMETHOD(device_probe,		ed_isa_probe),
189254721Semaste	DEVMETHOD(device_attach,	ed_isa_attach),
190254721Semaste	DEVMETHOD(device_detach,	ed_detach),
191254721Semaste
192254721Semaste	{ 0, 0 }
193254721Semaste};
194254721Semaste
195254721Semastestatic driver_t ed_isa_driver = {
196296417Sdim	"ed",
197	ed_isa_methods,
198	sizeof(struct ed_softc)
199};
200
201DRIVER_MODULE(ed, isa, ed_isa_driver, ed_devclass, 0, 0);
202MODULE_DEPEND(ed, isa, 1, 1, 1);
203MODULE_DEPEND(ed, ether, 1, 1, 1);
204MODULE_PNP_INFO("E:pnpid;", isa, ed, ed_ids, sizeof(ed_ids[0]),
205    nitems(ed_ids) - 1);
206
207