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