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