150477Speter/* $FreeBSD: stable/10/sys/dev/isp/isp_freebsd.h 317366 2017-04-24 11:21:32Z mav $ */
2139749Simp/*-
380313Smjacob * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions
435388Smjacob *
5196008Smjacob * Copyright (c) 1997-2008 by Matthew Jacob
6154704Smjacob * All rights reserved.
7154704Smjacob *
835388Smjacob * Redistribution and use in source and binary forms, with or without
935388Smjacob * modification, are permitted provided that the following conditions
1035388Smjacob * are met:
1135388Smjacob * 1. Redistributions of source code must retain the above copyright
1235388Smjacob *    notice immediately at the beginning of the file, without modification,
1335388Smjacob *    this list of conditions, and the following disclaimer.
1466189Smjacob * 2. The name of the author may not be used to endorse or promote products
1566189Smjacob *    derived from this software without specific prior written permission.
1635388Smjacob *
1735388Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1835388Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1935388Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2035388Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2135388Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2235388Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2335388Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2435388Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2535388Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2635388Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2735388Smjacob * SUCH DAMAGE.
2835388Smjacob */
2935388Smjacob#ifndef	_ISP_FREEBSD_H
3035388Smjacob#define	_ISP_FREEBSD_H
3135388Smjacob
3239445Smjacob#include <sys/param.h>
3348487Smjacob#include <sys/systm.h>
3495533Smike#include <sys/endian.h>
35298962Smav#include <sys/jail.h>
3674914Sjhb#include <sys/lock.h>
37157943Smjacob#include <sys/kernel.h>
38157943Smjacob#include <sys/queue.h>
3959452Smjacob#include <sys/malloc.h>
4067365Sjhb#include <sys/mutex.h>
4177365Smjacob#include <sys/condvar.h>
42292598Smav#include <sys/rman.h>
43227126Smjacob#include <sys/sysctl.h>
44157943Smjacob
4562496Smjacob#include <sys/proc.h>
4673246Smjacob#include <sys/bus.h>
47224804Smjacob#include <sys/taskqueue.h>
4839445Smjacob
4948487Smjacob#include <machine/bus.h>
5062496Smjacob#include <machine/cpu.h>
51196008Smjacob#include <machine/stdarg.h>
5239445Smjacob
5348487Smjacob#include <cam/cam.h>
5448487Smjacob#include <cam/cam_debug.h>
5548487Smjacob#include <cam/cam_ccb.h>
5648487Smjacob#include <cam/cam_sim.h>
5748487Smjacob#include <cam/cam_xpt.h>
5848487Smjacob#include <cam/cam_xpt_sim.h>
5948487Smjacob#include <cam/cam_debug.h>
6048487Smjacob#include <cam/scsi/scsi_all.h>
6148487Smjacob#include <cam/scsi/scsi_message.h>
6248487Smjacob
6352348Smjacob#include "opt_ddb.h"
6448487Smjacob#include "opt_isp.h"
65102272Smjacob
66196008Smjacob#define	ISP_PLATFORM_VERSION_MAJOR	7
67237537Smjacob#define	ISP_PLATFORM_VERSION_MINOR	10
68158656Smjacob
6987635Smjacob/*
7087635Smjacob * Efficiency- get rid of SBus code && tests unless we need them.
7187635Smjacob */
72153072Sru#ifdef __sparc64__
7387635Smjacob#define	ISP_SBUS_SUPPORTED	1
7487635Smjacob#else
7587635Smjacob#define	ISP_SBUS_SUPPORTED	0
7687635Smjacob#endif
7739235Sgibbs
78100680Smjacob#define	ISP_IFLAGS	INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE
79100680Smjacob
80238869Smjacob#define	N_XCMDS		64
81238869Smjacob#define	XCMD_SIZE	512
82238869Smjacobstruct ispsoftc;
83238869Smjacobtypedef union isp_ecmd {
84238869Smjacob	union isp_ecmd *	next;
85238869Smjacob	uint8_t			data[XCMD_SIZE];
86238869Smjacob} isp_ecmd_t;
87238869Smjacobisp_ecmd_t *	isp_get_ecmd(struct ispsoftc *);
88238869Smjacobvoid		isp_put_ecmd(struct ispsoftc *, isp_ecmd_t *);
89238869Smjacob
9055366Smjacob#ifdef	ISP_TARGET_MODE
91196008Smjacob#define	ATPDPSIZE	4096
92276233Smav#define	ATPDPHASHSIZE	32
93260341Smav#define	ATPDPHASH(x)	((((x) >> 24) ^ ((x) >> 16) ^ ((x) >> 8) ^ (x)) &  \
94260341Smav			    ((ATPDPHASHSIZE) - 1))
95196008Smjacob
96196008Smjacob#include <dev/isp/isp_target.h>
97260341Smavtypedef struct atio_private_data {
98260341Smav	LIST_ENTRY(atio_private_data)	next;
99155704Smjacob	uint32_t	orig_datalen;
100155704Smjacob	uint32_t	bytes_xfered;
101239143Smjacob	uint32_t	bytes_in_transit;
102237537Smjacob	uint32_t	tag;		/* typically f/w RX_ID */
103314733Smav	lun_id_t	lun;
104196008Smjacob	uint32_t	nphdl;
105196008Smjacob	uint32_t	sid;
106314765Smav	uint32_t	did;
107237537Smjacob	uint16_t	rxid;	/* wire rxid */
108237537Smjacob	uint16_t	oxid;	/* wire oxid */
109238869Smjacob	uint16_t	word3;	/* PRLI word3 params */
110238869Smjacob	uint16_t	ctcnt;	/* number of CTIOs currently active */
111239143Smjacob	uint8_t		seqno;	/* CTIO sequence number */
112196008Smjacob	uint32_t
113238869Smjacob			srr_notify_rcvd	: 1,
114238869Smjacob			cdb0		: 8,
115238869Smjacob			sendst		: 1,
116238869Smjacob			dead		: 1,
117238869Smjacob			tattr		: 3,
118238869Smjacob			state		: 3;
119238869Smjacob	void *		ests;
120238869Smjacob	/*
121238869Smjacob	 * The current SRR notify copy
122238869Smjacob	 */
123238869Smjacob	uint8_t		srr[64];	/*  sb QENTRY_LEN, but order of definitions is wrong */
124238869Smjacob	void *		srr_ccb;
125238869Smjacob	uint32_t	nsrr;
12684242Smjacob} atio_private_data_t;
12798288Smjacob#define	ATPD_STATE_FREE			0
12898288Smjacob#define	ATPD_STATE_ATIO			1
12998288Smjacob#define	ATPD_STATE_CAM			2
13098288Smjacob#define	ATPD_STATE_CTIO			3
13198288Smjacob#define	ATPD_STATE_LAST_CTIO		4
13298288Smjacob#define	ATPD_STATE_PDON			5
13384242Smjacob
134239143Smjacob#define	ATPD_CCB_OUTSTANDING		16
135239143Smjacob
136239143Smjacob#define	ATPD_SEQ_MASK			0x7f
137239143Smjacob#define	ATPD_SEQ_NOTIFY_CAM		0x80
138239143Smjacob#define	ATPD_SET_SEQNO(hdrp, atp)	((isphdr_t *)hdrp)->rqs_seqno &= ~ATPD_SEQ_MASK, ((isphdr_t *)hdrp)->rqs_seqno |= (atp)->seqno
139239143Smjacob#define	ATPD_GET_SEQNO(hdrp)		(((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_MASK)
140239143Smjacob#define	ATPD_GET_NCAM(hdrp)		((((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0)
141239143Smjacob
142314733Smavtypedef struct inot_private_data inot_private_data_t;
143314733Smavstruct inot_private_data {
144314733Smav	STAILQ_ENTRY(inot_private_data)	next;
145314733Smav	isp_notify_t nt;
146314733Smav	uint8_t data[64];	/* sb QENTRY_LEN, but order of definitions is wrong */
147314733Smav	uint32_t tag_id, seq_id;
148196008Smjacob};
149238869Smjacobtypedef struct isp_timed_notify_ack {
150238869Smjacob	void *isp;
151238869Smjacob	void *not;
152238869Smjacob	uint8_t data[64];	 /* sb QENTRY_LEN, but order of definitions is wrong */
153284799Smav	struct callout timer;
154238869Smjacob} isp_tna_t;
155196008Smjacob
156314733SmavSTAILQ_HEAD(ntpdlist, inot_private_data);
15755366Smjacobtypedef struct tstate {
158314733Smav	SLIST_ENTRY(tstate)	next;
159314733Smav	lun_id_t		ts_lun;
160314733Smav	struct ccb_hdr_slist	atios;
161314733Smav	struct ccb_hdr_slist	inots;
162314733Smav	struct ntpdlist		restart_queue;
16355366Smjacob} tstate_t;
16455366Smjacob
165196008Smjacob#define	LUN_HASH_SIZE		32
166196008Smjacob#define	LUN_HASH_FUNC(lun)	((lun) & (LUN_HASH_SIZE - 1))
167196008Smjacob
16855366Smjacob#endif
16955366Smjacob
170169292Smjacob/*
171169292Smjacob * Per command info.
172169292Smjacob */
173169292Smjacobstruct isp_pcmd {
174169292Smjacob	struct isp_pcmd *	next;
175238869Smjacob	bus_dmamap_t 		dmap;		/* dma map for this command */
176238869Smjacob	struct callout		wdog;		/* watchdog timer */
177239143Smjacob	uint32_t		datalen;	/* data length for this command (target mode only) */
178169292Smjacob};
179169292Smjacob#define	ISP_PCMD(ccb)		(ccb)->ccb_h.spriv_ptr1
180169292Smjacob#define	PISP_PCMD(ccb)		((struct isp_pcmd *)ISP_PCMD(ccb))
181169292Smjacob
182196008Smjacob/*
183238869Smjacob * Per nexus info.
184238869Smjacob */
185238869Smjacobstruct isp_nexus {
186290791Smav	uint64_t lun;			/* LUN for target */
187290791Smav	uint32_t tgt;			/* TGT for target */
188290791Smav	uint8_t crnseed;		/* next command reference number */
189290791Smav	struct isp_nexus *next;
190238869Smjacob};
191238869Smjacob#define	NEXUS_HASH_WIDTH	32
192238869Smjacob#define	INITIAL_NEXUS_COUNT	MAX_FC_TARG
193238869Smjacob#define	NEXUS_HASH(tgt, lun)	((tgt + lun) % NEXUS_HASH_WIDTH)
194238869Smjacob
195238869Smjacob/*
196196008Smjacob * Per channel information
197196008Smjacob */
198196008SmjacobSLIST_HEAD(tslist, tstate);
199314698SmavTAILQ_HEAD(isp_ccbq, ccb_hdr);
200314733SmavLIST_HEAD(atpdlist, atio_private_data);
201196008Smjacob
202196008Smjacobstruct isp_fc {
203196008Smjacob	struct cam_sim *sim;
204196008Smjacob	struct cam_path *path;
205196008Smjacob	struct ispsoftc *isp;
206196008Smjacob	struct proc *kproc;
207292927Smav	bus_dmamap_t scmap;
208196008Smjacob	uint64_t def_wwpn;
209196008Smjacob	uint64_t def_wwnn;
210291532Smav	time_t loop_down_time;
211291532Smav	int loop_down_limit;
212291532Smav	int gone_device_time;
213238869Smjacob	/*
214238869Smjacob	 * Per target/lun info- just to keep a per-ITL nexus crn count
215238869Smjacob	 */
216238869Smjacob	struct isp_nexus *nexus_hash[NEXUS_HASH_WIDTH];
217238869Smjacob	struct isp_nexus *nexus_free_list;
218196008Smjacob	uint32_t
219163899Smjacob		simqfrozen	: 3,
220196008Smjacob		default_id	: 8,
221205236Smjacob		def_role	: 2,	/* default role */
222291532Smav		loop_seen_once	: 1,
223200089Smjacob		fcbsy		: 1,
224200089Smjacob		ready		: 1;
225196008Smjacob	struct callout gdt;	/* gone device timer */
226224804Smjacob	struct task gtask;
227196008Smjacob#ifdef	ISP_TARGET_MODE
228314698Smav	struct tslist		lun_hash[LUN_HASH_SIZE];
229314698Smav	struct isp_ccbq		waitq;		/* waiting CCBs */
230314733Smav	struct ntpdlist		ntfree;
231314733Smav	inot_private_data_t	ntpool[ATPDPSIZE];
232314733Smav	struct atpdlist		atfree;
233314733Smav	struct atpdlist		atused[ATPDPHASHSIZE];
234314733Smav	atio_private_data_t	atpool[ATPDPSIZE];
235238869Smjacob#if defined(DEBUG)
236238869Smjacob	unsigned int inject_lost_data_frame;
237196008Smjacob#endif
238238869Smjacob#endif
239288707Smav	int			num_threads;
240196008Smjacob};
241196008Smjacob
242196008Smjacobstruct isp_spi {
243196008Smjacob	struct cam_sim *sim;
244196008Smjacob	struct cam_path *path;
245196008Smjacob	uint32_t
246196008Smjacob		simqfrozen	: 3,
247196008Smjacob		iid		: 4;
248196008Smjacob#ifdef	ISP_TARGET_MODE
249314698Smav	struct tslist		lun_hash[LUN_HASH_SIZE];
250314698Smav	struct isp_ccbq		waitq;		/* waiting CCBs */
251314733Smav	struct ntpdlist		ntfree;
252314733Smav	inot_private_data_t	ntpool[ATPDPSIZE];
253314733Smav	struct atpdlist		atfree;
254314733Smav	struct atpdlist		atused[ATPDPHASHSIZE];
255314733Smav	atio_private_data_t	atpool[ATPDPSIZE];
256196008Smjacob#endif
257288707Smav	int			num_threads;
258196008Smjacob};
259196008Smjacob
260196008Smjacobstruct isposinfo {
261196008Smjacob	/*
262196008Smjacob	 * Linkage, locking, and identity
263196008Smjacob	 */
264169292Smjacob	struct mtx		lock;
265196008Smjacob	device_t		dev;
266196008Smjacob	struct cdev *		cdev;
267196008Smjacob	struct cam_devq *	devq;
268196008Smjacob
269196008Smjacob	/*
270196008Smjacob	 * Firmware pointer
271196008Smjacob	 */
272166756Sluigi	const struct firmware *	fw;
273196008Smjacob
274196008Smjacob	/*
275292927Smav	 * DMA related stuff
276196008Smjacob	 */
277292598Smav	struct resource *	regs;
278292598Smav	struct resource *	regs2;
279196008Smjacob	bus_dma_tag_t		dmat;
280292929Smav	bus_dma_tag_t		reqdmat;
281292929Smav	bus_dma_tag_t		respdmat;
282292929Smav	bus_dma_tag_t		atiodmat;
283298966Smav	bus_dma_tag_t		iocbdmat;
284292927Smav	bus_dma_tag_t		scdmat;
285292929Smav	bus_dmamap_t		reqmap;
286292929Smav	bus_dmamap_t		respmap;
287292929Smav	bus_dmamap_t		atiomap;
288298966Smav	bus_dmamap_t		iocbmap;
289196008Smjacob
290169292Smjacob	/*
291196008Smjacob	 * Command and transaction related related stuff
292169292Smjacob	 */
293169292Smjacob	struct isp_pcmd *	pcmd_pool;
294169292Smjacob	struct isp_pcmd *	pcmd_free;
295169292Smjacob
296316091Smav	int			mbox_sleeping;
297316091Smav	int			mbox_sleep_ok;
298316091Smav	int			mboxbsy;
299316091Smav	int			mboxcmd_done;
300196008Smjacob
301196008Smjacob	struct callout		tmo;	/* general timer */
302196008Smjacob
303196008Smjacob	/*
304196008Smjacob	 * misc- needs to be sorted better XXXXXX
305196008Smjacob	 */
306196008Smjacob	int			framesize;
307196008Smjacob	int			exec_throttle;
308196008Smjacob	int			cont_max;
309196008Smjacob
310238869Smjacob	bus_addr_t		ecmd_dma;
311238869Smjacob	isp_ecmd_t *		ecmd_base;
312238869Smjacob	isp_ecmd_t *		ecmd_free;
313238869Smjacob
314196008Smjacob	/*
315196008Smjacob	 * Per-type private storage...
316196008Smjacob	 */
317196008Smjacob	union {
318196008Smjacob		struct isp_fc *fc;
319196008Smjacob		struct isp_spi *spi;
320196008Smjacob		void *ptr;
321196008Smjacob	} pc;
322288707Smav
323288707Smav	int			is_exiting;
32435388Smjacob};
325196008Smjacob#define	ISP_FC_PC(isp, chan)	(&(isp)->isp_osinfo.pc.fc[(chan)])
326196008Smjacob#define	ISP_SPI_PC(isp, chan)	(&(isp)->isp_osinfo.pc.spi[(chan)])
327196008Smjacob#define	ISP_GET_PC(isp, chan, tag, rslt)		\
328196008Smjacob	if (IS_SCSI(isp)) {				\
329196008Smjacob		rslt = ISP_SPI_PC(isp, chan)-> tag;	\
330196008Smjacob	} else {					\
331196008Smjacob		rslt = ISP_FC_PC(isp, chan)-> tag;	\
332196008Smjacob	}
333196008Smjacob#define	ISP_GET_PC_ADDR(isp, chan, tag, rp)		\
334196008Smjacob	if (IS_SCSI(isp)) {				\
335196008Smjacob		rp = &ISP_SPI_PC(isp, chan)-> tag;	\
336196008Smjacob	} else {					\
337196008Smjacob		rp = &ISP_FC_PC(isp, chan)-> tag;	\
338196008Smjacob	}
339196008Smjacob#define	ISP_SET_PC(isp, chan, tag, val)			\
340196008Smjacob	if (IS_SCSI(isp)) {				\
341196008Smjacob		ISP_SPI_PC(isp, chan)-> tag = val;	\
342196008Smjacob	} else {					\
343196008Smjacob		ISP_FC_PC(isp, chan)-> tag = val;	\
344196008Smjacob	}
34539235Sgibbs
346238869Smjacob#define	FCP_NEXT_CRN	isp_fcp_next_crn
34777365Smjacob#define	isp_lock	isp_osinfo.lock
348292598Smav#define	isp_regs	isp_osinfo.regs
349292598Smav#define	isp_regs2	isp_osinfo.regs2
35077365Smjacob
35164092Smjacob/*
35269525Smjacob * Locking macros...
35369525Smjacob */
354316403Smav#define	ISP_LOCK(isp)	mtx_lock(&(isp)->isp_lock)
355316403Smav#define	ISP_UNLOCK(isp)	mtx_unlock(&(isp)->isp_lock)
356316403Smav#define	ISP_ASSERT_LOCKED(isp)	mtx_assert(&(isp)->isp_lock, MA_OWNED)
35769525Smjacob
35869525Smjacob/*
35964092Smjacob * Required Macros/Defines
36064092Smjacob */
361196008Smjacob#define	ISP_FC_SCRLEN		0x1000
36245284Smjacob
363196008Smjacob#define	ISP_MEMZERO(a, b)	memset(a, 0, b)
364196008Smjacob#define	ISP_MEMCPY		memcpy
365196008Smjacob#define	ISP_SNPRINTF		snprintf
366291503Smav#define	ISP_DELAY(x)		DELAY(x)
367291505Smav#define	ISP_SLEEP(isp, x)	msleep_sbt(&(isp)->isp_osinfo.is_exiting, \
368316403Smav    &(isp)->isp_lock, 0, "isp_sleep", (x) * SBT_1US, 0, 0)
36935388Smjacob
370219098Smjacob#define	ISP_MIN			imin
371219098Smjacob
372196008Smjacob#ifndef	DIAGNOSTIC
373196008Smjacob#define	ISP_INLINE		__inline
374196008Smjacob#else
375196008Smjacob#define	ISP_INLINE
376196008Smjacob#endif
377196008Smjacob
37864092Smjacob#define	NANOTIME_T		struct timespec
37964092Smjacob#define	GET_NANOTIME		nanotime
38064092Smjacob#define	GET_NANOSEC(x)		((x)->tv_sec * 1000000000 + (x)->tv_nsec)
381164272Smjacob#define	NANOTIME_SUB		isp_nanotime_sub
38262496Smjacob
38399598Smjacob#define	MAXISPREQUEST(isp)	((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256)
38462496Smjacob
385218691Smarius#define	MEMORYBARRIER(isp, type, offset, size, chan)		\
38693706Smjacobswitch (type) {							\
387292929Smavcase SYNC_REQUEST:						\
388292929Smav	bus_dmamap_sync(isp->isp_osinfo.reqdmat,		\
389292929Smav	   isp->isp_osinfo.reqmap, BUS_DMASYNC_PREWRITE);	\
390292929Smav	break;							\
391292929Smavcase SYNC_RESULT:						\
392292929Smav	bus_dmamap_sync(isp->isp_osinfo.respdmat, 		\
393292929Smav	   isp->isp_osinfo.respmap, BUS_DMASYNC_POSTREAD);	\
394292929Smav	break;							\
39593706Smjacobcase SYNC_SFORDEV:						\
396218691Smarius{								\
397218691Smarius	struct isp_fc *fc = ISP_FC_PC(isp, chan);		\
398292927Smav	bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap,	\
399218691Smarius	   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		\
400218691Smarius	break;							\
401218691Smarius}								\
40293706Smjacobcase SYNC_SFORCPU:						\
403218691Smarius{								\
404218691Smarius	struct isp_fc *fc = ISP_FC_PC(isp, chan);		\
405292927Smav	bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap,	\
406218691Smarius	   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);	\
407218691Smarius	break;							\
408218691Smarius}								\
409167501Smjacobcase SYNC_REG:							\
410292598Smav	bus_barrier(isp->isp_osinfo.regs, offset, size,		\
411219282Smjacob	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);	\
412167501Smjacob	break;							\
413292929Smavcase SYNC_ATIOQ:						\
414292929Smav	bus_dmamap_sync(isp->isp_osinfo.atiodmat, 		\
415292929Smav	   isp->isp_osinfo.atiomap, BUS_DMASYNC_POSTREAD);	\
416292929Smav	break;							\
417298966Smavcase SYNC_IFORDEV:						\
418298966Smav	bus_dmamap_sync(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap, \
419298966Smav	   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		\
420298966Smav	break;							\
421298966Smavcase SYNC_IFORCPU:						\
422298966Smav	bus_dmamap_sync(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap, \
423298966Smav	   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);	\
424298966Smav	break;							\
42593706Smjacobdefault:							\
42693706Smjacob	break;							\
42793706Smjacob}
42862496Smjacob
429260347Smav#define	MEMORYBARRIERW(isp, type, offset, size, chan)		\
430260347Smavswitch (type) {							\
431292929Smavcase SYNC_REQUEST:						\
432292929Smav	bus_dmamap_sync(isp->isp_osinfo.reqdmat,		\
433292929Smav	   isp->isp_osinfo.reqmap, BUS_DMASYNC_PREWRITE);	\
434292929Smav	break;							\
435260347Smavcase SYNC_SFORDEV:						\
436260347Smav{								\
437260347Smav	struct isp_fc *fc = ISP_FC_PC(isp, chan);		\
438292927Smav	bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap,	\
439260347Smav	   BUS_DMASYNC_PREWRITE);				\
440260347Smav	break;							\
441260347Smav}								\
442260347Smavcase SYNC_SFORCPU:						\
443260347Smav{								\
444260347Smav	struct isp_fc *fc = ISP_FC_PC(isp, chan);		\
445292927Smav	bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap,	\
446260347Smav	   BUS_DMASYNC_POSTWRITE);				\
447260347Smav	break;							\
448260347Smav}								\
449260347Smavcase SYNC_REG:							\
450292598Smav	bus_barrier(isp->isp_osinfo.regs, offset, size,		\
451260347Smav	    BUS_SPACE_BARRIER_WRITE);				\
452260347Smav	break;							\
453298966Smavcase SYNC_IFORDEV:						\
454298966Smav	bus_dmamap_sync(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap, \
455298966Smav	   BUS_DMASYNC_PREWRITE);				\
456298966Smav	break;							\
457298966Smavcase SYNC_IFORCPU:						\
458298966Smav	bus_dmamap_sync(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap, \
459298966Smav	   BUS_DMASYNC_POSTWRITE);				\
460298966Smav	break;							\
461260347Smavdefault:							\
462260347Smav	break;							\
463260347Smav}
464260347Smav
465163899Smjacob#define	MBOX_ACQUIRE			isp_mbox_acquire
46664092Smjacob#define	MBOX_WAIT_COMPLETE		isp_mbox_wait_complete
467164272Smjacob#define	MBOX_NOTIFY_COMPLETE		isp_mbox_notify_done
468163899Smjacob#define	MBOX_RELEASE			isp_mbox_release
46962496Smjacob
470196008Smjacob#define	FC_SCRATCH_ACQUIRE		isp_fc_scratch_acquire
471196008Smjacob#define	FC_SCRATCH_RELEASE(isp, chan)	isp->isp_osinfo.pc.fc[chan].fcbsy = 0
47290224Smjacob
47364092Smjacob#ifndef	SCSI_GOOD
47464092Smjacob#define	SCSI_GOOD	SCSI_STATUS_OK
47564092Smjacob#endif
47664092Smjacob#ifndef	SCSI_CHECK
47764092Smjacob#define	SCSI_CHECK	SCSI_STATUS_CHECK_COND
47864092Smjacob#endif
47964092Smjacob#ifndef	SCSI_BUSY
48064092Smjacob#define	SCSI_BUSY	SCSI_STATUS_BUSY
48164092Smjacob#endif
48264092Smjacob#ifndef	SCSI_QFULL
48364092Smjacob#define	SCSI_QFULL	SCSI_STATUS_QUEUE_FULL
48464092Smjacob#endif
48564092Smjacob
48664092Smjacob#define	XS_T			struct ccb_scsiio
487155704Smjacob#define	XS_DMA_ADDR_T		bus_addr_t
488196008Smjacob#define XS_GET_DMA64_SEG(a, b, c)		\
489196008Smjacob{						\
490196008Smjacob	ispds64_t *d = a;			\
491196008Smjacob	bus_dma_segment_t *e = b;		\
492196008Smjacob	uint32_t f = c;				\
493196008Smjacob	e += f;					\
494196008Smjacob        d->ds_base = DMA_LO32(e->ds_addr);	\
495196008Smjacob        d->ds_basehi = DMA_HI32(e->ds_addr);	\
496196008Smjacob        d->ds_count = e->ds_len;		\
497196008Smjacob}
498196008Smjacob#define XS_GET_DMA_SEG(a, b, c)			\
499196008Smjacob{						\
500196008Smjacob	ispds_t *d = a;				\
501196008Smjacob	bus_dma_segment_t *e = b;		\
502196008Smjacob	uint32_t f = c;				\
503196008Smjacob	e += f;					\
504196008Smjacob        d->ds_base = DMA_LO32(e->ds_addr);	\
505196008Smjacob        d->ds_count = e->ds_len;		\
506196008Smjacob}
507317366Smav#if (BUS_SPACE_MAXADDR > UINT32_MAX)
508317366Smav#define XS_NEED_DMA64_SEG(s, n)					\
509317366Smav	(((bus_dma_segment_t *)s)[n].ds_addr +			\
510317366Smav	    ((bus_dma_segment_t *)s)[n].ds_len > UINT32_MAX)
511317366Smav#else
512317366Smav#define XS_NEED_DMA64_SEG(s, n)	(0)
513317366Smav#endif
514169292Smjacob#define	XS_ISP(ccb)		cam_sim_softc(xpt_path_sim((ccb)->ccb_h.path))
51564092Smjacob#define	XS_CHANNEL(ccb)		cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path))
51664092Smjacob#define	XS_TGT(ccb)		(ccb)->ccb_h.target_id
51764092Smjacob#define	XS_LUN(ccb)		(ccb)->ccb_h.target_lun
51835388Smjacob
51964092Smjacob#define	XS_CDBP(ccb)	\
52064092Smjacob	(((ccb)->ccb_h.flags & CAM_CDB_POINTER)? \
52164092Smjacob	 (ccb)->cdb_io.cdb_ptr : (ccb)->cdb_io.cdb_bytes)
52264092Smjacob
52364092Smjacob#define	XS_CDBLEN(ccb)		(ccb)->cdb_len
52448487Smjacob#define	XS_XFRLEN(ccb)		(ccb)->dxfer_len
525316407Smav#define	XS_TIME(ccb)	\
526316407Smav	(((ccb)->ccb_h.timeout > 0xffff * 1000 - 999) ? 0 : \
527316407Smav	  (((ccb)->ccb_h.timeout + 999) / 1000))
528196008Smjacob#define	XS_GET_RESID(ccb)	(ccb)->resid
529196008Smjacob#define	XS_SET_RESID(ccb, r)	(ccb)->resid = r
53064092Smjacob#define	XS_STSP(ccb)		(&(ccb)->scsi_status)
53148487Smjacob#define	XS_SNSP(ccb)		(&(ccb)->sense_data)
53264092Smjacob
533238869Smjacob#define	XS_TOT_SNSLEN(ccb)	ccb->sense_len
534238869Smjacob#define	XS_CUR_SNSLEN(ccb)	(ccb->sense_len - ccb->sense_resid)
53564092Smjacob
536225950Sken#define	XS_SNSKEY(ccb)		(scsi_get_sense_key(&(ccb)->sense_data, \
537238869Smjacob				 ccb->sense_len - ccb->sense_resid, 1))
538225950Sken
539225950Sken#define	XS_SNSASC(ccb)		(scsi_get_asc(&(ccb)->sense_data,	\
540238869Smjacob				 ccb->sense_len - ccb->sense_resid, 1))
541225950Sken
542225950Sken#define	XS_SNSASCQ(ccb)		(scsi_get_ascq(&(ccb)->sense_data,	\
543238869Smjacob				 ccb->sense_len - ccb->sense_resid, 1))
54464092Smjacob#define	XS_TAG_P(ccb)	\
54564092Smjacob	(((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID) && \
54664092Smjacob	 (ccb)->tag_action != CAM_TAG_ACTION_NONE)
54735388Smjacob
54864092Smjacob#define	XS_TAG_TYPE(ccb)	\
54964092Smjacob	((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \
55064092Smjacob	 ((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG))
55164092Smjacob
55264092Smjacob
55364092Smjacob#define	XS_SETERR(ccb, v)	(ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \
554238869Smjacob				(ccb)->ccb_h.status |= v
55564092Smjacob
55664092Smjacob#	define	HBA_NOERROR		CAM_REQ_INPROG
55764092Smjacob#	define	HBA_BOTCH		CAM_UNREC_HBA_ERROR
55864092Smjacob#	define	HBA_CMDTIMEOUT		CAM_CMD_TIMEOUT
55964092Smjacob#	define	HBA_SELTIMEOUT		CAM_SEL_TIMEOUT
56064092Smjacob#	define	HBA_TGTBSY		CAM_SCSI_STATUS_ERROR
561314759Smav#	define	HBA_REQINVAL		CAM_REQ_INVALID
56264092Smjacob#	define	HBA_BUSRESET		CAM_SCSI_BUS_RESET
56364092Smjacob#	define	HBA_ABORTED		CAM_REQ_ABORTED
56464092Smjacob#	define	HBA_DATAOVR		CAM_DATA_RUN_ERR
56564092Smjacob#	define	HBA_ARQFAIL		CAM_AUTOSENSE_FAIL
56664092Smjacob
56764092Smjacob
56864092Smjacob#define	XS_ERR(ccb)		((ccb)->ccb_h.status & CAM_STATUS_MASK)
56964092Smjacob
570238869Smjacob#define	XS_NOERR(ccb)		(((ccb)->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)
57164092Smjacob
572238869Smjacob#define	XS_INITERR(ccb)		XS_SETERR(ccb, CAM_REQ_INPROG), ccb->sense_resid = ccb->sense_len
57364092Smjacob
574317363Smav#define	XS_SAVE_SENSE(xs, sp, len)	do {				\
575317363Smav		uint32_t amt = min(len, (xs)->sense_len);		\
576317363Smav		memcpy(&(xs)->sense_data, sp, amt);			\
577317363Smav		(xs)->sense_resid = (xs)->sense_len - amt;		\
578317363Smav		(xs)->ccb_h.status |= CAM_AUTOSNS_VALID;		\
579238869Smjacob	} while (0)
58064092Smjacob
581317363Smav#define	XS_SENSE_APPEND(xs, sp, len)	do {				\
582317363Smav		uint8_t *ptr = (uint8_t *)(&(xs)->sense_data) +		\
583317363Smav		    ((xs)->sense_len - (xs)->sense_resid);		\
584317363Smav		uint32_t amt = min((len), (xs)->sense_resid);		\
585317363Smav		memcpy(ptr, sp, amt);					\
586317363Smav		(xs)->sense_resid -= amt;				\
587238869Smjacob	} while (0)
588238869Smjacob
589205698Smjacob#define	XS_SENSE_VALID(xs)	(((xs)->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
59064092Smjacob
591196008Smjacob#define	DEFAULT_FRAMESIZE(isp)		isp->isp_osinfo.framesize
592196008Smjacob#define	DEFAULT_EXEC_THROTTLE(isp)	isp->isp_osinfo.exec_throttle
59364092Smjacob
594291528Smav#define	DEFAULT_ROLE(isp, chan)	\
595291528Smav	(IS_FC(isp)? ISP_FC_PC(isp, chan)->def_role : ISP_ROLE_INITIATOR)
596167473Smjacob
597196008Smjacob#define	DEFAULT_IID(isp, chan)		isp->isp_osinfo.pc.spi[chan].iid
598167473Smjacob
599196008Smjacob#define	DEFAULT_LOOPID(x, chan)		isp->isp_osinfo.pc.fc[chan].default_id
600196008Smjacob
601196008Smjacob#define DEFAULT_NODEWWN(isp, chan)  	isp_default_wwn(isp, chan, 0, 1)
602196008Smjacob#define DEFAULT_PORTWWN(isp, chan)  	isp_default_wwn(isp, chan, 0, 0)
603196008Smjacob#define ACTIVE_NODEWWN(isp, chan)   	isp_default_wwn(isp, chan, 1, 1)
604196008Smjacob#define ACTIVE_PORTWWN(isp, chan)   	isp_default_wwn(isp, chan, 1, 0)
605196008Smjacob
606196008Smjacob
60787635Smjacob#if	BYTE_ORDER == BIG_ENDIAN
60887635Smjacob#ifdef	ISP_SBUS_SUPPORTED
60987635Smjacob#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
61087635Smjacob#define	ISP_IOXPUT_16(isp, s, d)				\
61187635Smjacob	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap16(s)
61287635Smjacob#define	ISP_IOXPUT_32(isp, s, d)				\
61387635Smjacob	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap32(s)
614155704Smjacob#define	ISP_IOXGET_8(isp, s, d)		d = (*((uint8_t *)s))
61587635Smjacob#define	ISP_IOXGET_16(isp, s, d)				\
61687635Smjacob	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
617155704Smjacob	*((uint16_t *)s) : bswap16(*((uint16_t *)s))
61887635Smjacob#define	ISP_IOXGET_32(isp, s, d)				\
61987635Smjacob	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
620155704Smjacob	*((uint32_t *)s) : bswap32(*((uint32_t *)s))
621163899Smjacob
622163899Smjacob#else	/* ISP_SBUS_SUPPORTED */
62387635Smjacob#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
62487635Smjacob#define	ISP_IOXPUT_16(isp, s, d)	*(d) = bswap16(s)
62587635Smjacob#define	ISP_IOXPUT_32(isp, s, d)	*(d) = bswap32(s)
626155704Smjacob#define	ISP_IOXGET_8(isp, s, d)		d = (*((uint8_t *)s))
627155704Smjacob#define	ISP_IOXGET_16(isp, s, d)	d = bswap16(*((uint16_t *)s))
628155704Smjacob#define	ISP_IOXGET_32(isp, s, d)	d = bswap32(*((uint32_t *)s))
62987635Smjacob#endif
63087635Smjacob#define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)	*rp = bswap16(*rp)
631171159Smjacob#define	ISP_SWIZZLE_NVRAM_LONG(isp, rp)	*rp = bswap32(*rp)
632163899Smjacob
633163899Smjacob#define	ISP_IOZGET_8(isp, s, d)		d = (*((uint8_t *)s))
634163899Smjacob#define	ISP_IOZGET_16(isp, s, d)	d = (*((uint16_t *)s))
635163899Smjacob#define	ISP_IOZGET_32(isp, s, d)	d = (*((uint32_t *)s))
636163899Smjacob#define	ISP_IOZPUT_8(isp, s, d)		*(d) = s
637163899Smjacob#define	ISP_IOZPUT_16(isp, s, d)	*(d) = s
638163899Smjacob#define	ISP_IOZPUT_32(isp, s, d)	*(d) = s
639163899Smjacob
640163899Smjacob
64187635Smjacob#else
64287635Smjacob#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
64387635Smjacob#define	ISP_IOXPUT_16(isp, s, d)	*(d) = s
64487635Smjacob#define	ISP_IOXPUT_32(isp, s, d)	*(d) = s
64587635Smjacob#define	ISP_IOXGET_8(isp, s, d)		d = *(s)
64687635Smjacob#define	ISP_IOXGET_16(isp, s, d)	d = *(s)
64787635Smjacob#define	ISP_IOXGET_32(isp, s, d)	d = *(s)
64887635Smjacob#define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)
649171159Smjacob#define	ISP_SWIZZLE_NVRAM_LONG(isp, rp)
650163899Smjacob
651163899Smjacob#define	ISP_IOZPUT_8(isp, s, d)		*(d) = s
652163899Smjacob#define	ISP_IOZPUT_16(isp, s, d)	*(d) = bswap16(s)
653163899Smjacob#define	ISP_IOZPUT_32(isp, s, d)	*(d) = bswap32(s)
654163899Smjacob
655163899Smjacob#define	ISP_IOZGET_8(isp, s, d)		d = (*((uint8_t *)(s)))
656163899Smjacob#define	ISP_IOZGET_16(isp, s, d)	d = bswap16(*((uint16_t *)(s)))
657163899Smjacob#define	ISP_IOZGET_32(isp, s, d)	d = bswap32(*((uint32_t *)(s)))
658163899Smjacob
65987635Smjacob#endif
66064092Smjacob
661171159Smjacob#define	ISP_SWAP16(isp, s)	bswap16(s)
662171159Smjacob#define	ISP_SWAP32(isp, s)	bswap32(s)
663171159Smjacob
66448487Smjacob/*
66564092Smjacob * Includes of common header files
66648487Smjacob */
66735388Smjacob
66864092Smjacob#include <dev/isp/ispreg.h>
66964092Smjacob#include <dev/isp/ispvar.h>
67064092Smjacob#include <dev/isp/ispmbox.h>
67135388Smjacob
67264092Smjacob/*
67364092Smjacob * isp_osinfo definiitions && shorthand
67464092Smjacob */
67564092Smjacob#define	SIMQFRZ_RESOURCE	0x1
67664092Smjacob#define	SIMQFRZ_LOOPDOWN	0x2
67764092Smjacob#define	SIMQFRZ_TIMED		0x4
67864092Smjacob
67973246Smjacob#define	isp_dev		isp_osinfo.dev
68064092Smjacob
68164092Smjacob/*
68264092Smjacob * prototypes for isp_pci && isp_freebsd to share
68364092Smjacob */
684196008Smjacobextern int isp_attach(ispsoftc_t *);
685224856Smjacobextern int isp_detach(ispsoftc_t *);
686196008Smjacobextern uint64_t isp_default_wwn(ispsoftc_t *, int, int, int);
68764092Smjacob
68864092Smjacob/*
68999756Smjacob * driver global data
69099756Smjacob */
69199756Smjacobextern int isp_announced;
692163899Smjacobextern int isp_loop_down_limit;
693164272Smjacobextern int isp_gone_device_time;
694163899Smjacobextern int isp_quickboot_time;
69599756Smjacob
69699756Smjacob/*
69764092Smjacob * Platform private flags
69864092Smjacob */
69962172Smjacob
70039235Sgibbs/*
701164272Smjacob * Platform Library Functions
702164272Smjacob */
703164272Smjacobvoid isp_prt(ispsoftc_t *, int level, const char *, ...) __printflike(3, 4);
704205698Smjacobvoid isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...) __printflike(4, 5);
705164272Smjacobuint64_t isp_nanotime_sub(struct timespec *, struct timespec *);
706164272Smjacobint isp_mbox_acquire(ispsoftc_t *);
707164272Smjacobvoid isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *);
708164272Smjacobvoid isp_mbox_notify_done(ispsoftc_t *);
709164272Smjacobvoid isp_mbox_release(ispsoftc_t *);
710196008Smjacobint isp_fc_scratch_acquire(ispsoftc_t *, int);
711169292Smjacobvoid isp_platform_intr(void *);
712316399Smavvoid isp_platform_intr_resp(void *);
713316399Smavvoid isp_platform_intr_atio(void *);
714169292Smjacobvoid isp_common_dmateardown(ispsoftc_t *, struct ccb_scsiio *, uint32_t);
715291506Smavvoid isp_fcp_reset_crn(ispsoftc_t *, int, uint32_t, int);
716238869Smjacobint isp_fcp_next_crn(ispsoftc_t *, uint8_t *, XS_T *);
717164272Smjacob
718164272Smjacob/*
719169292Smjacob * Platform Version specific defines
720166177Smjacob */
721196008Smjacob#define	ISP_PATH_PRT(i, l, p, ...)					\
722196008Smjacob	if ((l) == ISP_LOGALL || ((l)& (i)->isp_dblev) != 0) {		\
723196008Smjacob                xpt_print(p, __VA_ARGS__);				\
724196008Smjacob        }
725196008Smjacob
726166177Smjacob/*
72764092Smjacob * Platform specific inline functions
72839235Sgibbs */
72944819Smjacob
73064092Smjacob/*
731164272Smjacob * ISP General Library functions
73264092Smjacob */
73344819Smjacob
734155228Smjacob#include <dev/isp/isp_library.h>
735155228Smjacob
73635388Smjacob#endif	/* _ISP_FREEBSD_H */
737