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