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