scd_isa.c revision 119419
1106449Smdodd/*
2106449Smdodd */
3106449Smdodd
4119419Sobrien#include <sys/cdefs.h>
5119419Sobrien__FBSDID("$FreeBSD: head/sys/dev/scd/scd_isa.c 119419 2003-08-24 18:03:45Z obrien $");
6119419Sobrien
7106449Smdodd#include <sys/param.h>
8106449Smdodd#include <sys/systm.h>
9106449Smdodd#include <sys/kernel.h>
10106449Smdodd#include <sys/module.h>
11106449Smdodd#include <sys/conf.h>
12106449Smdodd#include <sys/fcntl.h>
13106449Smdodd#include <sys/bio.h>
14106449Smdodd#include <sys/cdio.h>
15106449Smdodd#include <sys/bus.h>
16106449Smdodd
17106449Smdodd#include <sys/mutex.h>
18106449Smdodd
19106449Smdodd#include <machine/bus_pio.h>
20106449Smdodd#include <machine/bus.h>
21106449Smdodd#include <machine/resource.h>
22106449Smdodd#include <sys/rman.h>
23106449Smdodd
24106449Smdodd#include <isa/isavar.h>
25106449Smdodd
26106449Smdodd#include <dev/scd/scdreg.h>
27106449Smdodd#include <dev/scd/scdvar.h>
28106449Smdodd
29106449Smdoddstatic int	scd_isa_probe	(device_t);
30106449Smdoddstatic int	scd_isa_attach	(device_t);
31106449Smdoddstatic int	scd_isa_detach	(device_t);
32106449Smdodd
33106449Smdoddstatic int	scd_alloc_resources	(device_t);
34106449Smdoddstatic void	scd_release_resources	(device_t);
35106449Smdodd
36106449Smdoddstatic int
37106449Smdoddscd_isa_probe (device_t dev)
38106449Smdodd{
39106449Smdodd	struct scd_softc *	sc;
40106449Smdodd	int			error;
41106449Smdodd
42106449Smdodd	/* No pnp support */
43106449Smdodd	if (isa_get_vendorid(dev))
44106449Smdodd		return (ENXIO);
45106449Smdodd
46106449Smdodd	/* IO port must be configured. */
47106449Smdodd	if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0)
48106449Smdodd		return (ENXIO);
49106449Smdodd
50106449Smdodd	sc = device_get_softc(dev);
51106449Smdodd	sc->dev = dev;
52106449Smdodd	sc->port_rid = 0;
53106449Smdodd	sc->port_type = SYS_RES_IOPORT;
54106449Smdodd	error = scd_alloc_resources(dev);
55106449Smdodd	if (error)
56106449Smdodd		goto fail;
57106449Smdodd
58106449Smdodd	error = scd_probe(sc);
59106449Smdodd	if (error) {
60106449Smdodd		device_printf(dev, "Probe failed.\n");
61106449Smdodd		goto fail;
62106449Smdodd	}
63106449Smdodd
64106449Smdodd	device_set_desc(dev, sc->data.name);
65106449Smdodd
66106449Smdoddfail:
67106449Smdodd	scd_release_resources(dev);
68106449Smdodd	return (error);
69106449Smdodd}
70106449Smdodd
71106449Smdoddstatic int
72106449Smdoddscd_isa_attach (device_t dev)
73106449Smdodd{
74106449Smdodd	struct scd_softc *	sc;
75106449Smdodd	int			error;
76106449Smdodd
77106449Smdodd	sc = device_get_softc(dev);
78106449Smdodd	error = 0;
79106449Smdodd
80106449Smdodd	sc->dev = dev;
81106449Smdodd	sc->port_rid = 0;
82106449Smdodd	sc->port_type = SYS_RES_IOPORT;
83106449Smdodd	error = scd_alloc_resources(dev);
84106449Smdodd	if (error)
85106449Smdodd		goto fail;
86106449Smdodd
87106449Smdodd	error = scd_probe(sc);
88106449Smdodd	if (error) {
89106449Smdodd		device_printf(dev, "Re-Probe failed.\n");
90106449Smdodd		goto fail;
91106449Smdodd	}
92106449Smdodd
93106449Smdodd	error = scd_attach(sc);
94106449Smdodd	if (error) {
95106449Smdodd		device_printf(dev, "Attach failed.\n");
96106449Smdodd		goto fail;
97106449Smdodd	}
98106449Smdodd
99106449Smdodd	return (0);
100106449Smdoddfail:
101106449Smdodd	scd_release_resources(dev);
102106449Smdodd	return (error);
103106449Smdodd}
104106449Smdodd
105106449Smdoddstatic int
106106449Smdoddscd_isa_detach (device_t dev)
107106449Smdodd{
108106449Smdodd	struct scd_softc *	sc;
109106449Smdodd	int			error;
110106449Smdodd
111106449Smdodd	sc = device_get_softc(dev);
112106449Smdodd	error = 0;
113106449Smdodd
114106449Smdodd	destroy_dev(sc->scd_dev_t);
115106449Smdodd
116106449Smdodd	scd_release_resources(dev);
117106449Smdodd
118106449Smdodd	return (error);
119106449Smdodd}
120106449Smdodd
121106449Smdoddstatic int
122106449Smdoddscd_alloc_resources (device_t dev)
123106449Smdodd{
124106449Smdodd	struct scd_softc *	sc;
125106449Smdodd	int			error;
126106449Smdodd
127106449Smdodd	sc = device_get_softc(dev);
128106449Smdodd	error = 0;
129106449Smdodd
130106449Smdodd	if (sc->port_type) {
131106449Smdodd		sc->port = bus_alloc_resource(dev, sc->port_type, &sc->port_rid,
132106449Smdodd				0, ~0, 1, RF_ACTIVE);
133106449Smdodd		if (sc->port == NULL) {
134106449Smdodd			device_printf(dev, "Unable to allocate PORT resource.\n");
135106449Smdodd			error = ENOMEM;
136106449Smdodd			goto bad;
137106449Smdodd		}
138106449Smdodd		sc->port_bst = rman_get_bustag(sc->port);
139106449Smdodd		sc->port_bsh = rman_get_bushandle(sc->port);
140106449Smdodd	}
141106449Smdodd
142106449Smdodd	mtx_init(&sc->mtx, device_get_nameunit(dev),
143106449Smdodd		"Interrupt lock", MTX_DEF | MTX_RECURSE);
144106449Smdodd
145106449Smdoddbad:
146106449Smdodd	return (error);
147106449Smdodd}
148106449Smdodd
149106449Smdoddvoid
150106449Smdoddscd_release_resources (device_t dev)
151106449Smdodd{
152106449Smdodd	struct scd_softc *	sc;
153106449Smdodd
154106449Smdodd	sc = device_get_softc(dev);
155106449Smdodd
156106449Smdodd	if (sc->port) {
157106449Smdodd		bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port);
158106449Smdodd		sc->port_bst = 0;
159106449Smdodd		sc->port_bsh = 0;
160106449Smdodd	}
161106449Smdodd
162106449Smdodd	if (mtx_initialized(&sc->mtx) != 0)
163106449Smdodd		mtx_destroy(&sc->mtx);
164106449Smdodd
165106449Smdodd	return;
166106449Smdodd}
167106449Smdodd
168106449Smdoddstatic device_method_t scd_isa_methods[] = {
169106449Smdodd	DEVMETHOD(device_probe,         scd_isa_probe),
170106449Smdodd	DEVMETHOD(device_attach,        scd_isa_attach),
171106449Smdodd	DEVMETHOD(device_detach,        scd_isa_detach),
172106449Smdodd
173106449Smdodd	{ 0, 0 }
174106449Smdodd};
175106449Smdodd
176106449Smdoddstatic driver_t scd_isa_driver = {
177106449Smdodd	"scd",
178106449Smdodd	scd_isa_methods,
179106449Smdodd	sizeof(struct scd_softc)
180106449Smdodd};
181106449Smdodd
182106449Smdoddstatic devclass_t	scd_devclass;
183106449Smdodd
184106449SmdoddDRIVER_MODULE(scd, isa, scd_isa_driver, scd_devclass, NULL, 0);
185