]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/mcd/mcd_isa.c
This commit was generated by cvs2svn to compensate for changes in r133543,
[FreeBSD/FreeBSD.git] / sys / dev / mcd / mcd_isa.c
1 /*
2  */
3
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD$");
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);