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