]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/scd/scd_isa.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / scd / scd_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/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
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
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
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
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
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);