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
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 mtx_init(&sc->mtx, "scd", NULL, MTX_DEF);
129
130 if (sc->port_type) {
131 sc->port = bus_alloc_resource_any(dev, sc->port_type,
132 &sc->port_rid, RF_ACTIVE);
133 if (sc->port == NULL) {
134 device_printf(dev, "Unable to allocate PORT resource.\n");
135 error = ENOMEM;
136 goto bad;
137 }
138 }
139
140 bad:
141 return (error);
142 }
143
144 void
scd_release_resources(device_t dev)145 scd_release_resources (device_t dev)
146 {
147 struct scd_softc * sc;
148
149 sc = device_get_softc(dev);
150
151 if (sc->port)
152 bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port);
153
154 mtx_destroy(&sc->mtx);
155
156 return;
157 }
158
159 static device_method_t scd_isa_methods[] = {
160 DEVMETHOD(device_probe, scd_isa_probe),
161 DEVMETHOD(device_attach, scd_isa_attach),
162 DEVMETHOD(device_detach, scd_isa_detach),
163
164 { 0, 0 }
165 };
166
167 static driver_t scd_isa_driver = {
168 "scd",
169 scd_isa_methods,
170 sizeof(struct scd_softc)
171 };
172
173 static devclass_t scd_devclass;
174
175 DRIVER_MODULE(scd, isa, scd_isa_driver, scd_devclass, NULL, 0);
176