isp_freebsd.h revision 102272
150477Speter/* $FreeBSD: head/sys/dev/isp/isp_freebsd.h 102272 2002-08-22 16:14:19Z mjacob $ */
235388Smjacob/*
380313Smjacob * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions
499599Smjacob * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 by Matthew Jacob
535388Smjacob *
635388Smjacob * Redistribution and use in source and binary forms, with or without
735388Smjacob * modification, are permitted provided that the following conditions
835388Smjacob * are met:
935388Smjacob * 1. Redistributions of source code must retain the above copyright
1035388Smjacob *    notice immediately at the beginning of the file, without modification,
1135388Smjacob *    this list of conditions, and the following disclaimer.
1266189Smjacob * 2. The name of the author may not be used to endorse or promote products
1366189Smjacob *    derived from this software without specific prior written permission.
1435388Smjacob *
1535388Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1635388Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1735388Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1835388Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
1935388Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2035388Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2135388Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2235388Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2335388Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2435388Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2535388Smjacob * SUCH DAMAGE.
2635388Smjacob */
2735388Smjacob#ifndef	_ISP_FREEBSD_H
2835388Smjacob#define	_ISP_FREEBSD_H
2935388Smjacob
3058100Smjacob#define	ISP_PLATFORM_VERSION_MAJOR	5
3180313Smjacob#define	ISP_PLATFORM_VERSION_MINOR	9
3239235Sgibbs
3339445Smjacob#include <sys/param.h>
3448487Smjacob#include <sys/systm.h>
3595533Smike#include <sys/endian.h>
3648487Smjacob#include <sys/kernel.h>
3748487Smjacob#include <sys/queue.h>
3874914Sjhb#include <sys/lock.h>
3959452Smjacob#include <sys/malloc.h>
4067365Sjhb#include <sys/mutex.h>
4177365Smjacob#include <sys/condvar.h>
4262496Smjacob#include <sys/proc.h>
4373246Smjacob#include <sys/bus.h>
4439445Smjacob
4548487Smjacob#include <machine/bus_memio.h>
4648487Smjacob#include <machine/bus_pio.h>
4748487Smjacob#include <machine/bus.h>
4848487Smjacob#include <machine/clock.h>
4962496Smjacob#include <machine/cpu.h>
5039445Smjacob
5148487Smjacob#include <cam/cam.h>
5248487Smjacob#include <cam/cam_debug.h>
5348487Smjacob#include <cam/cam_ccb.h>
5448487Smjacob#include <cam/cam_sim.h>
5548487Smjacob#include <cam/cam_xpt.h>
5648487Smjacob#include <cam/cam_xpt_sim.h>
5748487Smjacob#include <cam/cam_debug.h>
5848487Smjacob#include <cam/scsi/scsi_all.h>
5948487Smjacob#include <cam/scsi/scsi_message.h>
6048487Smjacob
6152348Smjacob#include "opt_ddb.h"
6248487Smjacob#include "opt_isp.h"
63102272Smjacob
64102272Smjacob#define	ISP_DMA_ADDR_T	bus_addr_t
65102272Smjacob
6687635Smjacob/*
6787635Smjacob * Efficiency- get rid of SBus code && tests unless we need them.
6887635Smjacob */
6993706Smjacob#if	_MACHINE_ARCH == sparc64
7087635Smjacob#define	ISP_SBUS_SUPPORTED	1
7187635Smjacob#else
7287635Smjacob#define	ISP_SBUS_SUPPORTED	0
7387635Smjacob#endif
7439235Sgibbs
7577365Smjacob#define	HANDLE_LOOPSTATE_IN_OUTER_LAYERS	1
76100680Smjacob#define	ISP_SMPLOCK				1
7777365Smjacob
78100680Smjacob#ifdef	ISP_SMPLOCK
79100680Smjacob#define	ISP_IFLAGS	INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE
80100680Smjacob#else
81100680Smjacob#define	ISP_IFLAGS	INTR_TYPE_CAM | INTR_ENTROPY
82100680Smjacob#endif
83100680Smjacob
8492739Salfredtypedef void ispfwfunc(int, int, int, u_int16_t **);
8555366Smjacob
8655366Smjacob#ifdef	ISP_TARGET_MODE
8787635Smjacob#define	ISP_TARGET_FUNCTIONS	1
8884242Smjacob#define	ATPDPSIZE	256
8984242Smjacobtypedef struct {
9084242Smjacob	u_int32_t	orig_datalen;
9184242Smjacob	u_int32_t	bytes_xfered;
9284242Smjacob	u_int32_t	last_xframt;
9398288Smjacob	u_int32_t	tag	: 16,
9498288Smjacob			lun	: 13,	/* not enough */
9598288Smjacob			state	: 3;
9684242Smjacob} atio_private_data_t;
9798288Smjacob#define	ATPD_STATE_FREE			0
9898288Smjacob#define	ATPD_STATE_ATIO			1
9998288Smjacob#define	ATPD_STATE_CAM			2
10098288Smjacob#define	ATPD_STATE_CTIO			3
10198288Smjacob#define	ATPD_STATE_LAST_CTIO		4
10298288Smjacob#define	ATPD_STATE_PDON			5
10384242Smjacob
10455366Smjacobtypedef struct tstate {
10555366Smjacob	struct tstate *next;
10655366Smjacob	struct cam_path *owner;
10755366Smjacob	struct ccb_hdr_slist atios;
10855366Smjacob	struct ccb_hdr_slist inots;
10955366Smjacob	lun_id_t lun;
11075198Smjacob	int bus;
11155366Smjacob	u_int32_t hold;
11298288Smjacob	int atio_count;
11355366Smjacob} tstate_t;
11455366Smjacob
11575198Smjacob#define	LUN_HASH_SIZE			32
11675198Smjacob#define	LUN_HASH_FUNC(isp, port, lun)					\
11775198Smjacob	((IS_DUALBUS(isp)) ?						\
11875198Smjacob		(((lun) & ((LUN_HASH_SIZE >> 1) - 1)) << (port)) :	\
11975198Smjacob		((lun) & (LUN_HASH_SIZE - 1)))
12055366Smjacob#endif
12155366Smjacob
12235388Smjacobstruct isposinfo {
12355366Smjacob	struct ispsoftc *	next;
12473246Smjacob	u_int64_t		default_port_wwn;
12573246Smjacob	u_int64_t		default_node_wwn;
12699598Smjacob	u_int32_t		default_id;
12773246Smjacob	device_t		dev;
12848487Smjacob	struct cam_sim		*sim;
12948487Smjacob	struct cam_path		*path;
13048487Smjacob	struct cam_sim		*sim2;
13148487Smjacob	struct cam_path		*path2;
13262496Smjacob	struct intr_config_hook	ehook;
13399598Smjacob	u_int8_t		: 1,
13499598Smjacob		fcbsy		: 1,
13599598Smjacob		ktmature	: 1,
13699598Smjacob		mboxwaiting	: 1,
13799598Smjacob		intsok		: 1,
13899598Smjacob		simqfrozen	: 3;
13967258Smjacob	struct mtx		lock;
14077365Smjacob	struct cv		kthread_cv;
14177365Smjacob	struct proc		*kproc;
14293706Smjacob	bus_dma_tag_t		cdmat;
14393706Smjacob	bus_dmamap_t		cdmap;
14493706Smjacob#define	isp_cdmat		isp_osinfo.cdmat
14593706Smjacob#define	isp_cdmap		isp_osinfo.cdmap
14655366Smjacob#ifdef	ISP_TARGET_MODE
14775198Smjacob#define	TM_WANTED		0x80
14875198Smjacob#define	TM_BUSY			0x40
14983025Smjacob#define	TM_WILDCARD_ENABLED	0x02
15083025Smjacob#define	TM_TMODE_ENABLED	0x01
15183025Smjacob	struct cv		tgtcv0[2];	/* two busses */
15283025Smjacob	struct cv		tgtcv1[2];	/* two busses */
15383025Smjacob	u_int8_t		tmflags[2];	/* two busses */
15483025Smjacob	u_int8_t		rstatus[2];	/* two bussed */
15555366Smjacob	u_int16_t		rollinfo;
15675198Smjacob	tstate_t		tsdflt[2];	/* two busses */
15755366Smjacob	tstate_t		*lun_hash[LUN_HASH_SIZE];
15884242Smjacob	atio_private_data_t	atpdp[ATPDPSIZE];
15955366Smjacob#endif
16035388Smjacob};
16139235Sgibbs
16277365Smjacob#define	isp_lock	isp_osinfo.lock
16377365Smjacob
16464092Smjacob/*
16569525Smjacob * Locking macros...
16669525Smjacob */
16769525Smjacob
16877365Smjacob#define	ISP_LOCK(x)		mtx_lock(&(x)->isp_lock)
16977365Smjacob#define	ISP_UNLOCK(x)		mtx_unlock(&(x)->isp_lock)
17077365Smjacob#define	ISPLOCK_2_CAMLOCK(isp)	\
17177365Smjacob	mtx_unlock(&(isp)->isp_lock); mtx_lock(&Giant)
17277365Smjacob#define	CAMLOCK_2_ISPLOCK(isp)	\
17377365Smjacob	mtx_unlock(&Giant); mtx_lock(&(isp)->isp_lock)
17469525Smjacob
17569525Smjacob/*
17664092Smjacob * Required Macros/Defines
17764092Smjacob */
17848487Smjacob
17964092Smjacob#define	INLINE			__inline
18048487Smjacob
18193837Smjacob#define	ISP2100_SCRLEN		0x800
18245284Smjacob
18364092Smjacob#define	MEMZERO			bzero
18464092Smjacob#define	MEMCPY(dst, src, amt)	bcopy((src), (dst), (amt))
18564092Smjacob#define	SNPRINTF		snprintf
18664092Smjacob#define	STRNCAT			strncat
18764092Smjacob#define	USEC_DELAY		DELAY
18869598Smjacob#define	USEC_SLEEP(isp, x)		\
18969598Smjacob	if (isp->isp_osinfo.intsok)	\
19069598Smjacob		ISP_UNLOCK(isp);	\
19169598Smjacob	DELAY(x);			\
19269598Smjacob	if (isp->isp_osinfo.intsok)	\
19369598Smjacob		ISP_LOCK(isp)
19435388Smjacob
19564092Smjacob#define	NANOTIME_T		struct timespec
19664092Smjacob#define	GET_NANOTIME		nanotime
19764092Smjacob#define	GET_NANOSEC(x)		((x)->tv_sec * 1000000000 + (x)->tv_nsec)
19864092Smjacob#define	NANOTIME_SUB		nanotime_sub
19962496Smjacob
20099598Smjacob#define	MAXISPREQUEST(isp)	((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256)
20162496Smjacob
20293706Smjacob#define	MEMORYBARRIER(isp, type, offset, size)			\
20393706Smjacobswitch (type) {							\
20493706Smjacobcase SYNC_SFORDEV:						\
20593706Smjacobcase SYNC_REQUEST:						\
20693706Smjacob	bus_dmamap_sync(isp->isp_cdmat, isp->isp_cdmap, 	\
20793706Smjacob	   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		\
20893706Smjacob	break;							\
20993706Smjacobcase SYNC_SFORCPU:						\
21093706Smjacobcase SYNC_RESULT:						\
21193706Smjacob	bus_dmamap_sync(isp->isp_cdmat, isp->isp_cdmap,		\
21293706Smjacob	   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);	\
21393706Smjacob	break;							\
21493706Smjacobdefault:							\
21593706Smjacob	break;							\
21693706Smjacob}
21762496Smjacob
21864092Smjacob#define	MBOX_ACQUIRE(isp)
21964092Smjacob#define	MBOX_WAIT_COMPLETE		isp_mbox_wait_complete
22062496Smjacob#define	MBOX_NOTIFY_COMPLETE(isp)	\
22162496Smjacob	if (isp->isp_osinfo.mboxwaiting) { \
22262496Smjacob		isp->isp_osinfo.mboxwaiting = 0; \
22399598Smjacob		wakeup(&isp->isp_mbxworkp); \
22462496Smjacob	} \
22562496Smjacob	isp->isp_mboxbsy = 0
22664092Smjacob#define	MBOX_RELEASE(isp)
22762496Smjacob
22899598Smjacob#define	FC_SCRATCH_ACQUIRE(isp)						\
22999598Smjacob	if (isp->isp_osinfo.fcbsy) {					\
23099598Smjacob		isp_prt(isp, ISP_LOGWARN,				\
23199598Smjacob		    "FC scratch area busy (line %d)!", __LINE__);	\
23299598Smjacob	} else								\
23399598Smjacob		isp->isp_osinfo.fcbsy = 1
23499598Smjacob#define	FC_SCRATCH_RELEASE(isp)		 isp->isp_osinfo.fcbsy = 0
23590224Smjacob
23664092Smjacob#ifndef	SCSI_GOOD
23764092Smjacob#define	SCSI_GOOD	SCSI_STATUS_OK
23864092Smjacob#endif
23964092Smjacob#ifndef	SCSI_CHECK
24064092Smjacob#define	SCSI_CHECK	SCSI_STATUS_CHECK_COND
24164092Smjacob#endif
24264092Smjacob#ifndef	SCSI_BUSY
24364092Smjacob#define	SCSI_BUSY	SCSI_STATUS_BUSY
24464092Smjacob#endif
24564092Smjacob#ifndef	SCSI_QFULL
24664092Smjacob#define	SCSI_QFULL	SCSI_STATUS_QUEUE_FULL
24764092Smjacob#endif
24864092Smjacob
24964092Smjacob#define	XS_T			struct ccb_scsiio
25048487Smjacob#define	XS_ISP(ccb)		((struct ispsoftc *) (ccb)->ccb_h.spriv_ptr1)
25164092Smjacob#define	XS_CHANNEL(ccb)		cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path))
25264092Smjacob#define	XS_TGT(ccb)		(ccb)->ccb_h.target_id
25364092Smjacob#define	XS_LUN(ccb)		(ccb)->ccb_h.target_lun
25435388Smjacob
25564092Smjacob#define	XS_CDBP(ccb)	\
25664092Smjacob	(((ccb)->ccb_h.flags & CAM_CDB_POINTER)? \
25764092Smjacob	 (ccb)->cdb_io.cdb_ptr : (ccb)->cdb_io.cdb_bytes)
25864092Smjacob
25964092Smjacob#define	XS_CDBLEN(ccb)		(ccb)->cdb_len
26048487Smjacob#define	XS_XFRLEN(ccb)		(ccb)->dxfer_len
26148487Smjacob#define	XS_TIME(ccb)		(ccb)->ccb_h.timeout
26264092Smjacob#define	XS_RESID(ccb)		(ccb)->resid
26364092Smjacob#define	XS_STSP(ccb)		(&(ccb)->scsi_status)
26448487Smjacob#define	XS_SNSP(ccb)		(&(ccb)->sense_data)
26564092Smjacob
26652348Smjacob#define	XS_SNSLEN(ccb)		\
26752348Smjacob	imin((sizeof((ccb)->sense_data)), ccb->sense_len)
26864092Smjacob
26948487Smjacob#define	XS_SNSKEY(ccb)		((ccb)->sense_data.flags & 0xf)
27064092Smjacob#define	XS_TAG_P(ccb)	\
27164092Smjacob	(((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID) && \
27264092Smjacob	 (ccb)->tag_action != CAM_TAG_ACTION_NONE)
27335388Smjacob
27464092Smjacob#define	XS_TAG_TYPE(ccb)	\
27564092Smjacob	((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \
27664092Smjacob	 ((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG))
27764092Smjacob
27864092Smjacob
27964092Smjacob#define	XS_SETERR(ccb, v)	(ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \
28064092Smjacob				(ccb)->ccb_h.status |= v, \
28164092Smjacob				(ccb)->ccb_h.spriv_field0 |= ISP_SPRIV_ERRSET
28264092Smjacob
28364092Smjacob#	define	HBA_NOERROR		CAM_REQ_INPROG
28464092Smjacob#	define	HBA_BOTCH		CAM_UNREC_HBA_ERROR
28564092Smjacob#	define	HBA_CMDTIMEOUT		CAM_CMD_TIMEOUT
28664092Smjacob#	define	HBA_SELTIMEOUT		CAM_SEL_TIMEOUT
28764092Smjacob#	define	HBA_TGTBSY		CAM_SCSI_STATUS_ERROR
28864092Smjacob#	define	HBA_BUSRESET		CAM_SCSI_BUS_RESET
28964092Smjacob#	define	HBA_ABORTED		CAM_REQ_ABORTED
29064092Smjacob#	define	HBA_DATAOVR		CAM_DATA_RUN_ERR
29164092Smjacob#	define	HBA_ARQFAIL		CAM_AUTOSENSE_FAIL
29264092Smjacob
29364092Smjacob
29464092Smjacob#define	XS_ERR(ccb)		((ccb)->ccb_h.status & CAM_STATUS_MASK)
29564092Smjacob
29664092Smjacob#define	XS_NOERR(ccb)		\
29764092Smjacob	(((ccb)->ccb_h.spriv_field0 & ISP_SPRIV_ERRSET) == 0 || \
29864092Smjacob	 ((ccb)->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)
29964092Smjacob
30064092Smjacob#define	XS_INITERR(ccb)		\
30164092Smjacob	XS_SETERR(ccb, CAM_REQ_INPROG), (ccb)->ccb_h.spriv_field0 = 0
30264092Smjacob
30364092Smjacob#define	XS_SAVE_SENSE(xs, sp)				\
30471076Smjacob	(xs)->ccb_h.status |= CAM_AUTOSNS_VALID,	\
30564092Smjacob	bcopy(sp->req_sense_data, &(xs)->sense_data,	\
30664092Smjacob	    imin(XS_SNSLEN(xs), sp->req_sense_len))
30764092Smjacob
30864092Smjacob#define	XS_SET_STATE_STAT(a, b, c)
30964092Smjacob
31099598Smjacob#define	DEFAULT_IID(x)		(isp)->isp_osinfo.default_id
31199598Smjacob#define	DEFAULT_LOOPID(x)	(isp)->isp_osinfo.default_id
31273246Smjacob#define	DEFAULT_NODEWWN(isp)	(isp)->isp_osinfo.default_node_wwn
31373246Smjacob#define	DEFAULT_PORTWWN(isp)	(isp)->isp_osinfo.default_port_wwn
31467049Smjacob#define	ISP_NODEWWN(isp)	FCPARAM(isp)->isp_nodewwn
31567049Smjacob#define	ISP_PORTWWN(isp)	FCPARAM(isp)->isp_portwwn
31664092Smjacob
31787635Smjacob#if	BYTE_ORDER == BIG_ENDIAN
31887635Smjacob#ifdef	ISP_SBUS_SUPPORTED
31987635Smjacob#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
32087635Smjacob#define	ISP_IOXPUT_16(isp, s, d)				\
32187635Smjacob	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap16(s)
32287635Smjacob#define	ISP_IOXPUT_32(isp, s, d)				\
32387635Smjacob	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap32(s)
32487635Smjacob#define	ISP_IOXGET_8(isp, s, d)		d = (*((u_int8_t *)s))
32587635Smjacob#define	ISP_IOXGET_16(isp, s, d)				\
32687635Smjacob	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
32787635Smjacob	*((u_int16_t *)s) : bswap16(*((u_int16_t *)s))
32887635Smjacob#define	ISP_IOXGET_32(isp, s, d)				\
32987635Smjacob	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
33087635Smjacob	*((u_int32_t *)s) : bswap32(*((u_int32_t *)s))
33187635Smjacob#else
33287635Smjacob#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
33387635Smjacob#define	ISP_IOXPUT_16(isp, s, d)	*(d) = bswap16(s)
33487635Smjacob#define	ISP_IOXPUT_32(isp, s, d)	*(d) = bswap32(s)
33587635Smjacob#define	ISP_IOXGET_8(isp, s, d)		d = (*((u_int8_t *)s))
33687635Smjacob#define	ISP_IOXGET_16(isp, s, d)	d = bswap16(*((u_int16_t *)s))
33787635Smjacob#define	ISP_IOXGET_32(isp, s, d)	d = bswap32(*((u_int32_t *)s))
33887635Smjacob#endif
33987635Smjacob#define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)	*rp = bswap16(*rp)
34087635Smjacob#else
34187635Smjacob#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
34287635Smjacob#define	ISP_IOXPUT_16(isp, s, d)	*(d) = s
34387635Smjacob#define	ISP_IOXPUT_32(isp, s, d)	*(d) = s
34487635Smjacob#define	ISP_IOXGET_8(isp, s, d)		d = *(s)
34587635Smjacob#define	ISP_IOXGET_16(isp, s, d)	d = *(s)
34687635Smjacob#define	ISP_IOXGET_32(isp, s, d)	d = *(s)
34787635Smjacob#define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)
34887635Smjacob#endif
34964092Smjacob
35048487Smjacob/*
35164092Smjacob * Includes of common header files
35248487Smjacob */
35335388Smjacob
35464092Smjacob#include <dev/isp/ispreg.h>
35564092Smjacob#include <dev/isp/ispvar.h>
35664092Smjacob#include <dev/isp/ispmbox.h>
35735388Smjacob
35864092Smjacob/*
35964092Smjacob * isp_osinfo definiitions && shorthand
36064092Smjacob */
36164092Smjacob#define	SIMQFRZ_RESOURCE	0x1
36264092Smjacob#define	SIMQFRZ_LOOPDOWN	0x2
36364092Smjacob#define	SIMQFRZ_TIMED		0x4
36464092Smjacob
36564092Smjacob#define	isp_sim		isp_osinfo.sim
36664092Smjacob#define	isp_path	isp_osinfo.path
36764092Smjacob#define	isp_sim2	isp_osinfo.sim2
36864092Smjacob#define	isp_path2	isp_osinfo.path2
36973246Smjacob#define	isp_dev		isp_osinfo.dev
37064092Smjacob
37164092Smjacob/*
37264092Smjacob * prototypes for isp_pci && isp_freebsd to share
37364092Smjacob */
37464092Smjacobextern void isp_attach(struct ispsoftc *);
37564092Smjacobextern void isp_uninit(struct ispsoftc *);
37664092Smjacob
37764092Smjacob/*
37899756Smjacob * driver global data
37999756Smjacob */
38099756Smjacobextern int isp_announced;
38199756Smjacob
38299756Smjacob/*
38364092Smjacob * Platform private flags
38464092Smjacob */
38562172Smjacob#define	ISP_SPRIV_ERRSET	0x1
38662172Smjacob#define	ISP_SPRIV_INWDOG	0x2
38762172Smjacob#define	ISP_SPRIV_GRACE		0x4
38862172Smjacob#define	ISP_SPRIV_DONE		0x8
38962172Smjacob
39062172Smjacob#define	XS_CMD_S_WDOG(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_INWDOG
39162172Smjacob#define	XS_CMD_C_WDOG(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_INWDOG
39262172Smjacob#define	XS_CMD_WDOG_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_INWDOG)
39362172Smjacob
39462172Smjacob#define	XS_CMD_S_GRACE(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_GRACE
39562172Smjacob#define	XS_CMD_C_GRACE(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_GRACE
39662172Smjacob#define	XS_CMD_GRACE_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_GRACE)
39762172Smjacob
39862172Smjacob#define	XS_CMD_S_DONE(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_DONE
39962172Smjacob#define	XS_CMD_C_DONE(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_DONE
40062172Smjacob#define	XS_CMD_DONE_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_DONE)
40162172Smjacob
40262172Smjacob#define	XS_CMD_S_CLEAR(sccb)	(sccb)->ccb_h.spriv_field0 = 0
40339235Sgibbs/*
40464092Smjacob * Platform specific inline functions
40539235Sgibbs */
40644819Smjacob
40764092Smjacobstatic INLINE void isp_mbox_wait_complete(struct ispsoftc *);
40864092Smjacobstatic INLINE void
40964092Smjacobisp_mbox_wait_complete(struct ispsoftc *isp)
41064092Smjacob{
41167258Smjacob	if (isp->isp_osinfo.intsok) {
41290224Smjacob		int lim = ((isp->isp_mbxwrk0)? 120 : 20) * hz;
41367258Smjacob		isp->isp_osinfo.mboxwaiting = 1;
41499598Smjacob		(void) msleep(&isp->isp_mbxworkp,
41590224Smjacob		    &isp->isp_lock, PRIBIO, "isp_mboxwaiting", lim);
41667258Smjacob		if (isp->isp_mboxbsy != 0) {
41770823Smjacob			isp_prt(isp, ISP_LOGWARN,
41870823Smjacob			    "Interrupting Mailbox Command (0x%x) Timeout",
41971076Smjacob			    isp->isp_lastmbxcmd);
42067258Smjacob			isp->isp_mboxbsy = 0;
42167258Smjacob		}
42267258Smjacob		isp->isp_osinfo.mboxwaiting = 0;
42367258Smjacob	} else {
42490224Smjacob		int lim = ((isp->isp_mbxwrk0)? 240 : 60) * 10000;
42564092Smjacob		int j;
42690224Smjacob		for (j = 0; j < lim; j++) {
42782689Smjacob			u_int16_t isr, sema, mbox;
42864092Smjacob			if (isp->isp_mboxbsy == 0) {
42964092Smjacob				break;
43064092Smjacob			}
43182689Smjacob			if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
43282689Smjacob				isp_intr(isp, isr, sema, mbox);
43382689Smjacob				if (isp->isp_mboxbsy == 0) {
43482689Smjacob					break;
43582689Smjacob				}
43682689Smjacob			}
43782689Smjacob			USEC_DELAY(500);
43864092Smjacob		}
43964092Smjacob		if (isp->isp_mboxbsy != 0) {
44070823Smjacob			isp_prt(isp, ISP_LOGWARN,
44170823Smjacob			    "Polled Mailbox Command (0x%x) Timeout",
44271076Smjacob			    isp->isp_lastmbxcmd);
44364092Smjacob		}
44464092Smjacob	}
44564092Smjacob}
44644819Smjacob
44764092Smjacobstatic INLINE u_int64_t nanotime_sub(struct timespec *, struct timespec *);
44864092Smjacobstatic INLINE u_int64_t
44964092Smjacobnanotime_sub(struct timespec *b, struct timespec *a)
45064092Smjacob{
45164092Smjacob	u_int64_t elapsed;
45264092Smjacob	struct timespec x = *b;
45364092Smjacob	timespecsub(&x, a);
45464092Smjacob	elapsed = GET_NANOSEC(&x);
45564092Smjacob	if (elapsed == 0)
45664092Smjacob		elapsed++;
45764092Smjacob	return (elapsed);
45864092Smjacob}
45944819Smjacob
46064092Smjacobstatic INLINE char *strncat(char *, const char *, size_t);
46164092Smjacobstatic INLINE char *
46262496Smjacobstrncat(char *d, const char *s, size_t c)
46362496Smjacob{
46462496Smjacob        char *t = d;
46544819Smjacob
46662496Smjacob        if (c) {
46762496Smjacob                while (*d)
46862496Smjacob                        d++;
46962496Smjacob                while ((*d++ = *s++)) {
47062496Smjacob                        if (--c == 0) {
47162496Smjacob                                *d = '\0';
47262496Smjacob                                break;
47362496Smjacob                        }
47462496Smjacob                }
47562496Smjacob        }
47662496Smjacob        return (t);
47762496Smjacob}
47862496Smjacob
47964092Smjacob/*
48064092Smjacob * Common inline functions
48164092Smjacob */
48244819Smjacob
48352348Smjacob#include <dev/isp/isp_inline.h>
48435388Smjacob#endif	/* _ISP_FREEBSD_H */
485