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