1 /* $NetBSD: asc.c,v 1.19 2012/10/27 17:17:23 chs 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.19 2012/10/27 17:17:23 chs 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 <arm/arm32/katelib.h> 119 120 #include <dev/podulebus/podules.h> 121 #include <dev/podulebus/powerromreg.h> 122 123 #include <acorn32/podulebus/podulebus.h> 124 #include <acorn32/podulebus/sbicreg.h> 125 #include <acorn32/podulebus/sbicvar.h> 126 #include <acorn32/podulebus/ascreg.h> 127 #include <acorn32/podulebus/ascvar.h> 128 129 void ascattach (device_t, device_t, void *); 130 int ascmatch (device_t, cfdata_t, void *); 131 132 void asc_enintr (struct sbic_softc *); 133 134 int asc_dmaok (void *, bus_dma_tag_t, struct sbic_acb *); 135 int asc_dmasetup (void *, bus_dma_tag_t, struct sbic_acb *, int); 136 int asc_dmanext (void *, bus_dma_tag_t, struct sbic_acb *, int); 137 void asc_dmastop (void *, bus_dma_tag_t, struct sbic_acb *); 138 void asc_dmafinish (void *, bus_dma_tag_t, struct sbic_acb *); 139 140 int asc_intr (void *); 141 void asc_minphys (struct buf *); 142 143 void asc_dump (void); 144 145 #ifdef DEBUG 146 int asc_dmadebug = 0; 147 #endif 148 149 CFATTACH_DECL_NEW(asc, sizeof(struct asc_softc), 150 ascmatch, ascattach, NULL, NULL); 151 152 extern struct cfdriver asc_cd; 153 154 u_long scsi_nosync; 155 int shift_nosync; 156 157 #if ASC_POLL > 0 158 int asc_poll = 0; 159 160 #endif 161 162 int 163 ascmatch(device_t parent, cfdata_t cf, void *aux) 164 { 165 struct podule_attach_args *pa = aux; 166 167 /* Look for the card */ 168 169 /* Standard ROM, skipping the MCS card that used the same ID. */ 170 if (pa->pa_product == PODULE_ACORN_SCSI && 171 strncmp(pa->pa_podule->description, "MCS", 3) != 0) 172 return 1; 173 174 /* PowerROM */ 175 if (pa->pa_product == PODULE_ALSYSTEMS_SCSI && 176 podulebus_initloader(pa) == 0 && 177 podloader_callloader(pa, 0, 0) == PRID_ACORN_SCSI1) 178 return 1; 179 180 return 0; 181 } 182 183 void 184 ascattach(device_t parent, device_t self, void *aux) 185 { 186 /* volatile struct sdmac *rp;*/ 187 struct asc_softc *sc; 188 struct sbic_softc *sbic; 189 struct podule_attach_args *pa; 190 191 sc = device_private(self); 192 pa = aux; 193 194 if (pa->pa_podule_number == -1) 195 panic("Podule has disappeared !"); 196 197 sc->sc_podule_number = pa->pa_podule_number; 198 sc->sc_podule = pa->pa_podule; 199 podules[sc->sc_podule_number].attached = 1; 200 201 sbic = &sc->sc_softc; 202 203 sbic->sc_dev = self; 204 sbic->sc_enintr = asc_enintr; 205 sbic->sc_dmaok = asc_dmaok; 206 sbic->sc_dmasetup = asc_dmasetup; 207 sbic->sc_dmanext = asc_dmanext; 208 sbic->sc_dmastop = asc_dmastop; 209 sbic->sc_dmafinish = asc_dmafinish; 210 211 /* Map sbic */ 212 sbic->sc_sbicp.sc_sbiciot = pa->pa_iot; 213 if (bus_space_map (sbic->sc_sbicp.sc_sbiciot, 214 sc->sc_podule->mod_base + ASC_SBIC, ASC_SBIC_SPACE, 0, 215 &sbic->sc_sbicp.sc_sbicioh)) 216 panic("%s: Cannot map SBIC", device_xname(self)); 217 218 sbic->sc_clkfreq = sbic_clock_override ? sbic_clock_override : 143; 219 220 sbic->sc_adapter.adapt_dev = self; 221 sbic->sc_adapter.adapt_nchannels = 1; 222 sbic->sc_adapter.adapt_openings = 7; 223 sbic->sc_adapter.adapt_max_periph = 1; 224 sbic->sc_adapter.adapt_ioctl = NULL; 225 sbic->sc_adapter.adapt_minphys = asc_minphys; 226 sbic->sc_adapter.adapt_request = sbic_scsi_request; 227 228 sbic->sc_channel.chan_adapter = &sbic->sc_adapter; 229 sbic->sc_channel.chan_bustype = &scsi_bustype; 230 sbic->sc_channel.chan_channel = 0; 231 sbic->sc_channel.chan_ntargets = 8; 232 sbic->sc_channel.chan_nluns = 8; 233 sbic->sc_channel.chan_id = 7; 234 235 /* Provide an override for the host id */ 236 (void)get_bootconf_option(boot_args, "asc.hostid", 237 BOOTOPT_TYPE_INT, &sbic->sc_channel.chan_id); 238 239 printf(": hostid=%d", sbic->sc_channel.chan_id); 240 241 #if ASC_POLL > 0 242 if (boot_args) 243 get_bootconf_option(boot_args, "ascpoll", BOOTOPT_TYPE_BOOLEAN, 244 &asc_poll); 245 246 if (asc_poll) { 247 sbic->sc_adapter.adapt_flags |= SCSIPI_ADAPT_POLL_ONLY; 248 printf(" polling"); 249 } 250 #endif 251 printf("\n"); 252 253 sc->sc_pagereg = sc->sc_podule->fast_base + ASC_PAGEREG; 254 sc->sc_intstat = sc->sc_podule->fast_base + ASC_INTSTATUS; 255 256 /* Reset the card */ 257 258 WriteByte(sc->sc_pagereg, 0x80); 259 DELAY(500000); 260 WriteByte(sc->sc_pagereg, 0x00); 261 DELAY(250000); 262 263 sbicinit(sbic); 264 265 /* If we are polling only, we don't need a interrupt handler. */ 266 267 #ifdef ASC_POLL 268 if (!asc_poll) 269 #endif 270 { 271 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, 272 device_xname(self), "intr"); 273 sc->sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO, 274 asc_intr, sc, &sc->sc_intrcnt); 275 if (sc->sc_ih == NULL) 276 panic("%s: Cannot claim podule IRQ", device_xname(self)); 277 } 278 279 /* 280 * attach all scsi units on us 281 */ 282 config_found(self, &sbic->sc_channel, scsiprint); 283 } 284 285 286 void 287 asc_enintr(struct sbic_softc *sbicsc) 288 { 289 struct asc_softc *sc = (struct asc_softc *)sbicsc; 290 291 sbicsc->sc_flags |= SBICF_INTR; 292 WriteByte(sc->sc_pagereg, 0x40); 293 } 294 295 int 296 asc_dmaok (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 297 { 298 return 0; 299 } 300 301 int 302 asc_dmasetup (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb, int dir) 303 { 304 printf("asc_dmasetup()"); 305 #ifdef DDB 306 Debugger(); 307 #else 308 panic("Hit a brick wall"); 309 #endif 310 return 0; 311 } 312 313 int 314 asc_dmanext (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb, int dir) 315 { 316 printf("asc_dmanext()"); 317 #ifdef DDB 318 Debugger(); 319 #else 320 panic("Hit a brick wall"); 321 #endif 322 return 0; 323 } 324 325 void 326 asc_dmastop (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 327 { 328 printf("asc_dmastop\n"); 329 } 330 331 void 332 asc_dmafinish (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 333 { 334 printf("asc_dmafinish\n"); 335 } 336 337 void 338 asc_dump(void) 339 { 340 int i; 341 struct asc_softc *sc; 342 343 for (i = 0; i < asc_cd.cd_ndevs; ++i) { 344 sc = device_lookup_private(&asc_cd, i); 345 if (sc != NULL) 346 sbic_dump(&sc->sc_softc); 347 } 348 } 349 350 int 351 asc_intr(void *arg) 352 { 353 struct asc_softc *sc = arg; 354 int intr; 355 356 /* printf("ascintr:");*/ 357 intr = ReadByte(sc->sc_intstat); 358 /* printf("%02x\n", intr);*/ 359 360 if (intr & IS_SBIC_IRQ) 361 sbicintr((struct sbic_softc *)sc); 362 363 return 0; /* Pass interrupt on down the chain */ 364 } 365 366 /* 367 * limit the transfer as required. 368 */ 369 void 370 asc_minphys(struct buf *bp) 371 { 372 #if 0 373 /* 374 * We must limit the DMA xfer size 375 */ 376 if (bp->b_bcount > MAX_DMA_LEN) { 377 printf("asc: Reducing DMA length\n"); 378 bp->b_bcount = MAX_DMA_LEN; 379 } 380 #endif 381 minphys(bp); 382 } 383