1 /* $NetBSD: asc.c,v 1.11 2002/10/02 03:31:59 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Richard Earnshaw 5 * All rights reserved. 6 * 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. The name of the company nor the name of the author may be used to 13 * endorse or promote products derived from this software without specific 14 * prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 * 29 * Copyright (c) 1996 Mark Brinicombe 30 * Copyright (c) 1982, 1990 The Regents of the University of California. 31 * All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. All advertising materials mentioning features or use of this software 42 * must display the following acknowledgement: 43 * This product includes software developed by the University of 44 * California, Berkeley and its contributors. 45 * 4. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 * 61 * from:ahsc.c 62 */ 63 64 /* 65 * Driver for the Acorn SCSI card using the SBIC (WD33C93A) generic driver 66 * 67 * Thanks to Acorn for supplying programming information on this card. 68 */ 69 70 /* #define ASC_DMAMAP_DEBUG */ 71 /* #define DEBUG */ 72 73 #include "opt_ddb.h" 74 75 #include <sys/param.h> 76 77 __KERNEL_RCSID(0, "$NetBSD: asc.c,v 1.11 2002/10/02 03:31:59 thorpej Exp $"); 78 79 #include <sys/systm.h> 80 #include <sys/kernel.h> 81 #include <sys/device.h> 82 #include <sys/buf.h> 83 84 #include <uvm/uvm_extern.h> 85 86 #include <machine/bus.h> 87 #include <machine/intr.h> 88 #include <machine/bootconfig.h> /* asc_poll */ 89 90 #include <dev/scsipi/scsi_all.h> 91 #include <dev/scsipi/scsipi_all.h> 92 #include <dev/scsipi/scsiconf.h> 93 94 #include <arm/arm32/katelib.h> 95 96 #include <dev/podulebus/podules.h> 97 #include <dev/podulebus/powerromreg.h> 98 99 #include <acorn32/podulebus/podulebus.h> 100 #include <acorn32/podulebus/sbicreg.h> 101 #include <acorn32/podulebus/sbicvar.h> 102 #include <acorn32/podulebus/ascreg.h> 103 #include <acorn32/podulebus/ascvar.h> 104 105 void ascattach (struct device *, struct device *, void *); 106 int ascmatch (struct device *, struct cfdata *, void *); 107 108 void asc_enintr (struct sbic_softc *); 109 110 int asc_dmaok (void *, bus_dma_tag_t, struct sbic_acb *); 111 int asc_dmasetup (void *, bus_dma_tag_t, struct sbic_acb *, int); 112 int asc_dmanext (void *, bus_dma_tag_t, struct sbic_acb *, int); 113 void asc_dmastop (void *, bus_dma_tag_t, struct sbic_acb *); 114 void asc_dmafinish (void *, bus_dma_tag_t, struct sbic_acb *); 115 116 int asc_intr (void *); 117 void asc_minphys (struct buf *); 118 119 void asc_dump (void); 120 121 #ifdef DEBUG 122 int asc_dmadebug = 0; 123 #endif 124 125 CFATTACH_DECL(asc, sizeof(struct asc_softc), 126 ascmatch, ascattach, NULL, NULL); 127 128 extern struct cfdriver asc_cd; 129 130 u_long scsi_nosync; 131 int shift_nosync; 132 133 #if ASC_POLL > 0 134 int asc_poll = 0; 135 136 #endif 137 138 int 139 ascmatch(struct device *pdp, struct cfdata *cf, void *auxp) 140 { 141 struct podule_attach_args *pa = (struct podule_attach_args *)auxp; 142 143 /* Look for the card */ 144 145 /* Standard ROM, skipping the MCS card that used the same ID. */ 146 if (pa->pa_product == PODULE_ACORN_SCSI && 147 strncmp(pa->pa_podule->description, "MCS", 3) != 0) 148 return 1; 149 150 /* PowerROM */ 151 if (pa->pa_product == PODULE_ALSYSTEMS_SCSI && 152 podulebus_initloader(pa) == 0 && 153 podloader_callloader(pa, 0, 0) == PRID_ACORN_SCSI1) 154 return 1; 155 156 return 0; 157 } 158 159 void 160 ascattach(struct device *pdp, struct device *dp, void *auxp) 161 { 162 /* volatile struct sdmac *rp;*/ 163 struct asc_softc *sc; 164 struct sbic_softc *sbic; 165 struct podule_attach_args *pa; 166 167 sc = (struct asc_softc *)dp; 168 pa = (struct podule_attach_args *)auxp; 169 170 if (pa->pa_podule_number == -1) 171 panic("Podule has disappeared !"); 172 173 sc->sc_podule_number = pa->pa_podule_number; 174 sc->sc_podule = pa->pa_podule; 175 podules[sc->sc_podule_number].attached = 1; 176 177 sbic = &sc->sc_softc; 178 179 sbic->sc_enintr = asc_enintr; 180 sbic->sc_dmaok = asc_dmaok; 181 sbic->sc_dmasetup = asc_dmasetup; 182 sbic->sc_dmanext = asc_dmanext; 183 sbic->sc_dmastop = asc_dmastop; 184 sbic->sc_dmafinish = asc_dmafinish; 185 186 /* Map sbic */ 187 sbic->sc_sbicp.sc_sbiciot = pa->pa_iot; 188 if (bus_space_map (sbic->sc_sbicp.sc_sbiciot, 189 sc->sc_podule->mod_base + ASC_SBIC, ASC_SBIC_SPACE, 0, 190 &sbic->sc_sbicp.sc_sbicioh)) 191 panic("%s: Cannot map SBIC", dp->dv_xname); 192 193 sbic->sc_clkfreq = sbic_clock_override ? sbic_clock_override : 143; 194 195 sbic->sc_adapter.adapt_dev = &sbic->sc_dev; 196 sbic->sc_adapter.adapt_nchannels = 1; 197 sbic->sc_adapter.adapt_openings = 7; 198 sbic->sc_adapter.adapt_max_periph = 1; 199 sbic->sc_adapter.adapt_ioctl = NULL; 200 sbic->sc_adapter.adapt_minphys = asc_minphys; 201 sbic->sc_adapter.adapt_request = sbic_scsi_request; 202 203 sbic->sc_channel.chan_adapter = &sbic->sc_adapter; 204 sbic->sc_channel.chan_bustype = &scsi_bustype; 205 sbic->sc_channel.chan_channel = 0; 206 sbic->sc_channel.chan_ntargets = 8; 207 sbic->sc_channel.chan_nluns = 8; 208 sbic->sc_channel.chan_id = 7; 209 210 /* Provide an override for the host id */ 211 (void)get_bootconf_option(boot_args, "asc.hostid", 212 BOOTOPT_TYPE_INT, &sbic->sc_channel.chan_id); 213 214 printf(": hostid=%d", sbic->sc_channel.chan_id); 215 216 #if ASC_POLL > 0 217 if (boot_args) 218 get_bootconf_option(boot_args, "ascpoll", BOOTOPT_TYPE_BOOLEAN, 219 &asc_poll); 220 221 if (asc_poll) { 222 sbic->sc_adapter.adapt_flags |= SCSIPI_ADAPT_POLL_ONLY; 223 printf(" polling"); 224 } 225 #endif 226 printf("\n"); 227 228 sc->sc_pagereg = sc->sc_podule->fast_base + ASC_PAGEREG; 229 sc->sc_intstat = sc->sc_podule->fast_base + ASC_INTSTATUS; 230 231 /* Reset the card */ 232 233 WriteByte(sc->sc_pagereg, 0x80); 234 DELAY(500000); 235 WriteByte(sc->sc_pagereg, 0x00); 236 DELAY(250000); 237 238 sbicinit(sbic); 239 240 /* If we are polling only, we don't need a interrupt handler. */ 241 242 #ifdef ASC_POLL 243 if (!asc_poll) 244 #endif 245 { 246 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, 247 dp->dv_xname, "intr"); 248 sc->sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO, 249 asc_intr, sc, &sc->sc_intrcnt); 250 if (sc->sc_ih == NULL) 251 panic("%s: Cannot claim podule IRQ", dp->dv_xname); 252 } 253 254 /* 255 * attach all scsi units on us 256 */ 257 config_found(dp, &sbic->sc_channel, scsiprint); 258 } 259 260 261 void 262 asc_enintr(struct sbic_softc *sbicsc) 263 { 264 struct asc_softc *sc = (struct asc_softc *)sbicsc; 265 266 sbicsc->sc_flags |= SBICF_INTR; 267 WriteByte(sc->sc_pagereg, 0x40); 268 } 269 270 int 271 asc_dmaok (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 272 { 273 return 0; 274 } 275 276 int 277 asc_dmasetup (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb, int dir) 278 { 279 printf("asc_dmasetup()"); 280 #ifdef DDB 281 Debugger(); 282 #else 283 panic("Hit a brick wall"); 284 #endif 285 return 0; 286 } 287 288 int 289 asc_dmanext (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb, int dir) 290 { 291 printf("asc_dmanext()"); 292 #ifdef DDB 293 Debugger(); 294 #else 295 panic("Hit a brick wall"); 296 #endif 297 return 0; 298 } 299 300 void 301 asc_dmastop (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 302 { 303 printf("asc_dmastop\n"); 304 } 305 306 void 307 asc_dmafinish (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 308 { 309 printf("asc_dmafinish\n"); 310 } 311 312 void 313 asc_dump(void) 314 { 315 int i; 316 317 for (i = 0; i < asc_cd.cd_ndevs; ++i) 318 if (asc_cd.cd_devs[i]) 319 sbic_dump(asc_cd.cd_devs[i]); 320 } 321 322 int 323 asc_intr(void *arg) 324 { 325 struct asc_softc *sc = arg; 326 int intr; 327 328 /* printf("ascintr:");*/ 329 intr = ReadByte(sc->sc_intstat); 330 /* printf("%02x\n", intr);*/ 331 332 if (intr & IS_SBIC_IRQ) 333 sbicintr((struct sbic_softc *)sc); 334 335 return 0; /* Pass interrupt on down the chain */ 336 } 337 338 /* 339 * limit the transfer as required. 340 */ 341 void 342 asc_minphys(struct buf *bp) 343 { 344 #if 0 345 /* 346 * We must limit the DMA xfer size 347 */ 348 if (bp->b_bcount > MAX_DMA_LEN) { 349 printf("asc: Reducing dma length\n"); 350 bp->b_bcount = MAX_DMA_LEN; 351 } 352 #endif 353 minphys(bp); 354 } 355 356