dpt_isa.c revision 112795
1/*- 2 * Copyright (c) 2000 Matthew N. Dodd <winter@jurai.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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. 13 * 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 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/dev/dpt/dpt_isa.c 112795 2003-03-29 14:50:14Z mdodd $ 27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/kernel.h> 32#include <sys/module.h> 33#include <sys/bus.h> 34 35#include <machine/bus_pio.h> 36#include <machine/bus.h> 37#include <machine/resource.h> 38#include <sys/rman.h> 39 40#include <isa/isavar.h> 41 42#include <cam/scsi/scsi_all.h> 43 44#include <dev/dpt/dpt.h> 45 46#ifdef notyet 47static void dpt_isa_identify (driver_t *, device_t); 48#endif 49static int dpt_isa_probe (device_t); 50static int dpt_isa_attach (device_t); 51static int dpt_isa_detach (device_t); 52 53static int dpt_isa_valid_irq (int); 54static int dpt_isa_valid_ioport (int); 55 56static int 57dpt_isa_valid_irq (int irq) 58{ 59 switch (irq) { 60 case 11: 61 case 12: 62 case 14: 63 case 15: 64 return (0); 65 default: 66 return (1); 67 }; 68 return (1); 69} 70 71static int 72dpt_isa_valid_ioport (int ioport) 73{ 74 switch (ioport) { 75 case 0x170: 76 case 0x1f0: 77 case 0x230: 78 case 0x330: 79 return (0); 80 default: 81 return (1); 82 }; 83 return (1); 84} 85 86#ifdef notyet 87static void 88dpt_isa_identify (driver_t *driver, device_t parent) 89{ 90 device_t child; 91 dpt_conf_t * conf; 92 int isa_bases[] = { 0x1f0, 0x170, 0x330, 0x230, 0 }; 93 int i; 94 95 for (i = 0; isa_bases[i]; i++) { 96 conf = dpt_pio_get_conf(isa_bases[i]); 97 if (!conf) { 98 if (bootverbose) 99 device_printf(parent, "dpt: dpt_pio_get_conf(%x) failed.\n", 100 isa_bases[i]); 101 continue; 102 } 103 104 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "dpt", -1); 105 if (child == 0) { 106 device_printf(parent, "dpt: BUS_ADD_CHILD() failed!\n"); 107 continue; 108 } 109 device_set_driver(child, driver); 110 bus_set_resource(child, SYS_RES_IOPORT, 0, isa_bases[i], 0x9); 111 } 112 return; 113} 114#endif 115 116static int 117dpt_isa_probe (device_t dev) 118{ 119 dpt_conf_t * conf; 120 u_int32_t io_base; 121 122 /* No pnp support */ 123 if (isa_get_vendorid(dev)) 124 return (ENXIO); 125 126 if ((io_base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0) 127 return (ENXIO); 128 129 if (dpt_isa_valid_ioport(io_base)) 130 ; 131 132 conf = dpt_pio_get_conf(io_base); 133 if (!conf) { 134 printf("dpt: dpt_pio_get_conf() failed.\n"); 135 return (ENXIO); 136 } 137 138 if (dpt_isa_valid_irq(conf->IRQ)) 139 ; 140 141 device_set_desc(dev, "ISA DPT SCSI controller"); 142 bus_set_resource(dev, SYS_RES_IRQ, 0, conf->IRQ, 1); 143 bus_set_resource(dev, SYS_RES_DRQ, 0, ((8 - conf->DMA_channel) & 7), 1); 144 145 return 0; 146} 147 148static int 149dpt_isa_attach (device_t dev) 150{ 151 dpt_softc_t * dpt; 152 int s; 153 int error = 0; 154 155 dpt = device_get_softc(dev); 156 157 158 dpt->io_rid = 0; 159 dpt->io_type = SYS_RES_IOPORT; 160 dpt->irq_rid = 0; 161 162 error = dpt_alloc_resources(dev); 163 if (error) { 164 goto bad; 165 } 166 167 dpt->drq_rid = 0; 168 dpt->drq_res = bus_alloc_resource(dev, SYS_RES_DRQ, &dpt->drq_rid, 169 0, ~0, 1, RF_ACTIVE); 170 if (!dpt->drq_res) { 171 device_printf(dev, "No DRQ!\n"); 172 error = ENOMEM; 173 goto bad; 174 } 175 isa_dma_acquire(rman_get_start(dpt->drq_res)); 176 isa_dmacascade(rman_get_start(dpt->drq_res)); 177 178 dpt_alloc(dev); 179 180 /* Allocate a dmatag representing the capabilities of this attachment */ 181 if (bus_dma_tag_create( /* parent */ NULL, 182 /* alignemnt */ 1, 183 /* boundary */ 0, 184 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 185 /* highaddr */ BUS_SPACE_MAXADDR, 186 /* filter */ NULL, 187 /* filterarg */ NULL, 188 /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, 189 /* nsegments */ ~0, 190 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 191 /* flags */ 0, 192 &dpt->parent_dmat) != 0) { 193 error = ENXIO; 194 goto bad; 195 } 196 197 s = splcam(); 198 199 if (dpt_init(dpt) != 0) { 200 splx(s); 201 error = ENXIO; 202 goto bad; 203 } 204 205 /* Register with the XPT */ 206 dpt_attach(dpt); 207 208 splx(s); 209 210 if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, 211 dpt_intr, dpt, &dpt->ih)) { 212 device_printf(dev, "Unable to register interrupt handler\n"); 213 error = ENXIO; 214 goto bad; 215 } 216 217 return (error); 218 219 bad: 220 if (dpt->drq_res) { 221 isa_dma_release(rman_get_start(dpt->drq_res)); 222 } 223 224 dpt_release_resources(dev); 225 226 if (dpt) 227 dpt_free(dpt); 228 229 return (error); 230} 231 232static int 233dpt_isa_detach (device_t dev) 234{ 235 dpt_softc_t * dpt; 236 int dma; 237 int error; 238 239 dpt = device_get_softc(dev); 240 241 dma = rman_get_start(dpt->drq_res); 242 error = dpt_detach(dev); 243 isa_dma_release(dma); 244 245 return (error); 246} 247 248 249static device_method_t dpt_isa_methods[] = { 250 /* Device interface */ 251#ifdef notyet 252 DEVMETHOD(device_identify, dpt_isa_identify), 253#endif 254 DEVMETHOD(device_probe, dpt_isa_probe), 255 DEVMETHOD(device_attach, dpt_isa_attach), 256 DEVMETHOD(device_detach, dpt_isa_detach), 257 258 { 0, 0 } 259}; 260 261static driver_t dpt_isa_driver = { 262 "dpt", 263 dpt_isa_methods, 264 sizeof(dpt_softc_t), 265}; 266 267DRIVER_MODULE(dpt, isa, dpt_isa_driver, dpt_devclass, 0, 0); 268