1 /*
2  */
3 
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: stable/10/sys/dev/scd/scd_isa.c 146734 2005-05-29 04:42:30Z nyan $");
6 
7 #include <sys/param.h>
8 #include <sys/systm.h>
9 #include <sys/kernel.h>
10 #include <sys/module.h>
11 #include <sys/conf.h>
12 #include <sys/fcntl.h>
13 #include <sys/bio.h>
14 #include <sys/cdio.h>
15 #include <sys/bus.h>
16 
17 #include <sys/mutex.h>
18 
19 #include <machine/bus.h>
20 #include <machine/resource.h>
21 #include <sys/rman.h>
22 
23 #include <isa/isavar.h>
24 
25 #include <dev/scd/scdreg.h>
26 #include <dev/scd/scdvar.h>
27 
28 static int	scd_isa_probe	(device_t);
29 static int	scd_isa_attach	(device_t);
30 static int	scd_isa_detach	(device_t);
31 
32 static int	scd_alloc_resources	(device_t);
33 static void	scd_release_resources	(device_t);
34 
35 static int
scd_isa_probe(device_t dev)36 scd_isa_probe (device_t dev)
37 {
38 	struct scd_softc *	sc;
39 	int			error;
40 
41 	/* No pnp support */
42 	if (isa_get_vendorid(dev))
43 		return (ENXIO);
44 
45 	/* IO port must be configured. */
46 	if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0)
47 		return (ENXIO);
48 
49 	sc = device_get_softc(dev);
50 	sc->dev = dev;
51 	sc->port_rid = 0;
52 	sc->port_type = SYS_RES_IOPORT;
53 	error = scd_alloc_resources(dev);
54 	if (error)
55 		goto fail;
56 
57 	error = scd_probe(sc);
58 	if (error) {
59 		device_printf(dev, "Probe failed.\n");
60 		goto fail;
61 	}
62 
63 	device_set_desc(dev, sc->data.name);
64 
65 fail:
66 	scd_release_resources(dev);
67 	return (error);
68 }
69 
70 static int
scd_isa_attach(device_t dev)71 scd_isa_attach (device_t dev)
72 {
73 	struct scd_softc *	sc;
74 	int			error;
75 
76 	sc = device_get_softc(dev);
77 	error = 0;
78 
79 	sc->dev = dev;
80 	sc->port_rid = 0;
81 	sc->port_type = SYS_RES_IOPORT;
82 	error = scd_alloc_resources(dev);
83 	if (error)
84 		goto fail;
85 
86 	error = scd_probe(sc);
87 	if (error) {
88 		device_printf(dev, "Re-Probe failed.\n");
89 		goto fail;
90 	}
91 
92 	error = scd_attach(sc);
93 	if (error) {
94 		device_printf(dev, "Attach failed.\n");
95 		goto fail;
96 	}
97 
98 	return (0);
99 fail:
100 	scd_release_resources(dev);
101 	return (error);
102 }
103 
104 static int
scd_isa_detach(device_t dev)105 scd_isa_detach (device_t dev)
106 {
107 	struct scd_softc *	sc;
108 	int			error;
109 
110 	sc = device_get_softc(dev);
111 	error = 0;
112 
113 	destroy_dev(sc->scd_dev_t);
114 
115 	scd_release_resources(dev);
116 
117 	return (error);
118 }
119 
120 static int
scd_alloc_resources(device_t dev)121 scd_alloc_resources (device_t dev)
122 {
123 	struct scd_softc *	sc;
124 	int			error;
125 
126 	sc = device_get_softc(dev);
127 	error = 0;
128 
129 	if (sc->port_type) {
130 		sc->port = bus_alloc_resource_any(dev, sc->port_type,
131 				&sc->port_rid, RF_ACTIVE);
132 		if (sc->port == NULL) {
133 			device_printf(dev, "Unable to allocate PORT resource.\n");
134 			error = ENOMEM;
135 			goto bad;
136 		}
137 		sc->port_bst = rman_get_bustag(sc->port);
138 		sc->port_bsh = rman_get_bushandle(sc->port);
139 	}
140 
141 	mtx_init(&sc->mtx, device_get_nameunit(dev),
142 		"Interrupt lock", MTX_DEF | MTX_RECURSE);
143 
144 bad:
145 	return (error);
146 }
147 
148 void
scd_release_resources(device_t dev)149 scd_release_resources (device_t dev)
150 {
151 	struct scd_softc *	sc;
152 
153 	sc = device_get_softc(dev);
154 
155 	if (sc->port) {
156 		bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port);
157 		sc->port_bst = 0;
158 		sc->port_bsh = 0;
159 	}
160 
161 	if (mtx_initialized(&sc->mtx) != 0)
162 		mtx_destroy(&sc->mtx);
163 
164 	return;
165 }
166 
167 static device_method_t scd_isa_methods[] = {
168 	DEVMETHOD(device_probe,         scd_isa_probe),
169 	DEVMETHOD(device_attach,        scd_isa_attach),
170 	DEVMETHOD(device_detach,        scd_isa_detach),
171 
172 	{ 0, 0 }
173 };
174 
175 static driver_t scd_isa_driver = {
176 	"scd",
177 	scd_isa_methods,
178 	sizeof(struct scd_softc)
179 };
180 
181 static devclass_t	scd_devclass;
182 
183 DRIVER_MODULE(scd, isa, scd_isa_driver, scd_devclass, NULL, 0);
184