scd_isa.c revision 127135
1/* 2 */ 3 4#include <sys/cdefs.h> 5__FBSDID("$FreeBSD: head/sys/dev/scd/scd_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/mutex.h> 18 19#include <machine/bus_pio.h> 20#include <machine/bus.h> 21#include <machine/resource.h> 22#include <sys/rman.h> 23 24#include <isa/isavar.h> 25 26#include <dev/scd/scdreg.h> 27#include <dev/scd/scdvar.h> 28 29static int scd_isa_probe (device_t); 30static int scd_isa_attach (device_t); 31static int scd_isa_detach (device_t); 32 33static int scd_alloc_resources (device_t); 34static void scd_release_resources (device_t); 35 36static int 37scd_isa_probe (device_t dev) 38{ 39 struct scd_softc * sc; 40 int error; 41 42 /* No pnp support */ 43 if (isa_get_vendorid(dev)) 44 return (ENXIO); 45 46 /* IO port must be configured. */ 47 if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0) 48 return (ENXIO); 49 50 sc = device_get_softc(dev); 51 sc->dev = dev; 52 sc->port_rid = 0; 53 sc->port_type = SYS_RES_IOPORT; 54 error = scd_alloc_resources(dev); 55 if (error) 56 goto fail; 57 58 error = scd_probe(sc); 59 if (error) { 60 device_printf(dev, "Probe failed.\n"); 61 goto fail; 62 } 63 64 device_set_desc(dev, sc->data.name); 65 66fail: 67 scd_release_resources(dev); 68 return (error); 69} 70 71static int 72scd_isa_attach (device_t dev) 73{ 74 struct scd_softc * sc; 75 int error; 76 77 sc = device_get_softc(dev); 78 error = 0; 79 80 sc->dev = dev; 81 sc->port_rid = 0; 82 sc->port_type = SYS_RES_IOPORT; 83 error = scd_alloc_resources(dev); 84 if (error) 85 goto fail; 86 87 error = scd_probe(sc); 88 if (error) { 89 device_printf(dev, "Re-Probe failed.\n"); 90 goto fail; 91 } 92 93 error = scd_attach(sc); 94 if (error) { 95 device_printf(dev, "Attach failed.\n"); 96 goto fail; 97 } 98 99 return (0); 100fail: 101 scd_release_resources(dev); 102 return (error); 103} 104 105static int 106scd_isa_detach (device_t dev) 107{ 108 struct scd_softc * sc; 109 int error; 110 111 sc = device_get_softc(dev); 112 error = 0; 113 114 destroy_dev(sc->scd_dev_t); 115 116 scd_release_resources(dev); 117 118 return (error); 119} 120 121static int 122scd_alloc_resources (device_t dev) 123{ 124 struct scd_softc * sc; 125 int error; 126 127 sc = device_get_softc(dev); 128 error = 0; 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 sc->port_bst = rman_get_bustag(sc->port); 139 sc->port_bsh = rman_get_bushandle(sc->port); 140 } 141 142 mtx_init(&sc->mtx, device_get_nameunit(dev), 143 "Interrupt lock", MTX_DEF | MTX_RECURSE); 144 145bad: 146 return (error); 147} 148 149void 150scd_release_resources (device_t dev) 151{ 152 struct scd_softc * sc; 153 154 sc = device_get_softc(dev); 155 156 if (sc->port) { 157 bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port); 158 sc->port_bst = 0; 159 sc->port_bsh = 0; 160 } 161 162 if (mtx_initialized(&sc->mtx) != 0) 163 mtx_destroy(&sc->mtx); 164 165 return; 166} 167 168static device_method_t scd_isa_methods[] = { 169 DEVMETHOD(device_probe, scd_isa_probe), 170 DEVMETHOD(device_attach, scd_isa_attach), 171 DEVMETHOD(device_detach, scd_isa_detach), 172 173 { 0, 0 } 174}; 175 176static driver_t scd_isa_driver = { 177 "scd", 178 scd_isa_methods, 179 sizeof(struct scd_softc) 180}; 181 182static devclass_t scd_devclass; 183 184DRIVER_MODULE(scd, isa, scd_isa_driver, scd_devclass, NULL, 0); 185