if_ed_isa.c revision 142254
185587Sobrien/*-
285587Sobrien * Copyright (c) 1995, David Greenman
385587Sobrien * All rights reserved.
485587Sobrien *
585587Sobrien * Redistribution and use in source and binary forms, with or without
685587Sobrien * modification, are permitted provided that the following conditions
785587Sobrien * are met:
885587Sobrien * 1. Redistributions of source code must retain the above copyright
985587Sobrien *    notice unmodified, this list of conditions, and the following
1085587Sobrien *    disclaimer.
1185587Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1285587Sobrien *    notice, this list of conditions and the following disclaimer in the
1385587Sobrien *    documentation and/or other materials provided with the distribution.
1485587Sobrien *
1585587Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1685587Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1785587Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1885587Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1985587Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2085587Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2185587Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2285587Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2385587Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2485587Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2585587Sobrien * SUCH DAMAGE.
2685587Sobrien *
2785587Sobrien */
2885587Sobrien
2985587Sobrien#include <sys/cdefs.h>
3085587Sobrien__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed_isa.c 142254 2005-02-22 18:58:34Z imp $");
3185587Sobrien
3285587Sobrien#include "opt_ed.h"
3385587Sobrien
3485587Sobrien#include <sys/param.h>
3585587Sobrien#include <sys/systm.h>
36118194Sru#include <sys/socket.h>
3785587Sobrien#include <sys/kernel.h>
3885587Sobrien
3985587Sobrien#include <sys/module.h>
4085587Sobrien#include <sys/bus.h>
4185587Sobrien#include <machine/bus.h>
4285587Sobrien
4385587Sobrien#include <net/ethernet.h>
4485587Sobrien#include <net/if.h>
4585587Sobrien#include <net/if_arp.h>
4685587Sobrien#include <net/if_mib.h>
4785587Sobrien
4885587Sobrien#include <isa/isavar.h>
4985587Sobrien
5085587Sobrien#include <dev/ed/if_edvar.h>
5185587Sobrien
5285587Sobrienstatic int ed_isa_probe(device_t);
5385587Sobrienstatic int ed_isa_attach(device_t);
5485587Sobrien
5585587Sobrienstatic struct isa_pnp_id ed_ids[] = {
5685587Sobrien	{ 0x1684a34d,	NULL },		/* SMC8416 */
5785587Sobrien	{ 0xd680d041,	NULL },		/* PNP80d6 */
5885587Sobrien	{ 0x1980635e,	NULL },		/* WSC8019 */
5985587Sobrien	{ 0x0131d805,	NULL },		/* ANX3101 */
6085587Sobrien	{ 0x01200507,	NULL },		/* AXE2001 */
6185587Sobrien	{ 0x19808c4a,	NULL },		/* RTL8019 */
6285587Sobrien	{ 0x0090252a,	NULL },		/* JQE9000 */
6385587Sobrien	{ 0x0020832e,	NULL },		/* KTC2000 */
6485587Sobrien	{ 0x4cf48906,	NULL },		/* ATIf44c */
6585587Sobrien	{ 0,		NULL }
6685587Sobrien};
6785587Sobrien
6885587Sobrienstatic int
6985587Sobriened_isa_probe_Novell(device_t dev)
7085587Sobrien{
7185587Sobrien	struct ed_softc *sc = device_get_softc(dev);
7285587Sobrien	int flags = device_get_flags(dev);
7385587Sobrien	int err;
7485587Sobrien
7585587Sobrien	err = ed_probe_Novell(dev, 0, flags);
7685587Sobrien	if (err)
7785587Sobrien		return err;
78107806Sobrien	ed_Novell_read_mac(sc);
7985587Sobrien	/*
8085587Sobrien	 * Final sanity check for Gateway Ethernet cards before
8185587Sobrien	 * believing that they really are Gateway AT.
8285587Sobrien	 */
8385587Sobrien	if ((ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) &&
8485587Sobrien	    (sc->arpcom.ac_enaddr[2] == 0x86)) {
8585587Sobrien		sc->type_str = "Gateway AT";
8685587Sobrien	}
8785587Sobrien
8885587Sobrien	return (0);
8985587Sobrien}
9085587Sobrien
9185587Sobrienstatic int
9285587Sobriened_isa_probe(device_t dev)
9385587Sobrien{
9485587Sobrien	int flags = device_get_flags(dev);
9585587Sobrien	int error = 0;
9690902Sdes
9785587Sobrien	/* Check isapnp ids */
9885587Sobrien	error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids);
9985587Sobrien
10085587Sobrien	/* If the card had a PnP ID that didn't match any we know about */
10185587Sobrien	if (error == ENXIO)
10285587Sobrien		goto end;
10385587Sobrien
10485587Sobrien	/* If we had some other problem. */
10585587Sobrien	if (!(error == 0 || error == ENOENT))
10685587Sobrien		goto end;
10785587Sobrien
10885587Sobrien	/* Heuristic probes */
10985587Sobrien
11085587Sobrien	error = ed_probe_WD80x3(dev, 0, flags);
11185587Sobrien	if (error == 0)
11285587Sobrien		goto end;
11385587Sobrien	ed_release_resources(dev);
11485587Sobrien
11585587Sobrien#ifdef ED_3C503
11685587Sobrien	error = ed_probe_3Com(dev, 0, flags);
11785587Sobrien	if (error == 0)
11885587Sobrien		goto end;
11985587Sobrien	ed_release_resources(dev);
120107806Sobrien#endif
12185587Sobrien
12285587Sobrien#ifdef ED_SIC
12385587Sobrien	error = ed_probe_SIC(dev, 0, flags);
12485587Sobrien	if (error == 0)
12585587Sobrien		goto end;
12685587Sobrien	ed_release_resources(dev);
12785587Sobrien#endif
12885587Sobrien	error = ed_isa_probe_Novell(dev);
12985587Sobrien	if (error == 0)
13085587Sobrien		goto end;
13185587Sobrien	ed_release_resources(dev);
13285587Sobrien
13385587Sobrien#ifdef ED_HPP
13485587Sobrien	error = ed_probe_HP_pclanp(dev, 0, flags);
13585587Sobrien	if (error == 0)
13685587Sobrien		goto end;
13785587Sobrien	ed_release_resources(dev);
13885587Sobrien#endif
13985587Sobrienend:
14085587Sobrien	if (error == 0)
14185587Sobrien		error = ed_alloc_irq(dev, 0, 0);
14285587Sobrien
14385587Sobrien	ed_release_resources(dev);
14485587Sobrien	return (error);
14585587Sobrien}
14685587Sobrien
14785587Sobrienstatic int
14885587Sobriened_isa_attach(device_t dev)
14985587Sobrien{
15085587Sobrien	struct ed_softc *sc = device_get_softc(dev);
15185587Sobrien	int error;
15285587Sobrien
15385587Sobrien	if (sc->port_used > 0)
15485587Sobrien		ed_alloc_port(dev, sc->port_rid, sc->port_used);
15585587Sobrien	if (sc->mem_used)
15685587Sobrien		ed_alloc_memory(dev, sc->mem_rid, sc->mem_used);
15785587Sobrien
15885587Sobrien	ed_alloc_irq(dev, sc->irq_rid, 0);
15985587Sobrien
16085587Sobrien	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
16185587Sobrien			       edintr, sc, &sc->irq_handle);
16285587Sobrien	if (error) {
16385587Sobrien		ed_release_resources(dev);
16485587Sobrien		return (error);
16585587Sobrien	}
16685587Sobrien
16785587Sobrien	return ed_attach(dev);
16885587Sobrien}
16985587Sobrien
17085587Sobrienstatic device_method_t ed_isa_methods[] = {
17185587Sobrien	/* Device interface */
17285587Sobrien	DEVMETHOD(device_probe,		ed_isa_probe),
17385587Sobrien	DEVMETHOD(device_attach,	ed_isa_attach),
17485587Sobrien	DEVMETHOD(device_detach,	ed_detach),
17585587Sobrien
17685587Sobrien	{ 0, 0 }
17785587Sobrien};
17885587Sobrien
17985587Sobrienstatic driver_t ed_isa_driver = {
18085587Sobrien	"ed",
18185587Sobrien	ed_isa_methods,
18285587Sobrien	sizeof(struct ed_softc)
18385587Sobrien};
18485587Sobrien
18585587SobrienDRIVER_MODULE(ed, isa, ed_isa_driver, ed_devclass, 0, 0);
18685587SobrienMODULE_DEPEND(ed, isa, 1, 1, 1);
18785587SobrienMODULE_DEPEND(ed, ether, 1, 1, 1);
18885587Sobrien