ispvar.h revision 39235
139235Sgibbs/* $Id: ispvar.h,v 1.17 1998/09/14 23:22:51 mjacob Exp $ */
235388Smjacob/*
335388Smjacob * Soft Definitions for for Qlogic ISP SCSI adapters.
435388Smjacob *
535388Smjacob *---------------------------------------
635388Smjacob * Copyright (c) 1997, 1998 by Matthew Jacob
735388Smjacob * NASA/Ames Research Center
835388Smjacob * All rights reserved.
935388Smjacob *---------------------------------------
1035388Smjacob * Redistribution and use in source and binary forms, with or without
1135388Smjacob * modification, are permitted provided that the following conditions
1235388Smjacob * are met:
1335388Smjacob * 1. Redistributions of source code must retain the above copyright
1435388Smjacob *    notice immediately at the beginning of the file, without modification,
1535388Smjacob *    this list of conditions, and the following disclaimer.
1635388Smjacob * 2. Redistributions in binary form must reproduce the above copyright
1735388Smjacob *    notice, this list of conditions and the following disclaimer in the
1835388Smjacob *    documentation and/or other materials provided with the distribution.
1935388Smjacob * 3. The name of the author may not be used to endorse or promote products
2035388Smjacob *    derived from this software without specific prior written permission.
2135388Smjacob *
2235388Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2335388Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2435388Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2535388Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2635388Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2735388Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2835388Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2935388Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3035388Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3135388Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3235388Smjacob * SUCH DAMAGE.
3335388Smjacob *
3435388Smjacob */
3535388Smjacob
3635388Smjacob#ifndef	_ISPVAR_H
3735388Smjacob#define	_ISPVAR_H
3835388Smjacob
3935388Smjacob#ifdef	__NetBSD__
4035388Smjacob#include <dev/ic/ispmbox.h>
4135388Smjacob#endif
4235388Smjacob#ifdef	__FreeBSD__
4335388Smjacob#include <dev/isp/ispmbox.h>
4435388Smjacob#endif
4535388Smjacob#ifdef	__linux__
4635388Smjacob#include <ispmbox.h>
4735388Smjacob#endif
4835388Smjacob
4939235Sgibbs#define	ISP_CORE_VERSION_MAJOR	1
5039235Sgibbs#define	ISP_CORE_VERSION_MINOR	3
5139235Sgibbs
5235388Smjacob/*
5335388Smjacob * Vector for MD code to provide specific services.
5435388Smjacob */
5535388Smjacobstruct ispsoftc;
5635388Smjacobstruct ispmdvec {
5735388Smjacob	u_int16_t	(*dv_rd_reg) __P((struct ispsoftc *, int));
5835388Smjacob	void		(*dv_wr_reg) __P((struct ispsoftc *, int, u_int16_t));
5935388Smjacob	int		(*dv_mbxdma) __P((struct ispsoftc *));
6035388Smjacob	int		(*dv_dmaset) __P((struct ispsoftc *,
6135388Smjacob		ISP_SCSI_XFER_T *, ispreq_t *, u_int8_t *, u_int8_t));
6235388Smjacob	void		(*dv_dmaclr)
6335388Smjacob		__P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t));
6435388Smjacob	void		(*dv_reset0) __P((struct ispsoftc *));
6535388Smjacob	void		(*dv_reset1) __P((struct ispsoftc *));
6635388Smjacob	void		(*dv_dregs) __P((struct ispsoftc *));
6735388Smjacob	const u_int16_t *dv_ispfw;	/* ptr to f/w */
6835388Smjacob	u_int16_t 	dv_fwlen;	/* length of f/w */
6935388Smjacob	u_int16_t	dv_codeorg;	/* code ORG for f/w */
7035388Smjacob	u_int16_t	dv_fwrev;	/* f/w revision */
7135388Smjacob	/*
7235388Smjacob	 * Initial values for conf1 register
7335388Smjacob	 */
7435388Smjacob	u_int16_t	dv_conf1;
7535388Smjacob	u_int16_t	dv_clock;	/* clock frequency */
7635388Smjacob};
7735388Smjacob
7835388Smjacob#define	MAX_TARGETS	16
7935388Smjacob#define	MAX_FC_TARG	126
8035388Smjacob
8139235Sgibbs/* queue length must be a power of two */
8239235Sgibbs#define	QENTRY_LEN			64
8339235Sgibbs#define	RQUEST_QUEUE_LEN		MAXISPREQUEST
8439235Sgibbs#define	RESULT_QUEUE_LEN		(MAXISPREQUEST/4)
8539235Sgibbs#define	ISP_QUEUE_ENTRY(q, idx)		((q) + ((idx) * QENTRY_LEN))
8639235Sgibbs#define	ISP_QUEUE_SIZE(n)		((n) * QENTRY_LEN)
8739235Sgibbs#define	ISP_NXT_QENTRY(idx, qlen)	(((idx) + 1) & ((qlen)-1))
8839235Sgibbs#define ISP_QAVAIL(in, out, qlen)	\
8939235Sgibbs	((in == out)? (qlen - 1) : ((in > out)? \
9039235Sgibbs		((qlen - 1) - (in - out)) : (out - in - 1)))
9135388Smjacob/*
9235388Smjacob * SCSI (as opposed to FC-PH) Specific Host Adapter Parameters
9335388Smjacob */
9435388Smjacob
9535388Smjacobtypedef struct {
9639235Sgibbs        u_int		isp_req_ack_active_neg	: 1,
9735388Smjacob	        	isp_data_line_active_neg: 1,
9835388Smjacob			isp_cmd_dma_burst_enable: 1,
9935388Smjacob			isp_data_dma_burst_enabl: 1,
10035388Smjacob			isp_fifo_threshold	: 2,
10135388Smjacob			isp_diffmode		: 1,
10239235Sgibbs			isp_fast_mttr		: 1,
10335388Smjacob			isp_initiator_id	: 4,
10435388Smjacob        		isp_async_data_setup	: 4;
10535388Smjacob        u_int16_t	isp_selection_timeout;
10635388Smjacob        u_int16_t	isp_max_queue_depth;
10735388Smjacob	u_int16_t	isp_clock;
10835388Smjacob	u_int8_t	isp_tag_aging;
10935388Smjacob       	u_int8_t	isp_bus_reset_delay;
11035388Smjacob        u_int8_t	isp_retry_count;
11135388Smjacob        u_int8_t	isp_retry_delay;
11235388Smjacob	struct {
11339235Sgibbs		u_int	dev_update	:	1,
11439235Sgibbs			dev_enable	:	1,
11539235Sgibbs			exc_throttle	:	7,
11639235Sgibbs			sync_offset	:	4,
11739235Sgibbs			sync_period	:	8;
11839235Sgibbs		u_int16_t dev_flags;		/* persistent device flags */
11939235Sgibbs		u_int16_t cur_dflags;		/* current device flags */
12035388Smjacob	} isp_devparam[MAX_TARGETS];
12135388Smjacob} sdparam;	/* scsi device parameters */
12235388Smjacob
12335388Smjacob/*
12435388Smjacob * Device Flags
12535388Smjacob */
12639235Sgibbs#define	DPARM_DISC	0x8000
12739235Sgibbs#define	DPARM_PARITY	0x4000
12839235Sgibbs#define	DPARM_WIDE	0x2000
12939235Sgibbs#define	DPARM_SYNC	0x1000
13039235Sgibbs#define	DPARM_TQING	0x0800
13139235Sgibbs#define	DPARM_ARQ	0x0400
13239235Sgibbs#define	DPARM_QFRZ	0x0200
13339235Sgibbs#define	DPARM_RENEG	0x0100
13439235Sgibbs#define	DPARM_NARROW	0x0080	/* Possibly only available with >= 7.55 fw */
13539235Sgibbs#define	DPARM_ASYNC	0x0040	/* Possibly only available with >= 7.55 fw */
13639235Sgibbs#define	DPARM_DEFAULT	(0xFFFF & ~DPARM_QFRZ)
13739235Sgibbs#define	DPARM_SAFE_DFLT	(DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
13835388Smjacob
13939235Sgibbs
14035388Smjacob#define ISP_20M_SYNCPARMS	0x080c
14135388Smjacob#define ISP_10M_SYNCPARMS	0x0c19
14235388Smjacob#define ISP_08M_SYNCPARMS	0x0c25
14335388Smjacob#define ISP_05M_SYNCPARMS	0x0c32
14435388Smjacob#define ISP_04M_SYNCPARMS	0x0c41
14535388Smjacob
14635388Smjacob/*
14735388Smjacob * Fibre Channel Specifics
14835388Smjacob */
14935388Smjacobtypedef struct {
15035388Smjacob	u_int64_t		isp_wwn;	/* WWN of adapter */
15139235Sgibbs	u_int8_t		isp_loopid;	/* hard loop id */
15239235Sgibbs	u_int8_t		isp_alpa;	/* ALPA */
15339235Sgibbs	u_int8_t		isp_execthrottle;
15439235Sgibbs        u_int8_t		isp_retry_delay;
15535388Smjacob        u_int8_t		isp_retry_count;
15635388Smjacob	u_int8_t		isp_fwstate;	/* ISP F/W state */
15739235Sgibbs	u_int16_t		isp_maxalloc;
15839235Sgibbs	u_int16_t		isp_maxfrmlen;
15939235Sgibbs	u_int16_t		isp_fwoptions;
16035388Smjacob	/*
16135388Smjacob	 * Scratch DMA mapped in area to fetch Port Database stuff, etc.
16235388Smjacob	 */
16335388Smjacob	volatile caddr_t	isp_scratch;
16435388Smjacob	u_int32_t		isp_scdma;
16535388Smjacob} fcparam;
16635388Smjacob
16735388Smjacob#define	ISP2100_SCRLEN		0x100
16835388Smjacob
16935388Smjacob#define	FW_CONFIG_WAIT		0x0000
17035388Smjacob#define	FW_WAIT_AL_PA		0x0001
17135388Smjacob#define	FW_WAIT_LOGIN		0x0002
17235388Smjacob#define	FW_READY		0x0003
17335388Smjacob#define	FW_LOSS_OF_SYNC		0x0004
17435388Smjacob#define	FW_ERROR		0x0005
17535388Smjacob#define	FW_REINIT		0x0006
17635388Smjacob#define	FW_NON_PART		0x0007
17735388Smjacob
17835597Sbdestatic __inline char *fw_statename __P((u_int8_t x));
17935597Sbdestatic __inline char *
18035597Sbdefw_statename(x)
18135597Sbde	u_int8_t x;
18235388Smjacob{
18335388Smjacob	switch(x) {
18435388Smjacob	case FW_CONFIG_WAIT:	return "Config Wait";
18535388Smjacob	case FW_WAIT_AL_PA:	return "Waiting for AL/PA";
18635388Smjacob	case FW_WAIT_LOGIN:	return "Wait Login";
18735388Smjacob	case FW_READY:		return "Ready";
18835388Smjacob	case FW_LOSS_OF_SYNC:	return "Loss Of Sync";
18935388Smjacob	case FW_ERROR:		return "Error";
19035388Smjacob	case FW_REINIT:		return "Re-Init";
19135388Smjacob	case FW_NON_PART:	return "Nonparticipating";
19235388Smjacob	default:		return "eh?";
19335388Smjacob	}
19435388Smjacob}
19535388Smjacob
19635388Smjacob/*
19735388Smjacob * Soft Structure per host adapter
19835388Smjacob */
19935388Smjacobstruct ispsoftc {
20035388Smjacob	/*
20135388Smjacob	 * Platform (OS) specific data
20235388Smjacob	 */
20335388Smjacob	struct isposinfo	isp_osinfo;
20435388Smjacob
20535388Smjacob	/*
20635388Smjacob	 * Pointer to bus specific data
20735388Smjacob	 */
20835388Smjacob	struct ispmdvec *	isp_mdvec;
20935388Smjacob
21035388Smjacob	/*
21135388Smjacob	 * State, debugging, etc..
21235388Smjacob	 */
21335388Smjacob
21439235Sgibbs	u_int				: 8,
21539235Sgibbs			isp_confopts	: 8,
21639235Sgibbs					: 2,
21739235Sgibbs			isp_dblev	: 3,
21839235Sgibbs			isp_gotdparms	: 1,
21935388Smjacob			isp_dogactive	: 1,
22039235Sgibbs			isp_bustype	: 1,	/* BUS Implementation */
22139235Sgibbs			isp_type	: 8;	/* HBA Type and Revision */
22235388Smjacob
22339235Sgibbs	u_int16_t		isp_fwrev;	/* Running F/W revision */
22439235Sgibbs	u_int16_t		isp_romfw_rev;	/* 'ROM' F/W revision */
22539235Sgibbs	void * 			isp_param;
22639235Sgibbs
22735388Smjacob	/*
22839235Sgibbs	 * Volatile state
22935388Smjacob	 */
23035388Smjacob
23139235Sgibbs	volatile u_int
23239235Sgibbs				:	19,
23339235Sgibbs		isp_state	:	3,
23439235Sgibbs		isp_sendmarker	:	1,	/* send a marker entry */
23539235Sgibbs		isp_update	:	1,	/* update paramters */
23639235Sgibbs		isp_nactive	:	9;	/* how many commands active */
23739235Sgibbs
23835388Smjacob	/*
23939235Sgibbs	 * Result and Request Queue indices.
24035388Smjacob	 */
24139235Sgibbs	volatile u_int8_t	isp_reqodx;	/* index of last ISP pickup */
24235388Smjacob	volatile u_int8_t	isp_reqidx;	/* index of next request */
24335388Smjacob	volatile u_int8_t	isp_residx;	/* index of next result */
24439235Sgibbs	volatile u_int8_t	isp_seqno;	/* rolling sequence # */
24535388Smjacob
24635388Smjacob	/*
24735388Smjacob	 * Sheer laziness, but it gets us around the problem
24835388Smjacob	 * where we don't have a clean way of remembering
24935388Smjacob	 * which transaction is bound to which ISP queue entry.
25035388Smjacob	 *
25135388Smjacob	 * There are other more clever ways to do this, but,
25235388Smjacob	 * jeez, so I blow a couple of KB per host adapter...
25335388Smjacob	 * and it *is* faster.
25435388Smjacob	 */
25539235Sgibbs	volatile ISP_SCSI_XFER_T *isp_xflist[RQUEST_QUEUE_LEN];
25635388Smjacob
25735388Smjacob	/*
25839235Sgibbs	 * request/result queues and dma handles for them.
25935388Smjacob	 */
26035388Smjacob	volatile caddr_t	isp_rquest;
26135388Smjacob	volatile caddr_t	isp_result;
26235388Smjacob	u_int32_t		isp_rquest_dma;
26335388Smjacob	u_int32_t		isp_result_dma;
26435388Smjacob};
26535388Smjacob
26635388Smjacob/*
26735388Smjacob * ISP States
26835388Smjacob */
26935388Smjacob#define	ISP_NILSTATE	0
27035388Smjacob#define	ISP_RESETSTATE	1
27135388Smjacob#define	ISP_INITSTATE	2
27235388Smjacob#define	ISP_RUNSTATE	3
27335388Smjacob
27435388Smjacob/*
27535388Smjacob * ISP Configuration Options
27635388Smjacob */
27735388Smjacob#define	ISP_CFG_NORELOAD	0x80	/* don't download f/w */
27835388Smjacob
27939235Sgibbs#define	ISP_FW_REV(maj, min)	((maj) << 10| (min))
28039235Sgibbs
28135388Smjacob/*
28239235Sgibbs * Bus (implementation) types
28335388Smjacob */
28439235Sgibbs#define	ISP_BT_PCI		0	/* PCI Implementations */
28539235Sgibbs#define	ISP_BT_SBUS		1	/* SBus Implementations */
28639235Sgibbs
28739235Sgibbs/*
28839235Sgibbs * Chip Types
28939235Sgibbs */
29035388Smjacob#define	ISP_HA_SCSI		0xf
29139235Sgibbs#define	ISP_HA_SCSI_UNKNOWN	0x1
29239235Sgibbs#define	ISP_HA_SCSI_1020	0x2
29339235Sgibbs#define	ISP_HA_SCSI_1020A	0x3
29439235Sgibbs#define	ISP_HA_SCSI_1040	0x4
29539235Sgibbs#define	ISP_HA_SCSI_1040A	0x5
29639235Sgibbs#define	ISP_HA_SCSI_1040B	0x6
29735388Smjacob#define	ISP_HA_FC		0xf0
29835388Smjacob#define	ISP_HA_FC_2100		0x10
29935388Smjacob
30035388Smjacob/*
30135388Smjacob * Macros to read, write ISP registers through MD code
30235388Smjacob */
30335388Smjacob
30435388Smjacob#define	ISP_READ(isp, reg)	\
30535388Smjacob	(*(isp)->isp_mdvec->dv_rd_reg)((isp), (reg))
30635388Smjacob
30735388Smjacob#define	ISP_WRITE(isp, reg, val)	\
30835388Smjacob	(*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), (val))
30935388Smjacob
31035388Smjacob#define	ISP_MBOXDMASETUP(isp)	\
31135388Smjacob	(*(isp)->isp_mdvec->dv_mbxdma)((isp))
31235388Smjacob
31335388Smjacob#define	ISP_DMASETUP(isp, xs, req, iptrp, optr)	\
31435388Smjacob	(*(isp)->isp_mdvec->dv_dmaset)((isp), (xs), (req), (iptrp), (optr))
31535388Smjacob
31635388Smjacob#define	ISP_DMAFREE(isp, xs, seqno)	\
31735388Smjacob	if ((isp)->isp_mdvec->dv_dmaclr) \
31835388Smjacob		 (*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (seqno))
31935388Smjacob
32035388Smjacob#define	ISP_RESET0(isp)	\
32135388Smjacob	if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp))
32235388Smjacob#define	ISP_RESET1(isp)	\
32335388Smjacob	if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp))
32435388Smjacob#define	ISP_DUMPREGS(isp)	\
32535388Smjacob	if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp))
32635388Smjacob
32735388Smjacob#define	ISP_SETBITS(isp, reg, val)	\
32835388Smjacob (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val))
32935388Smjacob
33035388Smjacob#define	ISP_CLRBITS(isp, reg, val)	\
33135388Smjacob (*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val))
33235388Smjacob
33335388Smjacob/*
33435388Smjacob * Function Prototypes
33535388Smjacob */
33635388Smjacob
33735388Smjacob/*
33839235Sgibbs * Reset Hardware. Totally. Assumes that you'll follow this with
33939235Sgibbs * a call to isp_init.
34035388Smjacob */
34135388Smjacobvoid isp_reset __P((struct ispsoftc *));
34235388Smjacob
34335388Smjacob/*
34435388Smjacob * Initialize Hardware to known state
34535388Smjacob */
34635388Smjacobvoid isp_init __P((struct ispsoftc *));
34735388Smjacob
34835388Smjacob/*
34935388Smjacob * Free any associated resources prior to decommissioning.
35035388Smjacob */
35135388Smjacobvoid isp_uninit __P((struct ispsoftc *));
35235388Smjacob
35335388Smjacob/*
35439235Sgibbs * Reset the ISP and call completion for any orphaned commands.
35539235Sgibbs */
35639235Sgibbsvoid isp_restart __P((struct ispsoftc *));
35739235Sgibbs
35839235Sgibbs/*
35935388Smjacob * Interrupt Service Routine
36035388Smjacob */
36135388Smjacobint isp_intr __P((void *));
36235388Smjacob
36335388Smjacob/*
36435388Smjacob * Watchdog Routine
36535388Smjacob */
36635388Smjacobvoid isp_watch __P((void *));
36735388Smjacob
36835388Smjacob/*
36935388Smjacob * Command Entry Point
37035388Smjacob */
37139235Sgibbsint32_t ispscsicmd __P((ISP_SCSI_XFER_T *));
37235388Smjacob
37339235Sgibbs/*
37439235Sgibbs * Platform Dependent to Internal Control Point
37539235Sgibbs *
37639235Sgibbs * For: 	Aborting a running command	- arg is an ISP_SCSI_XFER_T *
37739235Sgibbs *		Resetting a Device		- arg is target to reset
37839235Sgibbs *		Resetting a BUS			- arg is ignored
37939235Sgibbs *		Updating parameters		- arg is ignored
38039235Sgibbs *
38139235Sgibbs * Second argument is an index into xflist array.
38239235Sgibbs * Assumes all locks must be held already.
38339235Sgibbs */
38439235Sgibbstypedef enum {
38539235Sgibbs	ISPCTL_RESET_BUS,
38639235Sgibbs	ISPCTL_RESET_DEV,
38739235Sgibbs	ISPCTL_ABORT_CMD,
38839235Sgibbs	ISPCTL_UPDATE_PARAMS,
38939235Sgibbs} ispctl_t;
39039235Sgibbsint isp_control __P((struct ispsoftc *, ispctl_t, void *));
39139235Sgibbs
39239235Sgibbs/*
39339235Sgibbs * lost command routine (XXXX IN TRANSITION XXXX)
39439235Sgibbs */
39539235Sgibbsvoid isp_lostcmd __P((struct ispsoftc *, ISP_SCSI_XFER_T *));
39639235Sgibbs
39739235Sgibbs
39835388Smjacob#endif	/* _ISPVAR_H */
399