xref: /freebsd/sys/dev/isp/isp_freebsd.h (revision 39beb93c)
1 /* $FreeBSD$ */
2 /*-
3  * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions
4  *
5  * Copyright (c) 1997-2006 by Matthew Jacob
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice immediately at the beginning of the file, without modification,
13  *    this list of conditions, and the following disclaimer.
14  * 2. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 #ifndef	_ISP_FREEBSD_H
30 #define	_ISP_FREEBSD_H
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/endian.h>
35 #if __FreeBSD_version < 500000
36 #include <sys/kernel.h>
37 #include <sys/queue.h>
38 #include <sys/malloc.h>
39 #else
40 #include <sys/lock.h>
41 #include <sys/kernel.h>
42 #include <sys/queue.h>
43 #include <sys/malloc.h>
44 #include <sys/mutex.h>
45 #include <sys/condvar.h>
46 #endif
47 
48 #include <sys/proc.h>
49 #include <sys/bus.h>
50 
51 #include <machine/bus.h>
52 #if __FreeBSD_version < 500000
53 #include <machine/clock.h>
54 #endif
55 #include <machine/cpu.h>
56 
57 #include <cam/cam.h>
58 #include <cam/cam_debug.h>
59 #include <cam/cam_ccb.h>
60 #include <cam/cam_sim.h>
61 #include <cam/cam_xpt.h>
62 #include <cam/cam_xpt_sim.h>
63 #include <cam/cam_debug.h>
64 #include <cam/scsi/scsi_all.h>
65 #include <cam/scsi/scsi_message.h>
66 
67 #include "opt_ddb.h"
68 #include "opt_isp.h"
69 
70 #if __FreeBSD_version < 500000
71 #define	ISP_PLATFORM_VERSION_MAJOR	4
72 #define	ISP_PLATFORM_VERSION_MINOR	17
73 #else
74 #define	ISP_PLATFORM_VERSION_MAJOR	5
75 #define	ISP_PLATFORM_VERSION_MINOR	9
76 #endif
77 
78 /*
79  * Efficiency- get rid of SBus code && tests unless we need them.
80  */
81 #ifdef __sparc64__
82 #define	ISP_SBUS_SUPPORTED	1
83 #else
84 #define	ISP_SBUS_SUPPORTED	0
85 #endif
86 
87 
88 #if __FreeBSD_version < 500000
89 #define	ISP_IFLAGS	INTR_TYPE_CAM
90 #elif __FreeBSD_version < 700037
91 #define	ISP_IFLAGS	INTR_TYPE_CAM | INTR_ENTROPY
92 #else
93 #define	ISP_IFLAGS	INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE
94 #endif
95 
96 #if __FreeBSD_version < 700000
97 typedef void ispfwfunc(int, int, int, const void **);
98 #endif
99 
100 #ifdef	ISP_TARGET_MODE
101 #define	ISP_TARGET_FUNCTIONS	1
102 #define	ATPDPSIZE	256
103 typedef struct {
104 	uint32_t	orig_datalen;
105 	uint32_t	bytes_xfered;
106 	uint32_t	last_xframt;
107 	uint32_t	tag	: 16,
108 			lun	: 13,	/* not enough */
109 			state	: 3;
110 } atio_private_data_t;
111 #define	ATPD_STATE_FREE			0
112 #define	ATPD_STATE_ATIO			1
113 #define	ATPD_STATE_CAM			2
114 #define	ATPD_STATE_CTIO			3
115 #define	ATPD_STATE_LAST_CTIO		4
116 #define	ATPD_STATE_PDON			5
117 
118 typedef struct tstate {
119 	struct tstate *next;
120 	struct cam_path *owner;
121 	struct ccb_hdr_slist atios;
122 	struct ccb_hdr_slist inots;
123 	lun_id_t lun;
124 	int bus;
125 	uint32_t hold;
126 	int atio_count;
127 	int inot_count;
128 } tstate_t;
129 
130 #define	LUN_HASH_SIZE			32
131 #define	LUN_HASH_FUNC(isp, port, lun)					\
132 	((IS_DUALBUS(isp)) ?						\
133 		(((lun) & ((LUN_HASH_SIZE >> 1) - 1)) << (port)) :	\
134 		((lun) & (LUN_HASH_SIZE - 1)))
135 #endif
136 
137 /*
138  * Per command info.
139  */
140 struct isp_pcmd {
141 	struct isp_pcmd *	next;
142 	bus_dmamap_t 		dmap;	/* dma map for this command */
143 	struct ispsoftc *	isp;	/* containing isp */
144 	struct callout		wdog;	/* watchdog timer */
145 };
146 #define	ISP_PCMD(ccb)		(ccb)->ccb_h.spriv_ptr1
147 #define	PISP_PCMD(ccb)		((struct isp_pcmd *)ISP_PCMD(ccb))
148 
149 struct isposinfo {
150 	struct ispsoftc *	next;
151 	bus_space_tag_t		bus_tag;
152 	bus_space_handle_t	bus_handle;
153 	bus_dma_tag_t		dmat;
154 	uint64_t		default_port_wwn;
155 	uint64_t		default_node_wwn;
156 	uint32_t		default_id;
157 	device_t		dev;
158 	struct cam_sim		*sim;
159 	struct cam_path		*path;
160 	struct cam_sim		*sim2;
161 	struct cam_path		*path2;
162 	struct intr_config_hook	ehook;
163 	uint32_t		loop_down_time;
164 	uint32_t		loop_down_limit;
165 	uint32_t		gone_device_time;
166 	uint32_t		: 5,
167 		simqfrozen	: 3,
168 		hysteresis	: 8,
169 		gdt_running	: 1,
170 		ldt_running	: 1,
171 		disabled	: 1,
172 		fcbsy		: 1,
173 		mbox_sleeping	: 1,
174 		mbox_sleep_ok	: 1,
175 		mboxcmd_done	: 1,
176 		mboxbsy		: 1;
177 	struct callout		ldt;	/* loop down timer */
178 	struct callout		gdt;	/* gone device timer */
179 #if __FreeBSD_version < 500000
180 	uint32_t		splcount;
181 	uint32_t		splsaved;
182 #else
183 	struct mtx		lock;
184 	const struct firmware *	fw;
185 	union {
186 		struct {
187 			char wwnn[19];
188 			char wwpn[19];
189 		} fc;
190 	} sysctl_info;
191 #endif
192 	struct proc		*kproc;
193 	bus_dma_tag_t		cdmat;
194 	bus_dmamap_t		cdmap;
195 #define	isp_cdmat		isp_osinfo.cdmat
196 #define	isp_cdmap		isp_osinfo.cdmap
197 	/*
198 	 * Per command information.
199 	 */
200 	struct isp_pcmd *	pcmd_pool;
201 	struct isp_pcmd *	pcmd_free;
202 
203 #ifdef	ISP_TARGET_MODE
204 #define	TM_WILDCARD_ENABLED	0x02
205 #define	TM_TMODE_ENABLED	0x01
206 	uint8_t			tmflags[2];	/* two busses */
207 #define	NLEACT	4
208 	union ccb *		leact[NLEACT];
209 	tstate_t		tsdflt[2];	/* two busses */
210 	tstate_t		*lun_hash[LUN_HASH_SIZE];
211 	atio_private_data_t	atpdp[ATPDPSIZE];
212 #endif
213 };
214 #define	ISP_KT_WCHAN(isp)	(&(isp)->isp_osinfo.kproc)
215 
216 #define	isp_lock	isp_osinfo.lock
217 #define	isp_bus_tag	isp_osinfo.bus_tag
218 #define	isp_bus_handle	isp_osinfo.bus_handle
219 
220 /*
221  * Locking macros...
222  */
223 #if __FreeBSD_version < 500000
224 #define	ISP_LOCK(isp)						\
225 	if (isp->isp_osinfo.splcount++ == 0) {			\
226 		 isp->isp_osinfo.splsaved = splcam();		\
227 	}
228 #define	ISP_UNLOCK(isp)						\
229 	if (isp->isp_osinfo.splcount > 1) {			\
230 		isp->isp_osinfo.splcount--;			\
231 	} else {						\
232 		isp->isp_osinfo.splcount = 0;			\
233 		splx(isp->isp_osinfo.splsaved);			\
234 	}
235 #elif	__FreeBSD_version < 700037
236 #define	ISP_LOCK(isp)	do {} while (0)
237 #define	ISP_UNLOCK(isp)	do {} while (0)
238 #else
239 #define	ISP_LOCK(isp)	mtx_lock(&isp->isp_osinfo.lock)
240 #define	ISP_UNLOCK(isp)	mtx_unlock(&isp->isp_osinfo.lock)
241 #endif
242 
243 /*
244  * Required Macros/Defines
245  */
246 
247 #define	ISP2100_SCRLEN		0x1000
248 
249 #define	MEMZERO(a, b)		memset(a, 0, b)
250 #define	MEMCPY			memcpy
251 #define	SNPRINTF		snprintf
252 #define	USEC_DELAY		DELAY
253 #define	USEC_SLEEP(isp, x)	DELAY(x)
254 
255 #define	NANOTIME_T		struct timespec
256 #define	GET_NANOTIME		nanotime
257 #define	GET_NANOSEC(x)		((x)->tv_sec * 1000000000 + (x)->tv_nsec)
258 #define	NANOTIME_SUB		isp_nanotime_sub
259 
260 #define	MAXISPREQUEST(isp)	((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256)
261 
262 #define	MEMORYBARRIER(isp, type, offset, size)			\
263 switch (type) {							\
264 case SYNC_SFORDEV:						\
265 case SYNC_REQUEST:						\
266 	bus_dmamap_sync(isp->isp_cdmat, isp->isp_cdmap, 	\
267 	   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		\
268 	break;							\
269 case SYNC_SFORCPU:						\
270 case SYNC_RESULT:						\
271 	bus_dmamap_sync(isp->isp_cdmat, isp->isp_cdmap,		\
272 	   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);	\
273 	break;							\
274 case SYNC_REG:							\
275 	bus_space_barrier(isp->isp_bus_tag,			\
276 	    isp->isp_bus_handle, offset, size, 			\
277 	    BUS_SPACE_BARRIER_READ);				\
278 	break;							\
279 default:							\
280 	break;							\
281 }
282 
283 #define	MBOX_ACQUIRE			isp_mbox_acquire
284 #define	MBOX_WAIT_COMPLETE		isp_mbox_wait_complete
285 #define	MBOX_NOTIFY_COMPLETE		isp_mbox_notify_done
286 #define	MBOX_RELEASE			isp_mbox_release
287 
288 #define	FC_SCRATCH_ACQUIRE(isp)						\
289 	if (isp->isp_osinfo.fcbsy) {					\
290 		isp_prt(isp, ISP_LOGWARN,				\
291 		    "FC scratch area busy (line %d)!", __LINE__);	\
292 	} else								\
293 		isp->isp_osinfo.fcbsy = 1
294 #define	FC_SCRATCH_RELEASE(isp)		 isp->isp_osinfo.fcbsy = 0
295 
296 #ifndef	SCSI_GOOD
297 #define	SCSI_GOOD	SCSI_STATUS_OK
298 #endif
299 #ifndef	SCSI_CHECK
300 #define	SCSI_CHECK	SCSI_STATUS_CHECK_COND
301 #endif
302 #ifndef	SCSI_BUSY
303 #define	SCSI_BUSY	SCSI_STATUS_BUSY
304 #endif
305 #ifndef	SCSI_QFULL
306 #define	SCSI_QFULL	SCSI_STATUS_QUEUE_FULL
307 #endif
308 
309 #define	XS_T			struct ccb_scsiio
310 #define	XS_DMA_ADDR_T		bus_addr_t
311 #define	XS_ISP(ccb)		cam_sim_softc(xpt_path_sim((ccb)->ccb_h.path))
312 #define	XS_CHANNEL(ccb)		cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path))
313 #define	XS_TGT(ccb)		(ccb)->ccb_h.target_id
314 #define	XS_LUN(ccb)		(ccb)->ccb_h.target_lun
315 
316 #define	XS_CDBP(ccb)	\
317 	(((ccb)->ccb_h.flags & CAM_CDB_POINTER)? \
318 	 (ccb)->cdb_io.cdb_ptr : (ccb)->cdb_io.cdb_bytes)
319 
320 #define	XS_CDBLEN(ccb)		(ccb)->cdb_len
321 #define	XS_XFRLEN(ccb)		(ccb)->dxfer_len
322 #define	XS_TIME(ccb)		(ccb)->ccb_h.timeout
323 #define	XS_RESID(ccb)		(ccb)->resid
324 #define	XS_STSP(ccb)		(&(ccb)->scsi_status)
325 #define	XS_SNSP(ccb)		(&(ccb)->sense_data)
326 
327 #define	XS_SNSLEN(ccb)		\
328 	imin((sizeof((ccb)->sense_data)), ccb->sense_len)
329 
330 #define	XS_SNSKEY(ccb)		((ccb)->sense_data.flags & 0xf)
331 #define	XS_TAG_P(ccb)	\
332 	(((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID) && \
333 	 (ccb)->tag_action != CAM_TAG_ACTION_NONE)
334 
335 #define	XS_TAG_TYPE(ccb)	\
336 	((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \
337 	 ((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG))
338 
339 
340 #define	XS_SETERR(ccb, v)	(ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \
341 				(ccb)->ccb_h.status |= v, \
342 				(ccb)->ccb_h.spriv_field0 |= ISP_SPRIV_ERRSET
343 
344 #	define	HBA_NOERROR		CAM_REQ_INPROG
345 #	define	HBA_BOTCH		CAM_UNREC_HBA_ERROR
346 #	define	HBA_CMDTIMEOUT		CAM_CMD_TIMEOUT
347 #	define	HBA_SELTIMEOUT		CAM_SEL_TIMEOUT
348 #	define	HBA_TGTBSY		CAM_SCSI_STATUS_ERROR
349 #	define	HBA_BUSRESET		CAM_SCSI_BUS_RESET
350 #	define	HBA_ABORTED		CAM_REQ_ABORTED
351 #	define	HBA_DATAOVR		CAM_DATA_RUN_ERR
352 #	define	HBA_ARQFAIL		CAM_AUTOSENSE_FAIL
353 
354 
355 #define	XS_ERR(ccb)		((ccb)->ccb_h.status & CAM_STATUS_MASK)
356 
357 #define	XS_NOERR(ccb)		\
358 	(((ccb)->ccb_h.spriv_field0 & ISP_SPRIV_ERRSET) == 0 || \
359 	 ((ccb)->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)
360 
361 #define	XS_INITERR(ccb)		\
362 	XS_SETERR(ccb, CAM_REQ_INPROG), (ccb)->ccb_h.spriv_field0 = 0
363 
364 #define	XS_SAVE_SENSE(xs, sense_ptr, sense_len)		\
365 	(xs)->ccb_h.status |= CAM_AUTOSNS_VALID;	\
366 	memcpy(&(xs)->sense_data, sense_ptr, imin(XS_SNSLEN(xs), sense_len))
367 
368 #define	XS_SET_STATE_STAT(a, b, c)
369 
370 #define	DEFAULT_IID(x)		(isp)->isp_osinfo.default_id
371 #define	DEFAULT_LOOPID(x)	(isp)->isp_osinfo.default_id
372 #define	DEFAULT_NODEWWN(isp)	(isp)->isp_osinfo.default_node_wwn
373 #define	DEFAULT_PORTWWN(isp)	(isp)->isp_osinfo.default_port_wwn
374 #define	ISP_NODEWWN(isp)	FCPARAM(isp)->isp_wwnn_nvram
375 #define	ISP_PORTWWN(isp)	FCPARAM(isp)->isp_wwpn_nvram
376 
377 
378 #if __FreeBSD_version < 500000
379 #if _BYTE_ORDER == _LITTLE_ENDIAN
380 #define	bswap16		htobe16
381 #define	bswap32		htobe32
382 #else
383 #define	bswap16		htole16
384 #define	bswap32		htole32
385 #endif
386 #endif
387 
388 #if	BYTE_ORDER == BIG_ENDIAN
389 #ifdef	ISP_SBUS_SUPPORTED
390 #define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
391 #define	ISP_IOXPUT_16(isp, s, d)				\
392 	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap16(s)
393 #define	ISP_IOXPUT_32(isp, s, d)				\
394 	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap32(s)
395 #define	ISP_IOXGET_8(isp, s, d)		d = (*((uint8_t *)s))
396 #define	ISP_IOXGET_16(isp, s, d)				\
397 	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
398 	*((uint16_t *)s) : bswap16(*((uint16_t *)s))
399 #define	ISP_IOXGET_32(isp, s, d)				\
400 	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
401 	*((uint32_t *)s) : bswap32(*((uint32_t *)s))
402 
403 #else	/* ISP_SBUS_SUPPORTED */
404 #define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
405 #define	ISP_IOXPUT_16(isp, s, d)	*(d) = bswap16(s)
406 #define	ISP_IOXPUT_32(isp, s, d)	*(d) = bswap32(s)
407 #define	ISP_IOXGET_8(isp, s, d)		d = (*((uint8_t *)s))
408 #define	ISP_IOXGET_16(isp, s, d)	d = bswap16(*((uint16_t *)s))
409 #define	ISP_IOXGET_32(isp, s, d)	d = bswap32(*((uint32_t *)s))
410 #endif
411 #define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)	*rp = bswap16(*rp)
412 #define	ISP_SWIZZLE_NVRAM_LONG(isp, rp)	*rp = bswap32(*rp)
413 
414 #define	ISP_IOZGET_8(isp, s, d)		d = (*((uint8_t *)s))
415 #define	ISP_IOZGET_16(isp, s, d)	d = (*((uint16_t *)s))
416 #define	ISP_IOZGET_32(isp, s, d)	d = (*((uint32_t *)s))
417 #define	ISP_IOZPUT_8(isp, s, d)		*(d) = s
418 #define	ISP_IOZPUT_16(isp, s, d)	*(d) = s
419 #define	ISP_IOZPUT_32(isp, s, d)	*(d) = s
420 
421 
422 #else
423 #define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
424 #define	ISP_IOXPUT_16(isp, s, d)	*(d) = s
425 #define	ISP_IOXPUT_32(isp, s, d)	*(d) = s
426 #define	ISP_IOXGET_8(isp, s, d)		d = *(s)
427 #define	ISP_IOXGET_16(isp, s, d)	d = *(s)
428 #define	ISP_IOXGET_32(isp, s, d)	d = *(s)
429 #define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)
430 #define	ISP_SWIZZLE_NVRAM_LONG(isp, rp)
431 
432 #define	ISP_IOZPUT_8(isp, s, d)		*(d) = s
433 #define	ISP_IOZPUT_16(isp, s, d)	*(d) = bswap16(s)
434 #define	ISP_IOZPUT_32(isp, s, d)	*(d) = bswap32(s)
435 
436 #define	ISP_IOZGET_8(isp, s, d)		d = (*((uint8_t *)(s)))
437 #define	ISP_IOZGET_16(isp, s, d)	d = bswap16(*((uint16_t *)(s)))
438 #define	ISP_IOZGET_32(isp, s, d)	d = bswap32(*((uint32_t *)(s)))
439 
440 #endif
441 
442 #define	ISP_SWAP16(isp, s)	bswap16(s)
443 #define	ISP_SWAP32(isp, s)	bswap32(s)
444 
445 /*
446  * Includes of common header files
447  */
448 
449 #include <dev/isp/ispreg.h>
450 #include <dev/isp/ispvar.h>
451 #include <dev/isp/ispmbox.h>
452 
453 #ifdef	ISP_TARGET_MODE
454 #include <dev/isp/isp_tpublic.h>
455 #endif
456 
457 /*
458  * isp_osinfo definiitions && shorthand
459  */
460 #define	SIMQFRZ_RESOURCE	0x1
461 #define	SIMQFRZ_LOOPDOWN	0x2
462 #define	SIMQFRZ_TIMED		0x4
463 
464 #define	isp_sim		isp_osinfo.sim
465 #define	isp_path	isp_osinfo.path
466 #define	isp_sim2	isp_osinfo.sim2
467 #define	isp_path2	isp_osinfo.path2
468 #define	isp_dev		isp_osinfo.dev
469 
470 /*
471  * prototypes for isp_pci && isp_freebsd to share
472  */
473 extern void isp_attach(ispsoftc_t *);
474 extern void isp_uninit(ispsoftc_t *);
475 
476 /*
477  * driver global data
478  */
479 extern int isp_announced;
480 extern int isp_fabric_hysteresis;
481 extern int isp_loop_down_limit;
482 extern int isp_gone_device_time;
483 extern int isp_quickboot_time;
484 
485 /*
486  * Platform private flags
487  */
488 #define	ISP_SPRIV_ERRSET	0x1
489 #define	ISP_SPRIV_INWDOG	0x2
490 #define	ISP_SPRIV_GRACE		0x4
491 #define	ISP_SPRIV_DONE		0x8
492 
493 #define	XS_CMD_S_WDOG(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_INWDOG
494 #define	XS_CMD_C_WDOG(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_INWDOG
495 #define	XS_CMD_WDOG_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_INWDOG)
496 
497 #define	XS_CMD_S_GRACE(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_GRACE
498 #define	XS_CMD_C_GRACE(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_GRACE
499 #define	XS_CMD_GRACE_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_GRACE)
500 
501 #define	XS_CMD_S_DONE(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_DONE
502 #define	XS_CMD_C_DONE(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_DONE
503 #define	XS_CMD_DONE_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_DONE)
504 
505 #define	XS_CMD_S_CLEAR(sccb)	(sccb)->ccb_h.spriv_field0 = 0
506 
507 /*
508  * Platform Library Functions
509  */
510 void isp_prt(ispsoftc_t *, int level, const char *, ...) __printflike(3, 4);
511 uint64_t isp_nanotime_sub(struct timespec *, struct timespec *);
512 int isp_mbox_acquire(ispsoftc_t *);
513 void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *);
514 void isp_mbox_notify_done(ispsoftc_t *);
515 void isp_mbox_release(ispsoftc_t *);
516 int isp_mstohz(int);
517 void isp_platform_intr(void *);
518 void isp_common_dmateardown(ispsoftc_t *, struct ccb_scsiio *, uint32_t);
519 
520 /*
521  * Platform Version specific defines
522  */
523 #if __FreeBSD_version < 500000
524 #define	BUS_DMA_ROOTARG(x)	NULL
525 #define	isp_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z)	\
526 	bus_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z)
527 #elif	__FreeBSD_version < 700020
528 #define	BUS_DMA_ROOTARG(x)	NULL
529 #define	isp_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z)	\
530 	bus_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, \
531 	busdma_lock_mutex, &Giant, z)
532 #elif __FreeBSD_version < 700037
533 #define	BUS_DMA_ROOTARG(x)	bus_get_dma_tag(x)
534 #define	isp_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z)	\
535 	bus_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, \
536 	busdma_lock_mutex, &Giant, z)
537 #else
538 #define	BUS_DMA_ROOTARG(x)	bus_get_dma_tag(x)
539 #define	isp_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z)	\
540 	bus_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, \
541 	busdma_lock_mutex, &isp->isp_osinfo.lock, z)
542 #endif
543 
544 #if __FreeBSD_version < 700031
545 #define	isp_setup_intr(d, i, f, U, if, ifa, hp)	\
546 	bus_setup_intr(d, i, f, if, ifa, hp)
547 #else
548 #define	isp_setup_intr	bus_setup_intr
549 #endif
550 
551 #if __FreeBSD_version < 500000
552 #define	isp_sim_alloc	cam_sim_alloc
553 #define	isp_callout_init(x)	callout_init(x)
554 #elif	__FreeBSD_version < 700037
555 #define	isp_callout_init(x)	callout_init(x, 0)
556 #define	isp_sim_alloc		cam_sim_alloc
557 #else
558 #define	isp_callout_init(x)	callout_init(x, 1)
559 #define	isp_sim_alloc(a, b, c, d, e, f, g, h)	\
560 	cam_sim_alloc(a, b, c, d, e, &(d)->isp_osinfo.lock, f, g, h)
561 #endif
562 
563 /* Should be BUS_SPACE_MAXSIZE, but MAXPHYS is larger than BUS_SPACE_MAXSIZE */
564 #define ISP_NSEGS ((MAXPHYS / PAGE_SIZE) + 1)
565 
566 /*
567  * Platform specific inline functions
568  */
569 static __inline int isp_get_pcmd(ispsoftc_t *, union ccb *);
570 static __inline void isp_free_pcmd(ispsoftc_t *, union ccb *);
571 
572 static __inline int
573 isp_get_pcmd(ispsoftc_t *isp, union ccb *ccb)
574 {
575 	ISP_PCMD(ccb) = isp->isp_osinfo.pcmd_free;
576 	if (ISP_PCMD(ccb) == NULL) {
577 		return (-1);
578 	}
579 	isp->isp_osinfo.pcmd_free = ((struct isp_pcmd *)ISP_PCMD(ccb))->next;
580 	return (0);
581 }
582 
583 static __inline void
584 isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
585 {
586 	((struct isp_pcmd *)ISP_PCMD(ccb))->next = isp->isp_osinfo.pcmd_free;
587 	isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb);
588 	ISP_PCMD(ccb) = NULL;
589 }
590 
591 
592 /*
593  * ISP General Library functions
594  */
595 
596 #include <dev/isp/isp_library.h>
597 
598 #endif	/* _ISP_FREEBSD_H */
599