FreeBSD/Linux Kernel Cross Reference
sys/dev/mcd/mcd_isa.c
1 /*
2 */
3
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: releng/5.3/sys/dev/mcd/mcd_isa.c 127135 2004-03-17 17:50:55Z njl $");
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/lock.h>
18 #include <sys/mutex.h>
19
20 #include <machine/bus_pio.h>
21 #include <machine/bus.h>
22 #include <machine/resource.h>
23 #include <sys/rman.h>
24
25 #include <isa/isavar.h>
26
27 #include <dev/mcd/mcdreg.h>
28 #include <dev/mcd/mcdvar.h>
29
30 static int mcd_isa_probe (device_t);
31 static int mcd_isa_attach (device_t);
32 static int mcd_isa_detach (device_t);
33
34 static int mcd_alloc_resources (device_t);
35 static void mcd_release_resources (device_t);
36
37 static int
38 mcd_isa_probe (device_t dev)
39 {
40 struct mcd_softc * sc;
41 int error;
42
43 /* No pnp support */
44 if (isa_get_vendorid(dev))
45 return (ENXIO);
46
47 /* IO port must be configured. */
48 if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0)
49 return (ENXIO);
50
51 sc = device_get_softc(dev);
52 sc->dev = dev;
53 sc->port_rid = 0;
54 sc->port_type = SYS_RES_IOPORT;
55 error = mcd_alloc_resources(dev);
56 if (error)
57 goto fail;
58
59 error = mcd_probe(sc);
60 if (error) {
61 device_printf(dev, "Probe failed.\n");
62 goto fail;
63 }
64
65 device_set_desc(dev, sc->data.name);
66
67 fail:
68 mcd_release_resources(dev);
69 return (error);
70 }
71
72 static int
73 mcd_isa_attach (device_t dev)
74 {
75 struct mcd_softc * sc;
76 int error;
77
78 sc = device_get_softc(dev);
79 error = 0;
80
81 sc->dev = dev;
82 sc->port_rid = 0;
83 sc->port_type = SYS_RES_IOPORT;
84 error = mcd_alloc_resources(dev);
85 if (error)
86 goto fail;
87
88 error = mcd_probe(sc);
89 if (error) {
90 device_printf(dev, "Re-Probe failed.\n");
91 goto fail;
92 }
93
94 error = mcd_attach(sc);
95 if (error) {
96 device_printf(dev, "Attach failed.\n");
97 goto fail;
98 }
99
100 return (0);
101 fail:
102 mcd_release_resources(dev);
103 return (error);
104 }
105
106 static int
107 mcd_isa_detach (device_t dev)
108 {
109 struct mcd_softc * sc;
110 int error;
111
112 sc = device_get_softc(dev);
113 error = 0;
114
115 destroy_dev(sc->mcd_dev_t);
116
117 mcd_release_resources(dev);
118
119 return (error);
120 }
121
122 static int
123 mcd_alloc_resources (device_t dev)
124 {
125 struct mcd_softc * sc;
126 int error;
127
128 sc = device_get_softc(dev);
129 error = 0;
130
131 if (sc->port_type) {
132 sc->port = bus_alloc_resource_any(dev, sc->port_type,
133 &sc->port_rid, RF_ACTIVE);
134 if (sc->port == NULL) {
135 device_printf(dev, "Unable to allocate PORT resource.\n");
136 error = ENOMEM;
137 goto bad;
138 }
139 sc->port_bst = rman_get_bustag(sc->port);
140 sc->port_bsh = rman_get_bushandle(sc->port);
141 }
142
143 if (sc->irq_type) {
144 sc->irq = bus_alloc_resource_any(dev, sc->irq_type,
145 &sc->irq_rid, RF_ACTIVE);
146 if (sc->irq == NULL) {
147 device_printf(dev, "Unable to allocate IRQ resource.\n");
148 error = ENOMEM;
149 goto bad;
150 }
151 }
152
153 if (sc->drq_type) {
154 sc->drq = bus_alloc_resource_any(dev, sc->drq_type,
155 &sc->drq_rid, RF_ACTIVE);
156 if (sc->drq == NULL) {
157 device_printf(dev, "Unable to allocate DRQ resource.\n");
158 error = ENOMEM;
159 goto bad;
160 }
161 }
162
163 mtx_init(&sc->mtx, device_get_nameunit(dev),
164 "Interrupt lock", MTX_DEF | MTX_RECURSE);
165
166 bad:
167 return (error);
168 }
169
170 static void
171 mcd_release_resources (device_t dev)
172 {
173 struct mcd_softc * sc;
174
175 sc = device_get_softc(dev);
176
177 if (sc->irq_ih)
178 bus_teardown_intr(dev, sc->irq, sc->irq_ih);
179 if (sc->port) {
180 bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port);
181 sc->port_bst = 0;
182 sc->port_bsh = 0;
183 }
184 if (sc->irq)
185 bus_release_resource(dev, sc->irq_type, sc->irq_rid, sc->irq);
186 if (sc->drq)
187 bus_release_resource(dev, sc->drq_type, sc->drq_rid, sc->drq);
188
189 if (mtx_initialized(&sc->mtx) != 0)
190 mtx_destroy(&sc->mtx);
191
192 return;
193 }
194
195 static device_method_t mcd_isa_methods[] = {
196 DEVMETHOD(device_probe, mcd_isa_probe),
197 DEVMETHOD(device_attach, mcd_isa_attach),
198 DEVMETHOD(device_detach, mcd_isa_detach),
199
200 { 0, 0 }
201 };
202
203 static driver_t mcd_isa_driver = {
204 "mcd",
205 mcd_isa_methods,
206 sizeof(struct mcd_softc)
207 };
208
209 static devclass_t mcd_devclass;
210
211 DRIVER_MODULE(mcd, isa, mcd_isa_driver, mcd_devclass, NULL, 0);
Cache object: ae8265d034bb021c8d667601d3255c8f
|