scd_isa.c revision 127135
1106449Smdodd/* 2106449Smdodd */ 3106449Smdodd 4119419Sobrien#include <sys/cdefs.h> 5119419Sobrien__FBSDID("$FreeBSD: head/sys/dev/scd/scd_isa.c 127135 2004-03-17 17:50:55Z njl $"); 6119419Sobrien 7106449Smdodd#include <sys/param.h> 8106449Smdodd#include <sys/systm.h> 9106449Smdodd#include <sys/kernel.h> 10106449Smdodd#include <sys/module.h> 11106449Smdodd#include <sys/conf.h> 12106449Smdodd#include <sys/fcntl.h> 13106449Smdodd#include <sys/bio.h> 14106449Smdodd#include <sys/cdio.h> 15106449Smdodd#include <sys/bus.h> 16106449Smdodd 17106449Smdodd#include <sys/mutex.h> 18106449Smdodd 19106449Smdodd#include <machine/bus_pio.h> 20106449Smdodd#include <machine/bus.h> 21106449Smdodd#include <machine/resource.h> 22106449Smdodd#include <sys/rman.h> 23106449Smdodd 24106449Smdodd#include <isa/isavar.h> 25106449Smdodd 26106449Smdodd#include <dev/scd/scdreg.h> 27106449Smdodd#include <dev/scd/scdvar.h> 28106449Smdodd 29106449Smdoddstatic int scd_isa_probe (device_t); 30106449Smdoddstatic int scd_isa_attach (device_t); 31106449Smdoddstatic int scd_isa_detach (device_t); 32106449Smdodd 33106449Smdoddstatic int scd_alloc_resources (device_t); 34106449Smdoddstatic void scd_release_resources (device_t); 35106449Smdodd 36106449Smdoddstatic int 37106449Smdoddscd_isa_probe (device_t dev) 38106449Smdodd{ 39106449Smdodd struct scd_softc * sc; 40106449Smdodd int error; 41106449Smdodd 42106449Smdodd /* No pnp support */ 43106449Smdodd if (isa_get_vendorid(dev)) 44106449Smdodd return (ENXIO); 45106449Smdodd 46106449Smdodd /* IO port must be configured. */ 47106449Smdodd if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0) 48106449Smdodd return (ENXIO); 49106449Smdodd 50106449Smdodd sc = device_get_softc(dev); 51106449Smdodd sc->dev = dev; 52106449Smdodd sc->port_rid = 0; 53106449Smdodd sc->port_type = SYS_RES_IOPORT; 54106449Smdodd error = scd_alloc_resources(dev); 55106449Smdodd if (error) 56106449Smdodd goto fail; 57106449Smdodd 58106449Smdodd error = scd_probe(sc); 59106449Smdodd if (error) { 60106449Smdodd device_printf(dev, "Probe failed.\n"); 61106449Smdodd goto fail; 62106449Smdodd } 63106449Smdodd 64106449Smdodd device_set_desc(dev, sc->data.name); 65106449Smdodd 66106449Smdoddfail: 67106449Smdodd scd_release_resources(dev); 68106449Smdodd return (error); 69106449Smdodd} 70106449Smdodd 71106449Smdoddstatic int 72106449Smdoddscd_isa_attach (device_t dev) 73106449Smdodd{ 74106449Smdodd struct scd_softc * sc; 75106449Smdodd int error; 76106449Smdodd 77106449Smdodd sc = device_get_softc(dev); 78106449Smdodd error = 0; 79106449Smdodd 80106449Smdodd sc->dev = dev; 81106449Smdodd sc->port_rid = 0; 82106449Smdodd sc->port_type = SYS_RES_IOPORT; 83106449Smdodd error = scd_alloc_resources(dev); 84106449Smdodd if (error) 85106449Smdodd goto fail; 86106449Smdodd 87106449Smdodd error = scd_probe(sc); 88106449Smdodd if (error) { 89106449Smdodd device_printf(dev, "Re-Probe failed.\n"); 90106449Smdodd goto fail; 91106449Smdodd } 92106449Smdodd 93106449Smdodd error = scd_attach(sc); 94106449Smdodd if (error) { 95106449Smdodd device_printf(dev, "Attach failed.\n"); 96106449Smdodd goto fail; 97106449Smdodd } 98106449Smdodd 99106449Smdodd return (0); 100106449Smdoddfail: 101106449Smdodd scd_release_resources(dev); 102106449Smdodd return (error); 103106449Smdodd} 104106449Smdodd 105106449Smdoddstatic int 106106449Smdoddscd_isa_detach (device_t dev) 107106449Smdodd{ 108106449Smdodd struct scd_softc * sc; 109106449Smdodd int error; 110106449Smdodd 111106449Smdodd sc = device_get_softc(dev); 112106449Smdodd error = 0; 113106449Smdodd 114106449Smdodd destroy_dev(sc->scd_dev_t); 115106449Smdodd 116106449Smdodd scd_release_resources(dev); 117106449Smdodd 118106449Smdodd return (error); 119106449Smdodd} 120106449Smdodd 121106449Smdoddstatic int 122106449Smdoddscd_alloc_resources (device_t dev) 123106449Smdodd{ 124106449Smdodd struct scd_softc * sc; 125106449Smdodd int error; 126106449Smdodd 127106449Smdodd sc = device_get_softc(dev); 128106449Smdodd error = 0; 129106449Smdodd 130106449Smdodd if (sc->port_type) { 131127135Snjl sc->port = bus_alloc_resource_any(dev, sc->port_type, 132127135Snjl &sc->port_rid, RF_ACTIVE); 133106449Smdodd if (sc->port == NULL) { 134106449Smdodd device_printf(dev, "Unable to allocate PORT resource.\n"); 135106449Smdodd error = ENOMEM; 136106449Smdodd goto bad; 137106449Smdodd } 138106449Smdodd sc->port_bst = rman_get_bustag(sc->port); 139106449Smdodd sc->port_bsh = rman_get_bushandle(sc->port); 140106449Smdodd } 141106449Smdodd 142106449Smdodd mtx_init(&sc->mtx, device_get_nameunit(dev), 143106449Smdodd "Interrupt lock", MTX_DEF | MTX_RECURSE); 144106449Smdodd 145106449Smdoddbad: 146106449Smdodd return (error); 147106449Smdodd} 148106449Smdodd 149106449Smdoddvoid 150106449Smdoddscd_release_resources (device_t dev) 151106449Smdodd{ 152106449Smdodd struct scd_softc * sc; 153106449Smdodd 154106449Smdodd sc = device_get_softc(dev); 155106449Smdodd 156106449Smdodd if (sc->port) { 157106449Smdodd bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port); 158106449Smdodd sc->port_bst = 0; 159106449Smdodd sc->port_bsh = 0; 160106449Smdodd } 161106449Smdodd 162106449Smdodd if (mtx_initialized(&sc->mtx) != 0) 163106449Smdodd mtx_destroy(&sc->mtx); 164106449Smdodd 165106449Smdodd return; 166106449Smdodd} 167106449Smdodd 168106449Smdoddstatic device_method_t scd_isa_methods[] = { 169106449Smdodd DEVMETHOD(device_probe, scd_isa_probe), 170106449Smdodd DEVMETHOD(device_attach, scd_isa_attach), 171106449Smdodd DEVMETHOD(device_detach, scd_isa_detach), 172106449Smdodd 173106449Smdodd { 0, 0 } 174106449Smdodd}; 175106449Smdodd 176106449Smdoddstatic driver_t scd_isa_driver = { 177106449Smdodd "scd", 178106449Smdodd scd_isa_methods, 179106449Smdodd sizeof(struct scd_softc) 180106449Smdodd}; 181106449Smdodd 182106449Smdoddstatic devclass_t scd_devclass; 183106449Smdodd 184106449SmdoddDRIVER_MODULE(scd, isa, scd_isa_driver, scd_devclass, NULL, 0); 185