1 1.18 andvar /* $NetBSD: sbic.c,v 1.18 2022/05/03 20:52:30 andvar Exp $ */ 2 1.1 reinoud 3 1.1 reinoud /* 4 1.1 reinoud * Copyright (c) 2001 Richard Earnshaw 5 1.1 reinoud * All rights reserved. 6 1.1 reinoud * 7 1.1 reinoud * 1. Redistributions of source code must retain the above copyright 8 1.1 reinoud * notice, this list of conditions and the following disclaimer. 9 1.1 reinoud * 2. Redistributions in binary form must reproduce the above copyright 10 1.1 reinoud * notice, this list of conditions and the following disclaimer in the 11 1.1 reinoud * documentation and/or other materials provided with the distribution. 12 1.1 reinoud * 3. The name of the company nor the name of the author may be used to 13 1.1 reinoud * endorse or promote products derived from this software without specific 14 1.1 reinoud * prior written permission. 15 1.1 reinoud * 16 1.1 reinoud * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 1.1 reinoud * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 1.1 reinoud * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 reinoud * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 1.1 reinoud * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 1.1 reinoud * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 1.1 reinoud * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 reinoud * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 reinoud * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 reinoud * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 reinoud * POSSIBILITY OF SUCH DAMAGE. 27 1.1 reinoud * 28 1.7 agc * Copyright (c) 1990 The Regents of the University of California. 29 1.7 agc * All rights reserved. 30 1.7 agc * 31 1.7 agc * This code is derived from software contributed to Berkeley by 32 1.7 agc * Van Jacobson of Lawrence Berkeley Laboratory. 33 1.7 agc * 34 1.7 agc * Redistribution and use in source and binary forms, with or without 35 1.7 agc * modification, are permitted provided that the following conditions 36 1.7 agc * are met: 37 1.7 agc * 1. Redistributions of source code must retain the above copyright 38 1.7 agc * notice, this list of conditions and the following disclaimer. 39 1.7 agc * 2. Redistributions in binary form must reproduce the above copyright 40 1.7 agc * notice, this list of conditions and the following disclaimer in the 41 1.7 agc * documentation and/or other materials provided with the distribution. 42 1.7 agc * 3. Neither the name of the University nor the names of its contributors 43 1.7 agc * may be used to endorse or promote products derived from this software 44 1.7 agc * without specific prior written permission. 45 1.7 agc * 46 1.7 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 47 1.7 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 1.7 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 1.7 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 50 1.7 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 1.7 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 1.7 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 1.7 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 1.7 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 1.7 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 1.7 agc * SUCH DAMAGE. 57 1.1 reinoud * 58 1.1 reinoud * Copyright (c) 1994 Christian E. Hopps 59 1.1 reinoud * 60 1.1 reinoud * This code is derived from software contributed to Berkeley by 61 1.1 reinoud * Van Jacobson of Lawrence Berkeley Laboratory. 62 1.1 reinoud * 63 1.1 reinoud * Redistribution and use in source and binary forms, with or without 64 1.1 reinoud * modification, are permitted provided that the following conditions 65 1.1 reinoud * are met: 66 1.1 reinoud * 1. Redistributions of source code must retain the above copyright 67 1.1 reinoud * notice, this list of conditions and the following disclaimer. 68 1.1 reinoud * 2. Redistributions in binary form must reproduce the above copyright 69 1.1 reinoud * notice, this list of conditions and the following disclaimer in the 70 1.1 reinoud * documentation and/or other materials provided with the distribution. 71 1.1 reinoud * 3. All advertising materials mentioning features or use of this software 72 1.1 reinoud * must display the following acknowledgement: 73 1.1 reinoud * This product includes software developed by the University of 74 1.1 reinoud * California, Berkeley and its contributors. 75 1.1 reinoud * 4. Neither the name of the University nor the names of its contributors 76 1.1 reinoud * may be used to endorse or promote products derived from this software 77 1.1 reinoud * without specific prior written permission. 78 1.1 reinoud * 79 1.1 reinoud * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 80 1.1 reinoud * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 81 1.1 reinoud * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 82 1.1 reinoud * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 83 1.1 reinoud * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 84 1.1 reinoud * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 85 1.1 reinoud * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 86 1.1 reinoud * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 87 1.1 reinoud * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 88 1.1 reinoud * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 89 1.1 reinoud * SUCH DAMAGE. 90 1.1 reinoud * 91 1.1 reinoud * from: sbic.c,v 1.21 1996/01/07 22:01:54 92 1.1 reinoud */ 93 1.1 reinoud 94 1.1 reinoud /* 95 1.1 reinoud * WD 33C93 scsi adaptor driver 96 1.1 reinoud */ 97 1.1 reinoud 98 1.1 reinoud #if 0 99 1.1 reinoud /* 100 1.1 reinoud * The UPROTECTED_CSR code is bogus. It can read the csr (SCSI Status 101 1.1 reinoud * register) at times when an interrupt may be pending. Doing this will 102 1.1 reinoud * clear the interrupt, so we won't see it at times when we really need 103 1.1 reinoud * to. 104 1.1 reinoud */ 105 1.1 reinoud #define UNPROTECTED_CSR 106 1.1 reinoud #endif 107 1.1 reinoud 108 1.5 bjh21 #ifndef DEBUG 109 1.1 reinoud #define DEBUG 110 1.5 bjh21 #endif 111 1.1 reinoud /* #define SBIC_DEBUG(a) a */ 112 1.1 reinoud 113 1.1 reinoud #include "opt_ddb.h" 114 1.1 reinoud 115 1.1 reinoud #include <sys/param.h> 116 1.2 bjh21 117 1.18 andvar __KERNEL_RCSID(0, "$NetBSD: sbic.c,v 1.18 2022/05/03 20:52:30 andvar Exp $"); 118 1.2 bjh21 119 1.1 reinoud #include <sys/systm.h> 120 1.1 reinoud #include <sys/callout.h> 121 1.1 reinoud #include <sys/kernel.h> /* For hz */ 122 1.1 reinoud #include <sys/device.h> 123 1.1 reinoud #include <sys/buf.h> 124 1.16 dyoung #include <sys/bus.h> 125 1.1 reinoud 126 1.1 reinoud #include <uvm/uvm_extern.h> 127 1.1 reinoud 128 1.1 reinoud #include <machine/intr.h> 129 1.1 reinoud 130 1.1 reinoud #include <dev/scsipi/scsi_all.h> 131 1.1 reinoud #include <dev/scsipi/scsipi_all.h> 132 1.1 reinoud #include <dev/scsipi/scsiconf.h> 133 1.1 reinoud 134 1.1 reinoud #include <acorn32/podulebus/sbicreg.h> 135 1.1 reinoud #include <acorn32/podulebus/sbicvar.h> 136 1.1 reinoud 137 1.1 reinoud /* 138 1.1 reinoud * SCSI delays 139 1.1 reinoud * In u-seconds, primarily for state changes on the SPC. 140 1.1 reinoud */ 141 1.1 reinoud #define SBIC_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */ 142 1.1 reinoud #define SBIC_DATA_WAIT 50000 /* wait per data in/out step */ 143 1.1 reinoud #define SBIC_INIT_WAIT 50000 /* wait per step (both) during init */ 144 1.1 reinoud 145 1.1 reinoud #define SBIC_WAIT(regs, until, timeo) sbicwait(regs, until, timeo, __LINE__) 146 1.1 reinoud 147 1.1 reinoud static int sbicicmd (struct sbic_softc *, int, int, 148 1.1 reinoud struct sbic_acb *); 149 1.1 reinoud static int sbicgo (struct sbic_softc *, struct scsipi_xfer *); 150 1.1 reinoud static int sbicwait (sbic_regmap_p, char, int , int); 151 1.1 reinoud static int sbicselectbus (struct sbic_softc *, sbic_regmap_p, u_char, 152 1.1 reinoud u_char, u_char); 153 1.1 reinoud static int sbicxfstart (sbic_regmap_p, int, u_char, int); 154 1.1 reinoud static int sbicxfout (sbic_regmap_p regs, int, void *, int); 155 1.1 reinoud static int sbicfromscsiperiod (struct sbic_softc *, sbic_regmap_p, int); 156 1.1 reinoud static int sbictoscsiperiod (struct sbic_softc *, sbic_regmap_p, int); 157 1.1 reinoud static int sbicpoll (struct sbic_softc *); 158 1.1 reinoud static int sbicnextstate (struct sbic_softc *, u_char, u_char); 159 1.1 reinoud static int sbicmsgin (struct sbic_softc *); 160 1.1 reinoud static int sbicxfin (sbic_regmap_p regs, int, void *); 161 1.9 he static int sbicabort (struct sbic_softc *, sbic_regmap_p, const char *); 162 1.1 reinoud static void sbicxfdone (struct sbic_softc *, sbic_regmap_p, int); 163 1.1 reinoud static void sbicerror (struct sbic_softc *, sbic_regmap_p, u_char); 164 1.1 reinoud static void sbicreset (struct sbic_softc *); 165 1.1 reinoud static void sbic_scsidone (struct sbic_acb *, int); 166 1.1 reinoud static void sbic_sched (struct sbic_softc *); 167 1.1 reinoud static void sbic_save_ptrs (struct sbic_softc *, sbic_regmap_p); 168 1.1 reinoud 169 1.1 reinoud /* 170 1.1 reinoud * Synch xfer parameters, and timing conversions 171 1.1 reinoud */ 172 1.1 reinoud int sbic_min_period = SBIC_SYN_MIN_PERIOD; /* in cycles = f(ICLK,FSn) */ 173 1.1 reinoud int sbic_max_offset = SBIC_SYN_MAX_OFFSET; /* pure number */ 174 1.1 reinoud 175 1.1 reinoud int sbic_cmd_wait = SBIC_CMD_WAIT; 176 1.1 reinoud int sbic_data_wait = SBIC_DATA_WAIT; 177 1.1 reinoud int sbic_init_wait = SBIC_INIT_WAIT; 178 1.1 reinoud 179 1.1 reinoud /* 180 1.1 reinoud * was broken before.. now if you want this you get it for all drives 181 1.1 reinoud * on sbic controllers. 182 1.1 reinoud */ 183 1.1 reinoud u_char sbic_inhibit_sync[8]; 184 1.1 reinoud int sbic_enable_reselect = 1; 185 1.1 reinoud int sbic_clock_override = 0; 186 1.1 reinoud int sbic_no_dma = 1; /* was 0 */ 187 1.1 reinoud int sbic_parallel_operations = 1; 188 1.1 reinoud 189 1.1 reinoud #ifdef DEBUG 190 1.1 reinoud sbic_regmap_p debug_sbic_regs; 191 1.1 reinoud int sbicdma_ops = 0; /* total DMA operations */ 192 1.1 reinoud int sbicdma_saves = 0; 193 1.1 reinoud #define QPRINTF(a) if (sbic_debug > 1) printf a 194 1.1 reinoud #define DBGPRINTF(x,p) if (p) printf x 195 1.1 reinoud #define DBG(x) x 196 1.1 reinoud int sbic_debug = 0; 197 1.1 reinoud int sync_debug = 0; 198 1.1 reinoud int sbic_dma_debug = 0; 199 1.1 reinoud int reselect_debug = 0; 200 1.1 reinoud int data_pointer_debug = 0; 201 1.1 reinoud u_char debug_asr, debug_csr, routine; 202 1.1 reinoud 203 1.2 bjh21 void sbicdumpstate (void); 204 1.1 reinoud void sbictimeout (struct sbic_softc *); 205 1.1 reinoud void sbic_dump (struct sbic_softc *); 206 1.1 reinoud void sbic_dump_acb (struct sbic_acb *); 207 1.1 reinoud 208 1.1 reinoud #define CSR_TRACE_SIZE 32 209 1.1 reinoud #if CSR_TRACE_SIZE 210 1.1 reinoud #define CSR_TRACE(w,c,a,x) do { \ 211 1.9 he int _s = splbio(); \ 212 1.1 reinoud csr_trace[csr_traceptr].whr = (w); csr_trace[csr_traceptr].csr = (c); \ 213 1.1 reinoud csr_trace[csr_traceptr].asr = (a); csr_trace[csr_traceptr].xtn = (x); \ 214 1.1 reinoud csr_traceptr = (csr_traceptr + 1) & (CSR_TRACE_SIZE - 1); \ 215 1.9 he splx(_s); \ 216 1.1 reinoud } while (0) 217 1.1 reinoud int csr_traceptr; 218 1.1 reinoud int csr_tracesize = CSR_TRACE_SIZE; 219 1.1 reinoud struct { 220 1.1 reinoud u_char whr; 221 1.1 reinoud u_char csr; 222 1.1 reinoud u_char asr; 223 1.1 reinoud u_char xtn; 224 1.1 reinoud } csr_trace[CSR_TRACE_SIZE]; 225 1.1 reinoud #else 226 1.1 reinoud #define CSR_TRACE 227 1.1 reinoud #endif 228 1.1 reinoud 229 1.1 reinoud #define SBIC_TRACE_SIZE 0 230 1.1 reinoud #if SBIC_TRACE_SIZE 231 1.1 reinoud #define SBIC_TRACE(dev) do { \ 232 1.1 reinoud int s = splbio(); \ 233 1.1 reinoud sbic_trace[sbic_traceptr].sp = &s; \ 234 1.1 reinoud sbic_trace[sbic_traceptr].line = __LINE__; \ 235 1.1 reinoud sbic_trace[sbic_traceptr].sr = s; \ 236 1.1 reinoud sbic_trace[sbic_traceptr].csr = csr_traceptr; \ 237 1.1 reinoud sbic_traceptr = (sbic_traceptr + 1) & (SBIC_TRACE_SIZE - 1); \ 238 1.1 reinoud splx(s); \ 239 1.1 reinoud } while (0) 240 1.1 reinoud int sbic_traceptr; 241 1.1 reinoud int sbic_tracesize = SBIC_TRACE_SIZE; 242 1.1 reinoud struct { 243 1.1 reinoud void *sp; 244 1.1 reinoud u_short line; 245 1.1 reinoud u_short sr; 246 1.1 reinoud int csr; 247 1.1 reinoud } sbic_trace[SBIC_TRACE_SIZE]; 248 1.1 reinoud #else 249 1.1 reinoud #define SBIC_TRACE(dev) 250 1.1 reinoud #endif 251 1.1 reinoud 252 1.1 reinoud #else 253 1.1 reinoud #define QPRINTF(a) 254 1.1 reinoud #define DBGPRINTF(x,p) 255 1.1 reinoud #define DBG(x) 256 1.1 reinoud #define CSR_TRACE 257 1.1 reinoud #define SBIC_TRACE 258 1.1 reinoud #endif 259 1.1 reinoud 260 1.1 reinoud #ifndef SBIC_DEBUG 261 1.1 reinoud #define SBIC_DEBUG(x) 262 1.1 reinoud #endif 263 1.1 reinoud 264 1.1 reinoud /* 265 1.1 reinoud * default minphys routine for sbic based controllers 266 1.1 reinoud */ 267 1.1 reinoud void 268 1.1 reinoud sbic_minphys(struct buf *bp) 269 1.1 reinoud { 270 1.1 reinoud /* 271 1.1 reinoud * No max transfer at this level. 272 1.1 reinoud */ 273 1.1 reinoud minphys(bp); 274 1.1 reinoud } 275 1.1 reinoud 276 1.1 reinoud /* 277 1.1 reinoud * Save DMA pointers. Take into account partial transfer. Shut down DMA. 278 1.1 reinoud */ 279 1.1 reinoud static void 280 1.1 reinoud sbic_save_ptrs(struct sbic_softc *dev, sbic_regmap_p regs) 281 1.1 reinoud { 282 1.1 reinoud int count, asr, s; 283 1.1 reinoud struct sbic_acb* acb; 284 1.1 reinoud 285 1.1 reinoud SBIC_TRACE(dev); 286 1.1 reinoud if (!(dev->sc_flags & SBICF_INDMA)) 287 1.1 reinoud return; /* DMA not active */ 288 1.1 reinoud 289 1.1 reinoud s = splbio(); 290 1.1 reinoud 291 1.1 reinoud acb = dev->sc_nexus; 292 1.1 reinoud if (acb == NULL) { 293 1.1 reinoud splx(s); 294 1.1 reinoud return; 295 1.1 reinoud } 296 1.1 reinoud count = -1; 297 1.1 reinoud do { 298 1.1 reinoud GET_SBIC_asr(regs, asr); 299 1.1 reinoud if (asr & SBIC_ASR_DBR) { 300 1.1 reinoud printf("sbic_save_ptrs: asr %02x canceled!\n", asr); 301 1.1 reinoud splx(s); 302 1.1 reinoud SBIC_TRACE(dev); 303 1.1 reinoud return; 304 1.1 reinoud } 305 1.1 reinoud } while (asr & (SBIC_ASR_BSY | SBIC_ASR_CIP)); 306 1.1 reinoud 307 1.1 reinoud /* Save important state */ 308 1.1 reinoud /* must be done before dmastop */ 309 1.1 reinoud SBIC_TC_GET(regs, count); 310 1.1 reinoud 311 1.1 reinoud /* Shut down DMA ====CAREFUL==== */ 312 1.1 reinoud dev->sc_dmastop(dev->sc_dmah, dev->sc_dmat, acb); 313 1.1 reinoud dev->sc_flags &= ~SBICF_INDMA; 314 1.1 reinoud #ifdef DIAGNOSTIC 315 1.1 reinoud { 316 1.1 reinoud int count2; 317 1.1 reinoud 318 1.1 reinoud SBIC_TC_GET(regs, count2); 319 1.1 reinoud if (count2 != count) 320 1.1 reinoud panic("sbic_save_ptrs: DMA was still active(%d,%d)", 321 1.1 reinoud count, count2); 322 1.1 reinoud } 323 1.1 reinoud #endif 324 1.1 reinoud /* Note where we got to before stopping. We need this to resume 325 1.1 reinoud later. */ 326 1.1 reinoud acb->offset += acb->sc_tcnt - count; 327 1.1 reinoud SBIC_TC_PUT(regs, 0); 328 1.1 reinoud 329 1.1 reinoud DBGPRINTF(("SBIC saving tgt %d data pointers: Offset now %d ASR:%02x", 330 1.1 reinoud dev->target, acb->offset, asr), data_pointer_debug >= 1); 331 1.1 reinoud 332 1.1 reinoud acb->sc_tcnt = 0; 333 1.1 reinoud 334 1.1 reinoud DBG(sbicdma_saves++); 335 1.1 reinoud splx(s); 336 1.1 reinoud SBIC_TRACE(dev); 337 1.1 reinoud } 338 1.1 reinoud 339 1.1 reinoud /* 340 1.1 reinoud * used by specific sbic controller 341 1.1 reinoud * 342 1.1 reinoud * it appears that the higher level code does nothing with LUN's 343 1.1 reinoud * so I will too. I could plug it in, however so could they 344 1.1 reinoud * in scsi_scsi_cmd(). 345 1.1 reinoud */ 346 1.1 reinoud void 347 1.1 reinoud sbic_scsi_request(struct scsipi_channel *chan, 348 1.1 reinoud scsipi_adapter_req_t req, void *arg) 349 1.1 reinoud { 350 1.1 reinoud struct scsipi_xfer *xs; 351 1.1 reinoud struct sbic_acb *acb; 352 1.17 chs struct sbic_softc *dev = device_private(chan->chan_adapter->adapt_dev); 353 1.1 reinoud struct scsipi_periph *periph; 354 1.1 reinoud int flags, s, stat; 355 1.1 reinoud 356 1.1 reinoud switch (req) { 357 1.1 reinoud case ADAPTER_REQ_RUN_XFER: 358 1.1 reinoud xs = arg; 359 1.1 reinoud periph = xs->xs_periph; 360 1.1 reinoud SBIC_TRACE(dev); 361 1.1 reinoud flags = xs->xs_control; 362 1.1 reinoud 363 1.1 reinoud if (flags & XS_CTL_DATA_UIO) 364 1.1 reinoud panic("sbic: scsi data uio requested"); 365 1.1 reinoud 366 1.1 reinoud if (dev->sc_nexus && (flags & XS_CTL_POLL)) 367 1.1 reinoud panic("sbic_scsicmd: busy"); 368 1.1 reinoud 369 1.1 reinoud s = splbio(); 370 1.1 reinoud acb = dev->free_list.tqh_first; 371 1.1 reinoud if (acb) 372 1.1 reinoud TAILQ_REMOVE(&dev->free_list, acb, chain); 373 1.1 reinoud splx(s); 374 1.1 reinoud 375 1.1 reinoud if (acb == NULL) { 376 1.1 reinoud DBG(printf("sbic_scsicmd: unable to queue request for " 377 1.1 reinoud "target %d\n", periph->periph_target)); 378 1.1 reinoud #if defined(DDB) && defined(DEBUG) 379 1.1 reinoud Debugger(); 380 1.1 reinoud #endif 381 1.1 reinoud xs->error = XS_RESOURCE_SHORTAGE; 382 1.1 reinoud SBIC_TRACE(dev); 383 1.1 reinoud scsipi_done(xs); 384 1.1 reinoud return; 385 1.1 reinoud } 386 1.1 reinoud 387 1.1 reinoud acb->flags = ACB_ACTIVE; 388 1.1 reinoud if (flags & XS_CTL_DATA_IN) 389 1.1 reinoud acb->flags |= ACB_DATAIN; 390 1.1 reinoud acb->xs = xs; 391 1.1 reinoud memcpy(&acb->cmd, xs->cmd, xs->cmdlen); 392 1.1 reinoud acb->clen = xs->cmdlen; 393 1.1 reinoud acb->data = xs->data; 394 1.1 reinoud acb->datalen = xs->datalen; 395 1.1 reinoud 396 1.1 reinoud QPRINTF(("sbic_scsi_request: Cmd %02x (len %d), Data %p(%d)\n", 397 1.1 reinoud (unsigned) acb->cmd.opcode, acb->clen, xs->data, 398 1.1 reinoud xs->datalen)); 399 1.1 reinoud if (flags & XS_CTL_POLL) { 400 1.1 reinoud s = splbio(); 401 1.1 reinoud /* 402 1.1 reinoud * This has major side effects -- it locks up the 403 1.1 reinoud * machine. 404 1.1 reinoud */ 405 1.1 reinoud 406 1.1 reinoud dev->sc_flags |= SBICF_ICMD; 407 1.1 reinoud do { 408 1.1 reinoud while (dev->sc_nexus) 409 1.1 reinoud sbicpoll(dev); 410 1.1 reinoud dev->sc_nexus = acb; 411 1.1 reinoud dev->sc_stat[0] = -1; 412 1.1 reinoud dev->target = periph->periph_target; 413 1.1 reinoud dev->lun = periph->periph_lun; 414 1.1 reinoud stat = sbicicmd(dev, periph->periph_target, 415 1.1 reinoud periph->periph_lun, acb); 416 1.1 reinoud } while (dev->sc_nexus != acb); 417 1.1 reinoud 418 1.1 reinoud sbic_scsidone(acb, stat); 419 1.1 reinoud splx(s); 420 1.1 reinoud SBIC_TRACE(dev); 421 1.1 reinoud return; 422 1.1 reinoud } 423 1.1 reinoud 424 1.1 reinoud s = splbio(); 425 1.1 reinoud TAILQ_INSERT_TAIL(&dev->ready_list, acb, chain); 426 1.1 reinoud 427 1.1 reinoud if (dev->sc_nexus) { 428 1.1 reinoud splx(s); 429 1.1 reinoud SBIC_TRACE(dev); 430 1.1 reinoud return; 431 1.1 reinoud } 432 1.1 reinoud 433 1.1 reinoud /* 434 1.1 reinoud * Nothing is active, try to start it now. 435 1.1 reinoud */ 436 1.1 reinoud sbic_sched(dev); 437 1.1 reinoud splx(s); 438 1.1 reinoud 439 1.1 reinoud SBIC_TRACE(dev); 440 1.1 reinoud /* TODO: add sbic_poll to do XS_CTL_POLL operations */ 441 1.1 reinoud return; 442 1.1 reinoud 443 1.1 reinoud case ADAPTER_REQ_GROW_RESOURCES: 444 1.1 reinoud case ADAPTER_REQ_SET_XFER_MODE: 445 1.1 reinoud /* XXX Not supported. */ 446 1.1 reinoud return; 447 1.1 reinoud } 448 1.1 reinoud } 449 1.1 reinoud 450 1.1 reinoud /* 451 1.1 reinoud * attempt to start the next available command 452 1.1 reinoud */ 453 1.1 reinoud static void 454 1.1 reinoud sbic_sched(struct sbic_softc *dev) 455 1.1 reinoud { 456 1.1 reinoud struct scsipi_xfer *xs; 457 1.1 reinoud struct scsipi_periph *periph; 458 1.1 reinoud struct sbic_acb *acb; 459 1.1 reinoud int flags, /*phase,*/ stat, i; 460 1.1 reinoud 461 1.1 reinoud SBIC_TRACE(dev); 462 1.1 reinoud if (dev->sc_nexus) 463 1.1 reinoud return; /* a command is current active */ 464 1.1 reinoud 465 1.1 reinoud SBIC_TRACE(dev); 466 1.1 reinoud for (acb = dev->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) { 467 1.1 reinoud periph = acb->xs->xs_periph; 468 1.1 reinoud i = periph->periph_target; 469 1.1 reinoud if (!(dev->sc_tinfo[i].lubusy & (1 << periph->periph_lun))) { 470 1.1 reinoud struct sbic_tinfo *ti = &dev->sc_tinfo[i]; 471 1.1 reinoud 472 1.1 reinoud TAILQ_REMOVE(&dev->ready_list, acb, chain); 473 1.1 reinoud dev->sc_nexus = acb; 474 1.1 reinoud periph = acb->xs->xs_periph; 475 1.1 reinoud ti = &dev->sc_tinfo[periph->periph_target]; 476 1.1 reinoud ti->lubusy |= (1 << periph->periph_lun); 477 1.1 reinoud break; 478 1.1 reinoud } 479 1.1 reinoud } 480 1.1 reinoud 481 1.1 reinoud SBIC_TRACE(dev); 482 1.1 reinoud if (acb == NULL) 483 1.1 reinoud return; /* did not find an available command */ 484 1.1 reinoud 485 1.1 reinoud xs = acb->xs; 486 1.1 reinoud periph = xs->xs_periph; 487 1.1 reinoud flags = xs->xs_control; 488 1.1 reinoud 489 1.1 reinoud if (flags & XS_CTL_RESET) 490 1.1 reinoud sbicreset(dev); 491 1.1 reinoud 492 1.1 reinoud DBGPRINTF(("sbic_sched(%d,%d)\n", periph->periph_target, 493 1.1 reinoud periph->periph_lun), data_pointer_debug > 1); 494 1.1 reinoud DBG(if (data_pointer_debug > 1) sbic_dump_acb(acb)); 495 1.1 reinoud dev->sc_stat[0] = -1; 496 1.1 reinoud dev->target = periph->periph_target; 497 1.1 reinoud dev->lun = periph->periph_lun; 498 1.1 reinoud 499 1.1 reinoud /* Decide if we can use DMA for this transfer. */ 500 1.1 reinoud if ((flags & XS_CTL_POLL) == 0 501 1.1 reinoud && !sbic_no_dma 502 1.1 reinoud && dev->sc_dmaok(dev->sc_dmah, dev->sc_dmat, acb)) 503 1.1 reinoud acb->flags |= ACB_DMA; 504 1.1 reinoud 505 1.1 reinoud if ((flags & XS_CTL_POLL) || 506 1.1 reinoud (!sbic_parallel_operations && (acb->flags & ACB_DMA) == 0)) 507 1.1 reinoud stat = sbicicmd(dev, periph->periph_target, 508 1.1 reinoud periph->periph_lun, acb); 509 1.1 reinoud else if (sbicgo(dev, xs) == 0 && xs->error != XS_SELTIMEOUT) { 510 1.1 reinoud SBIC_TRACE(dev); 511 1.1 reinoud return; 512 1.1 reinoud } else 513 1.1 reinoud stat = dev->sc_stat[0]; 514 1.1 reinoud 515 1.1 reinoud sbic_scsidone(acb, stat); 516 1.1 reinoud SBIC_TRACE(dev); 517 1.1 reinoud } 518 1.1 reinoud 519 1.1 reinoud static void 520 1.1 reinoud sbic_scsidone(struct sbic_acb *acb, int stat) 521 1.1 reinoud { 522 1.1 reinoud struct scsipi_xfer *xs; 523 1.1 reinoud struct scsipi_periph *periph; 524 1.1 reinoud struct sbic_softc *dev; 525 1.1 reinoud /* int s;*/ 526 1.1 reinoud int dosched = 0; 527 1.1 reinoud 528 1.1 reinoud xs = acb->xs; 529 1.1 reinoud periph = xs->xs_periph; 530 1.17 chs dev = device_private(periph->periph_channel->chan_adapter->adapt_dev); 531 1.1 reinoud SBIC_TRACE(dev); 532 1.1 reinoud #ifdef DIAGNOSTIC 533 1.1 reinoud if (acb == NULL || xs == NULL) { 534 1.1 reinoud printf("sbic_scsidone -- (%d,%d) no scsipi_xfer\n", 535 1.1 reinoud dev->target, dev->lun); 536 1.1 reinoud #ifdef DDB 537 1.1 reinoud Debugger(); 538 1.1 reinoud #endif 539 1.1 reinoud return; 540 1.1 reinoud } 541 1.1 reinoud #endif 542 1.1 reinoud 543 1.1 reinoud DBGPRINTF(("scsidone: (%d,%d)->(%d,%d)%02x acbfl=%x\n", 544 1.1 reinoud periph->periph_target, periph->periph_lun, 545 1.1 reinoud dev->target, dev->lun, stat, acb->flags), 546 1.1 reinoud data_pointer_debug > 1); 547 1.1 reinoud DBG(if (xs->xs_periph->periph_target == dev->sc_channel.chan_id) 548 1.1 reinoud panic("target == hostid")); 549 1.1 reinoud 550 1.1 reinoud xs->status = stat; 551 1.1 reinoud xs->resid = 0; 552 1.1 reinoud if (xs->error == XS_NOERROR) { 553 1.1 reinoud if (stat == SCSI_CHECK || stat == SCSI_BUSY) 554 1.1 reinoud xs->error = XS_BUSY; 555 1.1 reinoud } 556 1.1 reinoud 557 1.1 reinoud /* 558 1.1 reinoud * Remove the ACB from whatever queue it's on. We have to do a bit of 559 1.1 reinoud * a hack to figure out which queue it's on. Note that it is *not* 560 1.1 reinoud * necessary to cdr down the ready queue, but we must cdr down the 561 1.1 reinoud * nexus queue and see if it's there, so we can mark the unit as no 562 1.1 reinoud * longer busy. This code is sickening, but it works. 563 1.1 reinoud */ 564 1.1 reinoud if (acb == dev->sc_nexus) { 565 1.1 reinoud dev->sc_nexus = NULL; 566 1.1 reinoud dev->sc_tinfo[periph->periph_target].lubusy &= 567 1.1 reinoud ~(1 << periph->periph_lun); 568 1.1 reinoud if (dev->ready_list.tqh_first) 569 1.1 reinoud dosched = 1; /* start next command */ 570 1.1 reinoud } else if (dev->ready_list.tqh_last == &acb->chain.tqe_next) { 571 1.1 reinoud TAILQ_REMOVE(&dev->ready_list, acb, chain); 572 1.1 reinoud } else { 573 1.1 reinoud register struct sbic_acb *acb2; 574 1.1 reinoud for (acb2 = dev->nexus_list.tqh_first; acb2; 575 1.1 reinoud acb2 = acb2->chain.tqe_next) { 576 1.1 reinoud if (acb2 == acb) { 577 1.1 reinoud TAILQ_REMOVE(&dev->nexus_list, acb, chain); 578 1.1 reinoud dev->sc_tinfo[periph->periph_target].lubusy 579 1.1 reinoud &= ~(1 << periph->periph_lun); 580 1.1 reinoud break; 581 1.1 reinoud } 582 1.1 reinoud } 583 1.1 reinoud if (acb2) 584 1.1 reinoud ; 585 1.1 reinoud else if (acb->chain.tqe_next) { 586 1.1 reinoud TAILQ_REMOVE(&dev->ready_list, acb, chain); 587 1.1 reinoud } else { 588 1.1 reinoud printf("%s: can't find matching acb\n", 589 1.17 chs device_xname(dev->sc_dev)); 590 1.1 reinoud #ifdef DDB 591 1.1 reinoud Debugger(); 592 1.1 reinoud #endif 593 1.1 reinoud } 594 1.1 reinoud } 595 1.1 reinoud /* Put it on the free list. */ 596 1.1 reinoud acb->flags = ACB_FREE; 597 1.1 reinoud TAILQ_INSERT_HEAD(&dev->free_list, acb, chain); 598 1.1 reinoud 599 1.1 reinoud dev->sc_tinfo[periph->periph_target].cmds++; 600 1.1 reinoud 601 1.1 reinoud scsipi_done(xs); 602 1.1 reinoud 603 1.1 reinoud if (dosched) 604 1.1 reinoud sbic_sched(dev); 605 1.1 reinoud SBIC_TRACE(dev); 606 1.1 reinoud } 607 1.1 reinoud 608 1.1 reinoud static int 609 1.1 reinoud sbicwait(sbic_regmap_p regs, char until, int timeo, int line) 610 1.1 reinoud { 611 1.1 reinoud u_char val; 612 1.1 reinoud int csr; 613 1.1 reinoud 614 1.1 reinoud SBIC_TRACE((struct sbic_softc *)0); 615 1.1 reinoud if (timeo == 0) 616 1.1 reinoud timeo = 1000000; /* some large value.. */ 617 1.1 reinoud 618 1.1 reinoud GET_SBIC_asr(regs,val); 619 1.1 reinoud while ((val & until) == 0) { 620 1.1 reinoud if (timeo-- == 0) { 621 1.1 reinoud GET_SBIC_csr(regs, csr); 622 1.1 reinoud printf("sbicwait TIMEO @%d with asr=x%x csr=x%x\n", 623 1.1 reinoud line, val, csr); 624 1.1 reinoud #if defined(DDB) && defined(DEBUG) 625 1.1 reinoud Debugger(); 626 1.1 reinoud #endif 627 1.1 reinoud return val; /* Maybe I should abort */ 628 1.1 reinoud break; 629 1.1 reinoud } 630 1.1 reinoud DELAY(1); 631 1.1 reinoud GET_SBIC_asr(regs,val); 632 1.1 reinoud } 633 1.1 reinoud SBIC_TRACE((struct sbic_softc *)0); 634 1.1 reinoud return val; 635 1.1 reinoud } 636 1.1 reinoud 637 1.1 reinoud static int 638 1.9 he sbicabort(struct sbic_softc *dev, sbic_regmap_p regs, const char *where) 639 1.1 reinoud { 640 1.1 reinoud u_char csr, asr; 641 1.1 reinoud 642 1.1 reinoud GET_SBIC_asr(regs, asr); 643 1.1 reinoud GET_SBIC_csr(regs, csr); 644 1.1 reinoud 645 1.1 reinoud printf ("%s: abort %s: csr = 0x%02x, asr = 0x%02x\n", 646 1.17 chs device_xname(dev->sc_dev), where, csr, asr); 647 1.1 reinoud 648 1.1 reinoud 649 1.1 reinoud #if 0 650 1.1 reinoud /* Clean up running command */ 651 1.1 reinoud if (dev->sc_nexus != NULL) { 652 1.1 reinoud dev->sc_nexus->xs->error = XS_DRIVER_STUFFUP; 653 1.1 reinoud sbic_scsidone(dev->sc_nexus, dev->sc_stat[0]); 654 1.1 reinoud } 655 1.1 reinoud while (acb = dev->nexus_list.tqh_first) { 656 1.1 reinoud acb->xs->error = XS_DRIVER_STUFFUP; 657 1.1 reinoud sbic_scsidone(acb, -1 /*acb->stat[0]*/); 658 1.1 reinoud } 659 1.1 reinoud #endif 660 1.1 reinoud 661 1.1 reinoud /* Clean up chip itself */ 662 1.1 reinoud if (dev->sc_flags & SBICF_SELECTED) { 663 1.1 reinoud while (asr & SBIC_ASR_DBR) { 664 1.1 reinoud /* sbic is jammed w/data. need to clear it */ 665 1.1 reinoud /* But we don't know what direction it needs to go */ 666 1.1 reinoud GET_SBIC_data(regs, asr); 667 1.1 reinoud printf("%s: abort %s: clearing data buffer 0x%02x\n", 668 1.17 chs device_xname(dev->sc_dev), where, asr); 669 1.1 reinoud GET_SBIC_asr(regs, asr); 670 1.1 reinoud /* Not the read direction, then */ 671 1.1 reinoud if (asr & SBIC_ASR_DBR) 672 1.1 reinoud SET_SBIC_data(regs, asr); 673 1.1 reinoud GET_SBIC_asr(regs, asr); 674 1.1 reinoud } 675 1.1 reinoud WAIT_CIP(regs); 676 1.1 reinoud printf("%s: sbicabort - sending ABORT command\n", 677 1.17 chs device_xname(dev->sc_dev)); 678 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_ABORT); 679 1.1 reinoud WAIT_CIP(regs); 680 1.1 reinoud 681 1.1 reinoud GET_SBIC_asr(regs, asr); 682 1.1 reinoud if (asr & (SBIC_ASR_BSY | SBIC_ASR_LCI)) { 683 1.1 reinoud /* ok, get more drastic.. */ 684 1.1 reinoud 685 1.1 reinoud printf("%s: sbicabort - asr %x, trying to reset\n", 686 1.17 chs device_xname(dev->sc_dev), asr); 687 1.1 reinoud sbicreset(dev); 688 1.1 reinoud dev->sc_flags &= ~SBICF_SELECTED; 689 1.1 reinoud return -1; 690 1.1 reinoud } 691 1.1 reinoud printf("%s: sbicabort - sending DISC command\n", 692 1.17 chs device_xname(dev->sc_dev)); 693 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_DISC); 694 1.1 reinoud 695 1.1 reinoud do { 696 1.1 reinoud asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0); 697 1.1 reinoud GET_SBIC_csr (regs, csr); 698 1.1 reinoud CSR_TRACE('a',csr,asr,0); 699 1.1 reinoud } while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) 700 1.1 reinoud && (csr != SBIC_CSR_CMD_INVALID)); 701 1.1 reinoud 702 1.1 reinoud /* lets just hope it worked.. */ 703 1.1 reinoud dev->sc_flags &= ~SBICF_SELECTED; 704 1.1 reinoud } 705 1.1 reinoud return -1; 706 1.1 reinoud } 707 1.1 reinoud 708 1.1 reinoud 709 1.1 reinoud /* 710 1.1 reinoud * Initialize driver-private structures 711 1.1 reinoud */ 712 1.1 reinoud 713 1.1 reinoud int 714 1.1 reinoud sbicinit(struct sbic_softc *dev) 715 1.1 reinoud { 716 1.1 reinoud sbic_regmap_p regs; 717 1.1 reinoud u_int i; 718 1.1 reinoud /* u_int my_id, s;*/ 719 1.1 reinoud /* u_char csr;*/ 720 1.1 reinoud struct sbic_acb *acb; 721 1.1 reinoud u_int inhibit_sync; 722 1.1 reinoud 723 1.1 reinoud extern u_long scsi_nosync; 724 1.1 reinoud extern int shift_nosync; 725 1.1 reinoud 726 1.1 reinoud SBIC_DEBUG(printf("sbicinit:\n")); 727 1.1 reinoud 728 1.1 reinoud regs = &dev->sc_sbicp; 729 1.1 reinoud 730 1.1 reinoud if ((dev->sc_flags & SBICF_ALIVE) == 0) { 731 1.1 reinoud TAILQ_INIT(&dev->ready_list); 732 1.1 reinoud TAILQ_INIT(&dev->nexus_list); 733 1.1 reinoud TAILQ_INIT(&dev->free_list); 734 1.12 ad callout_init(&dev->sc_timo_ch, 0); 735 1.1 reinoud dev->sc_nexus = NULL; 736 1.1 reinoud acb = dev->sc_acb; 737 1.1 reinoud memset(acb, 0, sizeof(dev->sc_acb)); 738 1.1 reinoud 739 1.1 reinoud SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__)); 740 1.1 reinoud 741 1.1 reinoud for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) { 742 1.1 reinoud TAILQ_INSERT_TAIL(&dev->free_list, acb, chain); 743 1.1 reinoud acb++; 744 1.1 reinoud } 745 1.1 reinoud memset(dev->sc_tinfo, 0, sizeof(dev->sc_tinfo)); 746 1.1 reinoud /* make sure timeout is really not needed */ 747 1.1 reinoud DBG(callout_reset(&dev->sc_timo_ch, 30 * hz, 748 1.1 reinoud (void *)sbictimeout, dev)); 749 1.1 reinoud } else 750 1.1 reinoud panic("sbic: reinitializing driver!"); 751 1.1 reinoud 752 1.1 reinoud SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__)); 753 1.1 reinoud 754 1.1 reinoud dev->sc_flags |= SBICF_ALIVE; 755 1.1 reinoud dev->sc_flags &= ~SBICF_SELECTED; 756 1.1 reinoud 757 1.1 reinoud /* initialize inhibit array */ 758 1.1 reinoud if (scsi_nosync) { 759 1.1 reinoud 760 1.1 reinoud SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__)); 761 1.1 reinoud 762 1.1 reinoud inhibit_sync = (scsi_nosync >> shift_nosync) & 0xff; 763 1.1 reinoud shift_nosync += 8; 764 1.1 reinoud 765 1.1 reinoud DBGPRINTF(("%s: Inhibiting synchronous transfer %02x\n", 766 1.17 chs device_xname(dev->sc_dev), inhibit_sync), inhibit_sync); 767 1.1 reinoud 768 1.1 reinoud for (i = 0; i < 8; ++i) 769 1.1 reinoud if (inhibit_sync & (1 << i)) 770 1.1 reinoud sbic_inhibit_sync[i] = 1; 771 1.1 reinoud } 772 1.1 reinoud 773 1.1 reinoud SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__)); 774 1.1 reinoud 775 1.1 reinoud sbicreset(dev); 776 1.1 reinoud return 0; 777 1.1 reinoud } 778 1.1 reinoud 779 1.1 reinoud static void 780 1.1 reinoud sbicreset(struct sbic_softc *dev) 781 1.1 reinoud { 782 1.1 reinoud sbic_regmap_p regs; 783 1.1 reinoud u_int my_id, s; 784 1.1 reinoud /* u_int i;*/ 785 1.1 reinoud u_char csr; 786 1.1 reinoud /* struct sbic_acb *acb;*/ 787 1.1 reinoud 788 1.1 reinoud SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__)); 789 1.1 reinoud 790 1.1 reinoud regs = &dev->sc_sbicp; 791 1.1 reinoud 792 1.1 reinoud SBIC_DEBUG(printf("sbicreset: regs = %08x\n", regs)); 793 1.1 reinoud 794 1.1 reinoud #if 0 795 1.1 reinoud if (dev->sc_flags & SBICF_ALIVE) { 796 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_ABORT); 797 1.1 reinoud WAIT_CIP(regs); 798 1.1 reinoud } 799 1.1 reinoud #else 800 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_ABORT); 801 1.1 reinoud 802 1.1 reinoud SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__)); 803 1.1 reinoud 804 1.1 reinoud WAIT_CIP(regs); 805 1.1 reinoud 806 1.1 reinoud SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__)); 807 1.1 reinoud #endif 808 1.1 reinoud s = splbio(); 809 1.1 reinoud my_id = dev->sc_channel.chan_id & SBIC_ID_MASK; 810 1.1 reinoud 811 1.1 reinoud /* Enable advanced mode */ 812 1.1 reinoud my_id |= SBIC_ID_EAF /*| SBIC_ID_EHP*/ ; 813 1.1 reinoud SET_SBIC_myid(regs, my_id); 814 1.1 reinoud 815 1.1 reinoud SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__)); 816 1.1 reinoud 817 1.1 reinoud /* 818 1.1 reinoud * Disable interrupts (in dmainit) then reset the chip 819 1.1 reinoud */ 820 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_RESET); 821 1.1 reinoud DELAY(25); 822 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, 0); 823 1.1 reinoud GET_SBIC_csr(regs, csr); /* clears interrupt also */ 824 1.1 reinoud 825 1.1 reinoud if (dev->sc_clkfreq < 110) 826 1.1 reinoud my_id |= SBIC_ID_FS_8_10; 827 1.1 reinoud else if (dev->sc_clkfreq < 160) 828 1.1 reinoud my_id |= SBIC_ID_FS_12_15; 829 1.1 reinoud else if (dev->sc_clkfreq < 210) 830 1.1 reinoud my_id |= SBIC_ID_FS_16_20; 831 1.1 reinoud 832 1.1 reinoud SET_SBIC_myid(regs, my_id); 833 1.1 reinoud 834 1.1 reinoud SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__)); 835 1.1 reinoud 836 1.1 reinoud /* 837 1.1 reinoud * Set up various chip parameters 838 1.1 reinoud */ 839 1.1 reinoud SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI /* | SBIC_CTL_HSP */ 840 1.1 reinoud | dev->sc_dmamode); 841 1.1 reinoud /* 842 1.1 reinoud * don't allow (re)selection (SBIC_RID_ES) 843 1.1 reinoud * until we can handle target mode!! 844 1.1 reinoud */ 845 1.1 reinoud SET_SBIC_rselid(regs, SBIC_RID_ER); 846 1.1 reinoud SET_SBIC_syn(regs, 0); /* asynch for now */ 847 1.1 reinoud 848 1.1 reinoud /* 849 1.1 reinoud * anything else was zeroed by reset 850 1.1 reinoud */ 851 1.1 reinoud splx(s); 852 1.1 reinoud 853 1.1 reinoud #if 0 854 1.1 reinoud if ((dev->sc_flags & SBICF_ALIVE) == 0) { 855 1.1 reinoud TAILQ_INIT(&dev->ready_list); 856 1.1 reinoud TAILQ_INIT(&dev->nexus_list); 857 1.1 reinoud TAILQ_INIT(&dev->free_list); 858 1.1 reinoud dev->sc_nexus = NULL; 859 1.1 reinoud acb = dev->sc_acb; 860 1.1 reinoud memset(acb, 0, sizeof(dev->sc_acb)); 861 1.1 reinoud for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) { 862 1.1 reinoud TAILQ_INSERT_TAIL(&dev->free_list, acb, chain); 863 1.1 reinoud acb++; 864 1.1 reinoud } 865 1.1 reinoud memset(dev->sc_tinfo, 0, sizeof(dev->sc_tinfo)); 866 1.1 reinoud } else { 867 1.1 reinoud if (dev->sc_nexus != NULL) { 868 1.1 reinoud dev->sc_nexus->xs->error = XS_DRIVER_STUFFUP; 869 1.1 reinoud sbic_scsidone(dev->sc_nexus, dev->sc_stat[0]); 870 1.1 reinoud } 871 1.1 reinoud while (acb = dev->nexus_list.tqh_first) { 872 1.1 reinoud acb->xs->error = XS_DRIVER_STUFFUP; 873 1.1 reinoud sbic_scsidone(acb, -1 /*acb->stat[0]*/); 874 1.1 reinoud } 875 1.1 reinoud } 876 1.1 reinoud 877 1.1 reinoud dev->sc_flags |= SBICF_ALIVE; 878 1.1 reinoud #endif 879 1.1 reinoud dev->sc_flags &= ~SBICF_SELECTED; 880 1.1 reinoud } 881 1.1 reinoud 882 1.1 reinoud static void 883 1.1 reinoud sbicerror(struct sbic_softc *dev, sbic_regmap_p regs, u_char csr) 884 1.1 reinoud { 885 1.1 reinoud #ifdef DIAGNOSTIC 886 1.1 reinoud if (dev->sc_nexus == NULL) 887 1.1 reinoud panic("sbicerror"); 888 1.1 reinoud #endif 889 1.1 reinoud if (dev->sc_nexus->xs->xs_control & XS_CTL_SILENT) 890 1.1 reinoud return; 891 1.1 reinoud 892 1.17 chs printf("%s: ", device_xname(dev->sc_dev)); 893 1.1 reinoud printf("csr == 0x%02x\n", csr); /* XXX */ 894 1.1 reinoud } 895 1.1 reinoud 896 1.1 reinoud /* 897 1.1 reinoud * select the bus, return when selected or error. 898 1.1 reinoud */ 899 1.1 reinoud static int 900 1.1 reinoud sbicselectbus(struct sbic_softc *dev, sbic_regmap_p regs, u_char target, 901 1.1 reinoud u_char lun, u_char our_addr) 902 1.1 reinoud { 903 1.1 reinoud u_char asr, csr, id; 904 1.1 reinoud 905 1.1 reinoud SBIC_TRACE(dev); 906 1.1 reinoud QPRINTF(("sbicselectbus %d\n", target)); 907 1.1 reinoud 908 1.1 reinoud /* 909 1.1 reinoud * if we're already selected, return (XXXX panic maybe?) 910 1.1 reinoud */ 911 1.1 reinoud if (dev->sc_flags & SBICF_SELECTED) { 912 1.1 reinoud SBIC_TRACE(dev); 913 1.1 reinoud return 1; 914 1.1 reinoud } 915 1.1 reinoud 916 1.1 reinoud /* 917 1.1 reinoud * issue select 918 1.1 reinoud */ 919 1.1 reinoud SBIC_TC_PUT(regs, 0); 920 1.1 reinoud SET_SBIC_selid(regs, target); 921 1.1 reinoud SET_SBIC_timeo(regs, SBIC_TIMEOUT(250,dev->sc_clkfreq)); 922 1.1 reinoud 923 1.1 reinoud /* 924 1.1 reinoud * set sync or async 925 1.1 reinoud */ 926 1.1 reinoud if (dev->sc_sync[target].state == SYNC_DONE) 927 1.1 reinoud SET_SBIC_syn(regs, SBIC_SYN (dev->sc_sync[target].offset, 928 1.1 reinoud dev->sc_sync[target].period)); 929 1.1 reinoud else 930 1.1 reinoud SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period)); 931 1.1 reinoud 932 1.1 reinoud GET_SBIC_asr(regs, asr); 933 1.1 reinoud if (asr & (SBIC_ASR_INT | SBIC_ASR_BSY)) { 934 1.1 reinoud /* This means we got ourselves reselected upon */ 935 1.1 reinoud /* printf("sbicselectbus: INT/BSY asr %02x\n", asr);*/ 936 1.1 reinoud #ifdef DDB 937 1.1 reinoud /* Debugger();*/ 938 1.1 reinoud #endif 939 1.1 reinoud SBIC_TRACE(dev); 940 1.1 reinoud return 1; 941 1.1 reinoud } 942 1.1 reinoud 943 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN); 944 1.1 reinoud 945 1.1 reinoud /* 946 1.1 reinoud * wait for select (merged from separate function may need 947 1.1 reinoud * cleanup) 948 1.1 reinoud */ 949 1.1 reinoud WAIT_CIP(regs); 950 1.1 reinoud do { 951 1.1 reinoud asr = SBIC_WAIT(regs, SBIC_ASR_INT | SBIC_ASR_LCI, 0); 952 1.1 reinoud if (asr & SBIC_ASR_LCI) { 953 1.1 reinoud 954 1.1 reinoud DBGPRINTF(("sbicselectbus: late LCI asr %02x\n", asr), 955 1.1 reinoud reselect_debug); 956 1.1 reinoud 957 1.1 reinoud SBIC_TRACE(dev); 958 1.1 reinoud return 1; 959 1.1 reinoud } 960 1.1 reinoud GET_SBIC_csr (regs, csr); 961 1.1 reinoud CSR_TRACE('s',csr,asr,target); 962 1.1 reinoud QPRINTF(("%02x ", csr)); 963 1.1 reinoud if (csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY) { 964 1.1 reinoud 965 1.1 reinoud DBGPRINTF(("sbicselectbus: reselected asr %02x\n", 966 1.1 reinoud asr), reselect_debug); 967 1.1 reinoud 968 1.1 reinoud /* We need to handle this now so we don't lock 969 1.1 reinoud up later */ 970 1.1 reinoud sbicnextstate(dev, csr, asr); 971 1.1 reinoud SBIC_TRACE(dev); 972 1.1 reinoud return 1; 973 1.1 reinoud } 974 1.1 reinoud if (csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN) { 975 1.1 reinoud panic("sbicselectbus: target issued select!"); 976 1.1 reinoud return 1; 977 1.1 reinoud } 978 1.1 reinoud } while (csr != (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) && 979 1.1 reinoud csr != (SBIC_CSR_MIS_2 | CMD_PHASE) && 980 1.1 reinoud csr != SBIC_CSR_SEL_TIMEO); 981 1.1 reinoud 982 1.1 reinoud /* Enable (or not) reselection */ 983 1.1 reinoud if (!sbic_enable_reselect && dev->nexus_list.tqh_first == NULL) 984 1.1 reinoud SET_SBIC_rselid (regs, 0); 985 1.1 reinoud else 986 1.1 reinoud SET_SBIC_rselid (regs, SBIC_RID_ER); 987 1.1 reinoud 988 1.1 reinoud if (csr == (SBIC_CSR_MIS_2 | CMD_PHASE)) { 989 1.1 reinoud dev->sc_flags |= SBICF_SELECTED; /* device ignored ATN */ 990 1.1 reinoud GET_SBIC_selid(regs, id); 991 1.1 reinoud dev->target = id; 992 1.1 reinoud GET_SBIC_tlun(regs,dev->lun); 993 1.1 reinoud if (dev->lun & SBIC_TLUN_VALID) 994 1.1 reinoud dev->lun &= SBIC_TLUN_MASK; 995 1.1 reinoud else 996 1.1 reinoud dev->lun = lun; 997 1.1 reinoud } else if (csr == (SBIC_CSR_MIS_2 | MESG_OUT_PHASE)) { 998 1.1 reinoud /* 999 1.1 reinoud * Send identify message 1000 1.1 reinoud * (SCSI-2 requires an identify msg (?)) 1001 1.1 reinoud */ 1002 1.1 reinoud GET_SBIC_selid(regs, id); 1003 1.1 reinoud dev->target = id; 1004 1.1 reinoud GET_SBIC_tlun(regs,dev->lun); 1005 1.1 reinoud if (dev->lun & SBIC_TLUN_VALID) 1006 1.1 reinoud dev->lun &= SBIC_TLUN_MASK; 1007 1.1 reinoud else 1008 1.1 reinoud dev->lun = lun; 1009 1.1 reinoud /* 1010 1.1 reinoud * handle drives that don't want to be asked 1011 1.1 reinoud * whether to go sync at all. 1012 1.1 reinoud */ 1013 1.1 reinoud if (sbic_inhibit_sync[id] 1014 1.1 reinoud && dev->sc_sync[id].state == SYNC_START) { 1015 1.1 reinoud DBGPRINTF(("Forcing target %d asynchronous.\n", id), 1016 1.1 reinoud sync_debug); 1017 1.1 reinoud 1018 1.1 reinoud dev->sc_sync[id].offset = 0; 1019 1.1 reinoud dev->sc_sync[id].period = sbic_min_period; 1020 1.1 reinoud dev->sc_sync[id].state = SYNC_DONE; 1021 1.1 reinoud } 1022 1.1 reinoud 1023 1.1 reinoud 1024 1.1 reinoud if (dev->sc_sync[id].state != SYNC_START){ 1025 1.1 reinoud if ((dev->sc_nexus->xs->xs_control & XS_CTL_POLL) 1026 1.1 reinoud || (dev->sc_flags & SBICF_ICMD) 1027 1.1 reinoud || !sbic_enable_reselect) 1028 1.1 reinoud SEND_BYTE(regs, MSG_IDENTIFY | lun); 1029 1.1 reinoud else 1030 1.1 reinoud SEND_BYTE(regs, MSG_IDENTIFY_DR | lun); 1031 1.1 reinoud } else { 1032 1.1 reinoud /* 1033 1.1 reinoud * try to initiate a sync transfer. 1034 1.1 reinoud * So compose the sync message we're going 1035 1.1 reinoud * to send to the target 1036 1.1 reinoud */ 1037 1.1 reinoud 1038 1.1 reinoud DBGPRINTF(("Sending sync request to target %d ... ", 1039 1.1 reinoud id), sync_debug); 1040 1.1 reinoud 1041 1.1 reinoud /* 1042 1.1 reinoud * setup scsi message sync message request 1043 1.1 reinoud */ 1044 1.1 reinoud dev->sc_msg[0] = MSG_IDENTIFY | lun; 1045 1.1 reinoud dev->sc_msg[1] = MSG_EXT_MESSAGE; 1046 1.1 reinoud dev->sc_msg[2] = 3; 1047 1.1 reinoud dev->sc_msg[3] = MSG_SYNC_REQ; 1048 1.1 reinoud dev->sc_msg[4] = sbictoscsiperiod(dev, regs, 1049 1.1 reinoud sbic_min_period); 1050 1.1 reinoud dev->sc_msg[5] = sbic_max_offset; 1051 1.1 reinoud 1052 1.1 reinoud if (sbicxfstart(regs, 6, MESG_OUT_PHASE, 1053 1.1 reinoud sbic_cmd_wait)) 1054 1.1 reinoud sbicxfout(regs, 6, dev->sc_msg, 1055 1.1 reinoud MESG_OUT_PHASE); 1056 1.1 reinoud 1057 1.1 reinoud dev->sc_sync[id].state = SYNC_SENT; 1058 1.1 reinoud 1059 1.1 reinoud DBGPRINTF(("sent\n"), sync_debug); 1060 1.1 reinoud } 1061 1.1 reinoud 1062 1.1 reinoud asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0); 1063 1.1 reinoud GET_SBIC_csr (regs, csr); 1064 1.1 reinoud CSR_TRACE('y',csr,asr,target); 1065 1.1 reinoud QPRINTF(("[%02x]", csr)); 1066 1.1 reinoud 1067 1.1 reinoud DBGPRINTF(("csr-result of last msgout: 0x%x\n", csr), 1068 1.1 reinoud sync_debug && dev->sc_sync[id].state == SYNC_SENT); 1069 1.1 reinoud 1070 1.1 reinoud if (csr != SBIC_CSR_SEL_TIMEO) 1071 1.1 reinoud dev->sc_flags |= SBICF_SELECTED; 1072 1.1 reinoud } 1073 1.1 reinoud if (csr == SBIC_CSR_SEL_TIMEO) 1074 1.1 reinoud dev->sc_nexus->xs->error = XS_SELTIMEOUT; 1075 1.1 reinoud 1076 1.1 reinoud QPRINTF(("\n")); 1077 1.1 reinoud 1078 1.1 reinoud SBIC_TRACE(dev); 1079 1.1 reinoud return csr == SBIC_CSR_SEL_TIMEO; 1080 1.1 reinoud } 1081 1.1 reinoud 1082 1.1 reinoud static int 1083 1.1 reinoud sbicxfstart(sbic_regmap_p regs, int len, u_char phase, int wait) 1084 1.1 reinoud { 1085 1.1 reinoud u_char id; 1086 1.1 reinoud 1087 1.1 reinoud switch (phase) { 1088 1.1 reinoud case DATA_IN_PHASE: 1089 1.1 reinoud case MESG_IN_PHASE: 1090 1.1 reinoud GET_SBIC_selid (regs, id); 1091 1.1 reinoud id |= SBIC_SID_FROM_SCSI; 1092 1.1 reinoud SET_SBIC_selid (regs, id); 1093 1.1 reinoud SBIC_TC_PUT (regs, (unsigned)len); 1094 1.1 reinoud break; 1095 1.1 reinoud case DATA_OUT_PHASE: 1096 1.1 reinoud case MESG_OUT_PHASE: 1097 1.1 reinoud case CMD_PHASE: 1098 1.1 reinoud GET_SBIC_selid (regs, id); 1099 1.1 reinoud id &= ~SBIC_SID_FROM_SCSI; 1100 1.1 reinoud SET_SBIC_selid (regs, id); 1101 1.1 reinoud SBIC_TC_PUT (regs, (unsigned)len); 1102 1.1 reinoud break; 1103 1.1 reinoud default: 1104 1.1 reinoud SBIC_TC_PUT (regs, 0); 1105 1.1 reinoud } 1106 1.1 reinoud QPRINTF(("sbicxfstart %d, %d, %d\n", len, phase, wait)); 1107 1.1 reinoud 1108 1.1 reinoud return 1; 1109 1.1 reinoud } 1110 1.1 reinoud 1111 1.1 reinoud static int 1112 1.1 reinoud sbicxfout(sbic_regmap_p regs, int len, void *bp, int phase) 1113 1.1 reinoud { 1114 1.1 reinoud #ifdef UNPROTECTED_CSR 1115 1.1 reinoud u_char orig_csr 1116 1.1 reinoud #endif 1117 1.1 reinoud u_char asr, *buf; 1118 1.1 reinoud /* u_char csr;*/ 1119 1.1 reinoud int wait; 1120 1.1 reinoud 1121 1.1 reinoud buf = bp; 1122 1.1 reinoud wait = sbic_data_wait; 1123 1.1 reinoud 1124 1.1 reinoud QPRINTF(("sbicxfout {%d} %02x %02x %02x %02x %02x " 1125 1.1 reinoud "%02x %02x %02x %02x %02x\n", len, buf[0], buf[1], buf[2], 1126 1.1 reinoud buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9])); 1127 1.1 reinoud 1128 1.1 reinoud #ifdef UNPROTECTED_CSR 1129 1.1 reinoud GET_SBIC_csr (regs, orig_csr); 1130 1.1 reinoud CSR_TRACE('>',orig_csr,0,0); 1131 1.1 reinoud #endif 1132 1.1 reinoud 1133 1.1 reinoud /* 1134 1.1 reinoud * sigh.. WD-PROTO strikes again.. sending the command in one go 1135 1.1 reinoud * causes the chip to lock up if talking to certain (misbehaving?) 1136 1.1 reinoud * targets. Anyway, this procedure should work for all targets, but 1137 1.1 reinoud * it's slightly slower due to the overhead 1138 1.1 reinoud */ 1139 1.1 reinoud WAIT_CIP (regs); 1140 1.1 reinoud SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); 1141 1.1 reinoud for (;len > 0; len--) { 1142 1.1 reinoud GET_SBIC_asr (regs, asr); 1143 1.1 reinoud while ((asr & SBIC_ASR_DBR) == 0) { 1144 1.1 reinoud if ((asr & SBIC_ASR_INT) || --wait < 0) { 1145 1.1 reinoud 1146 1.1 reinoud DBGPRINTF(("sbicxfout fail: l%d i%x w%d\n", 1147 1.1 reinoud len, asr, wait), sbic_debug); 1148 1.1 reinoud 1149 1.1 reinoud return len; 1150 1.1 reinoud } 1151 1.1 reinoud /* DELAY(1);*/ 1152 1.1 reinoud GET_SBIC_asr (regs, asr); 1153 1.1 reinoud } 1154 1.1 reinoud 1155 1.1 reinoud SET_SBIC_data (regs, *buf); 1156 1.1 reinoud buf++; 1157 1.1 reinoud } 1158 1.1 reinoud SBIC_TC_GET(regs, len); 1159 1.1 reinoud QPRINTF(("sbicxfout done %d bytes\n", len)); 1160 1.1 reinoud /* 1161 1.1 reinoud * this leaves with one csr to be read 1162 1.1 reinoud */ 1163 1.1 reinoud return 0; 1164 1.1 reinoud } 1165 1.1 reinoud 1166 1.1 reinoud /* returns # bytes left to read */ 1167 1.1 reinoud static int 1168 1.1 reinoud sbicxfin(sbic_regmap_p regs, int len, void *bp) 1169 1.1 reinoud { 1170 1.1 reinoud int wait; 1171 1.1 reinoud /* int read;*/ 1172 1.1 reinoud u_char *obp, *buf; 1173 1.1 reinoud #ifdef UNPROTECTED_CSR 1174 1.1 reinoud u_char orig_csr, csr; 1175 1.1 reinoud #endif 1176 1.1 reinoud u_char asr; 1177 1.1 reinoud 1178 1.1 reinoud wait = sbic_data_wait; 1179 1.1 reinoud obp = bp; 1180 1.1 reinoud buf = bp; 1181 1.1 reinoud 1182 1.1 reinoud #ifdef UNPROTECTED_CSR 1183 1.1 reinoud GET_SBIC_csr (regs, orig_csr); 1184 1.1 reinoud CSR_TRACE('<',orig_csr,0,0); 1185 1.1 reinoud 1186 1.1 reinoud QPRINTF(("sbicxfin %d, csr=%02x\n", len, orig_csr)); 1187 1.1 reinoud #endif 1188 1.1 reinoud 1189 1.1 reinoud WAIT_CIP (regs); 1190 1.1 reinoud SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO); 1191 1.1 reinoud for (;len > 0; len--) { 1192 1.1 reinoud GET_SBIC_asr (regs, asr); 1193 1.1 reinoud if ((asr & SBIC_ASR_PE)) { 1194 1.1 reinoud DBG(printf("sbicxfin parity error: l%d i%x w%d\n", 1195 1.1 reinoud len, asr, wait)); 1196 1.1 reinoud #if defined(DDB) && defined(DEBUG) 1197 1.1 reinoud Debugger(); 1198 1.1 reinoud #endif 1199 1.1 reinoud DBG(return ((unsigned long)buf - (unsigned long)bp)); 1200 1.1 reinoud } 1201 1.1 reinoud while ((asr & SBIC_ASR_DBR) == 0) { 1202 1.1 reinoud if ((asr & SBIC_ASR_INT) || --wait < 0) { 1203 1.1 reinoud 1204 1.1 reinoud DBG(if (sbic_debug) { 1205 1.1 reinoud QPRINTF(("sbicxfin fail:{%d} %02x %02x %02x %02x %02x %02x " 1206 1.1 reinoud "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2], 1207 1.1 reinoud obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9])); 1208 1.1 reinoud printf("sbicxfin fail: l%d i%x w%d\n", len, asr, wait); }); 1209 1.1 reinoud 1210 1.1 reinoud return len; 1211 1.1 reinoud } 1212 1.1 reinoud 1213 1.1 reinoud #ifdef UNPROTECTED_CSR 1214 1.1 reinoud if (!(asr & SBIC_ASR_BSY)) { 1215 1.1 reinoud GET_SBIC_csr(regs, csr); 1216 1.1 reinoud CSR_TRACE('<',csr,asr,len); 1217 1.1 reinoud QPRINTF(("[CSR%02xASR%02x]", csr, asr)); 1218 1.1 reinoud } 1219 1.1 reinoud #endif 1220 1.1 reinoud 1221 1.1 reinoud /* DELAY(1);*/ 1222 1.1 reinoud GET_SBIC_asr (regs, asr); 1223 1.1 reinoud } 1224 1.1 reinoud 1225 1.1 reinoud GET_SBIC_data (regs, *buf); 1226 1.1 reinoud /* QPRINTF(("asr=%02x, csr=%02x, data=%02x\n", asr, csr, *buf));*/ 1227 1.1 reinoud buf++; 1228 1.1 reinoud } 1229 1.1 reinoud 1230 1.1 reinoud QPRINTF(("sbicxfin {%d} %02x %02x %02x %02x %02x %02x " 1231 1.1 reinoud "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2], 1232 1.1 reinoud obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9])); 1233 1.1 reinoud 1234 1.1 reinoud /* this leaves with one csr to be read */ 1235 1.1 reinoud return len; 1236 1.1 reinoud } 1237 1.1 reinoud 1238 1.1 reinoud /* 1239 1.1 reinoud * SCSI 'immediate' command: issue a command to some SCSI device 1240 1.1 reinoud * and get back an 'immediate' response (i.e., do programmed xfer 1241 1.1 reinoud * to get the response data). 'cbuf' is a buffer containing a scsi 1242 1.1 reinoud * command of length clen bytes. 'buf' is a buffer of length 'len' 1243 1.1 reinoud * bytes for data. The transfer direction is determined by the device 1244 1.1 reinoud * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the 1245 1.1 reinoud * command must supply no data. 1246 1.1 reinoud */ 1247 1.1 reinoud static int 1248 1.1 reinoud sbicicmd(struct sbic_softc *dev, int target, int lun, struct sbic_acb *acb) 1249 1.1 reinoud { 1250 1.1 reinoud sbic_regmap_p regs; 1251 1.1 reinoud u_char phase, csr, asr; 1252 1.1 reinoud int wait; 1253 1.1 reinoud /* int newtarget, cmd_sent, parity_err;*/ 1254 1.1 reinoud 1255 1.1 reinoud /* int discon;*/ 1256 1.1 reinoud int i; 1257 1.1 reinoud 1258 1.1 reinoud void *cbuf, *buf; 1259 1.1 reinoud int clen, len; 1260 1.1 reinoud 1261 1.1 reinoud #define CSR_LOG_BUF_SIZE 0 1262 1.1 reinoud #if CSR_LOG_BUF_SIZE 1263 1.1 reinoud int bufptr; 1264 1.1 reinoud int csrbuf[CSR_LOG_BUF_SIZE]; 1265 1.1 reinoud bufptr = 0; 1266 1.1 reinoud #endif 1267 1.1 reinoud 1268 1.1 reinoud cbuf = &acb->cmd; 1269 1.1 reinoud clen = acb->clen; 1270 1.1 reinoud buf = acb->data; 1271 1.1 reinoud len = acb->datalen; 1272 1.1 reinoud 1273 1.1 reinoud SBIC_TRACE(dev); 1274 1.1 reinoud regs = &dev->sc_sbicp; 1275 1.1 reinoud 1276 1.1 reinoud acb->sc_tcnt = 0; 1277 1.1 reinoud 1278 1.1 reinoud DBG(routine = 3); 1279 1.1 reinoud DBG(debug_sbic_regs = regs); /* store this to allow debug calls */ 1280 1.1 reinoud DBGPRINTF(("sbicicmd(%d,%d):%d\n", target, lun, len), 1281 1.1 reinoud data_pointer_debug > 1); 1282 1.1 reinoud 1283 1.1 reinoud /* 1284 1.1 reinoud * set the sbic into non-DMA mode 1285 1.1 reinoud */ 1286 1.1 reinoud SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI /*| SBIC_CTL_HSP*/); 1287 1.1 reinoud 1288 1.1 reinoud dev->sc_stat[0] = 0xff; 1289 1.1 reinoud dev->sc_msg[0] = 0xff; 1290 1.1 reinoud i = 1; /* pre-load */ 1291 1.1 reinoud 1292 1.1 reinoud /* We're stealing the SCSI bus */ 1293 1.1 reinoud dev->sc_flags |= SBICF_ICMD; 1294 1.1 reinoud 1295 1.1 reinoud do { 1296 1.1 reinoud /* 1297 1.1 reinoud * select the SCSI bus (it's an error if bus isn't free) 1298 1.1 reinoud */ 1299 1.1 reinoud if (!(dev->sc_flags & SBICF_SELECTED) 1300 1.1 reinoud && sbicselectbus(dev, regs, target, lun, 1301 1.1 reinoud dev->sc_scsiaddr)) { 1302 1.1 reinoud /*printf("sbicicmd trying to select busy bus!\n");*/ 1303 1.1 reinoud dev->sc_flags &= ~SBICF_ICMD; 1304 1.1 reinoud return -1; 1305 1.1 reinoud } 1306 1.1 reinoud 1307 1.1 reinoud /* 1308 1.1 reinoud * Wait for a phase change (or error) then let the 1309 1.1 reinoud * device sequence us through the various SCSI phases. 1310 1.1 reinoud */ 1311 1.1 reinoud 1312 1.1 reinoud wait = sbic_cmd_wait; 1313 1.1 reinoud 1314 1.8 matt GET_SBIC_asr (regs, asr); 1315 1.1 reinoud GET_SBIC_csr (regs, csr); 1316 1.1 reinoud CSR_TRACE('I',csr,asr,target); 1317 1.1 reinoud QPRINTF((">ASR:%02xCSR:%02x<", asr, csr)); 1318 1.1 reinoud 1319 1.1 reinoud #if CSR_LOG_BUF_SIZE 1320 1.1 reinoud csrbuf[bufptr++] = csr; 1321 1.1 reinoud #endif 1322 1.1 reinoud 1323 1.1 reinoud 1324 1.1 reinoud switch (csr) { 1325 1.1 reinoud case SBIC_CSR_S_XFERRED: 1326 1.1 reinoud case SBIC_CSR_DISC: 1327 1.1 reinoud case SBIC_CSR_DISC_1: 1328 1.1 reinoud dev->sc_flags &= ~SBICF_SELECTED; 1329 1.1 reinoud GET_SBIC_cmd_phase (regs, phase); 1330 1.1 reinoud if (phase == 0x60) { 1331 1.1 reinoud GET_SBIC_tlun (regs, dev->sc_stat[0]); 1332 1.1 reinoud i = 0; /* done */ 1333 1.1 reinoud /* break;*/ /* Bypass all the state gobldygook */ 1334 1.1 reinoud } else { 1335 1.1 reinoud DBGPRINTF(("sbicicmd: handling disconnect\n"), 1336 1.1 reinoud reselect_debug > 1); 1337 1.1 reinoud 1338 1.1 reinoud i = SBIC_STATE_DISCONNECT; 1339 1.1 reinoud } 1340 1.1 reinoud break; 1341 1.1 reinoud 1342 1.1 reinoud case SBIC_CSR_XFERRED | CMD_PHASE: 1343 1.1 reinoud case SBIC_CSR_MIS | CMD_PHASE: 1344 1.1 reinoud case SBIC_CSR_MIS_1 | CMD_PHASE: 1345 1.1 reinoud case SBIC_CSR_MIS_2 | CMD_PHASE: 1346 1.1 reinoud if (sbicxfstart(regs, clen, CMD_PHASE, sbic_cmd_wait)) 1347 1.1 reinoud if (sbicxfout(regs, clen, 1348 1.1 reinoud cbuf, CMD_PHASE)) 1349 1.1 reinoud i = sbicabort(dev, regs, 1350 1.1 reinoud "icmd sending cmd"); 1351 1.1 reinoud #if 0 1352 1.1 reinoud GET_SBIC_csr(regs, csr); /* Lets us reload tcount */ 1353 1.1 reinoud WAIT_CIP(regs); 1354 1.1 reinoud GET_SBIC_asr(regs, asr); 1355 1.1 reinoud CSR_TRACE('I',csr,asr,target); 1356 1.1 reinoud if (asr & (SBIC_ASR_BSY | SBIC_ASR_LCI | SBIC_ASR_CIP)) 1357 1.1 reinoud printf("next: cmd sent asr %02x, csr %02x\n", 1358 1.1 reinoud asr, csr); 1359 1.1 reinoud #endif 1360 1.1 reinoud break; 1361 1.1 reinoud 1362 1.1 reinoud #if 0 1363 1.1 reinoud case SBIC_CSR_XFERRED | DATA_OUT_PHASE: 1364 1.1 reinoud case SBIC_CSR_XFERRED | DATA_IN_PHASE: 1365 1.1 reinoud case SBIC_CSR_MIS | DATA_OUT_PHASE: 1366 1.1 reinoud case SBIC_CSR_MIS | DATA_IN_PHASE: 1367 1.1 reinoud case SBIC_CSR_MIS_1 | DATA_OUT_PHASE: 1368 1.1 reinoud case SBIC_CSR_MIS_1 | DATA_IN_PHASE: 1369 1.1 reinoud case SBIC_CSR_MIS_2 | DATA_OUT_PHASE: 1370 1.1 reinoud case SBIC_CSR_MIS_2 | DATA_IN_PHASE: 1371 1.1 reinoud if (acb->datalen <= 0) 1372 1.1 reinoud i = sbicabort(dev, regs, "icmd out of data"); 1373 1.1 reinoud else { 1374 1.1 reinoud wait = sbic_data_wait; 1375 1.1 reinoud if (sbicxfstart(regs, acb->datalen, 1376 1.1 reinoud SBIC_PHASE(csr), wait)) 1377 1.1 reinoud if (csr & 0x01) 1378 1.1 reinoud /* data in? */ 1379 1.1 reinoud i = sbicxfin(regs, acb->datalen, acb->data); 1380 1.1 reinoud else 1381 1.1 reinoud i = sbicxfout(regs, acb->datalen, acb->data, 1382 1.1 reinoud SBIC_PHASE(csr)); 1383 1.1 reinoud acb->data += acb->datalen - i; 1384 1.1 reinoud acb->datalen = i; 1385 1.1 reinoud i = 1; 1386 1.1 reinoud } 1387 1.1 reinoud break; 1388 1.1 reinoud 1389 1.1 reinoud #endif 1390 1.1 reinoud case SBIC_CSR_XFERRED | STATUS_PHASE: 1391 1.1 reinoud case SBIC_CSR_MIS | STATUS_PHASE: 1392 1.1 reinoud case SBIC_CSR_MIS_1 | STATUS_PHASE: 1393 1.1 reinoud case SBIC_CSR_MIS_2 | STATUS_PHASE: 1394 1.1 reinoud /* 1395 1.1 reinoud * the sbic does the status/cmd-complete reading ok, 1396 1.1 reinoud * so do this with its hi-level commands. 1397 1.1 reinoud */ 1398 1.1 reinoud DBGPRINTF(("SBICICMD status phase\n"), sbic_debug); 1399 1.1 reinoud 1400 1.1 reinoud SBIC_TC_PUT(regs, 0); 1401 1.1 reinoud SET_SBIC_cmd_phase(regs, 0x46); 1402 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER); 1403 1.1 reinoud break; 1404 1.1 reinoud 1405 1.1 reinoud #if THIS_IS_A_RESERVED_STATE 1406 1.1 reinoud case BUS_FREE_PHASE: /* This is not legal */ 1407 1.1 reinoud if (dev->sc_stat[0] != 0xff) 1408 1.1 reinoud goto out; 1409 1.1 reinoud break; 1410 1.1 reinoud #endif 1411 1.1 reinoud 1412 1.1 reinoud default: 1413 1.1 reinoud i = sbicnextstate(dev, csr, asr); 1414 1.1 reinoud } 1415 1.1 reinoud 1416 1.1 reinoud /* 1417 1.1 reinoud * make sure the last command was taken, 1418 1.1 reinoud * ie. we're not hunting after an ignored command.. 1419 1.1 reinoud */ 1420 1.1 reinoud GET_SBIC_asr(regs, asr); 1421 1.1 reinoud 1422 1.1 reinoud /* tapes may take a loooong time.. */ 1423 1.1 reinoud while (asr & SBIC_ASR_BSY){ 1424 1.1 reinoud if (asr & SBIC_ASR_DBR) { 1425 1.1 reinoud printf("sbicicmd: Waiting while sbic is " 1426 1.1 reinoud "jammed, CSR:%02x,ASR:%02x\n", 1427 1.1 reinoud csr, asr); 1428 1.1 reinoud #ifdef DDB 1429 1.1 reinoud Debugger(); 1430 1.1 reinoud #endif 1431 1.1 reinoud /* SBIC is jammed */ 1432 1.1 reinoud /* DUNNO which direction */ 1433 1.1 reinoud /* Try old direction */ 1434 1.1 reinoud GET_SBIC_data(regs,i); 1435 1.1 reinoud GET_SBIC_asr(regs, asr); 1436 1.1 reinoud if (asr & SBIC_ASR_DBR) /* Wants us to write */ 1437 1.1 reinoud SET_SBIC_data(regs,i); 1438 1.1 reinoud } 1439 1.1 reinoud GET_SBIC_asr(regs, asr); 1440 1.1 reinoud } 1441 1.1 reinoud 1442 1.1 reinoud /* 1443 1.1 reinoud * wait for last command to complete 1444 1.1 reinoud */ 1445 1.1 reinoud if (asr & SBIC_ASR_LCI) { 1446 1.1 reinoud printf("sbicicmd: last command ignored\n"); 1447 1.1 reinoud } 1448 1.1 reinoud else if (i == 1) /* Bsy */ 1449 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, wait); 1450 1.1 reinoud 1451 1.1 reinoud /* 1452 1.1 reinoud * do it again 1453 1.1 reinoud */ 1454 1.1 reinoud } while (i > 0 && dev->sc_stat[0] == 0xff); 1455 1.1 reinoud 1456 1.1 reinoud /* Sometimes we need to do an extra read of the CSR */ 1457 1.1 reinoud GET_SBIC_csr(regs, csr); 1458 1.1 reinoud CSR_TRACE('I',csr,asr,0xff); 1459 1.1 reinoud 1460 1.1 reinoud #if CSR_LOG_BUF_SIZE 1461 1.1 reinoud if (reselect_debug > 1) 1462 1.1 reinoud for (i = 0; i < bufptr; i++) 1463 1.1 reinoud printf("CSR:%02x", csrbuf[i]); 1464 1.1 reinoud #endif 1465 1.1 reinoud 1466 1.1 reinoud DBGPRINTF(("sbicicmd done(%d,%d):%d =%d=\n", 1467 1.1 reinoud dev->target, lun, 1468 1.1 reinoud acb->datalen, 1469 1.1 reinoud dev->sc_stat[0]), 1470 1.1 reinoud data_pointer_debug > 1); 1471 1.1 reinoud 1472 1.1 reinoud QPRINTF(("=STS:%02x=", dev->sc_stat[0])); 1473 1.1 reinoud dev->sc_flags &= ~SBICF_ICMD; 1474 1.1 reinoud 1475 1.1 reinoud SBIC_TRACE(dev); 1476 1.1 reinoud return dev->sc_stat[0]; 1477 1.1 reinoud } 1478 1.1 reinoud 1479 1.1 reinoud /* 1480 1.1 reinoud * Finish SCSI xfer command: After the completion interrupt from 1481 1.1 reinoud * a read/write operation, sequence through the final phases in 1482 1.1 reinoud * programmed i/o. This routine is a lot like sbicicmd except we 1483 1.1 reinoud * skip (and don't allow) the select, cmd out and data in/out phases. 1484 1.1 reinoud */ 1485 1.1 reinoud static void 1486 1.1 reinoud sbicxfdone(struct sbic_softc *dev, sbic_regmap_p regs, int target) 1487 1.1 reinoud { 1488 1.1 reinoud u_char phase, asr, csr; 1489 1.1 reinoud int s; 1490 1.1 reinoud 1491 1.1 reinoud SBIC_TRACE(dev); 1492 1.1 reinoud QPRINTF(("{")); 1493 1.1 reinoud s = splbio(); 1494 1.1 reinoud 1495 1.1 reinoud /* 1496 1.1 reinoud * have the sbic complete on its own 1497 1.1 reinoud */ 1498 1.1 reinoud SBIC_TC_PUT(regs, 0); 1499 1.1 reinoud SET_SBIC_cmd_phase(regs, 0x46); 1500 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER); 1501 1.1 reinoud 1502 1.1 reinoud do { 1503 1.1 reinoud asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0); 1504 1.1 reinoud GET_SBIC_csr (regs, csr); 1505 1.1 reinoud CSR_TRACE('f',csr,asr,target); 1506 1.1 reinoud QPRINTF(("%02x:", csr)); 1507 1.1 reinoud } while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) 1508 1.1 reinoud && (csr != SBIC_CSR_S_XFERRED)); 1509 1.1 reinoud 1510 1.1 reinoud dev->sc_flags &= ~SBICF_SELECTED; 1511 1.1 reinoud 1512 1.1 reinoud GET_SBIC_cmd_phase (regs, phase); 1513 1.1 reinoud QPRINTF(("}%02x", phase)); 1514 1.1 reinoud if (phase == 0x60) 1515 1.1 reinoud GET_SBIC_tlun(regs, dev->sc_stat[0]); 1516 1.1 reinoud else 1517 1.1 reinoud sbicerror(dev, regs, csr); 1518 1.1 reinoud 1519 1.1 reinoud QPRINTF(("=STS:%02x=\n", dev->sc_stat[0])); 1520 1.1 reinoud splx(s); 1521 1.1 reinoud SBIC_TRACE(dev); 1522 1.1 reinoud } 1523 1.1 reinoud 1524 1.1 reinoud /* 1525 1.1 reinoud * No DMA chains 1526 1.1 reinoud */ 1527 1.1 reinoud 1528 1.1 reinoud static int 1529 1.1 reinoud sbicgo(struct sbic_softc *dev, struct scsipi_xfer *xs) 1530 1.1 reinoud { 1531 1.1 reinoud int i, usedma; 1532 1.1 reinoud /* int dmaflags, count; */ 1533 1.1 reinoud /* int wait;*/ 1534 1.1 reinoud /* u_char cmd;*/ 1535 1.1 reinoud u_char asr = 0, csr = 0; 1536 1.1 reinoud /* u_char *addr; */ 1537 1.1 reinoud sbic_regmap_p regs; 1538 1.1 reinoud struct sbic_acb *acb; 1539 1.1 reinoud 1540 1.1 reinoud SBIC_TRACE(dev); 1541 1.1 reinoud dev->target = xs->xs_periph->periph_target; 1542 1.1 reinoud dev->lun = xs->xs_periph->periph_lun; 1543 1.1 reinoud acb = dev->sc_nexus; 1544 1.1 reinoud regs = &dev->sc_sbicp; 1545 1.1 reinoud 1546 1.1 reinoud usedma = acb->flags & ACB_DMA; 1547 1.1 reinoud 1548 1.1 reinoud DBG(routine = 1); 1549 1.1 reinoud DBG(debug_sbic_regs = regs); /* store this to allow debug calls */ 1550 1.1 reinoud DBGPRINTF(("sbicgo(%d,%d)\n", dev->target, dev->lun), 1551 1.1 reinoud data_pointer_debug > 1); 1552 1.1 reinoud 1553 1.1 reinoud /* 1554 1.1 reinoud * set the sbic into DMA mode 1555 1.1 reinoud */ 1556 1.1 reinoud if (usedma) 1557 1.1 reinoud SET_SBIC_control(regs, 1558 1.1 reinoud SBIC_CTL_EDI | SBIC_CTL_IDI | dev->sc_dmamode); 1559 1.1 reinoud else 1560 1.1 reinoud SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI); 1561 1.1 reinoud 1562 1.1 reinoud 1563 1.1 reinoud /* 1564 1.1 reinoud * select the SCSI bus (it's an error if bus isn't free) 1565 1.1 reinoud */ 1566 1.1 reinoud if (sbicselectbus(dev, regs, dev->target, dev->lun, 1567 1.1 reinoud dev->sc_scsiaddr)) { 1568 1.1 reinoud /* printf("sbicgo: Trying to select busy bus!\n"); */ 1569 1.1 reinoud SBIC_TRACE(dev); 1570 1.1 reinoud /* Not done: may need to be rescheduled */ 1571 1.1 reinoud return 0; 1572 1.1 reinoud } 1573 1.1 reinoud dev->sc_stat[0] = 0xff; 1574 1.1 reinoud 1575 1.1 reinoud /* 1576 1.1 reinoud * Allocate the DMA chain 1577 1.1 reinoud */ 1578 1.1 reinoud 1579 1.1 reinoud /* Mark end of segment */ 1580 1.1 reinoud acb->sc_tcnt = 0; 1581 1.1 reinoud 1582 1.1 reinoud SBIC_TRACE(dev); 1583 1.1 reinoud /* Enable interrupts */ 1584 1.1 reinoud dev->sc_enintr(dev); 1585 1.1 reinoud if (usedma) { 1586 1.1 reinoud int tcnt; 1587 1.1 reinoud 1588 1.1 reinoud acb->offset = 0; 1589 1.1 reinoud acb->sc_tcnt = 0; 1590 1.1 reinoud /* Note, this does not start DMA */ 1591 1.1 reinoud tcnt = dev->sc_dmasetup(dev->sc_dmah, dev->sc_dmat, acb, 1592 1.1 reinoud (acb->flags & ACB_DATAIN) != 0); 1593 1.1 reinoud 1594 1.1 reinoud DBG(dev->sc_dmatimo = tcnt ? 1 : 0); 1595 1.1 reinoud DBG(++sbicdma_ops); /* count total DMA operations */ 1596 1.1 reinoud } 1597 1.1 reinoud 1598 1.1 reinoud SBIC_TRACE(dev); 1599 1.1 reinoud 1600 1.1 reinoud /* 1601 1.1 reinoud * enintr() also enables interrupts for the sbic 1602 1.1 reinoud */ 1603 1.1 reinoud DBG(debug_asr = asr); 1604 1.1 reinoud DBG(debug_csr = csr); 1605 1.1 reinoud 1606 1.1 reinoud /* 1607 1.1 reinoud * Lets cycle a while then let the interrupt handler take over 1608 1.1 reinoud */ 1609 1.1 reinoud 1610 1.8 matt GET_SBIC_asr(regs, asr); 1611 1.1 reinoud do { 1612 1.1 reinoud GET_SBIC_csr(regs, csr); 1613 1.1 reinoud CSR_TRACE('g', csr, asr, dev->target); 1614 1.1 reinoud 1615 1.1 reinoud DBG(debug_csr = csr); 1616 1.1 reinoud DBG(routine = 1); 1617 1.1 reinoud 1618 1.1 reinoud QPRINTF(("go[0x%x]", csr)); 1619 1.1 reinoud 1620 1.1 reinoud i = sbicnextstate(dev, csr, asr); 1621 1.1 reinoud 1622 1.1 reinoud WAIT_CIP(regs); 1623 1.1 reinoud GET_SBIC_asr(regs, asr); 1624 1.1 reinoud 1625 1.1 reinoud DBG(debug_asr = asr); 1626 1.1 reinoud 1627 1.1 reinoud if (asr & SBIC_ASR_LCI) 1628 1.1 reinoud printf("sbicgo: LCI asr:%02x csr:%02x\n", asr, csr); 1629 1.1 reinoud } while (i == SBIC_STATE_RUNNING && 1630 1.1 reinoud (asr & (SBIC_ASR_INT | SBIC_ASR_LCI))); 1631 1.1 reinoud 1632 1.1 reinoud CSR_TRACE('g',csr,asr,i<<4); 1633 1.1 reinoud SBIC_TRACE(dev); 1634 1.1 reinoud if (i == SBIC_STATE_DONE && dev->sc_stat[0] == 0xff) 1635 1.1 reinoud printf("sbicgo: done & stat = 0xff\n"); 1636 1.1 reinoud if (i == SBIC_STATE_DONE && dev->sc_stat[0] != 0xff) { 1637 1.1 reinoud /* if (i == SBIC_STATE_DONE && dev->sc_stat[0]) { */ 1638 1.1 reinoud /* Did we really finish that fast? */ 1639 1.1 reinoud return 1; 1640 1.1 reinoud } 1641 1.1 reinoud return 0; 1642 1.1 reinoud } 1643 1.1 reinoud 1644 1.1 reinoud 1645 1.1 reinoud int 1646 1.1 reinoud sbicintr(struct sbic_softc *dev) 1647 1.1 reinoud { 1648 1.1 reinoud sbic_regmap_p regs; 1649 1.1 reinoud u_char asr, csr; 1650 1.1 reinoud /* u_char *tmpaddr;*/ 1651 1.1 reinoud /* struct sbic_acb *acb;*/ 1652 1.1 reinoud int i; 1653 1.1 reinoud /* int newtarget, newlun;*/ 1654 1.1 reinoud /* unsigned tcnt;*/ 1655 1.1 reinoud 1656 1.1 reinoud regs = &dev->sc_sbicp; 1657 1.1 reinoud 1658 1.1 reinoud /* 1659 1.1 reinoud * pending interrupt? 1660 1.1 reinoud */ 1661 1.1 reinoud GET_SBIC_asr (regs, asr); 1662 1.1 reinoud if ((asr & SBIC_ASR_INT) == 0) 1663 1.1 reinoud return 0; 1664 1.1 reinoud 1665 1.1 reinoud SBIC_TRACE(dev); 1666 1.1 reinoud do { 1667 1.1 reinoud GET_SBIC_csr(regs, csr); 1668 1.1 reinoud CSR_TRACE('i',csr,asr,dev->target); 1669 1.1 reinoud 1670 1.1 reinoud DBG(debug_csr = csr); 1671 1.1 reinoud DBG(routine = 2); 1672 1.1 reinoud 1673 1.1 reinoud QPRINTF(("intr[0x%x]", csr)); 1674 1.1 reinoud 1675 1.1 reinoud i = sbicnextstate(dev, csr, asr); 1676 1.1 reinoud 1677 1.1 reinoud WAIT_CIP(regs); 1678 1.1 reinoud GET_SBIC_asr(regs, asr); 1679 1.1 reinoud 1680 1.1 reinoud DBG(debug_asr = asr); 1681 1.1 reinoud 1682 1.1 reinoud #if 0 1683 1.1 reinoud if (asr & SBIC_ASR_LCI) 1684 1.1 reinoud printf("sbicintr: LCI asr:%02x csr:%02x\n", asr, csr); 1685 1.1 reinoud #endif 1686 1.1 reinoud } while (i == SBIC_STATE_RUNNING && 1687 1.1 reinoud (asr & (SBIC_ASR_INT | SBIC_ASR_LCI))); 1688 1.1 reinoud CSR_TRACE('i', csr, asr, i << 4); 1689 1.1 reinoud SBIC_TRACE(dev); 1690 1.1 reinoud return 1; 1691 1.1 reinoud } 1692 1.1 reinoud 1693 1.1 reinoud /* 1694 1.1 reinoud * Run commands and wait for disconnect 1695 1.1 reinoud */ 1696 1.1 reinoud static int 1697 1.1 reinoud sbicpoll(struct sbic_softc *dev) 1698 1.1 reinoud { 1699 1.1 reinoud sbic_regmap_p regs; 1700 1.1 reinoud u_char asr, csr; 1701 1.1 reinoud /* struct sbic_pending* pendp;*/ 1702 1.1 reinoud int i; 1703 1.1 reinoud /* unsigned tcnt;*/ 1704 1.1 reinoud 1705 1.1 reinoud SBIC_TRACE(dev); 1706 1.1 reinoud regs = &dev->sc_sbicp; 1707 1.1 reinoud 1708 1.1 reinoud do { 1709 1.1 reinoud GET_SBIC_asr (regs, asr); 1710 1.1 reinoud 1711 1.1 reinoud DBG(debug_asr = asr); 1712 1.1 reinoud 1713 1.1 reinoud GET_SBIC_csr(regs, csr); 1714 1.1 reinoud CSR_TRACE('p', csr, asr, dev->target); 1715 1.1 reinoud 1716 1.1 reinoud DBG(debug_csr = csr); 1717 1.1 reinoud DBG(routine = 2); 1718 1.1 reinoud 1719 1.1 reinoud QPRINTF(("poll[0x%x]", csr)); 1720 1.1 reinoud 1721 1.1 reinoud i = sbicnextstate(dev, csr, asr); 1722 1.1 reinoud 1723 1.1 reinoud WAIT_CIP(regs); 1724 1.1 reinoud GET_SBIC_asr(regs, asr); 1725 1.1 reinoud /* tapes may take a loooong time.. */ 1726 1.1 reinoud while (asr & SBIC_ASR_BSY){ 1727 1.1 reinoud if (asr & SBIC_ASR_DBR) { 1728 1.1 reinoud printf("sbipoll: Waiting while sbic is " 1729 1.1 reinoud "jammed, CSR:%02x,ASR:%02x\n", 1730 1.1 reinoud csr, asr); 1731 1.1 reinoud #ifdef DDB 1732 1.1 reinoud Debugger(); 1733 1.1 reinoud #endif 1734 1.1 reinoud /* SBIC is jammed */ 1735 1.1 reinoud /* DUNNO which direction */ 1736 1.1 reinoud /* Try old direction */ 1737 1.1 reinoud GET_SBIC_data(regs,i); 1738 1.1 reinoud GET_SBIC_asr(regs, asr); 1739 1.1 reinoud if (asr & SBIC_ASR_DBR) /* Wants us to write */ 1740 1.1 reinoud SET_SBIC_data(regs,i); 1741 1.1 reinoud } 1742 1.1 reinoud GET_SBIC_asr(regs, asr); 1743 1.1 reinoud } 1744 1.1 reinoud 1745 1.1 reinoud if (asr & SBIC_ASR_LCI) 1746 1.1 reinoud printf("sbicpoll: LCI asr:%02x csr:%02x\n", asr, csr); 1747 1.1 reinoud else if (i == 1) /* BSY */ 1748 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, sbic_cmd_wait); 1749 1.1 reinoud } while (i == SBIC_STATE_RUNNING); 1750 1.1 reinoud CSR_TRACE('p', csr, asr, i << 4); 1751 1.1 reinoud SBIC_TRACE(dev); 1752 1.1 reinoud return 1; 1753 1.1 reinoud } 1754 1.1 reinoud 1755 1.1 reinoud /* 1756 1.1 reinoud * Handle a single msgin 1757 1.1 reinoud */ 1758 1.1 reinoud 1759 1.1 reinoud static int 1760 1.1 reinoud sbicmsgin(struct sbic_softc *dev) 1761 1.1 reinoud { 1762 1.1 reinoud sbic_regmap_p regs; 1763 1.1 reinoud int recvlen; 1764 1.1 reinoud u_char asr, csr, *tmpaddr; 1765 1.1 reinoud 1766 1.1 reinoud regs = &dev->sc_sbicp; 1767 1.1 reinoud 1768 1.1 reinoud dev->sc_msg[0] = 0xff; 1769 1.1 reinoud dev->sc_msg[1] = 0xff; 1770 1.1 reinoud 1771 1.1 reinoud GET_SBIC_asr(regs, asr); 1772 1.1 reinoud 1773 1.1 reinoud DBGPRINTF(("sbicmsgin asr=%02x\n", asr), reselect_debug > 1); 1774 1.1 reinoud 1775 1.1 reinoud sbic_save_ptrs(dev, regs); 1776 1.1 reinoud 1777 1.1 reinoud GET_SBIC_selid (regs, csr); 1778 1.1 reinoud SET_SBIC_selid (regs, csr | SBIC_SID_FROM_SCSI); 1779 1.1 reinoud 1780 1.1 reinoud SBIC_TC_PUT(regs, 0); 1781 1.1 reinoud tmpaddr = dev->sc_msg; 1782 1.1 reinoud recvlen = 1; 1783 1.1 reinoud do { 1784 1.1 reinoud while (recvlen--) { 1785 1.8 matt GET_SBIC_asr(regs, asr); 1786 1.1 reinoud GET_SBIC_csr(regs, csr); 1787 1.1 reinoud QPRINTF(("sbicmsgin ready to go (csr,asr)=(%02x,%02x)\n", 1788 1.1 reinoud csr, asr)); 1789 1.1 reinoud 1790 1.1 reinoud RECV_BYTE(regs, *tmpaddr); 1791 1.1 reinoud CSR_TRACE('m', csr, asr, *tmpaddr); 1792 1.1 reinoud #if 1 1793 1.1 reinoud /* 1794 1.1 reinoud * get the command completion interrupt, or we 1795 1.1 reinoud * can't send a new command (LCI) 1796 1.1 reinoud */ 1797 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, 0); 1798 1.1 reinoud GET_SBIC_csr(regs, csr); 1799 1.1 reinoud CSR_TRACE('X', csr, asr, dev->target); 1800 1.1 reinoud #else 1801 1.1 reinoud WAIT_CIP(regs); 1802 1.1 reinoud do { 1803 1.1 reinoud GET_SBIC_asr(regs, asr); 1804 1.1 reinoud csr = 0xff; 1805 1.1 reinoud GET_SBIC_csr(regs, csr); 1806 1.1 reinoud CSR_TRACE('X', csr, asr, dev->target); 1807 1.1 reinoud if (csr == 0xff) 1808 1.1 reinoud printf("sbicmsgin waiting: csr %02x " 1809 1.1 reinoud "asr %02x\n", csr, asr); 1810 1.1 reinoud } while (csr == 0xff); 1811 1.1 reinoud #endif 1812 1.1 reinoud 1813 1.1 reinoud DBGPRINTF(("sbicmsgin: got %02x csr %02x asr %02x\n", 1814 1.1 reinoud *tmpaddr, csr, asr), reselect_debug > 1); 1815 1.1 reinoud 1816 1.1 reinoud #if do_parity_check 1817 1.1 reinoud if (asr & SBIC_ASR_PE) { 1818 1.1 reinoud printf("Parity error"); 1819 1.1 reinoud /* This code simply does not work. */ 1820 1.1 reinoud WAIT_CIP(regs); 1821 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN); 1822 1.1 reinoud WAIT_CIP(regs); 1823 1.1 reinoud GET_SBIC_asr(regs, asr); 1824 1.1 reinoud WAIT_CIP(regs); 1825 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 1826 1.1 reinoud WAIT_CIP(regs); 1827 1.1 reinoud if (!(asr & SBIC_ASR_LCI)) 1828 1.1 reinoud /* Target wants to send garbled msg*/ 1829 1.1 reinoud continue; 1830 1.1 reinoud printf("--fixing\n"); 1831 1.1 reinoud /* loop until a msgout phase occurs on 1832 1.1 reinoud target */ 1833 1.1 reinoud while ((csr & 0x07) != MESG_OUT_PHASE) { 1834 1.1 reinoud while ((asr & SBIC_ASR_BSY) && 1835 1.1 reinoud !(asr & 1836 1.1 reinoud (SBIC_ASR_DBR | SBIC_ASR_INT))) 1837 1.1 reinoud GET_SBIC_asr(regs, asr); 1838 1.1 reinoud if (asr & SBIC_ASR_DBR) 1839 1.4 provos panic("msgin: jammed again!"); 1840 1.1 reinoud GET_SBIC_csr(regs, csr); 1841 1.1 reinoud CSR_TRACE('e', csr, asr, dev->target); 1842 1.1 reinoud if ((csr & 0x07) != MESG_OUT_PHASE) { 1843 1.1 reinoud sbicnextstate(dev, csr, asr); 1844 1.1 reinoud sbic_save_ptrs(dev, regs); 1845 1.1 reinoud } 1846 1.1 reinoud } 1847 1.1 reinoud /* Should be msg out by now */ 1848 1.1 reinoud SEND_BYTE(regs, MSG_PARITY_ERROR); 1849 1.1 reinoud } 1850 1.1 reinoud else 1851 1.1 reinoud #endif 1852 1.1 reinoud tmpaddr++; 1853 1.1 reinoud 1854 1.1 reinoud if (recvlen) { 1855 1.1 reinoud /* Clear ACK */ 1856 1.1 reinoud WAIT_CIP(regs); 1857 1.1 reinoud GET_SBIC_asr(regs, asr); 1858 1.1 reinoud GET_SBIC_csr(regs, csr); 1859 1.1 reinoud CSR_TRACE('X',csr,asr,dev->target); 1860 1.1 reinoud QPRINTF(("sbicmsgin pre byte CLR_ACK (csr,asr)=(%02x,%02x)\n", 1861 1.1 reinoud csr, asr)); 1862 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 1863 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, 0); 1864 1.1 reinoud } 1865 1.1 reinoud 1866 1.1 reinoud }; 1867 1.1 reinoud 1868 1.1 reinoud if (dev->sc_msg[0] == 0xff) { 1869 1.1 reinoud printf("sbicmsgin: sbic swallowed our message\n"); 1870 1.1 reinoud break; 1871 1.1 reinoud } 1872 1.1 reinoud 1873 1.1 reinoud DBGPRINTF(("msgin done csr 0x%x asr 0x%x msg 0x%x\n", 1874 1.1 reinoud csr, asr, dev->sc_msg[0]), sync_debug); 1875 1.1 reinoud 1876 1.1 reinoud /* 1877 1.1 reinoud * test whether this is a reply to our sync 1878 1.1 reinoud * request 1879 1.1 reinoud */ 1880 1.1 reinoud if (MSG_ISIDENTIFY(dev->sc_msg[0])) { 1881 1.1 reinoud QPRINTF(("IFFY")); 1882 1.1 reinoud /* Got IFFY msg -- ack it */ 1883 1.1 reinoud } else if (dev->sc_msg[0] == MSG_REJECT 1884 1.1 reinoud && dev->sc_sync[dev->target].state == SYNC_SENT) { 1885 1.1 reinoud QPRINTF(("REJECT of SYN")); 1886 1.1 reinoud 1887 1.1 reinoud DBGPRINTF(("target %d rejected sync, going async\n", 1888 1.1 reinoud dev->target), sync_debug); 1889 1.1 reinoud 1890 1.1 reinoud dev->sc_sync[dev->target].period = sbic_min_period; 1891 1.1 reinoud dev->sc_sync[dev->target].offset = 0; 1892 1.1 reinoud dev->sc_sync[dev->target].state = SYNC_DONE; 1893 1.1 reinoud SET_SBIC_syn(regs, 1894 1.1 reinoud SBIC_SYN(dev->sc_sync[dev->target].offset, 1895 1.1 reinoud dev->sc_sync[dev->target].period)); 1896 1.1 reinoud } else if ((dev->sc_msg[0] == MSG_REJECT)) { 1897 1.1 reinoud QPRINTF(("REJECT")); 1898 1.1 reinoud /* 1899 1.1 reinoud * we'll never REJECt a REJECT message.. 1900 1.1 reinoud */ 1901 1.1 reinoud } else if ((dev->sc_msg[0] == MSG_SAVE_DATA_PTR)) { 1902 1.1 reinoud QPRINTF(("MSG_SAVE_DATA_PTR")); 1903 1.1 reinoud /* 1904 1.1 reinoud * don't reject this either. 1905 1.1 reinoud */ 1906 1.1 reinoud } else if ((dev->sc_msg[0] == MSG_DISCONNECT)) { 1907 1.1 reinoud QPRINTF(("DISCONNECT")); 1908 1.1 reinoud 1909 1.1 reinoud DBGPRINTF(("sbicmsgin: got disconnect msg %s\n", 1910 1.1 reinoud (dev->sc_flags & SBICF_ICMD) ? "rejecting" : ""), 1911 1.1 reinoud reselect_debug > 1 && 1912 1.1 reinoud dev->sc_msg[0] == MSG_DISCONNECT); 1913 1.1 reinoud 1914 1.1 reinoud if (dev->sc_flags & SBICF_ICMD) { 1915 1.1 reinoud /* We're in immediate mode. Prevent 1916 1.1 reinoud disconnects. */ 1917 1.1 reinoud /* prepare to reject the message, NACK */ 1918 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN); 1919 1.1 reinoud WAIT_CIP(regs); 1920 1.1 reinoud } 1921 1.1 reinoud } else if (dev->sc_msg[0] == MSG_CMD_COMPLETE) { 1922 1.1 reinoud QPRINTF(("CMD_COMPLETE")); 1923 1.1 reinoud /* !! KLUDGE ALERT !! quite a few drives don't seem to 1924 1.1 reinoud * really like the current way of sending the 1925 1.1 reinoud * sync-handshake together with the ident-message, and 1926 1.1 reinoud * they react by sending command-complete and 1927 1.1 reinoud * disconnecting right after returning the valid sync 1928 1.1 reinoud * handshake. So, all I can do is reselect the drive, 1929 1.1 reinoud * and hope it won't disconnect again. I don't think 1930 1.1 reinoud * this is valid behavior, but I can't help fixing a 1931 1.1 reinoud * problem that apparently exists. 1932 1.1 reinoud * 1933 1.1 reinoud * Note: we should not get here on `normal' command 1934 1.1 reinoud * completion, as that condition is handled by the 1935 1.1 reinoud * high-level sel&xfer resume command used to walk 1936 1.1 reinoud * thru status/cc-phase. 1937 1.1 reinoud */ 1938 1.1 reinoud 1939 1.1 reinoud DBGPRINTF(("GOT MSG %d! target %d acting weird.." 1940 1.1 reinoud " waiting for disconnect...\n", 1941 1.1 reinoud dev->sc_msg[0], dev->target), sync_debug); 1942 1.1 reinoud 1943 1.1 reinoud /* Check to see if sbic is handling this */ 1944 1.1 reinoud GET_SBIC_asr(regs, asr); 1945 1.1 reinoud if (asr & SBIC_ASR_BSY) 1946 1.1 reinoud return SBIC_STATE_RUNNING; 1947 1.1 reinoud 1948 1.1 reinoud /* Let's try this: Assume it works and set 1949 1.1 reinoud status to 00 */ 1950 1.1 reinoud dev->sc_stat[0] = 0; 1951 1.1 reinoud } else if (dev->sc_msg[0] == MSG_EXT_MESSAGE 1952 1.1 reinoud && tmpaddr == &dev->sc_msg[1]) { 1953 1.1 reinoud QPRINTF(("ExtMSG\n")); 1954 1.1 reinoud /* Read in whole extended message */ 1955 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 1956 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, 0); 1957 1.1 reinoud GET_SBIC_asr(regs, asr); 1958 1.1 reinoud GET_SBIC_csr(regs, csr); 1959 1.1 reinoud QPRINTF(("CLR ACK asr %02x, csr %02x\n", asr, csr)); 1960 1.1 reinoud RECV_BYTE(regs, *tmpaddr); 1961 1.1 reinoud CSR_TRACE('x',csr,asr,*tmpaddr); 1962 1.1 reinoud /* Wait for command completion IRQ */ 1963 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, 0); 1964 1.1 reinoud recvlen = *tmpaddr++; 1965 1.1 reinoud QPRINTF(("Recving ext msg, asr %02x csr %02x len %02x\n", 1966 1.1 reinoud asr, csr, recvlen)); 1967 1.1 reinoud } else if (dev->sc_msg[0] == MSG_EXT_MESSAGE && 1968 1.1 reinoud dev->sc_msg[1] == 3 && 1969 1.1 reinoud dev->sc_msg[2] == MSG_SYNC_REQ) { 1970 1.1 reinoud QPRINTF(("SYN")); 1971 1.1 reinoud dev->sc_sync[dev->target].period = 1972 1.1 reinoud sbicfromscsiperiod(dev, 1973 1.1 reinoud regs, dev->sc_msg[3]); 1974 1.1 reinoud dev->sc_sync[dev->target].offset = dev->sc_msg[4]; 1975 1.1 reinoud dev->sc_sync[dev->target].state = SYNC_DONE; 1976 1.1 reinoud SET_SBIC_syn(regs, 1977 1.1 reinoud SBIC_SYN(dev->sc_sync[dev->target].offset, 1978 1.1 reinoud dev->sc_sync[dev->target].period)); 1979 1.1 reinoud printf("%s: target %d now synchronous," 1980 1.1 reinoud " period=%dns, offset=%d.\n", 1981 1.17 chs device_xname(dev->sc_dev), dev->target, 1982 1.1 reinoud dev->sc_msg[3] * 4, dev->sc_msg[4]); 1983 1.1 reinoud } else { 1984 1.1 reinoud 1985 1.1 reinoud DBGPRINTF(("sbicmsgin: Rejecting message 0x%02x\n", 1986 1.1 reinoud dev->sc_msg[0]), sbic_debug || sync_debug); 1987 1.1 reinoud 1988 1.1 reinoud /* prepare to reject the message, NACK */ 1989 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN); 1990 1.1 reinoud WAIT_CIP(regs); 1991 1.1 reinoud } 1992 1.1 reinoud /* Clear ACK */ 1993 1.1 reinoud WAIT_CIP(regs); 1994 1.1 reinoud GET_SBIC_asr(regs, asr); 1995 1.1 reinoud GET_SBIC_csr(regs, csr); 1996 1.1 reinoud CSR_TRACE('X',csr,asr,dev->target); 1997 1.1 reinoud QPRINTF(("sbicmsgin pre CLR_ACK (csr,asr)=(%02x,%02x)%d\n", 1998 1.1 reinoud csr, asr, recvlen)); 1999 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 2000 1.1 reinoud SBIC_WAIT(regs, SBIC_ASR_INT, 0); 2001 1.1 reinoud } 2002 1.1 reinoud #if 0 2003 1.1 reinoud while ((csr == SBIC_CSR_MSGIN_W_ACK) || 2004 1.1 reinoud (SBIC_PHASE(csr) == MESG_IN_PHASE)); 2005 1.1 reinoud #else 2006 1.1 reinoud while (recvlen > 0); 2007 1.1 reinoud #endif 2008 1.1 reinoud 2009 1.1 reinoud QPRINTF(("sbicmsgin finished: csr %02x, asr %02x\n",csr, asr)); 2010 1.1 reinoud 2011 1.1 reinoud /* Should still have one CSR to read */ 2012 1.1 reinoud return SBIC_STATE_RUNNING; 2013 1.1 reinoud } 2014 1.1 reinoud 2015 1.1 reinoud 2016 1.1 reinoud /* 2017 1.1 reinoud * sbicnextstate() 2018 1.1 reinoud * return: 2019 1.1 reinoud * 0 == done 2020 1.1 reinoud * 1 == working 2021 1.1 reinoud * 2 == disconnected 2022 1.1 reinoud * -1 == error 2023 1.1 reinoud */ 2024 1.1 reinoud static int 2025 1.1 reinoud sbicnextstate(struct sbic_softc *dev, u_char csr, u_char asr) 2026 1.1 reinoud { 2027 1.1 reinoud sbic_regmap_p regs; 2028 1.1 reinoud struct sbic_acb *acb; 2029 1.1 reinoud /* int i;*/ 2030 1.1 reinoud int newtarget, newlun, wait; 2031 1.1 reinoud /* unsigned tcnt;*/ 2032 1.1 reinoud 2033 1.1 reinoud SBIC_TRACE(dev); 2034 1.1 reinoud regs = &dev->sc_sbicp; 2035 1.1 reinoud acb = dev->sc_nexus; 2036 1.1 reinoud 2037 1.1 reinoud QPRINTF(("next[%02x,%02x]",asr,csr)); 2038 1.1 reinoud 2039 1.1 reinoud switch (csr) { 2040 1.1 reinoud case SBIC_CSR_XFERRED | CMD_PHASE: 2041 1.1 reinoud case SBIC_CSR_MIS | CMD_PHASE: 2042 1.1 reinoud case SBIC_CSR_MIS_1 | CMD_PHASE: 2043 1.1 reinoud case SBIC_CSR_MIS_2 | CMD_PHASE: 2044 1.1 reinoud sbic_save_ptrs(dev, regs); 2045 1.1 reinoud if (sbicxfstart(regs, acb->clen, CMD_PHASE, sbic_cmd_wait)) 2046 1.1 reinoud if (sbicxfout(regs, acb->clen, 2047 1.1 reinoud &acb->cmd, CMD_PHASE)) 2048 1.1 reinoud goto abort; 2049 1.1 reinoud break; 2050 1.1 reinoud 2051 1.1 reinoud case SBIC_CSR_XFERRED | STATUS_PHASE: 2052 1.1 reinoud case SBIC_CSR_MIS | STATUS_PHASE: 2053 1.1 reinoud case SBIC_CSR_MIS_1 | STATUS_PHASE: 2054 1.1 reinoud case SBIC_CSR_MIS_2 | STATUS_PHASE: 2055 1.1 reinoud /* 2056 1.1 reinoud * this should be the normal i/o completion case. 2057 1.1 reinoud * get the status & cmd complete msg then let the 2058 1.1 reinoud * device driver look at what happened. 2059 1.1 reinoud */ 2060 1.1 reinoud sbicxfdone(dev,regs,dev->target); 2061 1.1 reinoud 2062 1.1 reinoud if (acb->flags & ACB_DMA) { 2063 1.1 reinoud DBG(dev->sc_dmatimo = 0); 2064 1.1 reinoud 2065 1.1 reinoud dev->sc_dmafinish(dev->sc_dmah, dev->sc_dmat, acb); 2066 1.1 reinoud 2067 1.1 reinoud dev->sc_flags &= ~SBICF_INDMA; 2068 1.1 reinoud } 2069 1.1 reinoud sbic_scsidone(acb, dev->sc_stat[0]); 2070 1.1 reinoud SBIC_TRACE(dev); 2071 1.1 reinoud return SBIC_STATE_DONE; 2072 1.1 reinoud 2073 1.1 reinoud case SBIC_CSR_XFERRED | DATA_OUT_PHASE: 2074 1.1 reinoud case SBIC_CSR_XFERRED | DATA_IN_PHASE: 2075 1.1 reinoud case SBIC_CSR_MIS | DATA_OUT_PHASE: 2076 1.1 reinoud case SBIC_CSR_MIS | DATA_IN_PHASE: 2077 1.1 reinoud case SBIC_CSR_MIS_1 | DATA_OUT_PHASE: 2078 1.1 reinoud case SBIC_CSR_MIS_1 | DATA_IN_PHASE: 2079 1.1 reinoud case SBIC_CSR_MIS_2 | DATA_OUT_PHASE: 2080 1.1 reinoud case SBIC_CSR_MIS_2 | DATA_IN_PHASE: 2081 1.1 reinoud { 2082 1.1 reinoud int i = 0; 2083 1.1 reinoud 2084 1.1 reinoud if ((acb->xs->xs_control & XS_CTL_POLL) || 2085 1.1 reinoud (dev->sc_flags & SBICF_ICMD) || 2086 1.1 reinoud (acb->flags & ACB_DMA) == 0) { 2087 1.1 reinoud /* Do PIO */ 2088 1.1 reinoud SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI); 2089 1.1 reinoud if (acb->datalen <= 0) { 2090 1.1 reinoud printf("sbicnextstate:xfer count %d asr%x csr%x\n", 2091 1.1 reinoud acb->datalen, asr, csr); 2092 1.1 reinoud goto abort; 2093 1.1 reinoud } 2094 1.1 reinoud wait = sbic_data_wait; 2095 1.1 reinoud if (sbicxfstart(regs, acb->datalen, 2096 1.1 reinoud SBIC_PHASE(csr), wait)) { 2097 1.1 reinoud if (SBIC_PHASE(csr) == DATA_IN_PHASE) 2098 1.1 reinoud /* data in? */ 2099 1.1 reinoud i = sbicxfin(regs, acb->datalen, 2100 1.1 reinoud acb->data); 2101 1.1 reinoud else 2102 1.1 reinoud i = sbicxfout(regs, acb->datalen, 2103 1.1 reinoud acb->data, SBIC_PHASE(csr)); 2104 1.1 reinoud } 2105 1.1 reinoud acb->data += acb->datalen - i; 2106 1.1 reinoud acb->datalen = i; 2107 1.1 reinoud } else { 2108 1.1 reinoud /* Transfer = using DMA */ 2109 1.1 reinoud /* 2110 1.1 reinoud * do scatter-gather dma 2111 1.1 reinoud * hacking the controller chip, ouch.. 2112 1.1 reinoud */ 2113 1.1 reinoud SET_SBIC_control(regs, 2114 1.1 reinoud SBIC_CTL_EDI | SBIC_CTL_IDI | dev->sc_dmamode); 2115 1.1 reinoud /* 2116 1.1 reinoud * set next dma addr and dec count 2117 1.1 reinoud */ 2118 1.1 reinoud sbic_save_ptrs(dev, regs); 2119 1.1 reinoud 2120 1.1 reinoud if (acb->offset >= acb->datalen) { 2121 1.1 reinoud printf("sbicnextstate:xfer offset %d asr%x csr%x\n", 2122 1.1 reinoud acb->offset, asr, csr); 2123 1.1 reinoud goto abort; 2124 1.1 reinoud } 2125 1.1 reinoud DBGPRINTF(("next dmanext: %d(offset %d)\n", 2126 1.1 reinoud dev->target, acb->offset), 2127 1.1 reinoud data_pointer_debug > 1); 2128 1.1 reinoud DBG(dev->sc_dmatimo = 1); 2129 1.1 reinoud 2130 1.1 reinoud acb->sc_tcnt = 2131 1.1 reinoud dev->sc_dmanext(dev->sc_dmah, dev->sc_dmat, 2132 1.1 reinoud acb, acb->offset); 2133 1.18 andvar DBGPRINTF(("dmanext transferring %ld bytes\n", 2134 1.1 reinoud acb->sc_tcnt), data_pointer_debug); 2135 1.1 reinoud SBIC_TC_PUT(regs, (unsigned)acb->sc_tcnt); 2136 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_XFER_INFO); 2137 1.1 reinoud dev->sc_flags |= SBICF_INDMA; 2138 1.1 reinoud } 2139 1.1 reinoud break; 2140 1.1 reinoud } 2141 1.1 reinoud case SBIC_CSR_XFERRED | MESG_IN_PHASE: 2142 1.1 reinoud case SBIC_CSR_MIS | MESG_IN_PHASE: 2143 1.1 reinoud case SBIC_CSR_MIS_1 | MESG_IN_PHASE: 2144 1.1 reinoud case SBIC_CSR_MIS_2 | MESG_IN_PHASE: 2145 1.1 reinoud SBIC_TRACE(dev); 2146 1.1 reinoud return sbicmsgin(dev); 2147 1.1 reinoud 2148 1.1 reinoud case SBIC_CSR_MSGIN_W_ACK: 2149 1.1 reinoud /* Dunno what I'm ACKing */ 2150 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 2151 1.1 reinoud printf("Acking unknown msgin CSR:%02x",csr); 2152 1.1 reinoud break; 2153 1.1 reinoud 2154 1.1 reinoud case SBIC_CSR_XFERRED | MESG_OUT_PHASE: 2155 1.1 reinoud case SBIC_CSR_MIS | MESG_OUT_PHASE: 2156 1.1 reinoud case SBIC_CSR_MIS_1 | MESG_OUT_PHASE: 2157 1.1 reinoud case SBIC_CSR_MIS_2 | MESG_OUT_PHASE: 2158 1.1 reinoud 2159 1.1 reinoud DBGPRINTF(("sending REJECT msg to last msg.\n"), sync_debug); 2160 1.1 reinoud 2161 1.1 reinoud sbic_save_ptrs(dev, regs); 2162 1.1 reinoud /* 2163 1.1 reinoud * Should only get here on reject, since it's always 2164 1.1 reinoud * US that initiate a sync transfer. 2165 1.1 reinoud */ 2166 1.1 reinoud SEND_BYTE(regs, MSG_REJECT); 2167 1.1 reinoud WAIT_CIP(regs); 2168 1.1 reinoud if (asr & (SBIC_ASR_BSY | SBIC_ASR_LCI | SBIC_ASR_CIP)) 2169 1.1 reinoud printf("next: REJECT sent asr %02x\n", asr); 2170 1.1 reinoud SBIC_TRACE(dev); 2171 1.1 reinoud return SBIC_STATE_RUNNING; 2172 1.1 reinoud 2173 1.1 reinoud case SBIC_CSR_DISC: 2174 1.1 reinoud case SBIC_CSR_DISC_1: 2175 1.1 reinoud dev->sc_flags &= ~(SBICF_INDMA | SBICF_SELECTED); 2176 1.1 reinoud 2177 1.1 reinoud /* Try to schedule another target */ 2178 1.1 reinoud DBGPRINTF(("sbicnext target %d disconnected\n", dev->target), 2179 1.1 reinoud reselect_debug > 1); 2180 1.1 reinoud 2181 1.1 reinoud TAILQ_INSERT_HEAD(&dev->nexus_list, acb, chain); 2182 1.1 reinoud ++dev->sc_tinfo[dev->target].dconns; 2183 1.1 reinoud dev->sc_nexus = NULL; 2184 1.1 reinoud 2185 1.1 reinoud if ((acb->xs->xs_control & XS_CTL_POLL) 2186 1.1 reinoud || (dev->sc_flags & SBICF_ICMD) 2187 1.1 reinoud || (!sbic_parallel_operations)) { 2188 1.1 reinoud SBIC_TRACE(dev); 2189 1.1 reinoud return SBIC_STATE_DISCONNECT; 2190 1.1 reinoud } 2191 1.1 reinoud sbic_sched(dev); 2192 1.1 reinoud SBIC_TRACE(dev); 2193 1.1 reinoud return SBIC_STATE_DISCONNECT; 2194 1.1 reinoud 2195 1.1 reinoud case SBIC_CSR_RSLT_NI: 2196 1.1 reinoud case SBIC_CSR_RSLT_IFY: 2197 1.1 reinoud GET_SBIC_rselid(regs, newtarget); 2198 1.1 reinoud /* check SBIC_RID_SIV? */ 2199 1.1 reinoud newtarget &= SBIC_RID_MASK; 2200 1.1 reinoud if (csr == SBIC_CSR_RSLT_IFY) { 2201 1.1 reinoud /* Read IFY msg to avoid lockup */ 2202 1.1 reinoud GET_SBIC_data(regs, newlun); 2203 1.1 reinoud WAIT_CIP(regs); 2204 1.1 reinoud newlun &= SBIC_TLUN_MASK; 2205 1.1 reinoud CSR_TRACE('r',csr,asr,newtarget); 2206 1.1 reinoud } else { 2207 1.1 reinoud /* Need to get IFY message */ 2208 1.1 reinoud for (newlun = 256; newlun; --newlun) { 2209 1.1 reinoud GET_SBIC_asr(regs, asr); 2210 1.1 reinoud if (asr & SBIC_ASR_INT) 2211 1.1 reinoud break; 2212 1.1 reinoud delay(1); 2213 1.1 reinoud } 2214 1.1 reinoud newlun = 0; /* XXXX */ 2215 1.1 reinoud if ((asr & SBIC_ASR_INT) == 0) { 2216 1.1 reinoud 2217 1.1 reinoud DBGPRINTF(("RSLT_NI - no IFFY message? asr %x\n", 2218 1.1 reinoud asr), reselect_debug); 2219 1.1 reinoud 2220 1.1 reinoud } else { 2221 1.1 reinoud GET_SBIC_csr(regs,csr); 2222 1.1 reinoud CSR_TRACE('n',csr,asr,newtarget); 2223 1.1 reinoud if ((csr == (SBIC_CSR_MIS | MESG_IN_PHASE)) || 2224 1.1 reinoud (csr == (SBIC_CSR_MIS_1 | MESG_IN_PHASE)) || 2225 1.1 reinoud (csr == (SBIC_CSR_MIS_2 | MESG_IN_PHASE))) { 2226 1.1 reinoud sbicmsgin(dev); 2227 1.1 reinoud newlun = dev->sc_msg[0] & 7; 2228 1.1 reinoud } else { 2229 1.1 reinoud printf("RSLT_NI - not MESG_IN_PHASE %x\n", 2230 1.1 reinoud csr); 2231 1.1 reinoud } 2232 1.1 reinoud } 2233 1.1 reinoud } 2234 1.1 reinoud 2235 1.1 reinoud DBGPRINTF(("sbicnext: reselect %s from targ %d lun %d\n", 2236 1.1 reinoud csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", 2237 1.1 reinoud newtarget, newlun), 2238 1.1 reinoud reselect_debug > 1 || 2239 1.1 reinoud (reselect_debug && csr == SBIC_CSR_RSLT_NI)); 2240 1.1 reinoud 2241 1.1 reinoud if (dev->sc_nexus) { 2242 1.1 reinoud DBGPRINTF(("%s: reselect %s with active command\n", 2243 1.17 chs device_xname(dev->sc_dev), 2244 1.1 reinoud csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY"), 2245 1.1 reinoud reselect_debug > 1); 2246 1.1 reinoud #if defined(DDB) && defined (DEBUG) 2247 1.1 reinoud /* Debugger();*/ 2248 1.1 reinoud #endif 2249 1.1 reinoud 2250 1.1 reinoud TAILQ_INSERT_HEAD(&dev->ready_list, dev->sc_nexus, 2251 1.1 reinoud chain); 2252 1.1 reinoud dev->sc_tinfo[dev->target].lubusy &= ~(1 << dev->lun); 2253 1.1 reinoud dev->sc_nexus = NULL; 2254 1.1 reinoud } 2255 1.1 reinoud /* Reload sync values for this target */ 2256 1.1 reinoud if (dev->sc_sync[newtarget].state == SYNC_DONE) 2257 1.1 reinoud SET_SBIC_syn(regs, 2258 1.1 reinoud SBIC_SYN(dev->sc_sync[newtarget].offset, 2259 1.1 reinoud dev->sc_sync[newtarget].period)); 2260 1.1 reinoud else 2261 1.1 reinoud SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period)); 2262 1.1 reinoud for (acb = dev->nexus_list.tqh_first; acb; 2263 1.1 reinoud acb = acb->chain.tqe_next) { 2264 1.1 reinoud if (acb->xs->xs_periph->periph_target != newtarget || 2265 1.1 reinoud acb->xs->xs_periph->periph_lun != newlun) 2266 1.1 reinoud continue; 2267 1.1 reinoud TAILQ_REMOVE(&dev->nexus_list, acb, chain); 2268 1.1 reinoud dev->sc_nexus = acb; 2269 1.1 reinoud dev->sc_flags |= SBICF_SELECTED; 2270 1.1 reinoud dev->target = newtarget; 2271 1.1 reinoud dev->lun = newlun; 2272 1.1 reinoud break; 2273 1.1 reinoud } 2274 1.1 reinoud if (acb == NULL) { 2275 1.1 reinoud printf("%s: reselect %s targ %d not in nexus_list %p\n", 2276 1.17 chs device_xname(dev->sc_dev), 2277 1.1 reinoud csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", newtarget, 2278 1.1 reinoud &dev->nexus_list.tqh_first); 2279 1.1 reinoud panic("bad reselect in sbic"); 2280 1.1 reinoud } 2281 1.1 reinoud if (csr == SBIC_CSR_RSLT_IFY) 2282 1.1 reinoud SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); 2283 1.1 reinoud break; 2284 1.1 reinoud 2285 1.1 reinoud default: 2286 1.1 reinoud abort: 2287 1.1 reinoud /* 2288 1.1 reinoud * Something unexpected happened -- deal with it. 2289 1.1 reinoud */ 2290 1.1 reinoud printf("sbicnextstate: aborting csr %02x asr %02x\n", csr, 2291 1.1 reinoud asr); 2292 1.1 reinoud #ifdef DDB 2293 1.1 reinoud Debugger(); 2294 1.1 reinoud #endif 2295 1.1 reinoud DBG(dev->sc_dmatimo = 0); 2296 1.1 reinoud 2297 1.1 reinoud if (dev->sc_flags & SBICF_INDMA) { 2298 1.1 reinoud dev->sc_dmafinish(dev->sc_dmah, dev->sc_dmat, acb); 2299 1.1 reinoud dev->sc_flags &= ~SBICF_INDMA; 2300 1.1 reinoud DBG(dev->sc_dmatimo = 0); 2301 1.1 reinoud } 2302 1.1 reinoud SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI); 2303 1.1 reinoud sbicerror(dev, regs, csr); 2304 1.1 reinoud sbicabort(dev, regs, "next"); 2305 1.1 reinoud sbic_scsidone(acb, -1); 2306 1.1 reinoud SBIC_TRACE(dev); 2307 1.1 reinoud return SBIC_STATE_ERROR; 2308 1.1 reinoud } 2309 1.1 reinoud 2310 1.1 reinoud SBIC_TRACE(dev); 2311 1.1 reinoud return SBIC_STATE_RUNNING; 2312 1.1 reinoud } 2313 1.1 reinoud 2314 1.1 reinoud static int 2315 1.1 reinoud sbictoscsiperiod(struct sbic_softc *dev, sbic_regmap_p regs, int a) 2316 1.1 reinoud { 2317 1.1 reinoud unsigned int fs; 2318 1.1 reinoud 2319 1.1 reinoud /* 2320 1.1 reinoud * cycle = DIV / (2*CLK) 2321 1.1 reinoud * DIV = FS+2 2322 1.11 lukem * best we can do is 200ns at 20 MHz, 2 cycles 2323 1.1 reinoud */ 2324 1.1 reinoud 2325 1.1 reinoud GET_SBIC_myid(regs,fs); 2326 1.1 reinoud fs = (fs >> 6) + 2; /* DIV */ 2327 1.1 reinoud fs = (fs * 10000) / (dev->sc_clkfreq << 1); /* Cycle, in ns */ 2328 1.1 reinoud if (a < 2) 2329 1.1 reinoud a = 8; /* map to Cycles */ 2330 1.1 reinoud return (fs * a) >> 2; /* in 4 ns units */ 2331 1.1 reinoud } 2332 1.1 reinoud 2333 1.1 reinoud static int 2334 1.1 reinoud sbicfromscsiperiod(struct sbic_softc *dev, sbic_regmap_p regs, int p) 2335 1.1 reinoud { 2336 1.1 reinoud register unsigned int fs, ret; 2337 1.1 reinoud 2338 1.1 reinoud /* Just the inverse of the above */ 2339 1.1 reinoud 2340 1.1 reinoud GET_SBIC_myid(regs, fs); 2341 1.1 reinoud fs = (fs >> 6) + 2; /* DIV */ 2342 1.1 reinoud fs = (fs * 10000) / (dev->sc_clkfreq << 1); /* Cycle, in ns */ 2343 1.1 reinoud 2344 1.1 reinoud ret = p << 2; /* in ns units */ 2345 1.1 reinoud ret = ret / fs; /* in Cycles */ 2346 1.1 reinoud if (ret < sbic_min_period) 2347 1.1 reinoud return sbic_min_period; 2348 1.1 reinoud 2349 1.1 reinoud /* verify rounding */ 2350 1.1 reinoud if (sbictoscsiperiod(dev, regs, ret) < p) 2351 1.1 reinoud ret++; 2352 1.1 reinoud return (ret >= 8) ? 0 : ret; 2353 1.1 reinoud } 2354 1.1 reinoud 2355 1.1 reinoud #ifdef DEBUG 2356 1.1 reinoud 2357 1.1 reinoud void 2358 1.14 cegger sbicdumpstate(void) 2359 1.1 reinoud { 2360 1.1 reinoud u_char csr, asr; 2361 1.1 reinoud 2362 1.1 reinoud GET_SBIC_asr(debug_sbic_regs,asr); 2363 1.1 reinoud GET_SBIC_csr(debug_sbic_regs,csr); 2364 1.1 reinoud printf("%s: asr:csr(%02x:%02x)->(%02x:%02x)\n", 2365 1.1 reinoud (routine == 1) ? "sbicgo" : 2366 1.1 reinoud (routine == 2) ? "sbicintr" : 2367 1.1 reinoud (routine == 3) ? "sbicicmd" : 2368 1.1 reinoud (routine == 4) ? "sbicnext" : "unknown", 2369 1.1 reinoud debug_asr, debug_csr, asr, csr); 2370 1.1 reinoud 2371 1.1 reinoud } 2372 1.1 reinoud 2373 1.1 reinoud void 2374 1.1 reinoud sbictimeout(struct sbic_softc *dev) 2375 1.1 reinoud { 2376 1.1 reinoud int s, asr; 2377 1.1 reinoud 2378 1.1 reinoud s = splbio(); 2379 1.1 reinoud if (dev->sc_dmatimo) { 2380 1.1 reinoud if (dev->sc_dmatimo > 1) { 2381 1.6 wiz printf("%s: DMA timeout #%d\n", 2382 1.17 chs device_xname(dev->sc_dev), dev->sc_dmatimo - 1); 2383 1.1 reinoud GET_SBIC_asr(&dev->sc_sbicp, asr); 2384 1.1 reinoud if (asr & SBIC_ASR_INT) { 2385 1.1 reinoud /* We need to service a missed IRQ */ 2386 1.8 matt printf("Servicing a missed int:(%02x,%02x)->(%02x,?)\n", 2387 1.1 reinoud debug_asr, debug_csr, asr); 2388 1.1 reinoud sbicintr(dev); 2389 1.1 reinoud } 2390 1.1 reinoud sbicdumpstate(); 2391 1.1 reinoud } 2392 1.1 reinoud dev->sc_dmatimo++; 2393 1.1 reinoud } 2394 1.1 reinoud splx(s); 2395 1.1 reinoud callout_reset(&dev->sc_timo_ch, 30 * hz, 2396 1.1 reinoud (void *)sbictimeout, dev); 2397 1.1 reinoud } 2398 1.1 reinoud 2399 1.1 reinoud void 2400 1.1 reinoud sbic_dump_acb(struct sbic_acb *acb) 2401 1.1 reinoud { 2402 1.1 reinoud u_char *b = (u_char *) &acb->cmd; 2403 1.1 reinoud int i; 2404 1.1 reinoud 2405 1.1 reinoud printf("acb@%p ", acb); 2406 1.1 reinoud if (acb->xs == NULL) { 2407 1.1 reinoud printf("<unused>\n"); 2408 1.1 reinoud return; 2409 1.1 reinoud } 2410 1.1 reinoud printf("(%d:%d) flags %2x clen %2d cmd ", 2411 1.1 reinoud acb->xs->xs_periph->periph_target, 2412 1.1 reinoud acb->xs->xs_periph->periph_lun, acb->flags, acb->clen); 2413 1.1 reinoud for (i = acb->clen; i; --i) 2414 1.1 reinoud printf(" %02x", *b++); 2415 1.1 reinoud printf("\n"); 2416 1.1 reinoud printf(" xs: %8p data %8p:%04x ", acb->xs, acb->xs->data, 2417 1.1 reinoud acb->xs->datalen); 2418 1.1 reinoud printf("tcnt %lx\n", acb->sc_tcnt); 2419 1.1 reinoud } 2420 1.1 reinoud 2421 1.1 reinoud void 2422 1.1 reinoud sbic_dump(struct sbic_softc *dev) 2423 1.1 reinoud { 2424 1.1 reinoud sbic_regmap_p regs; 2425 1.1 reinoud u_char csr, asr; 2426 1.1 reinoud struct sbic_acb *acb; 2427 1.1 reinoud int s; 2428 1.1 reinoud int i; 2429 1.1 reinoud 2430 1.1 reinoud s = splbio(); 2431 1.1 reinoud regs = &dev->sc_sbicp; 2432 1.1 reinoud #if CSR_TRACE_SIZE 2433 1.1 reinoud printf("csr trace: "); 2434 1.1 reinoud i = csr_traceptr; 2435 1.1 reinoud do { 2436 1.1 reinoud printf("%c%02x%02x%02x ", csr_trace[i].whr, 2437 1.1 reinoud csr_trace[i].csr, csr_trace[i].asr, csr_trace[i].xtn); 2438 1.1 reinoud switch(csr_trace[i].whr) { 2439 1.1 reinoud case 'g': 2440 1.1 reinoud printf("go "); break; 2441 1.1 reinoud case 's': 2442 1.1 reinoud printf("select "); break; 2443 1.1 reinoud case 'y': 2444 1.1 reinoud printf("select+ "); break; 2445 1.1 reinoud case 'i': 2446 1.1 reinoud printf("intr "); break; 2447 1.1 reinoud case 'f': 2448 1.1 reinoud printf("finish "); break; 2449 1.1 reinoud case '>': 2450 1.1 reinoud printf("out "); break; 2451 1.1 reinoud case '<': 2452 1.1 reinoud printf("in "); break; 2453 1.1 reinoud case 'm': 2454 1.1 reinoud printf("msgin "); break; 2455 1.1 reinoud case 'x': 2456 1.1 reinoud printf("msginx "); break; 2457 1.1 reinoud case 'X': 2458 1.1 reinoud printf("msginX "); break; 2459 1.1 reinoud case 'r': 2460 1.1 reinoud printf("reselect "); break; 2461 1.1 reinoud case 'I': 2462 1.1 reinoud printf("icmd "); break; 2463 1.1 reinoud case 'a': 2464 1.1 reinoud printf("abort "); break; 2465 1.1 reinoud default: 2466 1.1 reinoud printf("? "); 2467 1.1 reinoud } 2468 1.1 reinoud switch(csr_trace[i].csr) { 2469 1.1 reinoud case 0x11: 2470 1.1 reinoud printf("INITIATOR"); break; 2471 1.1 reinoud case 0x16: 2472 1.1 reinoud printf("S_XFERRED"); break; 2473 1.1 reinoud case 0x20: 2474 1.1 reinoud printf("MSGIN_ACK"); break; 2475 1.1 reinoud case 0x41: 2476 1.1 reinoud printf("DISC"); break; 2477 1.1 reinoud case 0x42: 2478 1.1 reinoud printf("SEL_TIMEO"); break; 2479 1.1 reinoud case 0x80: 2480 1.1 reinoud printf("RSLT_NI"); break; 2481 1.1 reinoud case 0x81: 2482 1.1 reinoud printf("RSLT_IFY"); break; 2483 1.1 reinoud case 0x85: 2484 1.1 reinoud printf("DISC_1"); break; 2485 1.1 reinoud case 0x18: case 0x19: case 0x1a: 2486 1.1 reinoud case 0x1b: case 0x1e: case 0x1f: 2487 1.1 reinoud case 0x28: case 0x29: case 0x2a: 2488 1.1 reinoud case 0x2b: case 0x2e: case 0x2f: 2489 1.1 reinoud case 0x48: case 0x49: case 0x4a: 2490 1.1 reinoud case 0x4b: case 0x4e: case 0x4f: 2491 1.1 reinoud case 0x88: case 0x89: case 0x8a: 2492 1.1 reinoud case 0x8b: case 0x8e: case 0x8f: 2493 1.1 reinoud switch(csr_trace[i].csr & 0xf0) { 2494 1.1 reinoud case 0x10: 2495 1.1 reinoud printf("DONE_"); break; 2496 1.1 reinoud case 0x20: 2497 1.1 reinoud printf("STOP_"); break; 2498 1.1 reinoud case 0x40: 2499 1.1 reinoud printf("ERR_"); break; 2500 1.1 reinoud case 0x80: 2501 1.1 reinoud printf("REQ_"); break; 2502 1.1 reinoud } 2503 1.1 reinoud switch(csr_trace[i].csr & 7) { 2504 1.1 reinoud case 0: 2505 1.1 reinoud printf("DATA_OUT"); break; 2506 1.1 reinoud case 1: 2507 1.1 reinoud printf("DATA_IN"); break; 2508 1.1 reinoud case 2: 2509 1.1 reinoud printf("CMD"); break; 2510 1.1 reinoud case 3: 2511 1.1 reinoud printf("STATUS"); break; 2512 1.1 reinoud case 6: 2513 1.1 reinoud printf("MSG_OUT"); break; 2514 1.1 reinoud case 7: 2515 1.1 reinoud printf("MSG_IN"); break; 2516 1.1 reinoud default: 2517 1.1 reinoud printf("invld phs"); 2518 1.1 reinoud } 2519 1.1 reinoud break; 2520 1.1 reinoud default: printf("****"); break; 2521 1.1 reinoud } 2522 1.1 reinoud if (csr_trace[i].asr & SBIC_ASR_INT) 2523 1.1 reinoud printf(" ASR_INT"); 2524 1.1 reinoud if (csr_trace[i].asr & SBIC_ASR_LCI) 2525 1.1 reinoud printf(" ASR_LCI"); 2526 1.1 reinoud if (csr_trace[i].asr & SBIC_ASR_BSY) 2527 1.1 reinoud printf(" ASR_BSY"); 2528 1.1 reinoud if (csr_trace[i].asr & SBIC_ASR_CIP) 2529 1.1 reinoud printf(" ASR_CIP"); 2530 1.1 reinoud printf("\n"); 2531 1.1 reinoud i = (i + 1) & (CSR_TRACE_SIZE - 1); 2532 1.1 reinoud } while (i != csr_traceptr); 2533 1.1 reinoud #endif 2534 1.1 reinoud GET_SBIC_asr(regs, asr); 2535 1.1 reinoud if ((asr & SBIC_ASR_INT) == 0) 2536 1.1 reinoud GET_SBIC_csr(regs, csr); 2537 1.1 reinoud else 2538 1.1 reinoud csr = 0; 2539 1.17 chs printf("%s@%p regs %p asr %x csr %x\n", device_xname(dev->sc_dev), 2540 1.1 reinoud dev, regs, asr, csr); 2541 1.1 reinoud if ((acb = dev->free_list.tqh_first)) { 2542 1.1 reinoud printf("Free list:\n"); 2543 1.1 reinoud while (acb) { 2544 1.1 reinoud sbic_dump_acb(acb); 2545 1.1 reinoud acb = acb->chain.tqe_next; 2546 1.1 reinoud } 2547 1.1 reinoud } 2548 1.1 reinoud if ((acb = dev->ready_list.tqh_first)) { 2549 1.1 reinoud printf("Ready list:\n"); 2550 1.1 reinoud while (acb) { 2551 1.1 reinoud sbic_dump_acb(acb); 2552 1.1 reinoud acb = acb->chain.tqe_next; 2553 1.1 reinoud } 2554 1.1 reinoud } 2555 1.1 reinoud if ((acb = dev->nexus_list.tqh_first)) { 2556 1.1 reinoud printf("Nexus list:\n"); 2557 1.1 reinoud while (acb) { 2558 1.1 reinoud sbic_dump_acb(acb); 2559 1.1 reinoud acb = acb->chain.tqe_next; 2560 1.1 reinoud } 2561 1.1 reinoud } 2562 1.1 reinoud if (dev->sc_nexus) { 2563 1.1 reinoud printf("nexus:\n"); 2564 1.1 reinoud sbic_dump_acb(dev->sc_nexus); 2565 1.1 reinoud } 2566 1.1 reinoud printf("targ %d lun %d flags %x\n", 2567 1.1 reinoud dev->target, dev->lun, dev->sc_flags); 2568 1.1 reinoud for (i = 0; i < 8; ++i) { 2569 1.1 reinoud if (dev->sc_tinfo[i].cmds > 2) { 2570 1.1 reinoud printf("tgt %d: cmds %d disc %d lubusy %x\n", 2571 1.1 reinoud i, dev->sc_tinfo[i].cmds, 2572 1.1 reinoud dev->sc_tinfo[i].dconns, 2573 1.1 reinoud dev->sc_tinfo[i].lubusy); 2574 1.1 reinoud } 2575 1.1 reinoud } 2576 1.1 reinoud splx(s); 2577 1.1 reinoud } 2578 1.1 reinoud 2579 1.1 reinoud #endif 2580