xref: /NextBSD/sys/cam/scsi/scsi_low.h (revision 65145fa4c81da358fcbc3b650156dab705dfa34e)
1 /*	$FreeBSD$	*/
2 /*	$NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $	*/
3 /*	$NetBSD$	*/
4 
5 #define	SCSI_LOW_DIAGNOSTIC
6 #define	SCSI_LOW_ALT_QTAG_ALLOCATE
7 
8 /*-
9  * [NetBSD for NEC PC-98 series]
10  *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
11  *	NetBSD/pc98 porting staff. All rights reserved.
12  *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
13  *	Naofumi HONDA. All rights reserved.
14  *
15  * [Ported for FreeBSD CAM]
16  *  Copyright (c) 2000, 2001
17  *      MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
18  *      All rights reserved.
19  *
20  *  Redistribution and use in source and binary forms, with or without
21  *  modification, are permitted provided that the following conditions
22  *  are met:
23  *  1. Redistributions of source code must retain the above copyright
24  *     notice, this list of conditions and the following disclaimer.
25  *  2. Redistributions in binary form must reproduce the above copyright
26  *     notice, this list of conditions and the following disclaimer in the
27  *     documentation and/or other materials provided with the distribution.
28  *  3. The name of the author may not be used to endorse or promote products
29  *     derived from this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
35  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGE.
42  */
43 
44 #ifndef	_SCSI_LOW_H_
45 #define	_SCSI_LOW_H_
46 
47 /******** includes *******************************/
48 
49 #include <sys/bus.h>
50 #include <sys/kdb.h>
51 #include <cam/cam.h>
52 #include <cam/cam_ccb.h>
53 #include <cam/cam_sim.h>
54 #include <cam/cam_xpt_sim.h>
55 #include <cam/cam_debug.h>
56 
57 #include <cam/scsi/scsi_dvcfg.h>
58 #include <i386/isa/ccbque.h>
59 
60 /******** functions macro ************************/
61 
62 #undef	MSG_IDENTIFY
63 
64 /*================================================
65  * Generic Scsi Low header file
66  ================================================*/
67 /*************************************************
68  * Scsi low definitions
69  *************************************************/
70 #define	SCSI_LOW_SYNC		DVF_SCSI_SYNC
71 #define	SCSI_LOW_DISC		DVF_SCSI_DISC
72 #define	SCSI_LOW_WAIT		DVF_SCSI_WAIT
73 #define	SCSI_LOW_LINK		DVF_SCSI_LINK
74 #define	SCSI_LOW_QTAG		DVF_SCSI_QTAG
75 #define	SCSI_LOW_NOPARITY	DVF_SCSI_NOPARITY
76 #define	SCSI_LOW_SAVESP		DVF_SCSI_SAVESP
77 #define	SCSI_LOW_DEFCFG		DVF_SCSI_DEFCFG
78 #define	SCSI_LOW_BITS		DVF_SCSI_BITS
79 
80 #define	SCSI_LOW_PERIOD(n)	DVF_SCSI_PERIOD(n)
81 #define	SCSI_LOW_OFFSET(n)	DVF_SCSI_OFFSET(n)
82 
83 /* host scsi id and targets macro */
84 #ifndef	SCSI_LOW_NTARGETS
85 #define	SCSI_LOW_NTARGETS			8
86 #endif	/* SCSI_LOW_NTARGETS */
87 #define	SCSI_LOW_NCCB				128
88 
89 #define	SCSI_LOW_MAX_RETRY			3
90 #define	SCSI_LOW_MAX_SELECTION_RETRY		10
91 
92 /* timeout control macro */
93 #define	SCSI_LOW_TIMEOUT_HZ			10
94 #define SCSI_LOW_MIN_TOUT			12
95 #define SCSI_LOW_TIMEOUT_CHECK_INTERVAL 	1
96 #define	SCSI_LOW_POWDOWN_TC			15
97 #define	SCSI_LOW_MAX_PHCHANGES			256
98 #define	SCSI2_RESET_DELAY			5000000
99 
100 /* msg */
101 #define	SCSI_LOW_MAX_MSGLEN			32
102 #define	SCSI_LOW_MSG_LOG_DATALEN  		8
103 
104 /*************************************************
105  * Scsi Data Pointer
106  *************************************************/
107 /* scsi pointer */
108 struct sc_p {
109 	u_int8_t *scp_data;
110 	int scp_datalen;
111 
112 	u_int8_t *scp_cmd;
113 	int scp_cmdlen;
114 
115 	u_int8_t scp_direction;
116 #define	SCSI_LOW_RWUNK	(-1)
117 #define	SCSI_LOW_WRITE	0
118 #define	SCSI_LOW_READ	1
119 	u_int8_t scp_status;
120 	u_int8_t scp_spare[2];
121 };
122 
123 /*************************************************
124  * Command Control Block Structure
125  *************************************************/
126 typedef int scsi_low_tag_t;
127 struct targ_info;
128 
129 #define	SCSI_LOW_UNKLUN	((u_int) -1)
130 #define	SCSI_LOW_UNKTAG	((scsi_low_tag_t) -1)
131 
132 struct slccb {
133 	TAILQ_ENTRY(slccb) ccb_chain;
134 
135 	void *osdep;			/* os depend structure */
136 
137 	struct targ_info *ti;		/* targ_info */
138 	struct lun_info *li;		/* lun info */
139 	struct buf *bp;			/* io bufs */
140 
141 	scsi_low_tag_t ccb_tag;		/* effective qtag */
142 	scsi_low_tag_t ccb_otag;	/* allocated qtag */
143 
144 	/*****************************************
145 	 * Scsi data pointers (original and saved)
146 	 *****************************************/
147 	struct sc_p ccb_scp;		/* given */
148 	struct sc_p ccb_sscp;		/* saved scsi data pointer */
149 	int ccb_datalen;		/* transfered data counter */
150 
151 	/*****************************************
152 	 * Msgout
153 	 *****************************************/
154 	u_int ccb_msgoutflag;
155 	u_int ccb_omsgoutflag;
156 
157 	/*****************************************
158 	 * Error or Timeout counters
159 	 *****************************************/
160 	u_int ccb_flags;
161 #define	CCB_INTERNAL	0x0001
162 #define	CCB_SENSE	0x0002
163 #define	CCB_CLEARQ	0x0004
164 #define	CCB_DISCQ	0x0008
165 #define	CCB_STARTQ	0x0010
166 #define	CCB_POLLED	0x0100	/* polling ccb */
167 #define	CCB_NORETRY	0x0200	/* do NOT retry */
168 #define	CCB_AUTOSENSE	0x0400	/* do a sence after CA */
169 #define	CCB_URGENT	0x0800	/* an urgent ccb */
170 #define	CCB_NOSDONE	0x1000	/* do not call an os done routine */
171 #define	CCB_SCSIIO	0x2000	/* a normal scsi io coming from upper layer */
172 #define	CCB_SILENT	0x4000	/* no terminate messages */
173 
174 	u_int ccb_error;
175 
176 	int ccb_rcnt;			/* retry counter */
177 	int ccb_selrcnt;		/* selection retry counter */
178 	int ccb_tc;			/* timer counter */
179 	int ccb_tcmax;			/* max timeout */
180 
181 	/*****************************************
182 	 * Sense data buffer
183 	 *****************************************/
184 	u_int8_t ccb_scsi_cmd[12];
185 	struct scsi_sense_data ccb_sense;
186 };
187 
188 /*************************************************
189  * Slccb functions
190  *************************************************/
191 GENERIC_CCB_ASSERT(scsi_low, slccb)
192 
193 /*************************************************
194  * Target and Lun structures
195  *************************************************/
196 struct scsi_low_softc;
197 LIST_HEAD(scsi_low_softc_tab, scsi_low_softc);
198 TAILQ_HEAD(targ_info_tab, targ_info);
199 LIST_HEAD(lun_info_tab, lun_info);
200 
201 struct lun_info {
202 	int li_lun;
203 	struct targ_info *li_ti;		/* my target */
204 
205 	LIST_ENTRY(lun_info) lun_chain;		/* targ_info link */
206 
207 	struct slccbtab li_discq;			/* disconnect queue */
208 
209 	/*
210 	 * qtag control
211 	 */
212 	int li_maxnexus;
213 	int li_maxnqio;
214 	int li_nqio;
215 	int li_disc;
216 
217 #define	SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY)
218 	u_int li_qtagbits;
219 
220 #ifdef	SCSI_LOW_ALT_QTAG_ALLOCATE
221 	u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS];
222 	u_int li_qd;
223 #endif	/* SCSI_LOW_ALT_QTAG_ALLOCATE */
224 
225 #define	SCSI_LOW_QFLAG_CA_QCLEAR	0x01
226 	u_int li_qflags;
227 
228 	/*
229 	 * lun state
230 	 */
231 #define	SCSI_LOW_LUN_SLEEP	0x00
232 #define	SCSI_LOW_LUN_START	0x01
233 #define	SCSI_LOW_LUN_INQ	0x02
234 #define	SCSI_LOW_LUN_MODEQ	0x03
235 #define	SCSI_LOW_LUN_OK		0x04
236 	u_int li_state;				/* target lun state */
237 
238 	/*
239 	 * lun control flags
240  	 */
241 	u_int li_flags_valid;	/* valid flags */
242 #define	SCSI_LOW_LUN_FLAGS_USER_VALID	0x0001
243 #define	SCSI_LOW_LUN_FLAGS_DISK_VALID	0x0002
244 #define	SCSI_LOW_LUN_FLAGS_QUIRKS_VALID	0x0004
245 #define	SCSI_LOW_LUN_FLAGS_ALL_VALID \
246 	(SCSI_LOW_LUN_FLAGS_USER_VALID | \
247 	 SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID)
248 
249 	u_int li_flags;		/* real lun control flags */
250 	u_int li_cfgflags;	/* lun control flags given by user */
251 	u_int li_diskflags;	/* lun control flags given by hardware info */
252 	u_int li_quirks;	/* lun control flags given by upper layer */
253 
254 	/* inq buffer */
255 	struct scsi_low_inq_data {
256 		u_int8_t sd_type;
257 		u_int8_t sd_sp1;
258 		u_int8_t sd_version;
259 		u_int8_t sd_resp;
260 		u_int8_t sd_len;
261 		u_int8_t sd_sp2[2];
262 		u_int8_t sd_support;
263 	} __packed li_inq;
264 
265 	/* modeq buffer */
266 	struct scsi_low_mode_sense_data {
267 		u_int8_t sms_header[4];
268 		struct {
269 			u_int8_t cmp_page;
270 			u_int8_t cmp_length;
271 			u_int8_t cmp_rlec;
272 			u_int8_t cmp_qc;
273 			u_int8_t cmp_eca;
274 			u_int8_t cmp_spare[3];
275 		} __packed sms_cmp;
276 
277 	} li_sms;
278 };
279 
280 struct scsi_low_msg_log {
281 	int slml_ptr;
282 	struct {
283 		u_int8_t msg[2];
284 	} slml_msg[SCSI_LOW_MSG_LOG_DATALEN];
285 };
286 
287 struct targ_info {
288 	TAILQ_ENTRY(targ_info) ti_chain;	/* targ_info link */
289 
290 	struct scsi_low_softc *ti_sc;		/* our softc */
291 	u_int ti_id;				/* scsi id */
292 
293 	/*
294 	 * Lun chain
295 	 */
296 	struct lun_info_tab ti_litab;		/* lun chain */
297 
298 	/*
299 	 * total disconnected nexus
300 	 */
301 	int ti_disc;
302 
303 	/*
304 	 * Scsi phase control
305  	 */
306 
307 #define	PH_NULL		0x00
308 #define	PH_ARBSTART	0x01
309 #define	PH_SELSTART	0x02
310 #define	PH_SELECTED	0x03
311 #define	PH_CMD		0x04
312 #define	PH_DATA		0x05
313 #define	PH_MSGIN	0x06
314 #define	PH_MSGOUT	0x07
315 #define	PH_STAT		0x08
316 #define	PH_DISC		0x09
317 #define	PH_RESEL	0x0a
318 	u_int ti_phase;				/* scsi phase */
319 	u_int ti_ophase;			/* old scsi phase */
320 
321 	/*
322 	 * Msg in
323  	 */
324 	u_int ti_msginptr;			/* msgin ptr */
325 	u_int ti_msginlen;			/* expected msg length */
326 	int ti_msgin_parity_error;		/* parity error detected */
327 	u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN];	/* msgin buffer */
328 
329 	/*
330 	 * Msg out
331  	 */
332 	u_int ti_msgflags;			/* msgs to be asserted */
333 	u_int ti_omsgflags;			/* msgs asserted */
334 	u_int ti_emsgflags;			/* a msg currently asserted */
335 #define	SCSI_LOW_MSG_RESET	0x00000001
336 #define	SCSI_LOW_MSG_REJECT	0x00000002
337 #define	SCSI_LOW_MSG_PARITY	0x00000004
338 #define	SCSI_LOW_MSG_ERROR	0x00000008
339 #define	SCSI_LOW_MSG_IDENTIFY	0x00000010
340 #define	SCSI_LOW_MSG_ABORT	0x00000020
341 #define	SCSI_LOW_MSG_TERMIO	0x00000040
342 #define	SCSI_LOW_MSG_SIMPLE_QTAG	0x00000080
343 #define	SCSI_LOW_MSG_ORDERED_QTAG	0x00000100
344 #define	SCSI_LOW_MSG_HEAD_QTAG		0x00000200
345 #define	SCSI_LOW_MSG_ABORT_QTAG 0x00000400
346 #define	SCSI_LOW_MSG_CLEAR_QTAG 0x00000800
347 #define	SCSI_LOW_MSG_WIDE	0x00001000
348 #define	SCSI_LOW_MSG_SYNCH	0x00002000
349 #define	SCSI_LOW_MSG_NOOP	0x00004000
350 #define	SCSI_LOW_MSG_LAST	0x00008000
351 #define	SCSI_LOW_MSG_ALL	0xffffffff
352 
353 	/* msgout buffer */
354 	u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN];	/* scsi msgout */
355 	u_int ti_msgoutlen;			/* msgout strlen */
356 
357 	/*
358 	 * target initialize msgout
359  	 */
360 	u_int ti_setup_msg;		/* setup msgout requests */
361 	u_int ti_setup_msg_done;
362 
363 	/*
364 	 * synch and wide data info
365  	 */
366 	u_int ti_flags_valid;	/* valid flags */
367 #define	SCSI_LOW_TARG_FLAGS_USER_VALID		0x0001
368 #define	SCSI_LOW_TARG_FLAGS_DISK_VALID		0x0002
369 #define	SCSI_LOW_TARG_FLAGS_QUIRKS_VALID	0x0004
370 #define	SCSI_LOW_TARG_FLAGS_ALL_VALID \
371 	(SCSI_LOW_TARG_FLAGS_USER_VALID | \
372 	 SCSI_LOW_TARG_FLAGS_DISK_VALID | SCSI_LOW_TARG_FLAGS_QUIRKS_VALID)
373 
374 	u_int ti_diskflags;	/* given target disk flags */
375 	u_int ti_quirks;	/* given target quirk */
376 
377 	struct synch {
378 		u_int8_t offset;
379 		u_int8_t period;
380 	} ti_osynch, ti_maxsynch;		/* synch data */
381 
382 #define	SCSI_LOW_BUS_WIDTH_8	0
383 #define	SCSI_LOW_BUS_WIDTH_16	1
384 #define	SCSI_LOW_BUS_WIDTH_32	2
385 	u_int ti_owidth, ti_width;
386 
387 	/*
388 	 * lun info size.
389  	 */
390 	int ti_lunsize;
391 
392 #ifdef	SCSI_LOW_DIAGNOSTIC
393 	struct scsi_low_msg_log ti_log_msgout;
394 	struct scsi_low_msg_log ti_log_msgin;
395 #endif	/* SCSI_LOW_DIAGNOSTIC */
396 };
397 
398 /*************************************************
399  * COMMON HEADER STRUCTURE
400  *************************************************/
401 struct scsi_low_softc;
402 struct proc;
403 typedef struct scsi_low_softc *sc_low_t;
404 
405 #define	SCSI_LOW_START_OK	0
406 #define	SCSI_LOW_START_FAIL	1
407 #define	SCSI_LOW_INFO_ALLOC	0
408 #define	SCSI_LOW_INFO_REVOKE	1
409 #define	SCSI_LOW_INFO_DEALLOC	2
410 #define	SCSI_LOW_POWDOWN	1
411 #define	SCSI_LOW_ENGAGE		2
412 
413 #define	SC_LOW_INIT_T (int (*)(sc_low_t, int))
414 #define	SC_LOW_BUSRST_T (void (*)(sc_low_t))
415 #define	SC_LOW_TARG_INIT_T (int (*)(sc_low_t, struct targ_info *, int))
416 #define	SC_LOW_LUN_INIT_T (int (*)(sc_low_t, struct targ_info *, struct lun_info *, int))
417 #define	SC_LOW_SELECT_T (int (*)(sc_low_t, struct slccb *))
418 #define	SC_LOW_ATTEN_T (void (*)(sc_low_t))
419 #define	SC_LOW_NEXUS_T (int (*)(sc_low_t))
420 #define	SC_LOW_MSG_T (int (*)(sc_low_t, struct targ_info *, u_int))
421 #define	SC_LOW_POLL_T (int (*)(void *))
422 #define	SC_LOW_POWER_T (int (*)(sc_low_t, u_int))
423 #define	SC_LOW_TIMEOUT_T (int (*)(sc_low_t))
424 
425 struct scsi_low_funcs {
426 	int (*scsi_low_init)(sc_low_t, int);
427 	void (*scsi_low_bus_reset)(sc_low_t);
428 	int (*scsi_low_targ_init)(sc_low_t, struct targ_info *, int);
429 	int (*scsi_low_lun_init)(sc_low_t, struct targ_info *, struct lun_info *, int);
430 	int (*scsi_low_start_bus)(sc_low_t, struct slccb *);
431 	int (*scsi_low_establish_lun_nexus)(sc_low_t);
432 	int (*scsi_low_establish_ccb_nexus)(sc_low_t);
433 	void (*scsi_low_attention)(sc_low_t);
434 	int (*scsi_low_msg)(sc_low_t, struct targ_info *, u_int);
435 	int (*scsi_low_timeout)(sc_low_t);
436 	int (*scsi_low_poll)(void *);
437 	int (*scsi_low_power)(sc_low_t, u_int);
438 	int (*scsi_low_ioctl)(sc_low_t, u_long, caddr_t, int, struct proc *);
439 };
440 
441 struct scsi_low_softc {
442 	device_t sl_dev;
443 
444 	struct cam_sim *sl_sim;
445 	struct cam_path *sl_path;
446 
447 	int sl_poll_count;
448 
449 	struct mtx sl_lock;
450 	struct callout sl_engage_timer;
451 	struct callout sl_timeout_timer;
452 #ifdef	SCSI_LOW_POWFUNC
453 	struct callout sl_recover_timer;
454 #endif
455 
456 	/* our chain */
457 	LIST_ENTRY(scsi_low_softc) sl_chain;
458 
459 	/* my targets */
460 	struct targ_info *sl_ti[SCSI_LOW_NTARGETS];
461 	struct targ_info_tab sl_titab;
462 
463 	/* current active T_L_Q nexus */
464 	struct targ_info *sl_Tnexus;		/* Target nexus */
465 	struct lun_info *sl_Lnexus;		/* Lun nexus */
466 	struct slccb *sl_Qnexus;			/* Qtag nexus */
467 	int sl_nexus_call;
468 
469 	/* ccb start queue */
470 	struct slccbtab sl_start;
471 
472 	/* retry limit and phase change counter */
473 	int sl_max_retry;
474 	int sl_ph_count;
475 	int sl_timeout_count;
476 
477 	/* selection & total num disconnect targets */
478 	int sl_nio;
479 	int sl_disc;
480 	int sl_retry_sel;
481 	struct slccb *sl_selid;
482 
483 	/* attention */
484 	int sl_atten;			/* ATN asserted */
485 	int sl_clear_atten;		/* negate ATN required */
486 
487 	/* scsi phase suggested by scsi msg */
488 	u_int sl_msgphase;
489 #define	MSGPH_NULL	0x00		/* no msg */
490 #define	MSGPH_DISC	0x01		/* disconnect msg */
491 #define	MSGPH_CMDC	0x02		/* cmd complete msg */
492 #define	MSGPH_ABORT	0x03		/* abort seq */
493 #define	MSGPH_TERM	0x04		/* current io terminate */
494 #define	MSGPH_LCTERM	0x05		/* cmd link terminated */
495 #define	MSGPH_RESET	0x06		/* reset target */
496 
497 	/* error */
498 	u_int sl_error;			/* error flags */
499 #define	FATALIO		0x0001		/* generic io error & retry io */
500 #define	ABORTIO		0x0002		/* generic io error & terminate io */
501 #define	TIMEOUTIO	0x0004		/* watch dog timeout */
502 #define	SELTIMEOUTIO	0x0008		/* selection timeout */
503 #define	PDMAERR		0x0010		/* dma xfer error */
504 #define	MSGERR		0x0020		/* msgsys error */
505 #define	PARITYERR	0x0040		/* parity error */
506 #define	BUSYERR		0x0080		/* target busy error */
507 #define	STATERR		0x0100		/* status error */
508 #define	UACAERR		0x0200		/* target CA state, no sense check */
509 #define	SENSEIO		0x1000		/* cmd not excuted but sense data ok */
510 #define	SENSEERR	0x2000		/* cmd not excuted and sense data bad */
511 #define	UBFERR		0x4000		/* unexpected bus free */
512 #define	PENDINGIO	0x8000		/* ccb start not yet */
513 #define	SCSI_LOW_ERRORBITS "\020\017ubferr\016senseerr\015senseio\012uacaerr\011staterr\010busy\007parity\006msgerr\005pdmaerr\004seltimeout\003timeout\002abort\001fatal"
514 
515 	/* current scsi data pointer */
516 	struct sc_p sl_scp;
517 
518 	/* power control */
519 	u_int sl_active;		/* host is busy state */
520 	int sl_powc;			/* power down timer counter */
521 	u_int sl_rstep;			/* resume step */
522 
523 	/* configuration flags */
524 	u_int sl_flags;
525 #define	HW_POWDOWN	0x0001
526 #define	HW_RESUME	0x0002
527 #define	HW_PDMASTART	0x0004
528 #define	HW_INACTIVE	0x0008
529 #define	HW_POWERCTRL	0x0010
530 #define	HW_INITIALIZING 0x0020
531 #define	HW_READ_PADDING		0x1000
532 #define	HW_WRITE_PADDING	0x2000
533 
534 	u_int sl_cfgflags;
535 #define	CFG_NODISC		0x0001
536 #define	CFG_NOPARITY		0x0002
537 #define	CFG_NOATTEN		0x0004
538 #define	CFG_ASYNC		0x0008
539 #define	CFG_NOQTAG		0x0010
540 
541 	int sl_show_result;
542 #define	SHOW_SYNCH_NEG	0x0001
543 #define	SHOW_WIDE_NEG	0x0002
544 #define	SHOW_CALCF_RES	0x0010
545 #define	SHOW_PROBE_RES	0x0020
546 #define	SHOW_ALL_NEG	-1
547 
548 	/* host informations */
549 	u_int sl_hostid;
550 	int sl_nluns;
551 	int sl_ntargs;
552 	int sl_openings;
553 
554 	/* interface functions */
555 	struct scsi_low_funcs *sl_funcs;
556 
557 	/* targinfo size */
558 	int sl_targsize;
559 };
560 
561 #define	SCSI_LOW_LOCK(sl)		mtx_lock(&(sl)->sl_lock)
562 #define	SCSI_LOW_UNLOCK(sl)		mtx_unlock(&(sl)->sl_lock)
563 #define	SCSI_LOW_ASSERT_LOCKED(sl)	mtx_assert(&(sl)->sl_lock, MA_OWNED)
564 
565 /*************************************************
566  * SCSI LOW service functions
567  *************************************************/
568 /*
569  * Scsi low attachment function.
570  */
571 int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int);
572 int scsi_low_detach(struct scsi_low_softc *);
573 
574 /*
575  * Scsi low interface activate or deactivate functions
576  */
577 int scsi_low_is_busy(struct scsi_low_softc *);
578 int scsi_low_activate(struct scsi_low_softc *);
579 int scsi_low_deactivate(struct scsi_low_softc *);
580 
581 /*
582  * Scsi phase "bus service" functions.
583  * These functions are corresponding to each scsi bus phaeses.
584  */
585 /* bus idle phase (other initiators or targets release bus) */
586 void scsi_low_bus_idle(struct scsi_low_softc *);
587 
588 /* arbitration and selection phase */
589 void scsi_low_arbit_fail(struct scsi_low_softc *, struct slccb *);
590 static __inline void scsi_low_arbit_win(struct scsi_low_softc *);
591 
592 /* msgout phase */
593 #define	SCSI_LOW_MSGOUT_INIT		0x00000001
594 #define	SCSI_LOW_MSGOUT_UNIFY		0x00000002
595 int scsi_low_msgout(struct scsi_low_softc *, struct targ_info *, u_int);
596 
597 /* msgin phase */
598 #define SCSI_LOW_DATA_PE	0x80000000
599 int scsi_low_msgin(struct scsi_low_softc *, struct targ_info *, u_int);
600 
601 /* statusin phase */
602 static __inline int scsi_low_statusin(struct scsi_low_softc *, struct targ_info *, u_int);
603 
604 /* data phase */
605 int scsi_low_data(struct scsi_low_softc *, struct targ_info *, struct buf **, int);
606 static __inline void scsi_low_data_finish(struct scsi_low_softc *);
607 
608 /* cmd phase */
609 int scsi_low_cmd(struct scsi_low_softc *, struct targ_info *);
610 
611 /* reselection phase */
612 struct targ_info *scsi_low_reselected(struct scsi_low_softc *, u_int);
613 
614 /* disconnection phase */
615 int scsi_low_disconnected(struct scsi_low_softc *, struct targ_info *);
616 
617 /*
618  * Scsi bus restart function.
619  * Canncel all established nexuses => scsi system initialized => restart jobs.
620  */
621 #define	SCSI_LOW_RESTART_HARD	1
622 #define	SCSI_LOW_RESTART_SOFT	0
623 int scsi_low_restart(struct scsi_low_softc *, int, u_char *);
624 
625 /*
626  * Scsi utility fucntions
627  */
628 /* print current status */
629 void scsi_low_print(struct scsi_low_softc *, struct targ_info *);
630 
631 /* bus reset utility */
632 void scsi_low_bus_reset(struct scsi_low_softc *);
633 
634 /*************************************************
635  * Message macro defs
636  *************************************************/
637 #define	SCSI_LOW_SETUP_PHASE(ti, phase)			\
638 {							\
639 	(ti)->ti_ophase = ti->ti_phase;			\
640 	(ti)->ti_phase = (phase);			\
641 }
642 
643 #define	SCSI_LOW_SETUP_MSGPHASE(slp, PHASE)		\
644 {							\
645 	(slp)->sl_msgphase = (PHASE);			\
646 }
647 
648 #define	SCSI_LOW_ASSERT_ATN(slp)			\
649 {							\
650 	(slp)->sl_atten = 1;				\
651 }
652 
653 #define	SCSI_LOW_DEASSERT_ATN(slp)			\
654 {							\
655 	(slp)->sl_atten = 0;				\
656 }
657 
658 /*************************************************
659  * Inline functions
660  *************************************************/
661 static __inline void scsi_low_attention(struct scsi_low_softc *);
662 static __inline int scsi_low_is_msgout_continue(struct targ_info *, u_int);
663 static __inline int scsi_low_assert_msg(struct scsi_low_softc *, struct targ_info *, u_int, int);
664 static __inline int scsi_low_is_disconnect_ok(struct slccb *);
665 
666 static __inline int
scsi_low_is_msgout_continue(ti,mask)667 scsi_low_is_msgout_continue(ti, mask)
668 	struct targ_info *ti;
669 	u_int mask;
670 {
671 
672 	return ((ti->ti_msgflags & (~mask)) != 0);
673 }
674 
675 static __inline int
scsi_low_is_disconnect_ok(cb)676 scsi_low_is_disconnect_ok(cb)
677 	struct slccb *cb;
678 {
679 
680 	return ((cb->li->li_flags & SCSI_LOW_DISC) != 0 &&
681 		    (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) == 0);
682 }
683 
684 static __inline void
scsi_low_attention(slp)685 scsi_low_attention(slp)
686 	struct scsi_low_softc *slp;
687 {
688 
689 	if (slp->sl_atten != 0)
690 		return;
691 
692 	(*slp->sl_funcs->scsi_low_attention) (slp);
693 	SCSI_LOW_ASSERT_ATN(slp);
694 }
695 
696 static __inline int
scsi_low_assert_msg(slp,ti,msg,now)697 scsi_low_assert_msg(slp, ti, msg, now)
698 	struct scsi_low_softc *slp;
699 	struct targ_info *ti;
700 	u_int msg;
701 	int now;
702 {
703 
704 	ti->ti_msgflags |= msg;
705 	if (now != 0)
706 		scsi_low_attention(slp);
707 	return 0;
708 }
709 
710 static __inline void
scsi_low_arbit_win(slp)711 scsi_low_arbit_win(slp)
712 	struct scsi_low_softc *slp;
713 {
714 
715 	slp->sl_selid = NULL;
716 }
717 
718 static __inline void
scsi_low_data_finish(slp)719 scsi_low_data_finish(slp)
720 	struct scsi_low_softc *slp;
721 {
722 
723 	if (slp->sl_Qnexus != NULL)
724 	{
725 		slp->sl_Qnexus->ccb_datalen = slp->sl_scp.scp_datalen;
726 	}
727 }
728 
729 static __inline int
scsi_low_statusin(slp,ti,c)730 scsi_low_statusin(slp, ti, c)
731 	struct scsi_low_softc *slp;
732 	struct targ_info *ti;
733 	u_int c;
734 {
735 
736 	slp->sl_ph_count ++;
737 	if ((c & SCSI_LOW_DATA_PE) != 0)
738 	{
739 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 0);
740 		return EIO;
741 	}
742 	slp->sl_scp.scp_status = (u_int8_t) c;
743 	return 0;
744 }
745 
746 /*************************************************
747  * Message out defs
748  *************************************************/
749 /* XXX: use scsi_message.h */
750 #define	ST_GOOD		0x00
751 #define	ST_CHKCOND	0x02
752 #define	ST_MET		0x04
753 #define	ST_BUSY		0x08
754 #define	ST_INTERGOOD	0x10
755 #define	ST_INTERMET	0x14
756 #define	ST_CONFLICT	0x18
757 #define	ST_CMDTERM	0x22
758 #define	ST_QUEFULL	0x28
759 #define	ST_UNKNOWN	0xff
760 
761 #define	MSG_COMP	0x00
762 #define	MSG_EXTEND	0x01
763 
764 #define	MKMSG_EXTEND(XLEN, XCODE) ((((u_int)(XLEN)) << NBBY) | ((u_int)(XCODE)))
765 #define	MSG_EXTEND_MDPCODE	0x00
766 #define	MSG_EXTEND_MDPLEN	0x05
767 #define	MSG_EXTEND_SYNCHCODE	0x01
768 #define	MSG_EXTEND_SYNCHLEN	0x03
769 #define	MSG_EXTEND_WIDECODE	0x03
770 #define	MSG_EXTEND_WIDELEN	0x02
771 
772 #define	MSG_SAVESP	0x02
773 #define	MSG_RESTORESP	0x03
774 #define	MSG_DISCON	0x04
775 #define	MSG_I_ERROR	0x05
776 #define	MSG_ABORT	0x06
777 #define	MSG_REJECT	0x07
778 #define	MSG_NOOP	0x08
779 #define	MSG_PARITY	0x09
780 #define	MSG_LCOMP	0x0a
781 #define	MSG_LCOMP_F	0x0b
782 #define	MSG_RESET	0x0c
783 #define	MSG_ABORT_QTAG	0x0d
784 #define	MSG_CLEAR_QTAG	0x0e
785 #define	MSG_TERM_IO	0x11
786 #define	MSG_SIMPLE_QTAG	0x20
787 #define	MSG_HEAD_QTAG	0x21
788 #define	MSG_ORDERED_QTAG	0x22
789 #define	MSG_IDENTIFY	  	0x80
790 #define	MSG_IDENTIFY_DISCPRIV	0x40
791 #endif	/* !_SCSI_LOW_H_ */
792