2 * Copyright (c) 1998 Doug Rabson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
33 #include <sys/malloc.h>
34 #include <sys/module.h>
35 #include <machine/bus.h>
38 #include <machine/vmparam.h>
41 #include <machine/pmap.h>
42 #include <machine/md_var.h>
44 #include <machine/resource.h>
45 #include <isa/isavar.h>
46 #include <i386/isa/isa_device.h>
48 struct isa_compat_resources {
49 struct resource *ports;
50 struct resource *memory;
56 isa_compat_alloc_resources(device_t dev, struct isa_compat_resources *res)
61 if (bus_get_resource(dev, SYS_RES_IOPORT, 0,
62 &start, &count) == 0) {
64 res->ports = bus_alloc_resource(dev, SYS_RES_IOPORT,
67 if (res->ports == NULL && bootverbose)
68 printf("isa_compat: didn't get ports for %s\n",
69 device_get_name(dev));
73 if (bus_get_resource(dev, SYS_RES_MEMORY, 0,
77 res->memory = bus_alloc_resource(dev, SYS_RES_MEMORY,
80 if (res->memory == NULL && bootverbose)
81 printf("isa_compat: didn't get memory for %s\n",
82 device_get_name(dev));
86 if (bus_get_resource(dev, SYS_RES_DRQ, 0,
87 &start, &count) == 0) {
89 res->drq = bus_alloc_resource(dev, SYS_RES_DRQ,
92 if (res->drq == NULL && bootverbose)
93 printf("isa_compat: didn't get drq for %s\n",
94 device_get_name(dev));
98 if (bus_get_resource(dev, SYS_RES_IRQ, 0,
99 &start, &count) == 0) {
101 res->irq = bus_alloc_resource(dev, SYS_RES_IRQ,
103 RF_SHAREABLE | RF_ACTIVE);
104 if (res->irq == NULL && bootverbose)
105 printf("isa_compat: didn't get irq for %s\n",
106 device_get_name(dev));
112 isa_compat_release_resources(device_t dev, struct isa_compat_resources *res)
115 bus_release_resource(dev, SYS_RES_IOPORT, 0, res->ports);
119 bus_release_resource(dev, SYS_RES_MEMORY, 0, res->memory);
123 bus_release_resource(dev, SYS_RES_DRQ, 0, res->drq);
127 bus_release_resource(dev, SYS_RES_IRQ, 0, res->irq);
132 #define irqmask(x) ((x) < 0 ? 0 : (1 << (x)))
135 isa_compat_probe(device_t dev)
137 struct isa_device *dvp = device_get_softc(dev);
138 struct isa_compat_resources res;
142 if (isa_get_vendorid(dev))
145 bzero(&res, sizeof(res));
147 * Fill in the isa_device fields.
149 dvp->id_driver = device_get_driver(dev)->priv;
150 if (bus_get_resource(dev, SYS_RES_IOPORT, 0,
151 &start, &count) == 0)
152 dvp->id_iobase = start;
155 if (bus_get_resource(dev, SYS_RES_IRQ, 0,
156 &start, &count) == 0)
157 dvp->id_irq = irqmask(start);
160 if (bus_get_resource(dev, SYS_RES_DRQ, 0,
161 &start, &count) == 0)
165 if (bus_get_resource(dev, SYS_RES_MEMORY,
166 0, &start, &count) == 0) {
167 dvp->id_maddr = (void *)(uintptr_t)start;
168 dvp->id_msize = count;
170 dvp->id_maddr = NULL;
173 dvp->id_unit = device_get_unit(dev);
174 dvp->id_flags = device_get_flags(dev);
175 dvp->id_enabled = device_is_enabled(dev); /* XXX unused */
176 dvp->id_device = dev;
179 * Do the wrapped probe.
181 if (dvp->id_driver->probe) {
184 struct isa_device old;
186 isa_compat_alloc_resources(dev, &res);
188 maddr = rman_get_virtual(res.memory);
191 dvp->id_maddr = maddr;
193 portsize = dvp->id_driver->probe(dvp);
194 isa_compat_release_resources(dev, &res);
196 if (portsize > 0 || dvp->id_iobase != old.id_iobase)
197 bus_set_resource(dev, SYS_RES_IOPORT,
198 0, dvp->id_iobase, portsize);
199 if (dvp->id_irq != old.id_irq)
200 bus_set_resource(dev, SYS_RES_IRQ, 0,
201 ffs(dvp->id_irq) - 1, 1);
202 if (dvp->id_drq != old.id_drq)
203 bus_set_resource(dev, SYS_RES_DRQ, 0,
205 if (dvp->id_maddr != old.id_maddr
206 || dvp->id_msize != old.id_msize) {
207 maddr = dvp->id_maddr;
209 bus_set_resource(dev,
215 bus_delete_resource(dev,
226 isa_compat_attach(device_t dev)
228 struct isa_device *dvp = device_get_softc(dev);
229 struct isa_compat_resources res;
232 bzero(&res, sizeof(res));
233 isa_compat_alloc_resources(dev, &res);
234 if (dvp->id_driver->attach)
235 dvp->id_driver->attach(dvp);
236 if (res.irq && dvp->id_irq && dvp->id_intr) {
239 error = BUS_SETUP_INTR(device_get_parent(dev), dev,
240 res.irq, dvp->id_driver->intrflags,
242 (void *)(uintptr_t)dvp->id_unit,
245 printf("isa_compat_attach: failed to setup intr: %d\n",
248 device_printf(dev, "driver is using old-style compatibility shims\n");
252 static device_method_t isa_compat_methods[] = {
253 /* Device interface */
254 DEVMETHOD(device_probe, isa_compat_probe),
255 DEVMETHOD(device_attach, isa_compat_attach),
261 * Create a new style driver around each old isa driver.
264 compat_isa_handler(module_t mod, int type, void *data)
266 struct isa_driver *id = (struct isa_driver *)data;
268 devclass_t isa_devclass = devclass_find("isa");
272 driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT | M_ZERO);
275 driver->name = id->name;
276 driver->methods = isa_compat_methods;
277 driver->size = sizeof(struct isa_device);
279 if (id->sensitive_hw)
280 resource_set_int(id->name, -1, "sensitive", 1);
281 devclass_add_driver(isa_devclass, driver);
284 printf("%s: module unload not supported!\n", id->name);