1 /* $NetBSD: bha.c,v 1.12 1997/04/11 01:34:25 thorpej Exp $ */ 2 3 #undef BHADIAG 4 #ifdef DDB 5 #define integrate 6 #else 7 #define integrate static inline 8 #endif 9 10 /* 11 * Copyright (c) 1994, 1996, 1997 Charles M. Hannum. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgement: 23 * This product includes software developed by Charles M. Hannum. 24 * 4. The name of the author may not be used to endorse or promote products 25 * derived from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Originally written by Julian Elischer (julian@tfs.com) 41 * for TRW Financial Systems for use under the MACH(2.5) operating system. 42 * 43 * TRW Financial Systems, in accordance with their agreement with Carnegie 44 * Mellon University, makes this software available to CMU to distribute 45 * or use in any manner that they see fit as long as this message is kept with 46 * the software. For this reason TFS also grants any other persons or 47 * organisations permission to use or modify this software. 48 * 49 * TFS supplies this software to be publicly redistributed 50 * on the understanding that TFS is not responsible for the correct 51 * functioning of this software in any circumstances. 52 */ 53 54 #include <sys/types.h> 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/kernel.h> 58 #include <sys/errno.h> 59 #include <sys/ioctl.h> 60 #include <sys/device.h> 61 #include <sys/malloc.h> 62 #include <sys/buf.h> 63 #include <sys/proc.h> 64 #include <sys/user.h> 65 66 #include <machine/bus.h> 67 #include <machine/intr.h> 68 69 #include <scsi/scsi_all.h> 70 #include <scsi/scsiconf.h> 71 72 #include <dev/ic/bhareg.h> 73 #include <dev/ic/bhavar.h> 74 75 #ifndef DDB 76 #define Debugger() panic("should call debugger here (bha.c)") 77 #endif /* ! DDB */ 78 79 #ifdef alpha /* XXX */ 80 /* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ 81 extern vm_offset_t alpha_XXX_dmamap(vm_offset_t); 82 #undef vtophys 83 #define vtophys(va) alpha_XXX_dmamap((vm_offset_t) va) 84 #endif /* alpha */ 85 86 #define KVTOPHYS(x) vtophys(x) 87 88 #ifdef BHADEBUG 89 int bha_debug = 0; 90 #endif /* BHADEBUG */ 91 92 int bha_cmd __P((bus_space_tag_t, bus_space_handle_t, struct bha_softc *, 93 int, u_char *, int, u_char *)); 94 integrate void bha_finish_ccbs __P((struct bha_softc *)); 95 integrate void bha_reset_ccb __P((struct bha_softc *, struct bha_ccb *)); 96 void bha_free_ccb __P((struct bha_softc *, struct bha_ccb *)); 97 integrate void bha_init_ccb __P((struct bha_softc *, struct bha_ccb *)); 98 struct bha_ccb *bha_get_ccb __P((struct bha_softc *, int)); 99 struct bha_ccb *bha_ccb_phys_kv __P((struct bha_softc *, u_long)); 100 void bha_queue_ccb __P((struct bha_softc *, struct bha_ccb *)); 101 void bha_collect_mbo __P((struct bha_softc *)); 102 void bha_start_ccbs __P((struct bha_softc *)); 103 void bha_done __P((struct bha_softc *, struct bha_ccb *)); 104 void bha_init __P((struct bha_softc *)); 105 void bha_inquire_setup_information __P((struct bha_softc *)); 106 void bhaminphys __P((struct buf *)); 107 int bha_scsi_cmd __P((struct scsi_xfer *)); 108 int bha_poll __P((struct bha_softc *, struct scsi_xfer *, int)); 109 void bha_timeout __P((void *arg)); 110 111 struct scsi_adapter bha_switch = { 112 bha_scsi_cmd, 113 bhaminphys, 114 0, 115 0, 116 }; 117 118 /* the below structure is so we have a default dev struct for out link struct */ 119 struct scsi_device bha_dev = { 120 NULL, /* Use default error handler */ 121 NULL, /* have a queue, served by this */ 122 NULL, /* have no async handler */ 123 NULL, /* Use default 'done' routine */ 124 }; 125 126 struct cfdriver bha_cd = { 127 NULL, "bha", DV_DULL 128 }; 129 130 #define BHA_RESET_TIMEOUT 2000 /* time to wait for reset (mSec) */ 131 #define BHA_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */ 132 133 /* 134 * bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf) 135 * 136 * Activate Adapter command 137 * icnt: number of args (outbound bytes including opcode) 138 * ibuf: argument buffer 139 * ocnt: number of expected returned bytes 140 * obuf: result buffer 141 * wait: number of seconds to wait for response 142 * 143 * Performs an adapter command through the ports. Not to be confused with a 144 * scsi command, which is read in via the dma; one of the adapter commands 145 * tells it to read in a scsi command. 146 */ 147 int 148 bha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf) 149 bus_space_tag_t iot; 150 bus_space_handle_t ioh; 151 struct bha_softc *sc; 152 int icnt, ocnt; 153 u_char *ibuf, *obuf; 154 { 155 const char *name; 156 register int i; 157 int wait; 158 u_char sts; 159 u_char opcode = ibuf[0]; 160 161 if (sc != NULL) 162 name = sc->sc_dev.dv_xname; 163 else 164 name = "(bha probe)"; 165 166 /* 167 * Calculate a reasonable timeout for the command. 168 */ 169 switch (opcode) { 170 case BHA_INQUIRE_DEVICES: 171 case BHA_INQUIRE_DEVICES_2: 172 wait = 90 * 20000; 173 break; 174 default: 175 wait = 1 * 20000; 176 break; 177 } 178 179 /* 180 * Wait for the adapter to go idle, unless it's one of 181 * the commands which don't need this 182 */ 183 if (opcode != BHA_MBO_INTR_EN) { 184 for (i = 20000; i; i--) { /* 1 sec? */ 185 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT); 186 if (sts & BHA_STAT_IDLE) 187 break; 188 delay(50); 189 } 190 if (!i) { 191 printf("%s: bha_cmd, host not idle(0x%x)\n", 192 name, sts); 193 return (1); 194 } 195 } 196 /* 197 * Now that it is idle, if we expect output, preflush the 198 * queue feeding to us. 199 */ 200 if (ocnt) { 201 while ((bus_space_read_1(iot, ioh, BHA_STAT_PORT)) & 202 BHA_STAT_DF) 203 bus_space_read_1(iot, ioh, BHA_DATA_PORT); 204 } 205 /* 206 * Output the command and the number of arguments given 207 * for each byte, first check the port is empty. 208 */ 209 while (icnt--) { 210 for (i = wait; i; i--) { 211 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT); 212 if (!(sts & BHA_STAT_CDF)) 213 break; 214 delay(50); 215 } 216 if (!i) { 217 if (opcode != BHA_INQUIRE_REVISION) 218 printf("%s: bha_cmd, cmd/data port full\n", 219 name); 220 goto bad; 221 } 222 bus_space_write_1(iot, ioh, BHA_CMD_PORT, *ibuf++); 223 } 224 /* 225 * If we expect input, loop that many times, each time, 226 * looking for the data register to have valid data 227 */ 228 while (ocnt--) { 229 for (i = wait; i; i--) { 230 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT); 231 if (sts & BHA_STAT_DF) 232 break; 233 delay(50); 234 } 235 if (!i) { 236 if (opcode != BHA_INQUIRE_REVISION) 237 printf("%s: bha_cmd, cmd/data port empty %d\n", 238 name, ocnt); 239 goto bad; 240 } 241 *obuf++ = bus_space_read_1(iot, ioh, BHA_DATA_PORT); 242 } 243 /* 244 * Wait for the board to report a finished instruction. 245 * We may get an extra interrupt for the HACC signal, but this is 246 * unimportant. 247 */ 248 if (opcode != BHA_MBO_INTR_EN && opcode != BHA_MODIFY_IOPORT) { 249 for (i = 20000; i; i--) { /* 1 sec? */ 250 sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT); 251 /* XXX Need to save this in the interrupt handler? */ 252 if (sts & BHA_INTR_HACC) 253 break; 254 delay(50); 255 } 256 if (!i) { 257 printf("%s: bha_cmd, host not finished(0x%x)\n", 258 name, sts); 259 return (1); 260 } 261 } 262 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST); 263 return (0); 264 265 bad: 266 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_SRST); 267 return (1); 268 } 269 270 /* 271 * Attach all the sub-devices we can find 272 */ 273 void 274 bha_attach(sc, bpd) 275 struct bha_softc *sc; 276 struct bha_probe_data *bpd; 277 { 278 279 /* 280 * fill in the prototype scsi_link. 281 */ 282 sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE; 283 sc->sc_link.adapter_softc = sc; 284 sc->sc_link.adapter_target = bpd->sc_scsi_dev; 285 sc->sc_link.adapter = &bha_switch; 286 sc->sc_link.device = &bha_dev; 287 sc->sc_link.openings = 4; 288 sc->sc_link.max_target = bpd->sc_iswide ? 15 : 7; 289 290 bha_inquire_setup_information(sc); 291 bha_init(sc); 292 TAILQ_INIT(&sc->sc_free_ccb); 293 TAILQ_INIT(&sc->sc_waiting_ccb); 294 295 /* 296 * ask the adapter what subunits are present 297 */ 298 config_found(&sc->sc_dev, &sc->sc_link, scsiprint); 299 } 300 301 integrate void 302 bha_finish_ccbs(sc) 303 struct bha_softc *sc; 304 { 305 struct bha_mbx_in *wmbi; 306 struct bha_ccb *ccb; 307 int i; 308 309 wmbi = wmbx->tmbi; 310 311 if (wmbi->stat == BHA_MBI_FREE) { 312 for (i = 0; i < BHA_MBX_SIZE; i++) { 313 if (wmbi->stat != BHA_MBI_FREE) { 314 printf("%s: mbi not in round-robin order\n", 315 sc->sc_dev.dv_xname); 316 goto AGAIN; 317 } 318 bha_nextmbx(wmbi, wmbx, mbi); 319 } 320 #ifdef BHADIAGnot 321 printf("%s: mbi interrupt with no full mailboxes\n", 322 sc->sc_dev.dv_xname); 323 #endif 324 return; 325 } 326 327 AGAIN: 328 do { 329 ccb = bha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr)); 330 if (!ccb) { 331 printf("%s: bad mbi ccb pointer; skipping\n", 332 sc->sc_dev.dv_xname); 333 goto next; 334 } 335 336 #ifdef BHADEBUG 337 if (bha_debug) { 338 u_char *cp = &ccb->scsi_cmd; 339 printf("op=%x %x %x %x %x %x\n", 340 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); 341 printf("stat %x for mbi addr = 0x%08x, ", 342 wmbi->stat, wmbi); 343 printf("ccb addr = 0x%x\n", ccb); 344 } 345 #endif /* BHADEBUG */ 346 347 switch (wmbi->stat) { 348 case BHA_MBI_OK: 349 case BHA_MBI_ERROR: 350 if ((ccb->flags & CCB_ABORT) != 0) { 351 /* 352 * If we already started an abort, wait for it 353 * to complete before clearing the CCB. We 354 * could instead just clear CCB_SENDING, but 355 * what if the mailbox was already received? 356 * The worst that happens here is that we clear 357 * the CCB a bit later than we need to. BFD. 358 */ 359 goto next; 360 } 361 break; 362 363 case BHA_MBI_ABORT: 364 case BHA_MBI_UNKNOWN: 365 /* 366 * Even if the CCB wasn't found, we clear it anyway. 367 * See preceeding comment. 368 */ 369 break; 370 371 default: 372 printf("%s: bad mbi status %02x; skipping\n", 373 sc->sc_dev.dv_xname, wmbi->stat); 374 goto next; 375 } 376 377 untimeout(bha_timeout, ccb); 378 bha_done(sc, ccb); 379 380 next: 381 wmbi->stat = BHA_MBI_FREE; 382 bha_nextmbx(wmbi, wmbx, mbi); 383 } while (wmbi->stat != BHA_MBI_FREE); 384 385 wmbx->tmbi = wmbi; 386 } 387 388 /* 389 * Catch an interrupt from the adaptor 390 */ 391 int 392 bha_intr(arg) 393 void *arg; 394 { 395 struct bha_softc *sc = arg; 396 bus_space_tag_t iot = sc->sc_iot; 397 bus_space_handle_t ioh = sc->sc_ioh; 398 u_char sts; 399 400 #ifdef BHADEBUG 401 printf("%s: bha_intr ", sc->sc_dev.dv_xname); 402 #endif /* BHADEBUG */ 403 404 /* 405 * First acknowlege the interrupt, Then if it's not telling about 406 * a completed operation just return. 407 */ 408 sts = bus_space_read_1(iot, ioh, BHA_INTR_PORT); 409 if ((sts & BHA_INTR_ANYINTR) == 0) 410 return (0); 411 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, BHA_CTRL_IRST); 412 413 #ifdef BHADIAG 414 /* Make sure we clear CCB_SENDING before finishing a CCB. */ 415 bha_collect_mbo(sc); 416 #endif 417 418 /* Mail box out empty? */ 419 if (sts & BHA_INTR_MBOA) { 420 struct bha_toggle toggle; 421 422 toggle.cmd.opcode = BHA_MBO_INTR_EN; 423 toggle.cmd.enable = 0; 424 bha_cmd(iot, ioh, sc, 425 sizeof(toggle.cmd), (u_char *)&toggle.cmd, 426 0, (u_char *)0); 427 bha_start_ccbs(sc); 428 } 429 430 /* Mail box in full? */ 431 if (sts & BHA_INTR_MBIF) 432 bha_finish_ccbs(sc); 433 434 return (1); 435 } 436 437 integrate void 438 bha_reset_ccb(sc, ccb) 439 struct bha_softc *sc; 440 struct bha_ccb *ccb; 441 { 442 443 ccb->flags = 0; 444 } 445 446 /* 447 * A ccb is put onto the free list. 448 */ 449 void 450 bha_free_ccb(sc, ccb) 451 struct bha_softc *sc; 452 struct bha_ccb *ccb; 453 { 454 int s; 455 456 s = splbio(); 457 458 bha_reset_ccb(sc, ccb); 459 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); 460 461 /* 462 * If there were none, wake anybody waiting for one to come free, 463 * starting with queued entries. 464 */ 465 if (ccb->chain.tqe_next == 0) 466 wakeup(&sc->sc_free_ccb); 467 468 splx(s); 469 } 470 471 integrate void 472 bha_init_ccb(sc, ccb) 473 struct bha_softc *sc; 474 struct bha_ccb *ccb; 475 { 476 int hashnum; 477 478 bzero(ccb, sizeof(struct bha_ccb)); 479 /* 480 * put in the phystokv hash table 481 * Never gets taken out. 482 */ 483 ccb->hashkey = KVTOPHYS(ccb); 484 hashnum = CCB_HASH(ccb->hashkey); 485 ccb->nexthash = sc->sc_ccbhash[hashnum]; 486 sc->sc_ccbhash[hashnum] = ccb; 487 bha_reset_ccb(sc, ccb); 488 } 489 490 /* 491 * Get a free ccb 492 * 493 * If there are none, see if we can allocate a new one. If so, put it in 494 * the hash table too otherwise either return an error or sleep. 495 */ 496 struct bha_ccb * 497 bha_get_ccb(sc, flags) 498 struct bha_softc *sc; 499 int flags; 500 { 501 struct bha_ccb *ccb; 502 int s; 503 504 s = splbio(); 505 506 /* 507 * If we can and have to, sleep waiting for one to come free 508 * but only if we can't allocate a new one. 509 */ 510 for (;;) { 511 ccb = sc->sc_free_ccb.tqh_first; 512 if (ccb) { 513 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain); 514 break; 515 } 516 if (sc->sc_numccbs < BHA_CCB_MAX) { 517 ccb = (struct bha_ccb *) malloc(sizeof(struct bha_ccb), 518 M_TEMP, M_NOWAIT); 519 if (!ccb) { 520 printf("%s: can't malloc ccb\n", 521 sc->sc_dev.dv_xname); 522 goto out; 523 } 524 bha_init_ccb(sc, ccb); 525 sc->sc_numccbs++; 526 break; 527 } 528 if ((flags & SCSI_NOSLEEP) != 0) 529 goto out; 530 tsleep(&sc->sc_free_ccb, PRIBIO, "bhaccb", 0); 531 } 532 533 ccb->flags |= CCB_ALLOC; 534 535 out: 536 splx(s); 537 return (ccb); 538 } 539 540 /* 541 * Given a physical address, find the ccb that it corresponds to. 542 */ 543 struct bha_ccb * 544 bha_ccb_phys_kv(sc, ccb_phys) 545 struct bha_softc *sc; 546 u_long ccb_phys; 547 { 548 int hashnum = CCB_HASH(ccb_phys); 549 struct bha_ccb *ccb = sc->sc_ccbhash[hashnum]; 550 551 while (ccb) { 552 if (ccb->hashkey == ccb_phys) 553 break; 554 ccb = ccb->nexthash; 555 } 556 return (ccb); 557 } 558 559 /* 560 * Queue a CCB to be sent to the controller, and send it if possible. 561 */ 562 void 563 bha_queue_ccb(sc, ccb) 564 struct bha_softc *sc; 565 struct bha_ccb *ccb; 566 { 567 568 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain); 569 bha_start_ccbs(sc); 570 } 571 572 /* 573 * Garbage collect mailboxes that are no longer in use. 574 */ 575 void 576 bha_collect_mbo(sc) 577 struct bha_softc *sc; 578 { 579 struct bha_mbx_out *wmbo; /* Mail Box Out pointer */ 580 #ifdef BHADIAG 581 struct bha_ccb *ccb; 582 #endif 583 584 wmbo = wmbx->cmbo; 585 586 while (sc->sc_mbofull > 0) { 587 if (wmbo->cmd != BHA_MBO_FREE) 588 break; 589 590 #ifdef BHADIAG 591 ccb = bha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr)); 592 ccb->flags &= ~CCB_SENDING; 593 #endif 594 595 --sc->sc_mbofull; 596 bha_nextmbx(wmbo, wmbx, mbo); 597 } 598 599 wmbx->cmbo = wmbo; 600 } 601 602 /* 603 * Send as many CCBs as we have empty mailboxes for. 604 */ 605 void 606 bha_start_ccbs(sc) 607 struct bha_softc *sc; 608 { 609 bus_space_tag_t iot = sc->sc_iot; 610 bus_space_handle_t ioh = sc->sc_ioh; 611 struct bha_mbx_out *wmbo; /* Mail Box Out pointer */ 612 struct bha_ccb *ccb; 613 614 wmbo = wmbx->tmbo; 615 616 while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) { 617 if (sc->sc_mbofull >= BHA_MBX_SIZE) { 618 bha_collect_mbo(sc); 619 if (sc->sc_mbofull >= BHA_MBX_SIZE) { 620 struct bha_toggle toggle; 621 622 toggle.cmd.opcode = BHA_MBO_INTR_EN; 623 toggle.cmd.enable = 1; 624 bha_cmd(iot, ioh, sc, 625 sizeof(toggle.cmd), (u_char *)&toggle.cmd, 626 0, (u_char *)0); 627 break; 628 } 629 } 630 631 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain); 632 #ifdef BHADIAG 633 ccb->flags |= CCB_SENDING; 634 #endif 635 636 /* Link ccb to mbo. */ 637 ltophys(KVTOPHYS(ccb), wmbo->ccb_addr); 638 if (ccb->flags & CCB_ABORT) 639 wmbo->cmd = BHA_MBO_ABORT; 640 else 641 wmbo->cmd = BHA_MBO_START; 642 643 /* Tell the card to poll immediately. */ 644 bus_space_write_1(iot, ioh, BHA_CMD_PORT, BHA_START_SCSI); 645 646 if ((ccb->xs->flags & SCSI_POLL) == 0) 647 timeout(bha_timeout, ccb, (ccb->timeout * hz) / 1000); 648 649 ++sc->sc_mbofull; 650 bha_nextmbx(wmbo, wmbx, mbo); 651 } 652 653 wmbx->tmbo = wmbo; 654 } 655 656 /* 657 * We have a ccb which has been processed by the 658 * adaptor, now we look to see how the operation 659 * went. Wake up the owner if waiting 660 */ 661 void 662 bha_done(sc, ccb) 663 struct bha_softc *sc; 664 struct bha_ccb *ccb; 665 { 666 struct scsi_sense_data *s1, *s2; 667 struct scsi_xfer *xs = ccb->xs; 668 669 SC_DEBUG(xs->sc_link, SDEV_DB2, ("bha_done\n")); 670 /* 671 * Otherwise, put the results of the operation 672 * into the xfer and call whoever started it 673 */ 674 #ifdef BHADIAG 675 if (ccb->flags & CCB_SENDING) { 676 printf("%s: exiting ccb still in transit!\n", 677 sc->sc_dev.dv_xname); 678 Debugger(); 679 return; 680 } 681 #endif 682 if ((ccb->flags & CCB_ALLOC) == 0) { 683 printf("%s: exiting ccb not allocated!\n", 684 sc->sc_dev.dv_xname); 685 Debugger(); 686 return; 687 } 688 if (xs->error == XS_NOERROR) { 689 if (ccb->host_stat != BHA_OK) { 690 switch (ccb->host_stat) { 691 case BHA_SEL_TIMEOUT: /* No response */ 692 xs->error = XS_SELTIMEOUT; 693 break; 694 default: /* Other scsi protocol messes */ 695 printf("%s: host_stat %x\n", 696 sc->sc_dev.dv_xname, ccb->host_stat); 697 xs->error = XS_DRIVER_STUFFUP; 698 break; 699 } 700 } else if (ccb->target_stat != SCSI_OK) { 701 switch (ccb->target_stat) { 702 case SCSI_CHECK: 703 s1 = &ccb->scsi_sense; 704 s2 = &xs->sense; 705 *s2 = *s1; 706 xs->error = XS_SENSE; 707 break; 708 case SCSI_BUSY: 709 xs->error = XS_BUSY; 710 break; 711 default: 712 printf("%s: target_stat %x\n", 713 sc->sc_dev.dv_xname, ccb->target_stat); 714 xs->error = XS_DRIVER_STUFFUP; 715 break; 716 } 717 } else 718 xs->resid = 0; 719 } 720 bha_free_ccb(sc, ccb); 721 xs->flags |= ITSDONE; 722 scsi_done(xs); 723 } 724 725 /* 726 * Find the board and find it's irq/drq 727 */ 728 int 729 bha_find(iot, ioh, sc) 730 bus_space_tag_t iot; 731 bus_space_handle_t ioh; 732 struct bha_probe_data *sc; 733 { 734 int i, iswide; 735 u_char sts; 736 struct bha_extended_inquire inquire; 737 struct bha_config config; 738 int irq, drq; 739 740 /* Check something is at the ports we need to access */ 741 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT); 742 if (sts == 0xFF) 743 return (0); 744 745 /* 746 * Reset board, If it doesn't respond, assume 747 * that it's not there.. good for the probe 748 */ 749 750 bus_space_write_1(iot, ioh, BHA_CTRL_PORT, 751 BHA_CTRL_HRST | BHA_CTRL_SRST); 752 753 delay(100); 754 for (i = BHA_RESET_TIMEOUT; i; i--) { 755 sts = bus_space_read_1(iot, ioh, BHA_STAT_PORT); 756 if (sts == (BHA_STAT_IDLE | BHA_STAT_INIT)) 757 break; 758 delay(1000); 759 } 760 if (!i) { 761 #ifdef BHADEBUG 762 if (bha_debug) 763 printf("bha_find: No answer from buslogic board\n"); 764 #endif /* BHADEBUG */ 765 return (0); 766 } 767 768 /* 769 * The BusLogic cards implement an Adaptec 1542 (aha)-compatible 770 * interface. The native bha interface is not compatible with 771 * an aha. 1542. We need to ensure that we never match an 772 * Adaptec 1542. We must also avoid sending Adaptec-compatible 773 * commands to a real bha, lest it go into 1542 emulation mode. 774 * (On an indirect bus like ISA, we should always probe for BusLogic 775 * interfaces before Adaptec interfaces). 776 */ 777 778 /* 779 * Make sure we don't match an AHA-1542A or AHA-1542B, by checking 780 * for an extended-geometry register. The 1542[AB] don't have one. 781 */ 782 sts = bus_space_read_1(iot, ioh, BHA_EXTGEOM_PORT); 783 if (sts == 0xFF) 784 return (0); 785 786 /* 787 * Check that we actually know how to use this board. 788 */ 789 delay(1000); 790 inquire.cmd.opcode = BHA_INQUIRE_EXTENDED; 791 inquire.cmd.len = sizeof(inquire.reply); 792 i = bha_cmd(iot, ioh, (struct bha_softc *)0, 793 sizeof(inquire.cmd), (u_char *)&inquire.cmd, 794 sizeof(inquire.reply), (u_char *)&inquire.reply); 795 796 /* 797 * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev) 798 * have the extended-geometry register and also respond to 799 * BHA_INQUIRE_EXTENDED. Make sure we never match such cards, 800 * by checking the size of the reply is what a BusLogic card returns. 801 */ 802 if (i) { 803 #ifdef BHADEBUG 804 printf("bha_find: board returned %d instead of %d to %s\n", 805 i, sizeof(inquire.reply), "INQUIRE_EXTENDED"); 806 #endif 807 return (0); 808 } 809 810 /* OK, we know we've found a buslogic adaptor. */ 811 812 switch (inquire.reply.bus_type) { 813 case BHA_BUS_TYPE_24BIT: 814 case BHA_BUS_TYPE_32BIT: 815 break; 816 case BHA_BUS_TYPE_MCA: 817 /* We don't grok MicroChannel (yet). */ 818 return (0); 819 default: 820 printf("bha_find: illegal bus type %c\n", 821 inquire.reply.bus_type); 822 return (0); 823 } 824 825 /* Note if we have a wide bus. */ 826 iswide = inquire.reply.scsi_flags & BHA_SCSI_WIDE; 827 828 /* 829 * Assume we have a board at this stage setup dma channel from 830 * jumpers and save int level 831 */ 832 delay(1000); 833 config.cmd.opcode = BHA_INQUIRE_CONFIG; 834 bha_cmd(iot, ioh, (struct bha_softc *)0, 835 sizeof(config.cmd), (u_char *)&config.cmd, 836 sizeof(config.reply), (u_char *)&config.reply); 837 switch (config.reply.chan) { 838 case EISADMA: 839 drq = -1; 840 break; 841 case CHAN0: 842 drq = 0; 843 break; 844 case CHAN5: 845 drq = 5; 846 break; 847 case CHAN6: 848 drq = 6; 849 break; 850 case CHAN7: 851 drq = 7; 852 break; 853 default: 854 printf("bha_find: illegal drq setting %x\n", 855 config.reply.chan); 856 return (0); 857 } 858 859 switch (config.reply.intr) { 860 case INT9: 861 irq = 9; 862 break; 863 case INT10: 864 irq = 10; 865 break; 866 case INT11: 867 irq = 11; 868 break; 869 case INT12: 870 irq = 12; 871 break; 872 case INT14: 873 irq = 14; 874 break; 875 case INT15: 876 irq = 15; 877 break; 878 default: 879 printf("bha_find: illegal irq setting %x\n", 880 config.reply.intr); 881 return (0); 882 } 883 884 /* if we want to fill in softc, do so now */ 885 if (sc != NULL) { 886 sc->sc_irq = irq; 887 sc->sc_drq = drq; 888 sc->sc_scsi_dev = config.reply.scsi_dev; 889 sc->sc_iswide = iswide; 890 } 891 892 return (1); 893 } 894 895 896 /* 897 * Disable the ISA-compatiblity ioports on PCI bha devices, 898 * to ensure they're not autoconfigured a second time as an ISA bha. 899 */ 900 int 901 bha_disable_isacompat(sc) 902 struct bha_softc *sc; 903 { 904 struct bha_isadisable isa_disable; 905 906 isa_disable.cmd.opcode = BHA_MODIFY_IOPORT; 907 isa_disable.cmd.modifier = BHA_IOMODIFY_DISABLE1; 908 bha_cmd(sc->sc_iot, sc->sc_ioh, sc, 909 sizeof(isa_disable.cmd), (u_char*)&isa_disable.cmd, 910 0, (u_char *)0); 911 return (0); 912 } 913 914 915 /* 916 * Start the board, ready for normal operation 917 */ 918 void 919 bha_init(sc) 920 struct bha_softc *sc; 921 { 922 bus_space_tag_t iot = sc->sc_iot; 923 bus_space_handle_t ioh = sc->sc_ioh; 924 struct bha_devices devices; 925 struct bha_setup setup; 926 struct bha_mailbox mailbox; 927 struct bha_period period; 928 int i, rlen; 929 930 /* Enable round-robin scheme - appeared at firmware rev. 3.31. */ 931 if (strcmp(sc->sc_firmware, "3.31") >= 0) { 932 struct bha_toggle toggle; 933 934 toggle.cmd.opcode = BHA_ROUND_ROBIN; 935 toggle.cmd.enable = 1; 936 bha_cmd(iot, ioh, sc, 937 sizeof(toggle.cmd), (u_char *)&toggle.cmd, 938 0, (u_char *)0); 939 } 940 941 /* 942 * Inquire installed devices (to force synchronous negotiation). 943 */ 944 945 /* 946 * Poll targets 0 - 7. 947 */ 948 devices.cmd.opcode = BHA_INQUIRE_DEVICES; 949 bha_cmd(iot, ioh, sc, 950 sizeof(devices.cmd), (u_char *)&devices.cmd, 951 sizeof(devices.reply), (u_char *)&devices.reply); 952 953 /* 954 * Poll targets 8 - 15 if we have a wide bus. 955 */ 956 if (ISWIDE(sc)) { 957 devices.cmd.opcode = BHA_INQUIRE_DEVICES_2; 958 bha_cmd(iot, ioh, sc, 959 sizeof(devices.cmd), (u_char *)&devices.cmd, 960 sizeof(devices.reply), (u_char *)&devices.reply); 961 } 962 963 /* Obtain setup information from. */ 964 rlen = sizeof(setup.reply) + 965 (ISWIDE(sc) ? sizeof(setup.reply_w) : 0); 966 setup.cmd.opcode = BHA_INQUIRE_SETUP; 967 setup.cmd.len = rlen; 968 bha_cmd(iot, ioh, sc, 969 sizeof(setup.cmd), (u_char *)&setup.cmd, 970 rlen, (u_char *)&setup.reply); 971 972 printf("%s: %s, %s\n", 973 sc->sc_dev.dv_xname, 974 setup.reply.sync_neg ? "sync" : "async", 975 setup.reply.parity ? "parity" : "no parity"); 976 977 for (i = 0; i < 8; i++) 978 period.reply.period[i] = setup.reply.sync[i].period * 5 + 20; 979 if (ISWIDE(sc)) { 980 for (i = 0; i < 8; i++) 981 period.reply_w.period[i] = 982 setup.reply_w.sync[i].period * 5 + 20; 983 } 984 985 if (sc->sc_firmware[0] >= '3') { 986 rlen = sizeof(period.reply) + 987 (ISWIDE(sc) ? sizeof(period.reply_w) : 0); 988 period.cmd.opcode = BHA_INQUIRE_PERIOD; 989 period.cmd.len = rlen; 990 bha_cmd(iot, ioh, sc, 991 sizeof(period.cmd), (u_char *)&period.cmd, 992 rlen, (u_char *)&period.reply); 993 } 994 995 for (i = 0; i < 8; i++) { 996 if (!setup.reply.sync[i].valid || 997 (!setup.reply.sync[i].offset && 998 !setup.reply.sync[i].period)) 999 continue; 1000 printf("%s targ %d: sync, offset %d, period %dnsec\n", 1001 sc->sc_dev.dv_xname, i, 1002 setup.reply.sync[i].offset, period.reply.period[i] * 10); 1003 } 1004 if (ISWIDE(sc)) { 1005 for (i = 0; i < 8; i++) { 1006 if (!setup.reply_w.sync[i].valid || 1007 (!setup.reply_w.sync[i].offset && 1008 !setup.reply_w.sync[i].period)) 1009 continue; 1010 printf("%s targ %d: sync, offset %d, period %dnsec\n", 1011 sc->sc_dev.dv_xname, i + 8, 1012 setup.reply_w.sync[i].offset, 1013 period.reply_w.period[i] * 10); 1014 } 1015 } 1016 1017 /* 1018 * Set up initial mail box for round-robin operation. 1019 */ 1020 for (i = 0; i < BHA_MBX_SIZE; i++) { 1021 wmbx->mbo[i].cmd = BHA_MBO_FREE; 1022 wmbx->mbi[i].stat = BHA_MBI_FREE; 1023 } 1024 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0]; 1025 wmbx->tmbi = &wmbx->mbi[0]; 1026 sc->sc_mbofull = 0; 1027 1028 /* Initialize mail box. */ 1029 mailbox.cmd.opcode = BHA_MBX_INIT_EXTENDED; 1030 mailbox.cmd.nmbx = BHA_MBX_SIZE; 1031 ltophys(KVTOPHYS(wmbx), mailbox.cmd.addr); 1032 bha_cmd(iot, ioh, sc, 1033 sizeof(mailbox.cmd), (u_char *)&mailbox.cmd, 1034 0, (u_char *)0); 1035 } 1036 1037 void 1038 bha_inquire_setup_information(sc) 1039 struct bha_softc *sc; 1040 { 1041 bus_space_tag_t iot = sc->sc_iot; 1042 bus_space_handle_t ioh = sc->sc_ioh; 1043 struct bha_model model; 1044 struct bha_revision revision; 1045 struct bha_digit digit; 1046 char *p; 1047 1048 /* 1049 * Get the firmware revision. 1050 */ 1051 p = sc->sc_firmware; 1052 revision.cmd.opcode = BHA_INQUIRE_REVISION; 1053 bha_cmd(iot, ioh, sc, 1054 sizeof(revision.cmd), (u_char *)&revision.cmd, 1055 sizeof(revision.reply), (u_char *)&revision.reply); 1056 *p++ = revision.reply.firm_revision; 1057 *p++ = '.'; 1058 *p++ = revision.reply.firm_version; 1059 digit.cmd.opcode = BHA_INQUIRE_REVISION_3; 1060 bha_cmd(iot, ioh, sc, 1061 sizeof(digit.cmd), (u_char *)&digit.cmd, 1062 sizeof(digit.reply), (u_char *)&digit.reply); 1063 *p++ = digit.reply.digit; 1064 if (revision.reply.firm_revision >= '3' || 1065 (revision.reply.firm_revision == '3' && 1066 revision.reply.firm_version >= '3')) { 1067 digit.cmd.opcode = BHA_INQUIRE_REVISION_4; 1068 bha_cmd(iot, ioh, sc, 1069 sizeof(digit.cmd), (u_char *)&digit.cmd, 1070 sizeof(digit.reply), (u_char *)&digit.reply); 1071 *p++ = digit.reply.digit; 1072 } 1073 while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0')) 1074 p--; 1075 *p = '\0'; 1076 1077 /* 1078 * Get the model number. 1079 */ 1080 if (revision.reply.firm_revision >= '3') { 1081 p = sc->sc_model; 1082 model.cmd.opcode = BHA_INQUIRE_MODEL; 1083 model.cmd.len = sizeof(model.reply); 1084 bha_cmd(iot, ioh, sc, 1085 sizeof(model.cmd), (u_char *)&model.cmd, 1086 sizeof(model.reply), (u_char *)&model.reply); 1087 *p++ = model.reply.id[0]; 1088 *p++ = model.reply.id[1]; 1089 *p++ = model.reply.id[2]; 1090 *p++ = model.reply.id[3]; 1091 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0')) 1092 p--; 1093 *p++ = model.reply.version[0]; 1094 *p++ = model.reply.version[1]; 1095 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0')) 1096 p--; 1097 *p = '\0'; 1098 } else 1099 strcpy(sc->sc_model, "542B"); 1100 1101 printf("%s: model BT-%s, firmware %s\n", sc->sc_dev.dv_xname, 1102 sc->sc_model, sc->sc_firmware); 1103 } 1104 1105 void 1106 bhaminphys(bp) 1107 struct buf *bp; 1108 { 1109 1110 if (bp->b_bcount > ((BHA_NSEG - 1) << PGSHIFT)) 1111 bp->b_bcount = ((BHA_NSEG - 1) << PGSHIFT); 1112 minphys(bp); 1113 } 1114 1115 /* 1116 * start a scsi operation given the command and the data address. Also needs 1117 * the unit, target and lu. 1118 */ 1119 int 1120 bha_scsi_cmd(xs) 1121 struct scsi_xfer *xs; 1122 { 1123 struct scsi_link *sc_link = xs->sc_link; 1124 struct bha_softc *sc = sc_link->adapter_softc; 1125 struct bha_ccb *ccb; 1126 struct bha_scat_gath *sg; 1127 int seg; /* scatter gather seg being worked on */ 1128 u_long thiskv, thisphys, nextphys; 1129 int bytes_this_seg, bytes_this_page, datalen, flags; 1130 #ifdef TFS 1131 struct iovec *iovp; 1132 #endif 1133 int s; 1134 1135 SC_DEBUG(sc_link, SDEV_DB2, ("bha_scsi_cmd\n")); 1136 /* 1137 * get a ccb to use. If the transfer 1138 * is from a buf (possibly from interrupt time) 1139 * then we can't allow it to sleep 1140 */ 1141 flags = xs->flags; 1142 if ((ccb = bha_get_ccb(sc, flags)) == NULL) { 1143 xs->error = XS_DRIVER_STUFFUP; 1144 return (TRY_AGAIN_LATER); 1145 } 1146 ccb->xs = xs; 1147 ccb->timeout = xs->timeout; 1148 1149 /* 1150 * Put all the arguments for the xfer in the ccb 1151 */ 1152 if (flags & SCSI_RESET) { 1153 ccb->opcode = BHA_RESET_CCB; 1154 ccb->scsi_cmd_length = 0; 1155 } else { 1156 /* can't use S/G if zero length */ 1157 ccb->opcode = (xs->datalen ? BHA_INIT_SCAT_GATH_CCB 1158 : BHA_INITIATOR_CCB); 1159 bcopy(xs->cmd, &ccb->scsi_cmd, 1160 ccb->scsi_cmd_length = xs->cmdlen); 1161 } 1162 1163 if (xs->datalen) { 1164 sg = ccb->scat_gath; 1165 seg = 0; 1166 #ifdef TFS 1167 if (flags & SCSI_DATA_UIO) { 1168 iovp = ((struct uio *)xs->data)->uio_iov; 1169 datalen = ((struct uio *)xs->data)->uio_iovcnt; 1170 xs->datalen = 0; 1171 while (datalen && seg < BHA_NSEG) { 1172 ltophys(iovp->iov_base, sg->seg_addr); 1173 ltophys(iovp->iov_len, sg->seg_len); 1174 xs->datalen += iovp->iov_len; 1175 SC_DEBUGN(sc_link, SDEV_DB4, ("(0x%x@0x%x)", 1176 iovp->iov_len, iovp->iov_base)); 1177 sg++; 1178 iovp++; 1179 seg++; 1180 datalen--; 1181 } 1182 } else 1183 #endif /* TFS */ 1184 { 1185 /* 1186 * Set up the scatter-gather block. 1187 */ 1188 SC_DEBUG(sc_link, SDEV_DB4, 1189 ("%d @0x%x:- ", xs->datalen, xs->data)); 1190 1191 datalen = xs->datalen; 1192 thiskv = (u_long)xs->data; 1193 thisphys = KVTOPHYS(thiskv); 1194 1195 while (datalen && seg < BHA_NSEG) { 1196 bytes_this_seg = 0; 1197 1198 /* put in the base address */ 1199 ltophys(thisphys, sg->seg_addr); 1200 1201 SC_DEBUGN(sc_link, SDEV_DB4, 1202 ("0x%x", thisphys)); 1203 1204 /* do it at least once */ 1205 nextphys = thisphys; 1206 while (datalen && thisphys == nextphys) { 1207 /* 1208 * This page is contiguous (physically) 1209 * with the the last, just extend the 1210 * length 1211 */ 1212 /* how far to the end of the page */ 1213 nextphys = 1214 (thisphys & ~PGOFSET) + NBPG; 1215 bytes_this_page = nextphys - thisphys; 1216 /**** or the data ****/ 1217 bytes_this_page = min(bytes_this_page, 1218 datalen); 1219 bytes_this_seg += bytes_this_page; 1220 datalen -= bytes_this_page; 1221 1222 /* get more ready for the next page */ 1223 thiskv = (thiskv & ~PGOFSET) + NBPG; 1224 if (datalen) 1225 thisphys = KVTOPHYS(thiskv); 1226 } 1227 /* 1228 * next page isn't contiguous, finish the seg 1229 */ 1230 SC_DEBUGN(sc_link, SDEV_DB4, 1231 ("(0x%x)", bytes_this_seg)); 1232 ltophys(bytes_this_seg, sg->seg_len); 1233 sg++; 1234 seg++; 1235 } 1236 } 1237 /* end of iov/kv decision */ 1238 SC_DEBUGN(sc_link, SDEV_DB4, ("\n")); 1239 if (datalen) { 1240 /* 1241 * there's still data, must have run out of segs! 1242 */ 1243 printf("%s: bha_scsi_cmd, more than %d dma segs\n", 1244 sc->sc_dev.dv_xname, BHA_NSEG); 1245 goto bad; 1246 } 1247 ltophys(KVTOPHYS(ccb->scat_gath), ccb->data_addr); 1248 ltophys(seg * sizeof(struct bha_scat_gath), ccb->data_length); 1249 } else { /* No data xfer, use non S/G values */ 1250 ltophys(0, ccb->data_addr); 1251 ltophys(0, ccb->data_length); 1252 } 1253 1254 ccb->data_out = 0; 1255 ccb->data_in = 0; 1256 ccb->target = sc_link->target; 1257 ccb->lun = sc_link->lun; 1258 ltophys(KVTOPHYS(&ccb->scsi_sense), ccb->sense_ptr); 1259 ccb->req_sense_length = sizeof(ccb->scsi_sense); 1260 ccb->host_stat = 0x00; 1261 ccb->target_stat = 0x00; 1262 ccb->link_id = 0; 1263 ltophys(0, ccb->link_addr); 1264 1265 s = splbio(); 1266 bha_queue_ccb(sc, ccb); 1267 splx(s); 1268 1269 /* 1270 * Usually return SUCCESSFULLY QUEUED 1271 */ 1272 SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n")); 1273 if ((flags & SCSI_POLL) == 0) 1274 return (SUCCESSFULLY_QUEUED); 1275 1276 /* 1277 * If we can't use interrupts, poll on completion 1278 */ 1279 if (bha_poll(sc, xs, ccb->timeout)) { 1280 bha_timeout(ccb); 1281 if (bha_poll(sc, xs, ccb->timeout)) 1282 bha_timeout(ccb); 1283 } 1284 return (COMPLETE); 1285 1286 bad: 1287 xs->error = XS_DRIVER_STUFFUP; 1288 bha_free_ccb(sc, ccb); 1289 return (COMPLETE); 1290 } 1291 1292 /* 1293 * Poll a particular unit, looking for a particular xs 1294 */ 1295 int 1296 bha_poll(sc, xs, count) 1297 struct bha_softc *sc; 1298 struct scsi_xfer *xs; 1299 int count; 1300 { 1301 bus_space_tag_t iot = sc->sc_iot; 1302 bus_space_handle_t ioh = sc->sc_ioh; 1303 1304 /* timeouts are in msec, so we loop in 1000 usec cycles */ 1305 while (count) { 1306 /* 1307 * If we had interrupts enabled, would we 1308 * have got an interrupt? 1309 */ 1310 if (bus_space_read_1(iot, ioh, BHA_INTR_PORT) & 1311 BHA_INTR_ANYINTR) 1312 bha_intr(sc); 1313 if (xs->flags & ITSDONE) 1314 return (0); 1315 delay(1000); /* only happens in boot so ok */ 1316 count--; 1317 } 1318 return (1); 1319 } 1320 1321 void 1322 bha_timeout(arg) 1323 void *arg; 1324 { 1325 struct bha_ccb *ccb = arg; 1326 struct scsi_xfer *xs = ccb->xs; 1327 struct scsi_link *sc_link = xs->sc_link; 1328 struct bha_softc *sc = sc_link->adapter_softc; 1329 int s; 1330 1331 sc_print_addr(sc_link); 1332 printf("timed out"); 1333 1334 s = splbio(); 1335 1336 #ifdef BHADIAG 1337 /* 1338 * If the ccb's mbx is not free, then the board has gone Far East? 1339 */ 1340 bha_collect_mbo(sc); 1341 if (ccb->flags & CCB_SENDING) { 1342 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname); 1343 Debugger(); 1344 } 1345 #endif 1346 1347 /* 1348 * If it has been through before, then 1349 * a previous abort has failed, don't 1350 * try abort again 1351 */ 1352 if (ccb->flags & CCB_ABORT) { 1353 /* abort timed out */ 1354 printf(" AGAIN\n"); 1355 /* XXX Must reset! */ 1356 } else { 1357 /* abort the operation that has timed out */ 1358 printf("\n"); 1359 ccb->xs->error = XS_TIMEOUT; 1360 ccb->timeout = BHA_ABORT_TIMEOUT; 1361 ccb->flags |= CCB_ABORT; 1362 bha_queue_ccb(sc, ccb); 1363 } 1364 1365 splx(s); 1366 } 1367