18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
48c2ecf20Sopenharmony_ci * of PCI-SCSI IO processors.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 1999-2001  Gerard Roudier <groudier@free.fr>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * This driver is derived from the Linux sym53c8xx driver.
98c2ecf20Sopenharmony_ci * Copyright (C) 1998-2000  Gerard Roudier
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * The sym53c8xx driver is derived from the ncr53c8xx driver that had been
128c2ecf20Sopenharmony_ci * a port of the FreeBSD ncr driver to Linux-1.2.13.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * The original ncr driver has been written for 386bsd and FreeBSD by
158c2ecf20Sopenharmony_ci *         Wolfgang Stanglmeier        <wolf@cologne.de>
168c2ecf20Sopenharmony_ci *         Stefan Esser                <se@mi.Uni-Koeln.de>
178c2ecf20Sopenharmony_ci * Copyright (C) 1994  Wolfgang Stanglmeier
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * Other major contributions:
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * NVRAM detection and reading.
228c2ecf20Sopenharmony_ci * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci *-----------------------------------------------------------------------------
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include <linux/gfp.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#ifndef SYM_HIPD_H
308c2ecf20Sopenharmony_ci#define SYM_HIPD_H
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/*
338c2ecf20Sopenharmony_ci *  Generic driver options.
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci *  They may be defined in platform specific headers, if they
368c2ecf20Sopenharmony_ci *  are useful.
378c2ecf20Sopenharmony_ci *
388c2ecf20Sopenharmony_ci *    SYM_OPT_HANDLE_DEVICE_QUEUEING
398c2ecf20Sopenharmony_ci *        When this option is set, the driver will use a queue per
408c2ecf20Sopenharmony_ci *        device and handle QUEUE FULL status requeuing internally.
418c2ecf20Sopenharmony_ci *
428c2ecf20Sopenharmony_ci *    SYM_OPT_LIMIT_COMMAND_REORDERING
438c2ecf20Sopenharmony_ci *        When this option is set, the driver tries to limit tagged
448c2ecf20Sopenharmony_ci *        command reordering to some reasonable value.
458c2ecf20Sopenharmony_ci *        (set for Linux)
468c2ecf20Sopenharmony_ci */
478c2ecf20Sopenharmony_ci#if 0
488c2ecf20Sopenharmony_ci#define SYM_OPT_HANDLE_DEVICE_QUEUEING
498c2ecf20Sopenharmony_ci#define SYM_OPT_LIMIT_COMMAND_REORDERING
508c2ecf20Sopenharmony_ci#endif
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/*
538c2ecf20Sopenharmony_ci *  Active debugging tags and verbosity.
548c2ecf20Sopenharmony_ci *  Both DEBUG_FLAGS and sym_verbose can be redefined
558c2ecf20Sopenharmony_ci *  by the platform specific code to something else.
568c2ecf20Sopenharmony_ci */
578c2ecf20Sopenharmony_ci#define DEBUG_ALLOC	(0x0001)
588c2ecf20Sopenharmony_ci#define DEBUG_PHASE	(0x0002)
598c2ecf20Sopenharmony_ci#define DEBUG_POLL	(0x0004)
608c2ecf20Sopenharmony_ci#define DEBUG_QUEUE	(0x0008)
618c2ecf20Sopenharmony_ci#define DEBUG_RESULT	(0x0010)
628c2ecf20Sopenharmony_ci#define DEBUG_SCATTER	(0x0020)
638c2ecf20Sopenharmony_ci#define DEBUG_SCRIPT	(0x0040)
648c2ecf20Sopenharmony_ci#define DEBUG_TINY	(0x0080)
658c2ecf20Sopenharmony_ci#define DEBUG_TIMING	(0x0100)
668c2ecf20Sopenharmony_ci#define DEBUG_NEGO	(0x0200)
678c2ecf20Sopenharmony_ci#define DEBUG_TAGS	(0x0400)
688c2ecf20Sopenharmony_ci#define DEBUG_POINTER	(0x0800)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#ifndef DEBUG_FLAGS
718c2ecf20Sopenharmony_ci#define DEBUG_FLAGS	(0x0000)
728c2ecf20Sopenharmony_ci#endif
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#ifndef sym_verbose
758c2ecf20Sopenharmony_ci#define sym_verbose	(np->verbose)
768c2ecf20Sopenharmony_ci#endif
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/*
798c2ecf20Sopenharmony_ci *  These ones should have been already defined.
808c2ecf20Sopenharmony_ci */
818c2ecf20Sopenharmony_ci#ifndef assert
828c2ecf20Sopenharmony_ci#define	assert(expression) { \
838c2ecf20Sopenharmony_ci	if (!(expression)) { \
848c2ecf20Sopenharmony_ci		(void)panic( \
858c2ecf20Sopenharmony_ci			"assertion \"%s\" failed: file \"%s\", line %d\n", \
868c2ecf20Sopenharmony_ci			#expression, \
878c2ecf20Sopenharmony_ci			__FILE__, __LINE__); \
888c2ecf20Sopenharmony_ci	} \
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci#endif
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/*
938c2ecf20Sopenharmony_ci *  Number of tasks per device we want to handle.
948c2ecf20Sopenharmony_ci */
958c2ecf20Sopenharmony_ci#if	SYM_CONF_MAX_TAG_ORDER > 8
968c2ecf20Sopenharmony_ci#error	"more than 256 tags per logical unit not allowed."
978c2ecf20Sopenharmony_ci#endif
988c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_TASK	(1<<SYM_CONF_MAX_TAG_ORDER)
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci/*
1018c2ecf20Sopenharmony_ci *  Donnot use more tasks that we can handle.
1028c2ecf20Sopenharmony_ci */
1038c2ecf20Sopenharmony_ci#ifndef	SYM_CONF_MAX_TAG
1048c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_TAG	SYM_CONF_MAX_TASK
1058c2ecf20Sopenharmony_ci#endif
1068c2ecf20Sopenharmony_ci#if	SYM_CONF_MAX_TAG > SYM_CONF_MAX_TASK
1078c2ecf20Sopenharmony_ci#undef	SYM_CONF_MAX_TAG
1088c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_TAG	SYM_CONF_MAX_TASK
1098c2ecf20Sopenharmony_ci#endif
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci/*
1128c2ecf20Sopenharmony_ci *    This one means 'NO TAG for this job'
1138c2ecf20Sopenharmony_ci */
1148c2ecf20Sopenharmony_ci#define NO_TAG	(256)
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/*
1178c2ecf20Sopenharmony_ci *  Number of SCSI targets.
1188c2ecf20Sopenharmony_ci */
1198c2ecf20Sopenharmony_ci#if	SYM_CONF_MAX_TARGET > 16
1208c2ecf20Sopenharmony_ci#error	"more than 16 targets not allowed."
1218c2ecf20Sopenharmony_ci#endif
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/*
1248c2ecf20Sopenharmony_ci *  Number of logical units per target.
1258c2ecf20Sopenharmony_ci */
1268c2ecf20Sopenharmony_ci#if	SYM_CONF_MAX_LUN > 64
1278c2ecf20Sopenharmony_ci#error	"more than 64 logical units per target not allowed."
1288c2ecf20Sopenharmony_ci#endif
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci/*
1318c2ecf20Sopenharmony_ci *    Asynchronous pre-scaler (ns). Shall be 40 for
1328c2ecf20Sopenharmony_ci *    the SCSI timings to be compliant.
1338c2ecf20Sopenharmony_ci */
1348c2ecf20Sopenharmony_ci#define	SYM_CONF_MIN_ASYNC (40)
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci/*
1388c2ecf20Sopenharmony_ci * MEMORY ALLOCATOR.
1398c2ecf20Sopenharmony_ci */
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci#define SYM_MEM_WARN	1	/* Warn on failed operations */
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci#define SYM_MEM_PAGE_ORDER 0	/* 1 PAGE  maximum */
1448c2ecf20Sopenharmony_ci#define SYM_MEM_CLUSTER_SHIFT	(PAGE_SHIFT+SYM_MEM_PAGE_ORDER)
1458c2ecf20Sopenharmony_ci#define SYM_MEM_FREE_UNUSED	/* Free unused pages immediately */
1468c2ecf20Sopenharmony_ci/*
1478c2ecf20Sopenharmony_ci *  Shortest memory chunk is (1<<SYM_MEM_SHIFT), currently 16.
1488c2ecf20Sopenharmony_ci *  Actual allocations happen as SYM_MEM_CLUSTER_SIZE sized.
1498c2ecf20Sopenharmony_ci *  (1 PAGE at a time is just fine).
1508c2ecf20Sopenharmony_ci */
1518c2ecf20Sopenharmony_ci#define SYM_MEM_SHIFT	4
1528c2ecf20Sopenharmony_ci#define SYM_MEM_CLUSTER_SIZE	(1UL << SYM_MEM_CLUSTER_SHIFT)
1538c2ecf20Sopenharmony_ci#define SYM_MEM_CLUSTER_MASK	(SYM_MEM_CLUSTER_SIZE-1)
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci/*
1568c2ecf20Sopenharmony_ci *  Number of entries in the START and DONE queues.
1578c2ecf20Sopenharmony_ci *
1588c2ecf20Sopenharmony_ci *  We limit to 1 PAGE in order to succeed allocation of
1598c2ecf20Sopenharmony_ci *  these queues. Each entry is 8 bytes long (2 DWORDS).
1608c2ecf20Sopenharmony_ci */
1618c2ecf20Sopenharmony_ci#ifdef	SYM_CONF_MAX_START
1628c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_QUEUE (SYM_CONF_MAX_START+2)
1638c2ecf20Sopenharmony_ci#else
1648c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_QUEUE (7*SYM_CONF_MAX_TASK+2)
1658c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_START (SYM_CONF_MAX_QUEUE-2)
1668c2ecf20Sopenharmony_ci#endif
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci#if	SYM_CONF_MAX_QUEUE > SYM_MEM_CLUSTER_SIZE/8
1698c2ecf20Sopenharmony_ci#undef	SYM_CONF_MAX_QUEUE
1708c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_QUEUE (SYM_MEM_CLUSTER_SIZE/8)
1718c2ecf20Sopenharmony_ci#undef	SYM_CONF_MAX_START
1728c2ecf20Sopenharmony_ci#define	SYM_CONF_MAX_START (SYM_CONF_MAX_QUEUE-2)
1738c2ecf20Sopenharmony_ci#endif
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci/*
1768c2ecf20Sopenharmony_ci *  For this one, we want a short name :-)
1778c2ecf20Sopenharmony_ci */
1788c2ecf20Sopenharmony_ci#define MAX_QUEUE	SYM_CONF_MAX_QUEUE
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci/*
1818c2ecf20Sopenharmony_ci *  Common definitions for both bus space based and legacy IO methods.
1828c2ecf20Sopenharmony_ci */
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci#define INB_OFF(np, o)		ioread8(np->s.ioaddr + (o))
1858c2ecf20Sopenharmony_ci#define INW_OFF(np, o)		ioread16(np->s.ioaddr + (o))
1868c2ecf20Sopenharmony_ci#define INL_OFF(np, o)		ioread32(np->s.ioaddr + (o))
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci#define OUTB_OFF(np, o, val)	iowrite8((val), np->s.ioaddr + (o))
1898c2ecf20Sopenharmony_ci#define OUTW_OFF(np, o, val)	iowrite16((val), np->s.ioaddr + (o))
1908c2ecf20Sopenharmony_ci#define OUTL_OFF(np, o, val)	iowrite32((val), np->s.ioaddr + (o))
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci#define INB(np, r)		INB_OFF(np, offsetof(struct sym_reg, r))
1938c2ecf20Sopenharmony_ci#define INW(np, r)		INW_OFF(np, offsetof(struct sym_reg, r))
1948c2ecf20Sopenharmony_ci#define INL(np, r)		INL_OFF(np, offsetof(struct sym_reg, r))
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci#define OUTB(np, r, v)		OUTB_OFF(np, offsetof(struct sym_reg, r), (v))
1978c2ecf20Sopenharmony_ci#define OUTW(np, r, v)		OUTW_OFF(np, offsetof(struct sym_reg, r), (v))
1988c2ecf20Sopenharmony_ci#define OUTL(np, r, v)		OUTL_OFF(np, offsetof(struct sym_reg, r), (v))
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci#define OUTONB(np, r, m)	OUTB(np, r, INB(np, r) | (m))
2018c2ecf20Sopenharmony_ci#define OUTOFFB(np, r, m)	OUTB(np, r, INB(np, r) & ~(m))
2028c2ecf20Sopenharmony_ci#define OUTONW(np, r, m)	OUTW(np, r, INW(np, r) | (m))
2038c2ecf20Sopenharmony_ci#define OUTOFFW(np, r, m)	OUTW(np, r, INW(np, r) & ~(m))
2048c2ecf20Sopenharmony_ci#define OUTONL(np, r, m)	OUTL(np, r, INL(np, r) | (m))
2058c2ecf20Sopenharmony_ci#define OUTOFFL(np, r, m)	OUTL(np, r, INL(np, r) & ~(m))
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci/*
2088c2ecf20Sopenharmony_ci *  We normally want the chip to have a consistent view
2098c2ecf20Sopenharmony_ci *  of driver internal data structures when we restart it.
2108c2ecf20Sopenharmony_ci *  Thus these macros.
2118c2ecf20Sopenharmony_ci */
2128c2ecf20Sopenharmony_ci#define OUTL_DSP(np, v)				\
2138c2ecf20Sopenharmony_ci	do {					\
2148c2ecf20Sopenharmony_ci		MEMORY_WRITE_BARRIER();		\
2158c2ecf20Sopenharmony_ci		OUTL(np, nc_dsp, (v));		\
2168c2ecf20Sopenharmony_ci	} while (0)
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci#define OUTONB_STD()				\
2198c2ecf20Sopenharmony_ci	do {					\
2208c2ecf20Sopenharmony_ci		MEMORY_WRITE_BARRIER();		\
2218c2ecf20Sopenharmony_ci		OUTONB(np, nc_dcntl, (STD|NOCOM));	\
2228c2ecf20Sopenharmony_ci	} while (0)
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci/*
2258c2ecf20Sopenharmony_ci *  Command control block states.
2268c2ecf20Sopenharmony_ci */
2278c2ecf20Sopenharmony_ci#define HS_IDLE		(0)
2288c2ecf20Sopenharmony_ci#define HS_BUSY		(1)
2298c2ecf20Sopenharmony_ci#define HS_NEGOTIATE	(2)	/* sync/wide data transfer*/
2308c2ecf20Sopenharmony_ci#define HS_DISCONNECT	(3)	/* Disconnected by target */
2318c2ecf20Sopenharmony_ci#define HS_WAIT		(4)	/* waiting for resource	  */
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci#define HS_DONEMASK	(0x80)
2348c2ecf20Sopenharmony_ci#define HS_COMPLETE	(4|HS_DONEMASK)
2358c2ecf20Sopenharmony_ci#define HS_SEL_TIMEOUT	(5|HS_DONEMASK)	/* Selection timeout      */
2368c2ecf20Sopenharmony_ci#define HS_UNEXPECTED	(6|HS_DONEMASK)	/* Unexpected disconnect  */
2378c2ecf20Sopenharmony_ci#define HS_COMP_ERR	(7|HS_DONEMASK)	/* Completed with error	  */
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci/*
2408c2ecf20Sopenharmony_ci *  Software Interrupt Codes
2418c2ecf20Sopenharmony_ci */
2428c2ecf20Sopenharmony_ci#define	SIR_BAD_SCSI_STATUS	(1)
2438c2ecf20Sopenharmony_ci#define	SIR_SEL_ATN_NO_MSG_OUT	(2)
2448c2ecf20Sopenharmony_ci#define	SIR_MSG_RECEIVED	(3)
2458c2ecf20Sopenharmony_ci#define	SIR_MSG_WEIRD		(4)
2468c2ecf20Sopenharmony_ci#define	SIR_NEGO_FAILED		(5)
2478c2ecf20Sopenharmony_ci#define	SIR_NEGO_PROTO		(6)
2488c2ecf20Sopenharmony_ci#define	SIR_SCRIPT_STOPPED	(7)
2498c2ecf20Sopenharmony_ci#define	SIR_REJECT_TO_SEND	(8)
2508c2ecf20Sopenharmony_ci#define	SIR_SWIDE_OVERRUN	(9)
2518c2ecf20Sopenharmony_ci#define	SIR_SODL_UNDERRUN	(10)
2528c2ecf20Sopenharmony_ci#define	SIR_RESEL_NO_MSG_IN	(11)
2538c2ecf20Sopenharmony_ci#define	SIR_RESEL_NO_IDENTIFY	(12)
2548c2ecf20Sopenharmony_ci#define	SIR_RESEL_BAD_LUN	(13)
2558c2ecf20Sopenharmony_ci#define	SIR_TARGET_SELECTED	(14)
2568c2ecf20Sopenharmony_ci#define	SIR_RESEL_BAD_I_T_L	(15)
2578c2ecf20Sopenharmony_ci#define	SIR_RESEL_BAD_I_T_L_Q	(16)
2588c2ecf20Sopenharmony_ci#define	SIR_ABORT_SENT		(17)
2598c2ecf20Sopenharmony_ci#define	SIR_RESEL_ABORTED	(18)
2608c2ecf20Sopenharmony_ci#define	SIR_MSG_OUT_DONE	(19)
2618c2ecf20Sopenharmony_ci#define	SIR_COMPLETE_ERROR	(20)
2628c2ecf20Sopenharmony_ci#define	SIR_DATA_OVERRUN	(21)
2638c2ecf20Sopenharmony_ci#define	SIR_BAD_PHASE		(22)
2648c2ecf20Sopenharmony_ci#if	SYM_CONF_DMA_ADDRESSING_MODE == 2
2658c2ecf20Sopenharmony_ci#define	SIR_DMAP_DIRTY		(23)
2668c2ecf20Sopenharmony_ci#define	SIR_MAX			(23)
2678c2ecf20Sopenharmony_ci#else
2688c2ecf20Sopenharmony_ci#define	SIR_MAX			(22)
2698c2ecf20Sopenharmony_ci#endif
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci/*
2728c2ecf20Sopenharmony_ci *  Extended error bit codes.
2738c2ecf20Sopenharmony_ci *  xerr_status field of struct sym_ccb.
2748c2ecf20Sopenharmony_ci */
2758c2ecf20Sopenharmony_ci#define	XE_EXTRA_DATA	(1)	/* unexpected data phase	 */
2768c2ecf20Sopenharmony_ci#define	XE_BAD_PHASE	(1<<1)	/* illegal phase (4/5)		 */
2778c2ecf20Sopenharmony_ci#define	XE_PARITY_ERR	(1<<2)	/* unrecovered SCSI parity error */
2788c2ecf20Sopenharmony_ci#define	XE_SODL_UNRUN	(1<<3)	/* ODD transfer in DATA OUT phase */
2798c2ecf20Sopenharmony_ci#define	XE_SWIDE_OVRUN	(1<<4)	/* ODD transfer in DATA IN phase */
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci/*
2828c2ecf20Sopenharmony_ci *  Negotiation status.
2838c2ecf20Sopenharmony_ci *  nego_status field of struct sym_ccb.
2848c2ecf20Sopenharmony_ci */
2858c2ecf20Sopenharmony_ci#define NS_SYNC		(1)
2868c2ecf20Sopenharmony_ci#define NS_WIDE		(2)
2878c2ecf20Sopenharmony_ci#define NS_PPR		(3)
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci/*
2908c2ecf20Sopenharmony_ci *  A CCB hashed table is used to retrieve CCB address
2918c2ecf20Sopenharmony_ci *  from DSA value.
2928c2ecf20Sopenharmony_ci */
2938c2ecf20Sopenharmony_ci#define CCB_HASH_SHIFT		8
2948c2ecf20Sopenharmony_ci#define CCB_HASH_SIZE		(1UL << CCB_HASH_SHIFT)
2958c2ecf20Sopenharmony_ci#define CCB_HASH_MASK		(CCB_HASH_SIZE-1)
2968c2ecf20Sopenharmony_ci#if 1
2978c2ecf20Sopenharmony_ci#define CCB_HASH_CODE(dsa)	\
2988c2ecf20Sopenharmony_ci	(((dsa) >> (_LGRU16_(sizeof(struct sym_ccb)))) & CCB_HASH_MASK)
2998c2ecf20Sopenharmony_ci#else
3008c2ecf20Sopenharmony_ci#define CCB_HASH_CODE(dsa)	(((dsa) >> 9) & CCB_HASH_MASK)
3018c2ecf20Sopenharmony_ci#endif
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci#if	SYM_CONF_DMA_ADDRESSING_MODE == 2
3048c2ecf20Sopenharmony_ci/*
3058c2ecf20Sopenharmony_ci *  We may want to use segment registers for 64 bit DMA.
3068c2ecf20Sopenharmony_ci *  16 segments registers -> up to 64 GB addressable.
3078c2ecf20Sopenharmony_ci */
3088c2ecf20Sopenharmony_ci#define SYM_DMAP_SHIFT	(4)
3098c2ecf20Sopenharmony_ci#define SYM_DMAP_SIZE	(1u<<SYM_DMAP_SHIFT)
3108c2ecf20Sopenharmony_ci#define SYM_DMAP_MASK	(SYM_DMAP_SIZE-1)
3118c2ecf20Sopenharmony_ci#endif
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci/*
3148c2ecf20Sopenharmony_ci *  Device flags.
3158c2ecf20Sopenharmony_ci */
3168c2ecf20Sopenharmony_ci#define SYM_DISC_ENABLED	(1)
3178c2ecf20Sopenharmony_ci#define SYM_TAGS_ENABLED	(1<<1)
3188c2ecf20Sopenharmony_ci#define SYM_SCAN_BOOT_DISABLED	(1<<2)
3198c2ecf20Sopenharmony_ci#define SYM_SCAN_LUNS_DISABLED	(1<<3)
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci/*
3228c2ecf20Sopenharmony_ci *  Host adapter miscellaneous flags.
3238c2ecf20Sopenharmony_ci */
3248c2ecf20Sopenharmony_ci#define SYM_AVOID_BUS_RESET	(1)
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci/*
3278c2ecf20Sopenharmony_ci *  Misc.
3288c2ecf20Sopenharmony_ci */
3298c2ecf20Sopenharmony_ci#define SYM_SNOOP_TIMEOUT (10000000)
3308c2ecf20Sopenharmony_ci#define BUS_8_BIT	0
3318c2ecf20Sopenharmony_ci#define BUS_16_BIT	1
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci/*
3348c2ecf20Sopenharmony_ci *  Gather negotiable parameters value
3358c2ecf20Sopenharmony_ci */
3368c2ecf20Sopenharmony_cistruct sym_trans {
3378c2ecf20Sopenharmony_ci	u8 period;
3388c2ecf20Sopenharmony_ci	u8 offset;
3398c2ecf20Sopenharmony_ci	unsigned int width:1;
3408c2ecf20Sopenharmony_ci	unsigned int iu:1;
3418c2ecf20Sopenharmony_ci	unsigned int dt:1;
3428c2ecf20Sopenharmony_ci	unsigned int qas:1;
3438c2ecf20Sopenharmony_ci	unsigned int check_nego:1;
3448c2ecf20Sopenharmony_ci	unsigned int renego:2;
3458c2ecf20Sopenharmony_ci};
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci/*
3488c2ecf20Sopenharmony_ci *  Global TCB HEADER.
3498c2ecf20Sopenharmony_ci *
3508c2ecf20Sopenharmony_ci *  Due to lack of indirect addressing on earlier NCR chips,
3518c2ecf20Sopenharmony_ci *  this substructure is copied from the TCB to a global
3528c2ecf20Sopenharmony_ci *  address after selection.
3538c2ecf20Sopenharmony_ci *  For SYMBIOS chips that support LOAD/STORE this copy is
3548c2ecf20Sopenharmony_ci *  not needed and thus not performed.
3558c2ecf20Sopenharmony_ci */
3568c2ecf20Sopenharmony_cistruct sym_tcbh {
3578c2ecf20Sopenharmony_ci	/*
3588c2ecf20Sopenharmony_ci	 *  Scripts bus addresses of LUN table accessed from scripts.
3598c2ecf20Sopenharmony_ci	 *  LUN #0 is a special case, since multi-lun devices are rare,
3608c2ecf20Sopenharmony_ci	 *  and we we want to speed-up the general case and not waste
3618c2ecf20Sopenharmony_ci	 *  resources.
3628c2ecf20Sopenharmony_ci	 */
3638c2ecf20Sopenharmony_ci	u32	luntbl_sa;	/* bus address of this table	*/
3648c2ecf20Sopenharmony_ci	u32	lun0_sa;	/* bus address of LCB #0	*/
3658c2ecf20Sopenharmony_ci	/*
3668c2ecf20Sopenharmony_ci	 *  Actual SYNC/WIDE IO registers value for this target.
3678c2ecf20Sopenharmony_ci	 *  'sval', 'wval' and 'uval' are read from SCRIPTS and
3688c2ecf20Sopenharmony_ci	 *  so have alignment constraints.
3698c2ecf20Sopenharmony_ci	 */
3708c2ecf20Sopenharmony_ci/*0*/	u_char	uval;		/* -> SCNTL4 register		*/
3718c2ecf20Sopenharmony_ci/*1*/	u_char	sval;		/* -> SXFER  io register	*/
3728c2ecf20Sopenharmony_ci/*2*/	u_char	filler1;
3738c2ecf20Sopenharmony_ci/*3*/	u_char	wval;		/* -> SCNTL3 io register	*/
3748c2ecf20Sopenharmony_ci};
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci/*
3778c2ecf20Sopenharmony_ci *  Target Control Block
3788c2ecf20Sopenharmony_ci */
3798c2ecf20Sopenharmony_cistruct sym_tcb {
3808c2ecf20Sopenharmony_ci	/*
3818c2ecf20Sopenharmony_ci	 *  TCB header.
3828c2ecf20Sopenharmony_ci	 *  Assumed at offset 0.
3838c2ecf20Sopenharmony_ci	 */
3848c2ecf20Sopenharmony_ci/*0*/	struct sym_tcbh head;
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_ci	/*
3878c2ecf20Sopenharmony_ci	 *  LUN table used by the SCRIPTS processor.
3888c2ecf20Sopenharmony_ci	 *  An array of bus addresses is used on reselection.
3898c2ecf20Sopenharmony_ci	 */
3908c2ecf20Sopenharmony_ci	u32	*luntbl;	/* LCBs bus address table	*/
3918c2ecf20Sopenharmony_ci	int	nlcb;		/* Number of valid LCBs (including LUN #0) */
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci	/*
3948c2ecf20Sopenharmony_ci	 *  LUN table used by the C code.
3958c2ecf20Sopenharmony_ci	 */
3968c2ecf20Sopenharmony_ci	struct sym_lcb *lun0p;		/* LCB of LUN #0 (usual case)	*/
3978c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_LUN > 1
3988c2ecf20Sopenharmony_ci	struct sym_lcb **lunmp;		/* Other LCBs [1..MAX_LUN]	*/
3998c2ecf20Sopenharmony_ci#endif
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci#ifdef	SYM_HAVE_STCB
4028c2ecf20Sopenharmony_ci	/*
4038c2ecf20Sopenharmony_ci	 *  O/S specific data structure.
4048c2ecf20Sopenharmony_ci	 */
4058c2ecf20Sopenharmony_ci	struct sym_stcb s;
4068c2ecf20Sopenharmony_ci#endif
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	/* Transfer goal */
4098c2ecf20Sopenharmony_ci	struct sym_trans tgoal;
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	/* Last printed transfer speed */
4128c2ecf20Sopenharmony_ci	struct sym_trans tprint;
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci	/*
4158c2ecf20Sopenharmony_ci	 * Keep track of the CCB used for the negotiation in order
4168c2ecf20Sopenharmony_ci	 * to ensure that only 1 negotiation is queued at a time.
4178c2ecf20Sopenharmony_ci	 */
4188c2ecf20Sopenharmony_ci	struct sym_ccb *  nego_cp;	/* CCB used for the nego		*/
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	/*
4218c2ecf20Sopenharmony_ci	 *  Set when we want to reset the device.
4228c2ecf20Sopenharmony_ci	 */
4238c2ecf20Sopenharmony_ci	u_char	to_reset;
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	/*
4268c2ecf20Sopenharmony_ci	 *  Other user settable limits and options.
4278c2ecf20Sopenharmony_ci	 *  These limits are read from the NVRAM if present.
4288c2ecf20Sopenharmony_ci	 */
4298c2ecf20Sopenharmony_ci	unsigned char	usrflags;
4308c2ecf20Sopenharmony_ci	unsigned char	usr_period;
4318c2ecf20Sopenharmony_ci	unsigned char	usr_width;
4328c2ecf20Sopenharmony_ci	unsigned short	usrtags;
4338c2ecf20Sopenharmony_ci	struct scsi_target *starget;
4348c2ecf20Sopenharmony_ci};
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci/*
4378c2ecf20Sopenharmony_ci *  Global LCB HEADER.
4388c2ecf20Sopenharmony_ci *
4398c2ecf20Sopenharmony_ci *  Due to lack of indirect addressing on earlier NCR chips,
4408c2ecf20Sopenharmony_ci *  this substructure is copied from the LCB to a global
4418c2ecf20Sopenharmony_ci *  address after selection.
4428c2ecf20Sopenharmony_ci *  For SYMBIOS chips that support LOAD/STORE this copy is
4438c2ecf20Sopenharmony_ci *  not needed and thus not performed.
4448c2ecf20Sopenharmony_ci */
4458c2ecf20Sopenharmony_cistruct sym_lcbh {
4468c2ecf20Sopenharmony_ci	/*
4478c2ecf20Sopenharmony_ci	 *  SCRIPTS address jumped by SCRIPTS on reselection.
4488c2ecf20Sopenharmony_ci	 *  For not probed logical units, this address points to
4498c2ecf20Sopenharmony_ci	 *  SCRIPTS that deal with bad LU handling (must be at
4508c2ecf20Sopenharmony_ci	 *  offset zero of the LCB for that reason).
4518c2ecf20Sopenharmony_ci	 */
4528c2ecf20Sopenharmony_ci/*0*/	u32	resel_sa;
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci	/*
4558c2ecf20Sopenharmony_ci	 *  Task (bus address of a CCB) read from SCRIPTS that points
4568c2ecf20Sopenharmony_ci	 *  to the unique ITL nexus allowed to be disconnected.
4578c2ecf20Sopenharmony_ci	 */
4588c2ecf20Sopenharmony_ci	u32	itl_task_sa;
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci	/*
4618c2ecf20Sopenharmony_ci	 *  Task table bus address (read from SCRIPTS).
4628c2ecf20Sopenharmony_ci	 */
4638c2ecf20Sopenharmony_ci	u32	itlq_tbl_sa;
4648c2ecf20Sopenharmony_ci};
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci/*
4678c2ecf20Sopenharmony_ci *  Logical Unit Control Block
4688c2ecf20Sopenharmony_ci */
4698c2ecf20Sopenharmony_cistruct sym_lcb {
4708c2ecf20Sopenharmony_ci	/*
4718c2ecf20Sopenharmony_ci	 *  TCB header.
4728c2ecf20Sopenharmony_ci	 *  Assumed at offset 0.
4738c2ecf20Sopenharmony_ci	 */
4748c2ecf20Sopenharmony_ci/*0*/	struct sym_lcbh head;
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	/*
4778c2ecf20Sopenharmony_ci	 *  Task table read from SCRIPTS that contains pointers to
4788c2ecf20Sopenharmony_ci	 *  ITLQ nexuses. The bus address read from SCRIPTS is
4798c2ecf20Sopenharmony_ci	 *  inside the header.
4808c2ecf20Sopenharmony_ci	 */
4818c2ecf20Sopenharmony_ci	u32	*itlq_tbl;	/* Kernel virtual address	*/
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci	/*
4848c2ecf20Sopenharmony_ci	 *  Busy CCBs management.
4858c2ecf20Sopenharmony_ci	 */
4868c2ecf20Sopenharmony_ci	u_short	busy_itlq;	/* Number of busy tagged CCBs	*/
4878c2ecf20Sopenharmony_ci	u_short	busy_itl;	/* Number of busy untagged CCBs	*/
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_ci	/*
4908c2ecf20Sopenharmony_ci	 *  Circular tag allocation buffer.
4918c2ecf20Sopenharmony_ci	 */
4928c2ecf20Sopenharmony_ci	u_short	ia_tag;		/* Tag allocation index		*/
4938c2ecf20Sopenharmony_ci	u_short	if_tag;		/* Tag release index		*/
4948c2ecf20Sopenharmony_ci	u_char	*cb_tags;	/* Circular tags buffer		*/
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci	/*
4978c2ecf20Sopenharmony_ci	 *  O/S specific data structure.
4988c2ecf20Sopenharmony_ci	 */
4998c2ecf20Sopenharmony_ci#ifdef	SYM_HAVE_SLCB
5008c2ecf20Sopenharmony_ci	struct sym_slcb s;
5018c2ecf20Sopenharmony_ci#endif
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
5048c2ecf20Sopenharmony_ci	/*
5058c2ecf20Sopenharmony_ci	 *  Optionnaly the driver can handle device queueing,
5068c2ecf20Sopenharmony_ci	 *  and requeues internally command to redo.
5078c2ecf20Sopenharmony_ci	 */
5088c2ecf20Sopenharmony_ci	SYM_QUEHEAD waiting_ccbq;
5098c2ecf20Sopenharmony_ci	SYM_QUEHEAD started_ccbq;
5108c2ecf20Sopenharmony_ci	int	num_sgood;
5118c2ecf20Sopenharmony_ci	u_short	started_tags;
5128c2ecf20Sopenharmony_ci	u_short	started_no_tag;
5138c2ecf20Sopenharmony_ci	u_short	started_max;
5148c2ecf20Sopenharmony_ci	u_short	started_limit;
5158c2ecf20Sopenharmony_ci#endif
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
5188c2ecf20Sopenharmony_ci	/*
5198c2ecf20Sopenharmony_ci	 *  Optionally the driver can try to prevent SCSI
5208c2ecf20Sopenharmony_ci	 *  IOs from being reordered too much.
5218c2ecf20Sopenharmony_ci	 */
5228c2ecf20Sopenharmony_ci	u_char		tags_si;	/* Current index to tags sum	*/
5238c2ecf20Sopenharmony_ci	u_short		tags_sum[2];	/* Tags sum counters		*/
5248c2ecf20Sopenharmony_ci	u_short		tags_since;	/* # of tags since last switch	*/
5258c2ecf20Sopenharmony_ci#endif
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci	/*
5288c2ecf20Sopenharmony_ci	 *  Set when we want to clear all tasks.
5298c2ecf20Sopenharmony_ci	 */
5308c2ecf20Sopenharmony_ci	u_char to_clear;
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci	/*
5338c2ecf20Sopenharmony_ci	 *  Capabilities.
5348c2ecf20Sopenharmony_ci	 */
5358c2ecf20Sopenharmony_ci	u_char	user_flags;
5368c2ecf20Sopenharmony_ci	u_char	curr_flags;
5378c2ecf20Sopenharmony_ci};
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci/*
5408c2ecf20Sopenharmony_ci *  Action from SCRIPTS on a task.
5418c2ecf20Sopenharmony_ci *  Is part of the CCB, but is also used separately to plug
5428c2ecf20Sopenharmony_ci *  error handling action to perform from SCRIPTS.
5438c2ecf20Sopenharmony_ci */
5448c2ecf20Sopenharmony_cistruct sym_actscr {
5458c2ecf20Sopenharmony_ci	u32	start;		/* Jumped by SCRIPTS after selection	*/
5468c2ecf20Sopenharmony_ci	u32	restart;	/* Jumped by SCRIPTS on relection	*/
5478c2ecf20Sopenharmony_ci};
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_ci/*
5508c2ecf20Sopenharmony_ci *  Phase mismatch context.
5518c2ecf20Sopenharmony_ci *
5528c2ecf20Sopenharmony_ci *  It is part of the CCB and is used as parameters for the
5538c2ecf20Sopenharmony_ci *  DATA pointer. We need two contexts to handle correctly the
5548c2ecf20Sopenharmony_ci *  SAVED DATA POINTER.
5558c2ecf20Sopenharmony_ci */
5568c2ecf20Sopenharmony_cistruct sym_pmc {
5578c2ecf20Sopenharmony_ci	struct	sym_tblmove sg;	/* Updated interrupted SG block	*/
5588c2ecf20Sopenharmony_ci	u32	ret;		/* SCRIPT return address	*/
5598c2ecf20Sopenharmony_ci};
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci/*
5628c2ecf20Sopenharmony_ci *  LUN control block lookup.
5638c2ecf20Sopenharmony_ci *  We use a direct pointer for LUN #0, and a table of
5648c2ecf20Sopenharmony_ci *  pointers which is only allocated for devices that support
5658c2ecf20Sopenharmony_ci *  LUN(s) > 0.
5668c2ecf20Sopenharmony_ci */
5678c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_LUN <= 1
5688c2ecf20Sopenharmony_ci#define sym_lp(tp, lun) (!lun) ? (tp)->lun0p : NULL
5698c2ecf20Sopenharmony_ci#else
5708c2ecf20Sopenharmony_ci#define sym_lp(tp, lun) \
5718c2ecf20Sopenharmony_ci	(!lun) ? (tp)->lun0p : (tp)->lunmp ? (tp)->lunmp[((u8)lun)] : NULL
5728c2ecf20Sopenharmony_ci#endif
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci/*
5758c2ecf20Sopenharmony_ci *  Status are used by the host and the script processor.
5768c2ecf20Sopenharmony_ci *
5778c2ecf20Sopenharmony_ci *  The last four bytes (status[4]) are copied to the
5788c2ecf20Sopenharmony_ci *  scratchb register (declared as scr0..scr3) just after the
5798c2ecf20Sopenharmony_ci *  select/reselect, and copied back just after disconnecting.
5808c2ecf20Sopenharmony_ci *  Inside the script the XX_REG are used.
5818c2ecf20Sopenharmony_ci */
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci/*
5848c2ecf20Sopenharmony_ci *  Last four bytes (script)
5858c2ecf20Sopenharmony_ci */
5868c2ecf20Sopenharmony_ci#define  HX_REG	scr0
5878c2ecf20Sopenharmony_ci#define  HX_PRT	nc_scr0
5888c2ecf20Sopenharmony_ci#define  HS_REG	scr1
5898c2ecf20Sopenharmony_ci#define  HS_PRT	nc_scr1
5908c2ecf20Sopenharmony_ci#define  SS_REG	scr2
5918c2ecf20Sopenharmony_ci#define  SS_PRT	nc_scr2
5928c2ecf20Sopenharmony_ci#define  HF_REG	scr3
5938c2ecf20Sopenharmony_ci#define  HF_PRT	nc_scr3
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci/*
5968c2ecf20Sopenharmony_ci *  Last four bytes (host)
5978c2ecf20Sopenharmony_ci */
5988c2ecf20Sopenharmony_ci#define  host_xflags   phys.head.status[0]
5998c2ecf20Sopenharmony_ci#define  host_status   phys.head.status[1]
6008c2ecf20Sopenharmony_ci#define  ssss_status   phys.head.status[2]
6018c2ecf20Sopenharmony_ci#define  host_flags    phys.head.status[3]
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci/*
6048c2ecf20Sopenharmony_ci *  Host flags
6058c2ecf20Sopenharmony_ci */
6068c2ecf20Sopenharmony_ci#define HF_IN_PM0	1u
6078c2ecf20Sopenharmony_ci#define HF_IN_PM1	(1u<<1)
6088c2ecf20Sopenharmony_ci#define HF_ACT_PM	(1u<<2)
6098c2ecf20Sopenharmony_ci#define HF_DP_SAVED	(1u<<3)
6108c2ecf20Sopenharmony_ci#define HF_SENSE	(1u<<4)
6118c2ecf20Sopenharmony_ci#define HF_EXT_ERR	(1u<<5)
6128c2ecf20Sopenharmony_ci#define HF_DATA_IN	(1u<<6)
6138c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT
6148c2ecf20Sopenharmony_ci#define HF_HINT_IARB	(1u<<7)
6158c2ecf20Sopenharmony_ci#endif
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci/*
6188c2ecf20Sopenharmony_ci *  More host flags
6198c2ecf20Sopenharmony_ci */
6208c2ecf20Sopenharmony_ci#if	SYM_CONF_DMA_ADDRESSING_MODE == 2
6218c2ecf20Sopenharmony_ci#define	HX_DMAP_DIRTY	(1u<<7)
6228c2ecf20Sopenharmony_ci#endif
6238c2ecf20Sopenharmony_ci
6248c2ecf20Sopenharmony_ci/*
6258c2ecf20Sopenharmony_ci *  Global CCB HEADER.
6268c2ecf20Sopenharmony_ci *
6278c2ecf20Sopenharmony_ci *  Due to lack of indirect addressing on earlier NCR chips,
6288c2ecf20Sopenharmony_ci *  this substructure is copied from the ccb to a global
6298c2ecf20Sopenharmony_ci *  address after selection (or reselection) and copied back
6308c2ecf20Sopenharmony_ci *  before disconnect.
6318c2ecf20Sopenharmony_ci *  For SYMBIOS chips that support LOAD/STORE this copy is
6328c2ecf20Sopenharmony_ci *  not needed and thus not performed.
6338c2ecf20Sopenharmony_ci */
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_cistruct sym_ccbh {
6368c2ecf20Sopenharmony_ci	/*
6378c2ecf20Sopenharmony_ci	 *  Start and restart SCRIPTS addresses (must be at 0).
6388c2ecf20Sopenharmony_ci	 */
6398c2ecf20Sopenharmony_ci/*0*/	struct sym_actscr go;
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	/*
6428c2ecf20Sopenharmony_ci	 *  SCRIPTS jump address that deal with data pointers.
6438c2ecf20Sopenharmony_ci	 *  'savep' points to the position in the script responsible
6448c2ecf20Sopenharmony_ci	 *  for the actual transfer of data.
6458c2ecf20Sopenharmony_ci	 *  It's written on reception of a SAVE_DATA_POINTER message.
6468c2ecf20Sopenharmony_ci	 */
6478c2ecf20Sopenharmony_ci	u32	savep;		/* Jump address to saved data pointer	*/
6488c2ecf20Sopenharmony_ci	u32	lastp;		/* SCRIPTS address at end of data	*/
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci	/*
6518c2ecf20Sopenharmony_ci	 *  Status fields.
6528c2ecf20Sopenharmony_ci	 */
6538c2ecf20Sopenharmony_ci	u8	status[4];
6548c2ecf20Sopenharmony_ci};
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci/*
6578c2ecf20Sopenharmony_ci *  GET/SET the value of the data pointer used by SCRIPTS.
6588c2ecf20Sopenharmony_ci *
6598c2ecf20Sopenharmony_ci *  We must distinguish between the LOAD/STORE-based SCRIPTS
6608c2ecf20Sopenharmony_ci *  that use directly the header in the CCB, and the NCR-GENERIC
6618c2ecf20Sopenharmony_ci *  SCRIPTS that use the copy of the header in the HCB.
6628c2ecf20Sopenharmony_ci */
6638c2ecf20Sopenharmony_ci#if	SYM_CONF_GENERIC_SUPPORT
6648c2ecf20Sopenharmony_ci#define sym_set_script_dp(np, cp, dp)				\
6658c2ecf20Sopenharmony_ci	do {							\
6668c2ecf20Sopenharmony_ci		if (np->features & FE_LDSTR)			\
6678c2ecf20Sopenharmony_ci			cp->phys.head.lastp = cpu_to_scr(dp);	\
6688c2ecf20Sopenharmony_ci		else						\
6698c2ecf20Sopenharmony_ci			np->ccb_head.lastp = cpu_to_scr(dp);	\
6708c2ecf20Sopenharmony_ci	} while (0)
6718c2ecf20Sopenharmony_ci#define sym_get_script_dp(np, cp) 				\
6728c2ecf20Sopenharmony_ci	scr_to_cpu((np->features & FE_LDSTR) ?			\
6738c2ecf20Sopenharmony_ci		cp->phys.head.lastp : np->ccb_head.lastp)
6748c2ecf20Sopenharmony_ci#else
6758c2ecf20Sopenharmony_ci#define sym_set_script_dp(np, cp, dp)				\
6768c2ecf20Sopenharmony_ci	do {							\
6778c2ecf20Sopenharmony_ci		cp->phys.head.lastp = cpu_to_scr(dp);		\
6788c2ecf20Sopenharmony_ci	} while (0)
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_ci#define sym_get_script_dp(np, cp) (cp->phys.head.lastp)
6818c2ecf20Sopenharmony_ci#endif
6828c2ecf20Sopenharmony_ci
6838c2ecf20Sopenharmony_ci/*
6848c2ecf20Sopenharmony_ci *  Data Structure Block
6858c2ecf20Sopenharmony_ci *
6868c2ecf20Sopenharmony_ci *  During execution of a ccb by the script processor, the
6878c2ecf20Sopenharmony_ci *  DSA (data structure address) register points to this
6888c2ecf20Sopenharmony_ci *  substructure of the ccb.
6898c2ecf20Sopenharmony_ci */
6908c2ecf20Sopenharmony_cistruct sym_dsb {
6918c2ecf20Sopenharmony_ci	/*
6928c2ecf20Sopenharmony_ci	 *  CCB header.
6938c2ecf20Sopenharmony_ci	 *  Also assumed at offset 0 of the sym_ccb structure.
6948c2ecf20Sopenharmony_ci	 */
6958c2ecf20Sopenharmony_ci/*0*/	struct sym_ccbh head;
6968c2ecf20Sopenharmony_ci
6978c2ecf20Sopenharmony_ci	/*
6988c2ecf20Sopenharmony_ci	 *  Phase mismatch contexts.
6998c2ecf20Sopenharmony_ci	 *  We need two to handle correctly the SAVED DATA POINTER.
7008c2ecf20Sopenharmony_ci	 *  MUST BOTH BE AT OFFSET < 256, due to using 8 bit arithmetic
7018c2ecf20Sopenharmony_ci	 *  for address calculation from SCRIPTS.
7028c2ecf20Sopenharmony_ci	 */
7038c2ecf20Sopenharmony_ci	struct sym_pmc pm0;
7048c2ecf20Sopenharmony_ci	struct sym_pmc pm1;
7058c2ecf20Sopenharmony_ci
7068c2ecf20Sopenharmony_ci	/*
7078c2ecf20Sopenharmony_ci	 *  Table data for Script
7088c2ecf20Sopenharmony_ci	 */
7098c2ecf20Sopenharmony_ci	struct sym_tblsel  select;
7108c2ecf20Sopenharmony_ci	struct sym_tblmove smsg;
7118c2ecf20Sopenharmony_ci	struct sym_tblmove smsg_ext;
7128c2ecf20Sopenharmony_ci	struct sym_tblmove cmd;
7138c2ecf20Sopenharmony_ci	struct sym_tblmove sense;
7148c2ecf20Sopenharmony_ci	struct sym_tblmove wresid;
7158c2ecf20Sopenharmony_ci	struct sym_tblmove data [SYM_CONF_MAX_SG];
7168c2ecf20Sopenharmony_ci};
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci/*
7198c2ecf20Sopenharmony_ci *  Our Command Control Block
7208c2ecf20Sopenharmony_ci */
7218c2ecf20Sopenharmony_cistruct sym_ccb {
7228c2ecf20Sopenharmony_ci	/*
7238c2ecf20Sopenharmony_ci	 *  This is the data structure which is pointed by the DSA
7248c2ecf20Sopenharmony_ci	 *  register when it is executed by the script processor.
7258c2ecf20Sopenharmony_ci	 *  It must be the first entry.
7268c2ecf20Sopenharmony_ci	 */
7278c2ecf20Sopenharmony_ci	struct sym_dsb phys;
7288c2ecf20Sopenharmony_ci
7298c2ecf20Sopenharmony_ci	/*
7308c2ecf20Sopenharmony_ci	 *  Pointer to CAM ccb and related stuff.
7318c2ecf20Sopenharmony_ci	 */
7328c2ecf20Sopenharmony_ci	struct scsi_cmnd *cmd;	/* CAM scsiio ccb		*/
7338c2ecf20Sopenharmony_ci	u8	cdb_buf[16];	/* Copy of CDB			*/
7348c2ecf20Sopenharmony_ci#define	SYM_SNS_BBUF_LEN 32
7358c2ecf20Sopenharmony_ci	u8	sns_bbuf[SYM_SNS_BBUF_LEN]; /* Bounce buffer for sense data */
7368c2ecf20Sopenharmony_ci	int	data_len;	/* Total data length		*/
7378c2ecf20Sopenharmony_ci	int	segments;	/* Number of SG segments	*/
7388c2ecf20Sopenharmony_ci
7398c2ecf20Sopenharmony_ci	u8	order;		/* Tag type (if tagged command)	*/
7408c2ecf20Sopenharmony_ci	unsigned char odd_byte_adjustment;	/* odd-sized req on wide bus */
7418c2ecf20Sopenharmony_ci
7428c2ecf20Sopenharmony_ci	u_char	nego_status;	/* Negotiation status		*/
7438c2ecf20Sopenharmony_ci	u_char	xerr_status;	/* Extended error flags		*/
7448c2ecf20Sopenharmony_ci	u32	extra_bytes;	/* Extraneous bytes transferred	*/
7458c2ecf20Sopenharmony_ci
7468c2ecf20Sopenharmony_ci	/*
7478c2ecf20Sopenharmony_ci	 *  Message areas.
7488c2ecf20Sopenharmony_ci	 *  We prepare a message to be sent after selection.
7498c2ecf20Sopenharmony_ci	 *  We may use a second one if the command is rescheduled
7508c2ecf20Sopenharmony_ci	 *  due to CHECK_CONDITION or COMMAND TERMINATED.
7518c2ecf20Sopenharmony_ci	 *  Contents are IDENTIFY and SIMPLE_TAG.
7528c2ecf20Sopenharmony_ci	 *  While negotiating sync or wide transfer,
7538c2ecf20Sopenharmony_ci	 *  a SDTR or WDTR message is appended.
7548c2ecf20Sopenharmony_ci	 */
7558c2ecf20Sopenharmony_ci	u_char	scsi_smsg [12];
7568c2ecf20Sopenharmony_ci	u_char	scsi_smsg2[12];
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci	/*
7598c2ecf20Sopenharmony_ci	 *  Auto request sense related fields.
7608c2ecf20Sopenharmony_ci	 */
7618c2ecf20Sopenharmony_ci	u_char	sensecmd[6];	/* Request Sense command	*/
7628c2ecf20Sopenharmony_ci	u_char	sv_scsi_status;	/* Saved SCSI status 		*/
7638c2ecf20Sopenharmony_ci	u_char	sv_xerr_status;	/* Saved extended status	*/
7648c2ecf20Sopenharmony_ci	int	sv_resid;	/* Saved residual		*/
7658c2ecf20Sopenharmony_ci
7668c2ecf20Sopenharmony_ci	/*
7678c2ecf20Sopenharmony_ci	 *  Other fields.
7688c2ecf20Sopenharmony_ci	 */
7698c2ecf20Sopenharmony_ci	u32	ccb_ba;		/* BUS address of this CCB	*/
7708c2ecf20Sopenharmony_ci	u_short	tag;		/* Tag for this transfer	*/
7718c2ecf20Sopenharmony_ci				/*  NO_TAG means no tag		*/
7728c2ecf20Sopenharmony_ci	u_char	target;
7738c2ecf20Sopenharmony_ci	u_char	lun;
7748c2ecf20Sopenharmony_ci	struct sym_ccb *link_ccbh;	/* Host adapter CCB hash chain	*/
7758c2ecf20Sopenharmony_ci	SYM_QUEHEAD link_ccbq;	/* Link to free/busy CCB queue	*/
7768c2ecf20Sopenharmony_ci	u32	startp;		/* Initial data pointer		*/
7778c2ecf20Sopenharmony_ci	u32	goalp;		/* Expected last data pointer	*/
7788c2ecf20Sopenharmony_ci	int	ext_sg;		/* Extreme data pointer, used	*/
7798c2ecf20Sopenharmony_ci	int	ext_ofs;	/*  to calculate the residual.	*/
7808c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
7818c2ecf20Sopenharmony_ci	SYM_QUEHEAD link2_ccbq;	/* Link for device queueing	*/
7828c2ecf20Sopenharmony_ci	u_char	started;	/* CCB queued to the squeue	*/
7838c2ecf20Sopenharmony_ci#endif
7848c2ecf20Sopenharmony_ci	u_char	to_abort;	/* Want this IO to be aborted	*/
7858c2ecf20Sopenharmony_ci#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
7868c2ecf20Sopenharmony_ci	u_char	tags_si;	/* Lun tags sum index (0,1)	*/
7878c2ecf20Sopenharmony_ci#endif
7888c2ecf20Sopenharmony_ci};
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_ci#define CCB_BA(cp,lbl)	cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_citypedef struct device *m_pool_ident_t;
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_ci/*
7958c2ecf20Sopenharmony_ci *  Host Control Block
7968c2ecf20Sopenharmony_ci */
7978c2ecf20Sopenharmony_cistruct sym_hcb {
7988c2ecf20Sopenharmony_ci	/*
7998c2ecf20Sopenharmony_ci	 *  Global headers.
8008c2ecf20Sopenharmony_ci	 *  Due to poorness of addressing capabilities, earlier
8018c2ecf20Sopenharmony_ci	 *  chips (810, 815, 825) copy part of the data structures
8028c2ecf20Sopenharmony_ci	 *  (CCB, TCB and LCB) in fixed areas.
8038c2ecf20Sopenharmony_ci	 */
8048c2ecf20Sopenharmony_ci#if	SYM_CONF_GENERIC_SUPPORT
8058c2ecf20Sopenharmony_ci	struct sym_ccbh	ccb_head;
8068c2ecf20Sopenharmony_ci	struct sym_tcbh	tcb_head;
8078c2ecf20Sopenharmony_ci	struct sym_lcbh	lcb_head;
8088c2ecf20Sopenharmony_ci#endif
8098c2ecf20Sopenharmony_ci	/*
8108c2ecf20Sopenharmony_ci	 *  Idle task and invalid task actions and
8118c2ecf20Sopenharmony_ci	 *  their bus addresses.
8128c2ecf20Sopenharmony_ci	 */
8138c2ecf20Sopenharmony_ci	struct sym_actscr idletask, notask, bad_itl, bad_itlq;
8148c2ecf20Sopenharmony_ci	u32 idletask_ba, notask_ba, bad_itl_ba, bad_itlq_ba;
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	/*
8178c2ecf20Sopenharmony_ci	 *  Dummy lun table to protect us against target
8188c2ecf20Sopenharmony_ci	 *  returning bad lun number on reselection.
8198c2ecf20Sopenharmony_ci	 */
8208c2ecf20Sopenharmony_ci	u32	*badluntbl;	/* Table physical address	*/
8218c2ecf20Sopenharmony_ci	u32	badlun_sa;	/* SCRIPT handler BUS address	*/
8228c2ecf20Sopenharmony_ci
8238c2ecf20Sopenharmony_ci	/*
8248c2ecf20Sopenharmony_ci	 *  Bus address of this host control block.
8258c2ecf20Sopenharmony_ci	 */
8268c2ecf20Sopenharmony_ci	u32	hcb_ba;
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	/*
8298c2ecf20Sopenharmony_ci	 *  Bit 32-63 of the on-chip RAM bus address in LE format.
8308c2ecf20Sopenharmony_ci	 *  The START_RAM64 script loads the MMRS and MMWS from this
8318c2ecf20Sopenharmony_ci	 *  field.
8328c2ecf20Sopenharmony_ci	 */
8338c2ecf20Sopenharmony_ci	u32	scr_ram_seg;
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_ci	/*
8368c2ecf20Sopenharmony_ci	 *  Initial value of some IO register bits.
8378c2ecf20Sopenharmony_ci	 *  These values are assumed to have been set by BIOS, and may
8388c2ecf20Sopenharmony_ci	 *  be used to probe adapter implementation differences.
8398c2ecf20Sopenharmony_ci	 */
8408c2ecf20Sopenharmony_ci	u_char	sv_scntl0, sv_scntl3, sv_dmode, sv_dcntl, sv_ctest3, sv_ctest4,
8418c2ecf20Sopenharmony_ci		sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4, sv_scntl4,
8428c2ecf20Sopenharmony_ci		sv_stest1;
8438c2ecf20Sopenharmony_ci
8448c2ecf20Sopenharmony_ci	/*
8458c2ecf20Sopenharmony_ci	 *  Actual initial value of IO register bits used by the
8468c2ecf20Sopenharmony_ci	 *  driver. They are loaded at initialisation according to
8478c2ecf20Sopenharmony_ci	 *  features that are to be enabled/disabled.
8488c2ecf20Sopenharmony_ci	 */
8498c2ecf20Sopenharmony_ci	u_char	rv_scntl0, rv_scntl3, rv_dmode, rv_dcntl, rv_ctest3, rv_ctest4,
8508c2ecf20Sopenharmony_ci		rv_ctest5, rv_stest2, rv_ccntl0, rv_ccntl1, rv_scntl4;
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci	/*
8538c2ecf20Sopenharmony_ci	 *  Target data.
8548c2ecf20Sopenharmony_ci	 */
8558c2ecf20Sopenharmony_ci	struct sym_tcb	target[SYM_CONF_MAX_TARGET];
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	/*
8588c2ecf20Sopenharmony_ci	 *  Target control block bus address array used by the SCRIPT
8598c2ecf20Sopenharmony_ci	 *  on reselection.
8608c2ecf20Sopenharmony_ci	 */
8618c2ecf20Sopenharmony_ci	u32		*targtbl;
8628c2ecf20Sopenharmony_ci	u32		targtbl_ba;
8638c2ecf20Sopenharmony_ci
8648c2ecf20Sopenharmony_ci	/*
8658c2ecf20Sopenharmony_ci	 *  DMA pool handle for this HBA.
8668c2ecf20Sopenharmony_ci	 */
8678c2ecf20Sopenharmony_ci	m_pool_ident_t	bus_dmat;
8688c2ecf20Sopenharmony_ci
8698c2ecf20Sopenharmony_ci	/*
8708c2ecf20Sopenharmony_ci	 *  O/S specific data structure
8718c2ecf20Sopenharmony_ci	 */
8728c2ecf20Sopenharmony_ci	struct sym_shcb s;
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci	/*
8758c2ecf20Sopenharmony_ci	 *  Physical bus addresses of the chip.
8768c2ecf20Sopenharmony_ci	 */
8778c2ecf20Sopenharmony_ci	u32		mmio_ba;	/* MMIO 32 bit BUS address	*/
8788c2ecf20Sopenharmony_ci	u32		ram_ba;		/* RAM 32 bit BUS address	*/
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_ci	/*
8818c2ecf20Sopenharmony_ci	 *  SCRIPTS virtual and physical bus addresses.
8828c2ecf20Sopenharmony_ci	 *  'script'  is loaded in the on-chip RAM if present.
8838c2ecf20Sopenharmony_ci	 *  'scripth' stays in main memory for all chips except the
8848c2ecf20Sopenharmony_ci	 *  53C895A, 53C896 and 53C1010 that provide 8K on-chip RAM.
8858c2ecf20Sopenharmony_ci	 */
8868c2ecf20Sopenharmony_ci	u_char		*scripta0;	/* Copy of scripts A, B, Z	*/
8878c2ecf20Sopenharmony_ci	u_char		*scriptb0;
8888c2ecf20Sopenharmony_ci	u_char		*scriptz0;
8898c2ecf20Sopenharmony_ci	u32		scripta_ba;	/* Actual scripts A, B, Z	*/
8908c2ecf20Sopenharmony_ci	u32		scriptb_ba;	/* 32 bit bus addresses.	*/
8918c2ecf20Sopenharmony_ci	u32		scriptz_ba;
8928c2ecf20Sopenharmony_ci	u_short		scripta_sz;	/* Actual size of script A, B, Z*/
8938c2ecf20Sopenharmony_ci	u_short		scriptb_sz;
8948c2ecf20Sopenharmony_ci	u_short		scriptz_sz;
8958c2ecf20Sopenharmony_ci
8968c2ecf20Sopenharmony_ci	/*
8978c2ecf20Sopenharmony_ci	 *  Bus addresses, setup and patch methods for
8988c2ecf20Sopenharmony_ci	 *  the selected firmware.
8998c2ecf20Sopenharmony_ci	 */
9008c2ecf20Sopenharmony_ci	struct sym_fwa_ba fwa_bas;	/* Useful SCRIPTA bus addresses	*/
9018c2ecf20Sopenharmony_ci	struct sym_fwb_ba fwb_bas;	/* Useful SCRIPTB bus addresses	*/
9028c2ecf20Sopenharmony_ci	struct sym_fwz_ba fwz_bas;	/* Useful SCRIPTZ bus addresses	*/
9038c2ecf20Sopenharmony_ci	void		(*fw_setup)(struct sym_hcb *np, struct sym_fw *fw);
9048c2ecf20Sopenharmony_ci	void		(*fw_patch)(struct Scsi_Host *);
9058c2ecf20Sopenharmony_ci	char		*fw_name;
9068c2ecf20Sopenharmony_ci
9078c2ecf20Sopenharmony_ci	/*
9088c2ecf20Sopenharmony_ci	 *  General controller parameters and configuration.
9098c2ecf20Sopenharmony_ci	 */
9108c2ecf20Sopenharmony_ci	u_int	features;	/* Chip features map		*/
9118c2ecf20Sopenharmony_ci	u_char	myaddr;		/* SCSI id of the adapter	*/
9128c2ecf20Sopenharmony_ci	u_char	maxburst;	/* log base 2 of dwords burst	*/
9138c2ecf20Sopenharmony_ci	u_char	maxwide;	/* Maximum transfer width	*/
9148c2ecf20Sopenharmony_ci	u_char	minsync;	/* Min sync period factor (ST)	*/
9158c2ecf20Sopenharmony_ci	u_char	maxsync;	/* Max sync period factor (ST)	*/
9168c2ecf20Sopenharmony_ci	u_char	maxoffs;	/* Max scsi offset        (ST)	*/
9178c2ecf20Sopenharmony_ci	u_char	minsync_dt;	/* Min sync period factor (DT)	*/
9188c2ecf20Sopenharmony_ci	u_char	maxsync_dt;	/* Max sync period factor (DT)	*/
9198c2ecf20Sopenharmony_ci	u_char	maxoffs_dt;	/* Max scsi offset        (DT)	*/
9208c2ecf20Sopenharmony_ci	u_char	multiplier;	/* Clock multiplier (1,2,4)	*/
9218c2ecf20Sopenharmony_ci	u_char	clock_divn;	/* Number of clock divisors	*/
9228c2ecf20Sopenharmony_ci	u32	clock_khz;	/* SCSI clock frequency in KHz	*/
9238c2ecf20Sopenharmony_ci	u32	pciclk_khz;	/* Estimated PCI clock  in KHz	*/
9248c2ecf20Sopenharmony_ci	/*
9258c2ecf20Sopenharmony_ci	 *  Start queue management.
9268c2ecf20Sopenharmony_ci	 *  It is filled up by the host processor and accessed by the
9278c2ecf20Sopenharmony_ci	 *  SCRIPTS processor in order to start SCSI commands.
9288c2ecf20Sopenharmony_ci	 */
9298c2ecf20Sopenharmony_ci	volatile		/* Prevent code optimizations	*/
9308c2ecf20Sopenharmony_ci	u32	*squeue;	/* Start queue virtual address	*/
9318c2ecf20Sopenharmony_ci	u32	squeue_ba;	/* Start queue BUS address	*/
9328c2ecf20Sopenharmony_ci	u_short	squeueput;	/* Next free slot of the queue	*/
9338c2ecf20Sopenharmony_ci	u_short	actccbs;	/* Number of allocated CCBs	*/
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_ci	/*
9368c2ecf20Sopenharmony_ci	 *  Command completion queue.
9378c2ecf20Sopenharmony_ci	 *  It is the same size as the start queue to avoid overflow.
9388c2ecf20Sopenharmony_ci	 */
9398c2ecf20Sopenharmony_ci	u_short	dqueueget;	/* Next position to scan	*/
9408c2ecf20Sopenharmony_ci	volatile		/* Prevent code optimizations	*/
9418c2ecf20Sopenharmony_ci	u32	*dqueue;	/* Completion (done) queue	*/
9428c2ecf20Sopenharmony_ci	u32	dqueue_ba;	/* Done queue BUS address	*/
9438c2ecf20Sopenharmony_ci
9448c2ecf20Sopenharmony_ci	/*
9458c2ecf20Sopenharmony_ci	 *  Miscellaneous buffers accessed by the scripts-processor.
9468c2ecf20Sopenharmony_ci	 *  They shall be DWORD aligned, because they may be read or
9478c2ecf20Sopenharmony_ci	 *  written with a script command.
9488c2ecf20Sopenharmony_ci	 */
9498c2ecf20Sopenharmony_ci	u_char		msgout[8];	/* Buffer for MESSAGE OUT 	*/
9508c2ecf20Sopenharmony_ci	u_char		msgin [8];	/* Buffer for MESSAGE IN	*/
9518c2ecf20Sopenharmony_ci	u32		lastmsg;	/* Last SCSI message sent	*/
9528c2ecf20Sopenharmony_ci	u32		scratch;	/* Scratch for SCSI receive	*/
9538c2ecf20Sopenharmony_ci					/* Also used for cache test 	*/
9548c2ecf20Sopenharmony_ci	/*
9558c2ecf20Sopenharmony_ci	 *  Miscellaneous configuration and status parameters.
9568c2ecf20Sopenharmony_ci	 */
9578c2ecf20Sopenharmony_ci	u_char		usrflags;	/* Miscellaneous user flags	*/
9588c2ecf20Sopenharmony_ci	u_char		scsi_mode;	/* Current SCSI BUS mode	*/
9598c2ecf20Sopenharmony_ci	u_char		verbose;	/* Verbosity for this controller*/
9608c2ecf20Sopenharmony_ci
9618c2ecf20Sopenharmony_ci	/*
9628c2ecf20Sopenharmony_ci	 *  CCB lists and queue.
9638c2ecf20Sopenharmony_ci	 */
9648c2ecf20Sopenharmony_ci	struct sym_ccb **ccbh;			/* CCBs hashed by DSA value	*/
9658c2ecf20Sopenharmony_ci					/* CCB_HASH_SIZE lists of CCBs	*/
9668c2ecf20Sopenharmony_ci	SYM_QUEHEAD	free_ccbq;	/* Queue of available CCBs	*/
9678c2ecf20Sopenharmony_ci	SYM_QUEHEAD	busy_ccbq;	/* Queue of busy CCBs		*/
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_ci	/*
9708c2ecf20Sopenharmony_ci	 *  During error handling and/or recovery,
9718c2ecf20Sopenharmony_ci	 *  active CCBs that are to be completed with
9728c2ecf20Sopenharmony_ci	 *  error or requeued are moved from the busy_ccbq
9738c2ecf20Sopenharmony_ci	 *  to the comp_ccbq prior to completion.
9748c2ecf20Sopenharmony_ci	 */
9758c2ecf20Sopenharmony_ci	SYM_QUEHEAD	comp_ccbq;
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
9788c2ecf20Sopenharmony_ci	SYM_QUEHEAD	dummy_ccbq;
9798c2ecf20Sopenharmony_ci#endif
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	/*
9828c2ecf20Sopenharmony_ci	 *  IMMEDIATE ARBITRATION (IARB) control.
9838c2ecf20Sopenharmony_ci	 *
9848c2ecf20Sopenharmony_ci	 *  We keep track in 'last_cp' of the last CCB that has been
9858c2ecf20Sopenharmony_ci	 *  queued to the SCRIPTS processor and clear 'last_cp' when
9868c2ecf20Sopenharmony_ci	 *  this CCB completes. If last_cp is not zero at the moment
9878c2ecf20Sopenharmony_ci	 *  we queue a new CCB, we set a flag in 'last_cp' that is
9888c2ecf20Sopenharmony_ci	 *  used by the SCRIPTS as a hint for setting IARB.
9898c2ecf20Sopenharmony_ci	 *  We donnot set more than 'iarb_max' consecutive hints for
9908c2ecf20Sopenharmony_ci	 *  IARB in order to leave devices a chance to reselect.
9918c2ecf20Sopenharmony_ci	 *  By the way, any non zero value of 'iarb_max' is unfair. :)
9928c2ecf20Sopenharmony_ci	 */
9938c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT
9948c2ecf20Sopenharmony_ci	u_short		iarb_max;	/* Max. # consecutive IARB hints*/
9958c2ecf20Sopenharmony_ci	u_short		iarb_count;	/* Actual # of these hints	*/
9968c2ecf20Sopenharmony_ci	struct sym_ccb *	last_cp;
9978c2ecf20Sopenharmony_ci#endif
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_ci	/*
10008c2ecf20Sopenharmony_ci	 *  Command abort handling.
10018c2ecf20Sopenharmony_ci	 *  We need to synchronize tightly with the SCRIPTS
10028c2ecf20Sopenharmony_ci	 *  processor in order to handle things correctly.
10038c2ecf20Sopenharmony_ci	 */
10048c2ecf20Sopenharmony_ci	u_char		abrt_msg[4];	/* Message to send buffer	*/
10058c2ecf20Sopenharmony_ci	struct sym_tblmove abrt_tbl;	/* Table for the MOV of it 	*/
10068c2ecf20Sopenharmony_ci	struct sym_tblsel  abrt_sel;	/* Sync params for selection	*/
10078c2ecf20Sopenharmony_ci	u_char		istat_sem;	/* Tells the chip to stop (SEM)	*/
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_ci	/*
10108c2ecf20Sopenharmony_ci	 *  64 bit DMA handling.
10118c2ecf20Sopenharmony_ci	 */
10128c2ecf20Sopenharmony_ci#if	SYM_CONF_DMA_ADDRESSING_MODE != 0
10138c2ecf20Sopenharmony_ci	u_char	use_dac;		/* Use PCI DAC cycles		*/
10148c2ecf20Sopenharmony_ci#if	SYM_CONF_DMA_ADDRESSING_MODE == 2
10158c2ecf20Sopenharmony_ci	u_char	dmap_dirty;		/* Dma segments registers dirty	*/
10168c2ecf20Sopenharmony_ci	u32	dmap_bah[SYM_DMAP_SIZE];/* Segment registers map	*/
10178c2ecf20Sopenharmony_ci#endif
10188c2ecf20Sopenharmony_ci#endif
10198c2ecf20Sopenharmony_ci};
10208c2ecf20Sopenharmony_ci
10218c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 0
10228c2ecf20Sopenharmony_ci#define use_dac(np)	0
10238c2ecf20Sopenharmony_ci#define set_dac(np)	do { } while (0)
10248c2ecf20Sopenharmony_ci#else
10258c2ecf20Sopenharmony_ci#define use_dac(np)	(np)->use_dac
10268c2ecf20Sopenharmony_ci#define set_dac(np)	(np)->use_dac = 1
10278c2ecf20Sopenharmony_ci#endif
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci#define HCB_BA(np, lbl)	(np->hcb_ba + offsetof(struct sym_hcb, lbl))
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci
10328c2ecf20Sopenharmony_ci/*
10338c2ecf20Sopenharmony_ci *  FIRMWARES (sym_fw.c)
10348c2ecf20Sopenharmony_ci */
10358c2ecf20Sopenharmony_cistruct sym_fw * sym_find_firmware(struct sym_chip *chip);
10368c2ecf20Sopenharmony_civoid sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len);
10378c2ecf20Sopenharmony_ci
10388c2ecf20Sopenharmony_ci/*
10398c2ecf20Sopenharmony_ci *  Driver methods called from O/S specific code.
10408c2ecf20Sopenharmony_ci */
10418c2ecf20Sopenharmony_cichar *sym_driver_name(void);
10428c2ecf20Sopenharmony_civoid sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
10438c2ecf20Sopenharmony_ciint sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
10448c2ecf20Sopenharmony_cistruct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision);
10458c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
10468c2ecf20Sopenharmony_civoid sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
10478c2ecf20Sopenharmony_ci#else
10488c2ecf20Sopenharmony_civoid sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
10498c2ecf20Sopenharmony_ci#endif
10508c2ecf20Sopenharmony_civoid sym_start_up(struct Scsi_Host *, int reason);
10518c2ecf20Sopenharmony_ciirqreturn_t sym_interrupt(struct Scsi_Host *);
10528c2ecf20Sopenharmony_ciint sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task);
10538c2ecf20Sopenharmony_cistruct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order);
10548c2ecf20Sopenharmony_civoid sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp);
10558c2ecf20Sopenharmony_cistruct sym_lcb *sym_alloc_lcb(struct sym_hcb *np, u_char tn, u_char ln);
10568c2ecf20Sopenharmony_ciint sym_free_lcb(struct sym_hcb *np, u_char tn, u_char ln);
10578c2ecf20Sopenharmony_ciint sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp);
10588c2ecf20Sopenharmony_ciint sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out);
10598c2ecf20Sopenharmony_ciint sym_reset_scsi_target(struct sym_hcb *np, int target);
10608c2ecf20Sopenharmony_civoid sym_hcb_free(struct sym_hcb *np);
10618c2ecf20Sopenharmony_ciint sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram *nvram);
10628c2ecf20Sopenharmony_ci
10638c2ecf20Sopenharmony_ci/*
10648c2ecf20Sopenharmony_ci *  Build a scatter/gather entry.
10658c2ecf20Sopenharmony_ci *
10668c2ecf20Sopenharmony_ci *  For 64 bit systems, we use the 8 upper bits of the size field
10678c2ecf20Sopenharmony_ci *  to provide bus address bits 32-39 to the SCRIPTS processor.
10688c2ecf20Sopenharmony_ci *  This allows the 895A, 896, 1010 to address up to 1 TB of memory.
10698c2ecf20Sopenharmony_ci */
10708c2ecf20Sopenharmony_ci
10718c2ecf20Sopenharmony_ci#if   SYM_CONF_DMA_ADDRESSING_MODE == 0
10728c2ecf20Sopenharmony_ci#define DMA_DAC_MASK	DMA_BIT_MASK(32)
10738c2ecf20Sopenharmony_ci#define sym_build_sge(np, data, badd, len)	\
10748c2ecf20Sopenharmony_cido {						\
10758c2ecf20Sopenharmony_ci	(data)->addr = cpu_to_scr(badd);	\
10768c2ecf20Sopenharmony_ci	(data)->size = cpu_to_scr(len);		\
10778c2ecf20Sopenharmony_ci} while (0)
10788c2ecf20Sopenharmony_ci#elif SYM_CONF_DMA_ADDRESSING_MODE == 1
10798c2ecf20Sopenharmony_ci#define DMA_DAC_MASK	DMA_BIT_MASK(40)
10808c2ecf20Sopenharmony_ci#define sym_build_sge(np, data, badd, len)				\
10818c2ecf20Sopenharmony_cido {									\
10828c2ecf20Sopenharmony_ci	(data)->addr = cpu_to_scr(badd);				\
10838c2ecf20Sopenharmony_ci	(data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len);	\
10848c2ecf20Sopenharmony_ci} while (0)
10858c2ecf20Sopenharmony_ci#elif SYM_CONF_DMA_ADDRESSING_MODE == 2
10868c2ecf20Sopenharmony_ci#define DMA_DAC_MASK	DMA_BIT_MASK(64)
10878c2ecf20Sopenharmony_ciint sym_lookup_dmap(struct sym_hcb *np, u32 h, int s);
10888c2ecf20Sopenharmony_cistatic inline void
10898c2ecf20Sopenharmony_cisym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len)
10908c2ecf20Sopenharmony_ci{
10918c2ecf20Sopenharmony_ci	u32 h = (badd>>32);
10928c2ecf20Sopenharmony_ci	int s = (h&SYM_DMAP_MASK);
10938c2ecf20Sopenharmony_ci
10948c2ecf20Sopenharmony_ci	if (h != np->dmap_bah[s])
10958c2ecf20Sopenharmony_ci		goto bad;
10968c2ecf20Sopenharmony_cigood:
10978c2ecf20Sopenharmony_ci	(data)->addr = cpu_to_scr(badd);
10988c2ecf20Sopenharmony_ci	(data)->size = cpu_to_scr((s<<24) + len);
10998c2ecf20Sopenharmony_ci	return;
11008c2ecf20Sopenharmony_cibad:
11018c2ecf20Sopenharmony_ci	s = sym_lookup_dmap(np, h, s);
11028c2ecf20Sopenharmony_ci	goto good;
11038c2ecf20Sopenharmony_ci}
11048c2ecf20Sopenharmony_ci#else
11058c2ecf20Sopenharmony_ci#error "Unsupported DMA addressing mode"
11068c2ecf20Sopenharmony_ci#endif
11078c2ecf20Sopenharmony_ci
11088c2ecf20Sopenharmony_ci/*
11098c2ecf20Sopenharmony_ci *  MEMORY ALLOCATOR.
11108c2ecf20Sopenharmony_ci */
11118c2ecf20Sopenharmony_ci
11128c2ecf20Sopenharmony_ci#define sym_get_mem_cluster()	\
11138c2ecf20Sopenharmony_ci	(void *) __get_free_pages(GFP_ATOMIC, SYM_MEM_PAGE_ORDER)
11148c2ecf20Sopenharmony_ci#define sym_free_mem_cluster(p)	\
11158c2ecf20Sopenharmony_ci	free_pages((unsigned long)p, SYM_MEM_PAGE_ORDER)
11168c2ecf20Sopenharmony_ci
11178c2ecf20Sopenharmony_ci/*
11188c2ecf20Sopenharmony_ci *  Link between free memory chunks of a given size.
11198c2ecf20Sopenharmony_ci */
11208c2ecf20Sopenharmony_citypedef struct sym_m_link {
11218c2ecf20Sopenharmony_ci	struct sym_m_link *next;
11228c2ecf20Sopenharmony_ci} *m_link_p;
11238c2ecf20Sopenharmony_ci
11248c2ecf20Sopenharmony_ci/*
11258c2ecf20Sopenharmony_ci *  Virtual to bus physical translation for a given cluster.
11268c2ecf20Sopenharmony_ci *  Such a structure is only useful with DMA abstraction.
11278c2ecf20Sopenharmony_ci */
11288c2ecf20Sopenharmony_citypedef struct sym_m_vtob {	/* Virtual to Bus address translation */
11298c2ecf20Sopenharmony_ci	struct sym_m_vtob *next;
11308c2ecf20Sopenharmony_ci	void *vaddr;		/* Virtual address */
11318c2ecf20Sopenharmony_ci	dma_addr_t baddr;	/* Bus physical address */
11328c2ecf20Sopenharmony_ci} *m_vtob_p;
11338c2ecf20Sopenharmony_ci
11348c2ecf20Sopenharmony_ci/* Hash this stuff a bit to speed up translations */
11358c2ecf20Sopenharmony_ci#define VTOB_HASH_SHIFT		5
11368c2ecf20Sopenharmony_ci#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
11378c2ecf20Sopenharmony_ci#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
11388c2ecf20Sopenharmony_ci#define VTOB_HASH_CODE(m)	\
11398c2ecf20Sopenharmony_ci	((((unsigned long)(m)) >> SYM_MEM_CLUSTER_SHIFT) & VTOB_HASH_MASK)
11408c2ecf20Sopenharmony_ci
11418c2ecf20Sopenharmony_ci/*
11428c2ecf20Sopenharmony_ci *  Memory pool of a given kind.
11438c2ecf20Sopenharmony_ci *  Ideally, we want to use:
11448c2ecf20Sopenharmony_ci *  1) 1 pool for memory we donnot need to involve in DMA.
11458c2ecf20Sopenharmony_ci *  2) The same pool for controllers that require same DMA
11468c2ecf20Sopenharmony_ci *     constraints and features.
11478c2ecf20Sopenharmony_ci *     The OS specific m_pool_id_t thing and the sym_m_pool_match()
11488c2ecf20Sopenharmony_ci *     method are expected to tell the driver about.
11498c2ecf20Sopenharmony_ci */
11508c2ecf20Sopenharmony_citypedef struct sym_m_pool {
11518c2ecf20Sopenharmony_ci	m_pool_ident_t	dev_dmat;	/* Identifies the pool (see above) */
11528c2ecf20Sopenharmony_ci	void * (*get_mem_cluster)(struct sym_m_pool *);
11538c2ecf20Sopenharmony_ci#ifdef	SYM_MEM_FREE_UNUSED
11548c2ecf20Sopenharmony_ci	void (*free_mem_cluster)(struct sym_m_pool *, void *);
11558c2ecf20Sopenharmony_ci#endif
11568c2ecf20Sopenharmony_ci#define M_GET_MEM_CLUSTER()		mp->get_mem_cluster(mp)
11578c2ecf20Sopenharmony_ci#define M_FREE_MEM_CLUSTER(p)		mp->free_mem_cluster(mp, p)
11588c2ecf20Sopenharmony_ci	int nump;
11598c2ecf20Sopenharmony_ci	m_vtob_p vtob[VTOB_HASH_SIZE];
11608c2ecf20Sopenharmony_ci	struct sym_m_pool *next;
11618c2ecf20Sopenharmony_ci	struct sym_m_link h[SYM_MEM_CLUSTER_SHIFT - SYM_MEM_SHIFT + 1];
11628c2ecf20Sopenharmony_ci} *m_pool_p;
11638c2ecf20Sopenharmony_ci
11648c2ecf20Sopenharmony_ci/*
11658c2ecf20Sopenharmony_ci *  Alloc, free and translate addresses to bus physical
11668c2ecf20Sopenharmony_ci *  for DMAable memory.
11678c2ecf20Sopenharmony_ci */
11688c2ecf20Sopenharmony_civoid *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name);
11698c2ecf20Sopenharmony_civoid __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name);
11708c2ecf20Sopenharmony_cidma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m);
11718c2ecf20Sopenharmony_ci
11728c2ecf20Sopenharmony_ci/*
11738c2ecf20Sopenharmony_ci * Verbs used by the driver code for DMAable memory handling.
11748c2ecf20Sopenharmony_ci * The _uvptv_ macro avoids a nasty warning about pointer to volatile
11758c2ecf20Sopenharmony_ci * being discarded.
11768c2ecf20Sopenharmony_ci */
11778c2ecf20Sopenharmony_ci#define _uvptv_(p) ((void *)((u_long)(p)))
11788c2ecf20Sopenharmony_ci
11798c2ecf20Sopenharmony_ci#define _sym_calloc_dma(np, l, n)	__sym_calloc_dma(np->bus_dmat, l, n)
11808c2ecf20Sopenharmony_ci#define _sym_mfree_dma(np, p, l, n)	\
11818c2ecf20Sopenharmony_ci			__sym_mfree_dma(np->bus_dmat, _uvptv_(p), l, n)
11828c2ecf20Sopenharmony_ci#define sym_calloc_dma(l, n)		_sym_calloc_dma(np, l, n)
11838c2ecf20Sopenharmony_ci#define sym_mfree_dma(p, l, n)		_sym_mfree_dma(np, p, l, n)
11848c2ecf20Sopenharmony_ci#define vtobus(p)			__vtobus(np->bus_dmat, _uvptv_(p))
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_ci/*
11878c2ecf20Sopenharmony_ci *  We have to provide the driver memory allocator with methods for
11888c2ecf20Sopenharmony_ci *  it to maintain virtual to bus physical address translations.
11898c2ecf20Sopenharmony_ci */
11908c2ecf20Sopenharmony_ci
11918c2ecf20Sopenharmony_ci#define sym_m_pool_match(mp_id1, mp_id2)	(mp_id1 == mp_id2)
11928c2ecf20Sopenharmony_ci
11938c2ecf20Sopenharmony_cistatic inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
11948c2ecf20Sopenharmony_ci{
11958c2ecf20Sopenharmony_ci	void *vaddr = NULL;
11968c2ecf20Sopenharmony_ci	dma_addr_t baddr = 0;
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci	vaddr = dma_alloc_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, &baddr,
11998c2ecf20Sopenharmony_ci			GFP_ATOMIC);
12008c2ecf20Sopenharmony_ci	if (vaddr) {
12018c2ecf20Sopenharmony_ci		vbp->vaddr = vaddr;
12028c2ecf20Sopenharmony_ci		vbp->baddr = baddr;
12038c2ecf20Sopenharmony_ci	}
12048c2ecf20Sopenharmony_ci	return vaddr;
12058c2ecf20Sopenharmony_ci}
12068c2ecf20Sopenharmony_ci
12078c2ecf20Sopenharmony_cistatic inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
12088c2ecf20Sopenharmony_ci{
12098c2ecf20Sopenharmony_ci	dma_free_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, vbp->vaddr,
12108c2ecf20Sopenharmony_ci			vbp->baddr);
12118c2ecf20Sopenharmony_ci}
12128c2ecf20Sopenharmony_ci
12138c2ecf20Sopenharmony_ci#endif /* SYM_HIPD_H */
1214