1/* 2 * Device probe and attach routines for the following 3 * Advanced Systems Inc. SCSI controllers: 4 * 5 * Connectivity Products: 6 * ABP510/5150 - Bus-Master ISA (240 CDB) * 7 * ABP5140 - Bus-Master ISA PnP (16 CDB) * ** 8 * ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) *** 9 * 10 * Single Channel Products: 11 * ABP542 - Bus-Master ISA with floppy (240 CDB) 12 * ABP842 - Bus-Master VL (240 CDB) 13 * 14 * Dual Channel Products: 15 * ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel) 16 * 17 * * This board has been shipped by HP with the 4020i CD-R drive. 18 * The board has no BIOS so it cannot control a boot device, but 19 * it can control any secondary SCSI device. 20 * ** This board has been sold by SIIG as the i540 SpeedMaster. 21 * *** This board has been sold by SIIG as the i542 SpeedMaster. 22 * 23 * Copyright (c) 1996, 1997 Justin T. Gibbs. 24 * All rights reserved. 25 * 26 * Redistribution and use in source and binary forms, with or without 27 * modification, are permitted provided that the following conditions 28 * are met: 29 * 1. Redistributions of source code must retain the above copyright 30 * notice, this list of conditions, and the following disclaimer, 31 * without modification, immediately at the beginning of the file. 32 * 2. The name of the author may not be used to endorse or promote products 33 * derived from this software without specific prior written permission. 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 38 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 39 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 45 * SUCH DAMAGE. 46 *
|
47 * $FreeBSD: head/sys/dev/advansys/adv_isa.c 109536 2003-01-19 15:13:41Z mike $
|
47 * $FreeBSD: head/sys/dev/advansys/adv_isa.c 112782 2003-03-29 09:46:10Z mdodd $ |
48 */ 49 50#include <sys/param.h> 51#include <sys/systm.h> 52#include <sys/kernel.h> 53 54#include <machine/bus_pio.h> 55#include <machine/bus.h> 56#include <machine/resource.h> 57#include <sys/bus.h> 58#include <sys/rman.h> 59 60#include <isa/isavar.h> 61 62#include <dev/advansys/advansys.h> 63 64#include <cam/scsi/scsi_all.h> 65 66#define ADV_ISA_MAX_DMA_ADDR (0x00FFFFFFL) 67#define ADV_ISA_MAX_DMA_COUNT (0x00FFFFFFL) 68 69#define ADV_VL_MAX_DMA_ADDR (0x07FFFFFFL) 70#define ADV_VL_MAX_DMA_COUNT (0x07FFFFFFL) 71 72/* 73 * The overrun buffer shared amongst all ISA/VL adapters. 74 */ 75static u_int8_t* overrun_buf; 76static bus_dma_tag_t overrun_dmat; 77static bus_dmamap_t overrun_dmamap; 78static bus_addr_t overrun_physbase; 79 80/* Possible port addresses an ISA or VL adapter can live at */ 81static u_int16_t adv_isa_ioports[] = 82{ 83 0x100, 84 0x110, /* First selection in BIOS setup */ 85 0x120, 86 0x130, /* Second selection in BIOS setup */ 87 0x140, 88 0x150, /* Third selection in BIOS setup */ 89 0x190, /* Fourth selection in BIOS setup */ 90 0x210, /* Fifth selection in BIOS setup */ 91 0x230, /* Sixth selection in BIOS setup */ 92 0x250, /* Seventh selection in BIOS setup */ 93 0x330 /* Eighth and default selection in BIOS setup */ 94}; 95 96#define MAX_ISA_IOPORT_INDEX (sizeof(adv_isa_ioports)/sizeof(u_int16_t) - 1) 97 98static int adv_isa_probe(device_t dev); 99static int adv_isa_attach(device_t dev); 100static void adv_set_isapnp_wait_for_key(void); 101static int adv_get_isa_dma_channel(struct adv_softc *adv); 102static int adv_set_isa_dma_settings(struct adv_softc *adv); 103 104static int 105adv_isa_probe(device_t dev) 106{ 107 int port_index; 108 int max_port_index; 109 u_long iobase, iocount, irq; 110 int user_iobase = 0; 111 int rid = 0; 112 void *ih; 113 struct resource *iores, *irqres; 114 115 /* 116 * Default to scanning all possible device locations. 117 */ 118 port_index = 0; 119 max_port_index = MAX_ISA_IOPORT_INDEX; 120 121 if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, &iocount) == 0) { 122 user_iobase = 1; 123 for (;port_index <= max_port_index; port_index++) 124 if (iobase <= adv_isa_ioports[port_index]) 125 break; 126 if ((port_index > max_port_index) 127 || (iobase != adv_isa_ioports[port_index])) { 128 if (bootverbose) 129 printf("adv%d: Invalid baseport of 0x%lx specified. " 130 "Nearest valid baseport is 0x%x. Failing " 131 "probe.\n", device_get_unit(dev), iobase, 132 (port_index <= max_port_index) ? 133 adv_isa_ioports[port_index] : 134 adv_isa_ioports[max_port_index]); 135 return ENXIO; 136 } 137 max_port_index = port_index; 138 } 139 140 /* Perform the actual probing */ 141 adv_set_isapnp_wait_for_key(); 142 for (;port_index <= max_port_index; port_index++) { 143 u_int16_t port_addr = adv_isa_ioports[port_index]; 144 bus_size_t maxsegsz; 145 bus_size_t maxsize; 146 bus_addr_t lowaddr; 147 int error; 148 struct adv_softc *adv; 149 150 if (port_addr == 0) 151 /* Already been attached */ 152 continue; 153 154 if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port_addr, 1)) 155 continue; 156 157 /* XXX what is the real portsize? */ 158 iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, 159 RF_ACTIVE); 160 if (iores == NULL) 161 continue; 162 163 if (adv_find_signature(rman_get_bustag(iores), 164 rman_get_bushandle(iores)) == 0) { 165 bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); 166 continue; 167 } 168 169 /* 170 * Got one. Now allocate our softc 171 * and see if we can initialize the card. 172 */ 173 adv = adv_alloc(dev, rman_get_bustag(iores), 174 rman_get_bushandle(iores)); 175 if (adv == NULL) { 176 bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); 177 break; 178 } 179 180 /* 181 * Stop the chip. 182 */ 183 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); 184 ADV_OUTW(adv, ADV_CHIP_STATUS, 0); 185 /* 186 * Determine the chip version. 187 */ 188 adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION); 189 if ((adv->chip_version >= ADV_CHIP_MIN_VER_VL) 190 && (adv->chip_version <= ADV_CHIP_MAX_VER_VL)) { 191 adv->type = ADV_VL; 192 maxsegsz = ADV_VL_MAX_DMA_COUNT; 193 maxsize = BUS_SPACE_MAXSIZE_32BIT; 194 lowaddr = ADV_VL_MAX_DMA_ADDR; 195 bus_delete_resource(dev, SYS_RES_DRQ, 0); 196 } else if ((adv->chip_version >= ADV_CHIP_MIN_VER_ISA) 197 && (adv->chip_version <= ADV_CHIP_MAX_VER_ISA)) { 198 if (adv->chip_version >= ADV_CHIP_MIN_VER_ISA_PNP) { 199 adv->type = ADV_ISAPNP; 200 ADV_OUTB(adv, ADV_REG_IFC, 201 ADV_IFC_INIT_DEFAULT); 202 } else { 203 adv->type = ADV_ISA; 204 } 205 maxsegsz = ADV_ISA_MAX_DMA_COUNT; 206 maxsize = BUS_SPACE_MAXSIZE_24BIT; 207 lowaddr = ADV_ISA_MAX_DMA_ADDR; 208 adv->isa_dma_speed = ADV_DEF_ISA_DMA_SPEED; 209 adv->isa_dma_channel = adv_get_isa_dma_channel(adv); 210 bus_set_resource(dev, SYS_RES_DRQ, 0, 211 adv->isa_dma_channel, 1); 212 } else { 213 panic("advisaprobe: Unknown card revision\n"); 214 } 215 216 /* 217 * Allocate a parent dmatag for all tags created 218 * by the MI portions of the advansys driver 219 */ 220 /* XXX Should be a child of the ISA bus dma tag */
|
221 error = bus_dma_tag_create(/*parent*/NULL,
222 /*alignemnt*/1,
223 /*boundary*/0,
224 lowaddr,
225 /*highaddr*/BUS_SPACE_MAXADDR,
226 /*filter*/NULL,
227 /*filterarg*/NULL,
228 maxsize,
229 /*nsegs*/~0,
230 maxsegsz,
231 /*flags*/0,
232 &adv->parent_dmat);
|
221 error = bus_dma_tag_create( 222 /* parent */ NULL, 223 /* alignemnt */ 1, 224 /* boundary */ 0, 225 /* lowaddr */ lowaddr, 226 /* highaddr */ BUS_SPACE_MAXADDR, 227 /* filter */ NULL, 228 /* filterarg */ NULL, 229 /* maxsize */ maxsize, 230 /* nsegments */ ~0, 231 /* maxsegsz */ maxsegsz, 232 /* flags */ 0, 233 &adv->parent_dmat); |
234 235 if (error != 0) { 236 printf("%s: Could not allocate DMA tag - error %d\n", 237 adv_name(adv), error); 238 adv_free(adv); 239 bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); 240 break; 241 } 242 243 adv->init_level += 2; 244 245 if (overrun_buf == NULL) { 246 /* Need to allocate our overrun buffer */
|
246 if (bus_dma_tag_create(adv->parent_dmat,
247 /*alignment*/8,
248 /*boundary*/0,
249 ADV_ISA_MAX_DMA_ADDR,
250 BUS_SPACE_MAXADDR,
251 /*filter*/NULL,
252 /*filterarg*/NULL,
253 ADV_OVERRUN_BSIZE,
254 /*nsegments*/1,
255 BUS_SPACE_MAXSIZE_32BIT,
256 /*flags*/0,
257 &overrun_dmat) != 0) {
|
247 if (bus_dma_tag_create( 248 /* parent */ adv->parent_dmat, 249 /* alignment */ 8, 250 /* boundary */ 0, 251 /* lowaddr */ ADV_ISA_MAX_DMA_ADDR, 252 /* highaddr */ BUS_SPACE_MAXADDR, 253 /* filter */ NULL, 254 /* filterarg */ NULL, 255 /* maxsize */ ADV_OVERRUN_BSIZE, 256 /* nsegments */ 1, 257 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 258 /* flags */ 0, 259 &overrun_dmat) != 0) { |
260 adv_free(adv); 261 bus_release_resource(dev, SYS_RES_IOPORT, 0, 262 iores); 263 break; 264 } 265 if (bus_dmamem_alloc(overrun_dmat, 266 (void **)&overrun_buf, 267 BUS_DMA_NOWAIT, 268 &overrun_dmamap) != 0) { 269 bus_dma_tag_destroy(overrun_dmat); 270 adv_free(adv); 271 bus_release_resource(dev, SYS_RES_IOPORT, 0, 272 iores); 273 break; 274 } 275 /* And permanently map it in */ 276 bus_dmamap_load(overrun_dmat, overrun_dmamap, 277 overrun_buf, ADV_OVERRUN_BSIZE, 278 adv_map, &overrun_physbase, 279 /*flags*/0); 280 } 281 282 adv->overrun_physbase = overrun_physbase; 283 284 if (adv_init(adv) != 0) { 285 bus_dmamap_unload(overrun_dmat, overrun_dmamap); 286 bus_dmamem_free(overrun_dmat, overrun_buf, 287 overrun_dmamap); 288 bus_dma_tag_destroy(overrun_dmat); 289 adv_free(adv); 290 bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); 291 break; 292 } 293 294 switch (adv->type) { 295 case ADV_ISAPNP: 296 if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG) { 297 adv->bug_fix_control 298 |= ADV_BUG_FIX_ASYN_USE_SYN; 299 adv->fix_asyn_xfer = ~0; 300 } 301 /* Fall Through */ 302 case ADV_ISA: 303 adv->max_dma_count = ADV_ISA_MAX_DMA_COUNT; 304 adv->max_dma_addr = ADV_ISA_MAX_DMA_ADDR; 305 adv_set_isa_dma_settings(adv); 306 break; 307 308 case ADV_VL: 309 adv->max_dma_count = ADV_VL_MAX_DMA_COUNT; 310 adv->max_dma_addr = ADV_VL_MAX_DMA_ADDR; 311 break; 312 default: 313 panic("advisaprobe: Invalid card type\n"); 314 } 315 316 /* Determine our IRQ */ 317 if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL)) 318 bus_set_resource(dev, SYS_RES_IRQ, 0, 319 adv_get_chip_irq(adv), 1); 320 else 321 adv_set_chip_irq(adv, irq); 322 323 irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 324 RF_ACTIVE); 325 if (irqres == NULL || 326 bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY, 327 adv_intr, adv, &ih)) { 328 bus_dmamap_unload(overrun_dmat, overrun_dmamap); 329 bus_dmamem_free(overrun_dmat, overrun_buf, 330 overrun_dmamap); 331 bus_dma_tag_destroy(overrun_dmat); 332 adv_free(adv); 333 bus_release_resource(dev, SYS_RES_IOPORT, 0, iores); 334 break; 335 } 336 337 /* Mark as probed */ 338 adv_isa_ioports[port_index] = 0; 339 return 0; 340 } 341 342 if (user_iobase) 343 bus_set_resource(dev, SYS_RES_IOPORT, 0, iobase, iocount); 344 else 345 bus_delete_resource(dev, SYS_RES_IOPORT, 0); 346 347 return ENXIO; 348} 349 350static int 351adv_isa_attach(device_t dev) 352{ 353 struct adv_softc *adv = device_get_softc(dev); 354 355 return (adv_attach(adv)); 356} 357 358static int 359adv_get_isa_dma_channel(struct adv_softc *adv) 360{ 361 int channel; 362 363 channel = ADV_INW(adv, ADV_CONFIG_LSW) & ADV_CFG_LSW_ISA_DMA_CHANNEL; 364 if (channel == 0x03) 365 return (0); 366 else if (channel == 0x00) 367 return (7); 368 return (channel + 4); 369} 370 371static int 372adv_set_isa_dma_settings(struct adv_softc *adv) 373{ 374 u_int16_t cfg_lsw; 375 u_int8_t value; 376 377 if ((adv->isa_dma_channel >= 5) && (adv->isa_dma_channel <= 7)) { 378 if (adv->isa_dma_channel == 7) 379 value = 0x00; 380 else 381 value = adv->isa_dma_channel - 4; 382 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) 383 & ~ADV_CFG_LSW_ISA_DMA_CHANNEL; 384 cfg_lsw |= value; 385 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw); 386 387 adv->isa_dma_speed &= 0x07; 388 adv_set_bank(adv, 1); 389 ADV_OUTB(adv, ADV_DMA_SPEED, adv->isa_dma_speed); 390 adv_set_bank(adv, 0); 391 isa_dmacascade(adv->isa_dma_channel); 392 } 393 return (0); 394} 395 396static void 397adv_set_isapnp_wait_for_key(void) 398{ 399 static int isapnp_wait_set = 0; 400 if (isapnp_wait_set == 0) { 401 outb(ADV_ISA_PNP_PORT_ADDR, 0x02); 402 outb(ADV_ISA_PNP_PORT_WRITE, 0x02); 403 isapnp_wait_set++; 404 } 405} 406 407static device_method_t adv_isa_methods[] = { 408 /* Device interface */ 409 DEVMETHOD(device_probe, adv_isa_probe), 410 DEVMETHOD(device_attach, adv_isa_attach), 411 { 0, 0 } 412}; 413 414static driver_t adv_isa_driver = { 415 "adv", adv_isa_methods, sizeof(struct adv_softc) 416}; 417 418static devclass_t adv_isa_devclass; 419DRIVER_MODULE(adv, isa, adv_isa_driver, adv_isa_devclass, 0, 0);
|