Deleted Added
full compact
aic7xxx.c (70807) aic7xxx.c (71390)
1/*
2 * Core routines and tables shareable across OS platforms.
3 *
4 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000 Justin T. Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 14 unchanged lines hidden (view full) ---

23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
1/*
2 * Core routines and tables shareable across OS platforms.
3 *
4 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000 Justin T. Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 14 unchanged lines hidden (view full) ---

23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: //depot/src/aic7xxx/aic7xxx.c#21 $
31 * $Id: //depot/src/aic7xxx/aic7xxx.c#24 $
32 *
32 *
33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx.c 70807 2001-01-09 00:40:38Z gibbs $
33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx.c 71390 2001-01-22 21:03:48Z gibbs $
34 */
35
36#ifdef __linux__
37#include "aic7xxx_linux.h"
38#include "aic7xxx_inline.h"
39#include "aicasm/aicasm_insformat.h"
40#endif
41

--- 181 unchanged lines hidden (view full) ---

223#endif
224/************************* Sequencer Execution Control ************************/
225/*
226 * Restart the sequencer program from address zero
227 */
228void
229restart_sequencer(struct ahc_softc *ahc)
230{
34 */
35
36#ifdef __linux__
37#include "aic7xxx_linux.h"
38#include "aic7xxx_inline.h"
39#include "aicasm/aicasm_insformat.h"
40#endif
41

--- 181 unchanged lines hidden (view full) ---

223#endif
224/************************* Sequencer Execution Control ************************/
225/*
226 * Restart the sequencer program from address zero
227 */
228void
229restart_sequencer(struct ahc_softc *ahc)
230{
231 uint16_t stack[4];
232
233 pause_sequencer(ahc);
234 ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */
235 ahc_outb(ahc, MSG_OUT, MSG_NOOP); /* No message to send */
236 ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
237
238 /*
239 * Ensure that the sequencer's idea of TQINPOS

--- 9 unchanged lines hidden (view full) ---

249 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
250 if ((ahc->features & AHC_CMD_CHAN) != 0) {
251 /* Ensure that no DMA operations are in progress */
252 ahc_outb(ahc, CCSCBCNT, 0);
253 ahc_outb(ahc, CCSGCTL, 0);
254 ahc_outb(ahc, CCSCBCTL, 0);
255 }
256 ahc_outb(ahc, MWI_RESIDUAL, 0);
231
232 pause_sequencer(ahc);
233 ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */
234 ahc_outb(ahc, MSG_OUT, MSG_NOOP); /* No message to send */
235 ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
236
237 /*
238 * Ensure that the sequencer's idea of TQINPOS

--- 9 unchanged lines hidden (view full) ---

248 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
249 if ((ahc->features & AHC_CMD_CHAN) != 0) {
250 /* Ensure that no DMA operations are in progress */
251 ahc_outb(ahc, CCSCBCNT, 0);
252 ahc_outb(ahc, CCSGCTL, 0);
253 ahc_outb(ahc, CCSCBCTL, 0);
254 }
255 ahc_outb(ahc, MWI_RESIDUAL, 0);
257 /*
258 * Avoid stack pointer lockup on aic7895 chips where SEQADDR0
259 * cannot be changed without first writing to SEQADDR1. This
260 * seems to only happen if an interrupt or pause occurs mid
261 * update of the stack pointer (i.e. during a ret).
262 */
263 stack[0] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8);
264 stack[1] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8);
265 stack[2] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8);
266 stack[3] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8);
267 if (stack[0] == stack[1]
268 && stack[1] == stack[2]
269 && stack[2] == stack[3]
270 && stack[0] != 0)
271 ahc_outb(ahc, SEQADDR1, 0);
272 ahc_outb(ahc, SEQCTL, FASTMODE);
273 ahc_outb(ahc, SEQADDR0, 0);
274 ahc_outb(ahc, SEQADDR1, 0);
275 unpause_sequencer(ahc);
276}
277
278/************************* Input/Output Queues ********************************/
279void

--- 295 unchanged lines hidden (view full) ---

575 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
576 ahc_inb(ahc, SAVED_LUN))),
577 ahc_inb(ahc, SINDEX));
578 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
579 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
580 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
581 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
582 ahc_inb(ahc, SCB_CONTROL));
256 ahc_outb(ahc, SEQCTL, FASTMODE);
257 ahc_outb(ahc, SEQADDR0, 0);
258 ahc_outb(ahc, SEQADDR1, 0);
259 unpause_sequencer(ahc);
260}
261
262/************************* Input/Output Queues ********************************/
263void

--- 295 unchanged lines hidden (view full) ---

559 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
560 ahc_inb(ahc, SAVED_LUN))),
561 ahc_inb(ahc, SINDEX));
562 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
563 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
564 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
565 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
566 ahc_inb(ahc, SCB_CONTROL));
567 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
568 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
569 printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
570 printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
583 ahc_dump_card_state(ahc);
584 ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
585 ahc->msgout_len = 1;
586 ahc->msgout_index = 0;
587 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
588 ahc_outb(ahc, MSG_OUT, HOST_MSG);
589 ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, LASTPHASE) | ATNO);
590 break;

--- 214 unchanged lines hidden (view full) ---

805 */
806 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
807 SCB_GET_CHANNEL(ahc, scb),
808 SCB_GET_LUN(scb), scb->hscb->tag,
809 ROLE_INITIATOR, /*status*/0,
810 SEARCH_REMOVE);
811 break;
812 }
571 ahc_dump_card_state(ahc);
572 ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
573 ahc->msgout_len = 1;
574 ahc->msgout_index = 0;
575 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
576 ahc_outb(ahc, MSG_OUT, HOST_MSG);
577 ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, LASTPHASE) | ATNO);
578 break;

--- 214 unchanged lines hidden (view full) ---

793 */
794 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
795 SCB_GET_CHANNEL(ahc, scb),
796 SCB_GET_LUN(scb), scb->hscb->tag,
797 ROLE_INITIATOR, /*status*/0,
798 SEARCH_REMOVE);
799 break;
800 }
813 case ABORT_QINSCB:
814 {
815 printf("%s: Abort QINSCB\n", ahc_name(ahc));
816 break;
817 }
818 case NO_FREE_SCB:
819 {
820 printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
821 ahc_dump_card_state(ahc);
822 panic("for safety");
823 break;
824 }
825 case SCB_MISMATCH:

--- 23 unchanged lines hidden (view full) ---

849 ahc_inb(ahc, SAVED_LUN))),
850 ahc_inb(ahc, SINDEX),
851 ahc_inb(ahc, ACCUM));
852 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
853 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
854 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
855 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
856 ahc_inb(ahc, SCB_CONTROL));
801 case NO_FREE_SCB:
802 {
803 printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
804 ahc_dump_card_state(ahc);
805 panic("for safety");
806 break;
807 }
808 case SCB_MISMATCH:

--- 23 unchanged lines hidden (view full) ---

832 ahc_inb(ahc, SAVED_LUN))),
833 ahc_inb(ahc, SINDEX),
834 ahc_inb(ahc, ACCUM));
835 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
836 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
837 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
838 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
839 ahc_inb(ahc, SCB_CONTROL));
840 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
841 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
842 ahc_dump_card_state(ahc);
857 panic("for safety");
858 break;
859 }
860 default:
861 printf("ahc_intr: seqint, "
862 "intstat == 0x%x, scsisigi = 0x%x\n",
863 intstat, ahc_inb(ahc, SCSISIGI));
864 break;

--- 2163 unchanged lines hidden (view full) ---

3028 /*type*/MSG_SIMPLE_Q_TAG);
3029 ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
3030 ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, SCSISIGO) | ATNO);
3031
3032 /*
3033 * This transaction is now at the head of
3034 * the untagged queue for this target.
3035 */
843 panic("for safety");
844 break;
845 }
846 default:
847 printf("ahc_intr: seqint, "
848 "intstat == 0x%x, scsisigi = 0x%x\n",
849 intstat, ahc_inb(ahc, SCSISIGI));
850 break;

--- 2163 unchanged lines hidden (view full) ---

3014 /*type*/MSG_SIMPLE_Q_TAG);
3015 ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
3016 ahc_outb(ahc, SCSISIGO, ahc_inb(ahc, SCSISIGO) | ATNO);
3017
3018 /*
3019 * This transaction is now at the head of
3020 * the untagged queue for this target.
3021 */
3036 if ((ahc->features & AHC_SCB_BTT) == 0) {
3022 if ((ahc->flags & AHC_SCB_BTT) == 0) {
3037 struct scb_tailq *untagged_q;
3038
3039 untagged_q = &(ahc->untagged_queues[devinfo->target]);
3040 TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
3041 scb->flags |= SCB_UNTAGGEDQ;
3042 }
3043 ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
3044 scb->hscb->tag);

--- 1006 unchanged lines hidden (view full) ---

4051
4052 /* And permanently map it in */
4053 ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
4054 ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
4055 &ahc->shared_data_busaddr, /*flags*/0);
4056
4057 if ((ahc->features & AHC_TARGETMODE) != 0) {
4058 ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
3023 struct scb_tailq *untagged_q;
3024
3025 untagged_q = &(ahc->untagged_queues[devinfo->target]);
3026 TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
3027 scb->flags |= SCB_UNTAGGEDQ;
3028 }
3029 ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
3030 scb->hscb->tag);

--- 1006 unchanged lines hidden (view full) ---

4037
4038 /* And permanently map it in */
4039 ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
4040 ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
4041 &ahc->shared_data_busaddr, /*flags*/0);
4042
4043 if ((ahc->features & AHC_TARGETMODE) != 0) {
4044 ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
4059 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
4045 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
4060 ahc->dma_bug_buf = ahc->shared_data_busaddr
4061 + driver_data_size - 1;
4062 /* All target command blocks start out invalid. */
4063 for (i = 0; i < AHC_TMODE_CMDS; i++)
4064 ahc->targetcmds[i].cmd_valid = 0;
4065 ahc->tqinfifonext = 1;
4066 ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
4067 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);

--- 214 unchanged lines hidden (view full) ---

4282 tstate->tagenable = 0; /* Wait until the XPT says its okay */
4283 }
4284 ahc->user_discenable = discenable;
4285 ahc->user_tagenable = tagenable;
4286
4287 /* There are no untagged SCBs active yet. */
4288 for (i = 0; i < 16; i++) {
4289 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
4046 ahc->dma_bug_buf = ahc->shared_data_busaddr
4047 + driver_data_size - 1;
4048 /* All target command blocks start out invalid. */
4049 for (i = 0; i < AHC_TMODE_CMDS; i++)
4050 ahc->targetcmds[i].cmd_valid = 0;
4051 ahc->tqinfifonext = 1;
4052 ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
4053 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);

--- 214 unchanged lines hidden (view full) ---

4268 tstate->tagenable = 0; /* Wait until the XPT says its okay */
4269 }
4270 ahc->user_discenable = discenable;
4271 ahc->user_tagenable = tagenable;
4272
4273 /* There are no untagged SCBs active yet. */
4274 for (i = 0; i < 16; i++) {
4275 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
4290 if ((ahc->features & AHC_SCB_BTT) != 0) {
4276 if ((ahc->flags & AHC_SCB_BTT) != 0) {
4291 int lun;
4292
4293 /*
4294 * The SCB based BTT allows an entry per
4295 * target and lun pair.
4296 */
4297 for (lun = 1; lun < AHC_NUM_LUNS; lun++)
4298 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));

--- 116 unchanged lines hidden (view full) ---

4415 * outside of all critical sections and that all
4416 * pending work is completed prior to returning.
4417 * This routine should only be called from outside
4418 * an interrupt context.
4419 */
4420void
4421ahc_pause_and_flushwork(struct ahc_softc *ahc)
4422{
4277 int lun;
4278
4279 /*
4280 * The SCB based BTT allows an entry per
4281 * target and lun pair.
4282 */
4283 for (lun = 1; lun < AHC_NUM_LUNS; lun++)
4284 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));

--- 116 unchanged lines hidden (view full) ---

4401 * outside of all critical sections and that all
4402 * pending work is completed prior to returning.
4403 * This routine should only be called from outside
4404 * an interrupt context.
4405 */
4406void
4407ahc_pause_and_flushwork(struct ahc_softc *ahc)
4408{
4409 int intstat;
4410 int maxloops;
4411
4412 maxloops = 1000;
4423 ahc->flags |= AHC_ALL_INTERRUPTS;
4413 ahc->flags |= AHC_ALL_INTERRUPTS;
4414 intstat = 0;
4424 do {
4425 ahc_intr(ahc);
4426 pause_sequencer(ahc);
4427 ahc_clear_critical_section(ahc);
4415 do {
4416 ahc_intr(ahc);
4417 pause_sequencer(ahc);
4418 ahc_clear_critical_section(ahc);
4428 } while (ahc_inb(ahc, INTSTAT) & INT_PEND);
4419 if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)
4420 break;
4421 maxloops--;
4422 } while (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) && --maxloops);
4423 if (maxloops == 0) {
4424 printf("Infinite interrupt loop, INTSTAT = %x",
4425 ahc_inb(ahc, INTSTAT));
4426 }
4429 ahc_platform_flushwork(ahc);
4430 ahc->flags &= ~AHC_ALL_INTERRUPTS;
4431}
4432
4433int
4434ahc_suspend(struct ahc_softc *ahc)
4435{
4436 uint8_t *ptr;

--- 168 unchanged lines hidden (view full) ---

4605 * Optionally, clear the entry.
4606 */
4607u_int
4608ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
4609{
4610 u_int scbid;
4611 u_int target_offset;
4612
4427 ahc_platform_flushwork(ahc);
4428 ahc->flags &= ~AHC_ALL_INTERRUPTS;
4429}
4430
4431int
4432ahc_suspend(struct ahc_softc *ahc)
4433{
4434 uint8_t *ptr;

--- 168 unchanged lines hidden (view full) ---

4603 * Optionally, clear the entry.
4604 */
4605u_int
4606ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
4607{
4608 u_int scbid;
4609 u_int target_offset;
4610
4613 if ((ahc->features & AHC_SCB_BTT) != 0) {
4611 if ((ahc->flags & AHC_SCB_BTT) != 0) {
4614 u_int saved_scbptr;
4615
4616 saved_scbptr = ahc_inb(ahc, SCBPTR);
4617 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
4618 scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
4619 ahc_outb(ahc, SCBPTR, saved_scbptr);
4620 } else {
4621 target_offset = TCL_TARGET_OFFSET(tcl);
4622 scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
4623 }
4624
4625 return (scbid);
4626}
4627
4628void
4629ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
4630{
4631 u_int target_offset;
4632
4612 u_int saved_scbptr;
4613
4614 saved_scbptr = ahc_inb(ahc, SCBPTR);
4615 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
4616 scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
4617 ahc_outb(ahc, SCBPTR, saved_scbptr);
4618 } else {
4619 target_offset = TCL_TARGET_OFFSET(tcl);
4620 scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
4621 }
4622
4623 return (scbid);
4624}
4625
4626void
4627ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
4628{
4629 u_int target_offset;
4630
4633 if ((ahc->features & AHC_SCB_BTT) != 0) {
4631 if ((ahc->flags & AHC_SCB_BTT) != 0) {
4634 u_int saved_scbptr;
4635
4636 saved_scbptr = ahc_inb(ahc, SCBPTR);
4637 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
4638 ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
4639 ahc_outb(ahc, SCBPTR, saved_scbptr);
4640 } else {
4641 target_offset = TCL_TARGET_OFFSET(tcl);
4642 ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
4643 }
4644}
4645
4646void
4647ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
4648{
4649 u_int target_offset;
4650
4632 u_int saved_scbptr;
4633
4634 saved_scbptr = ahc_inb(ahc, SCBPTR);
4635 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
4636 ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
4637 ahc_outb(ahc, SCBPTR, saved_scbptr);
4638 } else {
4639 target_offset = TCL_TARGET_OFFSET(tcl);
4640 ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
4641 }
4642}
4643
4644void
4645ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
4646{
4647 u_int target_offset;
4648
4651 if ((ahc->features & AHC_SCB_BTT) != 0) {
4649 if ((ahc->flags & AHC_SCB_BTT) != 0) {
4652 u_int saved_scbptr;
4653
4654 saved_scbptr = ahc_inb(ahc, SCBPTR);
4655 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
4656 ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
4657 ahc_outb(ahc, SCBPTR, saved_scbptr);
4658 } else {
4659 target_offset = TCL_TARGET_OFFSET(tcl);

--- 125 unchanged lines hidden (view full) ---

4785 qintail = ahc->qinfifonext;
4786 have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
4787 if (have_qregs) {
4788 qinstart = ahc_inb(ahc, SNSCB_QOFF);
4789 ahc_outb(ahc, SNSCB_QOFF, qinstart);
4790 } else
4791 qinstart = ahc_inb(ahc, QINPOS);
4792 qinpos = qinstart;
4650 u_int saved_scbptr;
4651
4652 saved_scbptr = ahc_inb(ahc, SCBPTR);
4653 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
4654 ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
4655 ahc_outb(ahc, SCBPTR, saved_scbptr);
4656 } else {
4657 target_offset = TCL_TARGET_OFFSET(tcl);

--- 125 unchanged lines hidden (view full) ---

4783 qintail = ahc->qinfifonext;
4784 have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
4785 if (have_qregs) {
4786 qinstart = ahc_inb(ahc, SNSCB_QOFF);
4787 ahc_outb(ahc, SNSCB_QOFF, qinstart);
4788 } else
4789 qinstart = ahc_inb(ahc, QINPOS);
4790 qinpos = qinstart;
4793
4794 next = ahc_inb(ahc, NEXT_QUEUED_SCB);
4791 next = ahc_inb(ahc, NEXT_QUEUED_SCB);
4795 if (qinstart == qintail) {
4796 if (next != ahc->next_queued_scb->hscb->tag)
4797 qinpos--;
4798 } else if (next != ahc->qinfifo[qinstart]) {
4799 qinpos--;
4800 }
4801
4802 found = 0;
4803 prev_scb = NULL;
4804
4805 if (action == SEARCH_COMPLETE) {
4806 /*
4807 * Don't attempt to run any queued untagged transactions
4808 * until we are done with the abort process.
4809 */
4810 ahc_freeze_untagged_queues(ahc);
4811 }
4812
4792 found = 0;
4793 prev_scb = NULL;
4794
4795 if (action == SEARCH_COMPLETE) {
4796 /*
4797 * Don't attempt to run any queued untagged transactions
4798 * until we are done with the abort process.
4799 */
4800 ahc_freeze_untagged_queues(ahc);
4801 }
4802
4813 if (action != SEARCH_COUNT && (qinpos != qintail)) {
4814 /*
4815 * The sequencer may be in the process of dmaing
4816 * down the SCB at the beginning of the queue.
4817 * This could be problematic if either the first
4818 * or the second SCB is removed from the queue
4819 * (the first SCB includes a pointer to the "next"
4820 * SCB to dma). If we have the prospect of removing
4821 * any entries, swap the first element in the queue
4822 * with the next HSCB so the sequencer will notice
4823 * that NEXT_QUEUED_SCB has changed during its dma
4824 * attempt and will retry the DMA.
4825 */
4826 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
4827 ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
4828 ahc_swap_with_next_hscb(ahc, scb);
4829 ahc->qinfifo[qinpos] = scb->hscb->tag;
4830 }
4831
4832 /*
4833 * Start with an empty queue. Entries that are not chosen
4834 * for removal will be re-added to the queue as we go.
4835 */
4836 ahc->qinfifonext = qinpos;
4837 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
4838
4839 while (qinpos != qintail) {

--- 34 unchanged lines hidden (view full) ---

4874 }
4875
4876 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
4877 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
4878 } else {
4879 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
4880 }
4881
4803 /*
4804 * Start with an empty queue. Entries that are not chosen
4805 * for removal will be re-added to the queue as we go.
4806 */
4807 ahc->qinfifonext = qinpos;
4808 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
4809
4810 while (qinpos != qintail) {

--- 34 unchanged lines hidden (view full) ---

4845 }
4846
4847 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
4848 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
4849 } else {
4850 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
4851 }
4852
4853 if (action != SEARCH_COUNT
4854 && (found != 0)
4855 && (qinstart != ahc->qinfifonext)) {
4856 /*
4857 * The sequencer may be in the process of dmaing
4858 * down the SCB at the beginning of the queue.
4859 * This could be problematic if either the first,
4860 * or the second SCB is removed from the queue
4861 * (the first SCB includes a pointer to the "next"
4862 * SCB to dma). If we have removed any entries, swap
4863 * the first element in the queue with the next HSCB
4864 * so the sequencer will notice that NEXT_QUEUED_SCB
4865 * has changed during its dma attempt and will retry
4866 * the DMA.
4867 */
4868 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
4869
4870 /*
4871 * ahc_swap_with_next_hscb forces our next pointer to
4872 * point to the reserved SCB for future commands. Save
4873 * and restore our original next pointer to maintain
4874 * queue integrity.
4875 */
4876 next = scb->hscb->next;
4877 ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
4878 ahc_swap_with_next_hscb(ahc, scb);
4879 scb->hscb->next = next;
4880 ahc->qinfifo[qinstart] = scb->hscb->tag;
4881
4882 /* Fixup the tail "next" pointer. */
4883 qintail = ahc->qinfifonext - 1;
4884 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
4885 scb->hscb->next = ahc->next_queued_scb->hscb->tag;
4886 }
4887
4882 /*
4883 * Search waiting for selection list.
4884 */
4885 curscbptr = ahc_inb(ahc, SCBPTR);
4886 next = ahc_inb(ahc, WAITING_SCBH); /* Start at head of list. */
4887 prev = SCB_LIST_NULL;
4888
4889 while (next != SCB_LIST_NULL) {

--- 1035 unchanged lines hidden (view full) ---

5925
5926 saved_scbptr = ahc_inb(ahc, SCBPTR);
5927
5928 printf("%s: Dumping Card State at SEQADDR 0x%x\n",
5929 ahc_name(ahc),
5930 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
5931
5932 printf("SCB count = %d\n", ahc->scb_data->numscbs);
4888 /*
4889 * Search waiting for selection list.
4890 */
4891 curscbptr = ahc_inb(ahc, SCBPTR);
4892 next = ahc_inb(ahc, WAITING_SCBH); /* Start at head of list. */
4893 prev = SCB_LIST_NULL;
4894
4895 while (next != SCB_LIST_NULL) {

--- 1035 unchanged lines hidden (view full) ---

5931
5932 saved_scbptr = ahc_inb(ahc, SCBPTR);
5933
5934 printf("%s: Dumping Card State at SEQADDR 0x%x\n",
5935 ahc_name(ahc),
5936 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
5937
5938 printf("SCB count = %d\n", ahc->scb_data->numscbs);
5939 printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
5940 printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
5933 /* QINFIFO */
5934 printf("QINFIFO entries: ");
5935 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5936 qinpos = ahc_inb(ahc, SNSCB_QOFF);
5937 ahc_outb(ahc, SNSCB_QOFF, qinpos);
5938 } else
5939 qinpos = ahc_inb(ahc, QINPOS);
5940 qintail = ahc->qinfifonext;

--- 645 unchanged lines hidden ---
5941 /* QINFIFO */
5942 printf("QINFIFO entries: ");
5943 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5944 qinpos = ahc_inb(ahc, SNSCB_QOFF);
5945 ahc_outb(ahc, SNSCB_QOFF, qinpos);
5946 } else
5947 qinpos = ahc_inb(ahc, QINPOS);
5948 qintail = ahc->qinfifonext;

--- 645 unchanged lines hidden ---