aic79xx.h revision 116938
197883Sgibbs/*
297883Sgibbs * Core definitions and data structures shareable across OS platforms.
397883Sgibbs *
4102680Sgibbs * Copyright (c) 1994-2002 Justin T. Gibbs.
5102680Sgibbs * Copyright (c) 2000-2002 Adaptec Inc.
697883Sgibbs * All rights reserved.
797883Sgibbs *
897883Sgibbs * Redistribution and use in source and binary forms, with or without
997883Sgibbs * modification, are permitted provided that the following conditions
1097883Sgibbs * are met:
1197883Sgibbs * 1. Redistributions of source code must retain the above copyright
1297883Sgibbs *    notice, this list of conditions, and the following disclaimer,
1397883Sgibbs *    without modification.
1497883Sgibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1597883Sgibbs *    substantially similar to the "NO WARRANTY" disclaimer below
1697883Sgibbs *    ("Disclaimer") and any redistribution must be conditioned upon
1797883Sgibbs *    including a substantially similar Disclaimer requirement for further
1897883Sgibbs *    binary redistribution.
1997883Sgibbs * 3. Neither the names of the above-listed copyright holders nor the names
2097883Sgibbs *    of any contributors may be used to endorse or promote products derived
2197883Sgibbs *    from this software without specific prior written permission.
2297883Sgibbs *
2397883Sgibbs * Alternatively, this software may be distributed under the terms of the
2497883Sgibbs * GNU General Public License ("GPL") version 2 as published by the Free
2597883Sgibbs * Software Foundation.
2697883Sgibbs *
2797883Sgibbs * NO WARRANTY
2897883Sgibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2997883Sgibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3097883Sgibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3197883Sgibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3297883Sgibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3397883Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3497883Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3597883Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3697883Sgibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
3797883Sgibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3897883Sgibbs * POSSIBILITY OF SUCH DAMAGES.
3997883Sgibbs *
40116938Sgibbs * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#94 $
4197883Sgibbs *
4297883Sgibbs * $FreeBSD: head/sys/dev/aic7xxx/aic79xx.h 116938 2003-06-28 04:45:25Z gibbs $
4397883Sgibbs */
4497883Sgibbs
4597883Sgibbs#ifndef _AIC79XX_H_
4697883Sgibbs#define _AIC79XX_H_
4797883Sgibbs
4897883Sgibbs/* Register Definitions */
4997883Sgibbs#include "aic79xx_reg.h"
5097883Sgibbs
5197883Sgibbs/************************* Forward Declarations *******************************/
5297883Sgibbsstruct ahd_platform_data;
5397883Sgibbsstruct scb_platform_data;
5497883Sgibbs
5597883Sgibbs/****************************** Useful Macros *********************************/
5697883Sgibbs#ifndef MAX
5797883Sgibbs#define MAX(a,b) (((a) > (b)) ? (a) : (b))
5897883Sgibbs#endif
5997883Sgibbs
6097883Sgibbs#ifndef MIN
6197883Sgibbs#define MIN(a,b) (((a) < (b)) ? (a) : (b))
6297883Sgibbs#endif
6397883Sgibbs
6497883Sgibbs#ifndef TRUE
6597883Sgibbs#define TRUE 1
6697883Sgibbs#endif
6797883Sgibbs#ifndef FALSE
6897883Sgibbs#define FALSE 0
6997883Sgibbs#endif
7097883Sgibbs
7197883Sgibbs#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
7297883Sgibbs
7397883Sgibbs#define ALL_CHANNELS '\0'
7497883Sgibbs#define ALL_TARGETS_MASK 0xFFFF
7597883Sgibbs#define INITIATOR_WILDCARD	(~0)
7697883Sgibbs#define	SCB_LIST_NULL		0xFF00
7797883Sgibbs#define	SCB_LIST_NULL_LE	(ahd_htole16(SCB_LIST_NULL))
78102680Sgibbs#define QOUTFIFO_ENTRY_VALID 0x8000
79102680Sgibbs#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000))
8097883Sgibbs#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL)
8197883Sgibbs
8297883Sgibbs#define SCSIID_TARGET(ahd, scsiid)	\
8397883Sgibbs	(((scsiid) & TID) >> TID_SHIFT)
8497883Sgibbs#define SCSIID_OUR_ID(scsiid)		\
8597883Sgibbs	((scsiid) & OID)
8697883Sgibbs#define SCSIID_CHANNEL(ahd, scsiid) ('A')
8797883Sgibbs#define	SCB_IS_SCSIBUS_B(ahd, scb) (0)
8897883Sgibbs#define	SCB_GET_OUR_ID(scb) \
8997883Sgibbs	SCSIID_OUR_ID((scb)->hscb->scsiid)
9097883Sgibbs#define	SCB_GET_TARGET(ahd, scb) \
9197883Sgibbs	SCSIID_TARGET((ahd), (scb)->hscb->scsiid)
9297883Sgibbs#define	SCB_GET_CHANNEL(ahd, scb) \
9397883Sgibbs	SCSIID_CHANNEL(ahd, (scb)->hscb->scsiid)
9497883Sgibbs#define	SCB_GET_LUN(scb) \
9597883Sgibbs	((scb)->hscb->lun)
9697883Sgibbs#define SCB_GET_TARGET_OFFSET(ahd, scb)	\
9797883Sgibbs	SCB_GET_TARGET(ahd, scb)
9897883Sgibbs#define SCB_GET_TARGET_MASK(ahd, scb) \
9997883Sgibbs	(0x01 << (SCB_GET_TARGET_OFFSET(ahd, scb)))
100109588Sgibbs#ifdef AHD_DEBUG
101109588Sgibbs#define SCB_IS_SILENT(scb)					\
102109588Sgibbs	((ahd_debug & AHD_SHOW_MASKED_ERRORS) == 0		\
103109588Sgibbs      && (((scb)->flags & SCB_SILENT) != 0))
104109588Sgibbs#else
105109588Sgibbs#define SCB_IS_SILENT(scb)					\
106109588Sgibbs	(((scb)->flags & SCB_SILENT) != 0)
107109588Sgibbs#endif
10897883Sgibbs/*
10997883Sgibbs * TCLs have the following format: TTTTLLLLLLLL
11097883Sgibbs */
11197883Sgibbs#define TCL_TARGET_OFFSET(tcl) \
11297883Sgibbs	((((tcl) >> 4) & TID) >> 4)
11397883Sgibbs#define TCL_LUN(tcl) \
114102680Sgibbs	(tcl & (AHD_NUM_LUNS - 1))
11597883Sgibbs#define BUILD_TCL(scsiid, lun) \
11697883Sgibbs	((lun) | (((scsiid) & TID) << 4))
11797883Sgibbs#define BUILD_TCL_RAW(target, channel, lun) \
11897883Sgibbs	((lun) | ((target) << 8))
11997883Sgibbs
12097883Sgibbs#define SCB_GET_TAG(scb) \
12197883Sgibbs	ahd_le16toh(scb->hscb->tag)
12297883Sgibbs
12397883Sgibbs#ifndef	AHD_TARGET_MODE
12497883Sgibbs#undef	AHD_TMODE_ENABLE
12597883Sgibbs#define	AHD_TMODE_ENABLE 0
12697883Sgibbs#endif
12797883Sgibbs
128102680Sgibbs#define AHD_BUILD_COL_IDX(target, lun)				\
129102680Sgibbs	(((lun) << 4) | target)
130102680Sgibbs
131102680Sgibbs#define AHD_GET_SCB_COL_IDX(ahd, scb)				\
132102680Sgibbs	((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb))
133102680Sgibbs
134102680Sgibbs#define AHD_SET_SCB_COL_IDX(scb, col_idx)				\
135102680Sgibbsdo {									\
136102680Sgibbs	(scb)->hscb->scsiid = ((col_idx) << TID_SHIFT) & TID;		\
137102680Sgibbs	(scb)->hscb->lun = ((col_idx) >> 4) & (AHD_NUM_LUNS_NONPKT-1);	\
138102680Sgibbs} while (0)
139102680Sgibbs
140102680Sgibbs#define AHD_COPY_SCB_COL_IDX(dst, src)				\
141102680Sgibbsdo {								\
142102680Sgibbs	dst->hscb->scsiid = src->hscb->scsiid;			\
143102680Sgibbs	dst->hscb->lun = src->hscb->lun;			\
144102680Sgibbs} while (0)
145102680Sgibbs
146102680Sgibbs#define	AHD_NEVER_COL_IDX 0xFFFF
147102680Sgibbs
14897883Sgibbs/**************************** Driver Constants ********************************/
14997883Sgibbs/*
15097883Sgibbs * The maximum number of supported targets.
15197883Sgibbs */
15297883Sgibbs#define AHD_NUM_TARGETS 16
15397883Sgibbs
15497883Sgibbs/*
15597883Sgibbs * The maximum number of supported luns.
15697883Sgibbs * The identify message only supports 64 luns in non-packetized transfers.
15797883Sgibbs * You can have 2^64 luns when information unit transfers are enabled,
15897883Sgibbs * but until we see a need to support that many, we support 256.
15997883Sgibbs */
16097883Sgibbs#define AHD_NUM_LUNS_NONPKT 64
16197883Sgibbs#define AHD_NUM_LUNS 256
16297883Sgibbs
16397883Sgibbs/*
16497883Sgibbs * The maximum transfer per S/G segment.
16597883Sgibbs */
16697883Sgibbs#define AHD_MAXTRANSFER_SIZE	 0x00ffffff	/* limited by 24bit counter */
16797883Sgibbs
16897883Sgibbs/*
16997883Sgibbs * The maximum amount of SCB storage in hardware on a controller.
17097883Sgibbs * This value represents an upper bound.  Due to software design,
17197883Sgibbs * we may not be able to use this number.
17297883Sgibbs */
17397883Sgibbs#define AHD_SCB_MAX	512
17497883Sgibbs
17597883Sgibbs/*
17697883Sgibbs * The maximum number of concurrent transactions supported per driver instance.
17797883Sgibbs * Sequencer Control Blocks (SCBs) store per-transaction information.
17897883Sgibbs */
179102680Sgibbs#define AHD_MAX_QUEUE	AHD_SCB_MAX
18097883Sgibbs
18197883Sgibbs/*
18297883Sgibbs * Define the size of our QIN and QOUT FIFOs.  They must be a power of 2
183114623Sgibbs * in size and accommodate as many transactions as can be queued concurrently.
18497883Sgibbs */
185102680Sgibbs#define	AHD_QIN_SIZE	AHD_MAX_QUEUE
186102680Sgibbs#define	AHD_QOUT_SIZE	AHD_MAX_QUEUE
18797883Sgibbs
18897883Sgibbs#define AHD_QIN_WRAP(x) ((x) & (AHD_QIN_SIZE-1))
18997883Sgibbs/*
190102680Sgibbs * The maximum amount of SCB storage we allocate in host memory.
19197883Sgibbs */
192102680Sgibbs#define AHD_SCB_MAX_ALLOC AHD_MAX_QUEUE
19397883Sgibbs
19497883Sgibbs/*
19597883Sgibbs * Ring Buffer of incoming target commands.
19697883Sgibbs * We allocate 256 to simplify the logic in the sequencer
19797883Sgibbs * by using the natural wrap point of an 8bit counter.
19897883Sgibbs */
19997883Sgibbs#define AHD_TMODE_CMDS	256
20097883Sgibbs
20197883Sgibbs/* Reset line assertion time in us */
202102680Sgibbs#define AHD_BUSRESET_DELAY	25
20397883Sgibbs
20497883Sgibbs/******************* Chip Characteristics/Operating Settings  *****************/
20597883Sgibbs/*
20697883Sgibbs * Chip Type
20797883Sgibbs * The chip order is from least sophisticated to most sophisticated.
20897883Sgibbs */
20997883Sgibbstypedef enum {
21097883Sgibbs	AHD_NONE	= 0x0000,
21197883Sgibbs	AHD_CHIPID_MASK	= 0x00FF,
21297883Sgibbs	AHD_AIC7901	= 0x0001,
21397883Sgibbs	AHD_AIC7902	= 0x0002,
214102680Sgibbs	AHD_AIC7901A	= 0x0003,
21597883Sgibbs	AHD_PCI		= 0x0100,	/* Bus type PCI */
21697883Sgibbs	AHD_PCIX	= 0x0200,	/* Bus type PCIX */
21797883Sgibbs	AHD_BUS_MASK	= 0x0F00
21897883Sgibbs} ahd_chip;
21997883Sgibbs
22097883Sgibbs/*
22197883Sgibbs * Features available in each chip type.
22297883Sgibbs */
22397883Sgibbstypedef enum {
224107441Sscottl	AHD_FENONE		= 0x00000,
225107441Sscottl	AHD_WIDE  		= 0x00001,/* Wide Channel */
226107441Sscottl	AHD_MULTI_FUNC		= 0x00100,/* Multi-Function/Channel Device */
227107441Sscottl	AHD_TARGETMODE		= 0x01000,/* Has tested target mode support */
228107441Sscottl	AHD_MULTIROLE		= 0x02000,/* Space for two roles at a time */
229107441Sscottl	AHD_RTI			= 0x04000,/* Retained Training Support */
230107441Sscottl	AHD_NEW_IOCELL_OPTS	= 0x08000,/* More Signal knobs in the IOCELL */
231107441Sscottl	AHD_NEW_DFCNTRL_OPTS	= 0x10000,/* SCSIENWRDIS bit */
232107441Sscottl	AHD_REMOVABLE		= 0x00000,/* Hot-Swap supported - None so far*/
233107441Sscottl	AHD_AIC7901_FE		= AHD_FENONE,
234116933Sgibbs	AHD_AIC7901A_FE		= AHD_FENONE,
235107441Sscottl	AHD_AIC7902_FE		= AHD_MULTI_FUNC
23697883Sgibbs} ahd_feature;
23797883Sgibbs
23897883Sgibbs/*
23997883Sgibbs * Bugs in the silicon that we work around in software.
24097883Sgibbs */
24197883Sgibbstypedef enum {
24297883Sgibbs	AHD_BUGNONE		= 0x0000,
243107441Sscottl	/*
244107441Sscottl	 * Rev A hardware fails to update LAST/CURR/NEXTSCB
245107441Sscottl	 * correctly in certain packetized selection cases.
246107441Sscottl	 */
24797883Sgibbs	AHD_SENT_SCB_UPDATE_BUG	= 0x0001,
248107441Sscottl	/* The wrong SCB is accessed to check the abort pending bit. */
24997883Sgibbs	AHD_ABORT_LQI_BUG	= 0x0002,
250107441Sscottl	/* Packetized bitbucket crosses packet boundaries. */
25197883Sgibbs	AHD_PKT_BITBUCKET_BUG	= 0x0004,
252107441Sscottl	/* The selection timer runs twice as long as its setting. */
25397883Sgibbs	AHD_LONG_SETIMO_BUG	= 0x0008,
254107441Sscottl	/* The Non-LQ CRC error status is delayed until phase change. */
25597883Sgibbs	AHD_NLQICRC_DELAYED_BUG	= 0x0010,
256107441Sscottl	/* The chip must be reset for all outgoing bus resets.  */
25797883Sgibbs	AHD_SCSIRST_BUG		= 0x0020,
258107441Sscottl	/* Some PCIX fields must be saved and restored across chip reset. */
259102680Sgibbs	AHD_PCIX_CHIPRST_BUG	= 0x0040,
260107441Sscottl	/* MMAPIO is not functional in PCI-X mode.  */
261102680Sgibbs	AHD_PCIX_MMAPIO_BUG	= 0x0080,
262111954Sgibbs	/* Reads to SCBRAM fail to reset the discard timer. */
263111954Sgibbs	AHD_PCIX_SCBRAM_RD_BUG  = 0x0100,
26497883Sgibbs	/* Bug workarounds that can be disabled on non-PCIX busses. */
265102680Sgibbs	AHD_PCIX_BUG_MASK	= AHD_PCIX_CHIPRST_BUG
266111954Sgibbs				| AHD_PCIX_MMAPIO_BUG
267111954Sgibbs				| AHD_PCIX_SCBRAM_RD_BUG,
268107441Sscottl	/*
269107441Sscottl	 * LQOSTOP0 status set even for forced selections with ATN
270107441Sscottl	 * to perform non-packetized message delivery.
271107441Sscottl	 */
272111954Sgibbs	AHD_LQO_ATNO_BUG	= 0x0200,
273107441Sscottl	/* FIFO auto-flush does not always trigger.  */
274111954Sgibbs	AHD_AUTOFLUSH_BUG	= 0x0400,
275107441Sscottl	/* The CLRLQO registers are not self-clearing. */
276111954Sgibbs	AHD_CLRLQO_AUTOCLR_BUG	= 0x0800,
277107441Sscottl	/* The PACKETIZED status bit refers to the previous connection. */
278111954Sgibbs	AHD_PKTIZED_STATUS_BUG  = 0x1000,
279107441Sscottl	/* "Short Luns" are not placed into outgoing LQ packets correctly. */
280111954Sgibbs	AHD_PKT_LUN_BUG		= 0x2000,
281107441Sscottl	/*
282107441Sscottl	 * Only the FIFO allocated to the non-packetized connection may
283107441Sscottl	 * be in use during a non-packetzied connection.
284107441Sscottl	 */
285111954Sgibbs	AHD_NONPACKFIFO_BUG	= 0x4000,
286107441Sscottl	/*
287107441Sscottl	 * Writing to a DFF SCBPTR register may fail if concurent with
288107441Sscottl	 * a hardware write to the other DFF SCBPTR register.  This is
289107441Sscottl	 * not currently a concern in our sequencer since all chips with
290107441Sscottl	 * this bug have the AHD_NONPACKFIFO_BUG and all writes of concern
291107441Sscottl	 * occur in non-packetized connections.
292107441Sscottl	 */
293111954Sgibbs	AHD_MDFF_WSCBPTR_BUG	= 0x8000,
294107441Sscottl	/* SGHADDR updates are slow. */
295111954Sgibbs	AHD_REG_SLOW_SETTLE_BUG	= 0x10000,
296107441Sscottl	/*
297107441Sscottl	 * Changing the MODE_PTR coincident with an interrupt that
298107441Sscottl	 * switches to a different mode will cause the interrupt to
299107441Sscottl	 * be in the mode written outside of interrupt context.
300107441Sscottl	 */
301111954Sgibbs	AHD_SET_MODE_BUG	= 0x20000,
302107441Sscottl	/* Non-packetized busfree revision does not work. */
303111954Sgibbs	AHD_BUSFREEREV_BUG	= 0x40000,
304107441Sscottl	/*
305107441Sscottl	 * Paced transfers are indicated with a non-standard PPR
306107441Sscottl	 * option bit in the neg table, 160MHz is indicated by
307107441Sscottl	 * sync factor 0x7, and the offset if off by a factor of 2.
308107441Sscottl	 */
309111954Sgibbs	AHD_PACED_NEGTABLE_BUG	= 0x80000,
310107441Sscottl	/* LQOOVERRUN false positives. */
311111954Sgibbs	AHD_LQOOVERRUN_BUG	= 0x100000,
312107441Sscottl	/*
313107441Sscottl	 * Controller write to INTSTAT will lose to a host
314107441Sscottl	 * write to CLRINT.
315107441Sscottl	 */
316111954Sgibbs	AHD_INTCOLLISION_BUG	= 0x200000,
317111653Sgibbs	/*
318111653Sgibbs	 * The GEM318 violates the SCSI spec by not waiting
319111653Sgibbs	 * the mandated bus settle delay between phase changes
320111653Sgibbs	 * in some situations.  Some aic79xx chip revs. are more
321111653Sgibbs	 * strict in this regard and will treat REQ assertions
322111653Sgibbs	 * that fall within the bus settle delay window as
323111653Sgibbs	 * glitches.  This flag tells the firmware to tolerate
324111653Sgibbs	 * early REQ assertions.
325111653Sgibbs	 */
326114623Sgibbs	AHD_EARLY_REQ_BUG	= 0x400000,
327114623Sgibbs	/*
328114623Sgibbs	 * The LED does not stay on long enough in packetized modes.
329114623Sgibbs	 */
330114623Sgibbs	AHD_FAINT_LED_BUG	= 0x800000
33197883Sgibbs} ahd_bug;
33297883Sgibbs
33397883Sgibbs/*
33497883Sgibbs * Configuration specific settings.
33597883Sgibbs * The driver determines these settings by probing the
33697883Sgibbs * chip/controller's configuration.
33797883Sgibbs */
33897883Sgibbstypedef enum {
33997883Sgibbs	AHD_FNONE	      = 0x00000,
340114623Sgibbs	AHD_BOOT_CHANNEL      = 0x00001,/* We were set as the boot channel. */
34197883Sgibbs	AHD_USEDEFAULTS	      = 0x00004,/*
34297883Sgibbs					 * For cards without an seeprom
34397883Sgibbs					 * or a BIOS to initialize the chip's
34497883Sgibbs					 * SRAM, we use the default target
34597883Sgibbs					 * settings.
34697883Sgibbs					 */
34797883Sgibbs	AHD_SEQUENCER_DEBUG   = 0x00008,
34897883Sgibbs	AHD_RESET_BUS_A	      = 0x00010,
34997883Sgibbs	AHD_EXTENDED_TRANS_A  = 0x00020,
35097883Sgibbs	AHD_TERM_ENB_A	      = 0x00040,
35197883Sgibbs	AHD_SPCHK_ENB_A	      = 0x00080,
35297883Sgibbs	AHD_STPWLEVEL_A	      = 0x00100,
35397883Sgibbs	AHD_INITIATORROLE     = 0x00200,/*
35497883Sgibbs					 * Allow initiator operations on
35597883Sgibbs					 * this controller.
35697883Sgibbs					 */
35797883Sgibbs	AHD_TARGETROLE	      = 0x00400,/*
35897883Sgibbs					 * Allow target operations on this
35997883Sgibbs					 * controller.
36097883Sgibbs					 */
36197883Sgibbs	AHD_RESOURCE_SHORTAGE = 0x00800,
36297883Sgibbs	AHD_TQINFIFO_BLOCKED  = 0x01000,/* Blocked waiting for ATIOs */
36397883Sgibbs	AHD_INT50_SPEEDFLEX   = 0x02000,/*
36497883Sgibbs					 * Internal 50pin connector
36597883Sgibbs					 * sits behind an aic3860
36697883Sgibbs					 */
36797883Sgibbs	AHD_BIOS_ENABLED      = 0x04000,
36897883Sgibbs	AHD_ALL_INTERRUPTS    = 0x08000,
36997883Sgibbs	AHD_39BIT_ADDRESSING  = 0x10000,/* Use 39 bit addressing scheme. */
37097883Sgibbs	AHD_64BIT_ADDRESSING  = 0x20000,/* Use 64 bit addressing scheme. */
37197883Sgibbs	AHD_CURRENT_SENSING   = 0x40000,
37297883Sgibbs	AHD_SCB_CONFIG_USED   = 0x80000,/* No SEEPROM but SCB had info. */
373107441Sscottl	AHD_HP_BOARD	      = 0x100000,
374109588Sgibbs	AHD_RESET_POLL_ACTIVE = 0x200000,
375109588Sgibbs	AHD_UPDATE_PEND_CMDS  = 0x400000,
376116938Sgibbs	AHD_RUNNING_QOUTFIFO  = 0x800000,
377116938Sgibbs	AHD_HAD_FIRST_SEL     = 0x1000000
37897883Sgibbs} ahd_flag;
37997883Sgibbs
38097883Sgibbs/************************* Hardware  SCB Definition ***************************/
38197883Sgibbs
38297883Sgibbs/*
38397883Sgibbs * The driver keeps up to MAX_SCB scb structures per card in memory.  The SCB
384114623Sgibbs * consists of a "hardware SCB" mirroring the fields available on the card
38597883Sgibbs * and additional information the kernel stores for each transaction.
38697883Sgibbs *
38797883Sgibbs * To minimize space utilization, a portion of the hardware scb stores
38897883Sgibbs * different data during different portions of a SCSI transaction.
38997883Sgibbs * As initialized by the host driver for the initiator role, this area
39097883Sgibbs * contains the SCSI cdb (or a pointer to the  cdb) to be executed.  After
39197883Sgibbs * the cdb has been presented to the target, this area serves to store
39297883Sgibbs * residual transfer information and the SCSI status byte.
39397883Sgibbs * For the target role, the contents of this area do not change, but
39497883Sgibbs * still serve a different purpose than for the initiator role.  See
39597883Sgibbs * struct target_data for details.
39697883Sgibbs */
39797883Sgibbs
39897883Sgibbs/*
39997883Sgibbs * Status information embedded in the shared poriton of
40097883Sgibbs * an SCB after passing the cdb to the target.  The kernel
40197883Sgibbs * driver will only read this data for transactions that
40297883Sgibbs * complete abnormally.
40397883Sgibbs */
40497883Sgibbsstruct initiator_status {
40597883Sgibbs	uint32_t residual_datacnt;	/* Residual in the current S/G seg */
40697883Sgibbs	uint32_t residual_sgptr;	/* The next S/G for this transfer */
40797883Sgibbs	uint8_t	 scsi_status;		/* Standard SCSI status byte */
40897883Sgibbs};
40997883Sgibbs
41097883Sgibbsstruct target_status {
41197883Sgibbs	uint32_t residual_datacnt;	/* Residual in the current S/G seg */
41297883Sgibbs	uint32_t residual_sgptr;	/* The next S/G for this transfer */
41397883Sgibbs	uint8_t  scsi_status;		/* SCSI status to give to initiator */
41497883Sgibbs	uint8_t  target_phases;		/* Bitmap of phases to execute */
41597883Sgibbs	uint8_t  data_phase;		/* Data-In or Data-Out */
41697883Sgibbs	uint8_t  initiator_tag;		/* Initiator's transaction tag */
41797883Sgibbs};
41897883Sgibbs
41997883Sgibbs/*
42097883Sgibbs * Initiator mode SCB shared data area.
42197883Sgibbs * If the embedded CDB is 12 bytes or less, we embed
42297883Sgibbs * the sense buffer address in the SCB.  This allows
423111653Sgibbs * us to retrieve sense information without interrupting
42497883Sgibbs * the host in packetized mode.
42597883Sgibbs */
42697883Sgibbstypedef uint32_t sense_addr_t;
42797883Sgibbs#define MAX_CDB_LEN 16
42897883Sgibbs#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t))
42997883Sgibbsunion initiator_data {
430111653Sgibbs	struct {
431111653Sgibbs		uint64_t cdbptr;
432111653Sgibbs		uint8_t  cdblen;
433111653Sgibbs	} cdb_from_host;
43497883Sgibbs	uint8_t	 cdb[MAX_CDB_LEN];
43597883Sgibbs	struct {
43697883Sgibbs		uint8_t	 cdb[MAX_CDB_LEN_WITH_SENSE_ADDR];
43797883Sgibbs		sense_addr_t sense_addr;
43897883Sgibbs	} cdb_plus_saddr;
43997883Sgibbs};
44097883Sgibbs
44197883Sgibbs/*
44297883Sgibbs * Target mode version of the shared data SCB segment.
44397883Sgibbs */
44497883Sgibbsstruct target_data {
44597883Sgibbs	uint32_t spare[2];
44697883Sgibbs	uint8_t  scsi_status;		/* SCSI status to give to initiator */
44797883Sgibbs	uint8_t  target_phases;		/* Bitmap of phases to execute */
44897883Sgibbs	uint8_t  data_phase;		/* Data-In or Data-Out */
44997883Sgibbs	uint8_t  initiator_tag;		/* Initiator's transaction tag */
45097883Sgibbs};
45197883Sgibbs
45297883Sgibbsstruct hardware_scb {
45397883Sgibbs/*0*/	union {
45497883Sgibbs		union	initiator_data idata;
45597883Sgibbs		struct	target_data tdata;
45697883Sgibbs		struct	initiator_status istatus;
45797883Sgibbs		struct	target_status tstatus;
45897883Sgibbs	} shared_data;
45997883Sgibbs/*
46097883Sgibbs * A word about residuals.
46197883Sgibbs * The scb is presented to the sequencer with the dataptr and datacnt
46297883Sgibbs * fields initialized to the contents of the first S/G element to
46397883Sgibbs * transfer.  The sgptr field is initialized to the bus address for
46497883Sgibbs * the S/G element that follows the first in the in core S/G array
46597883Sgibbs * or'ed with the SG_FULL_RESID flag.  Sgptr may point to an invalid
46697883Sgibbs * S/G entry for this transfer (single S/G element transfer with the
46797883Sgibbs * first elements address and length preloaded in the dataptr/datacnt
46897883Sgibbs * fields).  If no transfer is to occur, sgptr is set to SG_LIST_NULL.
46997883Sgibbs * The SG_FULL_RESID flag ensures that the residual will be correctly
47097883Sgibbs * noted even if no data transfers occur.  Once the data phase is entered,
47197883Sgibbs * the residual sgptr and datacnt are loaded from the sgptr and the
47297883Sgibbs * datacnt fields.  After each S/G element's dataptr and length are
47397883Sgibbs * loaded into the hardware, the residual sgptr is advanced.  After
47497883Sgibbs * each S/G element is expired, its datacnt field is checked to see
47597883Sgibbs * if the LAST_SEG flag is set.  If so, SG_LIST_NULL is set in the
47697883Sgibbs * residual sg ptr and the transfer is considered complete.  If the
47797883Sgibbs * sequencer determines that there is a residual in the tranfer, or
47897883Sgibbs * there is non-zero status, it will set the SG_STATUS_VALID flag in
47997883Sgibbs * sgptr and dma the scb back into host memory.  To sumarize:
48097883Sgibbs *
48197883Sgibbs * Sequencer:
48297883Sgibbs *	o A residual has occurred if SG_FULL_RESID is set in sgptr,
48397883Sgibbs *	  or residual_sgptr does not have SG_LIST_NULL set.
48497883Sgibbs *
48597883Sgibbs *	o We are transfering the last segment if residual_datacnt has
48697883Sgibbs *	  the SG_LAST_SEG flag set.
48797883Sgibbs *
48897883Sgibbs * Host:
48997883Sgibbs *	o A residual can only have occurred if a completed scb has the
49097883Sgibbs *	  SG_STATUS_VALID flag set.  Inspection of the SCSI status field,
49197883Sgibbs *	  the residual_datacnt, and the residual_sgptr field will tell
49297883Sgibbs *	  for sure.
49397883Sgibbs *
49497883Sgibbs *	o residual_sgptr and sgptr refer to the "next" sg entry
49597883Sgibbs *	  and so may point beyond the last valid sg entry for the
49697883Sgibbs *	  transfer.
49797883Sgibbs */
49897883Sgibbs#define SG_PTR_MASK	0xFFFFFFF8
499115407Sscottl/*16*/	uint16_t tag;		/* Reused by Sequencer. */
500115407Sscottl/*18*/	uint8_t  control;	/* See SCB_CONTROL in aic79xx.reg for details */
501115407Sscottl/*19*/	uint8_t	 scsiid;	/*
50297883Sgibbs				 * Selection out Id
50397883Sgibbs				 * Our Id (bits 0-3) Their ID (bits 4-7)
50497883Sgibbs				 */
505115407Sscottl/*20*/	uint8_t  lun;
506115407Sscottl/*21*/	uint8_t  task_attribute;
507115407Sscottl/*22*/	uint8_t  cdb_len;
508115407Sscottl/*23*/	uint8_t  task_management;
509115407Sscottl/*24*/	uint64_t dataptr;
510115407Sscottl/*32*/	uint32_t datacnt;	/* Byte 3 is spare. */
511115407Sscottl/*36*/	uint32_t sgptr;
512115407Sscottl/*40*/	uint32_t hscb_busaddr;
513115407Sscottl/*44*/	uint32_t next_hscb_busaddr;
514114623Sgibbs/********** Long lun field only downloaded for full 8 byte lun support ********/
515102680Sgibbs/*48*/  uint8_t	 pkt_long_lun[8];
51697883Sgibbs/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/
517102680Sgibbs/*56*/  uint8_t	 spare[8];
51897883Sgibbs};
51997883Sgibbs
52097883Sgibbs/************************ Kernel SCB Definitions ******************************/
52197883Sgibbs/*
52297883Sgibbs * Some fields of the SCB are OS dependent.  Here we collect the
52397883Sgibbs * definitions for elements that all OS platforms need to include
52497883Sgibbs * in there SCB definition.
52597883Sgibbs */
52697883Sgibbs
52797883Sgibbs/*
52897883Sgibbs * Definition of a scatter/gather element as transfered to the controller.
52997883Sgibbs * The aic7xxx chips only support a 24bit length.  We use the top byte of
53097883Sgibbs * the length to store additional address bits and a flag to indicate
53197883Sgibbs * that a given segment terminates the transfer.  This gives us an
53297883Sgibbs * addressable range of 512GB on machines with 64bit PCI or with chips
53397883Sgibbs * that can support dual address cycles on 32bit PCI busses.
53497883Sgibbs */
53597883Sgibbsstruct ahd_dma_seg {
53697883Sgibbs	uint32_t	addr;
53797883Sgibbs	uint32_t	len;
53897883Sgibbs#define	AHD_DMA_LAST_SEG	0x80000000
53997883Sgibbs#define	AHD_SG_HIGH_ADDR_MASK	0x7F000000
54097883Sgibbs#define	AHD_SG_LEN_MASK		0x00FFFFFF
54197883Sgibbs};
54297883Sgibbs
54397883Sgibbsstruct ahd_dma64_seg {
54497883Sgibbs	uint64_t	addr;
54597883Sgibbs	uint32_t	len;
54697883Sgibbs	uint32_t	pad;
54797883Sgibbs};
54897883Sgibbs
54997883Sgibbsstruct map_node {
55097883Sgibbs	bus_dmamap_t		 dmamap;
55197883Sgibbs	bus_addr_t		 physaddr;
55297883Sgibbs	uint8_t			*vaddr;
55397883Sgibbs	SLIST_ENTRY(map_node)	 links;
55497883Sgibbs};
55597883Sgibbs
55697883Sgibbs/*
55797883Sgibbs * The current state of this SCB.
55897883Sgibbs */
55997883Sgibbstypedef enum {
560102680Sgibbs	SCB_FLAG_NONE		= 0x00000,
561102680Sgibbs	SCB_TRANSMISSION_ERROR	= 0x00001,/*
562102680Sgibbs					   * We detected a parity or CRC
563102680Sgibbs					   * error that has effected the
564102680Sgibbs					   * payload of the command.  This
565102680Sgibbs					   * flag is checked when normal
566102680Sgibbs					   * status is returned to catch
567102680Sgibbs					   * the case of a target not
568102680Sgibbs					   * responding to our attempt
569102680Sgibbs					   * to report the error.
570102680Sgibbs					   */
571102680Sgibbs	SCB_OTHERTCL_TIMEOUT	= 0x00002,/*
572102680Sgibbs					   * Another device was active
573102680Sgibbs					   * during the first timeout for
574102680Sgibbs					   * this SCB so we gave ourselves
575102680Sgibbs					   * an additional timeout period
576102680Sgibbs					   * in case it was hogging the
577102680Sgibbs					   * bus.
578102680Sgibbs				           */
579102680Sgibbs	SCB_DEVICE_RESET	= 0x00004,
580102680Sgibbs	SCB_SENSE		= 0x00008,
581102680Sgibbs	SCB_CDB32_PTR		= 0x00010,
582102680Sgibbs	SCB_RECOVERY_SCB	= 0x00020,
583102680Sgibbs	SCB_AUTO_NEGOTIATE	= 0x00040,/* Negotiate to achieve goal. */
584102680Sgibbs	SCB_NEGOTIATE		= 0x00080,/* Negotiation forced for command. */
585102680Sgibbs	SCB_ABORT		= 0x00100,
586107441Sscottl	SCB_ACTIVE		= 0x00200,
587107441Sscottl	SCB_TARGET_IMMEDIATE	= 0x00400,
588107441Sscottl	SCB_PACKETIZED		= 0x00800,
589107441Sscottl	SCB_EXPECT_PPR_BUSFREE	= 0x01000,
590107441Sscottl	SCB_PKT_SENSE		= 0x02000,
591107441Sscottl	SCB_CMDPHASE_ABORT	= 0x04000,
592109588Sgibbs	SCB_ON_COL_LIST		= 0x08000,
593109588Sgibbs	SCB_SILENT		= 0x10000 /*
594109588Sgibbs					   * Be quiet about transmission type
595109588Sgibbs					   * errors.  They are expected and we
596109588Sgibbs					   * don't want to upset the user.  This
597109588Sgibbs					   * flag is typically used during DV.
598109588Sgibbs					   */
59997883Sgibbs} scb_flag;
60097883Sgibbs
60197883Sgibbsstruct scb {
60297883Sgibbs	struct	hardware_scb	 *hscb;
60397883Sgibbs	union {
60497883Sgibbs		SLIST_ENTRY(scb)  sle;
605102680Sgibbs		LIST_ENTRY(scb)	  le;
60697883Sgibbs		TAILQ_ENTRY(scb)  tqe;
60797883Sgibbs	} links;
608102680Sgibbs	union {
609102680Sgibbs		SLIST_ENTRY(scb)  sle;
610102680Sgibbs		LIST_ENTRY(scb)	  le;
611102680Sgibbs		TAILQ_ENTRY(scb)  tqe;
612102680Sgibbs	} links2;
613102680Sgibbs#define pending_links links2.le
614102680Sgibbs#define collision_links links2.le
615102680Sgibbs	struct scb		 *col_scb;
61697883Sgibbs	ahd_io_ctx_t		  io_ctx;
61797883Sgibbs	struct ahd_softc	 *ahd_softc;
61897883Sgibbs	scb_flag		  flags;
61997883Sgibbs#ifndef __linux__
62097883Sgibbs	bus_dmamap_t		  dmamap;
62197883Sgibbs#endif
62297883Sgibbs	struct scb_platform_data *platform_data;
62397883Sgibbs	struct map_node	 	 *hscb_map;
62497883Sgibbs	struct map_node	 	 *sg_map;
62597883Sgibbs	struct map_node	 	 *sense_map;
62697883Sgibbs	void			 *sg_list;
62797883Sgibbs	uint8_t			 *sense_data;
62897883Sgibbs	bus_addr_t		  sg_list_busaddr;
62997883Sgibbs	bus_addr_t		  sense_busaddr;
63097883Sgibbs	u_int			  sg_count;/* How full ahd_dma_seg is */
631107441Sscottl#define	AHD_MAX_LQ_CRC_ERRORS 5
632107441Sscottl	u_int			  crc_retry_count;
63397883Sgibbs};
63497883Sgibbs
635102680SgibbsTAILQ_HEAD(scb_tailq, scb);
636102680SgibbsLIST_HEAD(scb_list, scb);
637102680Sgibbs
63897883Sgibbsstruct scb_data {
639102680Sgibbs	/*
640102680Sgibbs	 * TAILQ of lists of free SCBs grouped by device
641102680Sgibbs	 * collision domains.
642102680Sgibbs	 */
643102680Sgibbs	struct scb_tailq free_scbs;
644102680Sgibbs
645102680Sgibbs	/*
646102680Sgibbs	 * Per-device lists of SCBs whose tag ID would collide
647102680Sgibbs	 * with an already active tag on the device.
648102680Sgibbs	 */
649102680Sgibbs	struct scb_list free_scb_lists[AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT];
650102680Sgibbs
651102680Sgibbs	/*
652102680Sgibbs	 * SCBs that will not collide with any active device.
653102680Sgibbs	 */
654102680Sgibbs	struct scb_list any_dev_free_scb_list;
655102680Sgibbs
656102680Sgibbs	/*
657102680Sgibbs	 * Mapping from tag to SCB.
658102680Sgibbs	 */
65997883Sgibbs	struct	scb *scbindex[AHD_SCB_MAX];
660102680Sgibbs
66197883Sgibbs	/*
66297883Sgibbs	 * "Bus" addresses of our data structures.
66397883Sgibbs	 */
66497883Sgibbs	bus_dma_tag_t	 hscb_dmat;	/* dmat for our hardware SCB array */
66597883Sgibbs	bus_dma_tag_t	 sg_dmat;	/* dmat for our sg segments */
66697883Sgibbs	bus_dma_tag_t	 sense_dmat;	/* dmat for our sense buffers */
66797883Sgibbs	SLIST_HEAD(, map_node) hscb_maps;
66897883Sgibbs	SLIST_HEAD(, map_node) sg_maps;
66997883Sgibbs	SLIST_HEAD(, map_node) sense_maps;
67097883Sgibbs	int		 scbs_left;	/* unallocated scbs in head map_node */
67197883Sgibbs	int		 sgs_left;	/* unallocated sgs in head map_node */
67297883Sgibbs	int		 sense_left;	/* unallocated sense in head map_node */
67397883Sgibbs	uint16_t	 numscbs;
67497883Sgibbs	uint16_t	 maxhscbs;	/* Number of SCBs on the card */
67597883Sgibbs	uint8_t		 init_level;	/*
67697883Sgibbs					 * How far we've initialized
67797883Sgibbs					 * this structure.
67897883Sgibbs					 */
67997883Sgibbs};
68097883Sgibbs
68197883Sgibbs/************************ Target Mode Definitions *****************************/
68297883Sgibbs
68397883Sgibbs/*
68497883Sgibbs * Connection desciptor for select-in requests in target mode.
68597883Sgibbs */
68697883Sgibbsstruct target_cmd {
68797883Sgibbs	uint8_t scsiid;		/* Our ID and the initiator's ID */
68897883Sgibbs	uint8_t identify;	/* Identify message */
68997883Sgibbs	uint8_t bytes[22];	/*
69097883Sgibbs				 * Bytes contains any additional message
69197883Sgibbs				 * bytes terminated by 0xFF.  The remainder
69297883Sgibbs				 * is the cdb to execute.
69397883Sgibbs				 */
69497883Sgibbs	uint8_t cmd_valid;	/*
69597883Sgibbs				 * When a command is complete, the firmware
69697883Sgibbs				 * will set cmd_valid to all bits set.
69797883Sgibbs				 * After the host has seen the command,
69897883Sgibbs				 * the bits are cleared.  This allows us
69997883Sgibbs				 * to just peek at host memory to determine
70097883Sgibbs				 * if more work is complete. cmd_valid is on
70197883Sgibbs				 * an 8 byte boundary to simplify setting
70297883Sgibbs				 * it on aic7880 hardware which only has
70397883Sgibbs				 * limited direct access to the DMA FIFO.
70497883Sgibbs				 */
70597883Sgibbs	uint8_t pad[7];
70697883Sgibbs};
70797883Sgibbs
70897883Sgibbs/*
70997883Sgibbs * Number of events we can buffer up if we run out
71097883Sgibbs * of immediate notify ccbs.
71197883Sgibbs */
71297883Sgibbs#define AHD_TMODE_EVENT_BUFFER_SIZE 8
71397883Sgibbsstruct ahd_tmode_event {
71497883Sgibbs	uint8_t initiator_id;
71597883Sgibbs	uint8_t event_type;	/* MSG type or EVENT_TYPE_BUS_RESET */
71697883Sgibbs#define	EVENT_TYPE_BUS_RESET 0xFF
71797883Sgibbs	uint8_t event_arg;
71897883Sgibbs};
71997883Sgibbs
72097883Sgibbs/*
72197883Sgibbs * Per enabled lun target mode state.
72297883Sgibbs * As this state is directly influenced by the host OS'es target mode
72397883Sgibbs * environment, we let the OS module define it.  Forward declare the
72497883Sgibbs * structure here so we can store arrays of them, etc. in OS neutral
72597883Sgibbs * data structures.
72697883Sgibbs */
72797883Sgibbs#ifdef AHD_TARGET_MODE
72897883Sgibbsstruct ahd_tmode_lstate {
72997883Sgibbs	struct cam_path *path;
73097883Sgibbs	struct ccb_hdr_slist accept_tios;
73197883Sgibbs	struct ccb_hdr_slist immed_notifies;
73297883Sgibbs	struct ahd_tmode_event event_buffer[AHD_TMODE_EVENT_BUFFER_SIZE];
73397883Sgibbs	uint8_t event_r_idx;
73497883Sgibbs	uint8_t event_w_idx;
73597883Sgibbs};
73697883Sgibbs#else
73797883Sgibbsstruct ahd_tmode_lstate;
73897883Sgibbs#endif
73997883Sgibbs
74097883Sgibbs/******************** Transfer Negotiation Datastructures *********************/
74197883Sgibbs#define AHD_TRANS_CUR		0x01	/* Modify current neogtiation status */
74297883Sgibbs#define AHD_TRANS_ACTIVE	0x03	/* Assume this target is on the bus */
74397883Sgibbs#define AHD_TRANS_GOAL		0x04	/* Modify negotiation goal */
74497883Sgibbs#define AHD_TRANS_USER		0x08	/* Modify user negotiation settings */
74597883Sgibbs#define AHD_PERIOD_10MHz	0x19
74697883Sgibbs
747107441Sscottl#define AHD_WIDTH_UNKNOWN	0xFF
748107441Sscottl#define AHD_PERIOD_UNKNOWN	0xFF
749111653Sgibbs#define AHD_OFFSET_UNKNOWN	0xFF
750107441Sscottl#define AHD_PPR_OPTS_UNKNOWN	0xFF
751107441Sscottl
75297883Sgibbs/*
75397883Sgibbs * Transfer Negotiation Information.
75497883Sgibbs */
75597883Sgibbsstruct ahd_transinfo {
75697883Sgibbs	uint8_t protocol_version;	/* SCSI Revision level */
75797883Sgibbs	uint8_t transport_version;	/* SPI Revision level */
75897883Sgibbs	uint8_t width;			/* Bus width */
75997883Sgibbs	uint8_t period;			/* Sync rate factor */
76097883Sgibbs	uint8_t offset;			/* Sync offset */
76197883Sgibbs	uint8_t ppr_options;		/* Parallel Protocol Request options */
76297883Sgibbs};
76397883Sgibbs
76497883Sgibbs/*
76597883Sgibbs * Per-initiator current, goal and user transfer negotiation information. */
76697883Sgibbsstruct ahd_initiator_tinfo {
76797883Sgibbs	struct ahd_transinfo curr;
76897883Sgibbs	struct ahd_transinfo goal;
76997883Sgibbs	struct ahd_transinfo user;
77097883Sgibbs};
77197883Sgibbs
77297883Sgibbs/*
77397883Sgibbs * Per enabled target ID state.
77497883Sgibbs * Pointers to lun target state as well as sync/wide negotiation information
77597883Sgibbs * for each initiator<->target mapping.  For the initiator role we pretend
77697883Sgibbs * that we are the target and the targets are the initiators since the
77797883Sgibbs * negotiation is the same regardless of role.
77897883Sgibbs */
77997883Sgibbsstruct ahd_tmode_tstate {
78097883Sgibbs	struct ahd_tmode_lstate*	enabled_luns[AHD_NUM_LUNS];
78197883Sgibbs	struct ahd_initiator_tinfo	transinfo[AHD_NUM_TARGETS];
78297883Sgibbs
78397883Sgibbs	/*
78497883Sgibbs	 * Per initiator state bitmasks.
78597883Sgibbs	 */
78697883Sgibbs	uint16_t	 auto_negotiate;/* Auto Negotiation Required */
78797883Sgibbs	uint16_t	 discenable;	/* Disconnection allowed  */
78897883Sgibbs	uint16_t	 tagenable;	/* Tagged Queuing allowed */
78997883Sgibbs};
79097883Sgibbs
79197883Sgibbs/*
79297883Sgibbs * Points of interest along the negotiated transfer scale.
79397883Sgibbs */
79497883Sgibbs#define AHD_SYNCRATE_160	0x8
79597883Sgibbs#define AHD_SYNCRATE_PACED	0x8
79697883Sgibbs#define AHD_SYNCRATE_DT		0x9
79797883Sgibbs#define AHD_SYNCRATE_ULTRA2	0xa
79897883Sgibbs#define AHD_SYNCRATE_ULTRA	0xc
79997883Sgibbs#define AHD_SYNCRATE_FAST	0x19
80097883Sgibbs#define AHD_SYNCRATE_MIN_DT	AHD_SYNCRATE_FAST
80197883Sgibbs#define AHD_SYNCRATE_SYNC	0x32
80297883Sgibbs#define AHD_SYNCRATE_MIN	0x60
80397883Sgibbs#define	AHD_SYNCRATE_ASYNC	0xFF
804109588Sgibbs#define AHD_SYNCRATE_MAX	AHD_SYNCRATE_160
80597883Sgibbs
806107441Sscottl/* Safe and valid period for async negotiations. */
807107441Sscottl#define	AHD_ASYNC_XFER_PERIOD	0x44
808107441Sscottl
80997883Sgibbs/*
81097883Sgibbs * In RevA, the synctable uses a 120MHz rate for the period
81197883Sgibbs * factor 8 and 160MHz for the period factor 7.  The 120MHz
81297883Sgibbs * rate never made it into the official SCSI spec, so we must
81397883Sgibbs * compensate when setting the negotiation table for Rev A
81497883Sgibbs * parts.
81597883Sgibbs */
81697883Sgibbs#define AHD_SYNCRATE_REVA_120	0x8
81797883Sgibbs#define AHD_SYNCRATE_REVA_160	0x7
81897883Sgibbs
81997883Sgibbs/***************************** Lookup Tables **********************************/
82097883Sgibbs/*
82197883Sgibbs * Phase -> name and message out response
82297883Sgibbs * to parity errors in each phase table.
82397883Sgibbs */
82497883Sgibbsstruct ahd_phase_table_entry {
82597883Sgibbs        uint8_t phase;
82697883Sgibbs        uint8_t mesg_out; /* Message response to parity errors */
82797883Sgibbs	char *phasemsg;
82897883Sgibbs};
82997883Sgibbs
83097883Sgibbs/************************** Serial EEPROM Format ******************************/
83197883Sgibbs
83297883Sgibbsstruct seeprom_config {
83397883Sgibbs/*
83497883Sgibbs * Per SCSI ID Configuration Flags
83597883Sgibbs */
83697883Sgibbs	uint16_t device_flags[16];	/* words 0-15 */
83797883Sgibbs#define		CFXFER		0x003F	/* synchronous transfer rate */
83897883Sgibbs#define			CFXFER_ASYNC	0x3F
83997883Sgibbs#define		CFQAS		0x0040	/* Negotiate QAS */
84097883Sgibbs#define		CFPACKETIZED	0x0080	/* Negotiate Packetized Transfers */
84197883Sgibbs#define		CFSTART		0x0100	/* send start unit SCSI command */
84297883Sgibbs#define		CFINCBIOS	0x0200	/* include in BIOS scan */
84397883Sgibbs#define		CFDISC		0x0400	/* enable disconnection */
84497883Sgibbs#define		CFMULTILUNDEV	0x0800	/* Probe multiple luns in BIOS scan */
84597883Sgibbs#define		CFWIDEB		0x1000	/* wide bus device */
84697883Sgibbs#define		CFHOSTMANAGED	0x8000	/* Managed by a RAID controller */
84797883Sgibbs
84897883Sgibbs/*
84997883Sgibbs * BIOS Control Bits
85097883Sgibbs */
85197883Sgibbs	uint16_t bios_control;		/* word 16 */
85297883Sgibbs#define		CFSUPREM	0x0001	/* support all removeable drives */
85397883Sgibbs#define		CFSUPREMB	0x0002	/* support removeable boot drives */
85497883Sgibbs#define		CFBIOSSTATE	0x000C	/* BIOS Action State */
85597883Sgibbs#define		    CFBS_DISABLED	0x00
85697883Sgibbs#define		    CFBS_ENABLED	0x04
85797883Sgibbs#define		    CFBS_DISABLED_SCAN	0x08
85897883Sgibbs#define		CFENABLEDV	0x0010	/* Perform Domain Validation */
85997883Sgibbs#define		CFCTRL_A	0x0020	/* BIOS displays Ctrl-A message */
86097883Sgibbs#define		CFSPARITY	0x0040	/* SCSI parity */
86197883Sgibbs#define		CFEXTEND	0x0080	/* extended translation enabled */
86297883Sgibbs#define		CFBOOTCD	0x0100  /* Support Bootable CD-ROM */
86397883Sgibbs#define		CFMSG_LEVEL	0x0600	/* BIOS Message Level */
86497883Sgibbs#define			CFMSG_VERBOSE	0x0000
86597883Sgibbs#define			CFMSG_SILENT	0x0200
86697883Sgibbs#define			CFMSG_DIAG	0x0400
86797883Sgibbs#define		CFRESETB	0x0800	/* reset SCSI bus at boot */
86897883Sgibbs/*		UNUSED		0xf000	*/
86997883Sgibbs
87097883Sgibbs/*
87197883Sgibbs * Host Adapter Control Bits
87297883Sgibbs */
87397883Sgibbs	uint16_t adapter_control;	/* word 17 */
87497883Sgibbs#define		CFAUTOTERM	0x0001	/* Perform Auto termination */
87597883Sgibbs#define		CFSTERM		0x0002	/* SCSI low byte termination */
87697883Sgibbs#define		CFWSTERM	0x0004	/* SCSI high byte termination */
87797883Sgibbs#define		CFSEAUTOTERM	0x0008	/* Ultra2 Perform secondary Auto Term*/
87897883Sgibbs#define		CFSELOWTERM	0x0010	/* Ultra2 secondary low term */
87997883Sgibbs#define		CFSEHIGHTERM	0x0020	/* Ultra2 secondary high term */
88097883Sgibbs#define		CFSTPWLEVEL	0x0040	/* Termination level control */
88197883Sgibbs#define		CFBIOSAUTOTERM	0x0080	/* Perform Auto termination */
88297883Sgibbs#define		CFTERM_MENU	0x0100	/* BIOS displays termination menu */
88397883Sgibbs#define		CFCLUSTERENB	0x8000	/* Cluster Enable */
88497883Sgibbs
88597883Sgibbs/*
88697883Sgibbs * Bus Release Time, Host Adapter ID
88797883Sgibbs */
88897883Sgibbs	uint16_t brtime_id;		/* word 18 */
88997883Sgibbs#define		CFSCSIID	0x000f	/* host adapter SCSI ID */
89097883Sgibbs/*		UNUSED		0x00f0	*/
89197883Sgibbs#define		CFBRTIME	0xff00	/* bus release time/PCI Latency Time */
89297883Sgibbs
89397883Sgibbs/*
89497883Sgibbs * Maximum targets
89597883Sgibbs */
89697883Sgibbs	uint16_t max_targets;		/* word 19 */
89797883Sgibbs#define		CFMAXTARG	0x00ff	/* maximum targets */
89897883Sgibbs#define		CFBOOTLUN	0x0f00	/* Lun to boot from */
89997883Sgibbs#define		CFBOOTID	0xf000	/* Target to boot from */
90097883Sgibbs	uint16_t res_1[10];		/* words 20-29 */
90197883Sgibbs	uint16_t signature;		/* BIOS Signature */
90297883Sgibbs#define		CFSIGNATURE	0x400
90397883Sgibbs	uint16_t checksum;		/* word 31 */
90497883Sgibbs};
90597883Sgibbs
906114623Sgibbs/*
907114623Sgibbs * Vital Product Data used during POST and by the BIOS.
908114623Sgibbs */
909114623Sgibbsstruct vpd_config {
910114623Sgibbs	uint8_t  bios_flags;
911114623Sgibbs#define		VPDMASTERBIOS	0x0001
912114623Sgibbs#define		VPDBOOTHOST	0x0002
913114623Sgibbs	uint8_t  reserved_1[21];
914114623Sgibbs	uint8_t  resource_type;
915114623Sgibbs	uint8_t  resource_len[2];
916114623Sgibbs	uint8_t  resource_data[8];
917114623Sgibbs	uint8_t  vpd_tag;
918114623Sgibbs	uint16_t vpd_len;
919114623Sgibbs	uint8_t  vpd_keyword[2];
920114623Sgibbs	uint8_t  length;
921114623Sgibbs	uint8_t  revision;
922114623Sgibbs	uint8_t  device_flags;
923114623Sgibbs	uint8_t  termnation_menus[2];
924114623Sgibbs	uint8_t  fifo_threshold;
925114623Sgibbs	uint8_t  end_tag;
926114623Sgibbs	uint8_t  vpd_checksum;
927114623Sgibbs	uint16_t default_target_flags;
928114623Sgibbs	uint16_t default_bios_flags;
929114623Sgibbs	uint16_t default_ctrl_flags;
930114623Sgibbs	uint8_t  default_irq;
931114623Sgibbs	uint8_t  pci_lattime;
932114623Sgibbs	uint8_t  max_target;
933114623Sgibbs	uint8_t  boot_lun;
934114623Sgibbs	uint16_t signature;
935114623Sgibbs	uint8_t  reserved_2;
936114623Sgibbs	uint8_t  checksum;
937114623Sgibbs	uint8_t	 reserved_3[4];
938114623Sgibbs};
939114623Sgibbs
94097883Sgibbs/****************************** Flexport Logic ********************************/
94197883Sgibbs#define FLXADDR_TERMCTL			0x0
94297883Sgibbs#define		FLX_TERMCTL_ENSECHIGH	0x8
94397883Sgibbs#define		FLX_TERMCTL_ENSECLOW	0x4
94497883Sgibbs#define		FLX_TERMCTL_ENPRIHIGH	0x2
94597883Sgibbs#define		FLX_TERMCTL_ENPRILOW	0x1
94697883Sgibbs#define FLXADDR_ROMSTAT_CURSENSECTL	0x1
94797883Sgibbs#define		FLX_ROMSTAT_SEECFG	0xF0
94897883Sgibbs#define		FLX_ROMSTAT_EECFG	0x0F
94997883Sgibbs#define		FLX_ROMSTAT_SEE_93C66	0x00
95097883Sgibbs#define		FLX_ROMSTAT_SEE_NONE	0xF0
95197883Sgibbs#define		FLX_ROMSTAT_EE_512x8	0x0
95297883Sgibbs#define		FLX_ROMSTAT_EE_1MBx8	0x1
95397883Sgibbs#define		FLX_ROMSTAT_EE_2MBx8	0x2
95497883Sgibbs#define		FLX_ROMSTAT_EE_4MBx8	0x3
95597883Sgibbs#define		FLX_ROMSTAT_EE_16MBx8	0x4
95697883Sgibbs#define 		CURSENSE_ENB	0x1
95797883Sgibbs#define	FLXADDR_FLEXSTAT		0x2
95897883Sgibbs#define		FLX_FSTAT_BUSY		0x1
95997883Sgibbs#define FLXADDR_CURRENT_STAT		0x4
96097883Sgibbs#define		FLX_CSTAT_SEC_HIGH	0xC0
96197883Sgibbs#define		FLX_CSTAT_SEC_LOW	0x30
96297883Sgibbs#define		FLX_CSTAT_PRI_HIGH	0x0C
96397883Sgibbs#define		FLX_CSTAT_PRI_LOW	0x03
96497883Sgibbs#define		FLX_CSTAT_MASK		0x03
96597883Sgibbs#define		FLX_CSTAT_SHIFT		2
96697883Sgibbs#define		FLX_CSTAT_OKAY		0x0
96797883Sgibbs#define		FLX_CSTAT_OVER		0x1
96897883Sgibbs#define		FLX_CSTAT_UNDER		0x2
96997883Sgibbs#define		FLX_CSTAT_INVALID	0x3
97097883Sgibbs
97197883Sgibbsint		ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
972114623Sgibbs				 u_int start_addr, u_int count, int bstream);
97397883Sgibbs
97497883Sgibbsint		ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
97597883Sgibbs				  u_int start_addr, u_int count);
97697883Sgibbsint		ahd_wait_seeprom(struct ahd_softc *ahd);
977114623Sgibbsint		ahd_verify_vpd_cksum(struct vpd_config *vpd);
97897883Sgibbsint		ahd_verify_cksum(struct seeprom_config *sc);
97997883Sgibbsint		ahd_acquire_seeprom(struct ahd_softc *ahd);
98097883Sgibbsvoid		ahd_release_seeprom(struct ahd_softc *ahd);
98197883Sgibbs
98297883Sgibbs/****************************  Message Buffer *********************************/
98397883Sgibbstypedef enum {
98497883Sgibbs	MSG_FLAG_NONE			= 0x00,
98597883Sgibbs	MSG_FLAG_EXPECT_PPR_BUSFREE	= 0x01,
98697883Sgibbs	MSG_FLAG_IU_REQ_CHANGED		= 0x02,
98797883Sgibbs	MSG_FLAG_EXPECT_IDE_BUSFREE	= 0x04,
988107441Sscottl	MSG_FLAG_EXPECT_QASREJ_BUSFREE	= 0x08,
989107441Sscottl	MSG_FLAG_PACKETIZED		= 0x10
99097883Sgibbs} ahd_msg_flags;
99197883Sgibbs
99297883Sgibbstypedef enum {
99397883Sgibbs	MSG_TYPE_NONE			= 0x00,
99497883Sgibbs	MSG_TYPE_INITIATOR_MSGOUT	= 0x01,
99597883Sgibbs	MSG_TYPE_INITIATOR_MSGIN	= 0x02,
99697883Sgibbs	MSG_TYPE_TARGET_MSGOUT		= 0x03,
99797883Sgibbs	MSG_TYPE_TARGET_MSGIN		= 0x04
99897883Sgibbs} ahd_msg_type;
99997883Sgibbs
100097883Sgibbstypedef enum {
100197883Sgibbs	MSGLOOP_IN_PROG,
100297883Sgibbs	MSGLOOP_MSGCOMPLETE,
100397883Sgibbs	MSGLOOP_TERMINATED
100497883Sgibbs} msg_loop_stat;
100597883Sgibbs
100697883Sgibbs/*********************** Software Configuration Structure *********************/
100797883Sgibbsstruct ahd_suspend_channel_state {
100897883Sgibbs	uint8_t	scsiseq;
100997883Sgibbs	uint8_t	sxfrctl0;
101097883Sgibbs	uint8_t	sxfrctl1;
101197883Sgibbs	uint8_t	simode0;
101297883Sgibbs	uint8_t	simode1;
101397883Sgibbs	uint8_t	seltimer;
101497883Sgibbs	uint8_t	seqctl;
101597883Sgibbs};
101697883Sgibbs
101797883Sgibbsstruct ahd_suspend_state {
101897883Sgibbs	struct	ahd_suspend_channel_state channel[2];
101997883Sgibbs	uint8_t	optionmode;
102097883Sgibbs	uint8_t	dscommand0;
102197883Sgibbs	uint8_t	dspcistatus;
102297883Sgibbs	/* hsmailbox */
102397883Sgibbs	uint8_t	crccontrol1;
102497883Sgibbs	uint8_t	scbbaddr;
102597883Sgibbs	/* Host and sequencer SCB counts */
102697883Sgibbs	uint8_t	dff_thrsh;
102797883Sgibbs	uint8_t	*scratch_ram;
102897883Sgibbs	uint8_t	*btt;
102997883Sgibbs};
103097883Sgibbs
103197883Sgibbstypedef void (*ahd_bus_intr_t)(struct ahd_softc *);
103297883Sgibbs
103397883Sgibbstypedef enum {
103497883Sgibbs	AHD_MODE_DFF0,
103597883Sgibbs	AHD_MODE_DFF1,
103697883Sgibbs	AHD_MODE_CCHAN,
103797883Sgibbs	AHD_MODE_SCSI,
103897883Sgibbs	AHD_MODE_CFG,
103997883Sgibbs	AHD_MODE_UNKNOWN
104097883Sgibbs} ahd_mode;
104197883Sgibbs
104297883Sgibbs#define AHD_MK_MSK(x) (0x01 << (x))
104397883Sgibbs#define AHD_MODE_DFF0_MSK	AHD_MK_MSK(AHD_MODE_DFF0)
104497883Sgibbs#define AHD_MODE_DFF1_MSK	AHD_MK_MSK(AHD_MODE_DFF1)
104597883Sgibbs#define AHD_MODE_CCHAN_MSK	AHD_MK_MSK(AHD_MODE_CCHAN)
104697883Sgibbs#define AHD_MODE_SCSI_MSK	AHD_MK_MSK(AHD_MODE_SCSI)
104797883Sgibbs#define AHD_MODE_CFG_MSK	AHD_MK_MSK(AHD_MODE_CFG)
104897883Sgibbs#define AHD_MODE_UNKNOWN_MSK	AHD_MK_MSK(AHD_MODE_UNKNOWN)
104997883Sgibbs#define AHD_MODE_ANY_MSK (~0)
105097883Sgibbs
105197883Sgibbstypedef uint8_t ahd_mode_state;
105297883Sgibbs
105397883Sgibbstypedef void ahd_callback_t (void *);
105497883Sgibbs
105597883Sgibbsstruct ahd_softc {
105697883Sgibbs	bus_space_tag_t           tags[2];
105797883Sgibbs	bus_space_handle_t        bshs[2];
105897883Sgibbs#ifndef __linux__
105997883Sgibbs	bus_dma_tag_t		  buffer_dmat;   /* dmat for buffer I/O */
106097883Sgibbs#endif
106197883Sgibbs	struct scb_data		  scb_data;
106297883Sgibbs
1063102680Sgibbs	struct hardware_scb	 *next_queued_hscb;
106497883Sgibbs
106597883Sgibbs	/*
106697883Sgibbs	 * SCBs that have been sent to the controller
106797883Sgibbs	 */
106897883Sgibbs	LIST_HEAD(, scb)	  pending_scbs;
106997883Sgibbs
107097883Sgibbs	/*
107197883Sgibbs	 * Current register window mode information.
107297883Sgibbs	 */
107397883Sgibbs	ahd_mode		  dst_mode;
107497883Sgibbs	ahd_mode		  src_mode;
107597883Sgibbs
107697883Sgibbs	/*
107797883Sgibbs	 * Saved register window mode information
107897883Sgibbs	 * used for restore on next unpause.
107997883Sgibbs	 */
108097883Sgibbs	ahd_mode		  saved_dst_mode;
108197883Sgibbs	ahd_mode		  saved_src_mode;
108297883Sgibbs
108397883Sgibbs	/*
108497883Sgibbs	 * Platform specific data.
108597883Sgibbs	 */
108697883Sgibbs	struct ahd_platform_data *platform_data;
108797883Sgibbs
108897883Sgibbs	/*
108997883Sgibbs	 * Platform specific device information.
109097883Sgibbs	 */
109197883Sgibbs	ahd_dev_softc_t		  dev_softc;
109297883Sgibbs
109397883Sgibbs	/*
109497883Sgibbs	 * Bus specific device information.
109597883Sgibbs	 */
109697883Sgibbs	ahd_bus_intr_t		  bus_intr;
109797883Sgibbs
109897883Sgibbs	/*
109997883Sgibbs	 * Target mode related state kept on a per enabled lun basis.
110097883Sgibbs	 * Targets that are not enabled will have null entries.
110197883Sgibbs	 * As an initiator, we keep one target entry for our initiator
110297883Sgibbs	 * ID to store our sync/wide transfer settings.
110397883Sgibbs	 */
110497883Sgibbs	struct ahd_tmode_tstate  *enabled_targets[AHD_NUM_TARGETS];
110597883Sgibbs
110697883Sgibbs	/*
110797883Sgibbs	 * The black hole device responsible for handling requests for
110897883Sgibbs	 * disabled luns on enabled targets.
110997883Sgibbs	 */
111097883Sgibbs	struct ahd_tmode_lstate  *black_hole;
111197883Sgibbs
111297883Sgibbs	/*
111397883Sgibbs	 * Device instance currently on the bus awaiting a continue TIO
111497883Sgibbs	 * for a command that was not given the disconnect priveledge.
111597883Sgibbs	 */
111697883Sgibbs	struct ahd_tmode_lstate  *pending_device;
111797883Sgibbs
111897883Sgibbs	/*
111997883Sgibbs	 * Timer handles for timer driven callbacks.
112097883Sgibbs	 */
112197883Sgibbs	ahd_timer_t		  reset_timer;
1122109588Sgibbs	ahd_timer_t		  stat_timer;
112397883Sgibbs
112497883Sgibbs	/*
1125109588Sgibbs	 * Statistics.
1126109588Sgibbs	 */
1127109588Sgibbs#define	AHD_STAT_UPDATE_US	250000 /* 250ms */
1128109588Sgibbs#define	AHD_STAT_BUCKETS	4
1129109588Sgibbs	u_int			  cmdcmplt_bucket;
1130109588Sgibbs	uint32_t		  cmdcmplt_counts[AHD_STAT_BUCKETS];
1131109588Sgibbs	uint32_t		  cmdcmplt_total;
1132109588Sgibbs
1133109588Sgibbs	/*
113497883Sgibbs	 * Card characteristics
113597883Sgibbs	 */
113697883Sgibbs	ahd_chip		  chip;
113797883Sgibbs	ahd_feature		  features;
113897883Sgibbs	ahd_bug			  bugs;
113997883Sgibbs	ahd_flag		  flags;
114097883Sgibbs	struct seeprom_config	 *seep_config;
114197883Sgibbs
114297883Sgibbs	/* Values to store in the SEQCTL register for pause and unpause */
114397883Sgibbs	uint8_t			  unpause;
114497883Sgibbs	uint8_t			  pause;
114597883Sgibbs
114697883Sgibbs	/* Command Queues */
114797883Sgibbs	uint16_t		  qoutfifonext;
1148102680Sgibbs	uint16_t		  qoutfifonext_valid_tag;
114997883Sgibbs	uint16_t		  qinfifonext;
115097883Sgibbs	uint16_t		  qinfifo[AHD_SCB_MAX];
115197883Sgibbs	uint16_t		 *qoutfifo;
115297883Sgibbs
115397883Sgibbs	/* Critical Section Data */
115497883Sgibbs	struct cs		 *critical_sections;
115597883Sgibbs	u_int			  num_critical_sections;
115697883Sgibbs
115797883Sgibbs	/* Buffer for handling packetized bitbucket. */
115897883Sgibbs	uint8_t			 *overrun_buf;
115997883Sgibbs
116097883Sgibbs	/* Links for chaining softcs */
116197883Sgibbs	TAILQ_ENTRY(ahd_softc)	  links;
116297883Sgibbs
116397883Sgibbs	/* Channel Names ('A', 'B', etc.) */
116497883Sgibbs	char			  channel;
116597883Sgibbs
116697883Sgibbs	/* Initiator Bus ID */
116797883Sgibbs	uint8_t			  our_id;
116897883Sgibbs
116997883Sgibbs	/*
117097883Sgibbs	 * Target incoming command FIFO.
117197883Sgibbs	 */
117297883Sgibbs	struct target_cmd	 *targetcmds;
117397883Sgibbs	uint8_t			  tqinfifonext;
117497883Sgibbs
117597883Sgibbs	/*
1176109588Sgibbs	 * Cached verson of the hs_mailbox so we can avoid
1177109588Sgibbs	 * pausing the sequencer during mailbox updates.
1178109588Sgibbs	 */
1179109588Sgibbs	uint8_t			  hs_mailbox;
1180109588Sgibbs
1181109588Sgibbs	/*
118297883Sgibbs	 * Incoming and outgoing message handling.
118397883Sgibbs	 */
118497883Sgibbs	uint8_t			  send_msg_perror;
118597883Sgibbs	ahd_msg_flags		  msg_flags;
118697883Sgibbs	ahd_msg_type		  msg_type;
118797883Sgibbs	uint8_t			  msgout_buf[12];/* Message we are sending */
118897883Sgibbs	uint8_t			  msgin_buf[12];/* Message we are receiving */
118997883Sgibbs	u_int			  msgout_len;	/* Length of message to send */
119097883Sgibbs	u_int			  msgout_index;	/* Current index in msgout */
119197883Sgibbs	u_int			  msgin_index;	/* Current index in msgin */
119297883Sgibbs
119397883Sgibbs	/*
119497883Sgibbs	 * Mapping information for data structures shared
119597883Sgibbs	 * between the sequencer and kernel.
119697883Sgibbs	 */
119797883Sgibbs	bus_dma_tag_t		  parent_dmat;
119897883Sgibbs	bus_dma_tag_t		  shared_data_dmat;
119997883Sgibbs	bus_dmamap_t		  shared_data_dmamap;
120097883Sgibbs	bus_addr_t		  shared_data_busaddr;
120197883Sgibbs
120297883Sgibbs	/* Information saved through suspend/resume cycles */
120397883Sgibbs	struct ahd_suspend_state  suspend_state;
120497883Sgibbs
120597883Sgibbs	/* Number of enabled target mode device on this card */
120697883Sgibbs	u_int			  enabled_luns;
120797883Sgibbs
120897883Sgibbs	/* Initialization level of this data structure */
120997883Sgibbs	u_int			  init_level;
121097883Sgibbs
121197883Sgibbs	/* PCI cacheline size. */
121297883Sgibbs	u_int			  pci_cachesize;
121397883Sgibbs
1214107441Sscottl	/* IO Cell Parameters */
1215107441Sscottl	uint8_t			  iocell_opts[AHD_NUM_PER_DEV_ANNEXCOLS];
1216107441Sscottl
1217107441Sscottl	u_int			  stack_size;
1218107441Sscottl	uint16_t		 *saved_stack;
1219107441Sscottl
122097883Sgibbs	/* Per-Unit descriptive information */
122197883Sgibbs	const char		 *description;
122297883Sgibbs	const char		 *bus_description;
122397883Sgibbs	char			 *name;
122497883Sgibbs	int			  unit;
122597883Sgibbs
122697883Sgibbs	/* Selection Timer settings */
122797883Sgibbs	int			  seltime;
122897883Sgibbs
1229109588Sgibbs	/*
1230115329Sgibbs	 * Interrupt coalescing settings.
1231109588Sgibbs	 */
1232115329Sgibbs#define	AHD_INT_COALESCING_TIMER_DEFAULT		250 /*us*/
1233115329Sgibbs#define	AHD_INT_COALESCING_MAXCMDS_DEFAULT		10
1234115329Sgibbs#define	AHD_INT_COALESCING_MAXCMDS_MAX			127
1235115329Sgibbs#define	AHD_INT_COALESCING_MINCMDS_DEFAULT		5
1236115329Sgibbs#define	AHD_INT_COALESCING_MINCMDS_MAX			127
1237115329Sgibbs#define	AHD_INT_COALESCING_THRESHOLD_DEFAULT		2000
1238115329Sgibbs#define	AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT	1000
1239115329Sgibbs	u_int			  int_coalescing_timer;
1240115329Sgibbs	u_int			  int_coalescing_maxcmds;
1241115329Sgibbs	u_int			  int_coalescing_mincmds;
1242115329Sgibbs	u_int			  int_coalescing_threshold;
1243115329Sgibbs	u_int			  int_coalescing_stop_threshold;
1244109588Sgibbs
124597883Sgibbs	uint16_t	 	  user_discenable;/* Disconnection allowed  */
124697883Sgibbs	uint16_t		  user_tagenable;/* Tagged Queuing allowed */
124797883Sgibbs};
124897883Sgibbs
124997883SgibbsTAILQ_HEAD(ahd_softc_tailq, ahd_softc);
125097883Sgibbsextern struct ahd_softc_tailq ahd_tailq;
125197883Sgibbs
1252107441Sscottl/*************************** IO Cell Configuration ****************************/
1253107441Sscottl#define	AHD_PRECOMP_SLEW_INDEX						\
1254107441Sscottl    (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0)
1255107441Sscottl
1256107441Sscottl#define	AHD_AMPLITUDE_INDEX						\
1257107441Sscottl    (AHD_ANNEXCOL_AMPLITUDE - AHD_ANNEXCOL_PER_DEV0)
1258107441Sscottl
1259107441Sscottl#define AHD_SET_SLEWRATE(ahd, new_slew)					\
1260107441Sscottldo {									\
1261107441Sscottl    (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_SLEWRATE_MASK;	\
1262107441Sscottl    (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |=			\
1263107441Sscottl	(((new_slew) << AHD_SLEWRATE_SHIFT) & AHD_SLEWRATE_MASK);	\
1264107441Sscottl} while (0)
1265107441Sscottl
1266107441Sscottl#define AHD_SET_PRECOMP(ahd, new_pcomp)					\
1267107441Sscottldo {									\
1268107441Sscottl    (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK;	\
1269107441Sscottl    (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |=			\
1270107441Sscottl	(((new_pcomp) << AHD_PRECOMP_SHIFT) & AHD_PRECOMP_MASK);	\
1271107441Sscottl} while (0)
1272107441Sscottl
1273107441Sscottl#define AHD_SET_AMPLITUDE(ahd, new_amp)					\
1274107441Sscottldo {									\
1275107441Sscottl    (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] &= ~AHD_AMPLITUDE_MASK;	\
1276107441Sscottl    (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] |=				\
1277107441Sscottl	(((new_amp) << AHD_AMPLITUDE_SHIFT) & AHD_AMPLITUDE_MASK);	\
1278107441Sscottl} while (0)
1279107441Sscottl
128097883Sgibbs/************************ Active Device Information ***************************/
128197883Sgibbstypedef enum {
128297883Sgibbs	ROLE_UNKNOWN,
128397883Sgibbs	ROLE_INITIATOR,
128497883Sgibbs	ROLE_TARGET
128597883Sgibbs} role_t;
128697883Sgibbs
128797883Sgibbsstruct ahd_devinfo {
128897883Sgibbs	int	 our_scsiid;
128997883Sgibbs	int	 target_offset;
129097883Sgibbs	uint16_t target_mask;
129197883Sgibbs	u_int	 target;
129297883Sgibbs	u_int	 lun;
129397883Sgibbs	char	 channel;
129497883Sgibbs	role_t	 role;		/*
129597883Sgibbs				 * Only guaranteed to be correct if not
129697883Sgibbs				 * in the busfree state.
129797883Sgibbs				 */
129897883Sgibbs};
129997883Sgibbs
130097883Sgibbs/****************************** PCI Structures ********************************/
130197883Sgibbs#define AHD_PCI_IOADDR0	PCIR_MAPS	/* I/O BAR*/
130297883Sgibbs#define AHD_PCI_MEMADDR	(PCIR_MAPS + 4)	/* Memory BAR */
130397883Sgibbs#define AHD_PCI_IOADDR1	(PCIR_MAPS + 12)/* Second I/O BAR */
130497883Sgibbs
130597883Sgibbstypedef int (ahd_device_setup_t)(struct ahd_softc *);
130697883Sgibbs
130797883Sgibbsstruct ahd_pci_identity {
130897883Sgibbs	uint64_t		 full_id;
130997883Sgibbs	uint64_t		 id_mask;
131097883Sgibbs	char			*name;
131197883Sgibbs	ahd_device_setup_t	*setup;
131297883Sgibbs};
131397883Sgibbsextern struct ahd_pci_identity ahd_pci_ident_table [];
131497883Sgibbsextern const u_int ahd_num_pci_devs;
131597883Sgibbs
131697883Sgibbs/***************************** VL/EISA Declarations ***************************/
131797883Sgibbsstruct aic7770_identity {
131897883Sgibbs	uint32_t		 full_id;
131997883Sgibbs	uint32_t		 id_mask;
132097883Sgibbs	char			*name;
132197883Sgibbs	ahd_device_setup_t	*setup;
132297883Sgibbs};
132397883Sgibbsextern struct aic7770_identity aic7770_ident_table [];
132497883Sgibbsextern const int ahd_num_aic7770_devs;
132597883Sgibbs
132697883Sgibbs#define AHD_EISA_SLOT_OFFSET	0xc00
132797883Sgibbs#define AHD_EISA_IOSIZE		0x100
132897883Sgibbs
132997883Sgibbs/*************************** Function Declarations ****************************/
133097883Sgibbs/******************************************************************************/
1331109588Sgibbsvoid			ahd_reset_cmds_pending(struct ahd_softc *ahd);
133297883Sgibbsu_int			ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl);
133397883Sgibbsvoid			ahd_busy_tcl(struct ahd_softc *ahd,
133497883Sgibbs				     u_int tcl, u_int busyid);
133597883Sgibbsstatic __inline void	ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl);
133697883Sgibbsstatic __inline void
133797883Sgibbsahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
133897883Sgibbs{
133997883Sgibbs	ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
134097883Sgibbs}
134197883Sgibbs
134297883Sgibbs/***************************** PCI Front End *********************************/
1343107441Sscottlstruct	ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
1344107441Sscottlint			  ahd_pci_config(struct ahd_softc *,
1345107441Sscottl					 struct ahd_pci_identity *);
1346107441Sscottlint	ahd_pci_test_register_access(struct ahd_softc *);
134797883Sgibbs
134897883Sgibbs/************************** SCB and SCB queue management **********************/
134997883Sgibbsint		ahd_probe_scbs(struct ahd_softc *);
135097883Sgibbsvoid		ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
135197883Sgibbs					 struct scb *scb);
135297883Sgibbsint		ahd_match_scb(struct ahd_softc *ahd, struct scb *scb,
135397883Sgibbs			      int target, char channel, int lun,
135497883Sgibbs			      u_int tag, role_t role);
135597883Sgibbs
135697883Sgibbs/****************************** Initialization ********************************/
135797883Sgibbsstruct ahd_softc	*ahd_alloc(void *platform_arg, char *name);
135897883Sgibbsint			 ahd_softc_init(struct ahd_softc *);
135997883Sgibbsvoid			 ahd_controller_info(struct ahd_softc *ahd, char *buf);
136097883Sgibbsint			 ahd_init(struct ahd_softc *ahd);
136197883Sgibbsint			 ahd_default_config(struct ahd_softc *ahd);
1362114623Sgibbsint			 ahd_parse_vpddata(struct ahd_softc *ahd,
1363114623Sgibbs					   struct vpd_config *vpd);
136497883Sgibbsint			 ahd_parse_cfgdata(struct ahd_softc *ahd,
136597883Sgibbs					   struct seeprom_config *sc);
136697883Sgibbsvoid			 ahd_intr_enable(struct ahd_softc *ahd, int enable);
1367115329Sgibbsvoid			 ahd_update_coalescing_values(struct ahd_softc *ahd,
1368109588Sgibbs						      u_int timer,
1369109588Sgibbs						      u_int maxcmds,
1370109588Sgibbs						      u_int mincmds);
1371115329Sgibbsvoid			 ahd_enable_coalescing(struct ahd_softc *ahd,
1372109588Sgibbs					       int enable);
137397883Sgibbsvoid			 ahd_pause_and_flushwork(struct ahd_softc *ahd);
137497883Sgibbsint			 ahd_suspend(struct ahd_softc *ahd);
137597883Sgibbsint			 ahd_resume(struct ahd_softc *ahd);
137697883Sgibbsvoid			 ahd_softc_insert(struct ahd_softc *);
137797883Sgibbsstruct ahd_softc	*ahd_find_softc(struct ahd_softc *ahd);
137897883Sgibbsvoid			 ahd_set_unit(struct ahd_softc *, int);
137997883Sgibbsvoid			 ahd_set_name(struct ahd_softc *, char *);
1380102680Sgibbsstruct scb		*ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
1381102680Sgibbsvoid			 ahd_free_scb(struct ahd_softc *ahd, struct scb *scb);
138297883Sgibbsvoid			 ahd_alloc_scbs(struct ahd_softc *ahd);
138397883Sgibbsvoid			 ahd_free(struct ahd_softc *ahd);
1384115917Sgibbsint			 ahd_reset(struct ahd_softc *ahd, int reinit);
138597883Sgibbsvoid			 ahd_shutdown(void *arg);
1386115917Sgibbsint			 ahd_write_flexport(struct ahd_softc *ahd,
1387115917Sgibbs					    u_int addr, u_int value);
1388115917Sgibbsint			 ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
1389115917Sgibbs					   uint8_t *value);
1390115917Sgibbsint			 ahd_wait_flexport(struct ahd_softc *ahd);
139197883Sgibbs
139297883Sgibbs/*************************** Interrupt Services *******************************/
139397883Sgibbsvoid			ahd_pci_intr(struct ahd_softc *ahd);
139497883Sgibbsvoid			ahd_clear_intstat(struct ahd_softc *ahd);
1395109588Sgibbsvoid			ahd_flush_qoutfifo(struct ahd_softc *ahd);
139697883Sgibbsvoid			ahd_run_qoutfifo(struct ahd_softc *ahd);
139797883Sgibbs#ifdef AHD_TARGET_MODE
139897883Sgibbsvoid			ahd_run_tqinfifo(struct ahd_softc *ahd, int paused);
139997883Sgibbs#endif
140097883Sgibbsvoid			ahd_handle_hwerrint(struct ahd_softc *ahd);
140197883Sgibbsvoid			ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat);
140297883Sgibbsvoid			ahd_handle_scsiint(struct ahd_softc *ahd,
140397883Sgibbs					   u_int intstat);
140497883Sgibbsvoid			ahd_clear_critical_section(struct ahd_softc *ahd);
140597883Sgibbs
140697883Sgibbs/***************************** Error Recovery *********************************/
140797883Sgibbstypedef enum {
140897883Sgibbs	SEARCH_COMPLETE,
140997883Sgibbs	SEARCH_COUNT,
141097883Sgibbs	SEARCH_REMOVE,
141197883Sgibbs	SEARCH_PRINT
141297883Sgibbs} ahd_search_action;
141397883Sgibbsint			ahd_search_qinfifo(struct ahd_softc *ahd, int target,
141497883Sgibbs					   char channel, int lun, u_int tag,
141597883Sgibbs					   role_t role, uint32_t status,
141697883Sgibbs					   ahd_search_action action);
141797883Sgibbsint			ahd_search_disc_list(struct ahd_softc *ahd, int target,
141897883Sgibbs					     char channel, int lun, u_int tag,
141997883Sgibbs					     int stop_on_first, int remove,
142097883Sgibbs					     int save_state);
142197883Sgibbsvoid			ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
142297883Sgibbsint			ahd_reset_channel(struct ahd_softc *ahd, char channel,
142397883Sgibbs					  int initiate_reset);
142497883Sgibbsint			ahd_abort_scbs(struct ahd_softc *ahd, int target,
142597883Sgibbs				       char channel, int lun, u_int tag,
142697883Sgibbs				       role_t role, uint32_t status);
142797883Sgibbsvoid			ahd_restart(struct ahd_softc *ahd);
142897883Sgibbsvoid			ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo);
142997883Sgibbsvoid			ahd_handle_scb_status(struct ahd_softc *ahd,
143097883Sgibbs					      struct scb *scb);
143197883Sgibbsvoid			ahd_handle_scsi_status(struct ahd_softc *ahd,
143297883Sgibbs					       struct scb *scb);
143397883Sgibbsvoid			ahd_calc_residual(struct ahd_softc *ahd,
143497883Sgibbs					  struct scb *scb);
143597883Sgibbs/*************************** Utility Functions ********************************/
143697883Sgibbsstruct ahd_phase_table_entry*
143797883Sgibbs			ahd_lookup_phase_entry(int phase);
143897883Sgibbsvoid			ahd_compile_devinfo(struct ahd_devinfo *devinfo,
143997883Sgibbs					    u_int our_id, u_int target,
144097883Sgibbs					    u_int lun, char channel,
144197883Sgibbs					    role_t role);
144297883Sgibbs/************************** Transfer Negotiation ******************************/
144397883Sgibbsvoid			ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
144497883Sgibbs					  u_int *ppr_options, u_int maxsync);
144597883Sgibbsvoid			ahd_validate_offset(struct ahd_softc *ahd,
144697883Sgibbs					    struct ahd_initiator_tinfo *tinfo,
144797883Sgibbs					    u_int period, u_int *offset,
144897883Sgibbs					    int wide, role_t role);
144997883Sgibbsvoid			ahd_validate_width(struct ahd_softc *ahd,
145097883Sgibbs					   struct ahd_initiator_tinfo *tinfo,
145197883Sgibbs					   u_int *bus_width,
145297883Sgibbs					   role_t role);
1453107441Sscottl/*
1454107441Sscottl * Negotiation types.  These are used to qualify if we should renegotiate
1455107441Sscottl * even if our goal and current transport parameters are identical.
1456107441Sscottl */
1457107441Sscottltypedef enum {
1458107441Sscottl	AHD_NEG_TO_GOAL,	/* Renegotiate only if goal and curr differ. */
1459107441Sscottl	AHD_NEG_IF_NON_ASYNC,	/* Renegotiate so long as goal is non-async. */
1460107441Sscottl	AHD_NEG_ALWAYS		/* Renegotiat even if goal is async. */
1461107441Sscottl} ahd_neg_type;
146297883Sgibbsint			ahd_update_neg_request(struct ahd_softc*,
146397883Sgibbs					       struct ahd_devinfo*,
146497883Sgibbs					       struct ahd_tmode_tstate*,
146597883Sgibbs					       struct ahd_initiator_tinfo*,
1466107441Sscottl					       ahd_neg_type);
146797883Sgibbsvoid			ahd_set_width(struct ahd_softc *ahd,
146897883Sgibbs				      struct ahd_devinfo *devinfo,
146997883Sgibbs				      u_int width, u_int type, int paused);
147097883Sgibbsvoid			ahd_set_syncrate(struct ahd_softc *ahd,
147197883Sgibbs					 struct ahd_devinfo *devinfo,
147297883Sgibbs					 u_int period, u_int offset,
147397883Sgibbs					 u_int ppr_options,
147497883Sgibbs					 u_int type, int paused);
147597883Sgibbstypedef enum {
147697883Sgibbs	AHD_QUEUE_NONE,
147797883Sgibbs	AHD_QUEUE_BASIC,
147897883Sgibbs	AHD_QUEUE_TAGGED
147997883Sgibbs} ahd_queue_alg;
148097883Sgibbs
148197883Sgibbsvoid			ahd_set_tags(struct ahd_softc *ahd,
148297883Sgibbs				     struct ahd_devinfo *devinfo,
148397883Sgibbs				     ahd_queue_alg alg);
148497883Sgibbs
148597883Sgibbs/**************************** Target Mode *************************************/
148697883Sgibbs#ifdef AHD_TARGET_MODE
148797883Sgibbsvoid		ahd_send_lstate_events(struct ahd_softc *,
148897883Sgibbs				       struct ahd_tmode_lstate *);
148997883Sgibbsvoid		ahd_handle_en_lun(struct ahd_softc *ahd,
149097883Sgibbs				  struct cam_sim *sim, union ccb *ccb);
149197883Sgibbscam_status	ahd_find_tmode_devs(struct ahd_softc *ahd,
149297883Sgibbs				    struct cam_sim *sim, union ccb *ccb,
149397883Sgibbs				    struct ahd_tmode_tstate **tstate,
149497883Sgibbs				    struct ahd_tmode_lstate **lstate,
149597883Sgibbs				    int notfound_failure);
149697883Sgibbs#ifndef AHD_TMODE_ENABLE
149797883Sgibbs#define AHD_TMODE_ENABLE 0
149897883Sgibbs#endif
149997883Sgibbs#endif
150097883Sgibbs/******************************* Debug ***************************************/
150197883Sgibbs#ifdef AHD_DEBUG
150297883Sgibbsextern uint32_t ahd_debug;
1503107441Sscottl#define AHD_SHOW_MISC		0x00001
1504107441Sscottl#define AHD_SHOW_SENSE		0x00002
1505107441Sscottl#define AHD_SHOW_RECOVERY	0x00004
1506107441Sscottl#define AHD_DUMP_SEEPROM	0x00008
1507107441Sscottl#define AHD_SHOW_TERMCTL	0x00010
1508107441Sscottl#define AHD_SHOW_MEMORY		0x00020
1509107441Sscottl#define AHD_SHOW_MESSAGES	0x00040
1510107441Sscottl#define AHD_SHOW_MODEPTR	0x00080
1511107441Sscottl#define AHD_SHOW_SELTO		0x00100
1512107441Sscottl#define AHD_SHOW_FIFOS		0x00200
1513107441Sscottl#define AHD_SHOW_QFULL		0x00400
1514107441Sscottl#define	AHD_SHOW_DV		0x00800
1515107441Sscottl#define AHD_SHOW_MASKED_ERRORS	0x01000
1516107441Sscottl#define AHD_SHOW_QUEUE		0x02000
1517107441Sscottl#define AHD_SHOW_TQIN		0x04000
1518107441Sscottl#define AHD_SHOW_SG		0x08000
1519115329Sgibbs#define AHD_SHOW_INT_COALESCING	0x10000
1520109588Sgibbs#define AHD_DEBUG_SEQUENCER	0x20000
152197883Sgibbs#endif
152297883Sgibbsvoid			ahd_print_scb(struct scb *scb);
1523107441Sscottlvoid			ahd_print_devinfo(struct ahd_softc *ahd,
1524107441Sscottl					  struct ahd_devinfo *devinfo);
152597883Sgibbsvoid			ahd_dump_sglist(struct scb *scb);
152697883Sgibbsvoid			ahd_dump_all_cards_state(void);
152797883Sgibbsvoid			ahd_dump_card_state(struct ahd_softc *ahd);
1528102680Sgibbsint			ahd_print_register(ahd_reg_parse_entry_t *table,
1529102680Sgibbs					   u_int num_entries,
1530102680Sgibbs					   const char *name,
1531102680Sgibbs					   u_int address,
1532102680Sgibbs					   u_int value,
1533102680Sgibbs					   u_int *cur_column,
1534102680Sgibbs					   u_int wrap_point);
153597883Sgibbsvoid			ahd_dump_scbs(struct ahd_softc *ahd);
153697883Sgibbs#endif /* _AIC79XX_H_ */
1537