isp_freebsd.h revision 237210
1/* $FreeBSD: head/sys/dev/isp/isp_freebsd.h 237210 2012-06-17 21:39:40Z mjacob $ */
2/*-
3 * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions
4 *
5 * Copyright (c) 1997-2008 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#include <sys/lock.h>
36#include <sys/kernel.h>
37#include <sys/queue.h>
38#include <sys/malloc.h>
39#include <sys/mutex.h>
40#include <sys/condvar.h>
41#include <sys/sysctl.h>
42
43#include <sys/proc.h>
44#include <sys/bus.h>
45#include <sys/taskqueue.h>
46
47#include <machine/bus.h>
48#include <machine/cpu.h>
49#include <machine/stdarg.h>
50
51#include <cam/cam.h>
52#include <cam/cam_debug.h>
53#include <cam/cam_ccb.h>
54#include <cam/cam_sim.h>
55#include <cam/cam_xpt.h>
56#include <cam/cam_xpt_sim.h>
57#include <cam/cam_debug.h>
58#include <cam/scsi/scsi_all.h>
59#include <cam/scsi/scsi_message.h>
60
61#include "opt_ddb.h"
62#include "opt_isp.h"
63
64#define	ISP_PLATFORM_VERSION_MAJOR	7
65#define	ISP_PLATFORM_VERSION_MINOR	0
66
67/*
68 * Efficiency- get rid of SBus code && tests unless we need them.
69 */
70#ifdef __sparc64__
71#define	ISP_SBUS_SUPPORTED	1
72#else
73#define	ISP_SBUS_SUPPORTED	0
74#endif
75
76#define	ISP_IFLAGS	INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE
77
78#ifdef	ISP_TARGET_MODE
79/* Not quite right, but there was no bump for this change */
80#if __FreeBSD_version < 225469
81#define	SDFIXED(x)	(&x)
82#else
83#define	SDFIXED(x)	((struct scsi_sense_data_fixed *)(&x))
84#endif
85
86#define	ISP_TARGET_FUNCTIONS	1
87#define	ATPDPSIZE	4096
88
89#include <dev/isp/isp_target.h>
90
91typedef struct {
92	void *		next;
93	uint32_t	orig_datalen;
94	uint32_t	bytes_xfered;
95	uint32_t	last_xframt;
96	uint32_t	tag;
97	uint32_t	lun;
98	uint32_t	nphdl;
99	uint32_t	sid;
100	uint32_t	portid;
101	uint32_t
102			oxid	: 16,
103			cdb0	: 8,
104				: 1,
105			dead	: 1,
106			tattr	: 3,
107			state	: 3;
108} atio_private_data_t;
109#define	ATPD_STATE_FREE			0
110#define	ATPD_STATE_ATIO			1
111#define	ATPD_STATE_CAM			2
112#define	ATPD_STATE_CTIO			3
113#define	ATPD_STATE_LAST_CTIO		4
114#define	ATPD_STATE_PDON			5
115
116typedef union inot_private_data inot_private_data_t;
117union inot_private_data {
118	inot_private_data_t *next;
119	struct {
120		isp_notify_t nt;	/* must be first! */
121		uint8_t data[64];	/* sb QENTRY_LEN, but order of definitions is wrong */
122		uint32_t tag_id, seq_id;
123	} rd;
124};
125
126typedef struct tstate {
127	SLIST_ENTRY(tstate) next;
128	struct cam_path *owner;
129	struct ccb_hdr_slist atios;
130	struct ccb_hdr_slist inots;
131	uint32_t hold;
132	uint32_t
133		enabled		: 1,
134		atio_count	: 15,
135		inot_count	: 15;
136	inot_private_data_t *	restart_queue;
137	inot_private_data_t *	ntfree;
138	inot_private_data_t	ntpool[ATPDPSIZE];
139	atio_private_data_t *	atfree;
140	atio_private_data_t	atpool[ATPDPSIZE];
141} tstate_t;
142
143#define	LUN_HASH_SIZE		32
144#define	LUN_HASH_FUNC(lun)	((lun) & (LUN_HASH_SIZE - 1))
145
146#endif
147
148/*
149 * Per command info.
150 */
151struct isp_pcmd {
152	struct isp_pcmd *	next;
153	bus_dmamap_t 		dmap;	/* dma map for this command */
154	struct ispsoftc *	isp;	/* containing isp */
155	struct callout		wdog;	/* watchdog timer */
156	uint8_t 		crn;	/* command reference number */
157};
158#define	ISP_PCMD(ccb)		(ccb)->ccb_h.spriv_ptr1
159#define	PISP_PCMD(ccb)		((struct isp_pcmd *)ISP_PCMD(ccb))
160
161/*
162 * Per channel information
163 */
164SLIST_HEAD(tslist, tstate);
165
166struct isp_fc {
167	struct cam_sim *sim;
168	struct cam_path *path;
169	struct ispsoftc *isp;
170	struct proc *kproc;
171	bus_dma_tag_t tdmat;
172	bus_dmamap_t tdmap;
173	uint64_t def_wwpn;
174	uint64_t def_wwnn;
175	uint32_t loop_down_time;
176	uint32_t loop_down_limit;
177	uint32_t gone_device_time;
178	uint32_t
179#ifdef	ISP_TARGET_MODE
180#ifdef	ISP_INTERNAL_TARGET
181		proc_active	: 1,
182#endif
183		tm_luns_enabled	: 1,
184		tm_enable_defer	: 1,
185		tm_enabled	: 1,
186#endif
187		simqfrozen	: 3,
188		default_id	: 8,
189		hysteresis	: 8,
190		def_role	: 2,	/* default role */
191		gdt_running	: 1,
192		loop_dead	: 1,
193		fcbsy		: 1,
194		ready		: 1;
195	struct callout ldt;	/* loop down timer */
196	struct callout gdt;	/* gone device timer */
197	struct task ltask;
198	struct task gtask;
199#ifdef	ISP_TARGET_MODE
200	struct tslist lun_hash[LUN_HASH_SIZE];
201#ifdef	ISP_INTERNAL_TARGET
202	struct proc *		target_proc;
203#endif
204#endif
205	uint8_t	crnseed;	/* next command reference number */
206};
207
208struct isp_spi {
209	struct cam_sim *sim;
210	struct cam_path *path;
211	uint32_t
212#ifdef	ISP_TARGET_MODE
213#ifdef	ISP_INTERNAL_TARGET
214		proc_active	: 1,
215#endif
216		tm_luns_enabled	: 1,
217		tm_enable_defer	: 1,
218		tm_enabled	: 1,
219#endif
220		simqfrozen	: 3,
221		def_role	: 2,
222		iid		: 4;
223#ifdef	ISP_TARGET_MODE
224	struct tslist lun_hash[LUN_HASH_SIZE];
225#ifdef	ISP_INTERNAL_TARGET
226	struct proc *		target_proc;
227#endif
228#endif
229};
230
231struct isposinfo {
232	/*
233	 * Linkage, locking, and identity
234	 */
235	struct mtx		lock;
236	device_t		dev;
237	struct cdev *		cdev;
238	struct intr_config_hook	ehook;
239	struct cam_devq *	devq;
240
241	/*
242	 * Firmware pointer
243	 */
244	const struct firmware *	fw;
245
246	/*
247	 * DMA related sdtuff
248	 */
249	bus_space_tag_t		bus_tag;
250	bus_dma_tag_t		dmat;
251	bus_space_handle_t	bus_handle;
252	bus_dma_tag_t		cdmat;
253	bus_dmamap_t		cdmap;
254
255	/*
256	 * Command and transaction related related stuff
257	 */
258	struct isp_pcmd *	pcmd_pool;
259	struct isp_pcmd *	pcmd_free;
260
261	uint32_t
262#ifdef	ISP_TARGET_MODE
263		tmwanted	: 1,
264		tmbusy		: 1,
265#else
266				: 2,
267#endif
268		timer_active	: 1,
269		autoconf	: 1,
270		ehook_active	: 1,
271		disabled	: 1,
272		mbox_sleeping	: 1,
273		mbox_sleep_ok	: 1,
274		mboxcmd_done	: 1,
275		mboxbsy		: 1;
276
277	struct callout		tmo;	/* general timer */
278
279	/*
280	 * misc- needs to be sorted better XXXXXX
281	 */
282	int			framesize;
283	int			exec_throttle;
284	int			cont_max;
285
286#ifdef	ISP_TARGET_MODE
287	cam_status *		rptr;
288#endif
289
290	/*
291	 * Per-type private storage...
292	 */
293	union {
294		struct isp_fc *fc;
295		struct isp_spi *spi;
296		void *ptr;
297	} pc;
298};
299#define	ISP_FC_PC(isp, chan)	(&(isp)->isp_osinfo.pc.fc[(chan)])
300#define	ISP_SPI_PC(isp, chan)	(&(isp)->isp_osinfo.pc.spi[(chan)])
301#define	ISP_GET_PC(isp, chan, tag, rslt)		\
302	if (IS_SCSI(isp)) {				\
303		rslt = ISP_SPI_PC(isp, chan)-> tag;	\
304	} else {					\
305		rslt = ISP_FC_PC(isp, chan)-> tag;	\
306	}
307#define	ISP_GET_PC_ADDR(isp, chan, tag, rp)		\
308	if (IS_SCSI(isp)) {				\
309		rp = &ISP_SPI_PC(isp, chan)-> tag;	\
310	} else {					\
311		rp = &ISP_FC_PC(isp, chan)-> tag;	\
312	}
313#define	ISP_SET_PC(isp, chan, tag, val)			\
314	if (IS_SCSI(isp)) {				\
315		ISP_SPI_PC(isp, chan)-> tag = val;	\
316	} else {					\
317		ISP_FC_PC(isp, chan)-> tag = val;	\
318	}
319
320#define	FCP_NEXT_CRN(isp, cmd, rslt, chan, tgt, lun)				\
321	if ((isp)->isp_osinfo.pc.fc[(chan)].crnseed == 0) {			\
322		(isp)->isp_osinfo.pc.fc[(chan)].crnseed = 1;			\
323	}									\
324	if (cmd) {								\
325		PISP_PCMD(cmd)->crn = (isp)->isp_osinfo.pc.fc[(chan)].crnseed;	\
326	}									\
327	(rslt) = (isp)->isp_osinfo.pc.fc[(chan)].crnseed++
328
329
330#define	isp_lock	isp_osinfo.lock
331#define	isp_bus_tag	isp_osinfo.bus_tag
332#define	isp_bus_handle	isp_osinfo.bus_handle
333
334/*
335 * Locking macros...
336 */
337#define	ISP_LOCK(isp)	mtx_lock(&isp->isp_osinfo.lock)
338#define	ISP_UNLOCK(isp)	mtx_unlock(&isp->isp_osinfo.lock)
339
340/*
341 * Required Macros/Defines
342 */
343
344#define	ISP_FC_SCRLEN		0x1000
345
346#define	ISP_MEMZERO(a, b)	memset(a, 0, b)
347#define	ISP_MEMCPY		memcpy
348#define	ISP_SNPRINTF		snprintf
349#define	ISP_DELAY		DELAY
350#define	ISP_SLEEP(isp, x)	DELAY(x)
351
352#define	ISP_MIN			imin
353
354#ifndef	DIAGNOSTIC
355#define	ISP_INLINE		__inline
356#else
357#define	ISP_INLINE
358#endif
359
360#define	NANOTIME_T		struct timespec
361#define	GET_NANOTIME		nanotime
362#define	GET_NANOSEC(x)		((x)->tv_sec * 1000000000 + (x)->tv_nsec)
363#define	NANOTIME_SUB		isp_nanotime_sub
364
365#define	MAXISPREQUEST(isp)	((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256)
366
367#define	MEMORYBARRIER(isp, type, offset, size, chan)		\
368switch (type) {							\
369case SYNC_SFORDEV:						\
370{								\
371	struct isp_fc *fc = ISP_FC_PC(isp, chan);		\
372	bus_dmamap_sync(fc->tdmat, fc->tdmap,			\
373	   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		\
374	break;							\
375}								\
376case SYNC_REQUEST:						\
377	bus_dmamap_sync(isp->isp_osinfo.cdmat,			\
378	   isp->isp_osinfo.cdmap, 				\
379	   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);		\
380	break;							\
381case SYNC_SFORCPU:						\
382{								\
383	struct isp_fc *fc = ISP_FC_PC(isp, chan);		\
384	bus_dmamap_sync(fc->tdmat, fc->tdmap,			\
385	   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);	\
386	break;							\
387}								\
388case SYNC_RESULT:						\
389	bus_dmamap_sync(isp->isp_osinfo.cdmat, 			\
390	   isp->isp_osinfo.cdmap,				\
391	   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);	\
392	break;							\
393case SYNC_REG:							\
394	bus_space_barrier(isp->isp_osinfo.bus_tag,		\
395	    isp->isp_osinfo.bus_handle, offset, size,		\
396	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);	\
397	break;							\
398default:							\
399	break;							\
400}
401
402#define	MBOX_ACQUIRE			isp_mbox_acquire
403#define	MBOX_WAIT_COMPLETE		isp_mbox_wait_complete
404#define	MBOX_NOTIFY_COMPLETE		isp_mbox_notify_done
405#define	MBOX_RELEASE			isp_mbox_release
406
407#define	FC_SCRATCH_ACQUIRE		isp_fc_scratch_acquire
408#define	FC_SCRATCH_RELEASE(isp, chan)	isp->isp_osinfo.pc.fc[chan].fcbsy = 0
409
410#ifndef	SCSI_GOOD
411#define	SCSI_GOOD	SCSI_STATUS_OK
412#endif
413#ifndef	SCSI_CHECK
414#define	SCSI_CHECK	SCSI_STATUS_CHECK_COND
415#endif
416#ifndef	SCSI_BUSY
417#define	SCSI_BUSY	SCSI_STATUS_BUSY
418#endif
419#ifndef	SCSI_QFULL
420#define	SCSI_QFULL	SCSI_STATUS_QUEUE_FULL
421#endif
422
423#define	XS_T			struct ccb_scsiio
424#define	XS_DMA_ADDR_T		bus_addr_t
425#define XS_GET_DMA64_SEG(a, b, c)		\
426{						\
427	ispds64_t *d = a;			\
428	bus_dma_segment_t *e = b;		\
429	uint32_t f = c;				\
430	e += f;					\
431        d->ds_base = DMA_LO32(e->ds_addr);	\
432        d->ds_basehi = DMA_HI32(e->ds_addr);	\
433        d->ds_count = e->ds_len;		\
434}
435#define XS_GET_DMA_SEG(a, b, c)			\
436{						\
437	ispds_t *d = a;				\
438	bus_dma_segment_t *e = b;		\
439	uint32_t f = c;				\
440	e += f;					\
441        d->ds_base = DMA_LO32(e->ds_addr);	\
442        d->ds_count = e->ds_len;		\
443}
444#define	XS_ISP(ccb)		cam_sim_softc(xpt_path_sim((ccb)->ccb_h.path))
445#define	XS_CHANNEL(ccb)		cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path))
446#define	XS_TGT(ccb)		(ccb)->ccb_h.target_id
447#define	XS_LUN(ccb)		(ccb)->ccb_h.target_lun
448
449#define	XS_CDBP(ccb)	\
450	(((ccb)->ccb_h.flags & CAM_CDB_POINTER)? \
451	 (ccb)->cdb_io.cdb_ptr : (ccb)->cdb_io.cdb_bytes)
452
453#define	XS_CDBLEN(ccb)		(ccb)->cdb_len
454#define	XS_XFRLEN(ccb)		(ccb)->dxfer_len
455#define	XS_TIME(ccb)		(ccb)->ccb_h.timeout
456#define	XS_GET_RESID(ccb)	(ccb)->resid
457#define	XS_SET_RESID(ccb, r)	(ccb)->resid = r
458#define	XS_STSP(ccb)		(&(ccb)->scsi_status)
459#define	XS_SNSP(ccb)		(&(ccb)->sense_data)
460
461#define	XS_SNSLEN(ccb)		\
462	imin((sizeof((ccb)->sense_data)), ccb->sense_len - ccb->sense_resid)
463
464#define	XS_SNSKEY(ccb)		(scsi_get_sense_key(&(ccb)->sense_data, \
465				 ccb->sense_len - ccb->sense_resid, 	\
466				 /*show_errors*/ 1))
467
468#define	XS_SNSASC(ccb)		(scsi_get_asc(&(ccb)->sense_data,	\
469				 ccb->sense_len - ccb->sense_resid, 	\
470				 /*show_errors*/ 1))
471
472#define	XS_SNSASCQ(ccb)		(scsi_get_ascq(&(ccb)->sense_data,	\
473				 ccb->sense_len - ccb->sense_resid, 	\
474				 /*show_errors*/ 1))
475#define	XS_TAG_P(ccb)	\
476	(((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID) && \
477	 (ccb)->tag_action != CAM_TAG_ACTION_NONE)
478
479#define	XS_TAG_TYPE(ccb)	\
480	((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \
481	 ((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG))
482
483
484#define	XS_SETERR(ccb, v)	(ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \
485				(ccb)->ccb_h.status |= v, \
486				(ccb)->ccb_h.spriv_field0 |= ISP_SPRIV_ERRSET
487
488#	define	HBA_NOERROR		CAM_REQ_INPROG
489#	define	HBA_BOTCH		CAM_UNREC_HBA_ERROR
490#	define	HBA_CMDTIMEOUT		CAM_CMD_TIMEOUT
491#	define	HBA_SELTIMEOUT		CAM_SEL_TIMEOUT
492#	define	HBA_TGTBSY		CAM_SCSI_STATUS_ERROR
493#	define	HBA_BUSRESET		CAM_SCSI_BUS_RESET
494#	define	HBA_ABORTED		CAM_REQ_ABORTED
495#	define	HBA_DATAOVR		CAM_DATA_RUN_ERR
496#	define	HBA_ARQFAIL		CAM_AUTOSENSE_FAIL
497
498
499#define	XS_ERR(ccb)		((ccb)->ccb_h.status & CAM_STATUS_MASK)
500
501#define	XS_NOERR(ccb)		\
502	(((ccb)->ccb_h.spriv_field0 & ISP_SPRIV_ERRSET) == 0 || \
503	 ((ccb)->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)
504
505#define	XS_INITERR(ccb)		\
506	XS_SETERR(ccb, CAM_REQ_INPROG), (ccb)->ccb_h.spriv_field0 = 0
507
508#define	XS_SAVE_SENSE(xs, sense_ptr, slen)	do {			\
509		(xs)->ccb_h.status |= CAM_AUTOSNS_VALID;		\
510		memset(&(xs)->sense_data, 0, sizeof((xs)->sense_data));	\
511		memcpy(&(xs)->sense_data, sense_ptr, imin(XS_SNSLEN(xs),\
512		       slen)); 						\
513		if (slen < (xs)->sense_len) 				\
514			(xs)->sense_resid = (xs)->sense_len - slen;	\
515	} while (0);
516
517#define	XS_SENSE_VALID(xs)	(((xs)->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
518
519#define	DEFAULT_FRAMESIZE(isp)		isp->isp_osinfo.framesize
520#define	DEFAULT_EXEC_THROTTLE(isp)	isp->isp_osinfo.exec_throttle
521
522#define	GET_DEFAULT_ROLE(isp, chan)	\
523	(IS_FC(isp)? ISP_FC_PC(isp, chan)->def_role : ISP_SPI_PC(isp, chan)->def_role)
524#define	SET_DEFAULT_ROLE(isp, chan, val)		\
525	if (IS_FC(isp)) { 				\
526		ISP_FC_PC(isp, chan)->def_role = val;	\
527	} else {					\
528		ISP_SPI_PC(isp, chan)->def_role = val;	\
529	}
530
531#define	DEFAULT_IID(isp, chan)		isp->isp_osinfo.pc.spi[chan].iid
532
533#define	DEFAULT_LOOPID(x, chan)		isp->isp_osinfo.pc.fc[chan].default_id
534
535#define DEFAULT_NODEWWN(isp, chan)  	isp_default_wwn(isp, chan, 0, 1)
536#define DEFAULT_PORTWWN(isp, chan)  	isp_default_wwn(isp, chan, 0, 0)
537#define ACTIVE_NODEWWN(isp, chan)   	isp_default_wwn(isp, chan, 1, 1)
538#define ACTIVE_PORTWWN(isp, chan)   	isp_default_wwn(isp, chan, 1, 0)
539
540
541#if	BYTE_ORDER == BIG_ENDIAN
542#ifdef	ISP_SBUS_SUPPORTED
543#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
544#define	ISP_IOXPUT_16(isp, s, d)				\
545	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap16(s)
546#define	ISP_IOXPUT_32(isp, s, d)				\
547	*(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap32(s)
548#define	ISP_IOXGET_8(isp, s, d)		d = (*((uint8_t *)s))
549#define	ISP_IOXGET_16(isp, s, d)				\
550	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
551	*((uint16_t *)s) : bswap16(*((uint16_t *)s))
552#define	ISP_IOXGET_32(isp, s, d)				\
553	d = (isp->isp_bustype == ISP_BT_SBUS)?			\
554	*((uint32_t *)s) : bswap32(*((uint32_t *)s))
555
556#else	/* ISP_SBUS_SUPPORTED */
557#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
558#define	ISP_IOXPUT_16(isp, s, d)	*(d) = bswap16(s)
559#define	ISP_IOXPUT_32(isp, s, d)	*(d) = bswap32(s)
560#define	ISP_IOXGET_8(isp, s, d)		d = (*((uint8_t *)s))
561#define	ISP_IOXGET_16(isp, s, d)	d = bswap16(*((uint16_t *)s))
562#define	ISP_IOXGET_32(isp, s, d)	d = bswap32(*((uint32_t *)s))
563#endif
564#define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)	*rp = bswap16(*rp)
565#define	ISP_SWIZZLE_NVRAM_LONG(isp, rp)	*rp = bswap32(*rp)
566
567#define	ISP_IOZGET_8(isp, s, d)		d = (*((uint8_t *)s))
568#define	ISP_IOZGET_16(isp, s, d)	d = (*((uint16_t *)s))
569#define	ISP_IOZGET_32(isp, s, d)	d = (*((uint32_t *)s))
570#define	ISP_IOZPUT_8(isp, s, d)		*(d) = s
571#define	ISP_IOZPUT_16(isp, s, d)	*(d) = s
572#define	ISP_IOZPUT_32(isp, s, d)	*(d) = s
573
574
575#else
576#define	ISP_IOXPUT_8(isp, s, d)		*(d) = s
577#define	ISP_IOXPUT_16(isp, s, d)	*(d) = s
578#define	ISP_IOXPUT_32(isp, s, d)	*(d) = s
579#define	ISP_IOXGET_8(isp, s, d)		d = *(s)
580#define	ISP_IOXGET_16(isp, s, d)	d = *(s)
581#define	ISP_IOXGET_32(isp, s, d)	d = *(s)
582#define	ISP_SWIZZLE_NVRAM_WORD(isp, rp)
583#define	ISP_SWIZZLE_NVRAM_LONG(isp, rp)
584
585#define	ISP_IOZPUT_8(isp, s, d)		*(d) = s
586#define	ISP_IOZPUT_16(isp, s, d)	*(d) = bswap16(s)
587#define	ISP_IOZPUT_32(isp, s, d)	*(d) = bswap32(s)
588
589#define	ISP_IOZGET_8(isp, s, d)		d = (*((uint8_t *)(s)))
590#define	ISP_IOZGET_16(isp, s, d)	d = bswap16(*((uint16_t *)(s)))
591#define	ISP_IOZGET_32(isp, s, d)	d = bswap32(*((uint32_t *)(s)))
592
593#endif
594
595#define	ISP_SWAP16(isp, s)	bswap16(s)
596#define	ISP_SWAP32(isp, s)	bswap32(s)
597
598/*
599 * Includes of common header files
600 */
601
602#include <dev/isp/ispreg.h>
603#include <dev/isp/ispvar.h>
604#include <dev/isp/ispmbox.h>
605
606/*
607 * isp_osinfo definiitions && shorthand
608 */
609#define	SIMQFRZ_RESOURCE	0x1
610#define	SIMQFRZ_LOOPDOWN	0x2
611#define	SIMQFRZ_TIMED		0x4
612
613#define	isp_dev		isp_osinfo.dev
614
615/*
616 * prototypes for isp_pci && isp_freebsd to share
617 */
618extern int isp_attach(ispsoftc_t *);
619extern int isp_detach(ispsoftc_t *);
620extern void isp_uninit(ispsoftc_t *);
621extern uint64_t isp_default_wwn(ispsoftc_t *, int, int, int);
622
623/*
624 * driver global data
625 */
626extern int isp_announced;
627extern int isp_fabric_hysteresis;
628extern int isp_loop_down_limit;
629extern int isp_gone_device_time;
630extern int isp_quickboot_time;
631extern int isp_autoconfig;
632
633/*
634 * Platform private flags
635 */
636#define	ISP_SPRIV_ERRSET	0x1
637#define	ISP_SPRIV_TACTIVE	0x2
638#define	ISP_SPRIV_DONE		0x8
639#define	ISP_SPRIV_WPEND		0x10
640
641#define	XS_S_TACTIVE(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_TACTIVE
642#define	XS_C_TACTIVE(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_TACTIVE
643#define	XS_TACTIVE_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_TACTIVE)
644
645#define	XS_CMD_S_DONE(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_DONE
646#define	XS_CMD_C_DONE(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_DONE
647#define	XS_CMD_DONE_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_DONE)
648
649#define	XS_CMD_S_WPEND(sccb)	(sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_WPEND
650#define	XS_CMD_C_WPEND(sccb)	(sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_WPEND
651#define	XS_CMD_WPEND_P(sccb)	((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_WPEND)
652
653#define	XS_CMD_S_CLEAR(sccb)	(sccb)->ccb_h.spriv_field0 = 0
654
655/*
656 * Platform Library Functions
657 */
658void isp_prt(ispsoftc_t *, int level, const char *, ...) __printflike(3, 4);
659void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...) __printflike(4, 5);
660uint64_t isp_nanotime_sub(struct timespec *, struct timespec *);
661int isp_mbox_acquire(ispsoftc_t *);
662void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *);
663void isp_mbox_notify_done(ispsoftc_t *);
664void isp_mbox_release(ispsoftc_t *);
665int isp_fc_scratch_acquire(ispsoftc_t *, int);
666int isp_mstohz(int);
667void isp_platform_intr(void *);
668void isp_common_dmateardown(ispsoftc_t *, struct ccb_scsiio *, uint32_t);
669
670/*
671 * Platform Version specific defines
672 */
673#define	BUS_DMA_ROOTARG(x)	bus_get_dma_tag(x)
674#define	isp_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z)	\
675	bus_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, \
676	busdma_lock_mutex, &isp->isp_osinfo.lock, z)
677
678#define	isp_setup_intr	bus_setup_intr
679
680#define	isp_sim_alloc(a, b, c, d, e, f, g, h)	\
681	cam_sim_alloc(a, b, c, d, e, &(d)->isp_osinfo.lock, f, g, h)
682
683/* Should be BUS_SPACE_MAXSIZE, but MAXPHYS is larger than BUS_SPACE_MAXSIZE */
684#define ISP_NSEGS ((MAXPHYS / PAGE_SIZE) + 1)
685
686#define	ISP_PATH_PRT(i, l, p, ...)					\
687	if ((l) == ISP_LOGALL || ((l)& (i)->isp_dblev) != 0) {		\
688                xpt_print(p, __VA_ARGS__);				\
689        }
690
691/*
692 * Platform specific inline functions
693 */
694
695/*
696 * ISP General Library functions
697 */
698
699#include <dev/isp/isp_library.h>
700
701#endif	/* _ISP_FREEBSD_H */
702