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 --- |