diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-01-15 17:59:29 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-01-15 17:59:29 -0500 |
commit | f1dccedc8148026d9071c6805f7cb77374a9e56f (patch) | |
tree | ba4a630084b8d21309930321ff53a6ed4381c0f3 /drivers/scsi/aic7xxx/aic79xx_core.c | |
parent | c943aa859c392eb4cc76d911daa1f261555075b2 (diff) | |
parent | 0238cb4e7583c521bb3538060f98a73e65f61324 (diff) |
Merge ssh://master.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx_core.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_core.c | 771 |
1 files changed, 412 insertions, 359 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 4e8f00df978d..db8f5ce99ee3 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -37,9 +37,7 @@ | |||
37 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 37 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | * POSSIBILITY OF SUCH DAMAGES. | 38 | * POSSIBILITY OF SUCH DAMAGES. |
39 | * | 39 | * |
40 | * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#202 $ | 40 | * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#247 $ |
41 | * | ||
42 | * $FreeBSD$ | ||
43 | */ | 41 | */ |
44 | 42 | ||
45 | #ifdef __linux__ | 43 | #ifdef __linux__ |
@@ -332,6 +330,14 @@ ahd_restart(struct ahd_softc *ahd) | |||
332 | ahd_outb(ahd, SCSISEQ1, | 330 | ahd_outb(ahd, SCSISEQ1, |
333 | ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP)); | 331 | ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP)); |
334 | ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); | 332 | ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN); |
333 | |||
334 | /* | ||
335 | * Clear any pending sequencer interrupt. It is no | ||
336 | * longer relevant since we're resetting the Program | ||
337 | * Counter. | ||
338 | */ | ||
339 | ahd_outb(ahd, CLRINT, CLRSEQINT); | ||
340 | |||
335 | ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); | 341 | ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET); |
336 | ahd_unpause(ahd); | 342 | ahd_unpause(ahd); |
337 | } | 343 | } |
@@ -373,13 +379,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) | |||
373 | saved_modes = ahd_save_modes(ahd); | 379 | saved_modes = ahd_save_modes(ahd); |
374 | 380 | ||
375 | /* | 381 | /* |
376 | * Complete any SCBs that just finished being | 382 | * Flush the good status FIFO for completed packetized commands. |
377 | * DMA'ed into the qoutfifo. | ||
378 | */ | ||
379 | ahd_run_qoutfifo(ahd); | ||
380 | |||
381 | /* | ||
382 | * Flush the good status FIFO for compelted packetized commands. | ||
383 | */ | 383 | */ |
384 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); | 384 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); |
385 | saved_scbptr = ahd_get_scbptr(ahd); | 385 | saved_scbptr = ahd_get_scbptr(ahd); |
@@ -387,8 +387,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) | |||
387 | u_int fifo_mode; | 387 | u_int fifo_mode; |
388 | u_int i; | 388 | u_int i; |
389 | 389 | ||
390 | scbid = (ahd_inb(ahd, GSFIFO+1) << 8) | 390 | scbid = ahd_inw(ahd, GSFIFO); |
391 | | ahd_inb(ahd, GSFIFO); | ||
392 | scb = ahd_lookup_scb(ahd, scbid); | 391 | scb = ahd_lookup_scb(ahd, scbid); |
393 | if (scb == NULL) { | 392 | if (scb == NULL) { |
394 | printf("%s: Warning - GSFIFO SCB %d invalid\n", | 393 | printf("%s: Warning - GSFIFO SCB %d invalid\n", |
@@ -401,22 +400,33 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) | |||
401 | * the host before completing the command. | 400 | * the host before completing the command. |
402 | */ | 401 | */ |
403 | fifo_mode = 0; | 402 | fifo_mode = 0; |
403 | rescan_fifos: | ||
404 | for (i = 0; i < 2; i++) { | 404 | for (i = 0; i < 2; i++) { |
405 | /* Toggle to the other mode. */ | 405 | /* Toggle to the other mode. */ |
406 | fifo_mode ^= 1; | 406 | fifo_mode ^= 1; |
407 | ahd_set_modes(ahd, fifo_mode, fifo_mode); | 407 | ahd_set_modes(ahd, fifo_mode, fifo_mode); |
408 | |||
408 | if (ahd_scb_active_in_fifo(ahd, scb) == 0) | 409 | if (ahd_scb_active_in_fifo(ahd, scb) == 0) |
409 | continue; | 410 | continue; |
410 | 411 | ||
411 | ahd_run_data_fifo(ahd, scb); | 412 | ahd_run_data_fifo(ahd, scb); |
412 | 413 | ||
413 | /* | 414 | /* |
414 | * Clearing this transaction in this FIFO may | 415 | * Running this FIFO may cause a CFG4DATA for |
415 | * cause a CFG4DATA for this same transaction | 416 | * this same transaction to assert in the other |
416 | * to assert in the other FIFO. Make sure we | 417 | * FIFO or a new snapshot SAVEPTRS interrupt |
417 | * loop one more time and check the other FIFO. | 418 | * in this FIFO. Even running a FIFO may not |
419 | * clear the transaction if we are still waiting | ||
420 | * for data to drain to the host. We must loop | ||
421 | * until the transaction is not active in either | ||
422 | * FIFO just to be sure. Reset our loop counter | ||
423 | * so we will visit both FIFOs again before | ||
424 | * declaring this transaction finished. We | ||
425 | * also delay a bit so that status has a chance | ||
426 | * to change before we look at this FIFO again. | ||
418 | */ | 427 | */ |
419 | i = 0; | 428 | ahd_delay(200); |
429 | goto rescan_fifos; | ||
420 | } | 430 | } |
421 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); | 431 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); |
422 | ahd_set_scbptr(ahd, scbid); | 432 | ahd_set_scbptr(ahd, scbid); |
@@ -429,19 +439,28 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) | |||
429 | /* | 439 | /* |
430 | * The transfer completed with a residual. | 440 | * The transfer completed with a residual. |
431 | * Place this SCB on the complete DMA list | 441 | * Place this SCB on the complete DMA list |
432 | * so that we Update our in-core copy of the | 442 | * so that we update our in-core copy of the |
433 | * SCB before completing the command. | 443 | * SCB before completing the command. |
434 | */ | 444 | */ |
435 | ahd_outb(ahd, SCB_SCSI_STATUS, 0); | 445 | ahd_outb(ahd, SCB_SCSI_STATUS, 0); |
436 | ahd_outb(ahd, SCB_SGPTR, | 446 | ahd_outb(ahd, SCB_SGPTR, |
437 | ahd_inb_scbram(ahd, SCB_SGPTR) | 447 | ahd_inb_scbram(ahd, SCB_SGPTR) |
438 | | SG_STATUS_VALID); | 448 | | SG_STATUS_VALID); |
439 | ahd_outw(ahd, SCB_TAG, SCB_GET_TAG(scb)); | 449 | ahd_outw(ahd, SCB_TAG, scbid); |
450 | ahd_outw(ahd, SCB_NEXT_COMPLETE, SCB_LIST_NULL); | ||
440 | comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); | 451 | comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD); |
441 | ahd_outw(ahd, SCB_NEXT_COMPLETE, comp_head); | 452 | if (SCBID_IS_NULL(comp_head)) { |
442 | if (SCBID_IS_NULL(comp_head)) | 453 | ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, scbid); |
443 | ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, | 454 | ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, scbid); |
444 | SCB_GET_TAG(scb)); | 455 | } else { |
456 | u_int tail; | ||
457 | |||
458 | tail = ahd_inw(ahd, COMPLETE_DMA_SCB_TAIL); | ||
459 | ahd_set_scbptr(ahd, tail); | ||
460 | ahd_outw(ahd, SCB_NEXT_COMPLETE, scbid); | ||
461 | ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, scbid); | ||
462 | ahd_set_scbptr(ahd, scbid); | ||
463 | } | ||
445 | } else | 464 | } else |
446 | ahd_complete_scb(ahd, scb); | 465 | ahd_complete_scb(ahd, scb); |
447 | } | 466 | } |
@@ -465,9 +484,22 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) | |||
465 | break; | 484 | break; |
466 | ahd_delay(200); | 485 | ahd_delay(200); |
467 | } | 486 | } |
468 | if ((ccscbctl & CCSCBDIR) != 0) | 487 | /* |
488 | * We leave the sequencer to cleanup in the case of DMA's to | ||
489 | * update the qoutfifo. In all other cases (DMA's to the | ||
490 | * chip or a push of an SCB from the COMPLETE_DMA_SCB list), | ||
491 | * we disable the DMA engine so that the sequencer will not | ||
492 | * attempt to handle the DMA completion. | ||
493 | */ | ||
494 | if ((ccscbctl & CCSCBDIR) != 0 || (ccscbctl & ARRDONE) != 0) | ||
469 | ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN)); | 495 | ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN)); |
470 | 496 | ||
497 | /* | ||
498 | * Complete any SCBs that just finished | ||
499 | * being DMA'ed into the qoutfifo. | ||
500 | */ | ||
501 | ahd_run_qoutfifo(ahd); | ||
502 | |||
471 | saved_scbptr = ahd_get_scbptr(ahd); | 503 | saved_scbptr = ahd_get_scbptr(ahd); |
472 | /* | 504 | /* |
473 | * Manually update/complete any completed SCBs that are waiting to be | 505 | * Manually update/complete any completed SCBs that are waiting to be |
@@ -494,6 +526,24 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd) | |||
494 | scbid = next_scbid; | 526 | scbid = next_scbid; |
495 | } | 527 | } |
496 | ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); | 528 | ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); |
529 | ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, SCB_LIST_NULL); | ||
530 | |||
531 | scbid = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD); | ||
532 | while (!SCBID_IS_NULL(scbid)) { | ||
533 | |||
534 | ahd_set_scbptr(ahd, scbid); | ||
535 | next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE); | ||
536 | scb = ahd_lookup_scb(ahd, scbid); | ||
537 | if (scb == NULL) { | ||
538 | printf("%s: Warning - Complete Qfrz SCB %d invalid\n", | ||
539 | ahd_name(ahd), scbid); | ||
540 | continue; | ||
541 | } | ||
542 | |||
543 | ahd_complete_scb(ahd, scb); | ||
544 | scbid = next_scbid; | ||
545 | } | ||
546 | ahd_outw(ahd, COMPLETE_ON_QFREEZE_HEAD, SCB_LIST_NULL); | ||
497 | 547 | ||
498 | scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD); | 548 | scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD); |
499 | while (!SCBID_IS_NULL(scbid)) { | 549 | while (!SCBID_IS_NULL(scbid)) { |
@@ -558,150 +608,146 @@ ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb) | |||
558 | { | 608 | { |
559 | u_int seqintsrc; | 609 | u_int seqintsrc; |
560 | 610 | ||
561 | while (1) { | 611 | seqintsrc = ahd_inb(ahd, SEQINTSRC); |
562 | seqintsrc = ahd_inb(ahd, SEQINTSRC); | 612 | if ((seqintsrc & CFG4DATA) != 0) { |
563 | if ((seqintsrc & CFG4DATA) != 0) { | 613 | uint32_t datacnt; |
564 | uint32_t datacnt; | 614 | uint32_t sgptr; |
565 | uint32_t sgptr; | ||
566 | |||
567 | /* | ||
568 | * Clear full residual flag. | ||
569 | */ | ||
570 | sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID; | ||
571 | ahd_outb(ahd, SCB_SGPTR, sgptr); | ||
572 | 615 | ||
573 | /* | 616 | /* |
574 | * Load datacnt and address. | 617 | * Clear full residual flag. |
575 | */ | 618 | */ |
576 | datacnt = ahd_inl_scbram(ahd, SCB_DATACNT); | 619 | sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID; |
577 | if ((datacnt & AHD_DMA_LAST_SEG) != 0) { | 620 | ahd_outb(ahd, SCB_SGPTR, sgptr); |
578 | sgptr |= LAST_SEG; | ||
579 | ahd_outb(ahd, SG_STATE, 0); | ||
580 | } else | ||
581 | ahd_outb(ahd, SG_STATE, LOADING_NEEDED); | ||
582 | ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR)); | ||
583 | ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK); | ||
584 | ahd_outb(ahd, SG_CACHE_PRE, sgptr); | ||
585 | ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN); | ||
586 | 621 | ||
587 | /* | 622 | /* |
588 | * Initialize Residual Fields. | 623 | * Load datacnt and address. |
589 | */ | 624 | */ |
590 | ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24); | 625 | datacnt = ahd_inl_scbram(ahd, SCB_DATACNT); |
591 | ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK); | 626 | if ((datacnt & AHD_DMA_LAST_SEG) != 0) { |
627 | sgptr |= LAST_SEG; | ||
628 | ahd_outb(ahd, SG_STATE, 0); | ||
629 | } else | ||
630 | ahd_outb(ahd, SG_STATE, LOADING_NEEDED); | ||
631 | ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR)); | ||
632 | ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK); | ||
633 | ahd_outb(ahd, SG_CACHE_PRE, sgptr); | ||
634 | ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN); | ||
592 | 635 | ||
593 | /* | 636 | /* |
594 | * Mark the SCB as having a FIFO in use. | 637 | * Initialize Residual Fields. |
595 | */ | 638 | */ |
596 | ahd_outb(ahd, SCB_FIFO_USE_COUNT, | 639 | ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24); |
597 | ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1); | 640 | ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK); |
598 | 641 | ||
599 | /* | 642 | /* |
600 | * Install a "fake" handler for this FIFO. | 643 | * Mark the SCB as having a FIFO in use. |
601 | */ | 644 | */ |
602 | ahd_outw(ahd, LONGJMP_ADDR, 0); | 645 | ahd_outb(ahd, SCB_FIFO_USE_COUNT, |
646 | ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1); | ||
603 | 647 | ||
604 | /* | 648 | /* |
605 | * Notify the hardware that we have satisfied | 649 | * Install a "fake" handler for this FIFO. |
606 | * this sequencer interrupt. | 650 | */ |
607 | */ | 651 | ahd_outw(ahd, LONGJMP_ADDR, 0); |
608 | ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA); | ||
609 | } else if ((seqintsrc & SAVEPTRS) != 0) { | ||
610 | uint32_t sgptr; | ||
611 | uint32_t resid; | ||
612 | 652 | ||
613 | if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) { | 653 | /* |
614 | /* | 654 | * Notify the hardware that we have satisfied |
615 | * Snapshot Save Pointers. Clear | 655 | * this sequencer interrupt. |
616 | * the snapshot and continue. | 656 | */ |
617 | */ | 657 | ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA); |
618 | ahd_outb(ahd, DFFSXFRCTL, CLRCHN); | 658 | } else if ((seqintsrc & SAVEPTRS) != 0) { |
619 | continue; | 659 | uint32_t sgptr; |
620 | } | 660 | uint32_t resid; |
621 | 661 | ||
662 | if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) { | ||
622 | /* | 663 | /* |
623 | * Disable S/G fetch so the DMA engine | 664 | * Snapshot Save Pointers. All that |
624 | * is available to future users. | 665 | * is necessary to clear the snapshot |
666 | * is a CLRCHN. | ||
625 | */ | 667 | */ |
626 | if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) | 668 | goto clrchn; |
627 | ahd_outb(ahd, CCSGCTL, 0); | 669 | } |
628 | ahd_outb(ahd, SG_STATE, 0); | ||
629 | 670 | ||
630 | /* | 671 | /* |
631 | * Flush the data FIFO. Strickly only | 672 | * Disable S/G fetch so the DMA engine |
632 | * necessary for Rev A parts. | 673 | * is available to future users. |
633 | */ | 674 | */ |
634 | ahd_outb(ahd, DFCNTRL, | 675 | if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) |
635 | ahd_inb(ahd, DFCNTRL) | FIFOFLUSH); | 676 | ahd_outb(ahd, CCSGCTL, 0); |
677 | ahd_outb(ahd, SG_STATE, 0); | ||
636 | 678 | ||
637 | /* | 679 | /* |
638 | * Calculate residual. | 680 | * Flush the data FIFO. Strickly only |
639 | */ | 681 | * necessary for Rev A parts. |
640 | sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR); | 682 | */ |
641 | resid = ahd_inl(ahd, SHCNT); | 683 | ahd_outb(ahd, DFCNTRL, ahd_inb(ahd, DFCNTRL) | FIFOFLUSH); |
642 | resid |= | ||
643 | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24; | ||
644 | ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid); | ||
645 | if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) { | ||
646 | /* | ||
647 | * Must back up to the correct S/G element. | ||
648 | * Typically this just means resetting our | ||
649 | * low byte to the offset in the SG_CACHE, | ||
650 | * but if we wrapped, we have to correct | ||
651 | * the other bytes of the sgptr too. | ||
652 | */ | ||
653 | if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0 | ||
654 | && (sgptr & 0x80) == 0) | ||
655 | sgptr -= 0x100; | ||
656 | sgptr &= ~0xFF; | ||
657 | sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW) | ||
658 | & SG_ADDR_MASK; | ||
659 | ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr); | ||
660 | ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0); | ||
661 | } else if ((resid & AHD_SG_LEN_MASK) == 0) { | ||
662 | ahd_outb(ahd, SCB_RESIDUAL_SGPTR, | ||
663 | sgptr | SG_LIST_NULL); | ||
664 | } | ||
665 | /* | ||
666 | * Save Pointers. | ||
667 | */ | ||
668 | ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR)); | ||
669 | ahd_outl(ahd, SCB_DATACNT, resid); | ||
670 | ahd_outl(ahd, SCB_SGPTR, sgptr); | ||
671 | ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS); | ||
672 | ahd_outb(ahd, SEQIMODE, | ||
673 | ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS); | ||
674 | /* | ||
675 | * If the data is to the SCSI bus, we are | ||
676 | * done, otherwise wait for FIFOEMP. | ||
677 | */ | ||
678 | if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0) | ||
679 | break; | ||
680 | } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) { | ||
681 | uint32_t sgptr; | ||
682 | uint64_t data_addr; | ||
683 | uint32_t data_len; | ||
684 | u_int dfcntrl; | ||
685 | 684 | ||
685 | /* | ||
686 | * Calculate residual. | ||
687 | */ | ||
688 | sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR); | ||
689 | resid = ahd_inl(ahd, SHCNT); | ||
690 | resid |= ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24; | ||
691 | ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid); | ||
692 | if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) { | ||
686 | /* | 693 | /* |
687 | * Disable S/G fetch so the DMA engine | 694 | * Must back up to the correct S/G element. |
688 | * is available to future users. | 695 | * Typically this just means resetting our |
696 | * low byte to the offset in the SG_CACHE, | ||
697 | * but if we wrapped, we have to correct | ||
698 | * the other bytes of the sgptr too. | ||
689 | */ | 699 | */ |
690 | if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) { | 700 | if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0 |
691 | ahd_outb(ahd, CCSGCTL, 0); | 701 | && (sgptr & 0x80) == 0) |
692 | ahd_outb(ahd, SG_STATE, LOADING_NEEDED); | 702 | sgptr -= 0x100; |
693 | } | 703 | sgptr &= ~0xFF; |
704 | sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW) | ||
705 | & SG_ADDR_MASK; | ||
706 | ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr); | ||
707 | ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0); | ||
708 | } else if ((resid & AHD_SG_LEN_MASK) == 0) { | ||
709 | ahd_outb(ahd, SCB_RESIDUAL_SGPTR, | ||
710 | sgptr | SG_LIST_NULL); | ||
711 | } | ||
712 | /* | ||
713 | * Save Pointers. | ||
714 | */ | ||
715 | ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR)); | ||
716 | ahd_outl(ahd, SCB_DATACNT, resid); | ||
717 | ahd_outl(ahd, SCB_SGPTR, sgptr); | ||
718 | ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS); | ||
719 | ahd_outb(ahd, SEQIMODE, | ||
720 | ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS); | ||
721 | /* | ||
722 | * If the data is to the SCSI bus, we are | ||
723 | * done, otherwise wait for FIFOEMP. | ||
724 | */ | ||
725 | if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0) | ||
726 | goto clrchn; | ||
727 | } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) { | ||
728 | uint32_t sgptr; | ||
729 | uint64_t data_addr; | ||
730 | uint32_t data_len; | ||
731 | u_int dfcntrl; | ||
694 | 732 | ||
695 | /* | 733 | /* |
696 | * Wait for the DMA engine to notice that the | 734 | * Disable S/G fetch so the DMA engine |
697 | * host transfer is enabled and that there is | 735 | * is available to future users. We won't |
698 | * space in the S/G FIFO for new segments before | 736 | * be using the DMA engine to load segments. |
699 | * loading more segments. | 737 | */ |
700 | */ | 738 | if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) { |
701 | if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) == 0) | 739 | ahd_outb(ahd, CCSGCTL, 0); |
702 | continue; | 740 | ahd_outb(ahd, SG_STATE, LOADING_NEEDED); |
703 | if ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) == 0) | 741 | } |
704 | continue; | 742 | |
743 | /* | ||
744 | * Wait for the DMA engine to notice that the | ||
745 | * host transfer is enabled and that there is | ||
746 | * space in the S/G FIFO for new segments before | ||
747 | * loading more segments. | ||
748 | */ | ||
749 | if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) != 0 | ||
750 | && (ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0) { | ||
705 | 751 | ||
706 | /* | 752 | /* |
707 | * Determine the offset of the next S/G | 753 | * Determine the offset of the next S/G |
@@ -748,7 +794,7 @@ ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb) | |||
748 | * Advertise the segment to the hardware. | 794 | * Advertise the segment to the hardware. |
749 | */ | 795 | */ |
750 | dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN; | 796 | dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN; |
751 | if ((ahd->features & AHD_NEW_DFCNTRL_OPTS)!=0) { | 797 | if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) { |
752 | /* | 798 | /* |
753 | * Use SCSIENWRDIS so that SCSIEN | 799 | * Use SCSIENWRDIS so that SCSIEN |
754 | * is never modified by this | 800 | * is never modified by this |
@@ -757,35 +803,44 @@ ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb) | |||
757 | dfcntrl |= SCSIENWRDIS; | 803 | dfcntrl |= SCSIENWRDIS; |
758 | } | 804 | } |
759 | ahd_outb(ahd, DFCNTRL, dfcntrl); | 805 | ahd_outb(ahd, DFCNTRL, dfcntrl); |
760 | } else if ((ahd_inb(ahd, SG_CACHE_SHADOW) | ||
761 | & LAST_SEG_DONE) != 0) { | ||
762 | |||
763 | /* | ||
764 | * Transfer completed to the end of SG list | ||
765 | * and has flushed to the host. | ||
766 | */ | ||
767 | ahd_outb(ahd, SCB_SGPTR, | ||
768 | ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL); | ||
769 | break; | ||
770 | } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) { | ||
771 | break; | ||
772 | } | 806 | } |
773 | ahd_delay(200); | 807 | } else if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG_DONE) != 0) { |
808 | |||
809 | /* | ||
810 | * Transfer completed to the end of SG list | ||
811 | * and has flushed to the host. | ||
812 | */ | ||
813 | ahd_outb(ahd, SCB_SGPTR, | ||
814 | ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL); | ||
815 | goto clrchn; | ||
816 | } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) { | ||
817 | clrchn: | ||
818 | /* | ||
819 | * Clear any handler for this FIFO, decrement | ||
820 | * the FIFO use count for the SCB, and release | ||
821 | * the FIFO. | ||
822 | */ | ||
823 | ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); | ||
824 | ahd_outb(ahd, SCB_FIFO_USE_COUNT, | ||
825 | ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1); | ||
826 | ahd_outb(ahd, DFFSXFRCTL, CLRCHN); | ||
774 | } | 827 | } |
775 | /* | ||
776 | * Clear any handler for this FIFO, decrement | ||
777 | * the FIFO use count for the SCB, and release | ||
778 | * the FIFO. | ||
779 | */ | ||
780 | ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR); | ||
781 | ahd_outb(ahd, SCB_FIFO_USE_COUNT, | ||
782 | ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1); | ||
783 | ahd_outb(ahd, DFFSXFRCTL, CLRCHN); | ||
784 | } | 828 | } |
785 | 829 | ||
830 | /* | ||
831 | * Look for entries in the QoutFIFO that have completed. | ||
832 | * The valid_tag completion field indicates the validity | ||
833 | * of the entry - the valid value toggles each time through | ||
834 | * the queue. We use the sg_status field in the completion | ||
835 | * entry to avoid referencing the hscb if the completion | ||
836 | * occurred with no errors and no residual. sg_status is | ||
837 | * a copy of the first byte (little endian) of the sgptr | ||
838 | * hscb field. | ||
839 | */ | ||
786 | void | 840 | void |
787 | ahd_run_qoutfifo(struct ahd_softc *ahd) | 841 | ahd_run_qoutfifo(struct ahd_softc *ahd) |
788 | { | 842 | { |
843 | struct ahd_completion *completion; | ||
789 | struct scb *scb; | 844 | struct scb *scb; |
790 | u_int scb_index; | 845 | u_int scb_index; |
791 | 846 | ||
@@ -793,11 +848,13 @@ ahd_run_qoutfifo(struct ahd_softc *ahd) | |||
793 | panic("ahd_run_qoutfifo recursion"); | 848 | panic("ahd_run_qoutfifo recursion"); |
794 | ahd->flags |= AHD_RUNNING_QOUTFIFO; | 849 | ahd->flags |= AHD_RUNNING_QOUTFIFO; |
795 | ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD); | 850 | ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD); |
796 | while ((ahd->qoutfifo[ahd->qoutfifonext] | 851 | for (;;) { |
797 | & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) { | 852 | completion = &ahd->qoutfifo[ahd->qoutfifonext]; |
798 | 853 | ||
799 | scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext] | 854 | if (completion->valid_tag != ahd->qoutfifonext_valid_tag) |
800 | & ~QOUTFIFO_ENTRY_VALID_LE); | 855 | break; |
856 | |||
857 | scb_index = ahd_le16toh(completion->tag); | ||
801 | scb = ahd_lookup_scb(ahd, scb_index); | 858 | scb = ahd_lookup_scb(ahd, scb_index); |
802 | if (scb == NULL) { | 859 | if (scb == NULL) { |
803 | printf("%s: WARNING no command for scb %d " | 860 | printf("%s: WARNING no command for scb %d " |
@@ -805,12 +862,15 @@ ahd_run_qoutfifo(struct ahd_softc *ahd) | |||
805 | ahd_name(ahd), scb_index, | 862 | ahd_name(ahd), scb_index, |
806 | ahd->qoutfifonext); | 863 | ahd->qoutfifonext); |
807 | ahd_dump_card_state(ahd); | 864 | ahd_dump_card_state(ahd); |
808 | } else | 865 | } else if ((completion->sg_status & SG_STATUS_VALID) != 0) { |
809 | ahd_complete_scb(ahd, scb); | 866 | ahd_handle_scb_status(ahd, scb); |
867 | } else { | ||
868 | ahd_done(ahd, scb); | ||
869 | } | ||
810 | 870 | ||
811 | ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1); | 871 | ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1); |
812 | if (ahd->qoutfifonext == 0) | 872 | if (ahd->qoutfifonext == 0) |
813 | ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE; | 873 | ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID; |
814 | } | 874 | } |
815 | ahd->flags &= ~AHD_RUNNING_QOUTFIFO; | 875 | ahd->flags &= ~AHD_RUNNING_QOUTFIFO; |
816 | } | 876 | } |
@@ -876,26 +936,6 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | |||
876 | ahd_name(ahd), seqintcode); | 936 | ahd_name(ahd), seqintcode); |
877 | #endif | 937 | #endif |
878 | switch (seqintcode) { | 938 | switch (seqintcode) { |
879 | case BAD_SCB_STATUS: | ||
880 | { | ||
881 | struct scb *scb; | ||
882 | u_int scbid; | ||
883 | int cmds_pending; | ||
884 | |||
885 | scbid = ahd_get_scbptr(ahd); | ||
886 | scb = ahd_lookup_scb(ahd, scbid); | ||
887 | if (scb != NULL) { | ||
888 | ahd_complete_scb(ahd, scb); | ||
889 | } else { | ||
890 | printf("%s: WARNING no command for scb %d " | ||
891 | "(bad status)\n", ahd_name(ahd), scbid); | ||
892 | ahd_dump_card_state(ahd); | ||
893 | } | ||
894 | cmds_pending = ahd_inw(ahd, CMDS_PENDING); | ||
895 | if (cmds_pending > 0) | ||
896 | ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1); | ||
897 | break; | ||
898 | } | ||
899 | case ENTERING_NONPACK: | 939 | case ENTERING_NONPACK: |
900 | { | 940 | { |
901 | struct scb *scb; | 941 | struct scb *scb; |
@@ -1060,7 +1100,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | |||
1060 | ahd_outb(ahd, SAVED_LUN, 0); | 1100 | ahd_outb(ahd, SAVED_LUN, 0); |
1061 | ahd_outb(ahd, SEQ_FLAGS, 0); | 1101 | ahd_outb(ahd, SEQ_FLAGS, 0); |
1062 | ahd_assert_atn(ahd); | 1102 | ahd_assert_atn(ahd); |
1063 | scb->flags &= ~(SCB_PACKETIZED); | 1103 | scb->flags &= ~SCB_PACKETIZED; |
1064 | scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT; | 1104 | scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT; |
1065 | ahd_freeze_devq(ahd, scb); | 1105 | ahd_freeze_devq(ahd, scb); |
1066 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); | 1106 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); |
@@ -1503,9 +1543,6 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) | |||
1503 | && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) | 1543 | && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0) |
1504 | scb = NULL; | 1544 | scb = NULL; |
1505 | 1545 | ||
1506 | /* Make sure the sequencer is in a safe location. */ | ||
1507 | ahd_clear_critical_section(ahd); | ||
1508 | |||
1509 | if ((status0 & IOERR) != 0) { | 1546 | if ((status0 & IOERR) != 0) { |
1510 | u_int now_lvd; | 1547 | u_int now_lvd; |
1511 | 1548 | ||
@@ -1521,26 +1558,35 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) | |||
1521 | ahd_setup_iocell_workaround(ahd); | 1558 | ahd_setup_iocell_workaround(ahd); |
1522 | ahd_unpause(ahd); | 1559 | ahd_unpause(ahd); |
1523 | } else if ((status0 & OVERRUN) != 0) { | 1560 | } else if ((status0 & OVERRUN) != 0) { |
1561 | |||
1524 | printf("%s: SCSI offset overrun detected. Resetting bus.\n", | 1562 | printf("%s: SCSI offset overrun detected. Resetting bus.\n", |
1525 | ahd_name(ahd)); | 1563 | ahd_name(ahd)); |
1526 | ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); | 1564 | ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE); |
1527 | } else if ((status & SCSIRSTI) != 0) { | 1565 | } else if ((status & SCSIRSTI) != 0) { |
1566 | |||
1528 | printf("%s: Someone reset channel A\n", ahd_name(ahd)); | 1567 | printf("%s: Someone reset channel A\n", ahd_name(ahd)); |
1529 | ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); | 1568 | ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE); |
1530 | } else if ((status & SCSIPERR) != 0) { | 1569 | } else if ((status & SCSIPERR) != 0) { |
1570 | |||
1571 | /* Make sure the sequencer is in a safe location. */ | ||
1572 | ahd_clear_critical_section(ahd); | ||
1573 | |||
1531 | ahd_handle_transmission_error(ahd); | 1574 | ahd_handle_transmission_error(ahd); |
1532 | } else if (lqostat0 != 0) { | 1575 | } else if (lqostat0 != 0) { |
1576 | |||
1533 | printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0); | 1577 | printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0); |
1534 | ahd_outb(ahd, CLRLQOINT0, lqostat0); | 1578 | ahd_outb(ahd, CLRLQOINT0, lqostat0); |
1535 | if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) { | 1579 | if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) |
1536 | ahd_outb(ahd, CLRLQOINT1, 0); | 1580 | ahd_outb(ahd, CLRLQOINT1, 0); |
1537 | } | ||
1538 | } else if ((status & SELTO) != 0) { | 1581 | } else if ((status & SELTO) != 0) { |
1539 | u_int scbid; | 1582 | u_int scbid; |
1540 | 1583 | ||
1541 | /* Stop the selection */ | 1584 | /* Stop the selection */ |
1542 | ahd_outb(ahd, SCSISEQ0, 0); | 1585 | ahd_outb(ahd, SCSISEQ0, 0); |
1543 | 1586 | ||
1587 | /* Make sure the sequencer is in a safe location. */ | ||
1588 | ahd_clear_critical_section(ahd); | ||
1589 | |||
1544 | /* No more pending messages */ | 1590 | /* No more pending messages */ |
1545 | ahd_clear_msg_state(ahd); | 1591 | ahd_clear_msg_state(ahd); |
1546 | 1592 | ||
@@ -1573,24 +1619,27 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) | |||
1573 | scbid); | 1619 | scbid); |
1574 | } | 1620 | } |
1575 | #endif | 1621 | #endif |
1576 | /* | ||
1577 | * Force a renegotiation with this target just in | ||
1578 | * case the cable was pulled and will later be | ||
1579 | * re-attached. The target may forget its negotiation | ||
1580 | * settings with us should it attempt to reselect | ||
1581 | * during the interruption. The target will not issue | ||
1582 | * a unit attention in this case, so we must always | ||
1583 | * renegotiate. | ||
1584 | */ | ||
1585 | ahd_scb_devinfo(ahd, &devinfo, scb); | 1622 | ahd_scb_devinfo(ahd, &devinfo, scb); |
1586 | ahd_force_renegotiation(ahd, &devinfo); | ||
1587 | ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT); | 1623 | ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT); |
1588 | ahd_freeze_devq(ahd, scb); | 1624 | ahd_freeze_devq(ahd, scb); |
1625 | |||
1626 | /* | ||
1627 | * Cancel any pending transactions on the device | ||
1628 | * now that it seems to be missing. This will | ||
1629 | * also revert us to async/narrow transfers until | ||
1630 | * we can renegotiate with the device. | ||
1631 | */ | ||
1632 | ahd_handle_devreset(ahd, &devinfo, | ||
1633 | CAM_LUN_WILDCARD, | ||
1634 | CAM_SEL_TIMEOUT, | ||
1635 | "Selection Timeout", | ||
1636 | /*verbose_level*/1); | ||
1589 | } | 1637 | } |
1590 | ahd_outb(ahd, CLRINT, CLRSCSIINT); | 1638 | ahd_outb(ahd, CLRINT, CLRSCSIINT); |
1591 | ahd_iocell_first_selection(ahd); | 1639 | ahd_iocell_first_selection(ahd); |
1592 | ahd_unpause(ahd); | 1640 | ahd_unpause(ahd); |
1593 | } else if ((status0 & (SELDI|SELDO)) != 0) { | 1641 | } else if ((status0 & (SELDI|SELDO)) != 0) { |
1642 | |||
1594 | ahd_iocell_first_selection(ahd); | 1643 | ahd_iocell_first_selection(ahd); |
1595 | ahd_unpause(ahd); | 1644 | ahd_unpause(ahd); |
1596 | } else if (status3 != 0) { | 1645 | } else if (status3 != 0) { |
@@ -1598,6 +1647,10 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) | |||
1598 | ahd_name(ahd), status3); | 1647 | ahd_name(ahd), status3); |
1599 | ahd_outb(ahd, CLRSINT3, status3); | 1648 | ahd_outb(ahd, CLRSINT3, status3); |
1600 | } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) { | 1649 | } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) { |
1650 | |||
1651 | /* Make sure the sequencer is in a safe location. */ | ||
1652 | ahd_clear_critical_section(ahd); | ||
1653 | |||
1601 | ahd_handle_lqiphase_error(ahd, lqistat1); | 1654 | ahd_handle_lqiphase_error(ahd, lqistat1); |
1602 | } else if ((lqistat1 & LQICRCI_NLQ) != 0) { | 1655 | } else if ((lqistat1 & LQICRCI_NLQ) != 0) { |
1603 | /* | 1656 | /* |
@@ -1622,6 +1675,9 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) | |||
1622 | */ | 1675 | */ |
1623 | ahd_outb(ahd, SCSISEQ0, 0); | 1676 | ahd_outb(ahd, SCSISEQ0, 0); |
1624 | 1677 | ||
1678 | /* Make sure the sequencer is in a safe location. */ | ||
1679 | ahd_clear_critical_section(ahd); | ||
1680 | |||
1625 | /* | 1681 | /* |
1626 | * Determine what we were up to at the time of | 1682 | * Determine what we were up to at the time of |
1627 | * the busfree. | 1683 | * the busfree. |
@@ -1659,7 +1715,16 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) | |||
1659 | clear_fifo = 0; | 1715 | clear_fifo = 0; |
1660 | packetized = (lqostat1 & LQOBUSFREE) != 0; | 1716 | packetized = (lqostat1 & LQOBUSFREE) != 0; |
1661 | if (!packetized | 1717 | if (!packetized |
1662 | && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) | 1718 | && ahd_inb(ahd, LASTPHASE) == P_BUSFREE |
1719 | && (ahd_inb(ahd, SSTAT0) & SELDI) == 0 | ||
1720 | && ((ahd_inb(ahd, SSTAT0) & SELDO) == 0 | ||
1721 | || (ahd_inb(ahd, SCSISEQ0) & ENSELO) == 0)) | ||
1722 | /* | ||
1723 | * Assume packetized if we are not | ||
1724 | * on the bus in a non-packetized | ||
1725 | * capacity and any pending selection | ||
1726 | * was a packetized selection. | ||
1727 | */ | ||
1663 | packetized = 1; | 1728 | packetized = 1; |
1664 | break; | 1729 | break; |
1665 | } | 1730 | } |
@@ -2310,8 +2375,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
2310 | "PRGMCNT == 0x%x\n", | 2375 | "PRGMCNT == 0x%x\n", |
2311 | ahd_lookup_phase_entry(lastphase)->phasemsg, | 2376 | ahd_lookup_phase_entry(lastphase)->phasemsg, |
2312 | aborted, | 2377 | aborted, |
2313 | ahd_inb(ahd, PRGMCNT) | 2378 | ahd_inw(ahd, PRGMCNT)); |
2314 | | (ahd_inb(ahd, PRGMCNT+1) << 8)); | ||
2315 | ahd_dump_card_state(ahd); | 2379 | ahd_dump_card_state(ahd); |
2316 | } | 2380 | } |
2317 | /* Always restart the sequencer. */ | 2381 | /* Always restart the sequencer. */ |
@@ -2474,8 +2538,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd) | |||
2474 | u_int i; | 2538 | u_int i; |
2475 | 2539 | ||
2476 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); | 2540 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); |
2477 | seqaddr = ahd_inb(ahd, CURADDR) | 2541 | seqaddr = ahd_inw(ahd, CURADDR); |
2478 | | (ahd_inb(ahd, CURADDR+1) << 8); | ||
2479 | 2542 | ||
2480 | cs = ahd->critical_sections; | 2543 | cs = ahd->critical_sections; |
2481 | for (i = 0; i < ahd->num_critical_sections; i++, cs++) { | 2544 | for (i = 0; i < ahd->num_critical_sections; i++, cs++) { |
@@ -3196,14 +3259,25 @@ ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3196 | iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; | 3259 | iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; |
3197 | 3260 | ||
3198 | if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0 | 3261 | if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0 |
3199 | && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) { | 3262 | && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0 |
3263 | && (ppr_opts & MSG_EXT_PPR_IU_REQ) == 0) { | ||
3200 | /* | 3264 | /* |
3201 | * Slow down our CRC interval to be | 3265 | * Slow down our CRC interval to be |
3202 | * compatible with devices that can't | 3266 | * compatible with non-packetized |
3203 | * handle a CRC at full speed. | 3267 | * U160 devices that can't handle a |
3268 | * CRC at full speed. | ||
3204 | */ | 3269 | */ |
3205 | con_opts |= ENSLOWCRC; | 3270 | con_opts |= ENSLOWCRC; |
3206 | } | 3271 | } |
3272 | |||
3273 | if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) { | ||
3274 | /* | ||
3275 | * On H2A4, revert to a slower slewrate | ||
3276 | * on non-paced transfers. | ||
3277 | */ | ||
3278 | iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= | ||
3279 | ~AHD_SLEWRATE_MASK; | ||
3280 | } | ||
3207 | } | 3281 | } |
3208 | 3282 | ||
3209 | ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW); | 3283 | ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW); |
@@ -3292,11 +3366,15 @@ ahd_update_pending_scbs(struct ahd_softc *ahd) | |||
3292 | * Force the sequencer to reinitialize the selection for | 3366 | * Force the sequencer to reinitialize the selection for |
3293 | * the command at the head of the execution queue if it | 3367 | * the command at the head of the execution queue if it |
3294 | * has already been setup. The negotiation changes may | 3368 | * has already been setup. The negotiation changes may |
3295 | * effect whether we select-out with ATN. | 3369 | * effect whether we select-out with ATN. It is only |
3370 | * safe to clear ENSELO when the bus is not free and no | ||
3371 | * selection is in progres or completed. | ||
3296 | */ | 3372 | */ |
3297 | saved_modes = ahd_save_modes(ahd); | 3373 | saved_modes = ahd_save_modes(ahd); |
3298 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); | 3374 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); |
3299 | ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); | 3375 | if ((ahd_inb(ahd, SCSISIGI) & BSYI) != 0 |
3376 | && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0) | ||
3377 | ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO); | ||
3300 | saved_scbptr = ahd_get_scbptr(ahd); | 3378 | saved_scbptr = ahd_get_scbptr(ahd); |
3301 | /* Ensure that the hscbs down on the card match the new information */ | 3379 | /* Ensure that the hscbs down on the card match the new information */ |
3302 | for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) { | 3380 | for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) { |
@@ -4909,10 +4987,7 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd) | |||
4909 | * Determine initial values for data_addr and data_cnt | 4987 | * Determine initial values for data_addr and data_cnt |
4910 | * for resuming the data phase. | 4988 | * for resuming the data phase. |
4911 | */ | 4989 | */ |
4912 | sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24) | 4990 | sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR); |
4913 | | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16) | ||
4914 | | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8) | ||
4915 | | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR); | ||
4916 | sgptr &= SG_PTR_MASK; | 4991 | sgptr &= SG_PTR_MASK; |
4917 | 4992 | ||
4918 | resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16) | 4993 | resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16) |
@@ -4930,10 +5005,7 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd) | |||
4930 | dataptr = ahd_le64toh(sg->addr) | 5005 | dataptr = ahd_le64toh(sg->addr) |
4931 | + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) | 5006 | + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK) |
4932 | - resid; | 5007 | - resid; |
4933 | ahd_outb(ahd, HADDR + 7, dataptr >> 56); | 5008 | ahd_outl(ahd, HADDR + 4, dataptr >> 32); |
4934 | ahd_outb(ahd, HADDR + 6, dataptr >> 48); | ||
4935 | ahd_outb(ahd, HADDR + 5, dataptr >> 40); | ||
4936 | ahd_outb(ahd, HADDR + 4, dataptr >> 32); | ||
4937 | } else { | 5009 | } else { |
4938 | struct ahd_dma_seg *sg; | 5010 | struct ahd_dma_seg *sg; |
4939 | 5011 | ||
@@ -4948,10 +5020,7 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd) | |||
4948 | ahd_outb(ahd, HADDR + 4, | 5020 | ahd_outb(ahd, HADDR + 4, |
4949 | (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24); | 5021 | (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24); |
4950 | } | 5022 | } |
4951 | ahd_outb(ahd, HADDR + 3, dataptr >> 24); | 5023 | ahd_outl(ahd, HADDR, dataptr); |
4952 | ahd_outb(ahd, HADDR + 2, dataptr >> 16); | ||
4953 | ahd_outb(ahd, HADDR + 1, dataptr >> 8); | ||
4954 | ahd_outb(ahd, HADDR, dataptr); | ||
4955 | ahd_outb(ahd, HCNT + 2, resid >> 16); | 5024 | ahd_outb(ahd, HCNT + 2, resid >> 16); |
4956 | ahd_outb(ahd, HCNT + 1, resid >> 8); | 5025 | ahd_outb(ahd, HCNT + 1, resid >> 8); |
4957 | ahd_outb(ahd, HCNT, resid); | 5026 | ahd_outb(ahd, HCNT, resid); |
@@ -5011,13 +5080,14 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
5011 | ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, | 5080 | ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT, |
5012 | AHD_TRANS_CUR, /*paused*/TRUE); | 5081 | AHD_TRANS_CUR, /*paused*/TRUE); |
5013 | ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0, | 5082 | ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0, |
5014 | /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE); | 5083 | /*ppr_options*/0, AHD_TRANS_CUR, |
5084 | /*paused*/TRUE); | ||
5015 | 5085 | ||
5016 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 5086 | if (status != CAM_SEL_TIMEOUT) |
5017 | lun, AC_SENT_BDR, NULL); | 5087 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
5088 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | ||
5018 | 5089 | ||
5019 | if (message != NULL | 5090 | if (message != NULL && bootverbose) |
5020 | && (verbose_level <= bootverbose)) | ||
5021 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), | 5091 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), |
5022 | message, devinfo->channel, devinfo->target, found); | 5092 | message, devinfo->channel, devinfo->target, found); |
5023 | } | 5093 | } |
@@ -5203,13 +5273,13 @@ ahd_free(struct ahd_softc *ahd) | |||
5203 | /* FALLTHROUGH */ | 5273 | /* FALLTHROUGH */ |
5204 | case 4: | 5274 | case 4: |
5205 | ahd_dmamap_unload(ahd, ahd->shared_data_dmat, | 5275 | ahd_dmamap_unload(ahd, ahd->shared_data_dmat, |
5206 | ahd->shared_data_dmamap); | 5276 | ahd->shared_data_map.dmamap); |
5207 | /* FALLTHROUGH */ | 5277 | /* FALLTHROUGH */ |
5208 | case 3: | 5278 | case 3: |
5209 | ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, | 5279 | ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, |
5210 | ahd->shared_data_dmamap); | 5280 | ahd->shared_data_map.dmamap); |
5211 | ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, | 5281 | ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, |
5212 | ahd->shared_data_dmamap); | 5282 | ahd->shared_data_map.dmamap); |
5213 | /* FALLTHROUGH */ | 5283 | /* FALLTHROUGH */ |
5214 | case 2: | 5284 | case 2: |
5215 | ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); | 5285 | ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); |
@@ -5975,16 +6045,13 @@ ahd_alloc_scbs(struct ahd_softc *ahd) | |||
5975 | newcount = MIN(scb_data->sense_left, scb_data->scbs_left); | 6045 | newcount = MIN(scb_data->sense_left, scb_data->scbs_left); |
5976 | newcount = MIN(newcount, scb_data->sgs_left); | 6046 | newcount = MIN(newcount, scb_data->sgs_left); |
5977 | newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); | 6047 | newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); |
5978 | scb_data->sense_left -= newcount; | ||
5979 | scb_data->scbs_left -= newcount; | ||
5980 | scb_data->sgs_left -= newcount; | ||
5981 | for (i = 0; i < newcount; i++) { | 6048 | for (i = 0; i < newcount; i++) { |
5982 | u_int col_tag; | ||
5983 | |||
5984 | struct scb_platform_data *pdata; | 6049 | struct scb_platform_data *pdata; |
6050 | u_int col_tag; | ||
5985 | #ifndef __linux__ | 6051 | #ifndef __linux__ |
5986 | int error; | 6052 | int error; |
5987 | #endif | 6053 | #endif |
6054 | |||
5988 | next_scb = (struct scb *)malloc(sizeof(*next_scb), | 6055 | next_scb = (struct scb *)malloc(sizeof(*next_scb), |
5989 | M_DEVBUF, M_NOWAIT); | 6056 | M_DEVBUF, M_NOWAIT); |
5990 | if (next_scb == NULL) | 6057 | if (next_scb == NULL) |
@@ -6041,6 +6108,9 @@ ahd_alloc_scbs(struct ahd_softc *ahd) | |||
6041 | sense_data += AHD_SENSE_BUFSIZE; | 6108 | sense_data += AHD_SENSE_BUFSIZE; |
6042 | sense_busaddr += AHD_SENSE_BUFSIZE; | 6109 | sense_busaddr += AHD_SENSE_BUFSIZE; |
6043 | scb_data->numscbs++; | 6110 | scb_data->numscbs++; |
6111 | scb_data->sense_left--; | ||
6112 | scb_data->scbs_left--; | ||
6113 | scb_data->sgs_left--; | ||
6044 | } | 6114 | } |
6045 | } | 6115 | } |
6046 | 6116 | ||
@@ -6088,7 +6158,6 @@ static const char *termstat_strings[] = { | |||
6088 | int | 6158 | int |
6089 | ahd_init(struct ahd_softc *ahd) | 6159 | ahd_init(struct ahd_softc *ahd) |
6090 | { | 6160 | { |
6091 | uint8_t *base_vaddr; | ||
6092 | uint8_t *next_vaddr; | 6161 | uint8_t *next_vaddr; |
6093 | dma_addr_t next_baddr; | 6162 | dma_addr_t next_baddr; |
6094 | size_t driver_data_size; | 6163 | size_t driver_data_size; |
@@ -6156,7 +6225,7 @@ ahd_init(struct ahd_softc *ahd) | |||
6156 | * for the target mode role, we must additionally provide space for | 6225 | * for the target mode role, we must additionally provide space for |
6157 | * the incoming target command fifo. | 6226 | * the incoming target command fifo. |
6158 | */ | 6227 | */ |
6159 | driver_data_size = AHD_SCB_MAX * sizeof(uint16_t) | 6228 | driver_data_size = AHD_SCB_MAX * sizeof(*ahd->qoutfifo) |
6160 | + sizeof(struct hardware_scb); | 6229 | + sizeof(struct hardware_scb); |
6161 | if ((ahd->features & AHD_TARGETMODE) != 0) | 6230 | if ((ahd->features & AHD_TARGETMODE) != 0) |
6162 | driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd); | 6231 | driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd); |
@@ -6178,20 +6247,23 @@ ahd_init(struct ahd_softc *ahd) | |||
6178 | 6247 | ||
6179 | /* Allocation of driver data */ | 6248 | /* Allocation of driver data */ |
6180 | if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, | 6249 | if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, |
6181 | (void **)&base_vaddr, | 6250 | (void **)&ahd->shared_data_map.vaddr, |
6182 | BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) { | 6251 | BUS_DMA_NOWAIT, |
6252 | &ahd->shared_data_map.dmamap) != 0) { | ||
6183 | return (ENOMEM); | 6253 | return (ENOMEM); |
6184 | } | 6254 | } |
6185 | 6255 | ||
6186 | ahd->init_level++; | 6256 | ahd->init_level++; |
6187 | 6257 | ||
6188 | /* And permanently map it in */ | 6258 | /* And permanently map it in */ |
6189 | ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, | 6259 | ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, |
6190 | base_vaddr, driver_data_size, ahd_dmamap_cb, | 6260 | ahd->shared_data_map.vaddr, driver_data_size, |
6191 | &ahd->shared_data_busaddr, /*flags*/0); | 6261 | ahd_dmamap_cb, &ahd->shared_data_map.physaddr, |
6192 | ahd->qoutfifo = (uint16_t *)base_vaddr; | 6262 | /*flags*/0); |
6263 | ahd->qoutfifo = (struct ahd_completion *)ahd->shared_data_map.vaddr; | ||
6193 | next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; | 6264 | next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; |
6194 | next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t); | 6265 | next_baddr = ahd->shared_data_map.physaddr |
6266 | + AHD_QOUT_SIZE*sizeof(struct ahd_completion); | ||
6195 | if ((ahd->features & AHD_TARGETMODE) != 0) { | 6267 | if ((ahd->features & AHD_TARGETMODE) != 0) { |
6196 | ahd->targetcmds = (struct target_cmd *)next_vaddr; | 6268 | ahd->targetcmds = (struct target_cmd *)next_vaddr; |
6197 | next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); | 6269 | next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); |
@@ -6212,6 +6284,7 @@ ahd_init(struct ahd_softc *ahd) | |||
6212 | * specially from the DMA safe memory chunk used for the QOUTFIFO. | 6284 | * specially from the DMA safe memory chunk used for the QOUTFIFO. |
6213 | */ | 6285 | */ |
6214 | ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; | 6286 | ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; |
6287 | ahd->next_queued_hscb_map = &ahd->shared_data_map; | ||
6215 | ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr); | 6288 | ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr); |
6216 | 6289 | ||
6217 | ahd->init_level++; | 6290 | ahd->init_level++; |
@@ -6517,10 +6590,10 @@ ahd_chip_init(struct ahd_softc *ahd) | |||
6517 | 6590 | ||
6518 | /* All of our queues are empty */ | 6591 | /* All of our queues are empty */ |
6519 | ahd->qoutfifonext = 0; | 6592 | ahd->qoutfifonext = 0; |
6520 | ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE; | 6593 | ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID; |
6521 | ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8); | 6594 | ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID); |
6522 | for (i = 0; i < AHD_QOUT_SIZE; i++) | 6595 | for (i = 0; i < AHD_QOUT_SIZE; i++) |
6523 | ahd->qoutfifo[i] = 0; | 6596 | ahd->qoutfifo[i].valid_tag = 0; |
6524 | ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD); | 6597 | ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD); |
6525 | 6598 | ||
6526 | ahd->qinfifonext = 0; | 6599 | ahd->qinfifonext = 0; |
@@ -6553,24 +6626,22 @@ ahd_chip_init(struct ahd_softc *ahd) | |||
6553 | ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); | 6626 | ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); |
6554 | ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL); | 6627 | ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL); |
6555 | ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); | 6628 | ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL); |
6629 | ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, SCB_LIST_NULL); | ||
6630 | ahd_outw(ahd, COMPLETE_ON_QFREEZE_HEAD, SCB_LIST_NULL); | ||
6556 | 6631 | ||
6557 | /* | 6632 | /* |
6558 | * The Freeze Count is 0. | 6633 | * The Freeze Count is 0. |
6559 | */ | 6634 | */ |
6635 | ahd->qfreeze_cnt = 0; | ||
6560 | ahd_outw(ahd, QFREEZE_COUNT, 0); | 6636 | ahd_outw(ahd, QFREEZE_COUNT, 0); |
6637 | ahd_outw(ahd, KERNEL_QFREEZE_COUNT, 0); | ||
6561 | 6638 | ||
6562 | /* | 6639 | /* |
6563 | * Tell the sequencer where it can find our arrays in memory. | 6640 | * Tell the sequencer where it can find our arrays in memory. |
6564 | */ | 6641 | */ |
6565 | busaddr = ahd->shared_data_busaddr; | 6642 | busaddr = ahd->shared_data_map.physaddr; |
6566 | ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF); | 6643 | ahd_outl(ahd, SHARED_DATA_ADDR, busaddr); |
6567 | ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF); | 6644 | ahd_outl(ahd, QOUTFIFO_NEXT_ADDR, busaddr); |
6568 | ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF); | ||
6569 | ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF); | ||
6570 | ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF); | ||
6571 | ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF); | ||
6572 | ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF); | ||
6573 | ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF); | ||
6574 | 6645 | ||
6575 | /* | 6646 | /* |
6576 | * Setup the allowed SCSI Sequences based on operational mode. | 6647 | * Setup the allowed SCSI Sequences based on operational mode. |
@@ -6619,10 +6690,7 @@ ahd_chip_init(struct ahd_softc *ahd) | |||
6619 | * Tell the sequencer which SCB will be the next one it receives. | 6690 | * Tell the sequencer which SCB will be the next one it receives. |
6620 | */ | 6691 | */ |
6621 | busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); | 6692 | busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); |
6622 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); | 6693 | ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr); |
6623 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); | ||
6624 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); | ||
6625 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); | ||
6626 | 6694 | ||
6627 | /* | 6695 | /* |
6628 | * Default to coalescing disabled. | 6696 | * Default to coalescing disabled. |
@@ -6926,43 +6994,34 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) | |||
6926 | { | 6994 | { |
6927 | u_int intstat; | 6995 | u_int intstat; |
6928 | u_int maxloops; | 6996 | u_int maxloops; |
6929 | u_int qfreeze_cnt; | ||
6930 | 6997 | ||
6931 | maxloops = 1000; | 6998 | maxloops = 1000; |
6932 | ahd->flags |= AHD_ALL_INTERRUPTS; | 6999 | ahd->flags |= AHD_ALL_INTERRUPTS; |
6933 | ahd_pause(ahd); | 7000 | ahd_pause(ahd); |
6934 | /* | 7001 | /* |
6935 | * Increment the QFreeze Count so that the sequencer | 7002 | * Freeze the outgoing selections. We do this only |
6936 | * will not start new selections. We do this only | ||
6937 | * until we are safely paused without further selections | 7003 | * until we are safely paused without further selections |
6938 | * pending. | 7004 | * pending. |
6939 | */ | 7005 | */ |
6940 | ahd_outw(ahd, QFREEZE_COUNT, ahd_inw(ahd, QFREEZE_COUNT) + 1); | 7006 | ahd->qfreeze_cnt--; |
7007 | ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt); | ||
6941 | ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN); | 7008 | ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN); |
6942 | do { | 7009 | do { |
6943 | struct scb *waiting_scb; | ||
6944 | 7010 | ||
6945 | ahd_unpause(ahd); | 7011 | ahd_unpause(ahd); |
7012 | /* | ||
7013 | * Give the sequencer some time to service | ||
7014 | * any active selections. | ||
7015 | */ | ||
7016 | ahd_delay(500); | ||
7017 | |||
6946 | ahd_intr(ahd); | 7018 | ahd_intr(ahd); |
6947 | ahd_pause(ahd); | 7019 | ahd_pause(ahd); |
6948 | ahd_clear_critical_section(ahd); | ||
6949 | intstat = ahd_inb(ahd, INTSTAT); | 7020 | intstat = ahd_inb(ahd, INTSTAT); |
6950 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); | 7021 | if ((intstat & INT_PEND) == 0) { |
6951 | if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0) | 7022 | ahd_clear_critical_section(ahd); |
6952 | ahd_outb(ahd, SCSISEQ0, | 7023 | intstat = ahd_inb(ahd, INTSTAT); |
6953 | ahd_inb(ahd, SCSISEQ0) & ~ENSELO); | 7024 | } |
6954 | /* | ||
6955 | * In the non-packetized case, the sequencer (for Rev A), | ||
6956 | * relies on ENSELO remaining set after SELDO. The hardware | ||
6957 | * auto-clears ENSELO in the packetized case. | ||
6958 | */ | ||
6959 | waiting_scb = ahd_lookup_scb(ahd, | ||
6960 | ahd_inw(ahd, WAITING_TID_HEAD)); | ||
6961 | if (waiting_scb != NULL | ||
6962 | && (waiting_scb->flags & SCB_PACKETIZED) == 0 | ||
6963 | && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0) | ||
6964 | ahd_outb(ahd, SCSISEQ0, | ||
6965 | ahd_inb(ahd, SCSISEQ0) | ENSELO); | ||
6966 | } while (--maxloops | 7025 | } while (--maxloops |
6967 | && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0) | 7026 | && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0) |
6968 | && ((intstat & INT_PEND) != 0 | 7027 | && ((intstat & INT_PEND) != 0 |
@@ -6973,17 +7032,8 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) | |||
6973 | printf("Infinite interrupt loop, INTSTAT = %x", | 7032 | printf("Infinite interrupt loop, INTSTAT = %x", |
6974 | ahd_inb(ahd, INTSTAT)); | 7033 | ahd_inb(ahd, INTSTAT)); |
6975 | } | 7034 | } |
6976 | qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT); | 7035 | ahd->qfreeze_cnt++; |
6977 | if (qfreeze_cnt == 0) { | 7036 | ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt); |
6978 | printf("%s: ahd_pause_and_flushwork with 0 qfreeze count!\n", | ||
6979 | ahd_name(ahd)); | ||
6980 | } else { | ||
6981 | qfreeze_cnt--; | ||
6982 | } | ||
6983 | ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt); | ||
6984 | if (qfreeze_cnt == 0) | ||
6985 | ahd_outb(ahd, SEQ_FLAGS2, | ||
6986 | ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN); | ||
6987 | 7037 | ||
6988 | ahd_flush_qoutfifo(ahd); | 7038 | ahd_flush_qoutfifo(ahd); |
6989 | 7039 | ||
@@ -7155,10 +7205,7 @@ ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb, | |||
7155 | uint32_t busaddr; | 7205 | uint32_t busaddr; |
7156 | 7206 | ||
7157 | busaddr = ahd_le32toh(scb->hscb->hscb_busaddr); | 7207 | busaddr = ahd_le32toh(scb->hscb->hscb_busaddr); |
7158 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); | 7208 | ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr); |
7159 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); | ||
7160 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); | ||
7161 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); | ||
7162 | } else { | 7209 | } else { |
7163 | prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; | 7210 | prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; |
7164 | ahd_sync_scb(ahd, prev_scb, | 7211 | ahd_sync_scb(ahd, prev_scb, |
@@ -7265,10 +7312,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, | |||
7265 | */ | 7312 | */ |
7266 | ahd->qinfifonext = qinstart; | 7313 | ahd->qinfifonext = qinstart; |
7267 | busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); | 7314 | busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr); |
7268 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF); | 7315 | ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr); |
7269 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF); | ||
7270 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF); | ||
7271 | ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF); | ||
7272 | 7316 | ||
7273 | while (qinpos != qintail) { | 7317 | while (qinpos != qintail) { |
7274 | scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]); | 7318 | scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]); |
@@ -7330,6 +7374,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel, | |||
7330 | * appropriate, traverse the SCBs of each "their id" | 7374 | * appropriate, traverse the SCBs of each "their id" |
7331 | * looking for matches. | 7375 | * looking for matches. |
7332 | */ | 7376 | */ |
7377 | ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); | ||
7333 | savedscbptr = ahd_get_scbptr(ahd); | 7378 | savedscbptr = ahd_get_scbptr(ahd); |
7334 | tid_next = ahd_inw(ahd, WAITING_TID_HEAD); | 7379 | tid_next = ahd_inw(ahd, WAITING_TID_HEAD); |
7335 | tid_prev = SCB_LIST_NULL; | 7380 | tid_prev = SCB_LIST_NULL; |
@@ -7399,7 +7444,7 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel, | |||
7399 | u_int prev; | 7444 | u_int prev; |
7400 | int found; | 7445 | int found; |
7401 | 7446 | ||
7402 | AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); | 7447 | AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); |
7403 | found = 0; | 7448 | found = 0; |
7404 | prev = SCB_LIST_NULL; | 7449 | prev = SCB_LIST_NULL; |
7405 | next = *list_head; | 7450 | next = *list_head; |
@@ -7466,7 +7511,7 @@ static void | |||
7466 | ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev, | 7511 | ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev, |
7467 | u_int tid_cur, u_int tid_next) | 7512 | u_int tid_cur, u_int tid_next) |
7468 | { | 7513 | { |
7469 | AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); | 7514 | AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); |
7470 | 7515 | ||
7471 | if (SCBID_IS_NULL(tid_cur)) { | 7516 | if (SCBID_IS_NULL(tid_cur)) { |
7472 | 7517 | ||
@@ -7506,7 +7551,7 @@ ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid, | |||
7506 | { | 7551 | { |
7507 | u_int tail_offset; | 7552 | u_int tail_offset; |
7508 | 7553 | ||
7509 | AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); | 7554 | AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); |
7510 | if (!SCBID_IS_NULL(prev)) { | 7555 | if (!SCBID_IS_NULL(prev)) { |
7511 | ahd_set_scbptr(ahd, prev); | 7556 | ahd_set_scbptr(ahd, prev); |
7512 | ahd_outw(ahd, SCB_NEXT, next); | 7557 | ahd_outw(ahd, SCB_NEXT, next); |
@@ -7739,7 +7784,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7739 | */ | 7784 | */ |
7740 | ahd_clear_msg_state(ahd); | 7785 | ahd_clear_msg_state(ahd); |
7741 | ahd_outb(ahd, SIMODE1, | 7786 | ahd_outb(ahd, SIMODE1, |
7742 | ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE)); | 7787 | ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST)); |
7743 | 7788 | ||
7744 | if (initiate_reset) | 7789 | if (initiate_reset) |
7745 | ahd_reset_current_bus(ahd); | 7790 | ahd_reset_current_bus(ahd); |
@@ -7910,30 +7955,35 @@ ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) | |||
7910 | void | 7955 | void |
7911 | ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) | 7956 | ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) |
7912 | { | 7957 | { |
7913 | struct hardware_scb *hscb; | 7958 | struct hardware_scb *hscb; |
7914 | u_int qfreeze_cnt; | 7959 | int paused; |
7915 | 7960 | ||
7916 | /* | 7961 | /* |
7917 | * The sequencer freezes its select-out queue | 7962 | * The sequencer freezes its select-out queue |
7918 | * anytime a SCSI status error occurs. We must | 7963 | * anytime a SCSI status error occurs. We must |
7919 | * handle the error and decrement the QFREEZE count | 7964 | * handle the error and increment our qfreeze count |
7920 | * to allow the sequencer to continue. | 7965 | * to allow the sequencer to continue. We don't |
7966 | * bother clearing critical sections here since all | ||
7967 | * operations are on data structures that the sequencer | ||
7968 | * is not touching once the queue is frozen. | ||
7921 | */ | 7969 | */ |
7922 | hscb = scb->hscb; | 7970 | hscb = scb->hscb; |
7923 | 7971 | ||
7972 | if (ahd_is_paused(ahd)) { | ||
7973 | paused = 1; | ||
7974 | } else { | ||
7975 | paused = 0; | ||
7976 | ahd_pause(ahd); | ||
7977 | } | ||
7978 | |||
7924 | /* Freeze the queue until the client sees the error. */ | 7979 | /* Freeze the queue until the client sees the error. */ |
7925 | ahd_freeze_devq(ahd, scb); | 7980 | ahd_freeze_devq(ahd, scb); |
7926 | ahd_freeze_scb(scb); | 7981 | ahd_freeze_scb(scb); |
7927 | qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT); | 7982 | ahd->qfreeze_cnt++; |
7928 | if (qfreeze_cnt == 0) { | 7983 | ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt); |
7929 | printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd)); | 7984 | |
7930 | } else { | 7985 | if (paused == 0) |
7931 | qfreeze_cnt--; | 7986 | ahd_unpause(ahd); |
7932 | ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt); | ||
7933 | } | ||
7934 | if (qfreeze_cnt == 0) | ||
7935 | ahd_outb(ahd, SEQ_FLAGS2, | ||
7936 | ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN); | ||
7937 | 7987 | ||
7938 | /* Don't want to clobber the original sense code */ | 7988 | /* Don't want to clobber the original sense code */ |
7939 | if ((scb->flags & SCB_SENSE) != 0) { | 7989 | if ((scb->flags & SCB_SENSE) != 0) { |
@@ -8317,8 +8367,7 @@ ahd_dumpseq(struct ahd_softc* ahd) | |||
8317 | max_prog = 2048; | 8367 | max_prog = 2048; |
8318 | 8368 | ||
8319 | ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); | 8369 | ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); |
8320 | ahd_outb(ahd, PRGMCNT, 0); | 8370 | ahd_outw(ahd, PRGMCNT, 0); |
8321 | ahd_outb(ahd, PRGMCNT+1, 0); | ||
8322 | for (i = 0; i < max_prog; i++) { | 8371 | for (i = 0; i < max_prog; i++) { |
8323 | uint8_t ins_bytes[4]; | 8372 | uint8_t ins_bytes[4]; |
8324 | 8373 | ||
@@ -8347,13 +8396,14 @@ ahd_loadseq(struct ahd_softc *ahd) | |||
8347 | u_int sg_prefetch_cnt_limit; | 8396 | u_int sg_prefetch_cnt_limit; |
8348 | u_int sg_prefetch_align; | 8397 | u_int sg_prefetch_align; |
8349 | u_int sg_size; | 8398 | u_int sg_size; |
8399 | u_int cacheline_mask; | ||
8350 | uint8_t download_consts[DOWNLOAD_CONST_COUNT]; | 8400 | uint8_t download_consts[DOWNLOAD_CONST_COUNT]; |
8351 | 8401 | ||
8352 | if (bootverbose) | 8402 | if (bootverbose) |
8353 | printf("%s: Downloading Sequencer Program...", | 8403 | printf("%s: Downloading Sequencer Program...", |
8354 | ahd_name(ahd)); | 8404 | ahd_name(ahd)); |
8355 | 8405 | ||
8356 | #if DOWNLOAD_CONST_COUNT != 7 | 8406 | #if DOWNLOAD_CONST_COUNT != 8 |
8357 | #error "Download Const Mismatch" | 8407 | #error "Download Const Mismatch" |
8358 | #endif | 8408 | #endif |
8359 | /* | 8409 | /* |
@@ -8389,6 +8439,9 @@ ahd_loadseq(struct ahd_softc *ahd) | |||
8389 | /* Round down to the nearest power of 2. */ | 8439 | /* Round down to the nearest power of 2. */ |
8390 | while (powerof2(sg_prefetch_align) == 0) | 8440 | while (powerof2(sg_prefetch_align) == 0) |
8391 | sg_prefetch_align--; | 8441 | sg_prefetch_align--; |
8442 | |||
8443 | cacheline_mask = sg_prefetch_align - 1; | ||
8444 | |||
8392 | /* | 8445 | /* |
8393 | * If the cacheline boundary is greater than half our prefetch RAM | 8446 | * If the cacheline boundary is greater than half our prefetch RAM |
8394 | * we risk not being able to fetch even a single complete S/G | 8447 | * we risk not being able to fetch even a single complete S/G |
@@ -8429,12 +8482,12 @@ ahd_loadseq(struct ahd_softc *ahd) | |||
8429 | download_consts[PKT_OVERRUN_BUFOFFSET] = | 8482 | download_consts[PKT_OVERRUN_BUFOFFSET] = |
8430 | (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256; | 8483 | (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256; |
8431 | download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN; | 8484 | download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN; |
8485 | download_consts[CACHELINE_MASK] = cacheline_mask; | ||
8432 | cur_patch = patches; | 8486 | cur_patch = patches; |
8433 | downloaded = 0; | 8487 | downloaded = 0; |
8434 | skip_addr = 0; | 8488 | skip_addr = 0; |
8435 | ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); | 8489 | ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); |
8436 | ahd_outb(ahd, PRGMCNT, 0); | 8490 | ahd_outw(ahd, PRGMCNT, 0); |
8437 | ahd_outb(ahd, PRGMCNT+1, 0); | ||
8438 | 8491 | ||
8439 | for (i = 0; i < sizeof(seqprog)/4; i++) { | 8492 | for (i = 0; i < sizeof(seqprog)/4; i++) { |
8440 | if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) { | 8493 | if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) { |
@@ -8727,7 +8780,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) | |||
8727 | printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" | 8780 | printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" |
8728 | "%s: Dumping Card State at program address 0x%x Mode 0x%x\n", | 8781 | "%s: Dumping Card State at program address 0x%x Mode 0x%x\n", |
8729 | ahd_name(ahd), | 8782 | ahd_name(ahd), |
8730 | ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8), | 8783 | ahd_inw(ahd, CURADDR), |
8731 | ahd_build_mode_state(ahd, ahd->saved_src_mode, | 8784 | ahd_build_mode_state(ahd, ahd->saved_src_mode, |
8732 | ahd->saved_dst_mode)); | 8785 | ahd->saved_dst_mode)); |
8733 | if (paused) | 8786 | if (paused) |
@@ -8843,6 +8896,15 @@ ahd_dump_card_state(struct ahd_softc *ahd) | |||
8843 | scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE); | 8896 | scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE); |
8844 | } | 8897 | } |
8845 | printf("\n"); | 8898 | printf("\n"); |
8899 | printf("Sequencer On QFreeze and Complete list: "); | ||
8900 | scb_index = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD); | ||
8901 | i = 0; | ||
8902 | while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) { | ||
8903 | ahd_set_scbptr(ahd, scb_index); | ||
8904 | printf("%d ", scb_index); | ||
8905 | scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE); | ||
8906 | } | ||
8907 | printf("\n"); | ||
8846 | ahd_set_scbptr(ahd, saved_scb_index); | 8908 | ahd_set_scbptr(ahd, saved_scb_index); |
8847 | dffstat = ahd_inb(ahd, DFFSTAT); | 8909 | dffstat = ahd_inb(ahd, DFFSTAT); |
8848 | for (i = 0; i < 2; i++) { | 8910 | for (i = 0; i < 2; i++) { |
@@ -9077,7 +9139,7 @@ ahd_wait_seeprom(struct ahd_softc *ahd) | |||
9077 | { | 9139 | { |
9078 | int cnt; | 9140 | int cnt; |
9079 | 9141 | ||
9080 | cnt = 20; | 9142 | cnt = 5000; |
9081 | while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt) | 9143 | while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt) |
9082 | ahd_delay(5); | 9144 | ahd_delay(5); |
9083 | 9145 | ||
@@ -9423,13 +9485,9 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) | |||
9423 | if ((ahd->features & AHD_MULTI_TID) != 0) { | 9485 | if ((ahd->features & AHD_MULTI_TID) != 0) { |
9424 | u_int targid_mask; | 9486 | u_int targid_mask; |
9425 | 9487 | ||
9426 | targid_mask = ahd_inb(ahd, TARGID) | 9488 | targid_mask = ahd_inw(ahd, TARGID); |
9427 | | (ahd_inb(ahd, TARGID + 1) << 8); | ||
9428 | |||
9429 | targid_mask |= target_mask; | 9489 | targid_mask |= target_mask; |
9430 | ahd_outb(ahd, TARGID, targid_mask); | 9490 | ahd_outw(ahd, TARGID, targid_mask); |
9431 | ahd_outb(ahd, TARGID+1, (targid_mask >> 8)); | ||
9432 | |||
9433 | ahd_update_scsiid(ahd, targid_mask); | 9491 | ahd_update_scsiid(ahd, targid_mask); |
9434 | } else { | 9492 | } else { |
9435 | u_int our_id; | 9493 | u_int our_id; |
@@ -9543,14 +9601,9 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) | |||
9543 | if (ahd->features & AHD_MULTI_TID) { | 9601 | if (ahd->features & AHD_MULTI_TID) { |
9544 | u_int targid_mask; | 9602 | u_int targid_mask; |
9545 | 9603 | ||
9546 | targid_mask = ahd_inb(ahd, TARGID) | 9604 | targid_mask = ahd_inw(ahd, TARGID); |
9547 | | (ahd_inb(ahd, TARGID + 1) | ||
9548 | << 8); | ||
9549 | |||
9550 | targid_mask &= ~target_mask; | 9605 | targid_mask &= ~target_mask; |
9551 | ahd_outb(ahd, TARGID, targid_mask); | 9606 | ahd_outw(ahd, TARGID, targid_mask); |
9552 | ahd_outb(ahd, TARGID+1, | ||
9553 | (targid_mask >> 8)); | ||
9554 | ahd_update_scsiid(ahd, targid_mask); | 9607 | ahd_update_scsiid(ahd, targid_mask); |
9555 | } | 9608 | } |
9556 | } | 9609 | } |
@@ -9651,7 +9704,7 @@ ahd_run_tqinfifo(struct ahd_softc *ahd, int paused) | |||
9651 | 9704 | ||
9652 | cmd->cmd_valid = 0; | 9705 | cmd->cmd_valid = 0; |
9653 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, | 9706 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, |
9654 | ahd->shared_data_dmamap, | 9707 | ahd->shared_data_map.dmamap, |
9655 | ahd_targetcmd_offset(ahd, ahd->tqinfifonext), | 9708 | ahd_targetcmd_offset(ahd, ahd->tqinfifonext), |
9656 | sizeof(struct target_cmd), | 9709 | sizeof(struct target_cmd), |
9657 | BUS_DMASYNC_PREREAD); | 9710 | BUS_DMASYNC_PREREAD); |