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