1139749Simp/*-
266550Snyan * Copyright (c) 1995, David Greenman
366550Snyan * All rights reserved.
466550Snyan *
566550Snyan * Redistribution and use in source and binary forms, with or without
666550Snyan * modification, are permitted provided that the following conditions
766550Snyan * are met:
866550Snyan * 1. Redistributions of source code must retain the above copyright
966550Snyan *    notice unmodified, this list of conditions, and the following
1066550Snyan *    disclaimer.
1166550Snyan * 2. Redistributions in binary form must reproduce the above copyright
1266550Snyan *    notice, this list of conditions and the following disclaimer in the
1366550Snyan *    documentation and/or other materials provided with the distribution.
1466550Snyan *
1566550Snyan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1666550Snyan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1766550Snyan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1866550Snyan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1966550Snyan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2066550Snyan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2166550Snyan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2266550Snyan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2366550Snyan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2466550Snyan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2566550Snyan * SUCH DAMAGE.
2666550Snyan *
2766550Snyan */
2866550Snyan
29119419Sobrien#include <sys/cdefs.h>
30119419Sobrien__FBSDID("$FreeBSD$");
31119419Sobrien
3266550Snyan/*
3366550Snyan *	National Semiconductor  DP8393X SONIC Driver
3466550Snyan *
35150460Simp *	This is the PC Card attachment on FreeBSD
3666550Snyan *		written by Motomichi Matsuzaki <mzaki@e-mail.ne.jp> and
3766550Snyan *			   Hiroshi Yamashita <bluemoon@msj.biglobe.ne.jp>
3866550Snyan */
3966550Snyan
4066550Snyan#include <sys/param.h>
4166550Snyan#include <sys/systm.h>
4266550Snyan#include <sys/socket.h>
4366550Snyan#include <sys/kernel.h>
4466550Snyan
4566550Snyan#include <sys/module.h>
4666550Snyan#include <sys/bus.h>
4766550Snyan#include <machine/bus.h>
4866550Snyan
49181298Sjhb#include <net/ethernet.h>
5066550Snyan#include <net/if.h>
5166550Snyan#include <net/if_arp.h>
5266550Snyan#include <net/if_media.h>
5366550Snyan
5466550Snyan#include <dev/snc/dp83932var.h>
5566550Snyan#include <dev/snc/if_sncvar.h>
5666550Snyan#include <dev/snc/if_sncreg.h>
5766550Snyan
58181393Simp#include <dev/pccard/pccardvar.h>
59181393Simp#include <dev/pccard/pccard_cis.h>
60181393Simp#include "pccarddevs.h"
61181393Simp
62181393Simpstatic const struct pccard_product snc_pccard_products[] = {
63181393Simp	PCMCIA_CARD(NEC, PC9801N_J02),
64181393Simp	PCMCIA_CARD(NEC, PC9801N_J02R),
65181393Simp	{ NULL }
66181393Simp};
67181393Simp
6866550Snyan/*
69150460Simp *      PC Card (PCMCIA) specific code.
7066550Snyan */
7166550Snyanstatic int	snc_pccard_probe(device_t);
7266550Snyanstatic int	snc_pccard_attach(device_t);
7366550Snyanstatic int	snc_pccard_detach(device_t);
7466550Snyan
7566550Snyan
7666550Snyanstatic device_method_t snc_pccard_methods[] = {
7766550Snyan	/* Device interface */
7866550Snyan	DEVMETHOD(device_probe,		snc_pccard_probe),
7966550Snyan	DEVMETHOD(device_attach,	snc_pccard_attach),
8066550Snyan	DEVMETHOD(device_detach,	snc_pccard_detach),
8166550Snyan
8266550Snyan	{ 0, 0 }
8366550Snyan};
8466550Snyan
8566550Snyanstatic driver_t snc_pccard_driver = {
8666550Snyan	"snc",
8766550Snyan	snc_pccard_methods,
8866550Snyan	sizeof(struct snc_softc)
8966550Snyan};
9066550Snyan
91113506SmdoddDRIVER_MODULE(snc, pccard, snc_pccard_driver, snc_devclass, 0, 0);
92113506SmdoddMODULE_DEPEND(snc, ether, 1, 1, 1);
9366550Snyan
9466550Snyan/*
95140529Simp *      snc_pccard_detach - detach this instance from the device.
9666550Snyan */
9766550Snyanstatic int
9866550Snyansnc_pccard_detach(device_t dev)
9966550Snyan{
10066550Snyan	struct snc_softc *sc = device_get_softc(dev);
101147318Sbrooks	struct ifnet *ifp = sc->sc_ifp;
10266550Snyan
10366550Snyan	if (sc->gone) {
10466550Snyan		device_printf(dev, "already unloaded\n");
10566550Snyan		return (0);
10666550Snyan	}
107181298Sjhb	SNC_LOCK(sc);
10866550Snyan	sncshutdown(sc);
109181298Sjhb	SNC_UNLOCK(sc);
110181298Sjhb	callout_drain(&sc->sc_timer);
111181298Sjhb	ether_ifdetach(ifp);
11266550Snyan	sc->gone = 1;
11366550Snyan	bus_teardown_intr(dev, sc->irq, sc->irq_handle);
11466550Snyan	snc_release_resources(dev);
115181298Sjhb	mtx_destroy(&sc->sc_lock);
11666550Snyan	return (0);
11766550Snyan}
11866550Snyan
11966550Snyan/*
120140529Simp * Probe the pccard.
12166550Snyan */
12266550Snyanstatic int
12366550Snyansnc_pccard_probe(device_t dev)
12466550Snyan{
125181393Simp	const struct pccard_product *pp;
12666550Snyan
127181393Simp	if ((pp = pccard_product_lookup(dev, snc_pccard_products,
128181393Simp	    sizeof(snc_pccard_products[0]), NULL)) == NULL)
129181393Simp		return (EIO);
130181393Simp	if (pp->pp_name != NULL)
131181393Simp		device_set_desc(dev, pp->pp_name);
132181393Simp	return (0);
13366550Snyan}
13466550Snyan
13566550Snyanstatic int
13666550Snyansnc_pccard_attach(device_t dev)
13766550Snyan{
13866550Snyan	struct snc_softc *sc = device_get_softc(dev);
139181393Simp	int error;
14066550Snyan
141181393Simp	/*
142181393Simp	 * Not sure that this belongs here or in snc_pccard_attach
143181393Simp	 */
144181393Simp	if ((error = snc_alloc_port(dev, 0)) != 0)
145181393Simp		goto err;
146181393Simp	if ((error = snc_alloc_memory(dev, 0)) != 0)
147181393Simp		goto err;
148181393Simp	if ((error = snc_alloc_irq(dev, 0, 0)) != 0)
149181393Simp		goto err;
150181393Simp	if ((error = snc_probe(dev, SNEC_TYPE_PNP)) != 0)
151181393Simp		goto err;
15266550Snyan	/* This interface is always enabled. */
15366550Snyan	sc->sc_enabled = 1;
15466550Snyan	/* pccard_get_ether(dev, ether_addr); */
155181393Simp	if ((error = snc_attach(dev)) != 0)
156181393Simp		goto err;
157181393Simp	return 0;
158181393Simperr:;
159181393Simp	snc_release_resources(dev);
160181393Simp	return error;
16166550Snyan}
162