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