xref: /trueos/sys/cam/scsi/scsi_low.h (revision b972b67ed72b5687a023c92602aaef64163b2f59)
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 /*================================================
48  * Scsi low OSDEP
49  * (All os depend structures should be here!)
50  ================================================*/
51 /******** includes *******************************/
52 
53 #include <sys/bus.h>
54 #include <sys/kdb.h>
55 #include <cam/cam.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/cam_sim.h>
58 #include <cam/cam_xpt_sim.h>
59 #include <cam/cam_debug.h>
60 
61 #include <cam/scsi/scsi_dvcfg.h>
62 #include <i386/isa/ccbque.h>
63 
64 /******** functions macro ************************/
65 
66 #undef	MSG_IDENTIFY
67 
68 /******** os depend interface structures **********/
69 typedef	struct scsi_sense_data scsi_low_osdep_sense_data_t;
70 
71 struct scsi_low_osdep_interface {
72 	device_t si_dev;
73 
74 	struct cam_sim *sim;
75 	struct cam_path *path;
76 
77 	int si_poll_count;
78 
79 	struct callout_handle engage_ch;
80 	struct callout_handle timeout_ch;
81 #ifdef	SCSI_LOW_POWFUNC
82 	struct callout_handle recover_ch;
83 #endif
84 };
85 
86 /******** os depend interface functions *************/
87 struct slccb;
88 struct scsi_low_softc;
89 #define	SCSI_LOW_TIMEOUT_STOP		0
90 #define	SCSI_LOW_TIMEOUT_START		1
91 #define	SCSI_LOW_TIMEOUT_CH_IO		0
92 #define	SCSI_LOW_TIMEOUT_CH_ENGAGE	1
93 #define	SCSI_LOW_TIMEOUT_CH_RECOVER	2
94 
95 struct scsi_low_osdep_funcs {
96 	int (*scsi_low_osdep_attach) \
97 			(struct scsi_low_softc *);
98 	int (*scsi_low_osdep_world_start) \
99 			(struct scsi_low_softc *);
100 	int (*scsi_low_osdep_dettach) \
101 			(struct scsi_low_softc *);
102 	int (*scsi_low_osdep_ccb_setup) \
103 			(struct scsi_low_softc *, struct slccb *);
104 	int (*scsi_low_osdep_done) \
105 			(struct scsi_low_softc *, struct slccb *);
106 	void (*scsi_low_osdep_timeout) \
107 			(struct scsi_low_softc *, int, int);
108 };
109 
110 /*================================================
111  * Generic Scsi Low header file
112  * (All os depend structures should be above!)
113  ================================================*/
114 /*************************************************
115  * Scsi low definitions
116  *************************************************/
117 #define	SCSI_LOW_SYNC		DVF_SCSI_SYNC
118 #define	SCSI_LOW_DISC		DVF_SCSI_DISC
119 #define	SCSI_LOW_WAIT		DVF_SCSI_WAIT
120 #define	SCSI_LOW_LINK		DVF_SCSI_LINK
121 #define	SCSI_LOW_QTAG		DVF_SCSI_QTAG
122 #define	SCSI_LOW_NOPARITY	DVF_SCSI_NOPARITY
123 #define	SCSI_LOW_SAVESP		DVF_SCSI_SAVESP
124 #define	SCSI_LOW_DEFCFG		DVF_SCSI_DEFCFG
125 #define	SCSI_LOW_BITS		DVF_SCSI_BITS
126 
127 #define	SCSI_LOW_PERIOD(n)	DVF_SCSI_PERIOD(n)
128 #define	SCSI_LOW_OFFSET(n)	DVF_SCSI_OFFSET(n)
129 
130 /* host scsi id and targets macro */
131 #ifndef	SCSI_LOW_NTARGETS
132 #define	SCSI_LOW_NTARGETS			8
133 #endif	/* SCSI_LOW_NTARGETS */
134 #define	SCSI_LOW_NCCB				128
135 
136 #define	SCSI_LOW_MAX_RETRY			3
137 #define	SCSI_LOW_MAX_SELECTION_RETRY		10
138 
139 /* timeout control macro */
140 #define	SCSI_LOW_TIMEOUT_HZ			10
141 #define SCSI_LOW_MIN_TOUT			12
142 #define SCSI_LOW_TIMEOUT_CHECK_INTERVAL 	1
143 #define	SCSI_LOW_POWDOWN_TC			15
144 #define	SCSI_LOW_MAX_PHCHANGES			256
145 #define	SCSI2_RESET_DELAY			5000000
146 
147 /* msg */
148 #define	SCSI_LOW_MAX_MSGLEN			32
149 #define	SCSI_LOW_MSG_LOG_DATALEN  		8
150 
151 /*************************************************
152  * Scsi Data Pointer
153  *************************************************/
154 /* scsi pointer */
155 struct sc_p {
156 	u_int8_t *scp_data;
157 	int scp_datalen;
158 
159 	u_int8_t *scp_cmd;
160 	int scp_cmdlen;
161 
162 	u_int8_t scp_direction;
163 #define	SCSI_LOW_RWUNK	(-1)
164 #define	SCSI_LOW_WRITE	0
165 #define	SCSI_LOW_READ	1
166 	u_int8_t scp_status;
167 	u_int8_t scp_spare[2];
168 };
169 
170 /*************************************************
171  * Command Control Block Structure
172  *************************************************/
173 typedef int scsi_low_tag_t;
174 struct targ_info;
175 
176 #define	SCSI_LOW_UNKLUN	((u_int) -1)
177 #define	SCSI_LOW_UNKTAG	((scsi_low_tag_t) -1)
178 
179 struct slccb {
180 	TAILQ_ENTRY(slccb) ccb_chain;
181 
182 	void *osdep;			/* os depend structure */
183 
184 	struct targ_info *ti;		/* targ_info */
185 	struct lun_info *li;		/* lun info */
186 	struct buf *bp;			/* io bufs */
187 
188 	scsi_low_tag_t ccb_tag;		/* effective qtag */
189 	scsi_low_tag_t ccb_otag;	/* allocated qtag */
190 
191 	/*****************************************
192 	 * Scsi data pointers (original and saved)
193 	 *****************************************/
194 	struct sc_p ccb_scp;		/* given */
195 	struct sc_p ccb_sscp;		/* saved scsi data pointer */
196 	int ccb_datalen;		/* transfered data counter */
197 
198 	/*****************************************
199 	 * Msgout
200 	 *****************************************/
201 	u_int ccb_msgoutflag;
202 	u_int ccb_omsgoutflag;
203 
204 	/*****************************************
205 	 * Error or Timeout counters
206 	 *****************************************/
207 	u_int ccb_flags;
208 #define	CCB_INTERNAL	0x0001
209 #define	CCB_SENSE	0x0002
210 #define	CCB_CLEARQ	0x0004
211 #define	CCB_DISCQ	0x0008
212 #define	CCB_STARTQ	0x0010
213 #define	CCB_POLLED	0x0100	/* polling ccb */
214 #define	CCB_NORETRY	0x0200	/* do NOT retry */
215 #define	CCB_AUTOSENSE	0x0400	/* do a sence after CA */
216 #define	CCB_URGENT	0x0800	/* an urgent ccb */
217 #define	CCB_NOSDONE	0x1000	/* do not call an os done routine */
218 #define	CCB_SCSIIO	0x2000	/* a normal scsi io coming from upper layer */
219 #define	CCB_SILENT	0x4000	/* no terminate messages */
220 
221 	u_int ccb_error;
222 
223 	int ccb_rcnt;			/* retry counter */
224 	int ccb_selrcnt;		/* selection retry counter */
225 	int ccb_tc;			/* timer counter */
226 	int ccb_tcmax;			/* max timeout */
227 
228 	/*****************************************
229 	 * Sense data buffer
230 	 *****************************************/
231 	u_int8_t ccb_scsi_cmd[12];
232 	scsi_low_osdep_sense_data_t ccb_sense;
233 };
234 
235 /*************************************************
236  * Slccb functions
237  *************************************************/
238 GENERIC_CCB_ASSERT(scsi_low, slccb)
239 
240 /*************************************************
241  * Target and Lun structures
242  *************************************************/
243 struct scsi_low_softc;
244 LIST_HEAD(scsi_low_softc_tab, scsi_low_softc);
245 TAILQ_HEAD(targ_info_tab, targ_info);
246 LIST_HEAD(lun_info_tab, lun_info);
247 
248 struct lun_info {
249 	int li_lun;
250 	struct targ_info *li_ti;		/* my target */
251 
252 	LIST_ENTRY(lun_info) lun_chain;		/* targ_info link */
253 
254 	struct slccbtab li_discq;			/* disconnect queue */
255 
256 	/*
257 	 * qtag control
258 	 */
259 	int li_maxnexus;
260 	int li_maxnqio;
261 	int li_nqio;
262 	int li_disc;
263 
264 #define	SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY)
265 	u_int li_qtagbits;
266 
267 #ifdef	SCSI_LOW_ALT_QTAG_ALLOCATE
268 	u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS];
269 	u_int li_qd;
270 #endif	/* SCSI_LOW_ALT_QTAG_ALLOCATE */
271 
272 #define	SCSI_LOW_QFLAG_CA_QCLEAR	0x01
273 	u_int li_qflags;
274 
275 	/*
276 	 * lun state
277 	 */
278 #define	SCSI_LOW_LUN_SLEEP	0x00
279 #define	SCSI_LOW_LUN_START	0x01
280 #define	SCSI_LOW_LUN_INQ	0x02
281 #define	SCSI_LOW_LUN_MODEQ	0x03
282 #define	SCSI_LOW_LUN_OK		0x04
283 	u_int li_state;				/* target lun state */
284 
285 	/*
286 	 * lun control flags
287  	 */
288 	u_int li_flags_valid;	/* valid flags */
289 #define	SCSI_LOW_LUN_FLAGS_USER_VALID	0x0001
290 #define	SCSI_LOW_LUN_FLAGS_DISK_VALID	0x0002
291 #define	SCSI_LOW_LUN_FLAGS_QUIRKS_VALID	0x0004
292 #define	SCSI_LOW_LUN_FLAGS_ALL_VALID \
293 	(SCSI_LOW_LUN_FLAGS_USER_VALID | \
294 	 SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID)
295 
296 	u_int li_flags;		/* real lun control flags */
297 	u_int li_cfgflags;	/* lun control flags given by user */
298 	u_int li_diskflags;	/* lun control flags given by hardware info */
299 	u_int li_quirks;	/* lun control flags given by upper layer */
300 
301 	/* inq buffer */
302 	struct scsi_low_inq_data {
303 		u_int8_t sd_type;
304 		u_int8_t sd_sp1;
305 		u_int8_t sd_version;
306 		u_int8_t sd_resp;
307 		u_int8_t sd_len;
308 		u_int8_t sd_sp2[2];
309 		u_int8_t sd_support;
310 	} __packed li_inq;
311 
312 	/* modeq buffer */
313 	struct scsi_low_mode_sense_data {
314 		u_int8_t sms_header[4];
315 		struct {
316 			u_int8_t cmp_page;
317 			u_int8_t cmp_length;
318 			u_int8_t cmp_rlec;
319 			u_int8_t cmp_qc;
320 			u_int8_t cmp_eca;
321 			u_int8_t cmp_spare[3];
322 		} __packed sms_cmp;
323 
324 	} li_sms;
325 };
326 
327 struct scsi_low_msg_log {
328 	int slml_ptr;
329 	struct {
330 		u_int8_t msg[2];
331 	} slml_msg[SCSI_LOW_MSG_LOG_DATALEN];
332 };
333 
334 struct targ_info {
335 	TAILQ_ENTRY(targ_info) ti_chain;	/* targ_info link */
336 
337 	struct scsi_low_softc *ti_sc;		/* our softc */
338 	u_int ti_id;				/* scsi id */
339 
340 	/*
341 	 * Lun chain
342 	 */
343 	struct lun_info_tab ti_litab;		/* lun chain */
344 
345 	/*
346 	 * total disconnected nexus
347 	 */
348 	int ti_disc;
349 
350 	/*
351 	 * Scsi phase control
352  	 */
353 
354 #define	PH_NULL		0x00
355 #define	PH_ARBSTART	0x01
356 #define	PH_SELSTART	0x02
357 #define	PH_SELECTED	0x03
358 #define	PH_CMD		0x04
359 #define	PH_DATA		0x05
360 #define	PH_MSGIN	0x06
361 #define	PH_MSGOUT	0x07
362 #define	PH_STAT		0x08
363 #define	PH_DISC		0x09
364 #define	PH_RESEL	0x0a
365 	u_int ti_phase;				/* scsi phase */
366 	u_int ti_ophase;			/* old scsi phase */
367 
368 	/*
369 	 * Msg in
370  	 */
371 	u_int ti_msginptr;			/* msgin ptr */
372 	u_int ti_msginlen;			/* expected msg length */
373 	int ti_msgin_parity_error;		/* parity error detected */
374 	u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN];	/* msgin buffer */
375 
376 	/*
377 	 * Msg out
378  	 */
379 	u_int ti_msgflags;			/* msgs to be asserted */
380 	u_int ti_omsgflags;			/* msgs asserted */
381 	u_int ti_emsgflags;			/* a msg currently asserted */
382 #define	SCSI_LOW_MSG_RESET	0x00000001
383 #define	SCSI_LOW_MSG_REJECT	0x00000002
384 #define	SCSI_LOW_MSG_PARITY	0x00000004
385 #define	SCSI_LOW_MSG_ERROR	0x00000008
386 #define	SCSI_LOW_MSG_IDENTIFY	0x00000010
387 #define	SCSI_LOW_MSG_ABORT	0x00000020
388 #define	SCSI_LOW_MSG_TERMIO	0x00000040
389 #define	SCSI_LOW_MSG_SIMPLE_QTAG	0x00000080
390 #define	SCSI_LOW_MSG_ORDERED_QTAG	0x00000100
391 #define	SCSI_LOW_MSG_HEAD_QTAG		0x00000200
392 #define	SCSI_LOW_MSG_ABORT_QTAG 0x00000400
393 #define	SCSI_LOW_MSG_CLEAR_QTAG 0x00000800
394 #define	SCSI_LOW_MSG_WIDE	0x00001000
395 #define	SCSI_LOW_MSG_SYNCH	0x00002000
396 #define	SCSI_LOW_MSG_NOOP	0x00004000
397 #define	SCSI_LOW_MSG_LAST	0x00008000
398 #define	SCSI_LOW_MSG_ALL	0xffffffff
399 
400 	/* msgout buffer */
401 	u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN];	/* scsi msgout */
402 	u_int ti_msgoutlen;			/* msgout strlen */
403 
404 	/*
405 	 * target initialize msgout
406  	 */
407 	u_int ti_setup_msg;		/* setup msgout requests */
408 	u_int ti_setup_msg_done;
409 
410 	/*
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  *************************************************/
448 struct scsi_low_softc;
449 struct proc;
450 typedef 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 
472 struct 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 
488 struct 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  */
605 int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int);
606 int scsi_low_dettach(struct scsi_low_softc *);
607 
608 /*
609  * Scsi low interface activate or deactivate functions
610  */
611 int scsi_low_is_busy(struct scsi_low_softc *);
612 int scsi_low_activate(struct scsi_low_softc *);
613 int 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) */
620 void scsi_low_bus_idle(struct scsi_low_softc *);
621 
622 /* arbitration and selection phase */
623 void scsi_low_arbit_fail(struct scsi_low_softc *, struct slccb *);
624 static __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
629 int scsi_low_msgout(struct scsi_low_softc *, struct targ_info *, u_int);
630 
631 /* msgin phase */
632 #define SCSI_LOW_DATA_PE	0x80000000
633 int scsi_low_msgin(struct scsi_low_softc *, struct targ_info *, u_int);
634 
635 /* statusin phase */
636 static __inline int scsi_low_statusin(struct scsi_low_softc *, struct targ_info *, u_int);
637 
638 /* data phase */
639 int scsi_low_data(struct scsi_low_softc *, struct targ_info *, struct buf **, int);
640 static __inline void scsi_low_data_finish(struct scsi_low_softc *);
641 
642 /* cmd phase */
643 int scsi_low_cmd(struct scsi_low_softc *, struct targ_info *);
644 
645 /* reselection phase */
646 struct targ_info *scsi_low_reselected(struct scsi_low_softc *, u_int);
647 
648 /* disconnection phase */
649 int 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
657 int scsi_low_restart(struct scsi_low_softc *, int, u_char *);
658 
659 /*
660  * Scsi utility fucntions
661  */
662 /* print current status */
663 void scsi_low_print(struct scsi_low_softc *, struct targ_info *);
664 
665 /* bus reset utility */
666 void 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  *************************************************/
695 static __inline void scsi_low_attention(struct scsi_low_softc *);
696 static __inline int scsi_low_is_msgout_continue(struct targ_info *, u_int);
697 static __inline int scsi_low_assert_msg(struct scsi_low_softc *, struct targ_info *, u_int, int);
698 static __inline int scsi_low_is_disconnect_ok(struct slccb *);
699 
700 static __inline int
scsi_low_is_msgout_continue(ti,mask)701 scsi_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 
709 static __inline int
scsi_low_is_disconnect_ok(cb)710 scsi_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 
718 static __inline void
scsi_low_attention(slp)719 scsi_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 
730 static __inline int
scsi_low_assert_msg(slp,ti,msg,now)731 scsi_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 
744 static __inline void
scsi_low_arbit_win(slp)745 scsi_low_arbit_win(slp)
746 	struct scsi_low_softc *slp;
747 {
748 
749 	slp->sl_selid = NULL;
750 }
751 
752 static __inline void
scsi_low_data_finish(slp)753 scsi_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 
763 static __inline int
scsi_low_statusin(slp,ti,c)764 scsi_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