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