dpt_isa.c revision 73280
1168404Spjd/*- 2168404Spjd * Copyright (c) 2000 Matthew N. Dodd <winter@jurai.net> 3168404Spjd * All rights reserved. 4168404Spjd * 5168404Spjd * Redistribution and use in source and binary forms, with or without 6168404Spjd * modification, are permitted provided that the following conditions 7168404Spjd * are met: 8168404Spjd * 1. Redistributions of source code must retain the above copyright 9168404Spjd * notice, this list of conditions and the following disclaimer. 10168404Spjd * 2. Redistributions in binary form must reproduce the above copyright 11168404Spjd * notice, this list of conditions and the following disclaimer in the 12168404Spjd * documentation and/or other materials provided with the distribution. 13168404Spjd * 14168404Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15168404Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16168404Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17168404Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18168404Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19168404Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20168404Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21168404Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22168404Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23219089Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24168404Spjd * SUCH DAMAGE. 25168404Spjd * 26168404Spjd * $FreeBSD: head/sys/dev/dpt/dpt_isa.c 73280 2001-03-01 17:09:09Z markm $ 27168404Spjd */ 28168404Spjd 29168404Spjd#include <sys/param.h> 30168404Spjd#include <sys/systm.h> 31168404Spjd#include <sys/kernel.h> 32168404Spjd#include <sys/module.h> 33168404Spjd#include <sys/bus.h> 34185029Spjd 35168404Spjd#include <machine/bus_pio.h> 36168404Spjd#include <machine/bus.h> 37185029Spjd#include <machine/resource.h> 38185029Spjd#include <sys/rman.h> 39219089Spjd 40168404Spjd#include <isa/isavar.h> 41168404Spjd 42168404Spjd#include <cam/scsi/scsi_all.h> 43185029Spjd 44168404Spjd#include <dev/dpt/dpt.h> 45185029Spjd 46168404Spjdstatic int dpt_isa_probe (device_t); 47168404Spjdstatic int dpt_isa_attach (device_t); 48168404Spjd 49168404Spjdstatic int 50168404Spjddpt_isa_probe (device_t dev) 51168404Spjd{ 52168404Spjd dpt_conf_t * conf; 53168404Spjd u_int32_t io_base; 54168404Spjd 55168404Spjd /* No pnp support */ 56168404Spjd if (isa_get_vendorid(dev)) 57168404Spjd return (ENXIO); 58168404Spjd 59168404Spjd if ((io_base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0) 60168404Spjd return (ENXIO); 61168404Spjd 62168404Spjd conf = dpt_pio_get_conf(io_base); 63168404Spjd if (!conf) { 64168404Spjd printf("dpt: dpt_pio_get_conf() failed.\n"); 65168404Spjd return (ENXIO); 66168404Spjd } 67168404Spjd 68168404Spjd device_set_desc(dev, "ISA DPT SCSI controller"); 69168404Spjd bus_set_resource(dev, SYS_RES_IRQ, 0, conf->IRQ, 1); 70168404Spjd bus_set_resource(dev, SYS_RES_DRQ, 0, ((8 - conf->DMA_channel) & 7), 1); 71168404Spjd 72168404Spjd return 0; 73168404Spjd} 74168404Spjd 75168404Spjdstatic int 76168404Spjddpt_isa_attach (device_t dev) 77168404Spjd{ 78168404Spjd dpt_softc_t * dpt = NULL; 79168404Spjd struct resource *io = 0; 80168404Spjd struct resource *irq = 0; 81168404Spjd struct resource *drq = 0; 82168404Spjd int s; 83168404Spjd int rid; 84168404Spjd void * ih; 85168404Spjd int error = 0; 86168404Spjd 87168404Spjd rid = 0; 88168404Spjd io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 89168404Spjd if (!io) { 90168404Spjd device_printf(dev, "No I/O space?!\n"); 91168404Spjd error = ENOMEM; 92168404Spjd goto bad; 93168404Spjd } 94168404Spjd 95168404Spjd rid = 0; 96168404Spjd irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE); 97168404Spjd if (!irq) { 98168404Spjd device_printf(dev, "No IRQ!\n"); 99168404Spjd error = ENOMEM; 100168404Spjd goto bad; 101168404Spjd } 102168404Spjd 103168404Spjd rid = 0; 104168404Spjd drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid, 0, ~0, 1, RF_ACTIVE); 105168404Spjd if (!drq) { 106168404Spjd device_printf(dev, "No DRQ?!\n"); 107168404Spjd error = ENOMEM; 108168404Spjd goto bad; 109168404Spjd } 110168404Spjd 111168404Spjd dpt = dpt_alloc(dev, rman_get_bustag(io), rman_get_bushandle(io)); 112168404Spjd if (dpt == NULL) { 113168404Spjd error = ENXIO; 114168404Spjd goto bad; 115168404Spjd } 116168404Spjd 117168404Spjd isa_dmacascade(rman_get_start(drq)); 118168404Spjd 119168404Spjd /* Allocate a dmatag representing the capabilities of this attachment */ 120168404Spjd if (bus_dma_tag_create( /* parent */ NULL, 121168404Spjd /* alignemnt */ 1, 122168404Spjd /* boundary */ 0, 123168404Spjd /* lowaddr */ BUS_SPACE_MAXADDR_24BIT, 124168404Spjd /* highaddr */ BUS_SPACE_MAXADDR, 125168404Spjd /* filter */ NULL, 126168404Spjd /* filterarg */ NULL, 127168404Spjd /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, 128168404Spjd /* nsegments */ BUS_SPACE_UNRESTRICTED, 129168404Spjd /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 130168404Spjd /* flags */ 0, 131168404Spjd &dpt->parent_dmat) != 0) { 132168404Spjd error = ENXIO; 133168404Spjd goto bad; 134168404Spjd } 135168404Spjd 136168404Spjd s = splcam(); 137168404Spjd 138168404Spjd if (dpt_init(dpt) != 0) { 139168404Spjd splx(s); 140168404Spjd error = ENXIO; 141168404Spjd goto bad; 142168404Spjd } 143168404Spjd 144168404Spjd /* Register with the XPT */ 145168404Spjd dpt_attach(dpt); 146168404Spjd 147168404Spjd splx(s); 148168404Spjd 149168404Spjd if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_ENTROPY, dpt_intr, 150168404Spjd dpt, &ih)) { 151168404Spjd device_printf(dev, "Unable to register interrupt handler\n"); 152168404Spjd error = ENXIO; 153168404Spjd goto bad; 154168404Spjd } 155168404Spjd 156168404Spjd return (error); 157168404Spjd 158168404Spjd bad: 159168404Spjd if (dpt) 160168404Spjd dpt_free(dpt); 161168404Spjd if (io) 162168404Spjd bus_release_resource(dev, SYS_RES_IOPORT, 0, io); 163168404Spjd if (irq) 164168404Spjd bus_release_resource(dev, SYS_RES_IRQ, 0, irq); 165168404Spjd if (drq) 166168404Spjd bus_release_resource(dev, SYS_RES_DRQ, 0, drq); 167168404Spjd 168168404Spjd return (error); 169168404Spjd} 170168404Spjd 171168404Spjdstatic device_method_t dpt_isa_methods[] = { 172168404Spjd /* Device interface */ 173168404Spjd DEVMETHOD(device_probe, dpt_isa_probe), 174168404Spjd DEVMETHOD(device_attach, dpt_isa_attach), 175168404Spjd 176168404Spjd { 0, 0 } 177168404Spjd}; 178168404Spjd 179168404Spjdstatic driver_t dpt_isa_driver = { 180168404Spjd "dpt", 181168404Spjd dpt_isa_methods, 182168404Spjd sizeof(dpt_softc_t), 183168404Spjd}; 184168404Spjd 185168404Spjdstatic devclass_t dpt_devclass; 186168404Spjd 187168404SpjdDRIVER_MODULE(dpt, isa, dpt_isa_driver, dpt_devclass, 0, 0); 188168404Spjd