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