1098ca2bdSWarner Losh /*- 217d24755SJustin T. Gibbs * Core definitions and data structures shareable across OS platforms. 317d24755SJustin T. Gibbs * 4718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 5718cf2ccSPedro F. Giffuni * 6544c53b8SJustin T. Gibbs * Copyright (c) 1994-2002 Justin T. Gibbs. 7544c53b8SJustin T. Gibbs * Copyright (c) 2000-2002 Adaptec Inc. 817d24755SJustin T. Gibbs * All rights reserved. 917d24755SJustin T. Gibbs * 1017d24755SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 1117d24755SJustin T. Gibbs * modification, are permitted provided that the following conditions 1217d24755SJustin T. Gibbs * are met: 1317d24755SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 1417d24755SJustin T. Gibbs * notice, this list of conditions, and the following disclaimer, 1517d24755SJustin T. Gibbs * without modification. 1617d24755SJustin T. Gibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1717d24755SJustin T. Gibbs * substantially similar to the "NO WARRANTY" disclaimer below 1817d24755SJustin T. Gibbs * ("Disclaimer") and any redistribution must be conditioned upon 1917d24755SJustin T. Gibbs * including a substantially similar Disclaimer requirement for further 2017d24755SJustin T. Gibbs * binary redistribution. 2117d24755SJustin T. Gibbs * 3. Neither the names of the above-listed copyright holders nor the names 2217d24755SJustin T. Gibbs * of any contributors may be used to endorse or promote products derived 2317d24755SJustin T. Gibbs * from this software without specific prior written permission. 2417d24755SJustin T. Gibbs * 2517d24755SJustin T. Gibbs * Alternatively, this software may be distributed under the terms of the 2617d24755SJustin T. Gibbs * GNU General Public License ("GPL") version 2 as published by the Free 2717d24755SJustin T. Gibbs * Software Foundation. 2817d24755SJustin T. Gibbs * 2917d24755SJustin T. Gibbs * NO WARRANTY 3017d24755SJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3117d24755SJustin T. Gibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3217d24755SJustin T. Gibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3317d24755SJustin T. Gibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3417d24755SJustin T. Gibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3517d24755SJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3617d24755SJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3717d24755SJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3817d24755SJustin T. Gibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3917d24755SJustin T. Gibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4017d24755SJustin T. Gibbs * POSSIBILITY OF SUCH DAMAGES. 4117d24755SJustin T. Gibbs * 4222dbd4c6SJustin T. Gibbs * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#107 $ 4317d24755SJustin T. Gibbs */ 4417d24755SJustin T. Gibbs 4517d24755SJustin T. Gibbs #ifndef _AIC79XX_H_ 4617d24755SJustin T. Gibbs #define _AIC79XX_H_ 4717d24755SJustin T. Gibbs 4817d24755SJustin T. Gibbs /* Register Definitions */ 4917d24755SJustin T. Gibbs #include "aic79xx_reg.h" 5017d24755SJustin T. Gibbs 5117d24755SJustin T. Gibbs /************************* Forward Declarations *******************************/ 5217d24755SJustin T. Gibbs struct ahd_platform_data; 5317d24755SJustin T. Gibbs struct scb_platform_data; 5417d24755SJustin T. Gibbs 5517d24755SJustin T. Gibbs /****************************** Useful Macros *********************************/ 5617d24755SJustin T. Gibbs #ifndef MAX 5717d24755SJustin T. Gibbs #define MAX(a,b) (((a) > (b)) ? (a) : (b)) 5817d24755SJustin T. Gibbs #endif 5917d24755SJustin T. Gibbs 6017d24755SJustin T. Gibbs #ifndef MIN 6117d24755SJustin T. Gibbs #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 6217d24755SJustin T. Gibbs #endif 6317d24755SJustin T. Gibbs 6417d24755SJustin T. Gibbs #ifndef TRUE 6517d24755SJustin T. Gibbs #define TRUE 1 6617d24755SJustin T. Gibbs #endif 6717d24755SJustin T. Gibbs #ifndef FALSE 6817d24755SJustin T. Gibbs #define FALSE 0 6917d24755SJustin T. Gibbs #endif 7017d24755SJustin T. Gibbs 7117d24755SJustin T. Gibbs #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) 7217d24755SJustin T. Gibbs 7317d24755SJustin T. Gibbs #define ALL_CHANNELS '\0' 7417d24755SJustin T. Gibbs #define ALL_TARGETS_MASK 0xFFFF 7517d24755SJustin T. Gibbs #define INITIATOR_WILDCARD (~0) 7617d24755SJustin T. Gibbs #define SCB_LIST_NULL 0xFF00 77b3b25f2cSJustin T. Gibbs #define SCB_LIST_NULL_LE (aic_htole16(SCB_LIST_NULL)) 784164174aSJustin T. Gibbs #define QOUTFIFO_ENTRY_VALID 0x80 7917d24755SJustin T. Gibbs #define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL) 8017d24755SJustin T. Gibbs 8117d24755SJustin T. Gibbs #define SCSIID_TARGET(ahd, scsiid) \ 8217d24755SJustin T. Gibbs (((scsiid) & TID) >> TID_SHIFT) 8317d24755SJustin T. Gibbs #define SCSIID_OUR_ID(scsiid) \ 8417d24755SJustin T. Gibbs ((scsiid) & OID) 8517d24755SJustin T. Gibbs #define SCSIID_CHANNEL(ahd, scsiid) ('A') 8617d24755SJustin T. Gibbs #define SCB_IS_SCSIBUS_B(ahd, scb) (0) 8717d24755SJustin T. Gibbs #define SCB_GET_OUR_ID(scb) \ 8817d24755SJustin T. Gibbs SCSIID_OUR_ID((scb)->hscb->scsiid) 8917d24755SJustin T. Gibbs #define SCB_GET_TARGET(ahd, scb) \ 9017d24755SJustin T. Gibbs SCSIID_TARGET((ahd), (scb)->hscb->scsiid) 9117d24755SJustin T. Gibbs #define SCB_GET_CHANNEL(ahd, scb) \ 9217d24755SJustin T. Gibbs SCSIID_CHANNEL(ahd, (scb)->hscb->scsiid) 9317d24755SJustin T. Gibbs #define SCB_GET_LUN(scb) \ 9417d24755SJustin T. Gibbs ((scb)->hscb->lun) 9517d24755SJustin T. Gibbs #define SCB_GET_TARGET_OFFSET(ahd, scb) \ 9617d24755SJustin T. Gibbs SCB_GET_TARGET(ahd, scb) 9717d24755SJustin T. Gibbs #define SCB_GET_TARGET_MASK(ahd, scb) \ 9817d24755SJustin T. Gibbs (0x01 << (SCB_GET_TARGET_OFFSET(ahd, scb))) 990794987dSJustin T. Gibbs #ifdef AHD_DEBUG 1000794987dSJustin T. Gibbs #define SCB_IS_SILENT(scb) \ 1010794987dSJustin T. Gibbs ((ahd_debug & AHD_SHOW_MASKED_ERRORS) == 0 \ 1020794987dSJustin T. Gibbs && (((scb)->flags & SCB_SILENT) != 0)) 1030794987dSJustin T. Gibbs #else 1040794987dSJustin T. Gibbs #define SCB_IS_SILENT(scb) \ 1050794987dSJustin T. Gibbs (((scb)->flags & SCB_SILENT) != 0) 1060794987dSJustin T. Gibbs #endif 10717d24755SJustin T. Gibbs /* 10817d24755SJustin T. Gibbs * TCLs have the following format: TTTTLLLLLLLL 10917d24755SJustin T. Gibbs */ 11017d24755SJustin T. Gibbs #define TCL_TARGET_OFFSET(tcl) \ 11117d24755SJustin T. Gibbs ((((tcl) >> 4) & TID) >> 4) 11217d24755SJustin T. Gibbs #define TCL_LUN(tcl) \ 113544c53b8SJustin T. Gibbs (tcl & (AHD_NUM_LUNS - 1)) 11417d24755SJustin T. Gibbs #define BUILD_TCL(scsiid, lun) \ 11517d24755SJustin T. Gibbs ((lun) | (((scsiid) & TID) << 4)) 11617d24755SJustin T. Gibbs #define BUILD_TCL_RAW(target, channel, lun) \ 11717d24755SJustin T. Gibbs ((lun) | ((target) << 8)) 11817d24755SJustin T. Gibbs 11917d24755SJustin T. Gibbs #define SCB_GET_TAG(scb) \ 120b3b25f2cSJustin T. Gibbs aic_le16toh(scb->hscb->tag) 12117d24755SJustin T. Gibbs 12217d24755SJustin T. Gibbs #ifndef AHD_TARGET_MODE 12317d24755SJustin T. Gibbs #undef AHD_TMODE_ENABLE 12417d24755SJustin T. Gibbs #define AHD_TMODE_ENABLE 0 12517d24755SJustin T. Gibbs #endif 12617d24755SJustin T. Gibbs 127544c53b8SJustin T. Gibbs #define AHD_BUILD_COL_IDX(target, lun) \ 128544c53b8SJustin T. Gibbs (((lun) << 4) | target) 129544c53b8SJustin T. Gibbs 130544c53b8SJustin T. Gibbs #define AHD_GET_SCB_COL_IDX(ahd, scb) \ 131544c53b8SJustin T. Gibbs ((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb)) 132544c53b8SJustin T. Gibbs 133544c53b8SJustin T. Gibbs #define AHD_SET_SCB_COL_IDX(scb, col_idx) \ 134544c53b8SJustin T. Gibbs do { \ 135544c53b8SJustin T. Gibbs (scb)->hscb->scsiid = ((col_idx) << TID_SHIFT) & TID; \ 136544c53b8SJustin T. Gibbs (scb)->hscb->lun = ((col_idx) >> 4) & (AHD_NUM_LUNS_NONPKT-1); \ 137544c53b8SJustin T. Gibbs } while (0) 138544c53b8SJustin T. Gibbs 139544c53b8SJustin T. Gibbs #define AHD_COPY_SCB_COL_IDX(dst, src) \ 140544c53b8SJustin T. Gibbs do { \ 141544c53b8SJustin T. Gibbs dst->hscb->scsiid = src->hscb->scsiid; \ 142544c53b8SJustin T. Gibbs dst->hscb->lun = src->hscb->lun; \ 143544c53b8SJustin T. Gibbs } while (0) 144544c53b8SJustin T. Gibbs 145544c53b8SJustin T. Gibbs #define AHD_NEVER_COL_IDX 0xFFFF 146544c53b8SJustin T. Gibbs 14717d24755SJustin T. Gibbs /**************************** Driver Constants ********************************/ 14817d24755SJustin T. Gibbs /* 14917d24755SJustin T. Gibbs * The maximum number of supported targets. 15017d24755SJustin T. Gibbs */ 15117d24755SJustin T. Gibbs #define AHD_NUM_TARGETS 16 15217d24755SJustin T. Gibbs 15317d24755SJustin T. Gibbs /* 15417d24755SJustin T. Gibbs * The maximum number of supported luns. 15517d24755SJustin T. Gibbs * The identify message only supports 64 luns in non-packetized transfers. 15617d24755SJustin T. Gibbs * You can have 2^64 luns when information unit transfers are enabled, 15717d24755SJustin T. Gibbs * but until we see a need to support that many, we support 256. 15817d24755SJustin T. Gibbs */ 15917d24755SJustin T. Gibbs #define AHD_NUM_LUNS_NONPKT 64 16017d24755SJustin T. Gibbs #define AHD_NUM_LUNS 256 16117d24755SJustin T. Gibbs 16217d24755SJustin T. Gibbs /* 16317d24755SJustin T. Gibbs * The maximum transfer per S/G segment. 16417d24755SJustin T. Gibbs */ 16517d24755SJustin T. Gibbs #define AHD_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */ 16617d24755SJustin T. Gibbs 16717d24755SJustin T. Gibbs /* 16817d24755SJustin T. Gibbs * The maximum amount of SCB storage in hardware on a controller. 16917d24755SJustin T. Gibbs * This value represents an upper bound. Due to software design, 17017d24755SJustin T. Gibbs * we may not be able to use this number. 17117d24755SJustin T. Gibbs */ 17217d24755SJustin T. Gibbs #define AHD_SCB_MAX 512 17317d24755SJustin T. Gibbs 17417d24755SJustin T. Gibbs /* 17517d24755SJustin T. Gibbs * The maximum number of concurrent transactions supported per driver instance. 17617d24755SJustin T. Gibbs * Sequencer Control Blocks (SCBs) store per-transaction information. 17717d24755SJustin T. Gibbs */ 178544c53b8SJustin T. Gibbs #define AHD_MAX_QUEUE AHD_SCB_MAX 17917d24755SJustin T. Gibbs 18017d24755SJustin T. Gibbs /* 18117d24755SJustin T. Gibbs * Define the size of our QIN and QOUT FIFOs. They must be a power of 2 182d7cff4abSJustin T. Gibbs * in size and accommodate as many transactions as can be queued concurrently. 18317d24755SJustin T. Gibbs */ 184544c53b8SJustin T. Gibbs #define AHD_QIN_SIZE AHD_MAX_QUEUE 185544c53b8SJustin T. Gibbs #define AHD_QOUT_SIZE AHD_MAX_QUEUE 18617d24755SJustin T. Gibbs 18717d24755SJustin T. Gibbs #define AHD_QIN_WRAP(x) ((x) & (AHD_QIN_SIZE-1)) 18817d24755SJustin T. Gibbs /* 189544c53b8SJustin T. Gibbs * The maximum amount of SCB storage we allocate in host memory. 19017d24755SJustin T. Gibbs */ 191544c53b8SJustin T. Gibbs #define AHD_SCB_MAX_ALLOC AHD_MAX_QUEUE 19217d24755SJustin T. Gibbs 19317d24755SJustin T. Gibbs /* 19417d24755SJustin T. Gibbs * Ring Buffer of incoming target commands. 19517d24755SJustin T. Gibbs * We allocate 256 to simplify the logic in the sequencer 19617d24755SJustin T. Gibbs * by using the natural wrap point of an 8bit counter. 19717d24755SJustin T. Gibbs */ 19817d24755SJustin T. Gibbs #define AHD_TMODE_CMDS 256 19917d24755SJustin T. Gibbs 20017d24755SJustin T. Gibbs /* Reset line assertion time in us */ 201544c53b8SJustin T. Gibbs #define AHD_BUSRESET_DELAY 25 20217d24755SJustin T. Gibbs 20317d24755SJustin T. Gibbs /******************* Chip Characteristics/Operating Settings *****************/ 2044164174aSJustin T. Gibbs extern uint32_t ahd_attach_to_HostRAID_controllers; 2054164174aSJustin T. Gibbs 20617d24755SJustin T. Gibbs /* 20717d24755SJustin T. Gibbs * Chip Type 20817d24755SJustin T. Gibbs * The chip order is from least sophisticated to most sophisticated. 20917d24755SJustin T. Gibbs */ 21017d24755SJustin T. Gibbs typedef enum { 21117d24755SJustin T. Gibbs AHD_NONE = 0x0000, 21217d24755SJustin T. Gibbs AHD_CHIPID_MASK = 0x00FF, 21317d24755SJustin T. Gibbs AHD_AIC7901 = 0x0001, 21417d24755SJustin T. Gibbs AHD_AIC7902 = 0x0002, 215544c53b8SJustin T. Gibbs AHD_AIC7901A = 0x0003, 21617d24755SJustin T. Gibbs AHD_PCI = 0x0100, /* Bus type PCI */ 21717d24755SJustin T. Gibbs AHD_PCIX = 0x0200, /* Bus type PCIX */ 21817d24755SJustin T. Gibbs AHD_BUS_MASK = 0x0F00 21917d24755SJustin T. Gibbs } ahd_chip; 22017d24755SJustin T. Gibbs 22117d24755SJustin T. Gibbs /* 22217d24755SJustin T. Gibbs * Features available in each chip type. 22317d24755SJustin T. Gibbs */ 22417d24755SJustin T. Gibbs typedef enum { 22517d24755SJustin T. Gibbs AHD_FENONE = 0x00000, 22617d24755SJustin T. Gibbs AHD_WIDE = 0x00001,/* Wide Channel */ 2270c5aa4c5SScott Long AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */ 22817d24755SJustin T. Gibbs AHD_TARGETMODE = 0x01000,/* Has tested target mode support */ 22917d24755SJustin T. Gibbs AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */ 2300c5aa4c5SScott Long AHD_RTI = 0x04000,/* Retained Training Support */ 2310c5aa4c5SScott Long AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */ 2320c5aa4c5SScott Long AHD_NEW_DFCNTRL_OPTS = 0x10000,/* SCSIENWRDIS bit */ 233b3b25f2cSJustin T. Gibbs AHD_FAST_CDB_DELIVERY = 0x20000,/* CDB acks released to Output Sync */ 23417d24755SJustin T. Gibbs AHD_REMOVABLE = 0x00000,/* Hot-Swap supported - None so far*/ 23517d24755SJustin T. Gibbs AHD_AIC7901_FE = AHD_FENONE, 236c8ee7177SJustin T. Gibbs AHD_AIC7901A_FE = AHD_FENONE, 23717d24755SJustin T. Gibbs AHD_AIC7902_FE = AHD_MULTI_FUNC 23817d24755SJustin T. Gibbs } ahd_feature; 23917d24755SJustin T. Gibbs 24017d24755SJustin T. Gibbs /* 24117d24755SJustin T. Gibbs * Bugs in the silicon that we work around in software. 24217d24755SJustin T. Gibbs */ 24317d24755SJustin T. Gibbs typedef enum { 24417d24755SJustin T. Gibbs AHD_BUGNONE = 0x0000, 2450c5aa4c5SScott Long /* 2460c5aa4c5SScott Long * Rev A hardware fails to update LAST/CURR/NEXTSCB 2470c5aa4c5SScott Long * correctly in certain packetized selection cases. 2480c5aa4c5SScott Long */ 24917d24755SJustin T. Gibbs AHD_SENT_SCB_UPDATE_BUG = 0x0001, 2500c5aa4c5SScott Long /* The wrong SCB is accessed to check the abort pending bit. */ 25117d24755SJustin T. Gibbs AHD_ABORT_LQI_BUG = 0x0002, 2520c5aa4c5SScott Long /* Packetized bitbucket crosses packet boundaries. */ 25317d24755SJustin T. Gibbs AHD_PKT_BITBUCKET_BUG = 0x0004, 2540c5aa4c5SScott Long /* The selection timer runs twice as long as its setting. */ 25517d24755SJustin T. Gibbs AHD_LONG_SETIMO_BUG = 0x0008, 2560c5aa4c5SScott Long /* The Non-LQ CRC error status is delayed until phase change. */ 25717d24755SJustin T. Gibbs AHD_NLQICRC_DELAYED_BUG = 0x0010, 2580c5aa4c5SScott Long /* The chip must be reset for all outgoing bus resets. */ 25917d24755SJustin T. Gibbs AHD_SCSIRST_BUG = 0x0020, 2600c5aa4c5SScott Long /* Some PCIX fields must be saved and restored across chip reset. */ 261544c53b8SJustin T. Gibbs AHD_PCIX_CHIPRST_BUG = 0x0040, 2620c5aa4c5SScott Long /* MMAPIO is not functional in PCI-X mode. */ 263544c53b8SJustin T. Gibbs AHD_PCIX_MMAPIO_BUG = 0x0080, 2642cd3cc37SJustin T. Gibbs /* Reads to SCBRAM fail to reset the discard timer. */ 2652cd3cc37SJustin T. Gibbs AHD_PCIX_SCBRAM_RD_BUG = 0x0100, 26617d24755SJustin T. Gibbs /* Bug workarounds that can be disabled on non-PCIX busses. */ 267544c53b8SJustin T. Gibbs AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG 2682cd3cc37SJustin T. Gibbs | AHD_PCIX_MMAPIO_BUG 2692cd3cc37SJustin T. Gibbs | AHD_PCIX_SCBRAM_RD_BUG, 2700c5aa4c5SScott Long /* 2710c5aa4c5SScott Long * LQOSTOP0 status set even for forced selections with ATN 2720c5aa4c5SScott Long * to perform non-packetized message delivery. 2730c5aa4c5SScott Long */ 2742cd3cc37SJustin T. Gibbs AHD_LQO_ATNO_BUG = 0x0200, 2750c5aa4c5SScott Long /* FIFO auto-flush does not always trigger. */ 2762cd3cc37SJustin T. Gibbs AHD_AUTOFLUSH_BUG = 0x0400, 2770c5aa4c5SScott Long /* The CLRLQO registers are not self-clearing. */ 2782cd3cc37SJustin T. Gibbs AHD_CLRLQO_AUTOCLR_BUG = 0x0800, 2790c5aa4c5SScott Long /* The PACKETIZED status bit refers to the previous connection. */ 2802cd3cc37SJustin T. Gibbs AHD_PKTIZED_STATUS_BUG = 0x1000, 2810c5aa4c5SScott Long /* "Short Luns" are not placed into outgoing LQ packets correctly. */ 2822cd3cc37SJustin T. Gibbs AHD_PKT_LUN_BUG = 0x2000, 2830c5aa4c5SScott Long /* 2840c5aa4c5SScott Long * Only the FIFO allocated to the non-packetized connection may 2850c5aa4c5SScott Long * be in use during a non-packetzied connection. 2860c5aa4c5SScott Long */ 2872cd3cc37SJustin T. Gibbs AHD_NONPACKFIFO_BUG = 0x4000, 2880c5aa4c5SScott Long /* 289*5d785ad6SGordon Bergling * Writing to a DFF SCBPTR register may fail if concurrent with 2900c5aa4c5SScott Long * a hardware write to the other DFF SCBPTR register. This is 2910c5aa4c5SScott Long * not currently a concern in our sequencer since all chips with 2920c5aa4c5SScott Long * this bug have the AHD_NONPACKFIFO_BUG and all writes of concern 2930c5aa4c5SScott Long * occur in non-packetized connections. 2940c5aa4c5SScott Long */ 2952cd3cc37SJustin T. Gibbs AHD_MDFF_WSCBPTR_BUG = 0x8000, 2960c5aa4c5SScott Long /* SGHADDR updates are slow. */ 2972cd3cc37SJustin T. Gibbs AHD_REG_SLOW_SETTLE_BUG = 0x10000, 2980c5aa4c5SScott Long /* 2990c5aa4c5SScott Long * Changing the MODE_PTR coincident with an interrupt that 3000c5aa4c5SScott Long * switches to a different mode will cause the interrupt to 3010c5aa4c5SScott Long * be in the mode written outside of interrupt context. 3020c5aa4c5SScott Long */ 3032cd3cc37SJustin T. Gibbs AHD_SET_MODE_BUG = 0x20000, 3040c5aa4c5SScott Long /* Non-packetized busfree revision does not work. */ 3052cd3cc37SJustin T. Gibbs AHD_BUSFREEREV_BUG = 0x40000, 3060c5aa4c5SScott Long /* 3070c5aa4c5SScott Long * Paced transfers are indicated with a non-standard PPR 3080c5aa4c5SScott Long * option bit in the neg table, 160MHz is indicated by 3090c5aa4c5SScott Long * sync factor 0x7, and the offset if off by a factor of 2. 3100c5aa4c5SScott Long */ 3112cd3cc37SJustin T. Gibbs AHD_PACED_NEGTABLE_BUG = 0x80000, 3120c5aa4c5SScott Long /* LQOOVERRUN false positives. */ 3132cd3cc37SJustin T. Gibbs AHD_LQOOVERRUN_BUG = 0x100000, 3140c5aa4c5SScott Long /* 3150c5aa4c5SScott Long * Controller write to INTSTAT will lose to a host 3160c5aa4c5SScott Long * write to CLRINT. 3170c5aa4c5SScott Long */ 3182cd3cc37SJustin T. Gibbs AHD_INTCOLLISION_BUG = 0x200000, 319acae33b0SJustin T. Gibbs /* 320acae33b0SJustin T. Gibbs * The GEM318 violates the SCSI spec by not waiting 321acae33b0SJustin T. Gibbs * the mandated bus settle delay between phase changes 322acae33b0SJustin T. Gibbs * in some situations. Some aic79xx chip revs. are more 323acae33b0SJustin T. Gibbs * strict in this regard and will treat REQ assertions 324acae33b0SJustin T. Gibbs * that fall within the bus settle delay window as 325acae33b0SJustin T. Gibbs * glitches. This flag tells the firmware to tolerate 326acae33b0SJustin T. Gibbs * early REQ assertions. 327acae33b0SJustin T. Gibbs */ 328d7cff4abSJustin T. Gibbs AHD_EARLY_REQ_BUG = 0x400000, 329d7cff4abSJustin T. Gibbs /* 330d7cff4abSJustin T. Gibbs * The LED does not stay on long enough in packetized modes. 331d7cff4abSJustin T. Gibbs */ 332d7cff4abSJustin T. Gibbs AHD_FAINT_LED_BUG = 0x800000 33317d24755SJustin T. Gibbs } ahd_bug; 33417d24755SJustin T. Gibbs 33517d24755SJustin T. Gibbs /* 33617d24755SJustin T. Gibbs * Configuration specific settings. 33717d24755SJustin T. Gibbs * The driver determines these settings by probing the 33817d24755SJustin T. Gibbs * chip/controller's configuration. 33917d24755SJustin T. Gibbs */ 34017d24755SJustin T. Gibbs typedef enum { 34117d24755SJustin T. Gibbs AHD_FNONE = 0x00000, 342d7cff4abSJustin T. Gibbs AHD_BOOT_CHANNEL = 0x00001,/* We were set as the boot channel. */ 34317d24755SJustin T. Gibbs AHD_USEDEFAULTS = 0x00004,/* 34417d24755SJustin T. Gibbs * For cards without an seeprom 34517d24755SJustin T. Gibbs * or a BIOS to initialize the chip's 34617d24755SJustin T. Gibbs * SRAM, we use the default target 34717d24755SJustin T. Gibbs * settings. 34817d24755SJustin T. Gibbs */ 34917d24755SJustin T. Gibbs AHD_SEQUENCER_DEBUG = 0x00008, 35017d24755SJustin T. Gibbs AHD_RESET_BUS_A = 0x00010, 35117d24755SJustin T. Gibbs AHD_EXTENDED_TRANS_A = 0x00020, 35217d24755SJustin T. Gibbs AHD_TERM_ENB_A = 0x00040, 35317d24755SJustin T. Gibbs AHD_SPCHK_ENB_A = 0x00080, 35417d24755SJustin T. Gibbs AHD_STPWLEVEL_A = 0x00100, 35517d24755SJustin T. Gibbs AHD_INITIATORROLE = 0x00200,/* 35617d24755SJustin T. Gibbs * Allow initiator operations on 35717d24755SJustin T. Gibbs * this controller. 35817d24755SJustin T. Gibbs */ 35917d24755SJustin T. Gibbs AHD_TARGETROLE = 0x00400,/* 36017d24755SJustin T. Gibbs * Allow target operations on this 36117d24755SJustin T. Gibbs * controller. 36217d24755SJustin T. Gibbs */ 36317d24755SJustin T. Gibbs AHD_RESOURCE_SHORTAGE = 0x00800, 36417d24755SJustin T. Gibbs AHD_TQINFIFO_BLOCKED = 0x01000,/* Blocked waiting for ATIOs */ 36517d24755SJustin T. Gibbs AHD_INT50_SPEEDFLEX = 0x02000,/* 36617d24755SJustin T. Gibbs * Internal 50pin connector 36717d24755SJustin T. Gibbs * sits behind an aic3860 36817d24755SJustin T. Gibbs */ 36917d24755SJustin T. Gibbs AHD_BIOS_ENABLED = 0x04000, 37017d24755SJustin T. Gibbs AHD_ALL_INTERRUPTS = 0x08000, 37117d24755SJustin T. Gibbs AHD_39BIT_ADDRESSING = 0x10000,/* Use 39 bit addressing scheme. */ 37217d24755SJustin T. Gibbs AHD_64BIT_ADDRESSING = 0x20000,/* Use 64 bit addressing scheme. */ 37317d24755SJustin T. Gibbs AHD_CURRENT_SENSING = 0x40000, 37417d24755SJustin T. Gibbs AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */ 3750c5aa4c5SScott Long AHD_HP_BOARD = 0x100000, 3760794987dSJustin T. Gibbs AHD_RESET_POLL_ACTIVE = 0x200000, 3770794987dSJustin T. Gibbs AHD_UPDATE_PEND_CMDS = 0x400000, 3784294c2dcSJustin T. Gibbs AHD_RUNNING_QOUTFIFO = 0x800000, 379b3b25f2cSJustin T. Gibbs AHD_HAD_FIRST_SEL = 0x1000000, 3804164174aSJustin T. Gibbs AHD_SHUTDOWN_RECOVERY = 0x2000000, /* Terminate recovery thread. */ 3814164174aSJustin T. Gibbs AHD_HOSTRAID_BOARD = 0x4000000 38217d24755SJustin T. Gibbs } ahd_flag; 38317d24755SJustin T. Gibbs 38417d24755SJustin T. Gibbs /************************* Hardware SCB Definition ***************************/ 38517d24755SJustin T. Gibbs 38617d24755SJustin T. Gibbs /* 38717d24755SJustin T. Gibbs * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB 388d7cff4abSJustin T. Gibbs * consists of a "hardware SCB" mirroring the fields available on the card 38917d24755SJustin T. Gibbs * and additional information the kernel stores for each transaction. 39017d24755SJustin T. Gibbs * 39117d24755SJustin T. Gibbs * To minimize space utilization, a portion of the hardware scb stores 39217d24755SJustin T. Gibbs * different data during different portions of a SCSI transaction. 39317d24755SJustin T. Gibbs * As initialized by the host driver for the initiator role, this area 39417d24755SJustin T. Gibbs * contains the SCSI cdb (or a pointer to the cdb) to be executed. After 39517d24755SJustin T. Gibbs * the cdb has been presented to the target, this area serves to store 39617d24755SJustin T. Gibbs * residual transfer information and the SCSI status byte. 39717d24755SJustin T. Gibbs * For the target role, the contents of this area do not change, but 39817d24755SJustin T. Gibbs * still serve a different purpose than for the initiator role. See 39917d24755SJustin T. Gibbs * struct target_data for details. 40017d24755SJustin T. Gibbs */ 40117d24755SJustin T. Gibbs 40217d24755SJustin T. Gibbs /* 40317d24755SJustin T. Gibbs * Status information embedded in the shared poriton of 40417d24755SJustin T. Gibbs * an SCB after passing the cdb to the target. The kernel 40517d24755SJustin T. Gibbs * driver will only read this data for transactions that 40617d24755SJustin T. Gibbs * complete abnormally. 40717d24755SJustin T. Gibbs */ 40817d24755SJustin T. Gibbs struct initiator_status { 40917d24755SJustin T. Gibbs uint32_t residual_datacnt; /* Residual in the current S/G seg */ 41017d24755SJustin T. Gibbs uint32_t residual_sgptr; /* The next S/G for this transfer */ 41117d24755SJustin T. Gibbs uint8_t scsi_status; /* Standard SCSI status byte */ 41217d24755SJustin T. Gibbs }; 41317d24755SJustin T. Gibbs 41417d24755SJustin T. Gibbs struct target_status { 41517d24755SJustin T. Gibbs uint32_t residual_datacnt; /* Residual in the current S/G seg */ 41617d24755SJustin T. Gibbs uint32_t residual_sgptr; /* The next S/G for this transfer */ 41717d24755SJustin T. Gibbs uint8_t scsi_status; /* SCSI status to give to initiator */ 41817d24755SJustin T. Gibbs uint8_t target_phases; /* Bitmap of phases to execute */ 41917d24755SJustin T. Gibbs uint8_t data_phase; /* Data-In or Data-Out */ 42017d24755SJustin T. Gibbs uint8_t initiator_tag; /* Initiator's transaction tag */ 42117d24755SJustin T. Gibbs }; 42217d24755SJustin T. Gibbs 42317d24755SJustin T. Gibbs /* 42417d24755SJustin T. Gibbs * Initiator mode SCB shared data area. 42517d24755SJustin T. Gibbs * If the embedded CDB is 12 bytes or less, we embed 42617d24755SJustin T. Gibbs * the sense buffer address in the SCB. This allows 427acae33b0SJustin T. Gibbs * us to retrieve sense information without interrupting 42817d24755SJustin T. Gibbs * the host in packetized mode. 42917d24755SJustin T. Gibbs */ 43017d24755SJustin T. Gibbs typedef uint32_t sense_addr_t; 43117d24755SJustin T. Gibbs #define MAX_CDB_LEN 16 43217d24755SJustin T. Gibbs #define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t)) 43317d24755SJustin T. Gibbs union initiator_data { 434acae33b0SJustin T. Gibbs struct { 43517d24755SJustin T. Gibbs uint64_t cdbptr; 436acae33b0SJustin T. Gibbs uint8_t cdblen; 437acae33b0SJustin T. Gibbs } cdb_from_host; 43817d24755SJustin T. Gibbs uint8_t cdb[MAX_CDB_LEN]; 43917d24755SJustin T. Gibbs struct { 44017d24755SJustin T. Gibbs uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR]; 44117d24755SJustin T. Gibbs sense_addr_t sense_addr; 44217d24755SJustin T. Gibbs } cdb_plus_saddr; 44317d24755SJustin T. Gibbs }; 44417d24755SJustin T. Gibbs 44517d24755SJustin T. Gibbs /* 44617d24755SJustin T. Gibbs * Target mode version of the shared data SCB segment. 44717d24755SJustin T. Gibbs */ 44817d24755SJustin T. Gibbs struct target_data { 44917d24755SJustin T. Gibbs uint32_t spare[2]; 45017d24755SJustin T. Gibbs uint8_t scsi_status; /* SCSI status to give to initiator */ 45117d24755SJustin T. Gibbs uint8_t target_phases; /* Bitmap of phases to execute */ 45217d24755SJustin T. Gibbs uint8_t data_phase; /* Data-In or Data-Out */ 45317d24755SJustin T. Gibbs uint8_t initiator_tag; /* Initiator's transaction tag */ 45417d24755SJustin T. Gibbs }; 45517d24755SJustin T. Gibbs 45617d24755SJustin T. Gibbs struct hardware_scb { 45717d24755SJustin T. Gibbs /*0*/ union { 45817d24755SJustin T. Gibbs union initiator_data idata; 45917d24755SJustin T. Gibbs struct target_data tdata; 46017d24755SJustin T. Gibbs struct initiator_status istatus; 46117d24755SJustin T. Gibbs struct target_status tstatus; 46217d24755SJustin T. Gibbs } shared_data; 46317d24755SJustin T. Gibbs /* 46417d24755SJustin T. Gibbs * A word about residuals. 46517d24755SJustin T. Gibbs * The scb is presented to the sequencer with the dataptr and datacnt 46617d24755SJustin T. Gibbs * fields initialized to the contents of the first S/G element to 46717d24755SJustin T. Gibbs * transfer. The sgptr field is initialized to the bus address for 46817d24755SJustin T. Gibbs * the S/G element that follows the first in the in core S/G array 46917d24755SJustin T. Gibbs * or'ed with the SG_FULL_RESID flag. Sgptr may point to an invalid 47017d24755SJustin T. Gibbs * S/G entry for this transfer (single S/G element transfer with the 47117d24755SJustin T. Gibbs * first elements address and length preloaded in the dataptr/datacnt 47217d24755SJustin T. Gibbs * fields). If no transfer is to occur, sgptr is set to SG_LIST_NULL. 47317d24755SJustin T. Gibbs * The SG_FULL_RESID flag ensures that the residual will be correctly 47417d24755SJustin T. Gibbs * noted even if no data transfers occur. Once the data phase is entered, 47517d24755SJustin T. Gibbs * the residual sgptr and datacnt are loaded from the sgptr and the 47617d24755SJustin T. Gibbs * datacnt fields. After each S/G element's dataptr and length are 47717d24755SJustin T. Gibbs * loaded into the hardware, the residual sgptr is advanced. After 47817d24755SJustin T. Gibbs * each S/G element is expired, its datacnt field is checked to see 47917d24755SJustin T. Gibbs * if the LAST_SEG flag is set. If so, SG_LIST_NULL is set in the 48017d24755SJustin T. Gibbs * residual sg ptr and the transfer is considered complete. If the 481594c945aSPedro F. Giffuni * sequencer determines that there is a residual in the transfer, or 48217d24755SJustin T. Gibbs * there is non-zero status, it will set the SG_STATUS_VALID flag in 48317d24755SJustin T. Gibbs * sgptr and dma the scb back into host memory. To sumarize: 48417d24755SJustin T. Gibbs * 48517d24755SJustin T. Gibbs * Sequencer: 48617d24755SJustin T. Gibbs * o A residual has occurred if SG_FULL_RESID is set in sgptr, 48717d24755SJustin T. Gibbs * or residual_sgptr does not have SG_LIST_NULL set. 48817d24755SJustin T. Gibbs * 489594c945aSPedro F. Giffuni * o We are transferring the last segment if residual_datacnt has 49017d24755SJustin T. Gibbs * the SG_LAST_SEG flag set. 49117d24755SJustin T. Gibbs * 49217d24755SJustin T. Gibbs * Host: 49317d24755SJustin T. Gibbs * o A residual can only have occurred if a completed scb has the 49417d24755SJustin T. Gibbs * SG_STATUS_VALID flag set. Inspection of the SCSI status field, 49517d24755SJustin T. Gibbs * the residual_datacnt, and the residual_sgptr field will tell 49617d24755SJustin T. Gibbs * for sure. 49717d24755SJustin T. Gibbs * 49817d24755SJustin T. Gibbs * o residual_sgptr and sgptr refer to the "next" sg entry 49917d24755SJustin T. Gibbs * and so may point beyond the last valid sg entry for the 50017d24755SJustin T. Gibbs * transfer. 50117d24755SJustin T. Gibbs */ 50217d24755SJustin T. Gibbs #define SG_PTR_MASK 0xFFFFFFF8 5036ee007e1SScott Long /*16*/ uint16_t tag; /* Reused by Sequencer. */ 5046ee007e1SScott Long /*18*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */ 5056ee007e1SScott Long /*19*/ uint8_t scsiid; /* 50617d24755SJustin T. Gibbs * Selection out Id 50717d24755SJustin T. Gibbs * Our Id (bits 0-3) Their ID (bits 4-7) 50817d24755SJustin T. Gibbs */ 5096ee007e1SScott Long /*20*/ uint8_t lun; 5106ee007e1SScott Long /*21*/ uint8_t task_attribute; 5116ee007e1SScott Long /*22*/ uint8_t cdb_len; 5126ee007e1SScott Long /*23*/ uint8_t task_management; 5136ee007e1SScott Long /*24*/ uint64_t dataptr; 5146ee007e1SScott Long /*32*/ uint32_t datacnt; /* Byte 3 is spare. */ 5156ee007e1SScott Long /*36*/ uint32_t sgptr; 5166ee007e1SScott Long /*40*/ uint32_t hscb_busaddr; 5176ee007e1SScott Long /*44*/ uint32_t next_hscb_busaddr; 518d7cff4abSJustin T. Gibbs /********** Long lun field only downloaded for full 8 byte lun support ********/ 519544c53b8SJustin T. Gibbs /*48*/ uint8_t pkt_long_lun[8]; 52017d24755SJustin T. Gibbs /******* Fields below are not Downloaded (Sequencer may use for scratch) ******/ 521544c53b8SJustin T. Gibbs /*56*/ uint8_t spare[8]; 52217d24755SJustin T. Gibbs }; 52317d24755SJustin T. Gibbs 52417d24755SJustin T. Gibbs /************************ Kernel SCB Definitions ******************************/ 52517d24755SJustin T. Gibbs /* 52617d24755SJustin T. Gibbs * Some fields of the SCB are OS dependent. Here we collect the 52717d24755SJustin T. Gibbs * definitions for elements that all OS platforms need to include 52817d24755SJustin T. Gibbs * in there SCB definition. 52917d24755SJustin T. Gibbs */ 53017d24755SJustin T. Gibbs 53117d24755SJustin T. Gibbs /* 532594c945aSPedro F. Giffuni * Definition of a scatter/gather element as transferred to the controller. 53317d24755SJustin T. Gibbs * The aic7xxx chips only support a 24bit length. We use the top byte of 53417d24755SJustin T. Gibbs * the length to store additional address bits and a flag to indicate 53517d24755SJustin T. Gibbs * that a given segment terminates the transfer. This gives us an 53617d24755SJustin T. Gibbs * addressable range of 512GB on machines with 64bit PCI or with chips 53717d24755SJustin T. Gibbs * that can support dual address cycles on 32bit PCI busses. 53817d24755SJustin T. Gibbs */ 53917d24755SJustin T. Gibbs struct ahd_dma_seg { 54017d24755SJustin T. Gibbs uint32_t addr; 54117d24755SJustin T. Gibbs uint32_t len; 54217d24755SJustin T. Gibbs #define AHD_DMA_LAST_SEG 0x80000000 54317d24755SJustin T. Gibbs #define AHD_SG_HIGH_ADDR_MASK 0x7F000000 54417d24755SJustin T. Gibbs #define AHD_SG_LEN_MASK 0x00FFFFFF 54517d24755SJustin T. Gibbs }; 54617d24755SJustin T. Gibbs 54717d24755SJustin T. Gibbs struct ahd_dma64_seg { 54817d24755SJustin T. Gibbs uint64_t addr; 54917d24755SJustin T. Gibbs uint32_t len; 55017d24755SJustin T. Gibbs uint32_t pad; 55117d24755SJustin T. Gibbs }; 55217d24755SJustin T. Gibbs 55317d24755SJustin T. Gibbs struct map_node { 55417d24755SJustin T. Gibbs bus_dmamap_t dmamap; 555b3b25f2cSJustin T. Gibbs bus_addr_t busaddr; 55617d24755SJustin T. Gibbs uint8_t *vaddr; 55717d24755SJustin T. Gibbs SLIST_ENTRY(map_node) links; 55817d24755SJustin T. Gibbs }; 55917d24755SJustin T. Gibbs 56017d24755SJustin T. Gibbs /* 56117d24755SJustin T. Gibbs * The current state of this SCB. 56217d24755SJustin T. Gibbs */ 56317d24755SJustin T. Gibbs typedef enum { 564544c53b8SJustin T. Gibbs SCB_FLAG_NONE = 0x00000, 565544c53b8SJustin T. Gibbs SCB_TRANSMISSION_ERROR = 0x00001,/* 56617d24755SJustin T. Gibbs * We detected a parity or CRC 56717d24755SJustin T. Gibbs * error that has effected the 56817d24755SJustin T. Gibbs * payload of the command. This 56917d24755SJustin T. Gibbs * flag is checked when normal 57017d24755SJustin T. Gibbs * status is returned to catch 57117d24755SJustin T. Gibbs * the case of a target not 57217d24755SJustin T. Gibbs * responding to our attempt 57317d24755SJustin T. Gibbs * to report the error. 57417d24755SJustin T. Gibbs */ 575544c53b8SJustin T. Gibbs SCB_OTHERTCL_TIMEOUT = 0x00002,/* 57617d24755SJustin T. Gibbs * Another device was active 57717d24755SJustin T. Gibbs * during the first timeout for 57817d24755SJustin T. Gibbs * this SCB so we gave ourselves 57917d24755SJustin T. Gibbs * an additional timeout period 58017d24755SJustin T. Gibbs * in case it was hogging the 58117d24755SJustin T. Gibbs * bus. 58217d24755SJustin T. Gibbs */ 583544c53b8SJustin T. Gibbs SCB_DEVICE_RESET = 0x00004, 584544c53b8SJustin T. Gibbs SCB_SENSE = 0x00008, 585544c53b8SJustin T. Gibbs SCB_CDB32_PTR = 0x00010, 586544c53b8SJustin T. Gibbs SCB_RECOVERY_SCB = 0x00020, 587544c53b8SJustin T. Gibbs SCB_AUTO_NEGOTIATE = 0x00040,/* Negotiate to achieve goal. */ 588544c53b8SJustin T. Gibbs SCB_NEGOTIATE = 0x00080,/* Negotiation forced for command. */ 589544c53b8SJustin T. Gibbs SCB_ABORT = 0x00100, 5900c5aa4c5SScott Long SCB_ACTIVE = 0x00200, 5910c5aa4c5SScott Long SCB_TARGET_IMMEDIATE = 0x00400, 5920c5aa4c5SScott Long SCB_PACKETIZED = 0x00800, 5930c5aa4c5SScott Long SCB_EXPECT_PPR_BUSFREE = 0x01000, 5940c5aa4c5SScott Long SCB_PKT_SENSE = 0x02000, 5950c5aa4c5SScott Long SCB_CMDPHASE_ABORT = 0x04000, 5960794987dSJustin T. Gibbs SCB_ON_COL_LIST = 0x08000, 597b3b25f2cSJustin T. Gibbs SCB_SILENT = 0x10000,/* 5980794987dSJustin T. Gibbs * Be quiet about transmission type 5990794987dSJustin T. Gibbs * errors. They are expected and we 6000794987dSJustin T. Gibbs * don't want to upset the user. This 6010794987dSJustin T. Gibbs * flag is typically used during DV. 6020794987dSJustin T. Gibbs */ 603b3b25f2cSJustin T. Gibbs SCB_TIMEDOUT = 0x20000/* 604b3b25f2cSJustin T. Gibbs * SCB has timed out and is on the 605b3b25f2cSJustin T. Gibbs * timedout list. 606b3b25f2cSJustin T. Gibbs */ 60717d24755SJustin T. Gibbs } scb_flag; 60817d24755SJustin T. Gibbs 60917d24755SJustin T. Gibbs struct scb { 61017d24755SJustin T. Gibbs struct hardware_scb *hscb; 61117d24755SJustin T. Gibbs union { 61217d24755SJustin T. Gibbs SLIST_ENTRY(scb) sle; 613544c53b8SJustin T. Gibbs LIST_ENTRY(scb) le; 61417d24755SJustin T. Gibbs TAILQ_ENTRY(scb) tqe; 61517d24755SJustin T. Gibbs } links; 616544c53b8SJustin T. Gibbs union { 617544c53b8SJustin T. Gibbs SLIST_ENTRY(scb) sle; 618544c53b8SJustin T. Gibbs LIST_ENTRY(scb) le; 619544c53b8SJustin T. Gibbs TAILQ_ENTRY(scb) tqe; 620544c53b8SJustin T. Gibbs } links2; 621544c53b8SJustin T. Gibbs #define pending_links links2.le 622544c53b8SJustin T. Gibbs #define collision_links links2.le 623b3b25f2cSJustin T. Gibbs LIST_ENTRY(scb) timedout_links; 624544c53b8SJustin T. Gibbs struct scb *col_scb; 625b3b25f2cSJustin T. Gibbs aic_io_ctx_t io_ctx; 62617d24755SJustin T. Gibbs struct ahd_softc *ahd_softc; 62717d24755SJustin T. Gibbs scb_flag flags; 62817d24755SJustin T. Gibbs bus_dmamap_t dmamap; 62917d24755SJustin T. Gibbs struct scb_platform_data *platform_data; 63017d24755SJustin T. Gibbs struct map_node *hscb_map; 63117d24755SJustin T. Gibbs struct map_node *sg_map; 63217d24755SJustin T. Gibbs struct map_node *sense_map; 63317d24755SJustin T. Gibbs void *sg_list; 63417d24755SJustin T. Gibbs uint8_t *sense_data; 63517d24755SJustin T. Gibbs bus_addr_t sg_list_busaddr; 63617d24755SJustin T. Gibbs bus_addr_t sense_busaddr; 63717d24755SJustin T. Gibbs u_int sg_count;/* How full ahd_dma_seg is */ 6380c5aa4c5SScott Long #define AHD_MAX_LQ_CRC_ERRORS 5 6390c5aa4c5SScott Long u_int crc_retry_count; 640032b0a17SScott Long aic_timer_t io_timer; 64117d24755SJustin T. Gibbs }; 64217d24755SJustin T. Gibbs 643544c53b8SJustin T. Gibbs TAILQ_HEAD(scb_tailq, scb); 644544c53b8SJustin T. Gibbs LIST_HEAD(scb_list, scb); 645544c53b8SJustin T. Gibbs 64617d24755SJustin T. Gibbs struct scb_data { 647544c53b8SJustin T. Gibbs /* 648544c53b8SJustin T. Gibbs * TAILQ of lists of free SCBs grouped by device 649544c53b8SJustin T. Gibbs * collision domains. 65017d24755SJustin T. Gibbs */ 651544c53b8SJustin T. Gibbs struct scb_tailq free_scbs; 652544c53b8SJustin T. Gibbs 653544c53b8SJustin T. Gibbs /* 654544c53b8SJustin T. Gibbs * Per-device lists of SCBs whose tag ID would collide 655544c53b8SJustin T. Gibbs * with an already active tag on the device. 656544c53b8SJustin T. Gibbs */ 657544c53b8SJustin T. Gibbs struct scb_list free_scb_lists[AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT]; 658544c53b8SJustin T. Gibbs 659544c53b8SJustin T. Gibbs /* 660544c53b8SJustin T. Gibbs * SCBs that will not collide with any active device. 661544c53b8SJustin T. Gibbs */ 662544c53b8SJustin T. Gibbs struct scb_list any_dev_free_scb_list; 663544c53b8SJustin T. Gibbs 66417d24755SJustin T. Gibbs /* 66517d24755SJustin T. Gibbs * Mapping from tag to SCB. 66617d24755SJustin T. Gibbs */ 667544c53b8SJustin T. Gibbs struct scb *scbindex[AHD_SCB_MAX]; 668544c53b8SJustin T. Gibbs 6697afc0218SJustin T. Gibbs u_int recovery_scbs; /* Transactions currently in recovery */ 6707afc0218SJustin T. Gibbs 67117d24755SJustin T. Gibbs /* 67217d24755SJustin T. Gibbs * "Bus" addresses of our data structures. 67317d24755SJustin T. Gibbs */ 67417d24755SJustin T. Gibbs bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */ 67517d24755SJustin T. Gibbs bus_dma_tag_t sg_dmat; /* dmat for our sg segments */ 67617d24755SJustin T. Gibbs bus_dma_tag_t sense_dmat; /* dmat for our sense buffers */ 6777afc0218SJustin T. Gibbs 67817d24755SJustin T. Gibbs SLIST_HEAD(, map_node) hscb_maps; 67917d24755SJustin T. Gibbs SLIST_HEAD(, map_node) sg_maps; 68017d24755SJustin T. Gibbs SLIST_HEAD(, map_node) sense_maps; 68117d24755SJustin T. Gibbs int scbs_left; /* unallocated scbs in head map_node */ 68217d24755SJustin T. Gibbs int sgs_left; /* unallocated sgs in head map_node */ 68317d24755SJustin T. Gibbs int sense_left; /* unallocated sense in head map_node */ 68417d24755SJustin T. Gibbs uint16_t numscbs; 68517d24755SJustin T. Gibbs uint16_t maxhscbs; /* Number of SCBs on the card */ 68617d24755SJustin T. Gibbs uint8_t init_level; /* 68717d24755SJustin T. Gibbs * How far we've initialized 68817d24755SJustin T. Gibbs * this structure. 68917d24755SJustin T. Gibbs */ 69017d24755SJustin T. Gibbs }; 69117d24755SJustin T. Gibbs 69217d24755SJustin T. Gibbs /************************ Target Mode Definitions *****************************/ 69317d24755SJustin T. Gibbs 69417d24755SJustin T. Gibbs /* 695b1603638SGordon Bergling * Connection descriptor for select-in requests in target mode. 69617d24755SJustin T. Gibbs */ 69717d24755SJustin T. Gibbs struct target_cmd { 69817d24755SJustin T. Gibbs uint8_t scsiid; /* Our ID and the initiator's ID */ 69917d24755SJustin T. Gibbs uint8_t identify; /* Identify message */ 70017d24755SJustin T. Gibbs uint8_t bytes[22]; /* 70117d24755SJustin T. Gibbs * Bytes contains any additional message 70217d24755SJustin T. Gibbs * bytes terminated by 0xFF. The remainder 70317d24755SJustin T. Gibbs * is the cdb to execute. 70417d24755SJustin T. Gibbs */ 70517d24755SJustin T. Gibbs uint8_t cmd_valid; /* 70617d24755SJustin T. Gibbs * When a command is complete, the firmware 70717d24755SJustin T. Gibbs * will set cmd_valid to all bits set. 70817d24755SJustin T. Gibbs * After the host has seen the command, 70917d24755SJustin T. Gibbs * the bits are cleared. This allows us 71017d24755SJustin T. Gibbs * to just peek at host memory to determine 71117d24755SJustin T. Gibbs * if more work is complete. cmd_valid is on 71217d24755SJustin T. Gibbs * an 8 byte boundary to simplify setting 71317d24755SJustin T. Gibbs * it on aic7880 hardware which only has 71417d24755SJustin T. Gibbs * limited direct access to the DMA FIFO. 71517d24755SJustin T. Gibbs */ 71617d24755SJustin T. Gibbs uint8_t pad[7]; 71717d24755SJustin T. Gibbs }; 71817d24755SJustin T. Gibbs 71917d24755SJustin T. Gibbs /* 72017d24755SJustin T. Gibbs * Number of events we can buffer up if we run out 72117d24755SJustin T. Gibbs * of immediate notify ccbs. 72217d24755SJustin T. Gibbs */ 72317d24755SJustin T. Gibbs #define AHD_TMODE_EVENT_BUFFER_SIZE 8 72417d24755SJustin T. Gibbs struct ahd_tmode_event { 72517d24755SJustin T. Gibbs uint8_t initiator_id; 72617d24755SJustin T. Gibbs uint8_t event_type; /* MSG type or EVENT_TYPE_BUS_RESET */ 72717d24755SJustin T. Gibbs #define EVENT_TYPE_BUS_RESET 0xFF 72817d24755SJustin T. Gibbs uint8_t event_arg; 72917d24755SJustin T. Gibbs }; 73017d24755SJustin T. Gibbs 73117d24755SJustin T. Gibbs /* 73217d24755SJustin T. Gibbs * Per enabled lun target mode state. 73317d24755SJustin T. Gibbs * As this state is directly influenced by the host OS'es target mode 73417d24755SJustin T. Gibbs * environment, we let the OS module define it. Forward declare the 73517d24755SJustin T. Gibbs * structure here so we can store arrays of them, etc. in OS neutral 73617d24755SJustin T. Gibbs * data structures. 73717d24755SJustin T. Gibbs */ 73817d24755SJustin T. Gibbs #ifdef AHD_TARGET_MODE 73917d24755SJustin T. Gibbs struct ahd_tmode_lstate { 74017d24755SJustin T. Gibbs struct cam_path *path; 74117d24755SJustin T. Gibbs struct ccb_hdr_slist accept_tios; 74217d24755SJustin T. Gibbs struct ccb_hdr_slist immed_notifies; 74317d24755SJustin T. Gibbs struct ahd_tmode_event event_buffer[AHD_TMODE_EVENT_BUFFER_SIZE]; 74417d24755SJustin T. Gibbs uint8_t event_r_idx; 74517d24755SJustin T. Gibbs uint8_t event_w_idx; 74617d24755SJustin T. Gibbs }; 74717d24755SJustin T. Gibbs #else 74817d24755SJustin T. Gibbs struct ahd_tmode_lstate; 74917d24755SJustin T. Gibbs #endif 75017d24755SJustin T. Gibbs 75117d24755SJustin T. Gibbs /******************** Transfer Negotiation Datastructures *********************/ 75217d24755SJustin T. Gibbs #define AHD_TRANS_CUR 0x01 /* Modify current neogtiation status */ 75317d24755SJustin T. Gibbs #define AHD_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */ 75417d24755SJustin T. Gibbs #define AHD_TRANS_GOAL 0x04 /* Modify negotiation goal */ 75517d24755SJustin T. Gibbs #define AHD_TRANS_USER 0x08 /* Modify user negotiation settings */ 75617d24755SJustin T. Gibbs #define AHD_PERIOD_10MHz 0x19 75717d24755SJustin T. Gibbs 7580c5aa4c5SScott Long #define AHD_WIDTH_UNKNOWN 0xFF 7590c5aa4c5SScott Long #define AHD_PERIOD_UNKNOWN 0xFF 760acae33b0SJustin T. Gibbs #define AHD_OFFSET_UNKNOWN 0xFF 7610c5aa4c5SScott Long #define AHD_PPR_OPTS_UNKNOWN 0xFF 7620c5aa4c5SScott Long 76317d24755SJustin T. Gibbs /* 76417d24755SJustin T. Gibbs * Transfer Negotiation Information. 76517d24755SJustin T. Gibbs */ 76617d24755SJustin T. Gibbs struct ahd_transinfo { 76717d24755SJustin T. Gibbs uint8_t protocol_version; /* SCSI Revision level */ 76817d24755SJustin T. Gibbs uint8_t transport_version; /* SPI Revision level */ 76917d24755SJustin T. Gibbs uint8_t width; /* Bus width */ 77017d24755SJustin T. Gibbs uint8_t period; /* Sync rate factor */ 77117d24755SJustin T. Gibbs uint8_t offset; /* Sync offset */ 77217d24755SJustin T. Gibbs uint8_t ppr_options; /* Parallel Protocol Request options */ 77317d24755SJustin T. Gibbs }; 77417d24755SJustin T. Gibbs 77517d24755SJustin T. Gibbs /* 77617d24755SJustin T. Gibbs * Per-initiator current, goal and user transfer negotiation information. */ 77717d24755SJustin T. Gibbs struct ahd_initiator_tinfo { 77817d24755SJustin T. Gibbs struct ahd_transinfo curr; 77917d24755SJustin T. Gibbs struct ahd_transinfo goal; 78017d24755SJustin T. Gibbs struct ahd_transinfo user; 78117d24755SJustin T. Gibbs }; 78217d24755SJustin T. Gibbs 78317d24755SJustin T. Gibbs /* 78417d24755SJustin T. Gibbs * Per enabled target ID state. 78517d24755SJustin T. Gibbs * Pointers to lun target state as well as sync/wide negotiation information 78617d24755SJustin T. Gibbs * for each initiator<->target mapping. For the initiator role we pretend 78717d24755SJustin T. Gibbs * that we are the target and the targets are the initiators since the 78817d24755SJustin T. Gibbs * negotiation is the same regardless of role. 78917d24755SJustin T. Gibbs */ 79017d24755SJustin T. Gibbs struct ahd_tmode_tstate { 79117d24755SJustin T. Gibbs struct ahd_tmode_lstate* enabled_luns[AHD_NUM_LUNS]; 79217d24755SJustin T. Gibbs struct ahd_initiator_tinfo transinfo[AHD_NUM_TARGETS]; 79317d24755SJustin T. Gibbs 79417d24755SJustin T. Gibbs /* 79517d24755SJustin T. Gibbs * Per initiator state bitmasks. 79617d24755SJustin T. Gibbs */ 79717d24755SJustin T. Gibbs uint16_t auto_negotiate;/* Auto Negotiation Required */ 79817d24755SJustin T. Gibbs uint16_t discenable; /* Disconnection allowed */ 79917d24755SJustin T. Gibbs uint16_t tagenable; /* Tagged Queuing allowed */ 80017d24755SJustin T. Gibbs }; 80117d24755SJustin T. Gibbs 80217d24755SJustin T. Gibbs /* 80317d24755SJustin T. Gibbs * Points of interest along the negotiated transfer scale. 80417d24755SJustin T. Gibbs */ 80517d24755SJustin T. Gibbs #define AHD_SYNCRATE_160 0x8 80617d24755SJustin T. Gibbs #define AHD_SYNCRATE_PACED 0x8 80717d24755SJustin T. Gibbs #define AHD_SYNCRATE_DT 0x9 80817d24755SJustin T. Gibbs #define AHD_SYNCRATE_ULTRA2 0xa 80917d24755SJustin T. Gibbs #define AHD_SYNCRATE_ULTRA 0xc 81017d24755SJustin T. Gibbs #define AHD_SYNCRATE_FAST 0x19 81117d24755SJustin T. Gibbs #define AHD_SYNCRATE_MIN_DT AHD_SYNCRATE_FAST 81217d24755SJustin T. Gibbs #define AHD_SYNCRATE_SYNC 0x32 81317d24755SJustin T. Gibbs #define AHD_SYNCRATE_MIN 0x60 81417d24755SJustin T. Gibbs #define AHD_SYNCRATE_ASYNC 0xFF 8150794987dSJustin T. Gibbs #define AHD_SYNCRATE_MAX AHD_SYNCRATE_160 81617d24755SJustin T. Gibbs 8170c5aa4c5SScott Long /* Safe and valid period for async negotiations. */ 8180c5aa4c5SScott Long #define AHD_ASYNC_XFER_PERIOD 0x44 8190c5aa4c5SScott Long 82017d24755SJustin T. Gibbs /* 82117d24755SJustin T. Gibbs * In RevA, the synctable uses a 120MHz rate for the period 82217d24755SJustin T. Gibbs * factor 8 and 160MHz for the period factor 7. The 120MHz 82317d24755SJustin T. Gibbs * rate never made it into the official SCSI spec, so we must 82417d24755SJustin T. Gibbs * compensate when setting the negotiation table for Rev A 82517d24755SJustin T. Gibbs * parts. 82617d24755SJustin T. Gibbs */ 82717d24755SJustin T. Gibbs #define AHD_SYNCRATE_REVA_120 0x8 82817d24755SJustin T. Gibbs #define AHD_SYNCRATE_REVA_160 0x7 82917d24755SJustin T. Gibbs 83017d24755SJustin T. Gibbs /***************************** Lookup Tables **********************************/ 83117d24755SJustin T. Gibbs /* 83217d24755SJustin T. Gibbs * Phase -> name and message out response 83317d24755SJustin T. Gibbs * to parity errors in each phase table. 83417d24755SJustin T. Gibbs */ 83517d24755SJustin T. Gibbs struct ahd_phase_table_entry { 83617d24755SJustin T. Gibbs uint8_t phase; 83717d24755SJustin T. Gibbs uint8_t mesg_out; /* Message response to parity errors */ 83817d24755SJustin T. Gibbs char *phasemsg; 83917d24755SJustin T. Gibbs }; 84017d24755SJustin T. Gibbs 84117d24755SJustin T. Gibbs /************************** Serial EEPROM Format ******************************/ 84217d24755SJustin T. Gibbs 84317d24755SJustin T. Gibbs struct seeprom_config { 84417d24755SJustin T. Gibbs /* 84517d24755SJustin T. Gibbs * Per SCSI ID Configuration Flags 84617d24755SJustin T. Gibbs */ 84717d24755SJustin T. Gibbs uint16_t device_flags[16]; /* words 0-15 */ 84817d24755SJustin T. Gibbs #define CFXFER 0x003F /* synchronous transfer rate */ 84917d24755SJustin T. Gibbs #define CFXFER_ASYNC 0x3F 85017d24755SJustin T. Gibbs #define CFQAS 0x0040 /* Negotiate QAS */ 85117d24755SJustin T. Gibbs #define CFPACKETIZED 0x0080 /* Negotiate Packetized Transfers */ 85217d24755SJustin T. Gibbs #define CFSTART 0x0100 /* send start unit SCSI command */ 85317d24755SJustin T. Gibbs #define CFINCBIOS 0x0200 /* include in BIOS scan */ 85417d24755SJustin T. Gibbs #define CFDISC 0x0400 /* enable disconnection */ 85517d24755SJustin T. Gibbs #define CFMULTILUNDEV 0x0800 /* Probe multiple luns in BIOS scan */ 85617d24755SJustin T. Gibbs #define CFWIDEB 0x1000 /* wide bus device */ 85717d24755SJustin T. Gibbs #define CFHOSTMANAGED 0x8000 /* Managed by a RAID controller */ 85817d24755SJustin T. Gibbs 85917d24755SJustin T. Gibbs /* 86017d24755SJustin T. Gibbs * BIOS Control Bits 86117d24755SJustin T. Gibbs */ 86217d24755SJustin T. Gibbs uint16_t bios_control; /* word 16 */ 86317d24755SJustin T. Gibbs #define CFSUPREM 0x0001 /* support all removeable drives */ 86417d24755SJustin T. Gibbs #define CFSUPREMB 0x0002 /* support removeable boot drives */ 86517d24755SJustin T. Gibbs #define CFBIOSSTATE 0x000C /* BIOS Action State */ 86617d24755SJustin T. Gibbs #define CFBS_DISABLED 0x00 86717d24755SJustin T. Gibbs #define CFBS_ENABLED 0x04 86817d24755SJustin T. Gibbs #define CFBS_DISABLED_SCAN 0x08 86917d24755SJustin T. Gibbs #define CFENABLEDV 0x0010 /* Perform Domain Validation */ 87017d24755SJustin T. Gibbs #define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */ 87117d24755SJustin T. Gibbs #define CFSPARITY 0x0040 /* SCSI parity */ 87217d24755SJustin T. Gibbs #define CFEXTEND 0x0080 /* extended translation enabled */ 87317d24755SJustin T. Gibbs #define CFBOOTCD 0x0100 /* Support Bootable CD-ROM */ 87417d24755SJustin T. Gibbs #define CFMSG_LEVEL 0x0600 /* BIOS Message Level */ 87517d24755SJustin T. Gibbs #define CFMSG_VERBOSE 0x0000 87617d24755SJustin T. Gibbs #define CFMSG_SILENT 0x0200 87717d24755SJustin T. Gibbs #define CFMSG_DIAG 0x0400 87817d24755SJustin T. Gibbs #define CFRESETB 0x0800 /* reset SCSI bus at boot */ 87917d24755SJustin T. Gibbs /* UNUSED 0xf000 */ 88017d24755SJustin T. Gibbs 88117d24755SJustin T. Gibbs /* 88217d24755SJustin T. Gibbs * Host Adapter Control Bits 88317d24755SJustin T. Gibbs */ 88417d24755SJustin T. Gibbs uint16_t adapter_control; /* word 17 */ 88517d24755SJustin T. Gibbs #define CFAUTOTERM 0x0001 /* Perform Auto termination */ 88617d24755SJustin T. Gibbs #define CFSTERM 0x0002 /* SCSI low byte termination */ 88717d24755SJustin T. Gibbs #define CFWSTERM 0x0004 /* SCSI high byte termination */ 88817d24755SJustin T. Gibbs #define CFSEAUTOTERM 0x0008 /* Ultra2 Perform secondary Auto Term*/ 88917d24755SJustin T. Gibbs #define CFSELOWTERM 0x0010 /* Ultra2 secondary low term */ 89017d24755SJustin T. Gibbs #define CFSEHIGHTERM 0x0020 /* Ultra2 secondary high term */ 89117d24755SJustin T. Gibbs #define CFSTPWLEVEL 0x0040 /* Termination level control */ 89217d24755SJustin T. Gibbs #define CFBIOSAUTOTERM 0x0080 /* Perform Auto termination */ 89317d24755SJustin T. Gibbs #define CFTERM_MENU 0x0100 /* BIOS displays termination menu */ 89417d24755SJustin T. Gibbs #define CFCLUSTERENB 0x8000 /* Cluster Enable */ 89517d24755SJustin T. Gibbs 89617d24755SJustin T. Gibbs /* 89717d24755SJustin T. Gibbs * Bus Release Time, Host Adapter ID 89817d24755SJustin T. Gibbs */ 89917d24755SJustin T. Gibbs uint16_t brtime_id; /* word 18 */ 90017d24755SJustin T. Gibbs #define CFSCSIID 0x000f /* host adapter SCSI ID */ 90117d24755SJustin T. Gibbs /* UNUSED 0x00f0 */ 90217d24755SJustin T. Gibbs #define CFBRTIME 0xff00 /* bus release time/PCI Latency Time */ 90317d24755SJustin T. Gibbs 90417d24755SJustin T. Gibbs /* 90517d24755SJustin T. Gibbs * Maximum targets 90617d24755SJustin T. Gibbs */ 90717d24755SJustin T. Gibbs uint16_t max_targets; /* word 19 */ 90817d24755SJustin T. Gibbs #define CFMAXTARG 0x00ff /* maximum targets */ 90917d24755SJustin T. Gibbs #define CFBOOTLUN 0x0f00 /* Lun to boot from */ 91017d24755SJustin T. Gibbs #define CFBOOTID 0xf000 /* Target to boot from */ 91117d24755SJustin T. Gibbs uint16_t res_1[10]; /* words 20-29 */ 91217d24755SJustin T. Gibbs uint16_t signature; /* BIOS Signature */ 91317d24755SJustin T. Gibbs #define CFSIGNATURE 0x400 91417d24755SJustin T. Gibbs uint16_t checksum; /* word 31 */ 91517d24755SJustin T. Gibbs }; 91617d24755SJustin T. Gibbs 917d7cff4abSJustin T. Gibbs /* 918d7cff4abSJustin T. Gibbs * Vital Product Data used during POST and by the BIOS. 919d7cff4abSJustin T. Gibbs */ 920d7cff4abSJustin T. Gibbs struct vpd_config { 921d7cff4abSJustin T. Gibbs uint8_t bios_flags; 922d7cff4abSJustin T. Gibbs #define VPDMASTERBIOS 0x0001 923d7cff4abSJustin T. Gibbs #define VPDBOOTHOST 0x0002 924d7cff4abSJustin T. Gibbs uint8_t reserved_1[21]; 925d7cff4abSJustin T. Gibbs uint8_t resource_type; 926d7cff4abSJustin T. Gibbs uint8_t resource_len[2]; 927d7cff4abSJustin T. Gibbs uint8_t resource_data[8]; 928d7cff4abSJustin T. Gibbs uint8_t vpd_tag; 929d7cff4abSJustin T. Gibbs uint16_t vpd_len; 930d7cff4abSJustin T. Gibbs uint8_t vpd_keyword[2]; 931d7cff4abSJustin T. Gibbs uint8_t length; 932d7cff4abSJustin T. Gibbs uint8_t revision; 933d7cff4abSJustin T. Gibbs uint8_t device_flags; 934d7cff4abSJustin T. Gibbs uint8_t termnation_menus[2]; 935d7cff4abSJustin T. Gibbs uint8_t fifo_threshold; 936d7cff4abSJustin T. Gibbs uint8_t end_tag; 937d7cff4abSJustin T. Gibbs uint8_t vpd_checksum; 938d7cff4abSJustin T. Gibbs uint16_t default_target_flags; 939d7cff4abSJustin T. Gibbs uint16_t default_bios_flags; 940d7cff4abSJustin T. Gibbs uint16_t default_ctrl_flags; 941d7cff4abSJustin T. Gibbs uint8_t default_irq; 942d7cff4abSJustin T. Gibbs uint8_t pci_lattime; 943d7cff4abSJustin T. Gibbs uint8_t max_target; 944d7cff4abSJustin T. Gibbs uint8_t boot_lun; 945d7cff4abSJustin T. Gibbs uint16_t signature; 946d7cff4abSJustin T. Gibbs uint8_t reserved_2; 947d7cff4abSJustin T. Gibbs uint8_t checksum; 948d7cff4abSJustin T. Gibbs uint8_t reserved_3[4]; 949d7cff4abSJustin T. Gibbs }; 950d7cff4abSJustin T. Gibbs 95117d24755SJustin T. Gibbs /****************************** Flexport Logic ********************************/ 95217d24755SJustin T. Gibbs #define FLXADDR_TERMCTL 0x0 95317d24755SJustin T. Gibbs #define FLX_TERMCTL_ENSECHIGH 0x8 95417d24755SJustin T. Gibbs #define FLX_TERMCTL_ENSECLOW 0x4 95517d24755SJustin T. Gibbs #define FLX_TERMCTL_ENPRIHIGH 0x2 95617d24755SJustin T. Gibbs #define FLX_TERMCTL_ENPRILOW 0x1 95717d24755SJustin T. Gibbs #define FLXADDR_ROMSTAT_CURSENSECTL 0x1 95817d24755SJustin T. Gibbs #define FLX_ROMSTAT_SEECFG 0xF0 95917d24755SJustin T. Gibbs #define FLX_ROMSTAT_EECFG 0x0F 96017d24755SJustin T. Gibbs #define FLX_ROMSTAT_SEE_93C66 0x00 96117d24755SJustin T. Gibbs #define FLX_ROMSTAT_SEE_NONE 0xF0 96217d24755SJustin T. Gibbs #define FLX_ROMSTAT_EE_512x8 0x0 96317d24755SJustin T. Gibbs #define FLX_ROMSTAT_EE_1MBx8 0x1 96417d24755SJustin T. Gibbs #define FLX_ROMSTAT_EE_2MBx8 0x2 96517d24755SJustin T. Gibbs #define FLX_ROMSTAT_EE_4MBx8 0x3 96617d24755SJustin T. Gibbs #define FLX_ROMSTAT_EE_16MBx8 0x4 96717d24755SJustin T. Gibbs #define CURSENSE_ENB 0x1 96817d24755SJustin T. Gibbs #define FLXADDR_FLEXSTAT 0x2 96917d24755SJustin T. Gibbs #define FLX_FSTAT_BUSY 0x1 97017d24755SJustin T. Gibbs #define FLXADDR_CURRENT_STAT 0x4 97117d24755SJustin T. Gibbs #define FLX_CSTAT_SEC_HIGH 0xC0 97217d24755SJustin T. Gibbs #define FLX_CSTAT_SEC_LOW 0x30 97317d24755SJustin T. Gibbs #define FLX_CSTAT_PRI_HIGH 0x0C 97417d24755SJustin T. Gibbs #define FLX_CSTAT_PRI_LOW 0x03 97517d24755SJustin T. Gibbs #define FLX_CSTAT_MASK 0x03 97617d24755SJustin T. Gibbs #define FLX_CSTAT_SHIFT 2 97717d24755SJustin T. Gibbs #define FLX_CSTAT_OKAY 0x0 97817d24755SJustin T. Gibbs #define FLX_CSTAT_OVER 0x1 97917d24755SJustin T. Gibbs #define FLX_CSTAT_UNDER 0x2 98017d24755SJustin T. Gibbs #define FLX_CSTAT_INVALID 0x3 98117d24755SJustin T. Gibbs 98217d24755SJustin T. Gibbs int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, 983d7cff4abSJustin T. Gibbs u_int start_addr, u_int count, int bstream); 98417d24755SJustin T. Gibbs 98517d24755SJustin T. Gibbs int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, 98617d24755SJustin T. Gibbs u_int start_addr, u_int count); 98717d24755SJustin T. Gibbs int ahd_wait_seeprom(struct ahd_softc *ahd); 988d7cff4abSJustin T. Gibbs int ahd_verify_vpd_cksum(struct vpd_config *vpd); 98917d24755SJustin T. Gibbs int ahd_verify_cksum(struct seeprom_config *sc); 99017d24755SJustin T. Gibbs int ahd_acquire_seeprom(struct ahd_softc *ahd); 99117d24755SJustin T. Gibbs void ahd_release_seeprom(struct ahd_softc *ahd); 99217d24755SJustin T. Gibbs 99317d24755SJustin T. Gibbs /**************************** Message Buffer *********************************/ 99417d24755SJustin T. Gibbs typedef enum { 99517d24755SJustin T. Gibbs MSG_FLAG_NONE = 0x00, 99617d24755SJustin T. Gibbs MSG_FLAG_EXPECT_PPR_BUSFREE = 0x01, 99717d24755SJustin T. Gibbs MSG_FLAG_IU_REQ_CHANGED = 0x02, 99817d24755SJustin T. Gibbs MSG_FLAG_EXPECT_IDE_BUSFREE = 0x04, 9990c5aa4c5SScott Long MSG_FLAG_EXPECT_QASREJ_BUSFREE = 0x08, 10000c5aa4c5SScott Long MSG_FLAG_PACKETIZED = 0x10 100117d24755SJustin T. Gibbs } ahd_msg_flags; 100217d24755SJustin T. Gibbs 100317d24755SJustin T. Gibbs typedef enum { 100417d24755SJustin T. Gibbs MSG_TYPE_NONE = 0x00, 100517d24755SJustin T. Gibbs MSG_TYPE_INITIATOR_MSGOUT = 0x01, 100617d24755SJustin T. Gibbs MSG_TYPE_INITIATOR_MSGIN = 0x02, 100717d24755SJustin T. Gibbs MSG_TYPE_TARGET_MSGOUT = 0x03, 100817d24755SJustin T. Gibbs MSG_TYPE_TARGET_MSGIN = 0x04 100917d24755SJustin T. Gibbs } ahd_msg_type; 101017d24755SJustin T. Gibbs 101117d24755SJustin T. Gibbs typedef enum { 101217d24755SJustin T. Gibbs MSGLOOP_IN_PROG, 101317d24755SJustin T. Gibbs MSGLOOP_MSGCOMPLETE, 101417d24755SJustin T. Gibbs MSGLOOP_TERMINATED 101517d24755SJustin T. Gibbs } msg_loop_stat; 101617d24755SJustin T. Gibbs 101717d24755SJustin T. Gibbs /*********************** Software Configuration Structure *********************/ 101817d24755SJustin T. Gibbs struct ahd_suspend_channel_state { 101917d24755SJustin T. Gibbs uint8_t scsiseq; 102017d24755SJustin T. Gibbs uint8_t sxfrctl0; 102117d24755SJustin T. Gibbs uint8_t sxfrctl1; 102217d24755SJustin T. Gibbs uint8_t simode0; 102317d24755SJustin T. Gibbs uint8_t simode1; 102417d24755SJustin T. Gibbs uint8_t seltimer; 102517d24755SJustin T. Gibbs uint8_t seqctl; 102617d24755SJustin T. Gibbs }; 102717d24755SJustin T. Gibbs 102817d24755SJustin T. Gibbs struct ahd_suspend_state { 102917d24755SJustin T. Gibbs struct ahd_suspend_channel_state channel[2]; 103017d24755SJustin T. Gibbs uint8_t optionmode; 103117d24755SJustin T. Gibbs uint8_t dscommand0; 103217d24755SJustin T. Gibbs uint8_t dspcistatus; 103317d24755SJustin T. Gibbs /* hsmailbox */ 103417d24755SJustin T. Gibbs uint8_t crccontrol1; 103517d24755SJustin T. Gibbs uint8_t scbbaddr; 103617d24755SJustin T. Gibbs /* Host and sequencer SCB counts */ 103717d24755SJustin T. Gibbs uint8_t dff_thrsh; 103817d24755SJustin T. Gibbs uint8_t *scratch_ram; 103917d24755SJustin T. Gibbs uint8_t *btt; 104017d24755SJustin T. Gibbs }; 104117d24755SJustin T. Gibbs 104217d24755SJustin T. Gibbs typedef void (*ahd_bus_intr_t)(struct ahd_softc *); 104317d24755SJustin T. Gibbs 104417d24755SJustin T. Gibbs typedef enum { 104517d24755SJustin T. Gibbs AHD_MODE_DFF0, 104617d24755SJustin T. Gibbs AHD_MODE_DFF1, 104717d24755SJustin T. Gibbs AHD_MODE_CCHAN, 104817d24755SJustin T. Gibbs AHD_MODE_SCSI, 104917d24755SJustin T. Gibbs AHD_MODE_CFG, 105017d24755SJustin T. Gibbs AHD_MODE_UNKNOWN 105117d24755SJustin T. Gibbs } ahd_mode; 105217d24755SJustin T. Gibbs 105317d24755SJustin T. Gibbs #define AHD_MK_MSK(x) (0x01 << (x)) 105417d24755SJustin T. Gibbs #define AHD_MODE_DFF0_MSK AHD_MK_MSK(AHD_MODE_DFF0) 105517d24755SJustin T. Gibbs #define AHD_MODE_DFF1_MSK AHD_MK_MSK(AHD_MODE_DFF1) 105617d24755SJustin T. Gibbs #define AHD_MODE_CCHAN_MSK AHD_MK_MSK(AHD_MODE_CCHAN) 105717d24755SJustin T. Gibbs #define AHD_MODE_SCSI_MSK AHD_MK_MSK(AHD_MODE_SCSI) 105817d24755SJustin T. Gibbs #define AHD_MODE_CFG_MSK AHD_MK_MSK(AHD_MODE_CFG) 105917d24755SJustin T. Gibbs #define AHD_MODE_UNKNOWN_MSK AHD_MK_MSK(AHD_MODE_UNKNOWN) 106017d24755SJustin T. Gibbs #define AHD_MODE_ANY_MSK (~0) 106117d24755SJustin T. Gibbs 1062884015f6SAttilio Rao typedef enum { 1063884015f6SAttilio Rao AHD_SYSCTL_ROOT, 1064884015f6SAttilio Rao AHD_SYSCTL_SUMMARY, 1065884015f6SAttilio Rao AHD_SYSCTL_DEBUG, 1066884015f6SAttilio Rao AHD_SYSCTL_NUMBER 1067884015f6SAttilio Rao } ahd_sysctl_types_t; 1068884015f6SAttilio Rao 1069884015f6SAttilio Rao typedef enum { 1070884015f6SAttilio Rao AHD_ERRORS_CORRECTABLE, 1071884015f6SAttilio Rao AHD_ERRORS_UNCORRECTABLE, 1072884015f6SAttilio Rao AHD_ERRORS_FATAL, 1073884015f6SAttilio Rao AHD_ERRORS_NUMBER 1074884015f6SAttilio Rao } ahd_sysctl_errors_t; 1075884015f6SAttilio Rao 1076884015f6SAttilio Rao #define AHD_CORRECTABLE_ERROR(sc) \ 1077884015f6SAttilio Rao (((sc)->summerr[AHD_ERRORS_CORRECTABLE])++) 1078884015f6SAttilio Rao #define AHD_UNCORRECTABLE_ERROR(sc) \ 1079884015f6SAttilio Rao (((sc)->summerr[AHD_ERRORS_UNCORRECTABLE])++) 1080884015f6SAttilio Rao #define AHD_FATAL_ERROR(sc) \ 1081884015f6SAttilio Rao (((sc)->summerr[AHD_ERRORS_FATAL])++) 1082884015f6SAttilio Rao 108317d24755SJustin T. Gibbs typedef uint8_t ahd_mode_state; 108417d24755SJustin T. Gibbs 108517d24755SJustin T. Gibbs typedef void ahd_callback_t (void *); 108617d24755SJustin T. Gibbs 10874164174aSJustin T. Gibbs struct ahd_completion 10884164174aSJustin T. Gibbs { 10894164174aSJustin T. Gibbs uint16_t tag; 10904164174aSJustin T. Gibbs uint8_t sg_status; 10914164174aSJustin T. Gibbs uint8_t valid_tag; 10924164174aSJustin T. Gibbs }; 10934164174aSJustin T. Gibbs 10947afc0218SJustin T. Gibbs #define AIC_SCB_DATA(softc) (&(softc)->scb_data) 10957afc0218SJustin T. Gibbs 109617d24755SJustin T. Gibbs struct ahd_softc { 109717d24755SJustin T. Gibbs bus_space_tag_t tags[2]; 109817d24755SJustin T. Gibbs bus_space_handle_t bshs[2]; 109917d24755SJustin T. Gibbs bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ 110017d24755SJustin T. Gibbs struct scb_data scb_data; 110117d24755SJustin T. Gibbs 1102544c53b8SJustin T. Gibbs struct hardware_scb *next_queued_hscb; 1103b3b25f2cSJustin T. Gibbs struct map_node *next_queued_hscb_map; 110417d24755SJustin T. Gibbs 110517d24755SJustin T. Gibbs /* 110617d24755SJustin T. Gibbs * SCBs that have been sent to the controller 110717d24755SJustin T. Gibbs */ 110817d24755SJustin T. Gibbs LIST_HEAD(, scb) pending_scbs; 110917d24755SJustin T. Gibbs 111017d24755SJustin T. Gibbs /* 1111b3b25f2cSJustin T. Gibbs * SCBs whose timeout routine has been called. 1112b3b25f2cSJustin T. Gibbs */ 1113b3b25f2cSJustin T. Gibbs LIST_HEAD(, scb) timedout_scbs; 1114b3b25f2cSJustin T. Gibbs 1115b3b25f2cSJustin T. Gibbs /* 111617d24755SJustin T. Gibbs * Current register window mode information. 111717d24755SJustin T. Gibbs */ 111817d24755SJustin T. Gibbs ahd_mode dst_mode; 111917d24755SJustin T. Gibbs ahd_mode src_mode; 112017d24755SJustin T. Gibbs 112117d24755SJustin T. Gibbs /* 112217d24755SJustin T. Gibbs * Saved register window mode information 112317d24755SJustin T. Gibbs * used for restore on next unpause. 112417d24755SJustin T. Gibbs */ 112517d24755SJustin T. Gibbs ahd_mode saved_dst_mode; 112617d24755SJustin T. Gibbs ahd_mode saved_src_mode; 112717d24755SJustin T. Gibbs 112817d24755SJustin T. Gibbs /* 112917d24755SJustin T. Gibbs * Platform specific data. 113017d24755SJustin T. Gibbs */ 113117d24755SJustin T. Gibbs struct ahd_platform_data *platform_data; 113217d24755SJustin T. Gibbs 113317d24755SJustin T. Gibbs /* 113417d24755SJustin T. Gibbs * Platform specific device information. 113517d24755SJustin T. Gibbs */ 1136b3b25f2cSJustin T. Gibbs aic_dev_softc_t dev_softc; 113717d24755SJustin T. Gibbs 113817d24755SJustin T. Gibbs /* 113917d24755SJustin T. Gibbs * Bus specific device information. 114017d24755SJustin T. Gibbs */ 114117d24755SJustin T. Gibbs ahd_bus_intr_t bus_intr; 114217d24755SJustin T. Gibbs 114317d24755SJustin T. Gibbs /* 114417d24755SJustin T. Gibbs * Target mode related state kept on a per enabled lun basis. 114517d24755SJustin T. Gibbs * Targets that are not enabled will have null entries. 114617d24755SJustin T. Gibbs * As an initiator, we keep one target entry for our initiator 114717d24755SJustin T. Gibbs * ID to store our sync/wide transfer settings. 114817d24755SJustin T. Gibbs */ 114917d24755SJustin T. Gibbs struct ahd_tmode_tstate *enabled_targets[AHD_NUM_TARGETS]; 115017d24755SJustin T. Gibbs 115117d24755SJustin T. Gibbs /* 115217d24755SJustin T. Gibbs * The black hole device responsible for handling requests for 115317d24755SJustin T. Gibbs * disabled luns on enabled targets. 115417d24755SJustin T. Gibbs */ 115517d24755SJustin T. Gibbs struct ahd_tmode_lstate *black_hole; 115617d24755SJustin T. Gibbs 115717d24755SJustin T. Gibbs /* 115817d24755SJustin T. Gibbs * Device instance currently on the bus awaiting a continue TIO 115917d24755SJustin T. Gibbs * for a command that was not given the disconnect priveledge. 116017d24755SJustin T. Gibbs */ 116117d24755SJustin T. Gibbs struct ahd_tmode_lstate *pending_device; 116217d24755SJustin T. Gibbs 116317d24755SJustin T. Gibbs /* 116417d24755SJustin T. Gibbs * Timer handles for timer driven callbacks. 116517d24755SJustin T. Gibbs */ 1166b3b25f2cSJustin T. Gibbs aic_timer_t reset_timer; 1167b3b25f2cSJustin T. Gibbs aic_timer_t stat_timer; 11680794987dSJustin T. Gibbs 11690794987dSJustin T. Gibbs /* 11700794987dSJustin T. Gibbs * Statistics. 11710794987dSJustin T. Gibbs */ 1172ad32f91bSJustin T. Gibbs #define AHD_STAT_UPDATE_MS 250 11730794987dSJustin T. Gibbs #define AHD_STAT_BUCKETS 4 11740794987dSJustin T. Gibbs u_int cmdcmplt_bucket; 11750794987dSJustin T. Gibbs uint32_t cmdcmplt_counts[AHD_STAT_BUCKETS]; 11760794987dSJustin T. Gibbs uint32_t cmdcmplt_total; 117717d24755SJustin T. Gibbs 117817d24755SJustin T. Gibbs /* 1179884015f6SAttilio Rao * Errors statistics and printouts. 1180884015f6SAttilio Rao */ 1181884015f6SAttilio Rao struct sysctl_ctx_list sysctl_ctx[AHD_SYSCTL_NUMBER]; 1182884015f6SAttilio Rao struct sysctl_oid *sysctl_tree[AHD_SYSCTL_NUMBER]; 1183884015f6SAttilio Rao u_int summerr[AHD_ERRORS_NUMBER]; 1184884015f6SAttilio Rao 1185884015f6SAttilio Rao /* 118617d24755SJustin T. Gibbs * Card characteristics 118717d24755SJustin T. Gibbs */ 118817d24755SJustin T. Gibbs ahd_chip chip; 118917d24755SJustin T. Gibbs ahd_feature features; 119017d24755SJustin T. Gibbs ahd_bug bugs; 119117d24755SJustin T. Gibbs ahd_flag flags; 119217d24755SJustin T. Gibbs struct seeprom_config *seep_config; 119317d24755SJustin T. Gibbs 119417d24755SJustin T. Gibbs /* Command Queues */ 11954164174aSJustin T. Gibbs struct ahd_completion *qoutfifo; 119617d24755SJustin T. Gibbs uint16_t qoutfifonext; 1197544c53b8SJustin T. Gibbs uint16_t qoutfifonext_valid_tag; 119817d24755SJustin T. Gibbs uint16_t qinfifonext; 119917d24755SJustin T. Gibbs uint16_t qinfifo[AHD_SCB_MAX]; 12004164174aSJustin T. Gibbs 12014164174aSJustin T. Gibbs /* 12024164174aSJustin T. Gibbs * Our qfreeze count. The sequencer compares 12034164174aSJustin T. Gibbs * this value with its own counter to determine 12044164174aSJustin T. Gibbs * whether to allow selections to occur. 12054164174aSJustin T. Gibbs */ 12064164174aSJustin T. Gibbs uint16_t qfreeze_cnt; 12074164174aSJustin T. Gibbs 12084164174aSJustin T. Gibbs /* Values to store in the SEQCTL register for pause and unpause */ 12094164174aSJustin T. Gibbs uint8_t unpause; 12104164174aSJustin T. Gibbs uint8_t pause; 121117d24755SJustin T. Gibbs 121217d24755SJustin T. Gibbs /* Critical Section Data */ 121317d24755SJustin T. Gibbs struct cs *critical_sections; 121417d24755SJustin T. Gibbs u_int num_critical_sections; 121517d24755SJustin T. Gibbs 121617d24755SJustin T. Gibbs /* Buffer for handling packetized bitbucket. */ 121717d24755SJustin T. Gibbs uint8_t *overrun_buf; 121817d24755SJustin T. Gibbs 121917d24755SJustin T. Gibbs /* Links for chaining softcs */ 122017d24755SJustin T. Gibbs TAILQ_ENTRY(ahd_softc) links; 122117d24755SJustin T. Gibbs 122217d24755SJustin T. Gibbs /* Channel Names ('A', 'B', etc.) */ 122317d24755SJustin T. Gibbs char channel; 122417d24755SJustin T. Gibbs 122517d24755SJustin T. Gibbs /* Initiator Bus ID */ 122617d24755SJustin T. Gibbs uint8_t our_id; 122717d24755SJustin T. Gibbs 122817d24755SJustin T. Gibbs /* 122917d24755SJustin T. Gibbs * Target incoming command FIFO. 123017d24755SJustin T. Gibbs */ 123117d24755SJustin T. Gibbs struct target_cmd *targetcmds; 123217d24755SJustin T. Gibbs uint8_t tqinfifonext; 123317d24755SJustin T. Gibbs 123417d24755SJustin T. Gibbs /* 12350794987dSJustin T. Gibbs * Cached verson of the hs_mailbox so we can avoid 12360794987dSJustin T. Gibbs * pausing the sequencer during mailbox updates. 12370794987dSJustin T. Gibbs */ 12380794987dSJustin T. Gibbs uint8_t hs_mailbox; 12390794987dSJustin T. Gibbs 12400794987dSJustin T. Gibbs /* 124117d24755SJustin T. Gibbs * Incoming and outgoing message handling. 124217d24755SJustin T. Gibbs */ 124317d24755SJustin T. Gibbs uint8_t send_msg_perror; 124417d24755SJustin T. Gibbs ahd_msg_flags msg_flags; 124517d24755SJustin T. Gibbs ahd_msg_type msg_type; 124617d24755SJustin T. Gibbs uint8_t msgout_buf[12];/* Message we are sending */ 124717d24755SJustin T. Gibbs uint8_t msgin_buf[12];/* Message we are receiving */ 124817d24755SJustin T. Gibbs u_int msgout_len; /* Length of message to send */ 124917d24755SJustin T. Gibbs u_int msgout_index; /* Current index in msgout */ 125017d24755SJustin T. Gibbs u_int msgin_index; /* Current index in msgin */ 125117d24755SJustin T. Gibbs 125217d24755SJustin T. Gibbs /* 125317d24755SJustin T. Gibbs * Mapping information for data structures shared 125417d24755SJustin T. Gibbs * between the sequencer and kernel. 125517d24755SJustin T. Gibbs */ 125617d24755SJustin T. Gibbs bus_dma_tag_t parent_dmat; 125717d24755SJustin T. Gibbs bus_dma_tag_t shared_data_dmat; 1258b3b25f2cSJustin T. Gibbs struct map_node shared_data_map; 125917d24755SJustin T. Gibbs 126017d24755SJustin T. Gibbs /* Information saved through suspend/resume cycles */ 126117d24755SJustin T. Gibbs struct ahd_suspend_state suspend_state; 126217d24755SJustin T. Gibbs 126317d24755SJustin T. Gibbs /* Number of enabled target mode device on this card */ 126417d24755SJustin T. Gibbs u_int enabled_luns; 126517d24755SJustin T. Gibbs 126617d24755SJustin T. Gibbs /* Initialization level of this data structure */ 126717d24755SJustin T. Gibbs u_int init_level; 126817d24755SJustin T. Gibbs 126917d24755SJustin T. Gibbs /* PCI cacheline size. */ 127017d24755SJustin T. Gibbs u_int pci_cachesize; 127117d24755SJustin T. Gibbs 12726eb7ebfeSJohn Baldwin /* PCI-X capability offset. */ 12736eb7ebfeSJohn Baldwin int pcix_ptr; 12746eb7ebfeSJohn Baldwin 12750c5aa4c5SScott Long /* IO Cell Parameters */ 12760c5aa4c5SScott Long uint8_t iocell_opts[AHD_NUM_PER_DEV_ANNEXCOLS]; 12770c5aa4c5SScott Long 12780c5aa4c5SScott Long u_int stack_size; 12790c5aa4c5SScott Long uint16_t *saved_stack; 12800c5aa4c5SScott Long 128117d24755SJustin T. Gibbs /* Per-Unit descriptive information */ 128217d24755SJustin T. Gibbs const char *description; 128317d24755SJustin T. Gibbs const char *bus_description; 128417d24755SJustin T. Gibbs char *name; 128517d24755SJustin T. Gibbs int unit; 128617d24755SJustin T. Gibbs 128717d24755SJustin T. Gibbs /* Selection Timer settings */ 128817d24755SJustin T. Gibbs int seltime; 128917d24755SJustin T. Gibbs 12900794987dSJustin T. Gibbs /* 12918089f0f0SJustin T. Gibbs * Interrupt coalescing settings. 12920794987dSJustin T. Gibbs */ 12938089f0f0SJustin T. Gibbs #define AHD_INT_COALESCING_TIMER_DEFAULT 250 /*us*/ 12948089f0f0SJustin T. Gibbs #define AHD_INT_COALESCING_MAXCMDS_DEFAULT 10 12958089f0f0SJustin T. Gibbs #define AHD_INT_COALESCING_MAXCMDS_MAX 127 12968089f0f0SJustin T. Gibbs #define AHD_INT_COALESCING_MINCMDS_DEFAULT 5 12978089f0f0SJustin T. Gibbs #define AHD_INT_COALESCING_MINCMDS_MAX 127 12988089f0f0SJustin T. Gibbs #define AHD_INT_COALESCING_THRESHOLD_DEFAULT 2000 12998089f0f0SJustin T. Gibbs #define AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT 1000 13008089f0f0SJustin T. Gibbs u_int int_coalescing_timer; 13018089f0f0SJustin T. Gibbs u_int int_coalescing_maxcmds; 13028089f0f0SJustin T. Gibbs u_int int_coalescing_mincmds; 13038089f0f0SJustin T. Gibbs u_int int_coalescing_threshold; 13048089f0f0SJustin T. Gibbs u_int int_coalescing_stop_threshold; 13050794987dSJustin T. Gibbs 130617d24755SJustin T. Gibbs uint16_t user_discenable;/* Disconnection allowed */ 130717d24755SJustin T. Gibbs uint16_t user_tagenable;/* Tagged Queuing allowed */ 130817d24755SJustin T. Gibbs }; 130917d24755SJustin T. Gibbs 131017d24755SJustin T. Gibbs TAILQ_HEAD(ahd_softc_tailq, ahd_softc); 131117d24755SJustin T. Gibbs extern struct ahd_softc_tailq ahd_tailq; 131217d24755SJustin T. Gibbs 13130c5aa4c5SScott Long /*************************** IO Cell Configuration ****************************/ 13140c5aa4c5SScott Long #define AHD_PRECOMP_SLEW_INDEX \ 13150c5aa4c5SScott Long (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0) 13160c5aa4c5SScott Long 13170c5aa4c5SScott Long #define AHD_AMPLITUDE_INDEX \ 13180c5aa4c5SScott Long (AHD_ANNEXCOL_AMPLITUDE - AHD_ANNEXCOL_PER_DEV0) 13190c5aa4c5SScott Long 13200c5aa4c5SScott Long #define AHD_SET_SLEWRATE(ahd, new_slew) \ 13210c5aa4c5SScott Long do { \ 13220c5aa4c5SScott Long (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_SLEWRATE_MASK; \ 13230c5aa4c5SScott Long (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ 13240c5aa4c5SScott Long (((new_slew) << AHD_SLEWRATE_SHIFT) & AHD_SLEWRATE_MASK); \ 13250c5aa4c5SScott Long } while (0) 13260c5aa4c5SScott Long 13270c5aa4c5SScott Long #define AHD_SET_PRECOMP(ahd, new_pcomp) \ 13280c5aa4c5SScott Long do { \ 13290c5aa4c5SScott Long (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; \ 13300c5aa4c5SScott Long (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \ 13310c5aa4c5SScott Long (((new_pcomp) << AHD_PRECOMP_SHIFT) & AHD_PRECOMP_MASK); \ 13320c5aa4c5SScott Long } while (0) 13330c5aa4c5SScott Long 13340c5aa4c5SScott Long #define AHD_SET_AMPLITUDE(ahd, new_amp) \ 13350c5aa4c5SScott Long do { \ 13360c5aa4c5SScott Long (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] &= ~AHD_AMPLITUDE_MASK; \ 13370c5aa4c5SScott Long (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] |= \ 13380c5aa4c5SScott Long (((new_amp) << AHD_AMPLITUDE_SHIFT) & AHD_AMPLITUDE_MASK); \ 13390c5aa4c5SScott Long } while (0) 13400c5aa4c5SScott Long 134117d24755SJustin T. Gibbs /************************ Active Device Information ***************************/ 134217d24755SJustin T. Gibbs typedef enum { 134317d24755SJustin T. Gibbs ROLE_UNKNOWN, 134417d24755SJustin T. Gibbs ROLE_INITIATOR, 134517d24755SJustin T. Gibbs ROLE_TARGET 134617d24755SJustin T. Gibbs } role_t; 134717d24755SJustin T. Gibbs 134817d24755SJustin T. Gibbs struct ahd_devinfo { 134917d24755SJustin T. Gibbs int our_scsiid; 135017d24755SJustin T. Gibbs int target_offset; 135117d24755SJustin T. Gibbs uint16_t target_mask; 135217d24755SJustin T. Gibbs u_int target; 135317d24755SJustin T. Gibbs u_int lun; 135417d24755SJustin T. Gibbs char channel; 135517d24755SJustin T. Gibbs role_t role; /* 135617d24755SJustin T. Gibbs * Only guaranteed to be correct if not 135717d24755SJustin T. Gibbs * in the busfree state. 135817d24755SJustin T. Gibbs */ 135917d24755SJustin T. Gibbs }; 136017d24755SJustin T. Gibbs 136117d24755SJustin T. Gibbs /****************************** PCI Structures ********************************/ 1362e27951b2SJohn Baldwin #define AHD_PCI_IOADDR0 PCIR_BAR(0) /* I/O BAR*/ 1363e27951b2SJohn Baldwin #define AHD_PCI_MEMADDR PCIR_BAR(1) /* Memory BAR */ 1364e27951b2SJohn Baldwin #define AHD_PCI_IOADDR1 PCIR_BAR(3) /* Second I/O BAR */ 136517d24755SJustin T. Gibbs 136617d24755SJustin T. Gibbs typedef int (ahd_device_setup_t)(struct ahd_softc *); 136717d24755SJustin T. Gibbs 136817d24755SJustin T. Gibbs struct ahd_pci_identity { 136917d24755SJustin T. Gibbs uint64_t full_id; 137017d24755SJustin T. Gibbs uint64_t id_mask; 137117d24755SJustin T. Gibbs char *name; 137217d24755SJustin T. Gibbs ahd_device_setup_t *setup; 137317d24755SJustin T. Gibbs }; 137417d24755SJustin T. Gibbs extern struct ahd_pci_identity ahd_pci_ident_table []; 137517d24755SJustin T. Gibbs extern const u_int ahd_num_pci_devs; 137617d24755SJustin T. Gibbs 137717d24755SJustin T. Gibbs /*************************** Function Declarations ****************************/ 137817d24755SJustin T. Gibbs /******************************************************************************/ 13790794987dSJustin T. Gibbs void ahd_reset_cmds_pending(struct ahd_softc *ahd); 138017d24755SJustin T. Gibbs u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); 138117d24755SJustin T. Gibbs void ahd_busy_tcl(struct ahd_softc *ahd, 138217d24755SJustin T. Gibbs u_int tcl, u_int busyid); 138317d24755SJustin T. Gibbs static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl); 138417d24755SJustin T. Gibbs static __inline void 138517d24755SJustin T. Gibbs ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) 138617d24755SJustin T. Gibbs { 138717d24755SJustin T. Gibbs ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); 138817d24755SJustin T. Gibbs } 138917d24755SJustin T. Gibbs 139017d24755SJustin T. Gibbs /***************************** PCI Front End *********************************/ 1391b3b25f2cSJustin T. Gibbs struct ahd_pci_identity *ahd_find_pci_device(aic_dev_softc_t); 139217d24755SJustin T. Gibbs int ahd_pci_config(struct ahd_softc *, 139317d24755SJustin T. Gibbs struct ahd_pci_identity *); 13940c5aa4c5SScott Long int ahd_pci_test_register_access(struct ahd_softc *); 139517d24755SJustin T. Gibbs 139617d24755SJustin T. Gibbs /************************** SCB and SCB queue management **********************/ 139717d24755SJustin T. Gibbs int ahd_probe_scbs(struct ahd_softc *); 139817d24755SJustin T. Gibbs void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, 139917d24755SJustin T. Gibbs struct scb *scb); 140017d24755SJustin T. Gibbs int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, 140117d24755SJustin T. Gibbs int target, char channel, int lun, 140217d24755SJustin T. Gibbs u_int tag, role_t role); 140317d24755SJustin T. Gibbs 140417d24755SJustin T. Gibbs /****************************** Initialization ********************************/ 140517d24755SJustin T. Gibbs struct ahd_softc *ahd_alloc(void *platform_arg, char *name); 140617d24755SJustin T. Gibbs int ahd_softc_init(struct ahd_softc *); 140717d24755SJustin T. Gibbs void ahd_controller_info(struct ahd_softc *ahd, char *buf); 140817d24755SJustin T. Gibbs int ahd_init(struct ahd_softc *ahd); 140917d24755SJustin T. Gibbs int ahd_default_config(struct ahd_softc *ahd); 1410d7cff4abSJustin T. Gibbs int ahd_parse_vpddata(struct ahd_softc *ahd, 1411d7cff4abSJustin T. Gibbs struct vpd_config *vpd); 141217d24755SJustin T. Gibbs int ahd_parse_cfgdata(struct ahd_softc *ahd, 141317d24755SJustin T. Gibbs struct seeprom_config *sc); 141417d24755SJustin T. Gibbs void ahd_intr_enable(struct ahd_softc *ahd, int enable); 14158089f0f0SJustin T. Gibbs void ahd_update_coalescing_values(struct ahd_softc *ahd, 14160794987dSJustin T. Gibbs u_int timer, 14170794987dSJustin T. Gibbs u_int maxcmds, 14180794987dSJustin T. Gibbs u_int mincmds); 14198089f0f0SJustin T. Gibbs void ahd_enable_coalescing(struct ahd_softc *ahd, 14200794987dSJustin T. Gibbs int enable); 142117d24755SJustin T. Gibbs void ahd_pause_and_flushwork(struct ahd_softc *ahd); 142217d24755SJustin T. Gibbs int ahd_suspend(struct ahd_softc *ahd); 142317d24755SJustin T. Gibbs int ahd_resume(struct ahd_softc *ahd); 142417d24755SJustin T. Gibbs void ahd_softc_insert(struct ahd_softc *); 142517d24755SJustin T. Gibbs void ahd_set_unit(struct ahd_softc *, int); 142617d24755SJustin T. Gibbs void ahd_set_name(struct ahd_softc *, char *); 1427544c53b8SJustin T. Gibbs struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); 1428544c53b8SJustin T. Gibbs void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); 14297628acd8SScott Long int ahd_alloc_scbs(struct ahd_softc *ahd); 143017d24755SJustin T. Gibbs void ahd_free(struct ahd_softc *ahd); 14311d528d67SJustin T. Gibbs int ahd_reset(struct ahd_softc *ahd, int reinit); 143217d24755SJustin T. Gibbs void ahd_shutdown(void *arg); 143317d24755SJustin T. Gibbs int ahd_write_flexport(struct ahd_softc *ahd, 143417d24755SJustin T. Gibbs u_int addr, u_int value); 143517d24755SJustin T. Gibbs int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, 143617d24755SJustin T. Gibbs uint8_t *value); 143717d24755SJustin T. Gibbs int ahd_wait_flexport(struct ahd_softc *ahd); 143817d24755SJustin T. Gibbs 143917d24755SJustin T. Gibbs /*************************** Interrupt Services *******************************/ 144017d24755SJustin T. Gibbs void ahd_pci_intr(struct ahd_softc *ahd); 144117d24755SJustin T. Gibbs void ahd_clear_intstat(struct ahd_softc *ahd); 14420794987dSJustin T. Gibbs void ahd_flush_qoutfifo(struct ahd_softc *ahd); 144317d24755SJustin T. Gibbs void ahd_run_qoutfifo(struct ahd_softc *ahd); 144417d24755SJustin T. Gibbs #ifdef AHD_TARGET_MODE 144517d24755SJustin T. Gibbs void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); 144617d24755SJustin T. Gibbs #endif 144717d24755SJustin T. Gibbs void ahd_handle_hwerrint(struct ahd_softc *ahd); 144817d24755SJustin T. Gibbs void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); 144917d24755SJustin T. Gibbs void ahd_handle_scsiint(struct ahd_softc *ahd, 145017d24755SJustin T. Gibbs u_int intstat); 145117d24755SJustin T. Gibbs void ahd_clear_critical_section(struct ahd_softc *ahd); 145217d24755SJustin T. Gibbs 145317d24755SJustin T. Gibbs /***************************** Error Recovery *********************************/ 145417d24755SJustin T. Gibbs typedef enum { 145517d24755SJustin T. Gibbs SEARCH_COMPLETE, 145617d24755SJustin T. Gibbs SEARCH_COUNT, 145717d24755SJustin T. Gibbs SEARCH_REMOVE, 145817d24755SJustin T. Gibbs SEARCH_PRINT 145917d24755SJustin T. Gibbs } ahd_search_action; 1460789902c3SJustin T. Gibbs void ahd_done_with_status(struct ahd_softc *ahd, 1461789902c3SJustin T. Gibbs struct scb *scb, uint32_t status); 146217d24755SJustin T. Gibbs int ahd_search_qinfifo(struct ahd_softc *ahd, int target, 146317d24755SJustin T. Gibbs char channel, int lun, u_int tag, 146417d24755SJustin T. Gibbs role_t role, uint32_t status, 146517d24755SJustin T. Gibbs ahd_search_action action); 146617d24755SJustin T. Gibbs int ahd_search_disc_list(struct ahd_softc *ahd, int target, 146717d24755SJustin T. Gibbs char channel, int lun, u_int tag, 146817d24755SJustin T. Gibbs int stop_on_first, int remove, 146917d24755SJustin T. Gibbs int save_state); 147017d24755SJustin T. Gibbs void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb); 147117d24755SJustin T. Gibbs int ahd_reset_channel(struct ahd_softc *ahd, char channel, 147217d24755SJustin T. Gibbs int initiate_reset); 147317d24755SJustin T. Gibbs int ahd_abort_scbs(struct ahd_softc *ahd, int target, 147417d24755SJustin T. Gibbs char channel, int lun, u_int tag, 147517d24755SJustin T. Gibbs role_t role, uint32_t status); 147617d24755SJustin T. Gibbs void ahd_restart(struct ahd_softc *ahd); 147717d24755SJustin T. Gibbs void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo); 147817d24755SJustin T. Gibbs void ahd_handle_scb_status(struct ahd_softc *ahd, 147917d24755SJustin T. Gibbs struct scb *scb); 148017d24755SJustin T. Gibbs void ahd_handle_scsi_status(struct ahd_softc *ahd, 148117d24755SJustin T. Gibbs struct scb *scb); 148217d24755SJustin T. Gibbs void ahd_calc_residual(struct ahd_softc *ahd, 148317d24755SJustin T. Gibbs struct scb *scb); 1484b3b25f2cSJustin T. Gibbs void ahd_timeout(struct scb *scb); 1485b3b25f2cSJustin T. Gibbs void ahd_recover_commands(struct ahd_softc *ahd); 148617d24755SJustin T. Gibbs /*************************** Utility Functions ********************************/ 148717d24755SJustin T. Gibbs struct ahd_phase_table_entry* 148817d24755SJustin T. Gibbs ahd_lookup_phase_entry(int phase); 148917d24755SJustin T. Gibbs void ahd_compile_devinfo(struct ahd_devinfo *devinfo, 149017d24755SJustin T. Gibbs u_int our_id, u_int target, 149117d24755SJustin T. Gibbs u_int lun, char channel, 149217d24755SJustin T. Gibbs role_t role); 149317d24755SJustin T. Gibbs /************************** Transfer Negotiation ******************************/ 149417d24755SJustin T. Gibbs void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, 149517d24755SJustin T. Gibbs u_int *ppr_options, u_int maxsync); 149617d24755SJustin T. Gibbs void ahd_validate_offset(struct ahd_softc *ahd, 149717d24755SJustin T. Gibbs struct ahd_initiator_tinfo *tinfo, 149817d24755SJustin T. Gibbs u_int period, u_int *offset, 149917d24755SJustin T. Gibbs int wide, role_t role); 150017d24755SJustin T. Gibbs void ahd_validate_width(struct ahd_softc *ahd, 150117d24755SJustin T. Gibbs struct ahd_initiator_tinfo *tinfo, 150217d24755SJustin T. Gibbs u_int *bus_width, 150317d24755SJustin T. Gibbs role_t role); 15040c5aa4c5SScott Long /* 15050c5aa4c5SScott Long * Negotiation types. These are used to qualify if we should renegotiate 15060c5aa4c5SScott Long * even if our goal and current transport parameters are identical. 15070c5aa4c5SScott Long */ 15080c5aa4c5SScott Long typedef enum { 15090c5aa4c5SScott Long AHD_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */ 15100c5aa4c5SScott Long AHD_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */ 15110c5aa4c5SScott Long AHD_NEG_ALWAYS /* Renegotiat even if goal is async. */ 15120c5aa4c5SScott Long } ahd_neg_type; 151317d24755SJustin T. Gibbs int ahd_update_neg_request(struct ahd_softc*, 151417d24755SJustin T. Gibbs struct ahd_devinfo*, 151517d24755SJustin T. Gibbs struct ahd_tmode_tstate*, 151617d24755SJustin T. Gibbs struct ahd_initiator_tinfo*, 15170c5aa4c5SScott Long ahd_neg_type); 151817d24755SJustin T. Gibbs void ahd_set_width(struct ahd_softc *ahd, 151917d24755SJustin T. Gibbs struct ahd_devinfo *devinfo, 152017d24755SJustin T. Gibbs u_int width, u_int type, int paused); 152117d24755SJustin T. Gibbs void ahd_set_syncrate(struct ahd_softc *ahd, 152217d24755SJustin T. Gibbs struct ahd_devinfo *devinfo, 152317d24755SJustin T. Gibbs u_int period, u_int offset, 152417d24755SJustin T. Gibbs u_int ppr_options, 152517d24755SJustin T. Gibbs u_int type, int paused); 152617d24755SJustin T. Gibbs typedef enum { 152717d24755SJustin T. Gibbs AHD_QUEUE_NONE, 152817d24755SJustin T. Gibbs AHD_QUEUE_BASIC, 152917d24755SJustin T. Gibbs AHD_QUEUE_TAGGED 153017d24755SJustin T. Gibbs } ahd_queue_alg; 153117d24755SJustin T. Gibbs 153217d24755SJustin T. Gibbs void ahd_set_tags(struct ahd_softc *ahd, 153317d24755SJustin T. Gibbs struct ahd_devinfo *devinfo, 153417d24755SJustin T. Gibbs ahd_queue_alg alg); 153517d24755SJustin T. Gibbs 153617d24755SJustin T. Gibbs /**************************** Target Mode *************************************/ 153717d24755SJustin T. Gibbs #ifdef AHD_TARGET_MODE 153817d24755SJustin T. Gibbs void ahd_send_lstate_events(struct ahd_softc *, 153917d24755SJustin T. Gibbs struct ahd_tmode_lstate *); 154017d24755SJustin T. Gibbs void ahd_handle_en_lun(struct ahd_softc *ahd, 154117d24755SJustin T. Gibbs struct cam_sim *sim, union ccb *ccb); 154217d24755SJustin T. Gibbs cam_status ahd_find_tmode_devs(struct ahd_softc *ahd, 154317d24755SJustin T. Gibbs struct cam_sim *sim, union ccb *ccb, 154417d24755SJustin T. Gibbs struct ahd_tmode_tstate **tstate, 154517d24755SJustin T. Gibbs struct ahd_tmode_lstate **lstate, 154617d24755SJustin T. Gibbs int notfound_failure); 154717d24755SJustin T. Gibbs #ifndef AHD_TMODE_ENABLE 154817d24755SJustin T. Gibbs #define AHD_TMODE_ENABLE 0 154917d24755SJustin T. Gibbs #endif 155017d24755SJustin T. Gibbs #endif 155117d24755SJustin T. Gibbs /******************************* Debug ***************************************/ 155217d24755SJustin T. Gibbs #ifdef AHD_DEBUG 155317d24755SJustin T. Gibbs extern uint32_t ahd_debug; 15540c5aa4c5SScott Long #define AHD_SHOW_MISC 0x00001 15550c5aa4c5SScott Long #define AHD_SHOW_SENSE 0x00002 15560c5aa4c5SScott Long #define AHD_SHOW_RECOVERY 0x00004 15570c5aa4c5SScott Long #define AHD_DUMP_SEEPROM 0x00008 15580c5aa4c5SScott Long #define AHD_SHOW_TERMCTL 0x00010 15590c5aa4c5SScott Long #define AHD_SHOW_MEMORY 0x00020 15600c5aa4c5SScott Long #define AHD_SHOW_MESSAGES 0x00040 15610c5aa4c5SScott Long #define AHD_SHOW_MODEPTR 0x00080 15620c5aa4c5SScott Long #define AHD_SHOW_SELTO 0x00100 15630c5aa4c5SScott Long #define AHD_SHOW_FIFOS 0x00200 15640c5aa4c5SScott Long #define AHD_SHOW_QFULL 0x00400 15650c5aa4c5SScott Long #define AHD_SHOW_DV 0x00800 15660c5aa4c5SScott Long #define AHD_SHOW_MASKED_ERRORS 0x01000 15670c5aa4c5SScott Long #define AHD_SHOW_QUEUE 0x02000 15680c5aa4c5SScott Long #define AHD_SHOW_TQIN 0x04000 15690c5aa4c5SScott Long #define AHD_SHOW_SG 0x08000 15708089f0f0SJustin T. Gibbs #define AHD_SHOW_INT_COALESCING 0x10000 15710794987dSJustin T. Gibbs #define AHD_DEBUG_SEQUENCER 0x20000 157217d24755SJustin T. Gibbs #endif 157317d24755SJustin T. Gibbs void ahd_print_scb(struct scb *scb); 15740c5aa4c5SScott Long void ahd_print_devinfo(struct ahd_softc *ahd, 15750c5aa4c5SScott Long struct ahd_devinfo *devinfo); 157617d24755SJustin T. Gibbs void ahd_dump_sglist(struct scb *scb); 157717d24755SJustin T. Gibbs void ahd_dump_all_cards_state(void); 157817d24755SJustin T. Gibbs void ahd_dump_card_state(struct ahd_softc *ahd); 1579544c53b8SJustin T. Gibbs int ahd_print_register(ahd_reg_parse_entry_t *table, 1580544c53b8SJustin T. Gibbs u_int num_entries, 1581544c53b8SJustin T. Gibbs const char *name, 1582544c53b8SJustin T. Gibbs u_int address, 1583544c53b8SJustin T. Gibbs u_int value, 1584544c53b8SJustin T. Gibbs u_int *cur_column, 1585544c53b8SJustin T. Gibbs u_int wrap_point); 158617d24755SJustin T. Gibbs void ahd_dump_scbs(struct ahd_softc *ahd); 158717d24755SJustin T. Gibbs #endif /* _AIC79XX_H_ */ 1588