117d24755SJustin T. Gibbs /* 217d24755SJustin T. Gibbs * Inline routines shareable across OS platforms. 317d24755SJustin T. Gibbs * 417d24755SJustin T. Gibbs * Copyright (c) 1994-2001 Justin T. Gibbs. 5adcf242eSJustin T. Gibbs * Copyright (c) 2000-2002 Adaptec Inc. 617d24755SJustin T. Gibbs * All rights reserved. 717d24755SJustin T. Gibbs * 817d24755SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 917d24755SJustin T. Gibbs * modification, are permitted provided that the following conditions 1017d24755SJustin T. Gibbs * are met: 1117d24755SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 1217d24755SJustin T. Gibbs * notice, this list of conditions, and the following disclaimer, 1317d24755SJustin T. Gibbs * without modification. 1417d24755SJustin T. Gibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1517d24755SJustin T. Gibbs * substantially similar to the "NO WARRANTY" disclaimer below 1617d24755SJustin T. Gibbs * ("Disclaimer") and any redistribution must be conditioned upon 1717d24755SJustin T. Gibbs * including a substantially similar Disclaimer requirement for further 1817d24755SJustin T. Gibbs * binary redistribution. 1917d24755SJustin T. Gibbs * 3. Neither the names of the above-listed copyright holders nor the names 2017d24755SJustin T. Gibbs * of any contributors may be used to endorse or promote products derived 2117d24755SJustin T. Gibbs * from this software without specific prior written permission. 2217d24755SJustin T. Gibbs * 2317d24755SJustin T. Gibbs * Alternatively, this software may be distributed under the terms of the 2417d24755SJustin T. Gibbs * GNU General Public License ("GPL") version 2 as published by the Free 2517d24755SJustin T. Gibbs * Software Foundation. 2617d24755SJustin T. Gibbs * 2717d24755SJustin T. Gibbs * NO WARRANTY 2817d24755SJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2917d24755SJustin T. Gibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3017d24755SJustin T. Gibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3117d24755SJustin T. Gibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3217d24755SJustin T. Gibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3317d24755SJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3417d24755SJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3517d24755SJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3617d24755SJustin T. Gibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3717d24755SJustin T. Gibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3817d24755SJustin T. Gibbs * POSSIBILITY OF SUCH DAMAGES. 3917d24755SJustin T. Gibbs * 40adcf242eSJustin T. Gibbs * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#34 $ 4117d24755SJustin T. Gibbs * 4217d24755SJustin T. Gibbs * $FreeBSD$ 4317d24755SJustin T. Gibbs */ 4417d24755SJustin T. Gibbs 4517d24755SJustin T. Gibbs #ifndef _AIC79XX_INLINE_H_ 4617d24755SJustin T. Gibbs #define _AIC79XX_INLINE_H_ 4717d24755SJustin T. Gibbs 4817d24755SJustin T. Gibbs /******************************** Debugging ***********************************/ 4917d24755SJustin T. Gibbs static __inline char *ahd_name(struct ahd_softc *ahd); 5017d24755SJustin T. Gibbs 5117d24755SJustin T. Gibbs static __inline char * 5217d24755SJustin T. Gibbs ahd_name(struct ahd_softc *ahd) 5317d24755SJustin T. Gibbs { 5417d24755SJustin T. Gibbs return (ahd->name); 5517d24755SJustin T. Gibbs } 5617d24755SJustin T. Gibbs 5717d24755SJustin T. Gibbs /************************ Sequencer Execution Control *************************/ 5817d24755SJustin T. Gibbs static __inline void ahd_known_modes(struct ahd_softc *ahd, 5917d24755SJustin T. Gibbs ahd_mode src, ahd_mode dst); 6017d24755SJustin T. Gibbs static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd, 6117d24755SJustin T. Gibbs ahd_mode src, 6217d24755SJustin T. Gibbs ahd_mode dst); 6317d24755SJustin T. Gibbs static __inline void ahd_extract_mode_state(struct ahd_softc *ahd, 6417d24755SJustin T. Gibbs ahd_mode_state state, 6517d24755SJustin T. Gibbs ahd_mode *src, ahd_mode *dst); 6617d24755SJustin T. Gibbs static __inline void ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, 6717d24755SJustin T. Gibbs ahd_mode dst); 6817d24755SJustin T. Gibbs static __inline void ahd_update_modes(struct ahd_softc *ahd); 6917d24755SJustin T. Gibbs static __inline void ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, 7017d24755SJustin T. Gibbs ahd_mode dstmode, const char *file, 7117d24755SJustin T. Gibbs int line); 7217d24755SJustin T. Gibbs static __inline ahd_mode_state ahd_save_modes(struct ahd_softc *ahd); 7317d24755SJustin T. Gibbs static __inline void ahd_restore_modes(struct ahd_softc *ahd, 7417d24755SJustin T. Gibbs ahd_mode_state state); 7517d24755SJustin T. Gibbs static __inline int ahd_is_paused(struct ahd_softc *ahd); 7617d24755SJustin T. Gibbs static __inline void ahd_pause(struct ahd_softc *ahd); 7717d24755SJustin T. Gibbs static __inline void ahd_unpause(struct ahd_softc *ahd); 7817d24755SJustin T. Gibbs 7917d24755SJustin T. Gibbs static __inline void 8017d24755SJustin T. Gibbs ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) 8117d24755SJustin T. Gibbs { 8217d24755SJustin T. Gibbs ahd->src_mode = src; 8317d24755SJustin T. Gibbs ahd->dst_mode = dst; 8417d24755SJustin T. Gibbs ahd->saved_src_mode = src; 8517d24755SJustin T. Gibbs ahd->saved_dst_mode = dst; 8617d24755SJustin T. Gibbs } 8717d24755SJustin T. Gibbs 8817d24755SJustin T. Gibbs static __inline ahd_mode_state 8917d24755SJustin T. Gibbs ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) 9017d24755SJustin T. Gibbs { 9117d24755SJustin T. Gibbs return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT)); 9217d24755SJustin T. Gibbs } 9317d24755SJustin T. Gibbs 9417d24755SJustin T. Gibbs static __inline void 9517d24755SJustin T. Gibbs ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state, 9617d24755SJustin T. Gibbs ahd_mode *src, ahd_mode *dst) 9717d24755SJustin T. Gibbs { 9817d24755SJustin T. Gibbs *src = (state & SRC_MODE) >> SRC_MODE_SHIFT; 9917d24755SJustin T. Gibbs *dst = (state & DST_MODE) >> DST_MODE_SHIFT; 10017d24755SJustin T. Gibbs } 10117d24755SJustin T. Gibbs 10217d24755SJustin T. Gibbs static __inline void 10317d24755SJustin T. Gibbs ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst) 10417d24755SJustin T. Gibbs { 10517d24755SJustin T. Gibbs if (ahd->src_mode == src && ahd->dst_mode == dst) 10617d24755SJustin T. Gibbs return; 10717d24755SJustin T. Gibbs #ifdef AHD_DEBUG 10817d24755SJustin T. Gibbs if (ahd->src_mode == AHD_MODE_UNKNOWN 10917d24755SJustin T. Gibbs || ahd->dst_mode == AHD_MODE_UNKNOWN) 11017d24755SJustin T. Gibbs panic("Setting mode prior to saving it.\n"); 11117d24755SJustin T. Gibbs if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) 11217d24755SJustin T. Gibbs printf("Setting mode 0x%x\n", 11317d24755SJustin T. Gibbs ahd_build_mode_state(ahd, src, dst)); 11417d24755SJustin T. Gibbs #endif 11517d24755SJustin T. Gibbs ahd_outb(ahd, MODE_PTR, ahd_build_mode_state(ahd, src, dst)); 11617d24755SJustin T. Gibbs ahd->src_mode = src; 11717d24755SJustin T. Gibbs ahd->dst_mode = dst; 11817d24755SJustin T. Gibbs } 11917d24755SJustin T. Gibbs 12017d24755SJustin T. Gibbs static __inline void 12117d24755SJustin T. Gibbs ahd_update_modes(struct ahd_softc *ahd) 12217d24755SJustin T. Gibbs { 12317d24755SJustin T. Gibbs ahd_mode_state mode_ptr; 12417d24755SJustin T. Gibbs ahd_mode src; 12517d24755SJustin T. Gibbs ahd_mode dst; 12617d24755SJustin T. Gibbs 12717d24755SJustin T. Gibbs mode_ptr = ahd_inb(ahd, MODE_PTR); 12817d24755SJustin T. Gibbs #ifdef AHD_DEBUG 12917d24755SJustin T. Gibbs if ((ahd_debug & AHD_SHOW_MODEPTR) != 0) 13017d24755SJustin T. Gibbs printf("Reading mode 0x%x\n", mode_ptr); 13117d24755SJustin T. Gibbs #endif 13217d24755SJustin T. Gibbs ahd_extract_mode_state(ahd, mode_ptr, &src, &dst); 13317d24755SJustin T. Gibbs ahd_known_modes(ahd, src, dst); 13417d24755SJustin T. Gibbs } 13517d24755SJustin T. Gibbs 13617d24755SJustin T. Gibbs static __inline void 13717d24755SJustin T. Gibbs ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode, 13817d24755SJustin T. Gibbs ahd_mode dstmode, const char *file, int line) 13917d24755SJustin T. Gibbs { 14017d24755SJustin T. Gibbs #ifdef AHD_DEBUG 14117d24755SJustin T. Gibbs if ((srcmode & AHD_MK_MSK(ahd->src_mode)) == 0 14217d24755SJustin T. Gibbs || (dstmode & AHD_MK_MSK(ahd->dst_mode)) == 0) { 14317d24755SJustin T. Gibbs panic("%s:%s:%d: Mode assertion failed.\n", 14417d24755SJustin T. Gibbs ahd_name(ahd), file, line); 14517d24755SJustin T. Gibbs } 14617d24755SJustin T. Gibbs #endif 14717d24755SJustin T. Gibbs } 14817d24755SJustin T. Gibbs 14917d24755SJustin T. Gibbs static __inline ahd_mode_state 15017d24755SJustin T. Gibbs ahd_save_modes(struct ahd_softc *ahd) 15117d24755SJustin T. Gibbs { 15217d24755SJustin T. Gibbs if (ahd->src_mode == AHD_MODE_UNKNOWN 15317d24755SJustin T. Gibbs || ahd->dst_mode == AHD_MODE_UNKNOWN) 15417d24755SJustin T. Gibbs ahd_update_modes(ahd); 15517d24755SJustin T. Gibbs 15617d24755SJustin T. Gibbs return (ahd_build_mode_state(ahd, ahd->src_mode, ahd->dst_mode)); 15717d24755SJustin T. Gibbs } 15817d24755SJustin T. Gibbs 15917d24755SJustin T. Gibbs static __inline void 16017d24755SJustin T. Gibbs ahd_restore_modes(struct ahd_softc *ahd, ahd_mode_state state) 16117d24755SJustin T. Gibbs { 16217d24755SJustin T. Gibbs ahd_mode src; 16317d24755SJustin T. Gibbs ahd_mode dst; 16417d24755SJustin T. Gibbs 16517d24755SJustin T. Gibbs ahd_extract_mode_state(ahd, state, &src, &dst); 16617d24755SJustin T. Gibbs ahd_set_modes(ahd, src, dst); 16717d24755SJustin T. Gibbs } 16817d24755SJustin T. Gibbs 16917d24755SJustin T. Gibbs #define AHD_ASSERT_MODES(ahd, source, dest) \ 17017d24755SJustin T. Gibbs ahd_assert_modes(ahd, source, dest, __FILE__, __LINE__); 17117d24755SJustin T. Gibbs 17217d24755SJustin T. Gibbs /* 17317d24755SJustin T. Gibbs * Determine whether the sequencer has halted code execution. 17417d24755SJustin T. Gibbs * Returns non-zero status if the sequencer is stopped. 17517d24755SJustin T. Gibbs */ 17617d24755SJustin T. Gibbs static __inline int 17717d24755SJustin T. Gibbs ahd_is_paused(struct ahd_softc *ahd) 17817d24755SJustin T. Gibbs { 17917d24755SJustin T. Gibbs return ((ahd_inb(ahd, HCNTRL) & PAUSE) != 0); 18017d24755SJustin T. Gibbs } 18117d24755SJustin T. Gibbs 18217d24755SJustin T. Gibbs /* 18317d24755SJustin T. Gibbs * Request that the sequencer stop and wait, indefinitely, for it 18417d24755SJustin T. Gibbs * to stop. The sequencer will only acknowledge that it is paused 18517d24755SJustin T. Gibbs * once it has reached an instruction boundary and PAUSEDIS is 18617d24755SJustin T. Gibbs * cleared in the SEQCTL register. The sequencer may use PAUSEDIS 18717d24755SJustin T. Gibbs * for critical sections. 18817d24755SJustin T. Gibbs */ 18917d24755SJustin T. Gibbs static __inline void 19017d24755SJustin T. Gibbs ahd_pause(struct ahd_softc *ahd) 19117d24755SJustin T. Gibbs { 19217d24755SJustin T. Gibbs ahd_outb(ahd, HCNTRL, ahd->pause); 19317d24755SJustin T. Gibbs 19417d24755SJustin T. Gibbs /* 19517d24755SJustin T. Gibbs * Since the sequencer can disable pausing in a critical section, we 19617d24755SJustin T. Gibbs * must loop until it actually stops. 19717d24755SJustin T. Gibbs */ 19817d24755SJustin T. Gibbs while (ahd_is_paused(ahd) == 0) 19917d24755SJustin T. Gibbs ; 20017d24755SJustin T. Gibbs } 20117d24755SJustin T. Gibbs 20217d24755SJustin T. Gibbs /* 20317d24755SJustin T. Gibbs * Allow the sequencer to continue program execution. 20417d24755SJustin T. Gibbs * We check here to ensure that no additional interrupt 20517d24755SJustin T. Gibbs * sources that would cause the sequencer to halt have been 20617d24755SJustin T. Gibbs * asserted. If, for example, a SCSI bus reset is detected 20717d24755SJustin T. Gibbs * while we are fielding a different, pausing, interrupt type, 20817d24755SJustin T. Gibbs * we don't want to release the sequencer before going back 20917d24755SJustin T. Gibbs * into our interrupt handler and dealing with this new 21017d24755SJustin T. Gibbs * condition. 21117d24755SJustin T. Gibbs */ 21217d24755SJustin T. Gibbs static __inline void 21317d24755SJustin T. Gibbs ahd_unpause(struct ahd_softc *ahd) 21417d24755SJustin T. Gibbs { 21517d24755SJustin T. Gibbs /* 21617d24755SJustin T. Gibbs * Automatically restore our modes to those saved 21717d24755SJustin T. Gibbs * prior to the first change of the mode. 21817d24755SJustin T. Gibbs */ 21917d24755SJustin T. Gibbs if (ahd->saved_src_mode != AHD_MODE_UNKNOWN 22017d24755SJustin T. Gibbs && ahd->saved_dst_mode != AHD_MODE_UNKNOWN) 22117d24755SJustin T. Gibbs ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); 22217d24755SJustin T. Gibbs 22317d24755SJustin T. Gibbs if ((ahd_inb(ahd, INTSTAT) & ~(SWTMINT | CMDCMPLT)) == 0) 22417d24755SJustin T. Gibbs ahd_outb(ahd, HCNTRL, ahd->unpause); 22517d24755SJustin T. Gibbs 22617d24755SJustin T. Gibbs ahd_known_modes(ahd, AHD_MODE_UNKNOWN, AHD_MODE_UNKNOWN); 22717d24755SJustin T. Gibbs } 22817d24755SJustin T. Gibbs 22917d24755SJustin T. Gibbs /*********************** Untagged Transaction Routines ************************/ 23017d24755SJustin T. Gibbs static __inline void ahd_freeze_untagged_queues(struct ahd_softc *ahd); 23117d24755SJustin T. Gibbs static __inline void ahd_release_untagged_queues(struct ahd_softc *ahd); 23217d24755SJustin T. Gibbs 23317d24755SJustin T. Gibbs /* 23417d24755SJustin T. Gibbs * Block our completion routine from starting the next untagged 23517d24755SJustin T. Gibbs * transaction for this target or target lun. 23617d24755SJustin T. Gibbs */ 23717d24755SJustin T. Gibbs static __inline void 23817d24755SJustin T. Gibbs ahd_freeze_untagged_queues(struct ahd_softc *ahd) 23917d24755SJustin T. Gibbs { 24017d24755SJustin T. Gibbs /* 24117d24755SJustin T. Gibbs * Assume we have enough space in the card's SCB 24217d24755SJustin T. Gibbs * to obviate the need for a per target untagged 24317d24755SJustin T. Gibbs * transaction limit. 24417d24755SJustin T. Gibbs */ 24517d24755SJustin T. Gibbs #if 0 24617d24755SJustin T. Gibbs ahd->untagged_queue_lock++; 24717d24755SJustin T. Gibbs #endif 24817d24755SJustin T. Gibbs } 24917d24755SJustin T. Gibbs 25017d24755SJustin T. Gibbs /* 25117d24755SJustin T. Gibbs * Allow the next untagged transaction for this target or target lun 25217d24755SJustin T. Gibbs * to be executed. We use a counting semaphore to allow the lock 25317d24755SJustin T. Gibbs * to be acquired recursively. Once the count drops to zero, the 25417d24755SJustin T. Gibbs * transaction queues will be run. 25517d24755SJustin T. Gibbs */ 25617d24755SJustin T. Gibbs static __inline void 25717d24755SJustin T. Gibbs ahd_release_untagged_queues(struct ahd_softc *ahd) 25817d24755SJustin T. Gibbs { 25917d24755SJustin T. Gibbs /* 26017d24755SJustin T. Gibbs * Assume we have enough space in the card's SCB 26117d24755SJustin T. Gibbs * to obviate the need for a per target untagged 26217d24755SJustin T. Gibbs * transaction limit. 26317d24755SJustin T. Gibbs */ 26417d24755SJustin T. Gibbs #if 0 26517d24755SJustin T. Gibbs ahd->untagged_queue_lock--; 26617d24755SJustin T. Gibbs if (ahd->untagged_queue_lock == 0) 26717d24755SJustin T. Gibbs ahd_run_untagged_queues(ahd); 26817d24755SJustin T. Gibbs #endif 26917d24755SJustin T. Gibbs } 27017d24755SJustin T. Gibbs 27117d24755SJustin T. Gibbs /*********************** Scatter Gather List Handling *************************/ 27217d24755SJustin T. Gibbs static __inline void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, 27317d24755SJustin T. Gibbs void *sgptr, bus_addr_t addr, 27417d24755SJustin T. Gibbs bus_size_t len, int last); 27517d24755SJustin T. Gibbs static __inline void ahd_setup_scb_common(struct ahd_softc *ahd, 27617d24755SJustin T. Gibbs struct scb *scb); 27717d24755SJustin T. Gibbs static __inline void ahd_setup_data_scb(struct ahd_softc *ahd, 27817d24755SJustin T. Gibbs struct scb *scb); 27917d24755SJustin T. Gibbs static __inline void ahd_setup_noxfer_scb(struct ahd_softc *ahd, 28017d24755SJustin T. Gibbs struct scb *scb); 28117d24755SJustin T. Gibbs 28217d24755SJustin T. Gibbs static __inline void * 28317d24755SJustin T. Gibbs ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, 28417d24755SJustin T. Gibbs void *sgptr, bus_addr_t addr, bus_size_t len, int last) 28517d24755SJustin T. Gibbs { 28617d24755SJustin T. Gibbs scb->sg_count++; 28717d24755SJustin T. Gibbs if (sizeof(bus_addr_t) > 4 28817d24755SJustin T. Gibbs && (ahd->flags & AHD_64BIT_ADDRESSING) != 0) { 28917d24755SJustin T. Gibbs struct ahd_dma64_seg *sg; 29017d24755SJustin T. Gibbs 29117d24755SJustin T. Gibbs sg = (struct ahd_dma64_seg *)sgptr; 29217d24755SJustin T. Gibbs sg->addr = ahd_htole64(addr); 29317d24755SJustin T. Gibbs sg->len = ahd_htole32(len | (last ? AHD_DMA_LAST_SEG : 0)); 29417d24755SJustin T. Gibbs return (sg + 1); 29517d24755SJustin T. Gibbs } else { 29617d24755SJustin T. Gibbs struct ahd_dma_seg *sg; 29717d24755SJustin T. Gibbs 29817d24755SJustin T. Gibbs sg = (struct ahd_dma_seg *)sgptr; 29917d24755SJustin T. Gibbs sg->addr = ahd_htole64(addr); 30017d24755SJustin T. Gibbs sg->len = ahd_htole32(len | ((addr >> 8) & 0x7F000000) 30117d24755SJustin T. Gibbs | (last ? AHD_DMA_LAST_SEG : 0)); 30217d24755SJustin T. Gibbs return (sg + 1); 30317d24755SJustin T. Gibbs } 30417d24755SJustin T. Gibbs } 30517d24755SJustin T. Gibbs 30617d24755SJustin T. Gibbs static __inline void 30717d24755SJustin T. Gibbs ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb) 30817d24755SJustin T. Gibbs { 30917d24755SJustin T. Gibbs /* XXX Handle target mode SCBs. */ 31017d24755SJustin T. Gibbs if ((scb->flags & SCB_PACKETIZED) != 0) { 31117d24755SJustin T. Gibbs /* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */ 31217d24755SJustin T. Gibbs scb->hscb->task_attribute_nonpkt_tag = 31317d24755SJustin T. Gibbs scb->hscb->control & SCB_TAG_TYPE; 31417d24755SJustin T. Gibbs scb->hscb->task_management = 0; 315adcf242eSJustin T. Gibbs /* 316adcf242eSJustin T. Gibbs * For Rev A short lun workaround. 317adcf242eSJustin T. Gibbs */ 318adcf242eSJustin T. Gibbs scb->hscb->pkt_long_lun[6] = scb->hscb->lun; 31917d24755SJustin T. Gibbs } else { 32017d24755SJustin T. Gibbs scb->hscb->task_attribute_nonpkt_tag = SCB_GET_TAG(scb); 32117d24755SJustin T. Gibbs } 32217d24755SJustin T. Gibbs 32317d24755SJustin T. Gibbs if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR 32417d24755SJustin T. Gibbs || (scb->hscb->cdb_len & SCB_CDB_LEN_PTR) != 0) 32517d24755SJustin T. Gibbs scb->hscb->shared_data.idata.cdb_plus_saddr.sense_addr = 32617d24755SJustin T. Gibbs ahd_htole32(scb->sense_busaddr); 32717d24755SJustin T. Gibbs } 32817d24755SJustin T. Gibbs 32917d24755SJustin T. Gibbs static __inline void 33017d24755SJustin T. Gibbs ahd_setup_data_scb(struct ahd_softc *ahd, struct scb *scb) 33117d24755SJustin T. Gibbs { 33217d24755SJustin T. Gibbs /* 33317d24755SJustin T. Gibbs * Copy the first SG into the "current" data ponter area. 33417d24755SJustin T. Gibbs */ 33517d24755SJustin T. Gibbs if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { 33617d24755SJustin T. Gibbs struct ahd_dma64_seg *sg; 33717d24755SJustin T. Gibbs 33817d24755SJustin T. Gibbs sg = (struct ahd_dma64_seg *)scb->sg_list; 33917d24755SJustin T. Gibbs scb->hscb->dataptr = sg->addr; 34017d24755SJustin T. Gibbs scb->hscb->datacnt = sg->len; 34117d24755SJustin T. Gibbs } else { 34217d24755SJustin T. Gibbs struct ahd_dma_seg *sg; 34317d24755SJustin T. Gibbs 34417d24755SJustin T. Gibbs sg = (struct ahd_dma_seg *)scb->sg_list; 34517d24755SJustin T. Gibbs scb->hscb->dataptr = sg->addr; 34617d24755SJustin T. Gibbs if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { 34717d24755SJustin T. Gibbs uint64_t high_addr; 34817d24755SJustin T. Gibbs 349cdd49e97SJustin T. Gibbs high_addr = ahd_le32toh(sg->len) & 0x7F000000; 350cdd49e97SJustin T. Gibbs scb->hscb->dataptr |= ahd_htole64(high_addr << 8); 35117d24755SJustin T. Gibbs } 35217d24755SJustin T. Gibbs scb->hscb->datacnt = sg->len; 35317d24755SJustin T. Gibbs } 35417d24755SJustin T. Gibbs /* 35517d24755SJustin T. Gibbs * Note where to find the SG entries in bus space. 35617d24755SJustin T. Gibbs * We also set the full residual flag which the 35717d24755SJustin T. Gibbs * sequencer will clear as soon as a data transfer 35817d24755SJustin T. Gibbs * occurs. 35917d24755SJustin T. Gibbs */ 36017d24755SJustin T. Gibbs scb->hscb->sgptr = ahd_htole32(scb->sg_list_busaddr|SG_FULL_RESID); 36117d24755SJustin T. Gibbs } 36217d24755SJustin T. Gibbs 36317d24755SJustin T. Gibbs static __inline void 36417d24755SJustin T. Gibbs ahd_setup_noxfer_scb(struct ahd_softc *ahd, struct scb *scb) 36517d24755SJustin T. Gibbs { 36617d24755SJustin T. Gibbs scb->hscb->sgptr = ahd_htole32(SG_LIST_NULL); 36717d24755SJustin T. Gibbs scb->hscb->dataptr = 0; 36817d24755SJustin T. Gibbs scb->hscb->datacnt = 0; 36917d24755SJustin T. Gibbs } 37017d24755SJustin T. Gibbs 37117d24755SJustin T. Gibbs /************************** Memory mapping routines ***************************/ 37217d24755SJustin T. Gibbs static __inline size_t ahd_sg_size(struct ahd_softc *ahd); 37317d24755SJustin T. Gibbs static __inline void * 37417d24755SJustin T. Gibbs ahd_sg_bus_to_virt(struct ahd_softc *ahd, 37517d24755SJustin T. Gibbs struct scb *scb, 37617d24755SJustin T. Gibbs uint32_t sg_busaddr); 37717d24755SJustin T. Gibbs static __inline uint32_t 37817d24755SJustin T. Gibbs ahd_sg_virt_to_bus(struct ahd_softc *ahd, 37917d24755SJustin T. Gibbs struct scb *scb, 38017d24755SJustin T. Gibbs void *sg); 38117d24755SJustin T. Gibbs static __inline void ahd_sync_scb(struct ahd_softc *ahd, 38217d24755SJustin T. Gibbs struct scb *scb, int op); 38317d24755SJustin T. Gibbs static __inline void ahd_sync_sglist(struct ahd_softc *ahd, 38417d24755SJustin T. Gibbs struct scb *scb, int op); 38517d24755SJustin T. Gibbs static __inline void ahd_sync_sense(struct ahd_softc *ahd, 38617d24755SJustin T. Gibbs struct scb *scb, int op); 38717d24755SJustin T. Gibbs static __inline uint32_t 38817d24755SJustin T. Gibbs ahd_targetcmd_offset(struct ahd_softc *ahd, 38917d24755SJustin T. Gibbs u_int index); 39017d24755SJustin T. Gibbs 39117d24755SJustin T. Gibbs static __inline size_t 39217d24755SJustin T. Gibbs ahd_sg_size(struct ahd_softc *ahd) 39317d24755SJustin T. Gibbs { 39417d24755SJustin T. Gibbs if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) 39517d24755SJustin T. Gibbs return (sizeof(struct ahd_dma64_seg)); 39617d24755SJustin T. Gibbs return (sizeof(struct ahd_dma_seg)); 39717d24755SJustin T. Gibbs } 39817d24755SJustin T. Gibbs 39917d24755SJustin T. Gibbs static __inline void * 40017d24755SJustin T. Gibbs ahd_sg_bus_to_virt(struct ahd_softc *ahd, struct scb *scb, uint32_t sg_busaddr) 40117d24755SJustin T. Gibbs { 40217d24755SJustin T. Gibbs bus_addr_t sg_offset; 40317d24755SJustin T. Gibbs 40417d24755SJustin T. Gibbs /* sg_list_phys points to entry 1, not 0 */ 40517d24755SJustin T. Gibbs sg_offset = sg_busaddr - (scb->sg_list_busaddr - ahd_sg_size(ahd)); 40617d24755SJustin T. Gibbs return ((uint8_t *)scb->sg_list + sg_offset); 40717d24755SJustin T. Gibbs } 40817d24755SJustin T. Gibbs 40917d24755SJustin T. Gibbs static __inline uint32_t 41017d24755SJustin T. Gibbs ahd_sg_virt_to_bus(struct ahd_softc *ahd, struct scb *scb, void *sg) 41117d24755SJustin T. Gibbs { 41217d24755SJustin T. Gibbs bus_addr_t sg_offset; 41317d24755SJustin T. Gibbs 41417d24755SJustin T. Gibbs /* sg_list_phys points to entry 1, not 0 */ 41517d24755SJustin T. Gibbs sg_offset = ((uint8_t *)sg - (uint8_t *)scb->sg_list) 41617d24755SJustin T. Gibbs - ahd_sg_size(ahd); 41717d24755SJustin T. Gibbs 41817d24755SJustin T. Gibbs return (scb->sg_list_busaddr + sg_offset); 41917d24755SJustin T. Gibbs } 42017d24755SJustin T. Gibbs 42117d24755SJustin T. Gibbs static __inline void 42217d24755SJustin T. Gibbs ahd_sync_scb(struct ahd_softc *ahd, struct scb *scb, int op) 42317d24755SJustin T. Gibbs { 42417d24755SJustin T. Gibbs ahd_dmamap_sync(ahd, ahd->scb_data.hscb_dmat, 42517d24755SJustin T. Gibbs scb->hscb_map->dmamap, 42617d24755SJustin T. Gibbs /*offset*/(uint8_t*)scb->hscb - scb->hscb_map->vaddr, 42717d24755SJustin T. Gibbs /*len*/sizeof(*scb->hscb), op); 42817d24755SJustin T. Gibbs } 42917d24755SJustin T. Gibbs 43017d24755SJustin T. Gibbs static __inline void 43117d24755SJustin T. Gibbs ahd_sync_sglist(struct ahd_softc *ahd, struct scb *scb, int op) 43217d24755SJustin T. Gibbs { 43317d24755SJustin T. Gibbs if (scb->sg_count == 0) 43417d24755SJustin T. Gibbs return; 43517d24755SJustin T. Gibbs 43617d24755SJustin T. Gibbs ahd_dmamap_sync(ahd, ahd->scb_data.sg_dmat, 43717d24755SJustin T. Gibbs scb->sg_map->dmamap, 43817d24755SJustin T. Gibbs /*offset*/scb->sg_list_busaddr - ahd_sg_size(ahd), 43917d24755SJustin T. Gibbs /*len*/ahd_sg_size(ahd) * scb->sg_count, op); 44017d24755SJustin T. Gibbs } 44117d24755SJustin T. Gibbs 44217d24755SJustin T. Gibbs static __inline void 44317d24755SJustin T. Gibbs ahd_sync_sense(struct ahd_softc *ahd, struct scb *scb, int op) 44417d24755SJustin T. Gibbs { 44517d24755SJustin T. Gibbs ahd_dmamap_sync(ahd, ahd->scb_data.sense_dmat, 44617d24755SJustin T. Gibbs scb->sense_map->dmamap, 44717d24755SJustin T. Gibbs /*offset*/scb->sense_busaddr, 44817d24755SJustin T. Gibbs /*len*/AHD_SENSE_BUFSIZE, op); 44917d24755SJustin T. Gibbs } 45017d24755SJustin T. Gibbs 45117d24755SJustin T. Gibbs static __inline uint32_t 45217d24755SJustin T. Gibbs ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) 45317d24755SJustin T. Gibbs { 45417d24755SJustin T. Gibbs return (((uint8_t *)&ahd->targetcmds[index]) 45517d24755SJustin T. Gibbs - (uint8_t *)ahd->qoutfifo); 45617d24755SJustin T. Gibbs } 45717d24755SJustin T. Gibbs 45817d24755SJustin T. Gibbs /*********************** Miscelaneous Support Functions ***********************/ 45917d24755SJustin T. Gibbs static __inline void ahd_complete_scb(struct ahd_softc *ahd, 46017d24755SJustin T. Gibbs struct scb *scb); 46117d24755SJustin T. Gibbs static __inline void ahd_update_residual(struct ahd_softc *ahd, 46217d24755SJustin T. Gibbs struct scb *scb); 46317d24755SJustin T. Gibbs static __inline struct ahd_initiator_tinfo * 46417d24755SJustin T. Gibbs ahd_fetch_transinfo(struct ahd_softc *ahd, 46517d24755SJustin T. Gibbs char channel, u_int our_id, 46617d24755SJustin T. Gibbs u_int remote_id, 46717d24755SJustin T. Gibbs struct ahd_tmode_tstate **tstate); 46817d24755SJustin T. Gibbs static __inline uint16_t 46917d24755SJustin T. Gibbs ahd_inw(struct ahd_softc *ahd, u_int port); 47017d24755SJustin T. Gibbs static __inline void ahd_outw(struct ahd_softc *ahd, u_int port, 47117d24755SJustin T. Gibbs u_int value); 47217d24755SJustin T. Gibbs static __inline uint32_t 47317d24755SJustin T. Gibbs ahd_inl(struct ahd_softc *ahd, u_int port); 47417d24755SJustin T. Gibbs static __inline void ahd_outl(struct ahd_softc *ahd, u_int port, 47517d24755SJustin T. Gibbs uint32_t value); 47617d24755SJustin T. Gibbs static __inline uint64_t 47717d24755SJustin T. Gibbs ahd_inq(struct ahd_softc *ahd, u_int port); 47817d24755SJustin T. Gibbs static __inline void ahd_outq(struct ahd_softc *ahd, u_int port, 47917d24755SJustin T. Gibbs uint64_t value); 48017d24755SJustin T. Gibbs static __inline u_int ahd_get_scbptr(struct ahd_softc *ahd); 48117d24755SJustin T. Gibbs static __inline void ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr); 48217d24755SJustin T. Gibbs static __inline u_int ahd_get_hnscb_qoff(struct ahd_softc *ahd); 48317d24755SJustin T. Gibbs static __inline void ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value); 48417d24755SJustin T. Gibbs static __inline u_int ahd_get_hescb_qoff(struct ahd_softc *ahd); 48517d24755SJustin T. Gibbs static __inline void ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value); 48617d24755SJustin T. Gibbs static __inline u_int ahd_get_snscb_qoff(struct ahd_softc *ahd); 48717d24755SJustin T. Gibbs static __inline void ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value); 48817d24755SJustin T. Gibbs static __inline u_int ahd_get_sescb_qoff(struct ahd_softc *ahd); 48917d24755SJustin T. Gibbs static __inline void ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value); 49017d24755SJustin T. Gibbs static __inline u_int ahd_get_sdscb_qoff(struct ahd_softc *ahd); 49117d24755SJustin T. Gibbs static __inline void ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value); 49217d24755SJustin T. Gibbs static __inline u_int ahd_inb_scbram(struct ahd_softc *ahd, u_int offset); 49317d24755SJustin T. Gibbs static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset); 49417d24755SJustin T. Gibbs static __inline uint32_t 49517d24755SJustin T. Gibbs ahd_inl_scbram(struct ahd_softc *ahd, u_int offset); 49617d24755SJustin T. Gibbs static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd, 49717d24755SJustin T. Gibbs struct scb *scb); 49817d24755SJustin T. Gibbs static __inline void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb); 49917d24755SJustin T. Gibbs static __inline uint8_t * 50017d24755SJustin T. Gibbs ahd_get_sense_buf(struct ahd_softc *ahd, 50117d24755SJustin T. Gibbs struct scb *scb); 50217d24755SJustin T. Gibbs static __inline uint32_t 50317d24755SJustin T. Gibbs ahd_get_sense_bufaddr(struct ahd_softc *ahd, 50417d24755SJustin T. Gibbs struct scb *scb); 50517d24755SJustin T. Gibbs 50617d24755SJustin T. Gibbs static __inline void 50717d24755SJustin T. Gibbs ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) 50817d24755SJustin T. Gibbs { 50917d24755SJustin T. Gibbs uint32_t sgptr; 51017d24755SJustin T. Gibbs 51117d24755SJustin T. Gibbs sgptr = ahd_le32toh(scb->hscb->sgptr); 51217d24755SJustin T. Gibbs if ((sgptr & SG_STATUS_VALID) != 0) 51317d24755SJustin T. Gibbs ahd_handle_scb_status(ahd, scb); 51417d24755SJustin T. Gibbs else 51517d24755SJustin T. Gibbs ahd_done(ahd, scb); 51617d24755SJustin T. Gibbs } 51717d24755SJustin T. Gibbs 51817d24755SJustin T. Gibbs /* 51917d24755SJustin T. Gibbs * Determine whether the sequencer reported a residual 52017d24755SJustin T. Gibbs * for this SCB/transaction. 52117d24755SJustin T. Gibbs */ 52217d24755SJustin T. Gibbs static __inline void 52317d24755SJustin T. Gibbs ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) 52417d24755SJustin T. Gibbs { 52517d24755SJustin T. Gibbs uint32_t sgptr; 52617d24755SJustin T. Gibbs 52717d24755SJustin T. Gibbs sgptr = ahd_le32toh(scb->hscb->sgptr); 52817d24755SJustin T. Gibbs if ((sgptr & SG_STATUS_VALID) != 0) 52917d24755SJustin T. Gibbs ahd_calc_residual(ahd, scb); 53017d24755SJustin T. Gibbs } 53117d24755SJustin T. Gibbs 53217d24755SJustin T. Gibbs /* 53317d24755SJustin T. Gibbs * Return pointers to the transfer negotiation information 53417d24755SJustin T. Gibbs * for the specified our_id/remote_id pair. 53517d24755SJustin T. Gibbs */ 53617d24755SJustin T. Gibbs static __inline struct ahd_initiator_tinfo * 53717d24755SJustin T. Gibbs ahd_fetch_transinfo(struct ahd_softc *ahd, char channel, u_int our_id, 53817d24755SJustin T. Gibbs u_int remote_id, struct ahd_tmode_tstate **tstate) 53917d24755SJustin T. Gibbs { 54017d24755SJustin T. Gibbs /* 54117d24755SJustin T. Gibbs * Transfer data structures are stored from the perspective 54217d24755SJustin T. Gibbs * of the target role. Since the parameters for a connection 54317d24755SJustin T. Gibbs * in the initiator role to a given target are the same as 54417d24755SJustin T. Gibbs * when the roles are reversed, we pretend we are the target. 54517d24755SJustin T. Gibbs */ 54617d24755SJustin T. Gibbs if (channel == 'B') 54717d24755SJustin T. Gibbs our_id += 8; 54817d24755SJustin T. Gibbs *tstate = ahd->enabled_targets[our_id]; 54917d24755SJustin T. Gibbs return (&(*tstate)->transinfo[remote_id]); 55017d24755SJustin T. Gibbs } 55117d24755SJustin T. Gibbs 552adcf242eSJustin T. Gibbs #define AHD_COPY_COL_IDX(dst, src) \ 553adcf242eSJustin T. Gibbs do { \ 554adcf242eSJustin T. Gibbs dst->hscb->scsiid = src->hscb->scsiid; \ 555adcf242eSJustin T. Gibbs dst->hscb->lun = src->hscb->lun; \ 556adcf242eSJustin T. Gibbs } while (0) 55717d24755SJustin T. Gibbs 55817d24755SJustin T. Gibbs static __inline uint16_t 55917d24755SJustin T. Gibbs ahd_inw(struct ahd_softc *ahd, u_int port) 56017d24755SJustin T. Gibbs { 56117d24755SJustin T. Gibbs return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); 56217d24755SJustin T. Gibbs } 56317d24755SJustin T. Gibbs 56417d24755SJustin T. Gibbs static __inline void 56517d24755SJustin T. Gibbs ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) 56617d24755SJustin T. Gibbs { 56717d24755SJustin T. Gibbs ahd_outb(ahd, port, value & 0xFF); 56817d24755SJustin T. Gibbs ahd_outb(ahd, port+1, (value >> 8) & 0xFF); 56917d24755SJustin T. Gibbs } 57017d24755SJustin T. Gibbs 57117d24755SJustin T. Gibbs static __inline uint32_t 57217d24755SJustin T. Gibbs ahd_inl(struct ahd_softc *ahd, u_int port) 57317d24755SJustin T. Gibbs { 57417d24755SJustin T. Gibbs return ((ahd_inb(ahd, port)) 57517d24755SJustin T. Gibbs | (ahd_inb(ahd, port+1) << 8) 57617d24755SJustin T. Gibbs | (ahd_inb(ahd, port+2) << 16) 57717d24755SJustin T. Gibbs | (ahd_inb(ahd, port+3) << 24)); 57817d24755SJustin T. Gibbs } 57917d24755SJustin T. Gibbs 58017d24755SJustin T. Gibbs static __inline void 58117d24755SJustin T. Gibbs ahd_outl(struct ahd_softc *ahd, u_int port, uint32_t value) 58217d24755SJustin T. Gibbs { 58317d24755SJustin T. Gibbs ahd_outb(ahd, port, (value) & 0xFF); 58417d24755SJustin T. Gibbs ahd_outb(ahd, port+1, ((value) >> 8) & 0xFF); 58517d24755SJustin T. Gibbs ahd_outb(ahd, port+2, ((value) >> 16) & 0xFF); 58617d24755SJustin T. Gibbs ahd_outb(ahd, port+3, ((value) >> 24) & 0xFF); 58717d24755SJustin T. Gibbs } 58817d24755SJustin T. Gibbs 58917d24755SJustin T. Gibbs static __inline uint64_t 59017d24755SJustin T. Gibbs ahd_inq(struct ahd_softc *ahd, u_int port) 59117d24755SJustin T. Gibbs { 59217d24755SJustin T. Gibbs return ((ahd_inb(ahd, port)) 59317d24755SJustin T. Gibbs | (ahd_inb(ahd, port+1) << 8) 59417d24755SJustin T. Gibbs | (ahd_inb(ahd, port+2) << 16) 59517d24755SJustin T. Gibbs | (ahd_inb(ahd, port+3) << 24) 59617d24755SJustin T. Gibbs | (((uint64_t)ahd_inb(ahd, port+4)) << 32) 59717d24755SJustin T. Gibbs | (((uint64_t)ahd_inb(ahd, port+5)) << 40) 59817d24755SJustin T. Gibbs | (((uint64_t)ahd_inb(ahd, port+6)) << 48) 59917d24755SJustin T. Gibbs | (((uint64_t)ahd_inb(ahd, port+7)) << 56)); 60017d24755SJustin T. Gibbs } 60117d24755SJustin T. Gibbs 60217d24755SJustin T. Gibbs static __inline void 60317d24755SJustin T. Gibbs ahd_outq(struct ahd_softc *ahd, u_int port, uint64_t value) 60417d24755SJustin T. Gibbs { 60517d24755SJustin T. Gibbs ahd_outb(ahd, port, value & 0xFF); 60617d24755SJustin T. Gibbs ahd_outb(ahd, port+1, (value >> 8) & 0xFF); 60717d24755SJustin T. Gibbs ahd_outb(ahd, port+2, (value >> 16) & 0xFF); 60817d24755SJustin T. Gibbs ahd_outb(ahd, port+3, (value >> 24) & 0xFF); 60917d24755SJustin T. Gibbs ahd_outb(ahd, port+4, (value >> 32) & 0xFF); 61017d24755SJustin T. Gibbs ahd_outb(ahd, port+5, (value >> 40) & 0xFF); 61117d24755SJustin T. Gibbs ahd_outb(ahd, port+6, (value >> 48) & 0xFF); 61217d24755SJustin T. Gibbs ahd_outb(ahd, port+7, (value >> 56) & 0xFF); 61317d24755SJustin T. Gibbs } 61417d24755SJustin T. Gibbs 61517d24755SJustin T. Gibbs static __inline u_int 61617d24755SJustin T. Gibbs ahd_get_scbptr(struct ahd_softc *ahd) 61717d24755SJustin T. Gibbs { 61817d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), 61917d24755SJustin T. Gibbs ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); 62017d24755SJustin T. Gibbs return (ahd_inb(ahd, SCBPTR) | (ahd_inb(ahd, SCBPTR + 1) << 8)); 62117d24755SJustin T. Gibbs } 62217d24755SJustin T. Gibbs 62317d24755SJustin T. Gibbs static __inline void 62417d24755SJustin T. Gibbs ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr) 62517d24755SJustin T. Gibbs { 62617d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), 62717d24755SJustin T. Gibbs ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK)); 62817d24755SJustin T. Gibbs ahd_outb(ahd, SCBPTR, scbptr & 0xFF); 62917d24755SJustin T. Gibbs ahd_outb(ahd, SCBPTR+1, (scbptr >> 8) & 0xFF); 63017d24755SJustin T. Gibbs } 63117d24755SJustin T. Gibbs 63217d24755SJustin T. Gibbs static __inline u_int 63317d24755SJustin T. Gibbs ahd_get_hnscb_qoff(struct ahd_softc *ahd) 63417d24755SJustin T. Gibbs { 63517d24755SJustin T. Gibbs return (ahd_inw_atomic(ahd, HNSCB_QOFF)); 63617d24755SJustin T. Gibbs } 63717d24755SJustin T. Gibbs 63817d24755SJustin T. Gibbs static __inline void 63917d24755SJustin T. Gibbs ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value) 64017d24755SJustin T. Gibbs { 64117d24755SJustin T. Gibbs ahd_outw_atomic(ahd, HNSCB_QOFF, value); 64217d24755SJustin T. Gibbs } 64317d24755SJustin T. Gibbs 64417d24755SJustin T. Gibbs static __inline u_int 64517d24755SJustin T. Gibbs ahd_get_hescb_qoff(struct ahd_softc *ahd) 64617d24755SJustin T. Gibbs { 64717d24755SJustin T. Gibbs return (ahd_inb(ahd, HESCB_QOFF)); 64817d24755SJustin T. Gibbs } 64917d24755SJustin T. Gibbs 65017d24755SJustin T. Gibbs static __inline void 65117d24755SJustin T. Gibbs ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value) 65217d24755SJustin T. Gibbs { 65317d24755SJustin T. Gibbs ahd_outb(ahd, HESCB_QOFF, value); 65417d24755SJustin T. Gibbs } 65517d24755SJustin T. Gibbs 65617d24755SJustin T. Gibbs static __inline u_int 65717d24755SJustin T. Gibbs ahd_get_snscb_qoff(struct ahd_softc *ahd) 65817d24755SJustin T. Gibbs { 65917d24755SJustin T. Gibbs u_int oldvalue; 66017d24755SJustin T. Gibbs 66117d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); 66217d24755SJustin T. Gibbs oldvalue = ahd_inw(ahd, SNSCB_QOFF); 66317d24755SJustin T. Gibbs ahd_outw(ahd, SNSCB_QOFF, oldvalue); 66417d24755SJustin T. Gibbs return (oldvalue); 66517d24755SJustin T. Gibbs } 66617d24755SJustin T. Gibbs 66717d24755SJustin T. Gibbs static __inline void 66817d24755SJustin T. Gibbs ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value) 66917d24755SJustin T. Gibbs { 67017d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); 67117d24755SJustin T. Gibbs ahd_outw(ahd, SNSCB_QOFF, value); 67217d24755SJustin T. Gibbs } 67317d24755SJustin T. Gibbs 67417d24755SJustin T. Gibbs static __inline u_int 67517d24755SJustin T. Gibbs ahd_get_sescb_qoff(struct ahd_softc *ahd) 67617d24755SJustin T. Gibbs { 67717d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); 67817d24755SJustin T. Gibbs return (ahd_inb(ahd, SESCB_QOFF)); 67917d24755SJustin T. Gibbs } 68017d24755SJustin T. Gibbs 68117d24755SJustin T. Gibbs static __inline void 68217d24755SJustin T. Gibbs ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value) 68317d24755SJustin T. Gibbs { 68417d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); 68517d24755SJustin T. Gibbs ahd_outb(ahd, SESCB_QOFF, value); 68617d24755SJustin T. Gibbs } 68717d24755SJustin T. Gibbs 68817d24755SJustin T. Gibbs static __inline u_int 68917d24755SJustin T. Gibbs ahd_get_sdscb_qoff(struct ahd_softc *ahd) 69017d24755SJustin T. Gibbs { 69117d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); 69217d24755SJustin T. Gibbs return (ahd_inb(ahd, SDSCB_QOFF) | (ahd_inb(ahd, SDSCB_QOFF + 1) << 8)); 69317d24755SJustin T. Gibbs } 69417d24755SJustin T. Gibbs 69517d24755SJustin T. Gibbs static __inline void 69617d24755SJustin T. Gibbs ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value) 69717d24755SJustin T. Gibbs { 69817d24755SJustin T. Gibbs AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK); 69917d24755SJustin T. Gibbs ahd_outb(ahd, SDSCB_QOFF, value & 0xFF); 70017d24755SJustin T. Gibbs ahd_outb(ahd, SDSCB_QOFF+1, (value >> 8) & 0xFF); 70117d24755SJustin T. Gibbs } 70217d24755SJustin T. Gibbs 70317d24755SJustin T. Gibbs static __inline u_int 70417d24755SJustin T. Gibbs ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) 70517d24755SJustin T. Gibbs { 70617d24755SJustin T. Gibbs u_int value; 70717d24755SJustin T. Gibbs 70817d24755SJustin T. Gibbs /* 70917d24755SJustin T. Gibbs * Workaround PCI-X Rev A. hardware bug. 71017d24755SJustin T. Gibbs * After a host read of SCB memory, the chip 71117d24755SJustin T. Gibbs * may become confused into thinking prefetch 71217d24755SJustin T. Gibbs * was required. This starts the discard timer 71317d24755SJustin T. Gibbs * running and can cause an unexpected discard 71417d24755SJustin T. Gibbs * timer interrupt. The work around is to read 71517d24755SJustin T. Gibbs * a normal register prior to the exhaustion of 71617d24755SJustin T. Gibbs * the discard timer. The mode pointer register 71717d24755SJustin T. Gibbs * has no side effects and so serves well for 71817d24755SJustin T. Gibbs * this purpose. 71917d24755SJustin T. Gibbs * 72017d24755SJustin T. Gibbs * Razor #528 72117d24755SJustin T. Gibbs */ 72217d24755SJustin T. Gibbs value = ahd_inb(ahd, offset); 72317d24755SJustin T. Gibbs ahd_inb(ahd, MODE_PTR); 72417d24755SJustin T. Gibbs return (value); 72517d24755SJustin T. Gibbs } 72617d24755SJustin T. Gibbs 72717d24755SJustin T. Gibbs static __inline u_int 72817d24755SJustin T. Gibbs ahd_inw_scbram(struct ahd_softc *ahd, u_int offset) 72917d24755SJustin T. Gibbs { 73017d24755SJustin T. Gibbs return (ahd_inb_scbram(ahd, offset) 73117d24755SJustin T. Gibbs | (ahd_inb_scbram(ahd, offset+1) << 8)); 73217d24755SJustin T. Gibbs } 73317d24755SJustin T. Gibbs 73417d24755SJustin T. Gibbs static __inline uint32_t 73517d24755SJustin T. Gibbs ahd_inl_scbram(struct ahd_softc *ahd, u_int offset) 73617d24755SJustin T. Gibbs { 73717d24755SJustin T. Gibbs return (ahd_inb_scbram(ahd, offset) 73817d24755SJustin T. Gibbs | (ahd_inb_scbram(ahd, offset+1) << 8) 73917d24755SJustin T. Gibbs | (ahd_inb_scbram(ahd, offset+2) << 16) 74017d24755SJustin T. Gibbs | (ahd_inb_scbram(ahd, offset+3) << 24)); 74117d24755SJustin T. Gibbs } 74217d24755SJustin T. Gibbs 74317d24755SJustin T. Gibbs static __inline struct scb * 74417d24755SJustin T. Gibbs ahd_lookup_scb(struct ahd_softc *ahd, u_int tag) 74517d24755SJustin T. Gibbs { 74617d24755SJustin T. Gibbs struct scb* scb; 74717d24755SJustin T. Gibbs 74817d24755SJustin T. Gibbs if (tag >= AHD_SCB_MAX) 74917d24755SJustin T. Gibbs return (NULL); 75017d24755SJustin T. Gibbs scb = ahd->scb_data.scbindex[tag]; 75117d24755SJustin T. Gibbs if (scb != NULL) 75217d24755SJustin T. Gibbs ahd_sync_scb(ahd, scb, 75317d24755SJustin T. Gibbs BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 75417d24755SJustin T. Gibbs return (scb); 75517d24755SJustin T. Gibbs } 75617d24755SJustin T. Gibbs 75717d24755SJustin T. Gibbs static __inline void 75817d24755SJustin T. Gibbs ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) 75917d24755SJustin T. Gibbs { 76017d24755SJustin T. Gibbs struct hardware_scb *q_hscb; 76117d24755SJustin T. Gibbs uint32_t saved_hscb_busaddr; 76217d24755SJustin T. Gibbs 76317d24755SJustin T. Gibbs /* 76417d24755SJustin T. Gibbs * Our queuing method is a bit tricky. The card 76517d24755SJustin T. Gibbs * knows in advance which HSCB (by address) to download, 76617d24755SJustin T. Gibbs * and we can't disappoint it. To achieve this, the next 767adcf242eSJustin T. Gibbs * HSCB to download is saved off in ahd->next_queued_hscb. 76817d24755SJustin T. Gibbs * When we are called to queue "an arbitrary scb", 76917d24755SJustin T. Gibbs * we copy the contents of the incoming HSCB to the one 77017d24755SJustin T. Gibbs * the sequencer knows about, swap HSCB pointers and 77117d24755SJustin T. Gibbs * finally assign the SCB to the tag indexed location 77217d24755SJustin T. Gibbs * in the scb_array. This makes sure that we can still 77317d24755SJustin T. Gibbs * locate the correct SCB by SCB_TAG. 77417d24755SJustin T. Gibbs */ 775adcf242eSJustin T. Gibbs q_hscb = ahd->next_queued_hscb; 77617d24755SJustin T. Gibbs saved_hscb_busaddr = q_hscb->hscb_busaddr; 77717d24755SJustin T. Gibbs memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); 77817d24755SJustin T. Gibbs q_hscb->hscb_busaddr = saved_hscb_busaddr; 77917d24755SJustin T. Gibbs q_hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; 78017d24755SJustin T. Gibbs 78117d24755SJustin T. Gibbs /* Now swap HSCB pointers. */ 782adcf242eSJustin T. Gibbs ahd->next_queued_hscb = scb->hscb; 78317d24755SJustin T. Gibbs scb->hscb = q_hscb; 78417d24755SJustin T. Gibbs 78517d24755SJustin T. Gibbs /* Now define the mapping from tag to SCB in the scbindex */ 78617d24755SJustin T. Gibbs /* XXX This should be constant now. Can we avoid the mapping? */ 78717d24755SJustin T. Gibbs ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; 78817d24755SJustin T. Gibbs } 78917d24755SJustin T. Gibbs 79017d24755SJustin T. Gibbs /* 79117d24755SJustin T. Gibbs * Tell the sequencer about a new transaction to execute. 79217d24755SJustin T. Gibbs */ 79317d24755SJustin T. Gibbs static __inline void 79417d24755SJustin T. Gibbs ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb) 79517d24755SJustin T. Gibbs { 79617d24755SJustin T. Gibbs ahd_swap_with_next_hscb(ahd, scb); 79717d24755SJustin T. Gibbs 79817d24755SJustin T. Gibbs if (SCBID_IS_NULL(SCB_GET_TAG(scb))) 79917d24755SJustin T. Gibbs panic("Attempt to queue invalid SCB tag %x\n", 80017d24755SJustin T. Gibbs SCB_GET_TAG(scb)); 80117d24755SJustin T. Gibbs 80217d24755SJustin T. Gibbs /* 80317d24755SJustin T. Gibbs * Keep a history of SCBs we've downloaded in the qinfifo. 80417d24755SJustin T. Gibbs */ 80517d24755SJustin T. Gibbs ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); 80617d24755SJustin T. Gibbs ahd->qinfifonext++; 80717d24755SJustin T. Gibbs 80817d24755SJustin T. Gibbs if (scb->sg_count != 0) 80917d24755SJustin T. Gibbs ahd_setup_data_scb(ahd, scb); 81017d24755SJustin T. Gibbs else 81117d24755SJustin T. Gibbs ahd_setup_noxfer_scb(ahd, scb); 81217d24755SJustin T. Gibbs ahd_setup_scb_common(ahd, scb); 81317d24755SJustin T. Gibbs 81417d24755SJustin T. Gibbs /* 81517d24755SJustin T. Gibbs * Make sure our data is consistant from the 81617d24755SJustin T. Gibbs * perspective of the adapter. 81717d24755SJustin T. Gibbs */ 81817d24755SJustin T. Gibbs ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 81917d24755SJustin T. Gibbs 82017d24755SJustin T. Gibbs #ifdef AHD_DEBUG 82117d24755SJustin T. Gibbs if ((ahd_debug & AHD_SHOW_QUEUE) != 0) { 82217d24755SJustin T. Gibbs printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n", 82317d24755SJustin T. Gibbs ahd_name(ahd), 82417d24755SJustin T. Gibbs SCB_GET_TAG(scb), scb->hscb->hscb_busaddr, 82517d24755SJustin T. Gibbs (u_int)((scb->hscb->dataptr >> 32) & 0xFFFFFFFF), 82617d24755SJustin T. Gibbs (u_int)(scb->hscb->dataptr & 0xFFFFFFFF), 82717d24755SJustin T. Gibbs scb->hscb->datacnt); 82817d24755SJustin T. Gibbs } 82917d24755SJustin T. Gibbs #endif 83017d24755SJustin T. Gibbs /* Tell the adapter about the newly queued SCB */ 83117d24755SJustin T. Gibbs ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); 83217d24755SJustin T. Gibbs } 83317d24755SJustin T. Gibbs 83417d24755SJustin T. Gibbs static __inline uint8_t * 83517d24755SJustin T. Gibbs ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb) 83617d24755SJustin T. Gibbs { 83717d24755SJustin T. Gibbs return (scb->sense_data); 83817d24755SJustin T. Gibbs } 83917d24755SJustin T. Gibbs 84017d24755SJustin T. Gibbs static __inline uint32_t 84117d24755SJustin T. Gibbs ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb) 84217d24755SJustin T. Gibbs { 84317d24755SJustin T. Gibbs return (scb->sense_busaddr); 84417d24755SJustin T. Gibbs } 84517d24755SJustin T. Gibbs 84617d24755SJustin T. Gibbs /************************** Interrupt Processing ******************************/ 84717d24755SJustin T. Gibbs static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op); 84817d24755SJustin T. Gibbs static __inline void ahd_sync_tqinfifo(struct ahd_softc *ahd, int op); 84917d24755SJustin T. Gibbs static __inline u_int ahd_check_cmdcmpltqueues(struct ahd_softc *ahd); 85017d24755SJustin T. Gibbs static __inline void ahd_intr(struct ahd_softc *ahd); 85117d24755SJustin T. Gibbs 85217d24755SJustin T. Gibbs static __inline void 85317d24755SJustin T. Gibbs ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) 85417d24755SJustin T. Gibbs { 85517d24755SJustin T. Gibbs ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, 85617d24755SJustin T. Gibbs /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op); 85717d24755SJustin T. Gibbs } 85817d24755SJustin T. Gibbs 85917d24755SJustin T. Gibbs static __inline void 86017d24755SJustin T. Gibbs ahd_sync_tqinfifo(struct ahd_softc *ahd, int op) 86117d24755SJustin T. Gibbs { 86217d24755SJustin T. Gibbs #ifdef AHD_TARGET_MODE 86317d24755SJustin T. Gibbs if ((ahd->flags & AHD_TARGETROLE) != 0) { 86417d24755SJustin T. Gibbs ahd_dmamap_sync(ahd, ahd->shared_data_dmat, 86517d24755SJustin T. Gibbs ahd->shared_data_dmamap, 86617d24755SJustin T. Gibbs ahd_targetcmd_offset(ahd, 0), 86717d24755SJustin T. Gibbs sizeof(struct target_cmd) * AHD_TMODE_CMDS, 86817d24755SJustin T. Gibbs op); 86917d24755SJustin T. Gibbs } 87017d24755SJustin T. Gibbs #endif 87117d24755SJustin T. Gibbs } 87217d24755SJustin T. Gibbs 87317d24755SJustin T. Gibbs /* 87417d24755SJustin T. Gibbs * See if the firmware has posted any completed commands 87517d24755SJustin T. Gibbs * into our in-core command complete fifos. 87617d24755SJustin T. Gibbs */ 87717d24755SJustin T. Gibbs #define AHD_RUN_QOUTFIFO 0x1 87817d24755SJustin T. Gibbs #define AHD_RUN_TQINFIFO 0x2 87917d24755SJustin T. Gibbs static __inline u_int 88017d24755SJustin T. Gibbs ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) 88117d24755SJustin T. Gibbs { 88217d24755SJustin T. Gibbs u_int retval; 88317d24755SJustin T. Gibbs 88417d24755SJustin T. Gibbs retval = 0; 88517d24755SJustin T. Gibbs ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, 88617d24755SJustin T. Gibbs /*offset*/ahd->qoutfifonext, /*len*/2, 88717d24755SJustin T. Gibbs BUS_DMASYNC_POSTREAD); 888adcf242eSJustin T. Gibbs if ((ahd->qoutfifo[ahd->qoutfifonext] 889adcf242eSJustin T. Gibbs & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) 89017d24755SJustin T. Gibbs retval |= AHD_RUN_QOUTFIFO; 89117d24755SJustin T. Gibbs #ifdef AHD_TARGET_MODE 89217d24755SJustin T. Gibbs if ((ahd->flags & AHD_TARGETROLE) != 0 89317d24755SJustin T. Gibbs && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { 89417d24755SJustin T. Gibbs ahd_dmamap_sync(ahd, ahd->shared_data_dmat, 89517d24755SJustin T. Gibbs ahd->shared_data_dmamap, 89617d24755SJustin T. Gibbs ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), 89717d24755SJustin T. Gibbs /*len*/sizeof(struct target_cmd), 89817d24755SJustin T. Gibbs BUS_DMASYNC_POSTREAD); 89917d24755SJustin T. Gibbs if (ahd->targetcmds[ahd->tqinfifonext].cmd_valid != 0) 90017d24755SJustin T. Gibbs retval |= AHD_RUN_TQINFIFO; 90117d24755SJustin T. Gibbs } 90217d24755SJustin T. Gibbs #endif 90317d24755SJustin T. Gibbs return (retval); 90417d24755SJustin T. Gibbs } 90517d24755SJustin T. Gibbs 90617d24755SJustin T. Gibbs /* 90717d24755SJustin T. Gibbs * Catch an interrupt from the adapter 90817d24755SJustin T. Gibbs */ 90917d24755SJustin T. Gibbs static __inline void 91017d24755SJustin T. Gibbs ahd_intr(struct ahd_softc *ahd) 91117d24755SJustin T. Gibbs { 91217d24755SJustin T. Gibbs u_int intstat; 91317d24755SJustin T. Gibbs 914adcf242eSJustin T. Gibbs if ((ahd->pause & INTEN) == 0) { 915adcf242eSJustin T. Gibbs /* 916adcf242eSJustin T. Gibbs * Our interrupt is not enabled on the chip 917adcf242eSJustin T. Gibbs * and may be disabled for re-entrancy reasons, 918adcf242eSJustin T. Gibbs * so just return. This is likely just a shared 919adcf242eSJustin T. Gibbs * interrupt. 920adcf242eSJustin T. Gibbs */ 921adcf242eSJustin T. Gibbs return; 922adcf242eSJustin T. Gibbs } 923adcf242eSJustin T. Gibbs 92417d24755SJustin T. Gibbs /* 92517d24755SJustin T. Gibbs * Instead of directly reading the interrupt status register, 92617d24755SJustin T. Gibbs * infer the cause of the interrupt by checking our in-core 92717d24755SJustin T. Gibbs * completion queues. This avoids a costly PCI bus read in 92817d24755SJustin T. Gibbs * most cases. 92917d24755SJustin T. Gibbs */ 93017d24755SJustin T. Gibbs if ((ahd->flags & AHD_ALL_INTERRUPTS) == 0 93117d24755SJustin T. Gibbs && (ahd_check_cmdcmpltqueues(ahd) != 0)) 93217d24755SJustin T. Gibbs intstat = CMDCMPLT; 93317d24755SJustin T. Gibbs else 93417d24755SJustin T. Gibbs intstat = ahd_inb(ahd, INTSTAT); 93517d24755SJustin T. Gibbs 93617d24755SJustin T. Gibbs if (intstat & CMDCMPLT) { 93717d24755SJustin T. Gibbs ahd_outb(ahd, CLRINT, CLRCMDINT); 93817d24755SJustin T. Gibbs 93917d24755SJustin T. Gibbs /* 94017d24755SJustin T. Gibbs * Ensure that the chip sees that we've cleared 94117d24755SJustin T. Gibbs * this interrupt before we walk the output fifo. 94217d24755SJustin T. Gibbs * Otherwise, we may, due to posted bus writes, 94317d24755SJustin T. Gibbs * clear the interrupt after we finish the scan, 94417d24755SJustin T. Gibbs * and after the sequencer has added new entries 94517d24755SJustin T. Gibbs * and asserted the interrupt again. 94617d24755SJustin T. Gibbs */ 94717d24755SJustin T. Gibbs ahd_flush_device_writes(ahd); 94817d24755SJustin T. Gibbs ahd_run_qoutfifo(ahd); 94917d24755SJustin T. Gibbs #ifdef AHD_TARGET_MODE 95017d24755SJustin T. Gibbs if ((ahd->flags & AHD_TARGETROLE) != 0) 95117d24755SJustin T. Gibbs ahd_run_tqinfifo(ahd, /*paused*/FALSE); 95217d24755SJustin T. Gibbs #endif 95317d24755SJustin T. Gibbs } 95417d24755SJustin T. Gibbs 95517d24755SJustin T. Gibbs if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) 95617d24755SJustin T. Gibbs /* Hot eject */ 95717d24755SJustin T. Gibbs return; 95817d24755SJustin T. Gibbs 95917d24755SJustin T. Gibbs if ((intstat & INT_PEND) == 0) 96017d24755SJustin T. Gibbs return; 96117d24755SJustin T. Gibbs 96217d24755SJustin T. Gibbs if (intstat & HWERRINT) { 96317d24755SJustin T. Gibbs ahd_handle_hwerrint(ahd); 96417d24755SJustin T. Gibbs return; 96517d24755SJustin T. Gibbs } 96617d24755SJustin T. Gibbs 96717d24755SJustin T. Gibbs if ((intstat & (PCIINT|SPLTINT)) != 0) { 96817d24755SJustin T. Gibbs ahd->bus_intr(ahd); 96917d24755SJustin T. Gibbs return; 97017d24755SJustin T. Gibbs } 97117d24755SJustin T. Gibbs 97217d24755SJustin T. Gibbs if ((intstat & SEQINT) != 0) 97317d24755SJustin T. Gibbs ahd_handle_seqint(ahd, intstat); 97417d24755SJustin T. Gibbs 97517d24755SJustin T. Gibbs if ((intstat & SCSIINT) != 0) 97617d24755SJustin T. Gibbs ahd_handle_scsiint(ahd, intstat); 97717d24755SJustin T. Gibbs } 97817d24755SJustin T. Gibbs 97917d24755SJustin T. Gibbs #endif /* _AIC79XX_INLINE_H_ */ 980