scsi_low.h revision 311402
1262395Sbapt/*	$FreeBSD: stable/10/sys/cam/scsi/scsi_low.h 311402 2017-01-05 11:20:31Z mav $	*/
2262395Sbapt/*	$NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $	*/
3262395Sbapt/*	$NetBSD$	*/
4262395Sbapt
5262395Sbapt#define	SCSI_LOW_DIAGNOSTIC
6262395Sbapt#define	SCSI_LOW_ALT_QTAG_ALLOCATE
7262395Sbapt
8262395Sbapt/*-
9262395Sbapt * [NetBSD for NEC PC-98 series]
10262395Sbapt *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
11262395Sbapt *	NetBSD/pc98 porting staff. All rights reserved.
12262395Sbapt *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
13262395Sbapt *	Naofumi HONDA. All rights reserved.
14262395Sbapt *
15262395Sbapt * [Ported for FreeBSD CAM]
16262395Sbapt *  Copyright (c) 2000, 2001
17262395Sbapt *      MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
18262395Sbapt *      All rights reserved.
19262395Sbapt *
20262395Sbapt *  Redistribution and use in source and binary forms, with or without
21262395Sbapt *  modification, are permitted provided that the following conditions
22262395Sbapt *  are met:
23262395Sbapt *  1. Redistributions of source code must retain the above copyright
24262395Sbapt *     notice, this list of conditions and the following disclaimer.
25262395Sbapt *  2. Redistributions in binary form must reproduce the above copyright
26262395Sbapt *     notice, this list of conditions and the following disclaimer in the
27262395Sbapt *     documentation and/or other materials provided with the distribution.
28262395Sbapt *  3. The name of the author may not be used to endorse or promote products
29262395Sbapt *     derived from this software without specific prior written permission.
30262395Sbapt *
31262395Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32262395Sbapt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33262395Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34262395Sbapt * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
35262395Sbapt * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36262395Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37262395Sbapt * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38262395Sbapt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39262395Sbapt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40262395Sbapt * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41262395Sbapt * POSSIBILITY OF SUCH DAMAGE.
42262395Sbapt */
43262395Sbapt
44262395Sbapt#ifndef	_SCSI_LOW_H_
45262395Sbapt#define	_SCSI_LOW_H_
46262395Sbapt
47262395Sbapt/*================================================
48262395Sbapt * Scsi low OSDEP
49262395Sbapt * (All os depend structures should be here!)
50262395Sbapt ================================================*/
51262395Sbapt/******** includes *******************************/
52262395Sbapt
53262395Sbapt#include <sys/bus.h>
54262395Sbapt#include <sys/kdb.h>
55262395Sbapt#include <cam/cam.h>
56262395Sbapt#include <cam/cam_ccb.h>
57262395Sbapt#include <cam/cam_sim.h>
58262395Sbapt#include <cam/cam_xpt_sim.h>
59262395Sbapt#include <cam/cam_debug.h>
60262395Sbapt
61262395Sbapt#include <cam/scsi/scsi_dvcfg.h>
62262395Sbapt#include <i386/isa/ccbque.h>
63262395Sbapt
64262395Sbapt/******** functions macro ************************/
65262395Sbapt
66262395Sbapt#undef	MSG_IDENTIFY
67262395Sbapt
68262395Sbapt/******** os depend interface structures **********/
69262395Sbapttypedef	struct scsi_sense_data scsi_low_osdep_sense_data_t;
70262395Sbapt
71262395Sbaptstruct scsi_low_osdep_interface {
72262395Sbapt	device_t si_dev;
73262395Sbapt
74262395Sbapt	struct cam_sim *sim;
75262395Sbapt	struct cam_path *path;
76262395Sbapt
77262395Sbapt	int si_poll_count;
78262395Sbapt
79262395Sbapt	struct callout_handle engage_ch;
80262395Sbapt	struct callout_handle timeout_ch;
81262395Sbapt#ifdef	SCSI_LOW_POWFUNC
82262395Sbapt	struct callout_handle recover_ch;
83262395Sbapt#endif
84262395Sbapt};
85262395Sbapt
86262395Sbapt/******** os depend interface functions *************/
87262395Sbaptstruct slccb;
88262395Sbaptstruct scsi_low_softc;
89262395Sbapt#define	SCSI_LOW_TIMEOUT_STOP		0
90262395Sbapt#define	SCSI_LOW_TIMEOUT_START		1
91262395Sbapt#define	SCSI_LOW_TIMEOUT_CH_IO		0
92262395Sbapt#define	SCSI_LOW_TIMEOUT_CH_ENGAGE	1
93262395Sbapt#define	SCSI_LOW_TIMEOUT_CH_RECOVER	2
94262395Sbapt
95262395Sbaptstruct scsi_low_osdep_funcs {
96262395Sbapt	int (*scsi_low_osdep_attach) \
97262395Sbapt			(struct scsi_low_softc *);
98262395Sbapt	int (*scsi_low_osdep_world_start) \
99262395Sbapt			(struct scsi_low_softc *);
100262395Sbapt	int (*scsi_low_osdep_dettach) \
101262395Sbapt			(struct scsi_low_softc *);
102262395Sbapt	int (*scsi_low_osdep_ccb_setup) \
103262395Sbapt			(struct scsi_low_softc *, struct slccb *);
104262395Sbapt	int (*scsi_low_osdep_done) \
105262395Sbapt			(struct scsi_low_softc *, struct slccb *);
106262395Sbapt	void (*scsi_low_osdep_timeout) \
107262395Sbapt			(struct scsi_low_softc *, int, int);
108262395Sbapt};
109262395Sbapt
110262395Sbapt/*================================================
111262395Sbapt * Generic Scsi Low header file
112262395Sbapt * (All os depend structures should be above!)
113262395Sbapt ================================================*/
114262395Sbapt/*************************************************
115262395Sbapt * Scsi low definitions
116262395Sbapt *************************************************/
117262395Sbapt#define	SCSI_LOW_SYNC		DVF_SCSI_SYNC
118262395Sbapt#define	SCSI_LOW_DISC		DVF_SCSI_DISC
119262395Sbapt#define	SCSI_LOW_WAIT		DVF_SCSI_WAIT
120262395Sbapt#define	SCSI_LOW_LINK		DVF_SCSI_LINK
121262395Sbapt#define	SCSI_LOW_QTAG		DVF_SCSI_QTAG
122262395Sbapt#define	SCSI_LOW_NOPARITY	DVF_SCSI_NOPARITY
123262395Sbapt#define	SCSI_LOW_SAVESP		DVF_SCSI_SAVESP
124262395Sbapt#define	SCSI_LOW_DEFCFG		DVF_SCSI_DEFCFG
125262395Sbapt#define	SCSI_LOW_BITS		DVF_SCSI_BITS
126262395Sbapt
127262395Sbapt#define	SCSI_LOW_PERIOD(n)	DVF_SCSI_PERIOD(n)
128262395Sbapt#define	SCSI_LOW_OFFSET(n)	DVF_SCSI_OFFSET(n)
129262395Sbapt
130262395Sbapt/* host scsi id and targets macro */
131262395Sbapt#ifndef	SCSI_LOW_NTARGETS
132262395Sbapt#define	SCSI_LOW_NTARGETS			8
133262395Sbapt#endif	/* SCSI_LOW_NTARGETS */
134262395Sbapt#define	SCSI_LOW_NCCB				128
135262395Sbapt
136262395Sbapt#define	SCSI_LOW_MAX_RETRY			3
137262395Sbapt#define	SCSI_LOW_MAX_SELECTION_RETRY		10
138262395Sbapt
139262395Sbapt/* timeout control macro */
140262395Sbapt#define	SCSI_LOW_TIMEOUT_HZ			10
141262395Sbapt#define SCSI_LOW_MIN_TOUT			12
142262395Sbapt#define SCSI_LOW_TIMEOUT_CHECK_INTERVAL 	1
143262395Sbapt#define	SCSI_LOW_POWDOWN_TC			15
144262395Sbapt#define	SCSI_LOW_MAX_PHCHANGES			256
145262395Sbapt#define	SCSI2_RESET_DELAY			5000000
146262395Sbapt
147262395Sbapt/* msg */
148262395Sbapt#define	SCSI_LOW_MAX_MSGLEN			32
149262395Sbapt#define	SCSI_LOW_MSG_LOG_DATALEN  		8
150262395Sbapt
151262395Sbapt/*************************************************
152262395Sbapt * Scsi Data Pointer
153262395Sbapt *************************************************/
154262395Sbapt/* scsi pointer */
155262395Sbaptstruct sc_p {
156262395Sbapt	u_int8_t *scp_data;
157262395Sbapt	int scp_datalen;
158262395Sbapt
159262395Sbapt	u_int8_t *scp_cmd;
160262395Sbapt	int scp_cmdlen;
161262395Sbapt
162262395Sbapt	u_int8_t scp_direction;
163262395Sbapt#define	SCSI_LOW_RWUNK	(-1)
164262395Sbapt#define	SCSI_LOW_WRITE	0
165262395Sbapt#define	SCSI_LOW_READ	1
166262395Sbapt	u_int8_t scp_status;
167262395Sbapt	u_int8_t scp_spare[2];
168262395Sbapt};
169262395Sbapt
170262395Sbapt/*************************************************
171262395Sbapt * Command Control Block Structure
172262395Sbapt *************************************************/
173262395Sbapttypedef int scsi_low_tag_t;
174262395Sbaptstruct targ_info;
175262395Sbapt
176262395Sbapt#define	SCSI_LOW_UNKLUN	((u_int) -1)
177262395Sbapt#define	SCSI_LOW_UNKTAG	((scsi_low_tag_t) -1)
178262395Sbapt
179262395Sbaptstruct slccb {
180262395Sbapt	TAILQ_ENTRY(slccb) ccb_chain;
181262395Sbapt
182262395Sbapt	void *osdep;			/* os depend structure */
183262395Sbapt
184262395Sbapt	struct targ_info *ti;		/* targ_info */
185262395Sbapt	struct lun_info *li;		/* lun info */
186262395Sbapt	struct buf *bp;			/* io bufs */
187262395Sbapt
188262395Sbapt	scsi_low_tag_t ccb_tag;		/* effective qtag */
189262395Sbapt	scsi_low_tag_t ccb_otag;	/* allocated qtag */
190262395Sbapt
191262395Sbapt	/*****************************************
192262395Sbapt	 * Scsi data pointers (original and saved)
193262395Sbapt	 *****************************************/
194262395Sbapt	struct sc_p ccb_scp;		/* given */
195262395Sbapt	struct sc_p ccb_sscp;		/* saved scsi data pointer */
196262395Sbapt	int ccb_datalen;		/* transferred data counter */
197262395Sbapt
198262395Sbapt	/*****************************************
199262395Sbapt	 * Msgout
200262395Sbapt	 *****************************************/
201262395Sbapt	u_int ccb_msgoutflag;
202262395Sbapt	u_int ccb_omsgoutflag;
203262395Sbapt
204262395Sbapt	/*****************************************
205262395Sbapt	 * Error or Timeout counters
206262395Sbapt	 *****************************************/
207262395Sbapt	u_int ccb_flags;
208262395Sbapt#define	CCB_INTERNAL	0x0001
209262395Sbapt#define	CCB_SENSE	0x0002
210262395Sbapt#define	CCB_CLEARQ	0x0004
211262395Sbapt#define	CCB_DISCQ	0x0008
212262395Sbapt#define	CCB_STARTQ	0x0010
213262395Sbapt#define	CCB_POLLED	0x0100	/* polling ccb */
214262395Sbapt#define	CCB_NORETRY	0x0200	/* do NOT retry */
215262395Sbapt#define	CCB_AUTOSENSE	0x0400	/* do a sense after CA */
216262395Sbapt#define	CCB_URGENT	0x0800	/* an urgent ccb */
217262395Sbapt#define	CCB_NOSDONE	0x1000	/* do not call an os done routine */
218262395Sbapt#define	CCB_SCSIIO	0x2000	/* a normal scsi io coming from upper layer */
219262395Sbapt#define	CCB_SILENT	0x4000	/* no terminate messages */
220262395Sbapt
221262395Sbapt	u_int ccb_error;
222262395Sbapt
223262395Sbapt	int ccb_rcnt;			/* retry counter */
224262395Sbapt	int ccb_selrcnt;		/* selection retry counter */
225262395Sbapt	int ccb_tc;			/* timer counter */
226262395Sbapt	int ccb_tcmax;			/* max timeout */
227262395Sbapt
228262395Sbapt	/*****************************************
229262395Sbapt	 * Sense data buffer
230262395Sbapt	 *****************************************/
231262395Sbapt	u_int8_t ccb_scsi_cmd[12];
232262395Sbapt	scsi_low_osdep_sense_data_t ccb_sense;
233262395Sbapt};
234262395Sbapt
235262395Sbapt/*************************************************
236262395Sbapt * Slccb functions
237262395Sbapt *************************************************/
238262395SbaptGENERIC_CCB_ASSERT(scsi_low, slccb)
239262395Sbapt
240262395Sbapt/*************************************************
241262395Sbapt * Target and Lun structures
242262395Sbapt *************************************************/
243262395Sbaptstruct scsi_low_softc;
244262395SbaptLIST_HEAD(scsi_low_softc_tab, scsi_low_softc);
245262395SbaptTAILQ_HEAD(targ_info_tab, targ_info);
246262395SbaptLIST_HEAD(lun_info_tab, lun_info);
247262395Sbapt
248262395Sbaptstruct lun_info {
249262395Sbapt	int li_lun;
250262395Sbapt	struct targ_info *li_ti;		/* my target */
251262395Sbapt
252262395Sbapt	LIST_ENTRY(lun_info) lun_chain;		/* targ_info link */
253262395Sbapt
254262395Sbapt	struct slccbtab li_discq;			/* disconnect queue */
255262395Sbapt
256262395Sbapt	/*
257262395Sbapt	 * qtag control
258262395Sbapt	 */
259262395Sbapt	int li_maxnexus;
260262395Sbapt	int li_maxnqio;
261262395Sbapt	int li_nqio;
262262395Sbapt	int li_disc;
263262395Sbapt
264262395Sbapt#define	SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY)
265262395Sbapt	u_int li_qtagbits;
266262395Sbapt
267262395Sbapt#ifdef	SCSI_LOW_ALT_QTAG_ALLOCATE
268262395Sbapt	u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS];
269262395Sbapt	u_int li_qd;
270262395Sbapt#endif	/* SCSI_LOW_ALT_QTAG_ALLOCATE */
271262395Sbapt
272262395Sbapt#define	SCSI_LOW_QFLAG_CA_QCLEAR	0x01
273262395Sbapt	u_int li_qflags;
274262395Sbapt
275262395Sbapt	/*
276262395Sbapt	 * lun state
277262395Sbapt	 */
278262395Sbapt#define	SCSI_LOW_LUN_SLEEP	0x00
279262395Sbapt#define	SCSI_LOW_LUN_START	0x01
280262395Sbapt#define	SCSI_LOW_LUN_INQ	0x02
281262395Sbapt#define	SCSI_LOW_LUN_MODEQ	0x03
282262395Sbapt#define	SCSI_LOW_LUN_OK		0x04
283262395Sbapt	u_int li_state;				/* target lun state */
284262395Sbapt
285262395Sbapt	/*
286262395Sbapt	 * lun control flags
287262395Sbapt 	 */
288262395Sbapt	u_int li_flags_valid;	/* valid flags */
289262395Sbapt#define	SCSI_LOW_LUN_FLAGS_USER_VALID	0x0001
290262395Sbapt#define	SCSI_LOW_LUN_FLAGS_DISK_VALID	0x0002
291262395Sbapt#define	SCSI_LOW_LUN_FLAGS_QUIRKS_VALID	0x0004
292262395Sbapt#define	SCSI_LOW_LUN_FLAGS_ALL_VALID \
293262395Sbapt	(SCSI_LOW_LUN_FLAGS_USER_VALID | \
294262395Sbapt	 SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID)
295262395Sbapt
296262395Sbapt	u_int li_flags;		/* real lun control flags */
297262395Sbapt	u_int li_cfgflags;	/* lun control flags given by user */
298262395Sbapt	u_int li_diskflags;	/* lun control flags given by hardware info */
299262395Sbapt	u_int li_quirks;	/* lun control flags given by upper layer */
300262395Sbapt
301262395Sbapt	/* inq buffer */
302262395Sbapt	struct scsi_low_inq_data {
303262395Sbapt		u_int8_t sd_type;
304262395Sbapt		u_int8_t sd_sp1;
305262395Sbapt		u_int8_t sd_version;
306262395Sbapt		u_int8_t sd_resp;
307262395Sbapt		u_int8_t sd_len;
308262395Sbapt		u_int8_t sd_sp2[2];
309262395Sbapt		u_int8_t sd_support;
310262395Sbapt	} __packed li_inq;
311262395Sbapt
312262395Sbapt	/* modeq buffer */
313262395Sbapt	struct scsi_low_mode_sense_data {
314262395Sbapt		u_int8_t sms_header[4];
315262395Sbapt		struct {
316262395Sbapt			u_int8_t cmp_page;
317262395Sbapt			u_int8_t cmp_length;
318262395Sbapt			u_int8_t cmp_rlec;
319262395Sbapt			u_int8_t cmp_qc;
320262395Sbapt			u_int8_t cmp_eca;
321262395Sbapt			u_int8_t cmp_spare[3];
322262395Sbapt		} __packed sms_cmp;
323262395Sbapt
324262395Sbapt	} li_sms;
325262395Sbapt};
326262395Sbapt
327262395Sbaptstruct scsi_low_msg_log {
328262395Sbapt	int slml_ptr;
329262395Sbapt	struct {
330262395Sbapt		u_int8_t msg[2];
331262395Sbapt	} slml_msg[SCSI_LOW_MSG_LOG_DATALEN];
332262395Sbapt};
333262395Sbapt
334262395Sbaptstruct targ_info {
335262395Sbapt	TAILQ_ENTRY(targ_info) ti_chain;	/* targ_info link */
336262395Sbapt
337262395Sbapt	struct scsi_low_softc *ti_sc;		/* our softc */
338262395Sbapt	u_int ti_id;				/* scsi id */
339262395Sbapt
340262395Sbapt	/*
341262395Sbapt	 * Lun chain
342262395Sbapt	 */
343262395Sbapt	struct lun_info_tab ti_litab;		/* lun chain */
344262395Sbapt
345262395Sbapt	/*
346262395Sbapt	 * total disconnected nexus
347262395Sbapt	 */
348262395Sbapt	int ti_disc;
349262395Sbapt
350262395Sbapt	/*
351262395Sbapt	 * Scsi phase control
352262395Sbapt 	 */
353262395Sbapt
354262395Sbapt#define	PH_NULL		0x00
355262395Sbapt#define	PH_ARBSTART	0x01
356262395Sbapt#define	PH_SELSTART	0x02
357262395Sbapt#define	PH_SELECTED	0x03
358262395Sbapt#define	PH_CMD		0x04
359262395Sbapt#define	PH_DATA		0x05
360262395Sbapt#define	PH_MSGIN	0x06
361262395Sbapt#define	PH_MSGOUT	0x07
362262395Sbapt#define	PH_STAT		0x08
363262395Sbapt#define	PH_DISC		0x09
364262395Sbapt#define	PH_RESEL	0x0a
365262395Sbapt	u_int ti_phase;				/* scsi phase */
366262395Sbapt	u_int ti_ophase;			/* old scsi phase */
367262395Sbapt
368262395Sbapt	/*
369262395Sbapt	 * Msg in
370262395Sbapt 	 */
371262395Sbapt	u_int ti_msginptr;			/* msgin ptr */
372262395Sbapt	u_int ti_msginlen;			/* expected msg length */
373262395Sbapt	int ti_msgin_parity_error;		/* parity error detected */
374262395Sbapt	u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN];	/* msgin buffer */
375262395Sbapt
376262395Sbapt	/*
377262395Sbapt	 * Msg out
378262395Sbapt 	 */
379262395Sbapt	u_int ti_msgflags;			/* msgs to be asserted */
380262395Sbapt	u_int ti_omsgflags;			/* msgs asserted */
381262395Sbapt	u_int ti_emsgflags;			/* a msg currently asserted */
382262395Sbapt#define	SCSI_LOW_MSG_RESET	0x00000001
383262395Sbapt#define	SCSI_LOW_MSG_REJECT	0x00000002
384262395Sbapt#define	SCSI_LOW_MSG_PARITY	0x00000004
385262395Sbapt#define	SCSI_LOW_MSG_ERROR	0x00000008
386262395Sbapt#define	SCSI_LOW_MSG_IDENTIFY	0x00000010
387262395Sbapt#define	SCSI_LOW_MSG_ABORT	0x00000020
388262395Sbapt#define	SCSI_LOW_MSG_TERMIO	0x00000040
389262395Sbapt#define	SCSI_LOW_MSG_SIMPLE_QTAG	0x00000080
390262395Sbapt#define	SCSI_LOW_MSG_ORDERED_QTAG	0x00000100
391262395Sbapt#define	SCSI_LOW_MSG_HEAD_QTAG		0x00000200
392262395Sbapt#define	SCSI_LOW_MSG_ABORT_QTAG 0x00000400
393262395Sbapt#define	SCSI_LOW_MSG_CLEAR_QTAG 0x00000800
394262395Sbapt#define	SCSI_LOW_MSG_WIDE	0x00001000
395262395Sbapt#define	SCSI_LOW_MSG_SYNCH	0x00002000
396262395Sbapt#define	SCSI_LOW_MSG_NOOP	0x00004000
397262395Sbapt#define	SCSI_LOW_MSG_LAST	0x00008000
398262395Sbapt#define	SCSI_LOW_MSG_ALL	0xffffffff
399262395Sbapt
400262395Sbapt	/* msgout buffer */
401262395Sbapt	u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN];	/* scsi msgout */
402262395Sbapt	u_int ti_msgoutlen;			/* msgout strlen */
403262395Sbapt
404262395Sbapt	/*
405262395Sbapt	 * target initialize msgout
406262395Sbapt 	 */
407262395Sbapt	u_int ti_setup_msg;		/* setup msgout requests */
408262395Sbapt	u_int ti_setup_msg_done;
409262395Sbapt
410262395Sbapt	/*
411	 * synch and wide data info
412 	 */
413	u_int ti_flags_valid;	/* valid flags */
414#define	SCSI_LOW_TARG_FLAGS_USER_VALID		0x0001
415#define	SCSI_LOW_TARG_FLAGS_DISK_VALID		0x0002
416#define	SCSI_LOW_TARG_FLAGS_QUIRKS_VALID	0x0004
417#define	SCSI_LOW_TARG_FLAGS_ALL_VALID \
418	(SCSI_LOW_TARG_FLAGS_USER_VALID | \
419	 SCSI_LOW_TARG_FLAGS_DISK_VALID | SCSI_LOW_TARG_FLAGS_QUIRKS_VALID)
420
421	u_int ti_diskflags;	/* given target disk flags */
422	u_int ti_quirks;	/* given target quirk */
423
424	struct synch {
425		u_int8_t offset;
426		u_int8_t period;
427	} ti_osynch, ti_maxsynch;		/* synch data */
428
429#define	SCSI_LOW_BUS_WIDTH_8	0
430#define	SCSI_LOW_BUS_WIDTH_16	1
431#define	SCSI_LOW_BUS_WIDTH_32	2
432	u_int ti_owidth, ti_width;
433
434	/*
435	 * lun info size.
436 	 */
437	int ti_lunsize;
438
439#ifdef	SCSI_LOW_DIAGNOSTIC
440	struct scsi_low_msg_log ti_log_msgout;
441	struct scsi_low_msg_log ti_log_msgin;
442#endif	/* SCSI_LOW_DIAGNOSTIC */
443};
444
445/*************************************************
446 * COMMON HEADER STRUCTURE
447 *************************************************/
448struct scsi_low_softc;
449struct proc;
450typedef struct scsi_low_softc *sc_low_t;
451
452#define	SCSI_LOW_START_OK	0
453#define	SCSI_LOW_START_FAIL	1
454#define	SCSI_LOW_INFO_ALLOC	0
455#define	SCSI_LOW_INFO_REVOKE	1
456#define	SCSI_LOW_INFO_DEALLOC	2
457#define	SCSI_LOW_POWDOWN	1
458#define	SCSI_LOW_ENGAGE		2
459
460#define	SC_LOW_INIT_T (int (*)(sc_low_t, int))
461#define	SC_LOW_BUSRST_T (void (*)(sc_low_t))
462#define	SC_LOW_TARG_INIT_T (int (*)(sc_low_t, struct targ_info *, int))
463#define	SC_LOW_LUN_INIT_T (int (*)(sc_low_t, struct targ_info *, struct lun_info *, int))
464#define	SC_LOW_SELECT_T (int (*)(sc_low_t, struct slccb *))
465#define	SC_LOW_ATTEN_T (void (*)(sc_low_t))
466#define	SC_LOW_NEXUS_T (int (*)(sc_low_t))
467#define	SC_LOW_MSG_T (int (*)(sc_low_t, struct targ_info *, u_int))
468#define	SC_LOW_POLL_T (int (*)(void *))
469#define	SC_LOW_POWER_T (int (*)(sc_low_t, u_int))
470#define	SC_LOW_TIMEOUT_T (int (*)(sc_low_t))
471
472struct scsi_low_funcs {
473	int (*scsi_low_init)(sc_low_t, int);
474	void (*scsi_low_bus_reset)(sc_low_t);
475	int (*scsi_low_targ_init)(sc_low_t, struct targ_info *, int);
476	int (*scsi_low_lun_init)(sc_low_t, struct targ_info *, struct lun_info *, int);
477	int (*scsi_low_start_bus)(sc_low_t, struct slccb *);
478	int (*scsi_low_establish_lun_nexus)(sc_low_t);
479	int (*scsi_low_establish_ccb_nexus)(sc_low_t);
480	void (*scsi_low_attention)(sc_low_t);
481	int (*scsi_low_msg)(sc_low_t, struct targ_info *, u_int);
482	int (*scsi_low_timeout)(sc_low_t);
483	int (*scsi_low_poll)(void *);
484	int (*scsi_low_power)(sc_low_t, u_int);
485	int (*scsi_low_ioctl)(sc_low_t, u_long, caddr_t, int, struct proc *);
486};
487
488struct scsi_low_softc {
489	/* os depend structure */
490	struct scsi_low_osdep_interface sl_si;
491#define	sl_dev	sl_si.si_dev
492	struct scsi_low_osdep_funcs *sl_osdep_fp;
493
494	/* our chain */
495	LIST_ENTRY(scsi_low_softc) sl_chain;
496
497	/* my targets */
498	struct targ_info *sl_ti[SCSI_LOW_NTARGETS];
499	struct targ_info_tab sl_titab;
500
501	/* current active T_L_Q nexus */
502	struct targ_info *sl_Tnexus;		/* Target nexus */
503	struct lun_info *sl_Lnexus;		/* Lun nexus */
504	struct slccb *sl_Qnexus;			/* Qtag nexus */
505	int sl_nexus_call;
506
507	/* ccb start queue */
508	struct slccbtab sl_start;
509
510	/* retry limit and phase change counter */
511	int sl_max_retry;
512	int sl_ph_count;
513	int sl_timeout_count;
514
515	/* selection & total num disconnect targets */
516	int sl_nio;
517	int sl_disc;
518	int sl_retry_sel;
519	struct slccb *sl_selid;
520
521	/* attention */
522	int sl_atten;			/* ATN asserted */
523	int sl_clear_atten;		/* negate ATN required */
524
525	/* scsi phase suggested by scsi msg */
526	u_int sl_msgphase;
527#define	MSGPH_NULL	0x00		/* no msg */
528#define	MSGPH_DISC	0x01		/* disconnect msg */
529#define	MSGPH_CMDC	0x02		/* cmd complete msg */
530#define	MSGPH_ABORT	0x03		/* abort seq */
531#define	MSGPH_TERM	0x04		/* current io terminate */
532#define	MSGPH_LCTERM	0x05		/* cmd link terminated */
533#define	MSGPH_RESET	0x06		/* reset target */
534
535	/* error */
536	u_int sl_error;			/* error flags */
537#define	FATALIO		0x0001		/* generic io error & retry io */
538#define	ABORTIO		0x0002		/* generic io error & terminate io */
539#define	TIMEOUTIO	0x0004		/* watch dog timeout */
540#define	SELTIMEOUTIO	0x0008		/* selection timeout */
541#define	PDMAERR		0x0010		/* dma xfer error */
542#define	MSGERR		0x0020		/* msgsys error */
543#define	PARITYERR	0x0040		/* parity error */
544#define	BUSYERR		0x0080		/* target busy error */
545#define	STATERR		0x0100		/* status error */
546#define	UACAERR		0x0200		/* target CA state, no sense check */
547#define	SENSEIO		0x1000		/* cmd not excuted but sense data ok */
548#define	SENSEERR	0x2000		/* cmd not excuted and sense data bad */
549#define	UBFERR		0x4000		/* unexpected bus free */
550#define	PENDINGIO	0x8000		/* ccb start not yet */
551#define	SCSI_LOW_ERRORBITS "\020\017ubferr\016senseerr\015senseio\012uacaerr\011staterr\010busy\007parity\006msgerr\005pdmaerr\004seltimeout\003timeout\002abort\001fatal"
552
553	/* current scsi data pointer */
554	struct sc_p sl_scp;
555
556	/* power control */
557	u_int sl_active;		/* host is busy state */
558	int sl_powc;			/* power down timer counter */
559	u_int sl_rstep;			/* resume step */
560
561	/* configuration flags */
562	u_int sl_flags;
563#define	HW_POWDOWN	0x0001
564#define	HW_RESUME	0x0002
565#define	HW_PDMASTART	0x0004
566#define	HW_INACTIVE	0x0008
567#define	HW_POWERCTRL	0x0010
568#define	HW_INITIALIZING 0x0020
569#define	HW_READ_PADDING		0x1000
570#define	HW_WRITE_PADDING	0x2000
571
572	u_int sl_cfgflags;
573#define	CFG_NODISC		0x0001
574#define	CFG_NOPARITY		0x0002
575#define	CFG_NOATTEN		0x0004
576#define	CFG_ASYNC		0x0008
577#define	CFG_NOQTAG		0x0010
578
579	int sl_show_result;
580#define	SHOW_SYNCH_NEG	0x0001
581#define	SHOW_WIDE_NEG	0x0002
582#define	SHOW_CALCF_RES	0x0010
583#define	SHOW_PROBE_RES	0x0020
584#define	SHOW_ALL_NEG	-1
585
586	/* host informations */
587	u_int sl_hostid;
588	int sl_nluns;
589	int sl_ntargs;
590	int sl_openings;
591
592	/* interface functions */
593	struct scsi_low_funcs *sl_funcs;
594
595	/* targinfo size */
596	int sl_targsize;
597};
598
599/*************************************************
600 * SCSI LOW service functions
601 *************************************************/
602/*
603 * Scsi low attachment function.
604 */
605int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int);
606int scsi_low_dettach(struct scsi_low_softc *);
607
608/*
609 * Scsi low interface activate or deactivate functions
610 */
611int scsi_low_is_busy(struct scsi_low_softc *);
612int scsi_low_activate(struct scsi_low_softc *);
613int scsi_low_deactivate(struct scsi_low_softc *);
614
615/*
616 * Scsi phase "bus service" functions.
617 * These functions are corresponding to each scsi bus phaeses.
618 */
619/* bus idle phase (other initiators or targets release bus) */
620void scsi_low_bus_idle(struct scsi_low_softc *);
621
622/* arbitration and selection phase */
623void scsi_low_arbit_fail(struct scsi_low_softc *, struct slccb *);
624static __inline void scsi_low_arbit_win(struct scsi_low_softc *);
625
626/* msgout phase */
627#define	SCSI_LOW_MSGOUT_INIT		0x00000001
628#define	SCSI_LOW_MSGOUT_UNIFY		0x00000002
629int scsi_low_msgout(struct scsi_low_softc *, struct targ_info *, u_int);
630
631/* msgin phase */
632#define SCSI_LOW_DATA_PE	0x80000000
633int scsi_low_msgin(struct scsi_low_softc *, struct targ_info *, u_int);
634
635/* statusin phase */
636static __inline int scsi_low_statusin(struct scsi_low_softc *, struct targ_info *, u_int);
637
638/* data phase */
639int scsi_low_data(struct scsi_low_softc *, struct targ_info *, struct buf **, int);
640static __inline void scsi_low_data_finish(struct scsi_low_softc *);
641
642/* cmd phase */
643int scsi_low_cmd(struct scsi_low_softc *, struct targ_info *);
644
645/* reselection phase */
646struct targ_info *scsi_low_reselected(struct scsi_low_softc *, u_int);
647
648/* disconnection phase */
649int scsi_low_disconnected(struct scsi_low_softc *, struct targ_info *);
650
651/*
652 * Scsi bus restart function.
653 * Canncel all established nexuses => scsi system initialized => restart jobs.
654 */
655#define	SCSI_LOW_RESTART_HARD	1
656#define	SCSI_LOW_RESTART_SOFT	0
657int scsi_low_restart(struct scsi_low_softc *, int, u_char *);
658
659/*
660 * Scsi utility fucntions
661 */
662/* print current status */
663void scsi_low_print(struct scsi_low_softc *, struct targ_info *);
664
665/* bus reset utility */
666void scsi_low_bus_reset(struct scsi_low_softc *);
667
668/*************************************************
669 * Message macro defs
670 *************************************************/
671#define	SCSI_LOW_SETUP_PHASE(ti, phase)			\
672{							\
673	(ti)->ti_ophase = ti->ti_phase;			\
674	(ti)->ti_phase = (phase);			\
675}
676
677#define	SCSI_LOW_SETUP_MSGPHASE(slp, PHASE)		\
678{							\
679	(slp)->sl_msgphase = (PHASE);			\
680}
681
682#define	SCSI_LOW_ASSERT_ATN(slp)			\
683{							\
684	(slp)->sl_atten = 1;				\
685}
686
687#define	SCSI_LOW_DEASSERT_ATN(slp)			\
688{							\
689	(slp)->sl_atten = 0;				\
690}
691
692/*************************************************
693 * Inline functions
694 *************************************************/
695static __inline void scsi_low_attention(struct scsi_low_softc *);
696static __inline int scsi_low_is_msgout_continue(struct targ_info *, u_int);
697static __inline int scsi_low_assert_msg(struct scsi_low_softc *, struct targ_info *, u_int, int);
698static __inline int scsi_low_is_disconnect_ok(struct slccb *);
699
700static __inline int
701scsi_low_is_msgout_continue(ti, mask)
702	struct targ_info *ti;
703	u_int mask;
704{
705
706	return ((ti->ti_msgflags & (~mask)) != 0);
707}
708
709static __inline int
710scsi_low_is_disconnect_ok(cb)
711	struct slccb *cb;
712{
713
714	return ((cb->li->li_flags & SCSI_LOW_DISC) != 0 &&
715		    (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) == 0);
716}
717
718static __inline void
719scsi_low_attention(slp)
720	struct scsi_low_softc *slp;
721{
722
723	if (slp->sl_atten != 0)
724		return;
725
726	(*slp->sl_funcs->scsi_low_attention) (slp);
727	SCSI_LOW_ASSERT_ATN(slp);
728}
729
730static __inline int
731scsi_low_assert_msg(slp, ti, msg, now)
732	struct scsi_low_softc *slp;
733	struct targ_info *ti;
734	u_int msg;
735	int now;
736{
737
738	ti->ti_msgflags |= msg;
739	if (now != 0)
740		scsi_low_attention(slp);
741	return 0;
742}
743
744static __inline void
745scsi_low_arbit_win(slp)
746	struct scsi_low_softc *slp;
747{
748
749	slp->sl_selid = NULL;
750}
751
752static __inline void
753scsi_low_data_finish(slp)
754	struct scsi_low_softc *slp;
755{
756
757	if (slp->sl_Qnexus != NULL)
758	{
759		slp->sl_Qnexus->ccb_datalen = slp->sl_scp.scp_datalen;
760	}
761}
762
763static __inline int
764scsi_low_statusin(slp, ti, c)
765	struct scsi_low_softc *slp;
766	struct targ_info *ti;
767	u_int c;
768{
769
770	slp->sl_ph_count ++;
771	if ((c & SCSI_LOW_DATA_PE) != 0)
772	{
773		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 0);
774		return EIO;
775	}
776	slp->sl_scp.scp_status = (u_int8_t) c;
777	return 0;
778}
779
780/*************************************************
781 * Message out defs
782 *************************************************/
783/* XXX: use scsi_message.h */
784#define	ST_GOOD		0x00
785#define	ST_CHKCOND	0x02
786#define	ST_MET		0x04
787#define	ST_BUSY		0x08
788#define	ST_INTERGOOD	0x10
789#define	ST_INTERMET	0x14
790#define	ST_CONFLICT	0x18
791#define	ST_CMDTERM	0x22
792#define	ST_QUEFULL	0x28
793#define	ST_UNKNOWN	0xff
794
795#define	MSG_COMP	0x00
796#define	MSG_EXTEND	0x01
797
798#define	MKMSG_EXTEND(XLEN, XCODE) ((((u_int)(XLEN)) << NBBY) | ((u_int)(XCODE)))
799#define	MSG_EXTEND_MDPCODE	0x00
800#define	MSG_EXTEND_MDPLEN	0x05
801#define	MSG_EXTEND_SYNCHCODE	0x01
802#define	MSG_EXTEND_SYNCHLEN	0x03
803#define	MSG_EXTEND_WIDECODE	0x03
804#define	MSG_EXTEND_WIDELEN	0x02
805
806#define	MSG_SAVESP	0x02
807#define	MSG_RESTORESP	0x03
808#define	MSG_DISCON	0x04
809#define	MSG_I_ERROR	0x05
810#define	MSG_ABORT	0x06
811#define	MSG_REJECT	0x07
812#define	MSG_NOOP	0x08
813#define	MSG_PARITY	0x09
814#define	MSG_LCOMP	0x0a
815#define	MSG_LCOMP_F	0x0b
816#define	MSG_RESET	0x0c
817#define	MSG_ABORT_QTAG	0x0d
818#define	MSG_CLEAR_QTAG	0x0e
819#define	MSG_TERM_IO	0x11
820#define	MSG_SIMPLE_QTAG	0x20
821#define	MSG_HEAD_QTAG	0x21
822#define	MSG_ORDERED_QTAG	0x22
823#define	MSG_IDENTIFY	  	0x80
824#define	MSG_IDENTIFY_DISCPRIV	0x40
825#endif	/* !_SCSI_LOW_H_ */
826