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