1 1.44 chs /* $NetBSD: siop2.c,v 1.44 2019/11/10 21:16:22 chs Exp $ */ 2 1.1 is 3 1.1 is /* 4 1.1 is * Copyright (c) 1990 The Regents of the University of California. 5 1.1 is * All rights reserved. 6 1.1 is * 7 1.1 is * This code is derived from software contributed to Berkeley by 8 1.1 is * Van Jacobson of Lawrence Berkeley Laboratory. 9 1.1 is * 10 1.1 is * Redistribution and use in source and binary forms, with or without 11 1.1 is * modification, are permitted provided that the following conditions 12 1.1 is * are met: 13 1.1 is * 1. Redistributions of source code must retain the above copyright 14 1.1 is * notice, this list of conditions and the following disclaimer. 15 1.1 is * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 is * notice, this list of conditions and the following disclaimer in the 17 1.1 is * documentation and/or other materials provided with the distribution. 18 1.22 agc * 3. Neither the name of the University nor the names of its contributors 19 1.22 agc * may be used to endorse or promote products derived from this software 20 1.22 agc * without specific prior written permission. 21 1.22 agc * 22 1.22 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.22 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.22 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.22 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.22 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.22 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.22 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.22 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.22 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.22 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.22 agc * SUCH DAMAGE. 33 1.22 agc * 34 1.22 agc * @(#)siop.c 7.5 (Berkeley) 5/4/91 35 1.22 agc */ 36 1.22 agc 37 1.22 agc /* 38 1.22 agc * Copyright (c) 1994,1998 Michael L. Hitch 39 1.22 agc * 40 1.22 agc * This code is derived from software contributed to Berkeley by 41 1.22 agc * Van Jacobson of Lawrence Berkeley Laboratory. 42 1.22 agc * 43 1.22 agc * Redistribution and use in source and binary forms, with or without 44 1.22 agc * modification, are permitted provided that the following conditions 45 1.22 agc * are met: 46 1.22 agc * 1. Redistributions of source code must retain the above copyright 47 1.22 agc * notice, this list of conditions and the following disclaimer. 48 1.22 agc * 2. Redistributions in binary form must reproduce the above copyright 49 1.22 agc * notice, this list of conditions and the following disclaimer in the 50 1.22 agc * documentation and/or other materials provided with the distribution. 51 1.1 is * 52 1.23 mhitch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 53 1.23 mhitch * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 54 1.23 mhitch * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 55 1.23 mhitch * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 56 1.23 mhitch * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 57 1.23 mhitch * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 1.23 mhitch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 1.23 mhitch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 1.23 mhitch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 61 1.23 mhitch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.1 is * 63 1.1 is * @(#)siop.c 7.5 (Berkeley) 5/4/91 64 1.1 is */ 65 1.1 is 66 1.1 is /* 67 1.1 is * AMIGA 53C720/770 scsi adaptor driver 68 1.1 is */ 69 1.1 is 70 1.1 is #include "opt_ddb.h" 71 1.18 aymeric 72 1.18 aymeric #include <sys/cdefs.h> 73 1.44 chs __KERNEL_RCSID(0, "$NetBSD: siop2.c,v 1.44 2019/11/10 21:16:22 chs Exp $"); 74 1.1 is 75 1.1 is #include <sys/param.h> 76 1.1 is #include <sys/systm.h> 77 1.33 mhitch #include <sys/callout.h> 78 1.33 mhitch #include <sys/kernel.h> 79 1.1 is #include <sys/device.h> 80 1.1 is #include <sys/disklabel.h> 81 1.1 is #include <sys/buf.h> 82 1.1 is #include <sys/malloc.h> 83 1.20 thorpej 84 1.1 is #include <dev/scsipi/scsi_all.h> 85 1.1 is #include <dev/scsipi/scsipi_all.h> 86 1.1 is #include <dev/scsipi/scsiconf.h> 87 1.1 is #include <machine/cpu.h> 88 1.13 is #ifdef __m68k__ 89 1.13 is #include <m68k/include/cacheops.h> 90 1.37 phx #else 91 1.38 phx #define DCIAS(pa) dma_cachectl((void *)(pa), 1) 92 1.13 is #endif 93 1.1 is #include <amiga/amiga/custom.h> 94 1.38 phx #include <amiga/amiga/device.h> 95 1.1 is #include <amiga/amiga/isr.h> 96 1.1 is 97 1.1 is #define ARCH_720 98 1.1 is 99 1.1 is #include <amiga/dev/siopreg.h> 100 1.1 is #include <amiga/dev/siopvar.h> 101 1.1 is 102 1.1 is /* 103 1.1 is * SCSI delays 104 1.1 is * In u-seconds, primarily for state changes on the SPC. 105 1.1 is */ 106 1.1 is #define SCSI_CMD_WAIT 500000 /* wait per step of 'immediate' cmds */ 107 1.1 is #define SCSI_DATA_WAIT 500000 /* wait per data in/out step */ 108 1.1 is #define SCSI_INIT_WAIT 500000 /* wait per step (both) during init */ 109 1.1 is 110 1.17 aymeric void siopng_select(struct siop_softc *); 111 1.24 jmc void siopngabort(struct siop_softc *, siop_regmap_p, const char *); 112 1.17 aymeric void siopngerror(struct siop_softc *, siop_regmap_p, u_char); 113 1.17 aymeric int siopng_checkintr(struct siop_softc *, u_char, u_char, u_short, int *); 114 1.17 aymeric void siopngreset(struct siop_softc *); 115 1.17 aymeric void siopngsetdelay(int); 116 1.17 aymeric void siopng_scsidone(struct siop_acb *, int); 117 1.33 mhitch void siopng_timeout(void *); 118 1.17 aymeric void siopng_sched(struct siop_softc *); 119 1.17 aymeric void siopng_poll(struct siop_softc *, struct siop_acb *); 120 1.17 aymeric void siopngintr(struct siop_softc *); 121 1.17 aymeric void scsi_period_to_siopng(struct siop_softc *, int); 122 1.17 aymeric void siopng_start(struct siop_softc *, int, int, u_char *, int, u_char *, int); 123 1.17 aymeric void siopng_dump_acb(struct siop_acb *); 124 1.1 is 125 1.1 is /* 53C720/770 script */ 126 1.16 is 127 1.1 is #include <amiga/dev/siop2_script.out> 128 1.1 is 129 1.1 is /* default to not inhibit sync negotiation on any drive */ 130 1.7 is u_char siopng_inhibit_sync[16] = { 131 1.7 is 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 132 1.7 is }; /* initialize, so patchable */ 133 1.7 is 134 1.7 is u_char siopng_inhibit_wide[16] = { 135 1.7 is 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 136 1.7 is }; /* initialize, so patchable */ 137 1.7 is 138 1.7 is u_char siopng_allow_disc[16] = { 139 1.7 is 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 140 1.7 is }; 141 1.7 is 142 1.1 is int siopng_no_dma = 0; 143 1.1 is 144 1.1 is int siopng_reset_delay = 250; /* delay after reset, in milleseconds */ 145 1.1 is 146 1.1 is int siopng_cmd_wait = SCSI_CMD_WAIT; 147 1.1 is int siopng_data_wait = SCSI_DATA_WAIT; 148 1.1 is int siopng_init_wait = SCSI_INIT_WAIT; 149 1.1 is 150 1.39 phx /*#define DEBUG_SYNC*/ 151 1.1 is 152 1.1 is #ifdef DEBUG 153 1.1 is /* 154 1.1 is * 0x01 - full debug 155 1.1 is * 0x02 - DMA chaining 156 1.1 is * 0x04 - siopngintr 157 1.1 is * 0x08 - phase mismatch 158 1.1 is * 0x10 - <not used> 159 1.1 is * 0x20 - panic on unhandled exceptions 160 1.1 is * 0x100 - disconnect/reselect 161 1.1 is */ 162 1.1 is int siopng_debug = 0; 163 1.1 is int siopngsync_debug = 0; 164 1.1 is int siopngdma_hits = 0; 165 1.1 is int siopngdma_misses = 0; 166 1.1 is int siopngchain_ints = 0; 167 1.1 is int siopngstarts = 0; 168 1.1 is int siopngints = 0; 169 1.1 is int siopngphmm = 0; 170 1.1 is #define SIOP_TRACE_SIZE 128 171 1.1 is #define SIOP_TRACE(a,b,c,d) \ 172 1.1 is siopng_trbuf[siopng_trix] = (a); \ 173 1.1 is siopng_trbuf[siopng_trix+1] = (b); \ 174 1.1 is siopng_trbuf[siopng_trix+2] = (c); \ 175 1.1 is siopng_trbuf[siopng_trix+3] = (d); \ 176 1.1 is siopng_trix = (siopng_trix + 4) & (SIOP_TRACE_SIZE - 1); 177 1.1 is u_char siopng_trbuf[SIOP_TRACE_SIZE]; 178 1.1 is int siopng_trix; 179 1.17 aymeric void siopng_dump(struct siop_softc *); 180 1.17 aymeric void siopng_dump_trace(void); 181 1.1 is #else 182 1.1 is #define SIOP_TRACE(a,b,c,d) 183 1.1 is #endif 184 1.1 is 185 1.1 is 186 1.24 jmc static const char *siopng_chips[] = { 187 1.4 is "720", "720SE", "770", "0x3", 188 1.8 is "810A", "0x5", "0x6", "0x7", 189 1.4 is "0x8", "0x9", "0xA", "0xB", 190 1.4 is "0xC", "0xD", "0xE", "0xF", 191 1.4 is }; 192 1.4 is 193 1.1 is /* 194 1.1 is * default minphys routine for siopng based controllers 195 1.1 is */ 196 1.1 is void 197 1.17 aymeric siopng_minphys(struct buf *bp) 198 1.1 is { 199 1.1 is 200 1.1 is /* 201 1.1 is * No max transfer at this level. 202 1.1 is */ 203 1.1 is minphys(bp); 204 1.1 is } 205 1.1 is 206 1.1 is /* 207 1.1 is * used by specific siopng controller 208 1.1 is * 209 1.1 is */ 210 1.15 bouyer void 211 1.17 aymeric siopng_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 212 1.17 aymeric void *arg) 213 1.15 bouyer { 214 1.1 is struct scsipi_xfer *xs; 215 1.42 christos #ifdef DIAGNOSTIC 216 1.15 bouyer struct scsipi_periph *periph; 217 1.42 christos #endif 218 1.1 is struct siop_acb *acb; 219 1.41 chs struct siop_softc *sc = device_private(chan->chan_adapter->adapt_dev); 220 1.1 is int flags, s; 221 1.1 is 222 1.15 bouyer switch (req) { 223 1.15 bouyer case ADAPTER_REQ_RUN_XFER: 224 1.15 bouyer xs = arg; 225 1.42 christos #ifdef DIAGNOSTIC 226 1.15 bouyer periph = xs->xs_periph; 227 1.42 christos #endif 228 1.15 bouyer flags = xs->xs_control; 229 1.15 bouyer 230 1.15 bouyer /* XXXX ?? */ 231 1.15 bouyer if (flags & XS_CTL_DATA_UIO) 232 1.15 bouyer panic("siopng: scsi data uio requested"); 233 1.15 bouyer 234 1.15 bouyer /* XXXX ?? */ 235 1.15 bouyer if (sc->sc_nexus && flags & XS_CTL_POLL) 236 1.15 bouyer /* panic("siopng_scsicmd: busy");*/ 237 1.15 bouyer printf("siopng_scsicmd: busy\n"); 238 1.15 bouyer 239 1.15 bouyer s = splbio(); 240 1.15 bouyer acb = sc->free_list.tqh_first; 241 1.15 bouyer if (acb) { 242 1.15 bouyer TAILQ_REMOVE(&sc->free_list, acb, chain); 243 1.15 bouyer } 244 1.15 bouyer splx(s); 245 1.1 is 246 1.15 bouyer #ifdef DIAGNOSTIC 247 1.15 bouyer /* 248 1.15 bouyer * This should never happen as we track the resources 249 1.15 bouyer * in the mid-layer. 250 1.15 bouyer */ 251 1.15 bouyer if (acb == NULL) { 252 1.15 bouyer scsipi_printaddr(periph); 253 1.15 bouyer printf("unable to allocate acb\n"); 254 1.15 bouyer panic("siopng_scsipi_request"); 255 1.15 bouyer } 256 1.15 bouyer #endif 257 1.15 bouyer acb->flags = ACB_ACTIVE; 258 1.15 bouyer acb->xs = xs; 259 1.36 cegger memcpy(&acb->cmd, xs->cmd, xs->cmdlen); 260 1.15 bouyer acb->clen = xs->cmdlen; 261 1.15 bouyer acb->daddr = xs->data; 262 1.15 bouyer acb->dleft = xs->datalen; 263 1.1 is 264 1.15 bouyer s = splbio(); 265 1.15 bouyer TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain); 266 1.1 is 267 1.15 bouyer if (sc->sc_nexus == NULL) 268 1.15 bouyer siopng_sched(sc); 269 1.1 is 270 1.15 bouyer splx(s); 271 1.1 is 272 1.15 bouyer if (flags & XS_CTL_POLL || siopng_no_dma) 273 1.15 bouyer siopng_poll(sc, acb); 274 1.15 bouyer return; 275 1.1 is 276 1.15 bouyer case ADAPTER_REQ_GROW_RESOURCES: 277 1.15 bouyer return; 278 1.1 is 279 1.15 bouyer case ADAPTER_REQ_SET_XFER_MODE: 280 1.15 bouyer return; 281 1.15 bouyer } 282 1.1 is } 283 1.1 is 284 1.15 bouyer void 285 1.17 aymeric siopng_poll(struct siop_softc *sc, struct siop_acb *acb) 286 1.1 is { 287 1.1 is siop_regmap_p rp = sc->sc_siopp; 288 1.1 is struct scsipi_xfer *xs = acb->xs; 289 1.1 is int i; 290 1.1 is int status; 291 1.1 is u_char istat; 292 1.1 is u_char dstat; 293 1.1 is u_short sist; 294 1.1 is int s; 295 1.1 is int to; 296 1.1 is 297 1.1 is s = splbio(); 298 1.1 is to = xs->timeout / 1000; 299 1.1 is if (sc->nexus_list.tqh_first) 300 1.1 is printf("%s: siopng_poll called with disconnected device\n", 301 1.41 chs device_xname(sc->sc_dev)); 302 1.1 is for (;;) { 303 1.1 is /* use cmd_wait values? */ 304 1.1 is i = 50000; 305 1.1 is /* XXX spl0(); */ 306 1.1 is while (((istat = rp->siop_istat) & 307 1.1 is (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) { 308 1.1 is if (--i <= 0) { 309 1.1 is #ifdef DEBUG 310 1.1 is printf ("waiting: tgt %d cmd %02x sbcl %02x istat %02x sbdl %04x\n dsp %lx (+%lx) dcmd %lx ds %p timeout %d\n", 311 1.15 bouyer xs->xs_periph->periph_target, acb->cmd.opcode, 312 1.1 is rp->siop_sbcl, istat, rp->siop_sbdl, rp->siop_dsp, 313 1.1 is rp->siop_dsp - sc->sc_scriptspa, 314 1.28 mhitch *((volatile long *)&rp->siop_dcmd), &acb->ds, acb->xs->timeout); 315 1.1 is #endif 316 1.1 is i = 50000; 317 1.1 is --to; 318 1.1 is if (to <= 0) { 319 1.1 is siopngreset(sc); 320 1.15 bouyer return; 321 1.1 is } 322 1.1 is } 323 1.1 is delay(20); 324 1.1 is } 325 1.1 is sist = rp->siop_sist; 326 1.1 is dstat = rp->siop_dstat; 327 1.1 is if (siopng_checkintr(sc, istat, dstat, sist, &status)) { 328 1.1 is if (acb != sc->sc_nexus) 329 1.1 is printf("%s: siopng_poll disconnected device completed\n", 330 1.41 chs device_xname(sc->sc_dev)); 331 1.1 is else if ((sc->sc_flags & SIOP_INTDEFER) == 0) { 332 1.1 is sc->sc_flags &= ~SIOP_INTSOFF; 333 1.1 is rp->siop_sien = sc->sc_sien; 334 1.1 is rp->siop_dien = sc->sc_dien; 335 1.1 is } 336 1.1 is siopng_scsidone(sc->sc_nexus, status); 337 1.1 is } 338 1.14 thorpej if (xs->xs_status & XS_STS_DONE) 339 1.1 is break; 340 1.1 is } 341 1.1 is splx(s); 342 1.1 is } 343 1.1 is 344 1.1 is /* 345 1.1 is * start next command that's ready 346 1.1 is */ 347 1.1 is void 348 1.17 aymeric siopng_sched(struct siop_softc *sc) 349 1.1 is { 350 1.15 bouyer struct scsipi_periph *periph; 351 1.1 is struct siop_acb *acb; 352 1.1 is int i; 353 1.1 is 354 1.1 is #ifdef DEBUG 355 1.1 is if (sc->sc_nexus) { 356 1.1 is printf("%s: siopng_sched- nexus %p/%d ready %p/%d\n", 357 1.41 chs device_xname(sc->sc_dev), sc->sc_nexus, 358 1.15 bouyer sc->sc_nexus->xs->xs_periph->periph_target, 359 1.1 is sc->ready_list.tqh_first, 360 1.15 bouyer sc->ready_list.tqh_first->xs->xs_periph->periph_target); 361 1.1 is return; 362 1.1 is } 363 1.1 is #endif 364 1.1 is for (acb = sc->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) { 365 1.15 bouyer periph = acb->xs->xs_periph; 366 1.15 bouyer i = periph->periph_target; 367 1.15 bouyer if(!(sc->sc_tinfo[i].lubusy & (1 << periph->periph_lun))) { 368 1.1 is struct siop_tinfo *ti = &sc->sc_tinfo[i]; 369 1.1 is 370 1.1 is TAILQ_REMOVE(&sc->ready_list, acb, chain); 371 1.1 is sc->sc_nexus = acb; 372 1.15 bouyer periph = acb->xs->xs_periph; 373 1.15 bouyer ti = &sc->sc_tinfo[periph->periph_target]; 374 1.15 bouyer ti->lubusy |= (1 << periph->periph_lun); 375 1.1 is break; 376 1.1 is } 377 1.1 is } 378 1.1 is 379 1.1 is if (acb == NULL) { 380 1.1 is #ifdef DEBUGXXX 381 1.1 is printf("%s: siopng_sched didn't find ready command\n", 382 1.41 chs device_xname(sc->sc_dev)); 383 1.1 is #endif 384 1.1 is return; 385 1.1 is } 386 1.1 is 387 1.14 thorpej if (acb->xs->xs_control & XS_CTL_RESET) 388 1.1 is siopngreset(sc); 389 1.1 is 390 1.1 is #if 0 391 1.15 bouyer acb->cmd.bytes[0] |= periph->periph_lun << 5; /* XXXX */ 392 1.1 is #endif 393 1.1 is ++sc->sc_active; 394 1.1 is siopng_select(sc); 395 1.1 is } 396 1.1 is 397 1.1 is void 398 1.17 aymeric siopng_scsidone(struct siop_acb *acb, int stat) 399 1.1 is { 400 1.1 is struct scsipi_xfer *xs; 401 1.15 bouyer struct scsipi_periph *periph; 402 1.1 is struct siop_softc *sc; 403 1.1 is int dosched = 0; 404 1.1 is 405 1.1 is if (acb == NULL || (xs = acb->xs) == NULL) { 406 1.1 is #ifdef DIAGNOSTIC 407 1.1 is printf("siopng_scsidone: NULL acb or scsipi_xfer\n"); 408 1.1 is #if defined(DEBUG) && defined(DDB) 409 1.1 is Debugger(); 410 1.1 is #endif 411 1.1 is #endif 412 1.1 is return; 413 1.1 is } 414 1.33 mhitch 415 1.33 mhitch callout_stop(&xs->xs_callout); 416 1.33 mhitch 417 1.15 bouyer periph = xs->xs_periph; 418 1.41 chs sc = device_private(periph->periph_channel->chan_adapter->adapt_dev); 419 1.15 bouyer 420 1.1 is xs->status = stat; 421 1.15 bouyer xs->resid = 0; /* XXXX */ 422 1.1 is 423 1.15 bouyer if (xs->error == XS_NOERROR) { 424 1.15 bouyer if (stat == SCSI_CHECK || stat == SCSI_BUSY) 425 1.15 bouyer xs->error = XS_BUSY; 426 1.1 is } 427 1.1 is 428 1.1 is /* 429 1.1 is * Remove the ACB from whatever queue it's on. We have to do a bit of 430 1.1 is * a hack to figure out which queue it's on. Note that it is *not* 431 1.1 is * necessary to cdr down the ready queue, but we must cdr down the 432 1.1 is * nexus queue and see if it's there, so we can mark the unit as no 433 1.1 is * longer busy. This code is sickening, but it works. 434 1.1 is */ 435 1.1 is if (acb == sc->sc_nexus) { 436 1.1 is sc->sc_nexus = NULL; 437 1.15 bouyer sc->sc_tinfo[periph->periph_target].lubusy &= 438 1.15 bouyer ~(1<<periph->periph_lun); 439 1.1 is if (sc->ready_list.tqh_first) 440 1.1 is dosched = 1; /* start next command */ 441 1.1 is --sc->sc_active; 442 1.1 is SIOP_TRACE('d','a',stat,0) 443 1.1 is } else if (sc->ready_list.tqh_last == &acb->chain.tqe_next) { 444 1.1 is TAILQ_REMOVE(&sc->ready_list, acb, chain); 445 1.1 is SIOP_TRACE('d','r',stat,0) 446 1.1 is } else { 447 1.1 is register struct siop_acb *acb2; 448 1.1 is for (acb2 = sc->nexus_list.tqh_first; acb2; 449 1.1 is acb2 = acb2->chain.tqe_next) 450 1.1 is if (acb2 == acb) { 451 1.1 is TAILQ_REMOVE(&sc->nexus_list, acb, chain); 452 1.15 bouyer sc->sc_tinfo[periph->periph_target].lubusy 453 1.15 bouyer &= ~(1<<periph->periph_lun); 454 1.1 is --sc->sc_active; 455 1.1 is break; 456 1.1 is } 457 1.1 is if (acb2) 458 1.1 is ; 459 1.1 is else if (acb->chain.tqe_next) { 460 1.1 is TAILQ_REMOVE(&sc->ready_list, acb, chain); 461 1.1 is --sc->sc_active; 462 1.1 is } else { 463 1.1 is printf("%s: can't find matching acb\n", 464 1.41 chs device_xname(sc->sc_dev)); 465 1.1 is #ifdef DDB 466 1.1 is /* Debugger(); */ 467 1.1 is #endif 468 1.1 is } 469 1.1 is SIOP_TRACE('d','n',stat,0); 470 1.1 is } 471 1.1 is /* Put it on the free list. */ 472 1.1 is acb->flags = ACB_FREE; 473 1.1 is TAILQ_INSERT_HEAD(&sc->free_list, acb, chain); 474 1.1 is 475 1.15 bouyer sc->sc_tinfo[periph->periph_target].cmds++; 476 1.1 is 477 1.1 is scsipi_done(xs); 478 1.1 is 479 1.1 is if (dosched && sc->sc_nexus == NULL) 480 1.1 is siopng_sched(sc); 481 1.1 is } 482 1.1 is 483 1.1 is void 484 1.24 jmc siopngabort(register struct siop_softc *sc, siop_regmap_p rp, const char *where) 485 1.1 is { 486 1.1 is #ifdef fix_this 487 1.1 is int i; 488 1.1 is #endif 489 1.1 is 490 1.1 is printf ("%s: abort %s: dstat %02x, istat %02x sist %04x sien %04x sbcl %02x\n", 491 1.41 chs device_xname(sc->sc_dev), 492 1.1 is where, rp->siop_dstat, rp->siop_istat, rp->siop_sist, 493 1.1 is rp->siop_sien, rp->siop_sbcl); 494 1.1 is siopng_dump_registers(sc); 495 1.1 is 496 1.1 is if (sc->sc_active > 0) { 497 1.1 is #ifdef TODO 498 1.1 is SET_SBIC_cmd (rp, SBIC_CMD_ABORT); 499 1.1 is WAIT_CIP (rp); 500 1.1 is 501 1.1 is GET_SBIC_asr (rp, asr); 502 1.1 is if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI)) 503 1.1 is { 504 1.1 is /* ok, get more drastic.. */ 505 1.1 is 506 1.1 is SET_SBIC_cmd (rp, SBIC_CMD_RESET); 507 1.1 is delay(25); 508 1.1 is SBIC_WAIT(rp, SBIC_ASR_INT, 0); 509 1.1 is GET_SBIC_csr (rp, csr); /* clears interrupt also */ 510 1.1 is 511 1.1 is return; 512 1.1 is } 513 1.1 is 514 1.1 is do 515 1.1 is { 516 1.1 is SBIC_WAIT (rp, SBIC_ASR_INT, 0); 517 1.1 is GET_SBIC_csr (rp, csr); 518 1.1 is } 519 1.1 is while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) 520 1.1 is && (csr != SBIC_CSR_CMD_INVALID)); 521 1.1 is #endif 522 1.1 is 523 1.1 is /* lets just hope it worked.. */ 524 1.1 is #ifdef fix_this 525 1.1 is for (i = 0; i < 2; ++i) { 526 1.1 is if (sc->sc_iob[i].sc_xs && &sc->sc_iob[i] != 527 1.1 is sc->sc_cur) { 528 1.1 is printf ("siopngabort: cleanup!\n"); 529 1.1 is sc->sc_iob[i].sc_xs = NULL; 530 1.1 is } 531 1.1 is } 532 1.1 is #endif /* fix_this */ 533 1.1 is /* sc->sc_active = 0; */ 534 1.1 is } 535 1.1 is } 536 1.1 is 537 1.1 is void 538 1.17 aymeric siopnginitialize(struct siop_softc *sc) 539 1.1 is { 540 1.1 is int i; 541 1.1 is u_int inhibit_sync; 542 1.1 is extern u_long scsi_nosync; 543 1.1 is extern int shift_nosync; 544 1.1 is 545 1.1 is /* 546 1.1 is * Need to check that scripts is on a long word boundary 547 1.1 is * Also should verify that dev doesn't span non-contiguous 548 1.1 is * physical pages. 549 1.1 is */ 550 1.27 christos sc->sc_scriptspa = kvtop((void *)__UNCONST(siopng_scripts)); 551 1.1 is 552 1.1 is /* 553 1.1 is * malloc sc_acb to ensure that DS is on a long word boundary. 554 1.1 is */ 555 1.1 is 556 1.32 cegger sc->sc_acb = malloc(sizeof(struct siop_acb) * SIOP_NACB, 557 1.44 chs M_DEVBUF, M_WAITOK); 558 1.1 is 559 1.1 is sc->sc_tcp[1] = 1000 / sc->sc_clock_freq; 560 1.1 is sc->sc_tcp[2] = 1500 / sc->sc_clock_freq; 561 1.1 is sc->sc_tcp[3] = 2000 / sc->sc_clock_freq; 562 1.1 is sc->sc_minsync = sc->sc_tcp[1]; /* in 4ns units */ 563 1.1 is if (sc->sc_minsync < 25) 564 1.1 is sc->sc_minsync = 25; 565 1.6 mhitch sc->sc_minsync >>= 1; /* Using clock doubler, allow Ultra */ 566 1.1 is if (sc->sc_clock_freq <= 25) { 567 1.1 is sc->sc_dcntl |= 0x80; /* SCLK/1 */ 568 1.1 is sc->sc_tcp[0] = sc->sc_tcp[1]; 569 1.1 is } else if (sc->sc_clock_freq <= 37) { 570 1.1 is sc->sc_dcntl |= 0x40; /* SCLK/1.5 */ 571 1.1 is sc->sc_tcp[0] = sc->sc_tcp[2]; 572 1.1 is } else if (sc->sc_clock_freq <= 50) { 573 1.1 is sc->sc_dcntl |= 0x00; /* SCLK/2 */ 574 1.1 is sc->sc_tcp[0] = sc->sc_tcp[3]; 575 1.1 is } else { 576 1.1 is sc->sc_dcntl |= 0xc0; /* SCLK/3 */ 577 1.1 is sc->sc_tcp[0] = 3000 / sc->sc_clock_freq; 578 1.1 is } 579 1.1 is 580 1.1 is if (scsi_nosync) { 581 1.6 mhitch inhibit_sync = (scsi_nosync >> shift_nosync) & 0xffff; 582 1.6 mhitch shift_nosync += 16; /* XXX maxtarget */ 583 1.1 is #ifdef DEBUG 584 1.1 is if (inhibit_sync) 585 1.1 is printf("%s: Inhibiting synchronous transfer %02x\n", 586 1.41 chs device_xname(sc->sc_dev), inhibit_sync); 587 1.1 is #endif 588 1.6 mhitch for (i = 0; i < 16; ++i) /* XXX maxtarget */ 589 1.1 is if (inhibit_sync & (1 << i)) 590 1.1 is siopng_inhibit_sync[i] = 1; 591 1.1 is } 592 1.1 is 593 1.1 is siopngreset (sc); 594 1.1 is } 595 1.1 is 596 1.1 is void 597 1.33 mhitch siopng_timeout(void *arg) 598 1.33 mhitch { 599 1.33 mhitch struct siop_acb *acb; 600 1.33 mhitch struct scsipi_periph *periph; 601 1.33 mhitch struct siop_softc *sc; 602 1.33 mhitch int s; 603 1.33 mhitch 604 1.33 mhitch acb = arg; 605 1.33 mhitch periph = acb->xs->xs_periph; 606 1.33 mhitch sc = device_private(periph->periph_channel->chan_adapter->adapt_dev); 607 1.33 mhitch scsipi_printaddr(periph); 608 1.33 mhitch printf("timed out\n"); 609 1.33 mhitch 610 1.33 mhitch s = splbio(); 611 1.33 mhitch 612 1.33 mhitch acb->xs->error = XS_TIMEOUT; 613 1.33 mhitch siopngreset(sc); 614 1.33 mhitch 615 1.33 mhitch splx(s); 616 1.33 mhitch } 617 1.33 mhitch 618 1.33 mhitch void 619 1.17 aymeric siopngreset(struct siop_softc *sc) 620 1.1 is { 621 1.1 is siop_regmap_p rp; 622 1.1 is u_int i, s; 623 1.1 is u_short dummy; 624 1.1 is struct siop_acb *acb; 625 1.1 is 626 1.1 is rp = sc->sc_siopp; 627 1.1 is 628 1.1 is if (sc->sc_flags & SIOP_ALIVE) 629 1.1 is siopngabort(sc, rp, "reset"); 630 1.1 is 631 1.41 chs printf("%s: ", device_xname(sc->sc_dev)); /* XXXX */ 632 1.1 is 633 1.1 is s = splbio(); 634 1.1 is 635 1.1 is /* 636 1.1 is * Reset the chip 637 1.1 is * XXX - is this really needed? 638 1.1 is */ 639 1.1 is rp->siop_istat |= SIOP_ISTAT_ABRT; /* abort current script */ 640 1.1 is rp->siop_istat |= SIOP_ISTAT_RST; /* reset chip */ 641 1.1 is rp->siop_istat &= ~SIOP_ISTAT_RST; 642 1.1 is /* 643 1.1 is * Reset SCSI bus (do we really want this?) 644 1.1 is */ 645 1.1 is rp->siop_sien = 0; 646 1.1 is rp->siop_scntl1 |= SIOP_SCNTL1_RST; 647 1.1 is delay(1); 648 1.1 is rp->siop_scntl1 &= ~SIOP_SCNTL1_RST; 649 1.1 is 650 1.1 is /* 651 1.1 is * Set up various chip parameters 652 1.1 is */ 653 1.6 mhitch rp->siop_stest1 |= SIOP_STEST1_DBLEN; /* SCLK doubler enable */ 654 1.1 is delay(20); 655 1.6 mhitch rp->siop_stest3 |= SIOP_STEST3_HSC; /* Halt SCSI clock */ 656 1.6 mhitch rp->siop_scntl3 = 0x15; /* SCF/CCF*/ 657 1.6 mhitch rp->siop_stest1 |= SIOP_STEST1_DBLSEL; /* SCLK doubler select */ 658 1.6 mhitch rp->siop_stest3 &= ~SIOP_STEST3_HSC; /* Clear Halt SCSI clock */ 659 1.1 is rp->siop_scntl0 = SIOP_ARB_FULL | /*SIOP_SCNTL0_EPC |*/ SIOP_SCNTL0_EPG; 660 1.1 is rp->siop_dcntl = sc->sc_dcntl; 661 1.1 is rp->siop_dmode = 0xc0; /* XXX burst length */ 662 1.1 is rp->siop_sien = 0x00; /* don't enable interrupts yet */ 663 1.1 is rp->siop_dien = 0x00; /* don't enable interrupts yet */ 664 1.15 bouyer rp->siop_scid = sc->sc_channel.chan_id | 665 1.6 mhitch SIOP_SCID_RRE | SIOP_SCID_SRE; 666 1.15 bouyer rp->siop_respid = 1 << sc->sc_channel.chan_id; 667 1.1 is rp->siop_dwt = 0x00; 668 1.1 is rp->siop_stime0 = 0x0c; /* XXXXX check */ 669 1.1 is 670 1.1 is /* will need to re-negotiate sync xfers */ 671 1.34 cegger memset(&sc->sc_sync, 0, sizeof (sc->sc_sync)); 672 1.1 is 673 1.1 is i = rp->siop_istat; 674 1.1 is if (i & SIOP_ISTAT_SIP) 675 1.1 is dummy = rp->siop_sist; 676 1.1 is if (i & SIOP_ISTAT_DIP) 677 1.1 is dummy = rp->siop_dstat; 678 1.1 is 679 1.42 christos __USE(dummy); 680 1.1 is splx (s); 681 1.1 is 682 1.1 is delay (siopng_reset_delay * 1000); 683 1.12 is 684 1.12 is /* 685 1.12 is * is lower half unterminated? 686 1.12 is */ 687 1.12 is if ((rp->siop_sbdl & 0x00ff) == 0x00ff) { 688 1.12 is printf(" no SCSI termination, host adapter deactivated.\n"); 689 1.15 bouyer sc->sc_channel.chan_ntargets = 0; /* XXX */ 690 1.12 is sc->sc_flags &= ~(SIOP_ALIVE|SIOP_INTDEFER|SIOP_INTSOFF); 691 1.12 is /* disable SCSI and DMA interrupts */ 692 1.12 is sc->sc_sien = 0; 693 1.12 is sc->sc_dien = 0; 694 1.12 is rp->siop_sien = sc->sc_sien; 695 1.12 is rp->siop_dien = sc->sc_dien; 696 1.12 is 697 1.12 is return; 698 1.12 is } 699 1.12 is 700 1.1 is /* 701 1.1 is * Check if upper half of SCSI bus is unterminated, and disallow 702 1.1 is * disconnections if it appears to be unterminated. 703 1.1 is */ 704 1.1 is if ((rp->siop_sbdl & 0xff00) == 0xff00) { 705 1.1 is printf(" NO WIDE TERM"); 706 1.6 mhitch /* XXX need to restrict maximum target ID as well? */ 707 1.15 bouyer sc->sc_channel.chan_ntargets = 8; 708 1.6 mhitch for (i = 0; i < 16; ++i) { 709 1.1 is siopng_allow_disc[i] = 0; 710 1.6 mhitch siopng_inhibit_wide[i] |= 0x80; 711 1.6 mhitch } 712 1.1 is } 713 1.4 is 714 1.4 is printf("siopng type %s id %d reset V%d\n", 715 1.4 is siopng_chips[rp->siop_macntl>>4], 716 1.15 bouyer sc->sc_channel.chan_ntargets, 717 1.1 is rp->siop_ctest3 >> 4); 718 1.1 is 719 1.1 is if ((sc->sc_flags & SIOP_ALIVE) == 0) { 720 1.1 is TAILQ_INIT(&sc->ready_list); 721 1.1 is TAILQ_INIT(&sc->nexus_list); 722 1.1 is TAILQ_INIT(&sc->free_list); 723 1.1 is sc->sc_nexus = NULL; 724 1.1 is acb = sc->sc_acb; 725 1.34 cegger memset(acb, 0, sizeof(struct siop_acb) * SIOP_NACB); 726 1.1 is for (i = 0; i < SIOP_NACB; i++) { 727 1.1 is TAILQ_INSERT_TAIL(&sc->free_list, acb, chain); 728 1.1 is acb++; 729 1.1 is } 730 1.34 cegger memset(sc->sc_tinfo, 0, sizeof(sc->sc_tinfo)); 731 1.1 is } else { 732 1.1 is if (sc->sc_nexus != NULL) { 733 1.15 bouyer sc->sc_nexus->xs->error = XS_RESET; 734 1.1 is siopng_scsidone(sc->sc_nexus, sc->sc_nexus->stat[0]); 735 1.1 is } 736 1.1 is while ((acb = sc->nexus_list.tqh_first) > 0) { 737 1.15 bouyer acb->xs->error = XS_RESET; 738 1.1 is siopng_scsidone(acb, acb->stat[0]); 739 1.1 is } 740 1.1 is } 741 1.1 is 742 1.1 is sc->sc_flags |= SIOP_ALIVE; 743 1.1 is sc->sc_flags &= ~(SIOP_INTDEFER|SIOP_INTSOFF); 744 1.1 is /* enable SCSI and DMA interrupts */ 745 1.1 is sc->sc_sien = SIOP_SIEN_MA | SIOP_SIEN_STO | /*SIOP_SIEN_GEN |*/ 746 1.1 is /*SIOP_SIEN_SEL |*/ SIOP_SIEN_SGE | SIOP_SIEN_UDC | 747 1.1 is SIOP_SIEN_RST | SIOP_SIEN_PAR; 748 1.1 is sc->sc_dien = SIOP_DIEN_BF | SIOP_DIEN_ABRT | SIOP_DIEN_SIR | 749 1.1 is /*SIOP_DIEN_WTD |*/ SIOP_DIEN_IID; 750 1.1 is rp->siop_sien = sc->sc_sien; 751 1.1 is rp->siop_dien = sc->sc_dien; 752 1.10 is /*siopng_dump_registers(sc);*/ 753 1.1 is } 754 1.1 is 755 1.1 is /* 756 1.1 is * Setup Data Storage for 53C720/770 and start SCRIPTS processing 757 1.1 is */ 758 1.1 is 759 1.1 is void 760 1.17 aymeric siopng_start(struct siop_softc *sc, int target, int lun, u_char *cbuf, 761 1.17 aymeric int clen, u_char *buf, int len) 762 1.1 is { 763 1.1 is siop_regmap_p rp = sc->sc_siopp; 764 1.1 is int nchain; 765 1.1 is int count, tcount; 766 1.1 is char *addr, *dmaend; 767 1.1 is struct siop_acb *acb = sc->sc_nexus; 768 1.1 is #ifdef DEBUG 769 1.1 is int i; 770 1.1 is #endif 771 1.1 is 772 1.1 is #ifdef DEBUG 773 1.1 is if (siopng_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) { 774 1.1 is printf ("ACK! siopng was busy: rp %p script %p dsa %p active %ld\n", 775 1.2 is rp, &siopng_scripts, &acb->ds, sc->sc_active); 776 1.1 is printf ("istat %02x sfbr %02x respid %02x sien %04x dien %02x\n", 777 1.1 is rp->siop_istat, rp->siop_sfbr, rp->siop_respid, 778 1.1 is rp->siop_sien, rp->siop_dien); 779 1.1 is #ifdef DDB 780 1.1 is /*Debugger();*/ 781 1.1 is #endif 782 1.1 is } 783 1.1 is #endif 784 1.1 is acb->msgout[0] = MSG_IDENTIFY | lun; 785 1.1 is if (siopng_allow_disc[target] & 2 || 786 1.1 is (siopng_allow_disc[target] && len == 0)) 787 1.1 is acb->msgout[0] = MSG_IDENTIFY_DR | lun; 788 1.1 is acb->status = 0; 789 1.1 is acb->stat[0] = -1; 790 1.1 is acb->msg[0] = -1; 791 1.1 is acb->ds.scsi_addr = (target << 16) | (sc->sc_sync[target].sxfer << 8) | 792 1.6 mhitch (sc->sc_sync[target].scntl3 << 24); 793 1.1 is acb->ds.idlen = 1; 794 1.1 is acb->ds.idbuf = (char *) kvtop(&acb->msgout[0]); 795 1.1 is acb->ds.cmdlen = clen; 796 1.1 is acb->ds.cmdbuf = (char *) kvtop(cbuf); 797 1.1 is acb->ds.stslen = 1; 798 1.1 is acb->ds.stsbuf = (char *) kvtop(&acb->stat[0]); 799 1.1 is acb->ds.msglen = 1; 800 1.1 is acb->ds.msgbuf = (char *) kvtop(&acb->msg[0]); 801 1.1 is acb->msg[1] = -1; 802 1.1 is acb->ds.msginlen = 1; 803 1.1 is acb->ds.extmsglen = 1; 804 1.1 is acb->ds.synmsglen = 3; 805 1.6 mhitch acb->ds.msginbuf = acb->ds.msgbuf + 1; 806 1.6 mhitch acb->ds.extmsgbuf = acb->ds.msginbuf + 1; 807 1.6 mhitch acb->ds.synmsgbuf = acb->ds.extmsgbuf + 1; 808 1.34 cegger memset(&acb->ds.chain, 0, sizeof (acb->ds.chain)); 809 1.1 is 810 1.6 mhitch if (sc->sc_sync[target].state == NEG_WIDE) { 811 1.6 mhitch if (siopng_inhibit_wide[target]) { 812 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC; 813 1.6 mhitch sc->sc_sync[target].scntl3 &= ~SIOP_SCNTL3_EWS; 814 1.6 mhitch #ifdef DEBUG 815 1.6 mhitch if (siopngsync_debug) 816 1.6 mhitch printf ("Forcing target %d narrow\n", target); 817 1.6 mhitch #endif 818 1.6 mhitch } 819 1.6 mhitch else { 820 1.6 mhitch sc->sc_sync[target].scntl3 = 0x15 | /* XXX */ 821 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */ 822 1.6 mhitch acb->msg[2] = -1; 823 1.6 mhitch acb->msgout[1] = MSG_EXT_MESSAGE; 824 1.6 mhitch acb->msgout[2] = 2; 825 1.6 mhitch acb->msgout[3] = MSG_WIDE_REQ; 826 1.6 mhitch acb->msgout[4] = 1; 827 1.6 mhitch acb->ds.idlen = 5; 828 1.6 mhitch acb->ds.synmsglen = 2; 829 1.6 mhitch sc->sc_sync[target].state = NEG_WAITW; 830 1.6 mhitch #ifdef DEBUG 831 1.6 mhitch if (siopngsync_debug) 832 1.6 mhitch printf("Sending wide request to target %d\n", target); 833 1.6 mhitch #endif 834 1.6 mhitch } 835 1.6 mhitch } 836 1.6 mhitch if (sc->sc_sync[target].state == NEG_SYNC) { 837 1.1 is if (siopng_inhibit_sync[target]) { 838 1.6 mhitch sc->sc_sync[target].state = NEG_DONE; 839 1.6 mhitch sc->sc_sync[target].scntl3 = 5 | /* XXX */ 840 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */ 841 1.1 is sc->sc_sync[target].sxfer = 0; 842 1.1 is #ifdef DEBUG 843 1.1 is if (siopngsync_debug) 844 1.1 is printf ("Forcing target %d asynchronous\n", target); 845 1.1 is #endif 846 1.1 is } 847 1.1 is else { 848 1.6 mhitch sc->sc_sync[target].scntl3 = 0x15 | /* XXX */ 849 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */ 850 1.1 is acb->msg[2] = -1; 851 1.1 is acb->msgout[1] = MSG_EXT_MESSAGE; 852 1.1 is acb->msgout[2] = 3; 853 1.1 is acb->msgout[3] = MSG_SYNC_REQ; 854 1.1 is #ifdef MAXTOR_SYNC_KLUDGE 855 1.1 is acb->msgout[4] = 50 / 4; /* ask for ridiculous period */ 856 1.1 is #else 857 1.1 is acb->msgout[4] = sc->sc_minsync; 858 1.1 is #endif 859 1.1 is acb->msgout[5] = SIOP_MAX_OFFSET; 860 1.1 is acb->ds.idlen = 6; 861 1.6 mhitch sc->sc_sync[target].state = NEG_WAITS; 862 1.1 is #ifdef DEBUG 863 1.1 is if (siopngsync_debug) 864 1.1 is printf ("Sending sync request to target %d\n", target); 865 1.1 is #endif 866 1.1 is } 867 1.1 is } 868 1.1 is 869 1.1 is /* 870 1.1 is * Build physical DMA addresses for scatter/gather I/O 871 1.1 is */ 872 1.1 is acb->iob_buf = buf; 873 1.1 is acb->iob_len = len; 874 1.1 is acb->iob_curbuf = acb->iob_curlen = 0; 875 1.1 is nchain = 0; 876 1.1 is count = len; 877 1.1 is addr = buf; 878 1.1 is dmaend = NULL; 879 1.1 is while (count > 0) { 880 1.1 is acb->ds.chain[nchain].databuf = (char *) kvtop (addr); 881 1.20 thorpej if (count < (tcount = PAGE_SIZE - ((int) addr & PGOFSET))) 882 1.1 is tcount = count; 883 1.3 is 884 1.3 is #if DEBUG_ONLY_IF_DESPERATE 885 1.3 is printf("chain[%d]: count %d tcount %d vaddr %p paddr %p\n", 886 1.3 is nchain, count, tcount, addr, 887 1.3 is acb->ds.chain[nchain].databuf); 888 1.3 is #endif 889 1.1 is acb->ds.chain[nchain].datalen = tcount; 890 1.1 is addr += tcount; 891 1.1 is count -= tcount; 892 1.1 is if (acb->ds.chain[nchain].databuf == dmaend) { 893 1.1 is dmaend += acb->ds.chain[nchain].datalen; 894 1.1 is acb->ds.chain[nchain].datalen = 0; 895 1.1 is acb->ds.chain[--nchain].datalen += tcount; 896 1.1 is #ifdef DEBUG 897 1.1 is ++siopngdma_hits; 898 1.1 is #endif 899 1.1 is } 900 1.1 is else { 901 1.1 is dmaend = acb->ds.chain[nchain].databuf + 902 1.1 is acb->ds.chain[nchain].datalen; 903 1.1 is acb->ds.chain[nchain].datalen = tcount; 904 1.1 is #ifdef DEBUG 905 1.1 is if (nchain) /* Don't count miss on first one */ 906 1.1 is ++siopngdma_misses; 907 1.1 is #endif 908 1.1 is } 909 1.1 is ++nchain; 910 1.1 is } 911 1.1 is #ifdef DEBUG 912 1.1 is if (nchain != 1 && len != 0 && siopng_debug & 3) { 913 1.1 is printf ("DMA chaining set: %d\n", nchain); 914 1.1 is for (i = 0; i < nchain; ++i) { 915 1.1 is printf (" [%d] %8p %lx\n", i, acb->ds.chain[i].databuf, 916 1.1 is acb->ds.chain[i].datalen); 917 1.1 is } 918 1.1 is } 919 1.1 is #endif 920 1.1 is 921 1.1 is /* push data cache for all data the 53c720/770 needs to access */ 922 1.27 christos dma_cachectl ((void *)acb, sizeof (struct siop_acb)); 923 1.1 is dma_cachectl (cbuf, clen); 924 1.1 is if (buf != NULL && len != 0) 925 1.1 is dma_cachectl (buf, len); 926 1.1 is #ifdef DEBUG 927 1.1 is if (siopng_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) { 928 1.1 is printf ("ACK! siopng was busy at start: rp %p script %p dsa %p active %ld\n", 929 1.2 is rp, &siopng_scripts, &acb->ds, sc->sc_active); 930 1.1 is #ifdef DDB 931 1.1 is /*Debugger();*/ 932 1.1 is #endif 933 1.1 is } 934 1.1 is #endif 935 1.1 is if (sc->nexus_list.tqh_first == NULL) { 936 1.33 mhitch callout_reset(&acb->xs->xs_callout, 937 1.33 mhitch mstohz(acb->xs->timeout) + 1, siopng_timeout, acb); 938 1.1 is if (rp->siop_istat & SIOP_ISTAT_CON) 939 1.1 is printf("%s: siopng_select while connected?\n", 940 1.41 chs device_xname(sc->sc_dev)); 941 1.1 is rp->siop_temp = 0; 942 1.1 is #ifndef FIXME 943 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3; 944 1.1 is #endif 945 1.38 phx amiga_membarrier(); 946 1.27 christos rp->siop_dsa = kvtop((void *)&acb->ds); 947 1.38 phx amiga_membarrier(); 948 1.1 is rp->siop_dsp = sc->sc_scriptspa; 949 1.38 phx amiga_membarrier(); 950 1.1 is SIOP_TRACE('s',1,0,0) 951 1.1 is } else { 952 1.1 is if ((rp->siop_istat & SIOP_ISTAT_CON) == 0) { 953 1.1 is rp->siop_istat = SIOP_ISTAT_SIGP; 954 1.1 is SIOP_TRACE('s',2,0,0); 955 1.1 is } 956 1.1 is else { 957 1.1 is SIOP_TRACE('s',3,rp->siop_istat,0); 958 1.1 is } 959 1.1 is } 960 1.1 is #ifdef DEBUG 961 1.1 is ++siopngstarts; 962 1.1 is #endif 963 1.1 is } 964 1.1 is 965 1.1 is /* 966 1.1 is * Process a DMA or SCSI interrupt from the 53C720/770 SIOP 967 1.1 is */ 968 1.1 is 969 1.1 is int 970 1.17 aymeric siopng_checkintr(struct siop_softc *sc, u_char istat, u_char dstat, 971 1.17 aymeric u_short sist, int *status) 972 1.1 is { 973 1.1 is siop_regmap_p rp = sc->sc_siopp; 974 1.1 is struct siop_acb *acb = sc->sc_nexus; 975 1.1 is int target = 0; 976 1.3 is int dfifo, dbc, sstat0, sstat1, sstat2; 977 1.1 is 978 1.1 is dfifo = rp->siop_dfifo; 979 1.1 is dbc = rp->siop_dbc0; 980 1.3 is sstat0 = rp->siop_sstat0; 981 1.1 is sstat1 = rp->siop_sstat1; 982 1.42 christos __USE(sstat1); 983 1.3 is sstat2 = rp->siop_sstat2; 984 1.1 is rp->siop_ctest3 |= SIOP_CTEST8_CLF; 985 1.1 is while ((rp->siop_ctest1 & SIOP_CTEST1_FMT) != SIOP_CTEST1_FMT) 986 1.1 is ; 987 1.1 is rp->siop_ctest3 &= ~SIOP_CTEST8_CLF; 988 1.1 is #ifdef DEBUG 989 1.1 is ++siopngints; 990 1.1 is #if 0 991 1.1 is if (siopng_debug & 0x100) { 992 1.1 is DCIAS(&acb->stat[0]); /* XXX */ 993 1.1 is printf ("siopngchkintr: istat %x dstat %x sist %x dsps %x sbcl %x sts %x msg %x\n", 994 1.1 is istat, dstat, sist, rp->siop_dsps, rp->siop_sbcl, acb->stat[0], acb->msg[0]); 995 1.1 is printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n", 996 1.1 is acb->msg[0], acb->msg[1], acb->msg[2], 997 1.1 is acb->msg[3], acb->msg[4], acb->msg[5]); 998 1.1 is } 999 1.1 is #endif 1000 1.1 is if (rp->siop_dsp && (rp->siop_dsp < sc->sc_scriptspa || 1001 1.2 is rp->siop_dsp >= sc->sc_scriptspa + sizeof(siopng_scripts))) { 1002 1.1 is printf ("%s: dsp not within script dsp %lx scripts %lx:%lx", 1003 1.41 chs device_xname(sc->sc_dev), rp->siop_dsp, sc->sc_scriptspa, 1004 1.2 is sc->sc_scriptspa + sizeof(siopng_scripts)); 1005 1.1 is printf(" istat %x dstat %x sist %x\n", 1006 1.1 is istat, dstat, sist); 1007 1.1 is #ifdef DDB 1008 1.1 is Debugger(); 1009 1.1 is #endif 1010 1.1 is } 1011 1.1 is #endif 1012 1.1 is SIOP_TRACE('i',dstat,istat,(istat&SIOP_ISTAT_DIP)?rp->siop_dsps&0xff:sist); 1013 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff00) { 1014 1.1 is /* Normal completion status, or check condition */ 1015 1.1 is #ifdef DEBUG 1016 1.27 christos if (rp->siop_dsa != kvtop((void *)&acb->ds)) { 1017 1.1 is printf ("siopng: invalid dsa: %lx %x\n", rp->siop_dsa, 1018 1.29 is (unsigned)kvtop((void *)&acb->ds)); 1019 1.1 is panic("*** siopng DSA invalid ***"); 1020 1.1 is } 1021 1.1 is #endif 1022 1.15 bouyer target = acb->xs->xs_periph->periph_target; 1023 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITW) { 1024 1.6 mhitch if (acb->msg[1] == 0xff) 1025 1.6 mhitch printf ("%s: target %d ignored wide request\n", 1026 1.41 chs device_xname(sc->sc_dev), target); 1027 1.6 mhitch else if (acb->msg[1] == MSG_REJECT) 1028 1.6 mhitch printf ("%s: target %d rejected wide request\n", 1029 1.41 chs device_xname(sc->sc_dev), target); 1030 1.6 mhitch else { 1031 1.6 mhitch printf("%s: target %d (wide) %02x %02x %02x %02x\n", 1032 1.41 chs device_xname(sc->sc_dev), target, acb->msg[1], 1033 1.6 mhitch acb->msg[2], acb->msg[3], acb->msg[4]); 1034 1.6 mhitch if (acb->msg[1] == MSG_EXT_MESSAGE && 1035 1.6 mhitch acb->msg[2] == 2 && 1036 1.6 mhitch acb->msg[3] == MSG_WIDE_REQ) 1037 1.6 mhitch sc->sc_sync[target].scntl3 = acb->msg[4] ? 1038 1.6 mhitch sc->sc_sync[target].scntl3 | SIOP_SCNTL3_EWS : 1039 1.6 mhitch sc->sc_sync[target].scntl3 & ~SIOP_SCNTL3_EWS; 1040 1.6 mhitch } 1041 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC; 1042 1.6 mhitch } 1043 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITS) { 1044 1.6 mhitch if (acb->msg[1] == 0xff) 1045 1.6 mhitch printf ("%s: target %d ignored sync request\n", 1046 1.41 chs device_xname(sc->sc_dev), target); 1047 1.6 mhitch else if (acb->msg[1] == MSG_REJECT) 1048 1.6 mhitch printf ("%s: target %d rejected sync request\n", 1049 1.41 chs device_xname(sc->sc_dev), target); 1050 1.6 mhitch else 1051 1.6 mhitch /* XXX - need to set sync transfer parameters */ 1052 1.6 mhitch printf("%s: target %d (sync) %02x %02x %02x\n", 1053 1.41 chs device_xname(sc->sc_dev), target, acb->msg[1], 1054 1.6 mhitch acb->msg[2], acb->msg[3]); 1055 1.6 mhitch sc->sc_sync[target].state = NEG_DONE; 1056 1.6 mhitch } 1057 1.6 mhitch dma_cachectl(&acb->stat[0], 1); 1058 1.6 mhitch *status = acb->stat[0]; 1059 1.6 mhitch #ifdef DEBUG 1060 1.6 mhitch if (rp->siop_sbcl & SIOP_BSY) { 1061 1.6 mhitch /*printf ("ACK! siop was busy at end: rp %x script %x dsa %x\n", 1062 1.6 mhitch rp, &siopng_scripts, &acb->ds);*/ 1063 1.6 mhitch #ifdef DDB 1064 1.6 mhitch /*Debugger();*/ 1065 1.6 mhitch #endif 1066 1.6 mhitch } 1067 1.6 mhitch if (acb->msg[0] != 0x00) 1068 1.6 mhitch printf("%s: message was not COMMAND COMPLETE: %x\n", 1069 1.41 chs device_xname(sc->sc_dev), acb->msg[0]); 1070 1.6 mhitch #endif 1071 1.6 mhitch if (sc->nexus_list.tqh_first) 1072 1.6 mhitch rp->siop_dcntl |= SIOP_DCNTL_STD; 1073 1.6 mhitch return 1; 1074 1.6 mhitch } 1075 1.6 mhitch if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff0b) { 1076 1.15 bouyer target = acb->xs->xs_periph->periph_target; 1077 1.6 mhitch if (acb->msg[1] == MSG_EXT_MESSAGE && acb->msg[2] == 2 && 1078 1.6 mhitch acb->msg[3] == MSG_WIDE_REQ) { 1079 1.6 mhitch #ifdef DEBUG 1080 1.6 mhitch if (siopngsync_debug) 1081 1.6 mhitch printf ("wide msg in: %02x %02x %02x %02x %02x %02x\n", 1082 1.6 mhitch acb->msg[0], acb->msg[1], acb->msg[2], 1083 1.6 mhitch acb->msg[3], acb->msg[4], acb->msg[5]); 1084 1.6 mhitch #endif 1085 1.6 mhitch sc->sc_sync[target].scntl3 &= ~(SIOP_SCNTL3_EWS); 1086 1.6 mhitch if (acb->msg[2] == 2 && 1087 1.6 mhitch acb->msg[3] == MSG_WIDE_REQ && 1088 1.6 mhitch acb->msg[4] != 0) { 1089 1.6 mhitch sc->sc_sync[target].scntl3 |= SIOP_SCNTL3_EWS; 1090 1.6 mhitch printf ("%s: target %d now wide %d\n", 1091 1.41 chs device_xname(sc->sc_dev), target, 1092 1.6 mhitch acb->msg[4]); 1093 1.6 mhitch } 1094 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3; 1095 1.38 phx amiga_membarrier(); 1096 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITW) { 1097 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC; 1098 1.6 mhitch rp->siop_dsp = sc->sc_scriptspa + Ent_clear_ack; 1099 1.38 phx amiga_membarrier(); 1100 1.6 mhitch return(0); 1101 1.6 mhitch } 1102 1.6 mhitch rp->siop_dcntl |= SIOP_DCNTL_STD; 1103 1.38 phx amiga_membarrier(); 1104 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC; 1105 1.6 mhitch return (0); 1106 1.6 mhitch } 1107 1.6 mhitch if (acb->msg[1] == MSG_EXT_MESSAGE && acb->msg[2] == 3 && 1108 1.6 mhitch acb->msg[3] == MSG_SYNC_REQ) { 1109 1.1 is #ifdef DEBUG 1110 1.1 is if (siopngsync_debug) 1111 1.1 is printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n", 1112 1.1 is acb->msg[0], acb->msg[1], acb->msg[2], 1113 1.1 is acb->msg[3], acb->msg[4], acb->msg[5]); 1114 1.1 is #endif 1115 1.1 is sc->sc_sync[target].sxfer = 0; 1116 1.6 mhitch sc->sc_sync[target].scntl3 = 5 | /* XXX */ 1117 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */ 1118 1.1 is if (acb->msg[2] == 3 && 1119 1.1 is acb->msg[3] == MSG_SYNC_REQ && 1120 1.1 is acb->msg[5] != 0) { 1121 1.1 is #ifdef MAXTOR_KLUDGE 1122 1.1 is /* 1123 1.1 is * Kludge for my Maxtor XT8580S 1124 1.1 is * It accepts whatever we request, even 1125 1.1 is * though it won't work. So we ask for 1126 1.1 is * a short period than we can handle. If 1127 1.1 is * the device says it can do it, use 208ns. 1128 1.1 is * If the device says it can do less than 1129 1.1 is * 100ns, then we limit it to 100ns. 1130 1.1 is */ 1131 1.1 is if (acb->msg[4] && acb->msg[4] < 100 / 4) { 1132 1.1 is #ifdef DEBUG 1133 1.1 is printf ("%d: target %d wanted %dns period\n", 1134 1.41 chs device_xname(sc->sc_dev), target, 1135 1.1 is acb->msg[4] * 4); 1136 1.1 is #endif 1137 1.1 is if (acb->msg[4] == 50 / 4) 1138 1.1 is acb->msg[4] = 208 / 4; 1139 1.1 is else 1140 1.1 is acb->msg[4] = 100 / 4; 1141 1.1 is } 1142 1.1 is #endif /* MAXTOR_KLUDGE */ 1143 1.1 is printf ("%s: target %d now synchronous, period=%dns, offset=%d\n", 1144 1.41 chs device_xname(sc->sc_dev), target, 1145 1.11 mhitch (acb->msg[4] == 12) ? 50 : acb->msg[4] * 4, 1146 1.11 mhitch acb->msg[5]); 1147 1.1 is scsi_period_to_siopng (sc, target); 1148 1.1 is } 1149 1.6 mhitch rp->siop_sxfer = sc->sc_sync[target].sxfer; 1150 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3; 1151 1.38 phx amiga_membarrier(); 1152 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITS) { 1153 1.6 mhitch sc->sc_sync[target].state = NEG_DONE; 1154 1.6 mhitch rp->siop_dsp = sc->sc_scriptspa + Ent_clear_ack; 1155 1.38 phx amiga_membarrier(); 1156 1.6 mhitch return(0); 1157 1.6 mhitch } 1158 1.6 mhitch rp->siop_dcntl |= SIOP_DCNTL_STD; 1159 1.38 phx amiga_membarrier(); 1160 1.6 mhitch sc->sc_sync[target].state = NEG_DONE; 1161 1.6 mhitch return (0); 1162 1.1 is } 1163 1.6 mhitch /* XXX - not SDTR message */ 1164 1.1 is } 1165 1.1 is if (sist & SIOP_SIST_MA) { /* Phase mismatch */ 1166 1.1 is #ifdef DEBUG 1167 1.1 is ++siopngphmm; 1168 1.1 is if (acb == NULL) 1169 1.1 is printf("%s: Phase mismatch with no active command?\n", 1170 1.41 chs device_xname(sc->sc_dev)); 1171 1.1 is #endif 1172 1.1 is if (acb->iob_len) { 1173 1.1 is int adjust; 1174 1.1 is adjust = ((dfifo - (dbc & 0x7f)) & 0x7f); 1175 1.6 mhitch if (sstat0 & SIOP_SSTAT0_OLF) /* sstat0 SODL lsb */ 1176 1.3 is ++adjust; 1177 1.9 mhitch if (sstat0 & SIOP_SSTAT0_ORF) /* sstat0 SODR lsb */ 1178 1.3 is ++adjust; 1179 1.6 mhitch if (sstat2 & SIOP_SSTAT2_OLF1) /* sstat2 SODL msb */ 1180 1.1 is ++adjust; 1181 1.9 mhitch if (sstat2 & SIOP_SSTAT2_ORF1) /* sstat2 SODR msb */ 1182 1.1 is ++adjust; 1183 1.24 jmc acb->iob_curlen = 1184 1.24 jmc *((long *)__UNVOLATILE(&rp->siop_dcmd)) & 0xffffff; 1185 1.1 is acb->iob_curlen += adjust; 1186 1.24 jmc acb->iob_curbuf = 1187 1.24 jmc *((long *)__UNVOLATILE(&rp->siop_dnad)) - adjust; 1188 1.1 is #ifdef DEBUG 1189 1.1 is if (siopng_debug & 0x100) { 1190 1.1 is int i; 1191 1.1 is printf ("Phase mismatch: curbuf %lx curlen %lx dfifo %x dbc %x sstat1 %x adjust %x sbcl %x starts %d acb %p\n", 1192 1.1 is acb->iob_curbuf, acb->iob_curlen, dfifo, 1193 1.1 is dbc, sstat1, adjust, rp->siop_sbcl, siopngstarts, acb); 1194 1.1 is if (acb->ds.chain[1].datalen) { 1195 1.1 is for (i = 0; acb->ds.chain[i].datalen; ++i) 1196 1.1 is printf("chain[%d] addr %p len %lx\n", 1197 1.1 is i, acb->ds.chain[i].databuf, 1198 1.1 is acb->ds.chain[i].datalen); 1199 1.1 is } 1200 1.1 is } 1201 1.1 is #endif 1202 1.27 christos dma_cachectl ((void *)acb, sizeof(*acb)); 1203 1.1 is } 1204 1.1 is #ifdef DEBUG 1205 1.1 is SIOP_TRACE('m',rp->siop_sbcl,(rp->siop_dsp>>8),rp->siop_dsp); 1206 1.1 is if (siopng_debug & 9) 1207 1.1 is printf ("Phase mismatch: %x dsp +%lx dcmd %lx\n", 1208 1.1 is rp->siop_sbcl, 1209 1.1 is rp->siop_dsp - sc->sc_scriptspa, 1210 1.28 mhitch *((volatile long *)&rp->siop_dcmd)); 1211 1.1 is #endif 1212 1.1 is if ((rp->siop_sbcl & SIOP_REQ) == 0) { 1213 1.1 is printf ("Phase mismatch: REQ not asserted! %02x dsp %lx\n", 1214 1.1 is rp->siop_sbcl, rp->siop_dsp); 1215 1.1 is #if defined(DEBUG) && defined(DDB) 1216 1.1 is Debugger(); 1217 1.1 is #endif 1218 1.1 is } 1219 1.1 is switch (rp->siop_sbcl & 7) { 1220 1.1 is case 0: /* data out */ 1221 1.1 is case 1: /* data in */ 1222 1.1 is case 2: /* status */ 1223 1.1 is case 3: /* command */ 1224 1.1 is case 6: /* message in */ 1225 1.1 is case 7: /* message out */ 1226 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_switch; 1227 1.38 phx amiga_membarrier(); 1228 1.1 is break; 1229 1.1 is default: 1230 1.1 is goto bad_phase; 1231 1.1 is } 1232 1.1 is return 0; 1233 1.1 is } 1234 1.1 is if (sist & SIOP_SIST_STO) { /* Select timed out */ 1235 1.1 is #ifdef DEBUG 1236 1.1 is if (acb == NULL) 1237 1.1 is printf("%s: Select timeout with no active command?\n", 1238 1.41 chs device_xname(sc->sc_dev)); 1239 1.1 is if (rp->siop_sbcl & SIOP_BSY) { 1240 1.1 is printf ("ACK! siop was busy at timeout: rp %p script %p dsa %p\n", 1241 1.2 is rp, &siopng_scripts, &acb->ds); 1242 1.1 is printf(" sbcl %x sdid %x istat %x dstat %x sist %x\n", 1243 1.1 is rp->siop_sbcl, rp->siop_sdid, istat, dstat, sist); 1244 1.1 is if (!(rp->siop_sbcl & SIOP_BSY)) { 1245 1.1 is printf ("Yikes, it's not busy now!\n"); 1246 1.1 is #if 0 1247 1.1 is *status = -1; 1248 1.38 phx if (sc->nexus_list.tqh_first) { 1249 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect; 1250 1.38 phx amiga_membarrier(); 1251 1.38 phx } 1252 1.1 is return 1; 1253 1.1 is #endif 1254 1.1 is } 1255 1.1 is /* rp->siop_dcntl |= SIOP_DCNTL_STD;*/ 1256 1.1 is return (0); 1257 1.1 is } 1258 1.1 is #endif 1259 1.1 is *status = -1; 1260 1.1 is acb->xs->error = XS_SELTIMEOUT; 1261 1.38 phx if (sc->nexus_list.tqh_first) { 1262 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect; 1263 1.38 phx amiga_membarrier(); 1264 1.38 phx } 1265 1.1 is return 1; 1266 1.1 is } 1267 1.1 is if (acb) 1268 1.15 bouyer target = acb->xs->xs_periph->periph_target; 1269 1.1 is else 1270 1.1 is target = 7; 1271 1.1 is if (sist & SIOP_SIST_UDC) { 1272 1.1 is #ifdef DEBUG 1273 1.1 is if (acb == NULL) 1274 1.1 is printf("%s: Unexpected disconnect with no active command?\n", 1275 1.41 chs device_xname(sc->sc_dev)); 1276 1.1 is printf ("%s: target %d disconnected unexpectedly\n", 1277 1.41 chs device_xname(sc->sc_dev), target); 1278 1.1 is siopng_dump_registers(sc); 1279 1.1 is siopng_dump(sc); 1280 1.1 is #endif 1281 1.1 is #if 0 1282 1.1 is siopngabort (sc, rp, "siopngchkintr"); 1283 1.1 is #endif 1284 1.1 is *status = STS_BUSY; 1285 1.38 phx if (sc->nexus_list.tqh_first) { 1286 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect; 1287 1.38 phx amiga_membarrier(); 1288 1.38 phx } 1289 1.1 is return (acb != NULL); 1290 1.1 is } 1291 1.1 is if (dstat & SIOP_DSTAT_SIR && (rp->siop_dsps == 0xff01 || 1292 1.1 is rp->siop_dsps == 0xff02)) { 1293 1.1 is #ifdef DEBUG 1294 1.1 is if (siopng_debug & 0x100) 1295 1.1 is printf ("%s: ID %02x disconnected TEMP %lx (+%lx) curbuf %lx curlen %lx buf %p len %lx dfifo %x dbc %x sstat1 %x starts %d acb %p\n", 1296 1.41 chs device_xname(sc->sc_dev), 1 << target, rp->siop_temp, 1297 1.1 is rp->siop_temp ? rp->siop_temp - sc->sc_scriptspa : 0, 1298 1.1 is acb->iob_curbuf, acb->iob_curlen, 1299 1.1 is acb->ds.chain[0].databuf, acb->ds.chain[0].datalen, dfifo, dbc, sstat1, siopngstarts, acb); 1300 1.1 is #endif 1301 1.1 is if (acb == NULL) { 1302 1.1 is printf("%s: Disconnect with no active command?\n", 1303 1.41 chs device_xname(sc->sc_dev)); 1304 1.1 is return (0); 1305 1.1 is } 1306 1.1 is /* 1307 1.1 is * XXXX need to update iob_curbuf/iob_curlen to reflect 1308 1.1 is * current data transferred. If device disconnected in 1309 1.1 is * the middle of a DMA block, they should already be set 1310 1.1 is * by the phase change interrupt. If the disconnect 1311 1.1 is * occurs on a DMA block boundary, we have to figure out 1312 1.1 is * which DMA block it was. 1313 1.1 is */ 1314 1.1 is if (acb->iob_len && rp->siop_temp) { 1315 1.1 is int n = rp->siop_temp - sc->sc_scriptspa; 1316 1.1 is 1317 1.1 is if (acb->iob_curlen && acb->iob_curlen != acb->ds.chain[0].datalen) 1318 1.1 is printf("%s: iob_curbuf/len already set? n %x iob %lx/%lx chain[0] %p/%lx\n", 1319 1.41 chs device_xname(sc->sc_dev), n, acb->iob_curbuf, acb->iob_curlen, 1320 1.1 is acb->ds.chain[0].databuf, acb->ds.chain[0].datalen); 1321 1.1 is if (n < Ent_datain) 1322 1.1 is n = (n - Ent_dataout) / 16; 1323 1.1 is else 1324 1.1 is n = (n - Ent_datain) / 16; 1325 1.1 is if (n <= 0 && n > DMAMAXIO) 1326 1.1 is printf("TEMP invalid %d\n", n); 1327 1.1 is else { 1328 1.1 is acb->iob_curbuf = (u_long)acb->ds.chain[n].databuf; 1329 1.1 is acb->iob_curlen = acb->ds.chain[n].datalen; 1330 1.1 is } 1331 1.1 is #ifdef DEBUG 1332 1.1 is if (siopng_debug & 0x100) { 1333 1.41 chs printf("%s: TEMP offset %d", device_xname(sc->sc_dev), n); 1334 1.1 is printf(" curbuf %lx curlen %lx\n", acb->iob_curbuf, 1335 1.1 is acb->iob_curlen); 1336 1.1 is } 1337 1.1 is #endif 1338 1.1 is } 1339 1.1 is /* 1340 1.1 is * If data transfer was interrupted by disconnect, iob_curbuf 1341 1.1 is * and iob_curlen should reflect the point of interruption. 1342 1.1 is * Adjust the DMA chain so that the data transfer begins 1343 1.1 is * at the appropriate place upon reselection. 1344 1.1 is * XXX This should only be done on save data pointer message? 1345 1.1 is */ 1346 1.1 is if (acb->iob_curlen) { 1347 1.1 is int i, j; 1348 1.1 is 1349 1.1 is #ifdef DEBUG 1350 1.1 is if (siopng_debug & 0x100) 1351 1.1 is printf ("%s: adjusting DMA chain\n", 1352 1.41 chs device_xname(sc->sc_dev)); 1353 1.1 is if (rp->siop_dsps == 0xff02) 1354 1.1 is printf ("%s: ID %02x disconnected without Save Data Pointers\n", 1355 1.41 chs device_xname(sc->sc_dev), 1 << target); 1356 1.1 is #endif 1357 1.1 is for (i = 0; i < DMAMAXIO; ++i) { 1358 1.1 is if (acb->ds.chain[i].datalen == 0) 1359 1.1 is break; 1360 1.1 is if (acb->iob_curbuf >= (long)acb->ds.chain[i].databuf && 1361 1.1 is acb->iob_curbuf < (long)(acb->ds.chain[i].databuf + 1362 1.1 is acb->ds.chain[i].datalen)) 1363 1.1 is break; 1364 1.1 is } 1365 1.1 is if (i >= DMAMAXIO || acb->ds.chain[i].datalen == 0) { 1366 1.1 is printf("couldn't find saved data pointer: "); 1367 1.1 is printf("curbuf %lx curlen %lx i %d\n", 1368 1.1 is acb->iob_curbuf, acb->iob_curlen, i); 1369 1.1 is #ifdef DDB 1370 1.1 is Debugger(); 1371 1.1 is #endif 1372 1.1 is } 1373 1.1 is #ifdef DEBUG 1374 1.1 is if (siopng_debug & 0x100) 1375 1.1 is printf(" chain[0]: %p/%lx -> %lx/%lx\n", 1376 1.1 is acb->ds.chain[0].databuf, 1377 1.1 is acb->ds.chain[0].datalen, 1378 1.1 is acb->iob_curbuf, 1379 1.1 is acb->iob_curlen); 1380 1.1 is #endif 1381 1.1 is acb->ds.chain[0].databuf = (char *)acb->iob_curbuf; 1382 1.1 is acb->ds.chain[0].datalen = acb->iob_curlen; 1383 1.1 is for (j = 1, ++i; i < DMAMAXIO && acb->ds.chain[i].datalen; ++i, ++j) { 1384 1.1 is #ifdef DEBUG 1385 1.1 is if (siopng_debug & 0x100) 1386 1.1 is printf(" chain[%d]: %p/%lx -> %p/%lx\n", j, 1387 1.1 is acb->ds.chain[j].databuf, 1388 1.1 is acb->ds.chain[j].datalen, 1389 1.1 is acb->ds.chain[i].databuf, 1390 1.1 is acb->ds.chain[i].datalen); 1391 1.1 is #endif 1392 1.1 is acb->ds.chain[j].databuf = acb->ds.chain[i].databuf; 1393 1.1 is acb->ds.chain[j].datalen = acb->ds.chain[i].datalen; 1394 1.1 is } 1395 1.1 is if (j < DMAMAXIO) 1396 1.1 is acb->ds.chain[j].datalen = 0; 1397 1.27 christos DCIAS(kvtop((void *)&acb->ds.chain)); 1398 1.1 is } 1399 1.1 is ++sc->sc_tinfo[target].dconns; 1400 1.1 is /* 1401 1.1 is * add nexus to waiting list 1402 1.1 is * clear nexus 1403 1.1 is * try to start another command for another target/lun 1404 1.1 is */ 1405 1.1 is acb->status = sc->sc_flags & SIOP_INTSOFF; 1406 1.1 is TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain); 1407 1.1 is sc->sc_nexus = NULL; /* no current device */ 1408 1.1 is /* start script to wait for reselect */ 1409 1.38 phx if (sc->sc_nexus == NULL) { 1410 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect; 1411 1.38 phx amiga_membarrier(); 1412 1.38 phx } 1413 1.1 is /* XXXX start another command ? */ 1414 1.1 is if (sc->ready_list.tqh_first) 1415 1.1 is siopng_sched(sc); 1416 1.1 is #if 0 1417 1.1 is else 1418 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD; 1419 1.1 is #endif 1420 1.1 is return (0); 1421 1.1 is } 1422 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff03) { 1423 1.1 is int reselid = rp->siop_scratcha & 0x7f; 1424 1.1 is int reselun = rp->siop_sfbr & 0x07; 1425 1.1 is 1426 1.1 is sc->sc_sstat1 = rp->siop_sbcl; /* XXXX save current SBCL */ 1427 1.1 is #ifdef DEBUG 1428 1.1 is if (siopng_debug & 0x100) 1429 1.1 is printf ("%s: target ID %02x reselected dsps %lx\n", 1430 1.41 chs device_xname(sc->sc_dev), reselid, 1431 1.1 is rp->siop_dsps); 1432 1.1 is if ((rp->siop_sfbr & 0x80) == 0) 1433 1.1 is printf("%s: Reselect message in was not identify: %x\n", 1434 1.41 chs device_xname(sc->sc_dev), rp->siop_sfbr); 1435 1.1 is #endif 1436 1.1 is if (sc->sc_nexus) { 1437 1.1 is #ifdef DEBUG 1438 1.1 is if (siopng_debug & 0x100) 1439 1.1 is printf ("%s: reselect ID %02x w/active\n", 1440 1.41 chs device_xname(sc->sc_dev), reselid); 1441 1.1 is #endif 1442 1.1 is TAILQ_INSERT_HEAD(&sc->ready_list, sc->sc_nexus, chain); 1443 1.15 bouyer sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target].lubusy 1444 1.15 bouyer &= ~(1 << sc->sc_nexus->xs->xs_periph->periph_lun); 1445 1.1 is --sc->sc_active; 1446 1.1 is } 1447 1.1 is /* 1448 1.1 is * locate acb of reselecting device 1449 1.1 is * set sc->sc_nexus to acb 1450 1.1 is */ 1451 1.1 is for (acb = sc->nexus_list.tqh_first; acb; 1452 1.1 is acb = acb->chain.tqe_next) { 1453 1.1 is if (reselid != ((acb->ds.scsi_addr >> 16) & 0xff) || 1454 1.1 is reselun != (acb->msgout[0] & 0x07)) 1455 1.1 is continue; 1456 1.1 is TAILQ_REMOVE(&sc->nexus_list, acb, chain); 1457 1.1 is sc->sc_nexus = acb; 1458 1.1 is sc->sc_flags |= acb->status; 1459 1.1 is acb->status = 0; 1460 1.1 is DCIAS(kvtop(&acb->stat[0])); 1461 1.27 christos rp->siop_dsa = kvtop((void *)&acb->ds); 1462 1.38 phx amiga_membarrier(); 1463 1.1 is rp->siop_sxfer = 1464 1.15 bouyer sc->sc_sync[acb->xs->xs_periph->periph_target].sxfer; 1465 1.1 is #ifndef FIXME 1466 1.1 is rp->siop_scntl3 = 1467 1.15 bouyer sc->sc_sync[acb->xs->xs_periph->periph_target].scntl3; 1468 1.38 phx amiga_membarrier(); 1469 1.1 is #endif 1470 1.1 is break; 1471 1.1 is } 1472 1.1 is if (acb == NULL) { 1473 1.1 is printf("%s: target ID %02x reselect nexus_list %p\n", 1474 1.41 chs device_xname(sc->sc_dev), reselid, 1475 1.1 is sc->nexus_list.tqh_first); 1476 1.1 is panic("unable to find reselecting device"); 1477 1.1 is } 1478 1.27 christos dma_cachectl ((void *)acb, sizeof(*acb)); 1479 1.1 is rp->siop_temp = 0; 1480 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD; 1481 1.38 phx amiga_membarrier(); 1482 1.1 is return (0); 1483 1.1 is } 1484 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff04) { 1485 1.1 is #ifdef DEBUG 1486 1.1 is u_short ctest2 = rp->siop_ctest2; 1487 1.1 is 1488 1.1 is /* reselect was interrupted (by Sig_P or select) */ 1489 1.1 is if (siopng_debug & 0x100 || 1490 1.1 is (ctest2 & SIOP_CTEST2_SIGP) == 0) 1491 1.1 is printf ("%s: reselect interrupted (Sig_P?) scntl1 %x ctest2 %x sfbr %x istat %x/%x\n", 1492 1.41 chs device_xname(sc->sc_dev), rp->siop_scntl1, 1493 1.1 is ctest2, rp->siop_sfbr, istat, rp->siop_istat); 1494 1.1 is #endif 1495 1.1 is /* XXX assumes it was not select */ 1496 1.1 is if (sc->sc_nexus == NULL) { 1497 1.1 is #ifdef DEBUG 1498 1.1 is printf("%s: reselect interrupted, sc_nexus == NULL\n", 1499 1.41 chs device_xname(sc->sc_dev)); 1500 1.1 is #if 0 1501 1.1 is siopng_dump(sc); 1502 1.1 is #ifdef DDB 1503 1.1 is Debugger(); 1504 1.1 is #endif 1505 1.1 is #endif 1506 1.1 is #endif 1507 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD; 1508 1.1 is return(0); 1509 1.1 is } 1510 1.15 bouyer target = sc->sc_nexus->xs->xs_periph->periph_target; 1511 1.1 is rp->siop_temp = 0; 1512 1.27 christos rp->siop_dsa = kvtop((void *)&sc->sc_nexus->ds); 1513 1.38 phx amiga_membarrier(); 1514 1.1 is rp->siop_sxfer = sc->sc_sync[target].sxfer; 1515 1.1 is #ifndef FIXME 1516 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3; 1517 1.38 phx amiga_membarrier(); 1518 1.1 is #endif 1519 1.1 is rp->siop_dsp = sc->sc_scriptspa; 1520 1.38 phx amiga_membarrier(); 1521 1.1 is return (0); 1522 1.1 is } 1523 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff06) { 1524 1.1 is if (acb == NULL) 1525 1.1 is printf("%s: Bad message-in with no active command?\n", 1526 1.41 chs device_xname(sc->sc_dev)); 1527 1.1 is /* Unrecognized message in byte */ 1528 1.1 is dma_cachectl (&acb->msg[1],1); 1529 1.1 is printf ("%s: Unrecognized message in data sfbr %x msg %x sbcl %x\n", 1530 1.41 chs device_xname(sc->sc_dev), rp->siop_sfbr, acb->msg[1], rp->siop_sbcl); 1531 1.1 is /* what should be done here? */ 1532 1.1 is DCIAS(kvtop(&acb->msg[1])); 1533 1.31 mhitch rp->siop_dsp = sc->sc_scriptspa + Ent_clear_ack; 1534 1.38 phx amiga_membarrier(); 1535 1.1 is return (0); 1536 1.1 is } 1537 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff0a) { 1538 1.1 is /* Status phase wasn't followed by message in phase? */ 1539 1.1 is printf ("%s: Status phase not followed by message in phase? sbcl %x sbdl %x\n", 1540 1.41 chs device_xname(sc->sc_dev), rp->siop_sbcl, rp->siop_sbdl); 1541 1.1 is if (rp->siop_sbcl == 0xa7) { 1542 1.1 is /* It is now, just continue the script? */ 1543 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD; 1544 1.1 is return (0); 1545 1.1 is } 1546 1.1 is } 1547 1.1 is if (sist == 0 && dstat & SIOP_DSTAT_SIR) { 1548 1.1 is dma_cachectl (&acb->stat[0], 1); 1549 1.1 is dma_cachectl (&acb->msg[0], 1); 1550 1.1 is printf ("SIOP interrupt: %lx sts %x msg %x %x sbcl %x\n", 1551 1.1 is rp->siop_dsps, acb->stat[0], acb->msg[0], acb->msg[1], 1552 1.1 is rp->siop_sbcl); 1553 1.1 is siopngreset (sc); 1554 1.1 is *status = -1; 1555 1.1 is return 0; /* siopngreset has cleaned up */ 1556 1.1 is } 1557 1.1 is if (sist & SIOP_SIST_SGE) 1558 1.1 is printf ("SIOP: SCSI Gross Error\n"); 1559 1.1 is if (sist & SIOP_SIST_PAR) 1560 1.1 is printf ("SIOP: Parity Error\n"); 1561 1.1 is if (dstat & SIOP_DSTAT_IID) 1562 1.1 is printf ("SIOP: Invalid instruction detected\n"); 1563 1.1 is bad_phase: 1564 1.1 is /* 1565 1.1 is * temporary panic for unhandled conditions 1566 1.1 is * displays various things about the 53C720/770 status and registers 1567 1.1 is * then panics. 1568 1.1 is * XXXX need to clean this up to print out the info, reset, and continue 1569 1.1 is */ 1570 1.1 is printf ("siopngchkintr: target %x ds %p\n", target, &acb->ds); 1571 1.29 is printf ("scripts %lx ds %x rp %x dsp %lx dcmd %lx\n", 1572 1.29 is sc->sc_scriptspa, (unsigned)kvtop((void *)&acb->ds), 1573 1.29 is (unsigned)kvtop((void *)__UNVOLATILE(rp)), rp->siop_dsp, 1574 1.29 is *((long *)__UNVOLATILE(&rp->siop_dcmd))); 1575 1.1 is printf ("siopngchkintr: istat %x dstat %x sist %x dsps %lx dsa %lx sbcl %x sts %x msg %x %x sfbr %x\n", 1576 1.1 is istat, dstat, sist, rp->siop_dsps, rp->siop_dsa, 1577 1.1 is rp->siop_sbcl, acb->stat[0], acb->msg[0], acb->msg[1], rp->siop_sfbr); 1578 1.1 is #ifdef DEBUG 1579 1.1 is if (siopng_debug & 0x20) 1580 1.1 is panic("siopngchkintr: **** temp ****"); 1581 1.1 is #endif 1582 1.1 is #ifdef DDB 1583 1.1 is Debugger (); 1584 1.1 is #endif 1585 1.1 is siopngreset (sc); /* hard reset */ 1586 1.1 is *status = -1; 1587 1.1 is return 0; /* siopngreset cleaned up */ 1588 1.1 is } 1589 1.1 is 1590 1.1 is void 1591 1.17 aymeric siopng_select(struct siop_softc *sc) 1592 1.1 is { 1593 1.1 is siop_regmap_p rp; 1594 1.1 is struct siop_acb *acb = sc->sc_nexus; 1595 1.1 is 1596 1.1 is #ifdef DEBUG 1597 1.1 is if (siopng_debug & 1) 1598 1.41 chs printf ("%s: select ", device_xname(sc->sc_dev)); 1599 1.1 is #endif 1600 1.1 is 1601 1.1 is rp = sc->sc_siopp; 1602 1.14 thorpej if (acb->xs->xs_control & XS_CTL_POLL || siopng_no_dma) { 1603 1.1 is sc->sc_flags |= SIOP_INTSOFF; 1604 1.1 is sc->sc_flags &= ~SIOP_INTDEFER; 1605 1.1 is if ((rp->siop_istat & 0x08) == 0) { 1606 1.1 is rp->siop_sien = 0; 1607 1.1 is rp->siop_dien = 0; 1608 1.1 is } 1609 1.1 is #if 0 1610 1.1 is } else if ((sc->sc_flags & SIOP_INTDEFER) == 0) { 1611 1.1 is sc->sc_flags &= ~SIOP_INTSOFF; 1612 1.1 is if ((rp->siop_istat & 0x08) == 0) { 1613 1.1 is rp->siop_sien = sc->sc_sien; 1614 1.1 is rp->siop_dien = sc->sc_dien; 1615 1.1 is } 1616 1.1 is #endif 1617 1.1 is } 1618 1.1 is #ifdef DEBUG 1619 1.1 is if (siopng_debug & 1) 1620 1.1 is printf ("siopng_select: target %x cmd %02x ds %p\n", 1621 1.15 bouyer acb->xs->xs_periph->periph_target, acb->cmd.opcode, 1622 1.1 is &sc->sc_nexus->ds); 1623 1.1 is #endif 1624 1.1 is 1625 1.15 bouyer siopng_start(sc, acb->xs->xs_periph->periph_target, 1626 1.15 bouyer acb->xs->xs_periph->periph_lun, 1627 1.1 is (u_char *)&acb->cmd, acb->clen, acb->daddr, acb->dleft); 1628 1.1 is 1629 1.1 is return; 1630 1.1 is } 1631 1.1 is 1632 1.1 is /* 1633 1.1 is * 53C720/770 interrupt handler 1634 1.1 is */ 1635 1.1 is 1636 1.1 is void 1637 1.17 aymeric siopngintr(register struct siop_softc *sc) 1638 1.1 is { 1639 1.1 is siop_regmap_p rp; 1640 1.1 is u_char istat, dstat; 1641 1.1 is u_short sist; 1642 1.1 is int status; 1643 1.1 is int s = splbio(); 1644 1.1 is 1645 1.1 is istat = sc->sc_istat; 1646 1.1 is if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) { 1647 1.1 is splx(s); 1648 1.1 is return; 1649 1.1 is } 1650 1.1 is 1651 1.1 is /* Got a valid interrupt on this device */ 1652 1.1 is rp = sc->sc_siopp; 1653 1.1 is dstat = sc->sc_dstat; 1654 1.1 is sist = sc->sc_sist; 1655 1.1 is if (dstat & SIOP_DSTAT_SIR) 1656 1.1 is sc->sc_intcode = rp->siop_dsps; 1657 1.1 is sc->sc_istat = 0; 1658 1.1 is #ifdef DEBUG 1659 1.1 is if (siopng_debug & 1) 1660 1.1 is printf ("%s: intr istat %x dstat %x sist %x\n", 1661 1.41 chs device_xname(sc->sc_dev), istat, dstat, sist); 1662 1.1 is if (!sc->sc_active) { 1663 1.1 is printf ("%s: spurious interrupt? istat %x dstat %x sist %x nexus %p status %x\n", 1664 1.41 chs device_xname(sc->sc_dev), istat, dstat, sist, 1665 1.1 is sc->sc_nexus, sc->sc_nexus ? sc->sc_nexus->stat[0] : 0); 1666 1.1 is } 1667 1.1 is #endif 1668 1.1 is 1669 1.1 is #ifdef DEBUG 1670 1.1 is if (siopng_debug & 5) { 1671 1.1 is DCIAS(kvtop(&sc->sc_nexus->stat[0])); 1672 1.1 is printf ("%s: intr istat %x dstat %x sist %x dsps %lx sbcl %x sts %x msg %x\n", 1673 1.41 chs device_xname(sc->sc_dev), istat, dstat, sist, 1674 1.1 is rp->siop_dsps, rp->siop_sbcl, 1675 1.1 is sc->sc_nexus->stat[0], sc->sc_nexus->msg[0]); 1676 1.1 is } 1677 1.1 is #endif 1678 1.1 is if (sc->sc_flags & SIOP_INTDEFER) { 1679 1.1 is sc->sc_flags &= ~(SIOP_INTDEFER | SIOP_INTSOFF); 1680 1.1 is rp->siop_sien = sc->sc_sien; 1681 1.1 is rp->siop_dien = sc->sc_dien; 1682 1.1 is } 1683 1.1 is if (siopng_checkintr (sc, istat, dstat, sist, &status)) { 1684 1.1 is #if 1 1685 1.1 is if (status == 0xff) 1686 1.1 is printf ("siopngintr: status == 0xff\n"); 1687 1.1 is #endif 1688 1.1 is if ((sc->sc_flags & (SIOP_INTSOFF | SIOP_INTDEFER)) != SIOP_INTSOFF) { 1689 1.1 is #if 0 1690 1.1 is if (rp->siop_sbcl & SIOP_BSY) { 1691 1.1 is printf ("%s: SCSI bus busy at completion", 1692 1.41 chs device_xname(sc->sc_dev)); 1693 1.1 is printf(" targ %d sbcl %02x sfbr %x respid %02x dsp +%x\n", 1694 1.15 bouyer sc->sc_nexus->xs->xs_periph->periph_target, 1695 1.1 is rp->siop_sbcl, rp->siop_sfbr, rp->siop_respid, 1696 1.1 is rp->siop_dsp - sc->sc_scriptspa); 1697 1.1 is } 1698 1.1 is #endif 1699 1.1 is siopng_scsidone(sc->sc_nexus, sc->sc_nexus ? 1700 1.1 is sc->sc_nexus->stat[0] : -1); 1701 1.1 is } 1702 1.1 is } 1703 1.1 is splx(s); 1704 1.1 is } 1705 1.1 is 1706 1.1 is /* 1707 1.26 lukem * This is based on the Progressive Peripherals 33 MHz Zeus driver and will 1708 1.1 is * not be correct for other 53c710 boards. 1709 1.1 is * 1710 1.1 is */ 1711 1.1 is void 1712 1.17 aymeric scsi_period_to_siopng(struct siop_softc *sc, int target) 1713 1.1 is { 1714 1.1 is int period, offset, sxfer, scntl3 = 0; 1715 1.1 is 1716 1.1 is period = sc->sc_nexus->msg[4]; 1717 1.1 is offset = sc->sc_nexus->msg[5]; 1718 1.1 is #ifdef FIXME 1719 1.1 is for (scntl3 = 1; scntl3 < 4; ++scntl3) { 1720 1.1 is sxfer = (period * 4 - 1) / sc->sc_tcp[scntl3] - 3; 1721 1.1 is if (sxfer >= 0 && sxfer <= 7) 1722 1.1 is break; 1723 1.1 is } 1724 1.1 is if (scntl3 > 3) { 1725 1.1 is printf("siopng sync: unable to compute sync params for period %dns\n", 1726 1.1 is period * 4); 1727 1.1 is /* 1728 1.1 is * XXX need to pick a value we can do and renegotiate 1729 1.1 is */ 1730 1.1 is sxfer = scntl3 = 0; 1731 1.1 is } else { 1732 1.1 is sxfer = (sxfer << 4) | ((offset <= SIOP_MAX_OFFSET) ? 1733 1.1 is offset : SIOP_MAX_OFFSET); 1734 1.1 is #ifdef DEBUG_SYNC 1735 1.1 is printf("siopng sync: params for period %dns: sxfer %x scntl3 %x", 1736 1.1 is period * 4, sxfer, scntl3); 1737 1.1 is printf(" actual period %dns\n", 1738 1.1 is sc->sc_tcp[scntl3] * ((sxfer >> 4) + 4)); 1739 1.1 is #endif /* DEBUG_SYNC */ 1740 1.1 is } 1741 1.1 is #else /* FIXME */ 1742 1.1 is sxfer = offset <= SIOP_MAX_OFFSET ? offset : SIOP_MAX_OFFSET; 1743 1.6 mhitch sxfer |= 0x20; /* XXX XFERP: 5 */ 1744 1.1 is #ifndef FIXME 1745 1.6 mhitch if (period <= (50 / 4)) /* XXX */ 1746 1.6 mhitch scntl3 = 0x95; /* Ultra, SCF: /1, CCF: /4 */ 1747 1.6 mhitch else if (period <= (100 / 4)) 1748 1.6 mhitch scntl3 = 0x35; /* SCF: /2, CCF: /4 */ 1749 1.6 mhitch else if (period <= (200 / 4)) 1750 1.6 mhitch scntl3 = 0x55; /* SCF: /4, CCF: /4 */ 1751 1.6 mhitch else 1752 1.6 mhitch scntl3 = 0xff; /* XXX ??? */ 1753 1.1 is #else 1754 1.1 is scntl3 = 5; 1755 1.1 is #endif 1756 1.1 is #endif 1757 1.1 is sc->sc_sync[target].sxfer = sxfer; 1758 1.6 mhitch sc->sc_sync[target].scntl3 = scntl3 | 1759 1.6 mhitch (sc->sc_sync[target].scntl3 & SIOP_SCNTL3_EWS); 1760 1.1 is #ifdef DEBUG_SYNC 1761 1.1 is printf ("siopng sync: siop_sxfr %02x, siop_scntl3 %02x\n", sxfer, scntl3); 1762 1.1 is #endif 1763 1.1 is } 1764 1.1 is 1765 1.1 is void 1766 1.17 aymeric siopng_dump_registers(struct siop_softc *sc) 1767 1.1 is { 1768 1.1 is siop_regmap_p rp = sc->sc_siopp; 1769 1.1 is 1770 1.1 is printf(" scntl0 %02x scntl1 %02x scntl2 %02x scntl3 %02x\n", 1771 1.1 is rp->siop_scntl0, rp->siop_scntl1, rp->siop_scntl2, rp->siop_scntl3); 1772 1.1 is printf(" scid %02x sxfer %02x sdid %02x gpreg %02x\n", 1773 1.1 is rp->siop_scid, rp->siop_sxfer, rp->siop_sdid, rp->siop_gpreg); 1774 1.1 is printf(" sfbr %02x socl %02x ssid %02x sbcl %02x\n", 1775 1.1 is rp->siop_sfbr, rp->siop_socl, rp->siop_ssid, rp->siop_sbcl); 1776 1.1 is printf(" dstat %02x sstat0 %02x sstat1 %02x sstat2 %02x\n", 1777 1.1 is rp->siop_dstat, rp->siop_sstat0, rp->siop_sstat1, rp->siop_sstat2); 1778 1.1 is printf(" ctest0 %02x ctest1 %02x ctest2 %02x ctest3 %02x\n", 1779 1.1 is rp->siop_ctest0, rp->siop_ctest1, rp->siop_ctest2, rp->siop_ctest3); 1780 1.1 is printf(" dfifo %02x ctest4 %02x ctest5 %02x ctest6 %02x\n", 1781 1.1 is 0, rp->siop_ctest4, rp->siop_ctest5, rp->siop_ctest6); 1782 1.1 is printf(" dcmd %02x dbc2 %02x dbc1 %02x dbc0 %02x\n", 1783 1.1 is rp->siop_dcmd, rp->siop_dbc2, rp->siop_dbc1, rp->siop_dbc0); 1784 1.1 is printf(" dmode %02x dien %02x dwt %02x dcntl %02x\n", 1785 1.1 is rp->siop_dmode, rp->siop_dien, rp->siop_dwt, rp->siop_dcntl); 1786 1.1 is printf(" stest0 %02x stest1 %02x stest2 %02x stest3 %02x\n", 1787 1.1 is rp->siop_stest0, rp->siop_stest1, rp->siop_stest2, rp->siop_stest3); 1788 1.1 is printf(" istat %02x sien %04x sist %04x respid %04x\n", 1789 1.1 is rp->siop_istat, rp->siop_sien, rp->siop_sist, rp->siop_respid); 1790 1.1 is printf(" sidl %04x sodl %04x sbdl %04x\n", 1791 1.1 is rp->siop_sidl, rp->siop_sodl, rp->siop_sbdl); 1792 1.1 is printf(" dsps %08lx dsp %08lx (+%lx)\n", 1793 1.1 is rp->siop_dsps, rp->siop_dsp, rp->siop_dsp > sc->sc_scriptspa ? 1794 1.1 is rp->siop_dsp - sc->sc_scriptspa : 0); 1795 1.1 is printf(" dsa %08lx temp %08lx dnad %08lx\n", 1796 1.1 is rp->siop_dsa, rp->siop_temp, rp->siop_dnad); 1797 1.1 is printf(" scratcha %08lx scratchb %08lx adder %08lx\n", 1798 1.1 is rp->siop_scratcha, rp->siop_scratchb, rp->siop_adder); 1799 1.1 is } 1800 1.1 is 1801 1.1 is #ifdef DEBUG 1802 1.1 is 1803 1.1 is #if SIOP_TRACE_SIZE 1804 1.1 is void 1805 1.17 aymeric siopng_dump_trace(void) 1806 1.1 is { 1807 1.1 is int i; 1808 1.1 is 1809 1.1 is printf("siopng trace: next index %d\n", siopng_trix); 1810 1.1 is i = siopng_trix; 1811 1.1 is do { 1812 1.1 is printf("%3d: '%c' %02x %02x %02x\n", i, siopng_trbuf[i], 1813 1.1 is siopng_trbuf[i + 1], siopng_trbuf[i + 2], siopng_trbuf[i + 3]); 1814 1.1 is i = (i + 4) & (SIOP_TRACE_SIZE - 1); 1815 1.1 is } while (i != siopng_trix); 1816 1.1 is } 1817 1.1 is #endif 1818 1.1 is 1819 1.1 is void 1820 1.17 aymeric siopng_dump_acb(struct siop_acb *acb) 1821 1.1 is { 1822 1.1 is u_char *b = (u_char *) &acb->cmd; 1823 1.1 is int i; 1824 1.1 is 1825 1.1 is printf("acb@%p ", acb); 1826 1.1 is if (acb->xs == NULL) { 1827 1.1 is printf("<unused>\n"); 1828 1.1 is return; 1829 1.1 is } 1830 1.1 is printf("(%d:%d) flags %2x clen %2d cmd ", 1831 1.15 bouyer acb->xs->xs_periph->periph_target, 1832 1.15 bouyer acb->xs->xs_periph->periph_lun, acb->flags, acb->clen); 1833 1.1 is for (i = acb->clen; i; --i) 1834 1.1 is printf(" %02x", *b++); 1835 1.1 is printf("\n"); 1836 1.1 is printf(" xs: %p data %p:%04x ", acb->xs, acb->xs->data, 1837 1.1 is acb->xs->datalen); 1838 1.1 is printf("va %p:%lx ", acb->iob_buf, acb->iob_len); 1839 1.1 is printf("cur %lx:%lx\n", acb->iob_curbuf, acb->iob_curlen); 1840 1.1 is } 1841 1.1 is 1842 1.1 is void 1843 1.17 aymeric siopng_dump(struct siop_softc *sc) 1844 1.1 is { 1845 1.1 is struct siop_acb *acb; 1846 1.1 is siop_regmap_p rp = sc->sc_siopp; 1847 1.1 is int s; 1848 1.1 is int i; 1849 1.1 is 1850 1.1 is s = splbio(); 1851 1.1 is #if SIOP_TRACE_SIZE 1852 1.1 is siopng_dump_trace(); 1853 1.1 is #endif 1854 1.1 is printf("%s@%p regs %p istat %x\n", 1855 1.41 chs device_xname(sc->sc_dev), sc, rp, rp->siop_istat); 1856 1.1 is if ((acb = sc->free_list.tqh_first) > 0) { 1857 1.1 is printf("Free list:\n"); 1858 1.1 is while (acb) { 1859 1.1 is siopng_dump_acb(acb); 1860 1.1 is acb = acb->chain.tqe_next; 1861 1.1 is } 1862 1.1 is } 1863 1.1 is if ((acb = sc->ready_list.tqh_first) > 0) { 1864 1.1 is printf("Ready list:\n"); 1865 1.1 is while (acb) { 1866 1.1 is siopng_dump_acb(acb); 1867 1.1 is acb = acb->chain.tqe_next; 1868 1.1 is } 1869 1.1 is } 1870 1.1 is if ((acb = sc->nexus_list.tqh_first) > 0) { 1871 1.1 is printf("Nexus list:\n"); 1872 1.1 is while (acb) { 1873 1.1 is siopng_dump_acb(acb); 1874 1.1 is acb = acb->chain.tqe_next; 1875 1.1 is } 1876 1.1 is } 1877 1.1 is if (sc->sc_nexus) { 1878 1.1 is printf("Nexus:\n"); 1879 1.1 is siopng_dump_acb(sc->sc_nexus); 1880 1.1 is } 1881 1.1 is for (i = 0; i < 8; ++i) { 1882 1.1 is if (sc->sc_tinfo[i].cmds > 2) { 1883 1.15 bouyer printf("tgt %d: cmds %d disc %d lubusy %x\n", 1884 1.1 is i, sc->sc_tinfo[i].cmds, 1885 1.1 is sc->sc_tinfo[i].dconns, 1886 1.1 is sc->sc_tinfo[i].lubusy); 1887 1.1 is } 1888 1.1 is } 1889 1.1 is splx(s); 1890 1.1 is } 1891 1.1 is #endif 1892