1 /* $NetBSD: asc.c,v 1.16 2009/05/12 06:54:10 cegger 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.16 2009/05/12 06:54:10 cegger Exp $"); 102 103 #include <sys/systm.h> 104 #include <sys/kernel.h> 105 #include <sys/device.h> 106 #include <sys/buf.h> 107 108 #include <uvm/uvm_extern.h> 109 110 #include <machine/bus.h> 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 (struct device *, struct device *, void *); 130 int ascmatch (struct device *, struct cfdata *, 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(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(struct device *pdp, struct cfdata *cf, void *auxp) 164 { 165 struct podule_attach_args *pa = (struct podule_attach_args *)auxp; 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(struct device *pdp, struct device *dp, void *auxp) 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 = (struct asc_softc *)dp; 192 pa = (struct podule_attach_args *)auxp; 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_enintr = asc_enintr; 204 sbic->sc_dmaok = asc_dmaok; 205 sbic->sc_dmasetup = asc_dmasetup; 206 sbic->sc_dmanext = asc_dmanext; 207 sbic->sc_dmastop = asc_dmastop; 208 sbic->sc_dmafinish = asc_dmafinish; 209 210 /* Map sbic */ 211 sbic->sc_sbicp.sc_sbiciot = pa->pa_iot; 212 if (bus_space_map (sbic->sc_sbicp.sc_sbiciot, 213 sc->sc_podule->mod_base + ASC_SBIC, ASC_SBIC_SPACE, 0, 214 &sbic->sc_sbicp.sc_sbicioh)) 215 panic("%s: Cannot map SBIC", dp->dv_xname); 216 217 sbic->sc_clkfreq = sbic_clock_override ? sbic_clock_override : 143; 218 219 sbic->sc_adapter.adapt_dev = &sbic->sc_dev; 220 sbic->sc_adapter.adapt_nchannels = 1; 221 sbic->sc_adapter.adapt_openings = 7; 222 sbic->sc_adapter.adapt_max_periph = 1; 223 sbic->sc_adapter.adapt_ioctl = NULL; 224 sbic->sc_adapter.adapt_minphys = asc_minphys; 225 sbic->sc_adapter.adapt_request = sbic_scsi_request; 226 227 sbic->sc_channel.chan_adapter = &sbic->sc_adapter; 228 sbic->sc_channel.chan_bustype = &scsi_bustype; 229 sbic->sc_channel.chan_channel = 0; 230 sbic->sc_channel.chan_ntargets = 8; 231 sbic->sc_channel.chan_nluns = 8; 232 sbic->sc_channel.chan_id = 7; 233 234 /* Provide an override for the host id */ 235 (void)get_bootconf_option(boot_args, "asc.hostid", 236 BOOTOPT_TYPE_INT, &sbic->sc_channel.chan_id); 237 238 printf(": hostid=%d", sbic->sc_channel.chan_id); 239 240 #if ASC_POLL > 0 241 if (boot_args) 242 get_bootconf_option(boot_args, "ascpoll", BOOTOPT_TYPE_BOOLEAN, 243 &asc_poll); 244 245 if (asc_poll) { 246 sbic->sc_adapter.adapt_flags |= SCSIPI_ADAPT_POLL_ONLY; 247 printf(" polling"); 248 } 249 #endif 250 printf("\n"); 251 252 sc->sc_pagereg = sc->sc_podule->fast_base + ASC_PAGEREG; 253 sc->sc_intstat = sc->sc_podule->fast_base + ASC_INTSTATUS; 254 255 /* Reset the card */ 256 257 WriteByte(sc->sc_pagereg, 0x80); 258 DELAY(500000); 259 WriteByte(sc->sc_pagereg, 0x00); 260 DELAY(250000); 261 262 sbicinit(sbic); 263 264 /* If we are polling only, we don't need a interrupt handler. */ 265 266 #ifdef ASC_POLL 267 if (!asc_poll) 268 #endif 269 { 270 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, 271 device_xname(dp), "intr"); 272 sc->sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO, 273 asc_intr, sc, &sc->sc_intrcnt); 274 if (sc->sc_ih == NULL) 275 panic("%s: Cannot claim podule IRQ", dp->dv_xname); 276 } 277 278 /* 279 * attach all scsi units on us 280 */ 281 config_found(dp, &sbic->sc_channel, scsiprint); 282 } 283 284 285 void 286 asc_enintr(struct sbic_softc *sbicsc) 287 { 288 struct asc_softc *sc = (struct asc_softc *)sbicsc; 289 290 sbicsc->sc_flags |= SBICF_INTR; 291 WriteByte(sc->sc_pagereg, 0x40); 292 } 293 294 int 295 asc_dmaok (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 296 { 297 return 0; 298 } 299 300 int 301 asc_dmasetup (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb, int dir) 302 { 303 printf("asc_dmasetup()"); 304 #ifdef DDB 305 Debugger(); 306 #else 307 panic("Hit a brick wall"); 308 #endif 309 return 0; 310 } 311 312 int 313 asc_dmanext (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb, int dir) 314 { 315 printf("asc_dmanext()"); 316 #ifdef DDB 317 Debugger(); 318 #else 319 panic("Hit a brick wall"); 320 #endif 321 return 0; 322 } 323 324 void 325 asc_dmastop (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 326 { 327 printf("asc_dmastop\n"); 328 } 329 330 void 331 asc_dmafinish (void *dma_h, bus_dma_tag_t dma_t, struct sbic_acb *acb) 332 { 333 printf("asc_dmafinish\n"); 334 } 335 336 void 337 asc_dump(void) 338 { 339 int i; 340 struct sbi_softc *sc; 341 342 for (i = 0; i < asc_cd.cd_ndevs; ++i) { 343 sc = device_lookup_private(&asc_cd, i); 344 if (sc != NULL) 345 sbic_dump(sc); 346 } 347 } 348 349 int 350 asc_intr(void *arg) 351 { 352 struct asc_softc *sc = arg; 353 int intr; 354 355 /* printf("ascintr:");*/ 356 intr = ReadByte(sc->sc_intstat); 357 /* printf("%02x\n", intr);*/ 358 359 if (intr & IS_SBIC_IRQ) 360 sbicintr((struct sbic_softc *)sc); 361 362 return 0; /* Pass interrupt on down the chain */ 363 } 364 365 /* 366 * limit the transfer as required. 367 */ 368 void 369 asc_minphys(struct buf *bp) 370 { 371 #if 0 372 /* 373 * We must limit the DMA xfer size 374 */ 375 if (bp->b_bcount > MAX_DMA_LEN) { 376 printf("asc: Reducing DMA length\n"); 377 bp->b_bcount = MAX_DMA_LEN; 378 } 379 #endif 380 minphys(bp); 381 } 382 383