aha_isa.c revision 42887
1122394Sharti/* 2122394Sharti * Product specific probe and attach routines for: 3122394Sharti * Adaptec 154x. 4122394Sharti * 5163820Sharti * Derived from code written by: 6163820Sharti * 7163820Sharti * Copyright (c) 1998 Justin T. Gibbs 8122394Sharti * All rights reserved. 9122394Sharti * 10133211Sharti * Redistribution and use in source and binary forms, with or without 11133211Sharti * modification, are permitted provided that the following conditions 12133211Sharti * are met: 13133211Sharti * 1. Redistributions of source code must retain the above copyright 14133211Sharti * notice, this list of conditions, and the following disclaimer, 15133211Sharti * without modification, immediately at the beginning of the file. 16122394Sharti * 2. The name of the author may not be used to endorse or promote products 17122394Sharti * derived from this software without specific prior written permission. 18122394Sharti * 19133211Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20133211Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21133211Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22133211Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23133211Sharti * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24133211Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25133211Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26133211Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27133211Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28133211Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29133211Sharti * SUCH DAMAGE. 30133211Sharti * 31122394Sharti * $Id: aha_isa.c,v 1.5 1998/11/10 06:44:54 gibbs Exp $ 32163820Sharti */ 33122394Sharti 34122394Sharti#include "pnp.h" 35122394Sharti 36122394Sharti#include <sys/param.h> 37216294Ssyrinx#include <sys/systm.h> 38122394Sharti#include <sys/kernel.h> 39122394Sharti 40163820Sharti#include <machine/bus_pio.h> 41122394Sharti#include <machine/bus.h> 42122394Sharti 43122394Sharti#include <i386/isa/isa_device.h> 44122394Sharti#include <dev/aha/ahareg.h> 45122394Sharti 46216294Ssyrinx#include <cam/scsi/scsi_all.h> 47122394Sharti 48122394Sharti#if NPNP > 0 49122394Sharti#include <i386/isa/pnp.h> 50122394Sharti#endif 51122394Sharti 52122394Shartistatic int aha_isa_probe(struct isa_device *dev); 53122394Shartistatic int aha_isa_attach(struct isa_device *dev); 54122394Shartistatic void aha_isa_intr(void *unit); 55122394Sharti 56122394Shartistruct isa_driver ahadriver = 57163820Sharti{ 58163820Sharti aha_isa_probe, 59163820Sharti aha_isa_attach, 60163820Sharti "aha" 61163820Sharti}; 62122394Sharti 63122394Sharti/* 64122394Sharti * Check if the device can be found at the port given 65122394Sharti * and if so, set it up ready for further work 66122394Sharti * as an argument, takes the isa_device structure from 67122394Sharti * autoconf.c 68122394Sharti */ 69122394Shartistatic int 70122394Shartiaha_isa_probe(dev) 71122394Sharti struct isa_device *dev; 72122394Sharti{ 73122394Sharti /* 74122394Sharti * find unit and check we have that many defined 75122394Sharti */ 76122394Sharti struct aha_softc *aha; 77122394Sharti int port_index; 78122394Sharti int max_port_index; 79122394Sharti 80122394Sharti aha = NULL; 81122394Sharti 82122394Sharti /* 83122394Sharti * Bound our board search if the user has 84122394Sharti * specified an exact port. 85122394Sharti */ 86122394Sharti aha_find_probe_range(dev->id_iobase, &port_index, &max_port_index); 87122394Sharti 88122394Sharti if (port_index < 0) 89122394Sharti return 0; 90122394Sharti 91122394Sharti /* Attempt to find an adapter */ 92122394Sharti for (;port_index <= max_port_index; port_index++) { 93122394Sharti config_data_t config_data; 94122394Sharti u_int ioport; 95122394Sharti int error; 96122394Sharti 97122394Sharti ioport = aha_iop_from_bio(port_index); 98122394Sharti 99122394Sharti /* 100122394Sharti * Ensure this port has not already been claimed already 101122394Sharti * by a PCI, EISA or ISA adapter. 102122394Sharti */ 103122394Sharti if (aha_check_probed_iop(ioport) != 0) 104122394Sharti continue; 105122394Sharti dev->id_iobase = ioport; 106122394Sharti if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET)) 107122394Sharti continue; 108122394Sharti 109122394Sharti /* Allocate a softc for use during probing */ 110122394Sharti aha = aha_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport); 111122394Sharti 112122394Sharti if (aha == NULL) 113122394Sharti break; 114163820Sharti 115163820Sharti /* We're going to attempt to probe it now, so mark it probed */ 116122394Sharti aha_mark_probed_bio(port_index); 117163820Sharti 118163820Sharti /* See if there is really a card present */ 119163820Sharti if (aha_probe(aha) || aha_fetch_adapter_info(aha)) { 120163820Sharti aha_free(aha); 121122394Sharti continue; 122163820Sharti } 123122394Sharti 124122394Sharti /* 125163820Sharti * Determine our IRQ, and DMA settings and 126163820Sharti * export them to the configuration system. 127122394Sharti */ 128163820Sharti error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 129163820Sharti (u_int8_t*)&config_data, sizeof(config_data), 130122394Sharti DEFAULT_CMD_TIMEOUT); 131163820Sharti if (error != 0) { 132163820Sharti printf("aha_isa_probe: Could not determine IRQ or DMA " 133163820Sharti "settings for adapter at 0x%x. Failing probe\n", 134163820Sharti ioport); 135122394Sharti aha_free(aha); 136163820Sharti continue; 137163820Sharti } 138163820Sharti 139163820Sharti switch (config_data.dma_chan) { 140163820Sharti case DMA_CHAN_5: 141163820Sharti dev->id_drq = 5; 142122394Sharti break; 143163820Sharti case DMA_CHAN_6: 144163820Sharti dev->id_drq = 6; 145163820Sharti break; 146163820Sharti case DMA_CHAN_7: 147163820Sharti dev->id_drq = 7; 148163820Sharti break; 149163820Sharti default: 150163820Sharti printf("aha_isa_probe: Invalid DMA setting " 151163820Sharti "detected for adapter at 0x%x. " 152163820Sharti "Failing probe\n", ioport); 153163820Sharti return (0); 154163820Sharti } 155163820Sharti dev->id_irq = (config_data.irq << 9); 156163820Sharti dev->id_intr = aha_isa_intr; 157163820Sharti aha_unit++; 158163820Sharti return (AHA_NREGS); 159163820Sharti } 160163820Sharti 161163820Sharti return (0); 162163820Sharti} 163163820Sharti 164122394Sharti/* 165122394Sharti * Attach all the sub-devices we can find 166122394Sharti */ 167216294Ssyrinxstatic int 168216294Ssyrinxaha_isa_attach(dev) 169216294Ssyrinx struct isa_device *dev; 170216294Ssyrinx{ 171216294Ssyrinx struct aha_softc *aha; 172216294Ssyrinx bus_dma_filter_t *filter; 173216294Ssyrinx void *filter_arg; 174122394Sharti bus_addr_t lowaddr; 175216294Ssyrinx 176216294Ssyrinx aha = aha_softcs[dev->id_unit]; 177216294Ssyrinx if (dev->id_drq != -1) 178122394Sharti isa_dmacascade(dev->id_drq); 179216294Ssyrinx 180216294Ssyrinx /* Allocate our parent dmatag */ 181216294Ssyrinx filter = NULL; 182216294Ssyrinx filter_arg = NULL; 183216294Ssyrinx lowaddr = BUS_SPACE_MAXADDR_24BIT; 184216294Ssyrinx 185216294Ssyrinx if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0, 186216294Ssyrinx lowaddr, /*highaddr*/BUS_SPACE_MAXADDR, 187216294Ssyrinx filter, filter_arg, 188216294Ssyrinx /*maxsize*/BUS_SPACE_MAXSIZE_24BIT, 189216294Ssyrinx /*nsegments*/BUS_SPACE_UNRESTRICTED, 190216294Ssyrinx /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT, 191216294Ssyrinx /*flags*/0, &aha->parent_dmat) != 0) { 192216294Ssyrinx aha_free(aha); 193216294Ssyrinx return (-1); 194216294Ssyrinx } 195216294Ssyrinx 196216294Ssyrinx if (aha_init(aha)) { 197216294Ssyrinx printf("aha init failed\n"); 198216294Ssyrinx aha_free(aha); 199216294Ssyrinx return (-1); 200216294Ssyrinx } 201216294Ssyrinx 202216294Ssyrinx return (aha_attach(aha)); 203216294Ssyrinx} 204216294Ssyrinx 205216294Ssyrinx/* 206216294Ssyrinx * Handle an ISA interrupt. 207216294Ssyrinx * XXX should go away as soon as ISA interrupt handlers 208216294Ssyrinx * take a (void *) arg. 209216294Ssyrinx */ 210216294Ssyrinxstatic void 211216294Ssyrinxaha_isa_intr(void *unit) 212216294Ssyrinx{ 213216294Ssyrinx struct aha_softc* arg = aha_softcs[(int)unit]; 214216294Ssyrinx aha_intr((void *)arg); 215216294Ssyrinx} 216216294Ssyrinx 217216294Ssyrinx/* 218216294Ssyrinx * support PnP cards if we are using 'em 219216294Ssyrinx */ 220216294Ssyrinx 221216294Ssyrinx#if NPNP > 0 222216294Ssyrinx 223216294Ssyrinxstatic char *ahapnp_probe(u_long csn, u_long vend_id); 224216294Ssyrinxstatic void ahapnp_attach(u_long csn, u_long vend_id, char *name, 225216294Ssyrinx struct isa_device *dev); 226216294Ssyrinxstatic u_long nahapnp = NAHA; 227216294Ssyrinx 228216294Ssyrinxstatic struct pnp_device ahapnp = { 229216294Ssyrinx "ahapnp", 230216294Ssyrinx ahapnp_probe, 231216294Ssyrinx ahapnp_attach, 232216294Ssyrinx &nahapnp, 233216294Ssyrinx &bio_imask 234216294Ssyrinx}; 235216294SsyrinxDATA_SET (pnpdevice_set, ahapnp); 236216294Ssyrinx 237216294Ssyrinxstatic char * 238216294Ssyrinxahapnp_probe(u_long csn, u_long vend_id) 239216294Ssyrinx{ 240216294Ssyrinx struct pnp_cinfo d; 241216294Ssyrinx char *s = NULL; 242216294Ssyrinx 243216294Ssyrinx if (vend_id != AHA1542_PNP && vend_id != AHA1542_PNPCOMPAT) 244216294Ssyrinx return (NULL); 245122394Sharti 246122394Sharti read_pnp_parms(&d, 0); 247122394Sharti if (d.enable == 0 || d.flags & 1) { 248122394Sharti printf("CSN %lu is disabled.\n", csn); 249122394Sharti return (NULL); 250122394Sharti } 251122394Sharti s = "Adaptec 1542CP"; 252122394Sharti 253122394Sharti return (s); 254122394Sharti} 255122394Sharti 256122394Shartistatic void 257122394Shartiahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) 258122394Sharti{ 259122394Sharti struct pnp_cinfo d; 260122394Sharti struct isa_device *dvp; 261122394Sharti 262122394Sharti if (dev->id_unit >= NAHATOT) 263122394Sharti return; 264122394Sharti 265122394Sharti if (read_pnp_parms(&d, 0) == 0) { 266122394Sharti printf("failed to read pnp parms\n"); 267122394Sharti return; 268122394Sharti } 269122394Sharti 270122394Sharti write_pnp_parms(&d, 0); 271122394Sharti 272122394Sharti enable_pnp_card(); 273122394Sharti 274122394Sharti dev->id_iobase = d.port[0]; 275122394Sharti dev->id_irq = (1 << d.irq[0]); 276122394Sharti dev->id_intr = aha_intr; 277122394Sharti dev->id_drq = d.drq[0]; 278122394Sharti 279122394Sharti if (dev->id_driver == NULL) { 280122394Sharti dev->id_driver = &ahadriver; 281122394Sharti dvp = find_isadev(isa_devtab_tty, &ahadriver, 0); 282122394Sharti if (dvp != NULL) 283122394Sharti dev->id_id = dvp->id_id; 284122394Sharti } 285122394Sharti 286122394Sharti if ((dev->id_alive = aha_isa_probe(dev)) != 0) 287122394Sharti aha_isa_attach(dev); 288122394Sharti else 289122394Sharti printf("aha%d: probe failed\n", dev->id_unit); 290122394Sharti} 291122394Sharti#endif 292122394Sharti