1 /*	$NecBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $	*/
2 /*	$NetBSD$	*/
3 
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: stable/10/sys/cam/scsi/scsi_low.c 315813 2017-03-23 06:41:13Z mav $");
6 
7 #define	SCSI_LOW_STATICS
8 #define	SCSI_LOW_DEBUG
9 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
10 #define	SCSI_LOW_START_UP_CHECK
11 
12 /* #define	SCSI_LOW_INFO_DETAIL */
13 
14 /* #define	SCSI_LOW_QCLEAR_AFTER_CA */
15 /* #define	SCSI_LOW_FLAGS_QUIRKS_OK */
16 
17 #define	SCSI_LOW_FLAGS_QUIRKS_OK
18 
19 /*-
20  * [NetBSD for NEC PC-98 series]
21  *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
22  *	NetBSD/pc98 porting staff. All rights reserved.
23  *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
24  *	Naofumi HONDA. All rights reserved.
25  *
26  * [Ported for FreeBSD CAM]
27  *  Copyright (c) 2000, 2001
28  *      MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
29  *      All rights reserved.
30  *
31  *  Redistribution and use in source and binary forms, with or without
32  *  modification, are permitted provided that the following conditions
33  *  are met:
34  *  1. Redistributions of source code must retain the above copyright
35  *     notice, this list of conditions and the following disclaimer.
36  *  2. Redistributions in binary form must reproduce the above copyright
37  *     notice, this list of conditions and the following disclaimer in the
38  *     documentation and/or other materials provided with the distribution.
39  *  3. The name of the author may not be used to endorse or promote products
40  *     derived from this software without specific prior written permission.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
46  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
51  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
52  * POSSIBILITY OF SUCH DAMAGE.
53  */
54 
55 /* <On the nexus establishment>
56  * When our host is reselected,
57  * nexus establish processes are little complicated.
58  * Normal steps are followings:
59  * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
60  * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
61  * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
62  */
63 #include "opt_ddb.h"
64 
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/kernel.h>
68 #include <sys/bio.h>
69 #include <sys/buf.h>
70 #include <sys/queue.h>
71 #include <sys/malloc.h>
72 #include <sys/errno.h>
73 
74 #include <cam/cam.h>
75 #include <cam/cam_ccb.h>
76 #include <cam/cam_sim.h>
77 #include <cam/cam_debug.h>
78 #include <cam/cam_periph.h>
79 #include <cam/cam_xpt_periph.h>
80 
81 #include <cam/scsi/scsi_all.h>
82 #include <cam/scsi/scsi_message.h>
83 
84 #include <cam/scsi/scsi_low.h>
85 
86 #include <sys/cons.h>
87 
88 /**************************************************************
89  * Constants
90  **************************************************************/
91 #define	SCSI_LOW_POLL_HZ	1000
92 
93 /* functions return values */
94 #define	SCSI_LOW_START_NO_QTAG	0
95 #define	SCSI_LOW_START_QTAG	1
96 
97 #define	SCSI_LOW_DONE_COMPLETE	0
98 #define	SCSI_LOW_DONE_RETRY	1
99 
100 /* internal disk flags */
101 #define	SCSI_LOW_DISK_DISC	0x00000001
102 #define	SCSI_LOW_DISK_QTAG	0x00000002
103 #define	SCSI_LOW_DISK_LINK	0x00000004
104 #define	SCSI_LOW_DISK_PARITY	0x00000008
105 #define	SCSI_LOW_DISK_SYNC	0x00010000
106 #define	SCSI_LOW_DISK_WIDE_16	0x00020000
107 #define	SCSI_LOW_DISK_WIDE_32	0x00040000
108 #define	SCSI_LOW_DISK_WIDE	(SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
109 #define	SCSI_LOW_DISK_LFLAGS	0x0000ffff
110 #define	SCSI_LOW_DISK_TFLAGS	0xffff0000
111 
112 static MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
113 
114 /**************************************************************
115  * Declarations
116  **************************************************************/
117 /* static */ void scsi_low_info(struct scsi_low_softc *, struct targ_info *, u_char *);
118 static void scsi_low_engage(void *);
119 static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t);
120 static int scsi_low_done(struct scsi_low_softc *, struct slccb *);
121 static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *);
122 static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *);
123 static void scsi_low_twiddle_wait(void);
124 static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int);
125 static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int);
126 static void scsi_low_calcf_lun(struct lun_info *);
127 static void scsi_low_calcf_target(struct targ_info *);
128 static void scsi_low_calcf_show(struct lun_info *);
129 static void scsi_low_reset_nexus(struct scsi_low_softc *, int);
130 static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int);
131 static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int);
132 static int scsi_low_init(struct scsi_low_softc *, u_int);
133 static void scsi_low_start(struct scsi_low_softc *);
134 static void scsi_low_free_ti(struct scsi_low_softc *);
135 
136 static int scsi_low_alloc_qtag(struct slccb *);
137 static int scsi_low_dealloc_qtag(struct slccb *);
138 static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
139 static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
140 static void scsi_low_unit_ready_cmd(struct slccb *);
141 static void scsi_low_timeout(void *);
142 static int scsi_low_timeout_check(struct scsi_low_softc *);
143 #ifdef	SCSI_LOW_START_UP_CHECK
144 static int scsi_low_start_up(struct scsi_low_softc *);
145 #endif	/* SCSI_LOW_START_UP_CHECK */
146 static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *);
147 static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int);
148 
149 int scsi_low_version_major = 2;
150 int scsi_low_version_minor = 17;
151 
152 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
153 
154 /**************************************************************
155  * Debug, Run test and Statics
156  **************************************************************/
157 #ifdef	SCSI_LOW_INFO_DETAIL
158 #define	SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
159 #else	/* !SCSI_LOW_INFO_DETAIL */
160 #define	SCSI_LOW_INFO(slp, ti, s) device_printf((slp)->sl_dev, "%s\n", (s))
161 #endif	/* !SCSI_LOW_INFO_DETAIL */
162 
163 #ifdef	SCSI_LOW_STATICS
164 static struct scsi_low_statics {
165 	int nexus_win;
166 	int nexus_fail;
167 	int nexus_disconnected;
168 	int nexus_reselected;
169 	int nexus_conflict;
170 } scsi_low_statics;
171 #endif	/* SCSI_LOW_STATICS */
172 
173 #ifdef	SCSI_LOW_DEBUG
174 #define	SCSI_LOW_DEBUG_DONE	0x00001
175 #define	SCSI_LOW_DEBUG_DISC	0x00002
176 #define	SCSI_LOW_DEBUG_SENSE	0x00004
177 #define	SCSI_LOW_DEBUG_CALCF	0x00008
178 #define	SCSI_LOW_DEBUG_ACTION	0x10000
179 int scsi_low_debug = 0;
180 
181 #define	SCSI_LOW_MAX_ATTEN_CHECK	32
182 #define	SCSI_LOW_ATTEN_CHECK	0x0001
183 #define	SCSI_LOW_CMDLNK_CHECK	0x0002
184 #define	SCSI_LOW_ABORT_CHECK	0x0004
185 #define	SCSI_LOW_NEXUS_CHECK	0x0008
186 int scsi_low_test = 0;
187 int scsi_low_test_id = 0;
188 
189 static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *);
190 static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *);
191 static void scsi_low_test_atten(struct scsi_low_softc *, struct targ_info *, u_int);
192 #define	SCSI_LOW_DEBUG_TEST_GO(fl, id) \
193 	((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
194 #define	SCSI_LOW_DEBUG_GO(fl, id) \
195 	((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
196 #endif	/* SCSI_LOW_DEBUG */
197 
198 /**************************************************************
199  * CCB
200  **************************************************************/
201 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
202 GENERIC_CCB(scsi_low, slccb, ccb_chain)
203 
204 /**************************************************************
205  * Inline functions
206  **************************************************************/
207 #define	SCSI_LOW_INLINE	static __inline
208 SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *);
209 SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *);
210 SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int);
211 SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *);
212 SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *);
213 SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *);
214 SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *);
215 
216 SCSI_LOW_INLINE void
scsi_low_activate_qtag(cb)217 scsi_low_activate_qtag(cb)
218 	struct slccb *cb;
219 {
220 	struct lun_info *li = cb->li;
221 
222 	if (cb->ccb_tag != SCSI_LOW_UNKTAG)
223 		return;
224 
225 	li->li_nqio ++;
226 	cb->ccb_tag = cb->ccb_otag;
227 }
228 
229 SCSI_LOW_INLINE void
scsi_low_deactivate_qtag(cb)230 scsi_low_deactivate_qtag(cb)
231 	struct slccb *cb;
232 {
233 	struct lun_info *li = cb->li;
234 
235 	if (cb->ccb_tag == SCSI_LOW_UNKTAG)
236 		return;
237 
238 	li->li_nqio --;
239 	cb->ccb_tag = SCSI_LOW_UNKTAG;
240 }
241 
242 SCSI_LOW_INLINE void
scsi_low_ccb_message_exec(slp,cb)243 scsi_low_ccb_message_exec(slp, cb)
244 	struct scsi_low_softc *slp;
245 	struct slccb *cb;
246 {
247 
248 	scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
249 	cb->ccb_msgoutflag = 0;
250 }
251 
252 SCSI_LOW_INLINE void
scsi_low_ccb_message_assert(cb,msg)253 scsi_low_ccb_message_assert(cb, msg)
254 	struct slccb *cb;
255 	u_int msg;
256 {
257 
258 	cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
259 }
260 
261 SCSI_LOW_INLINE void
scsi_low_ccb_message_retry(cb)262 scsi_low_ccb_message_retry(cb)
263 	struct slccb *cb;
264 {
265 	cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
266 }
267 
268 SCSI_LOW_INLINE void
scsi_low_ccb_message_clear(cb)269 scsi_low_ccb_message_clear(cb)
270 	struct slccb *cb;
271 {
272 	cb->ccb_msgoutflag = 0;
273 }
274 
275 SCSI_LOW_INLINE void
scsi_low_init_msgsys(slp,ti)276 scsi_low_init_msgsys(slp, ti)
277 	struct scsi_low_softc *slp;
278 	struct targ_info *ti;
279 {
280 
281 	ti->ti_msginptr = 0;
282 	ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
283 	SCSI_LOW_DEASSERT_ATN(slp);
284 	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
285 }
286 
287 /*=============================================================
288  * START OF OS switch  (All OS depend fucntions should be here)
289  =============================================================*/
290 /* common os depend utitlities */
291 #define	SCSI_LOW_CMD_RESIDUAL_CHK	0x0001
292 #define	SCSI_LOW_CMD_ORDERED_QTAG	0x0002
293 #define	SCSI_LOW_CMD_ABORT_WARNING	0x0004
294 
295 static u_int8_t scsi_low_cmd_flags[256] = {
296 /*	0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
297 /*0*/	0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
298 /*1*/	0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
299 /*2*/	0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
300 /*3*/	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
301 };
302 
303 struct scsi_low_error_code {
304 	int error_bits;
305 	int error_code;
306 };
307 
308 static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *);
309 static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *);
310 
311 static struct slccb *
scsi_low_find_ccb(slp,target,lun,osdep)312 scsi_low_find_ccb(slp, target, lun, osdep)
313 	struct scsi_low_softc *slp;
314 	u_int target, lun;
315 	void *osdep;
316 {
317 	struct targ_info *ti;
318 	struct lun_info *li;
319 	struct slccb *cb;
320 
321 	ti = slp->sl_ti[target];
322 	li = scsi_low_alloc_li(ti, lun, 0);
323 	if (li == NULL)
324 		return NULL;
325 
326 	if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
327 		return cb;
328 
329 	TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain)
330 	{
331 		if (cb->osdep == osdep)
332 			return cb;
333 	}
334 
335 	TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
336 	{
337 		if (cb->osdep == osdep)
338 			return cb;
339 	}
340 	return NULL;
341 }
342 
343 static int
scsi_low_translate_error_code(cb,tp)344 scsi_low_translate_error_code(cb, tp)
345 	struct slccb *cb;
346 	struct scsi_low_error_code *tp;
347 {
348 
349 	if (cb->ccb_error == 0)
350 		return tp->error_code;
351 
352 	for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
353 		;
354 	return tp->error_code;
355 }
356 
357 /**************************************************************
358  * SCSI INTERFACE (CAM)
359  **************************************************************/
360 #define	SCSI_LOW_MALLOC(size)		malloc((size), M_SCSILOW, M_NOWAIT)
361 #define	SCSI_LOW_FREE(pt)		free((pt), M_SCSILOW)
362 #define	SCSI_LOW_ALLOC_CCB(flags)	scsi_low_get_ccb()
363 
364 static void scsi_low_poll_cam(struct cam_sim *);
365 void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *);
366 
367 static int scsi_low_attach_cam(struct scsi_low_softc *);
368 static int scsi_low_world_start_cam(struct scsi_low_softc *);
369 static int scsi_low_dettach_cam(struct scsi_low_softc *);
370 static int scsi_low_ccb_setup_cam(struct scsi_low_softc *, struct slccb *);
371 static int scsi_low_done_cam(struct scsi_low_softc *, struct slccb *);
372 static void scsi_low_timeout_cam(struct scsi_low_softc *, int, int);
373 
374 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
375 	scsi_low_attach_cam,
376 	scsi_low_world_start_cam,
377 	scsi_low_dettach_cam,
378 	scsi_low_ccb_setup_cam,
379 	scsi_low_done_cam,
380 	scsi_low_timeout_cam
381 };
382 
383 struct scsi_low_error_code scsi_low_error_code_cam[] = {
384 	{0,			CAM_REQ_CMP},
385 	{SENSEIO, 		CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
386 	{SENSEERR,		CAM_AUTOSENSE_FAIL},
387 	{UACAERR,		CAM_SCSI_STATUS_ERROR},
388 	{BUSYERR | STATERR,	CAM_SCSI_STATUS_ERROR},
389 	{SELTIMEOUTIO,		CAM_SEL_TIMEOUT},
390 	{TIMEOUTIO,		CAM_CMD_TIMEOUT},
391 	{PDMAERR,		CAM_DATA_RUN_ERR},
392 	{PARITYERR,		CAM_UNCOR_PARITY},
393 	{UBFERR,		CAM_UNEXP_BUSFREE},
394 	{ABORTIO,		CAM_REQ_ABORTED},
395 	{-1,			CAM_UNREC_HBA_ERROR}
396 };
397 
398 #define	SIM2SLP(sim)	((struct scsi_low_softc *) cam_sim_softc((sim)))
399 
400 /* XXX:
401  * Please check a polling hz, currently we assume scsi_low_poll() is
402  * called each 1 ms.
403  */
404 #define	SCSI_LOW_CAM_POLL_HZ	1000	/* OK ? */
405 
406 static void
scsi_low_poll_cam(sim)407 scsi_low_poll_cam(sim)
408 	struct cam_sim *sim;
409 {
410 	struct scsi_low_softc *slp = SIM2SLP(sim);
411 
412 	(*slp->sl_funcs->scsi_low_poll) (slp);
413 
414 	if (slp->sl_si.si_poll_count ++ >=
415 	    SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
416 	{
417 		slp->sl_si.si_poll_count = 0;
418 		scsi_low_timeout_check(slp);
419 	}
420 }
421 
422 void
scsi_low_scsi_action_cam(sim,ccb)423 scsi_low_scsi_action_cam(sim, ccb)
424 	struct cam_sim *sim;
425 	union ccb *ccb;
426 {
427 	struct scsi_low_softc *slp = SIM2SLP(sim);
428 	struct targ_info *ti;
429 	struct lun_info *li;
430 	struct slccb *cb;
431 	u_int lun, flags, msg, target;
432 	int s, rv;
433 
434 	target = (u_int) (ccb->ccb_h.target_id);
435 	lun = (u_int) ccb->ccb_h.target_lun;
436 
437 #ifdef	SCSI_LOW_DEBUG
438 	if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
439 	{
440 		device_printf(slp->sl_dev,
441 		    "cam_action: func code 0x%x target: %d, lun: %d\n",
442 		    ccb->ccb_h.func_code, target, lun);
443 	}
444 #endif	/* SCSI_LOW_DEBUG */
445 
446 	switch (ccb->ccb_h.func_code) {
447 	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
448 #ifdef	SCSI_LOW_DIAGNOSTIC
449 		if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
450 		{
451 			device_printf(slp->sl_dev, "invalid target/lun\n");
452 			ccb->ccb_h.status = CAM_REQ_INVALID;
453 			xpt_done(ccb);
454 			return;
455 		}
456 #endif	/* SCSI_LOW_DIAGNOSTIC */
457 
458 		if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
459 			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
460 			xpt_done(ccb);
461 			return;
462 		}
463 
464 		ti = slp->sl_ti[target];
465 		cb->osdep = ccb;
466 		cb->bp = NULL;
467 		if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
468 			flags = CCB_AUTOSENSE | CCB_SCSIIO;
469 		else
470 			flags = CCB_SCSIIO;
471 
472 		s = splcam();
473 		li = scsi_low_alloc_li(ti, lun, 1);
474 
475 		if (ti->ti_setup_msg != 0)
476 		{
477 			scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
478 		}
479 
480 		scsi_low_enqueue(slp, ti, li, cb, flags, 0);
481 
482 #ifdef	SCSI_LOW_DEBUG
483 		if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
484 		{
485 			scsi_low_test_abort(slp, ti, li);
486 		}
487 #endif	/* SCSI_LOW_DEBUG */
488 		splx(s);
489 		break;
490 
491 	case XPT_EN_LUN:		/* Enable LUN as a target */
492 	case XPT_TARGET_IO:		/* Execute target I/O request */
493 	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
494 	case XPT_CONT_TARGET_IO:	/* Continue Host Target I/O Connection*/
495 		/* XXX Implement */
496 		ccb->ccb_h.status = CAM_REQ_INVALID;
497 		xpt_done(ccb);
498 		break;
499 
500 	case XPT_ABORT:			/* Abort the specified CCB */
501 #ifdef	SCSI_LOW_DIAGNOSTIC
502 		if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
503 		{
504 			device_printf(slp->sl_dev, "invalid target/lun\n");
505 			ccb->ccb_h.status = CAM_REQ_INVALID;
506 			xpt_done(ccb);
507 			return;
508 		}
509 #endif	/* SCSI_LOW_DIAGNOSTIC */
510 
511 		s = splcam();
512 		cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
513 		rv = scsi_low_abort_ccb(slp, cb);
514 		splx(s);
515 
516 		if (rv == 0)
517 			ccb->ccb_h.status = CAM_REQ_CMP;
518 		else
519 			ccb->ccb_h.status = CAM_REQ_INVALID;
520 		xpt_done(ccb);
521 		break;
522 
523 	case XPT_SET_TRAN_SETTINGS: {
524 		struct ccb_trans_settings_scsi *scsi;
525         	struct ccb_trans_settings_spi *spi;
526 		struct ccb_trans_settings *cts;
527 		u_int val;
528 
529 #ifdef	SCSI_LOW_DIAGNOSTIC
530 		if (target == CAM_TARGET_WILDCARD)
531 		{
532 			device_printf(slp->sl_dev, "invalid target\n");
533 			ccb->ccb_h.status = CAM_REQ_INVALID;
534 			xpt_done(ccb);
535 			return;
536 		}
537 #endif	/* SCSI_LOW_DIAGNOSTIC */
538 		cts = &ccb->cts;
539 		ti = slp->sl_ti[target];
540 		if (lun == CAM_LUN_WILDCARD)
541 			lun = 0;
542 
543 		s = splcam();
544 		scsi = &cts->proto_specific.scsi;
545 		spi = &cts->xport_specific.spi;
546 		if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH |
547 				   CTS_SPI_VALID_SYNC_RATE |
548 				   CTS_SPI_VALID_SYNC_OFFSET)) != 0)
549 		{
550 			if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
551 				val = spi->bus_width;
552 				if (val < ti->ti_width)
553 					ti->ti_width = val;
554 			}
555 			if (spi->valid & CTS_SPI_VALID_SYNC_RATE) {
556 				val = spi->sync_period;
557 				if (val == 0 || val > ti->ti_maxsynch.period)
558 					ti->ti_maxsynch.period = val;
559 			}
560 			if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
561 				val = spi->sync_offset;
562 				if (val < ti->ti_maxsynch.offset)
563 					ti->ti_maxsynch.offset = val;
564 			}
565 			ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
566 			scsi_low_calcf_target(ti);
567 		}
568 
569 		if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 ||
570                     (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
571 
572 			li = scsi_low_alloc_li(ti, lun, 1);
573 			if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) {
574 				li->li_quirks |= SCSI_LOW_DISK_DISC;
575 			} else {
576 				li->li_quirks &= ~SCSI_LOW_DISK_DISC;
577 			}
578 
579 			if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
580 				li->li_quirks |= SCSI_LOW_DISK_QTAG;
581 			} else {
582 				li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
583 			}
584 			li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
585 			scsi_low_calcf_target(ti);
586 			scsi_low_calcf_lun(li);
587 			if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
588 				scsi_low_calcf_show(li);
589 		}
590 		splx(s);
591 
592 		ccb->ccb_h.status = CAM_REQ_CMP;
593 		xpt_done(ccb);
594 		break;
595 	}
596 
597 	case XPT_GET_TRAN_SETTINGS: {
598 		struct ccb_trans_settings *cts;
599 		u_int diskflags;
600 
601 		cts = &ccb->cts;
602 #ifdef	SCSI_LOW_DIAGNOSTIC
603 		if (target == CAM_TARGET_WILDCARD)
604 		{
605 			device_printf(slp->sl_dev, "invalid target\n");
606 			ccb->ccb_h.status = CAM_REQ_INVALID;
607 			xpt_done(ccb);
608 			return;
609 		}
610 #endif	/* SCSI_LOW_DIAGNOSTIC */
611 		ti = slp->sl_ti[target];
612 		if (lun == CAM_LUN_WILDCARD)
613 			lun = 0;
614 
615 		s = splcam();
616 		li = scsi_low_alloc_li(ti, lun, 1);
617 		if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
618 			struct ccb_trans_settings_scsi *scsi =
619 				&cts->proto_specific.scsi;
620 			struct ccb_trans_settings_spi *spi =
621 				&cts->xport_specific.spi;
622 #ifdef	SCSI_LOW_DIAGNOSTIC
623 			if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
624 			{
625 				ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
626 				device_printf(slp->sl_dev,
627 				    "invalid GET_TRANS_CURRENT_SETTINGS call\n");
628 				goto settings_out;
629 			}
630 #endif	/* SCSI_LOW_DIAGNOSTIC */
631 			cts->protocol = PROTO_SCSI;
632 			cts->protocol_version = SCSI_REV_2;
633 			cts->transport = XPORT_SPI;
634 			cts->transport_version = 2;
635 
636 			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
637 			spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
638 
639 			diskflags = li->li_diskflags & li->li_cfgflags;
640 			if (diskflags & SCSI_LOW_DISK_DISC)
641 				spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
642 			if (diskflags & SCSI_LOW_DISK_QTAG)
643 				scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
644 
645 			spi->sync_period = ti->ti_maxsynch.period;
646 			spi->valid |= CTS_SPI_VALID_SYNC_RATE;
647 			spi->sync_offset = ti->ti_maxsynch.offset;
648 			spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
649 
650 			spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
651 			spi->bus_width = ti->ti_width;
652 
653 			if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
654 				scsi->valid = CTS_SCSI_VALID_TQ;
655 				spi->valid |= CTS_SPI_VALID_DISC;
656 			} else
657 				scsi->valid = 0;
658 		} else
659 			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
660 settings_out:
661 		splx(s);
662 		xpt_done(ccb);
663 		break;
664 	}
665 
666 	case XPT_CALC_GEOMETRY: { /* not yet HN2 */
667 		cam_calc_geometry(&ccb->ccg, /*extended*/1);
668 		xpt_done(ccb);
669 		break;
670 	}
671 
672 	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
673 		s = splcam();
674 		scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
675 		splx(s);
676 		ccb->ccb_h.status = CAM_REQ_CMP;
677 		xpt_done(ccb);
678 		break;
679 
680 	case XPT_TERM_IO:	/* Terminate the I/O process */
681 		ccb->ccb_h.status = CAM_REQ_INVALID;
682 		xpt_done(ccb);
683 		break;
684 
685 	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
686 #ifdef	SCSI_LOW_DIAGNOSTIC
687 		if (target == CAM_TARGET_WILDCARD)
688 		{
689 			device_printf(slp->sl_dev, "invalid target\n");
690 			ccb->ccb_h.status = CAM_REQ_INVALID;
691 			xpt_done(ccb);
692 			return;
693 		}
694 #endif	/* SCSI_LOW_DIAGNOSTIC */
695 
696 		msg = SCSI_LOW_MSG_RESET;
697 		if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
698 		{
699 			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
700 			xpt_done(ccb);
701 			return;
702 		}
703 
704 		ti = slp->sl_ti[target];
705 		if (lun == CAM_LUN_WILDCARD)
706 			lun = 0;
707 		cb->osdep = ccb;
708 		cb->bp = NULL;
709 		if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
710 			flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
711 		else
712 			flags = CCB_NORETRY | CCB_URGENT;
713 
714 		s = splcam();
715 		li = scsi_low_alloc_li(ti, lun, 1);
716 		scsi_low_enqueue(slp, ti, li, cb, flags, msg);
717 		splx(s);
718 		break;
719 
720 	case XPT_PATH_INQ: {		/* Path routing inquiry */
721 		struct ccb_pathinq *cpi = &ccb->cpi;
722 
723 		cpi->version_num = scsi_low_version_major;
724 		cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
725 		ti = slp->sl_ti[slp->sl_hostid];	/* host id */
726 		if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
727 			cpi->hba_inquiry |= PI_WIDE_16;
728 		if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
729 			cpi->hba_inquiry |= PI_WIDE_32;
730 		if (ti->ti_maxsynch.offset > 0)
731 			cpi->hba_inquiry |= PI_SDTR_ABLE;
732 		cpi->target_sprt = 0;
733 		cpi->hba_misc = 0;
734 		cpi->hba_eng_cnt = 0;
735 		cpi->max_target = slp->sl_ntargs - 1;
736 		cpi->max_lun = slp->sl_nluns - 1;
737 		cpi->initiator_id = slp->sl_hostid;
738 		cpi->bus_id = cam_sim_bus(sim);
739 		cpi->base_transfer_speed = 3300;
740 		cpi->transport = XPORT_SPI;
741 		cpi->transport_version = 2;
742 		cpi->protocol = PROTO_SCSI;
743 		cpi->protocol_version = SCSI_REV_2;
744 		strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
745 		strlcpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
746 		strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
747 		cpi->unit_number = cam_sim_unit(sim);
748 		cpi->ccb_h.status = CAM_REQ_CMP;
749 		xpt_done(ccb);
750 		break;
751 	}
752 
753 	default:
754 	        printf("scsi_low: non support func_code = %d ",
755 			ccb->ccb_h.func_code);
756 		ccb->ccb_h.status = CAM_REQ_INVALID;
757 		xpt_done(ccb);
758 		break;
759 	}
760 }
761 
762 static int
scsi_low_attach_cam(slp)763 scsi_low_attach_cam(slp)
764 	struct scsi_low_softc *slp;
765 {
766 	struct cam_devq *devq;
767 	int tagged_openings;
768 
769 	devq = cam_simq_alloc(SCSI_LOW_NCCB);
770 	if (devq == NULL)
771 		return (ENOMEM);
772 
773 	/*
774 	 * ask the adapter what subunits are present
775 	 */
776 	tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
777 	slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
778 				scsi_low_poll_cam,
779 				device_get_name(slp->sl_dev), slp,
780 				device_get_unit(slp->sl_dev), &Giant,
781 				slp->sl_openings, tagged_openings, devq);
782 
783 	if (slp->sl_si.sim == NULL) {
784 		cam_simq_free(devq);
785 	 	return ENODEV;
786 	}
787 
788 	if (xpt_bus_register(slp->sl_si.sim, NULL, 0) != CAM_SUCCESS) {
789 		free(slp->sl_si.sim, M_SCSILOW);
790 	 	return ENODEV;
791 	}
792 
793 	if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
794 			cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
795 			CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
796 		xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
797 		cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE);
798 		return ENODEV;
799 	}
800 
801 	slp->sl_show_result = SHOW_CALCF_RES;		/* OK ? */
802 	return 0;
803 }
804 
805 static int
scsi_low_world_start_cam(slp)806 scsi_low_world_start_cam(slp)
807 	struct scsi_low_softc *slp;
808 {
809 
810 	return 0;
811 }
812 
813 static int
scsi_low_dettach_cam(slp)814 scsi_low_dettach_cam(slp)
815 	struct scsi_low_softc *slp;
816 {
817 
818 	xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
819 	xpt_free_path(slp->sl_si.path);
820 	xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
821 	cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE);
822 	return 0;
823 }
824 
825 static int
scsi_low_ccb_setup_cam(slp,cb)826 scsi_low_ccb_setup_cam(slp, cb)
827 	struct scsi_low_softc *slp;
828 	struct slccb *cb;
829 {
830         union ccb *ccb = (union ccb *) cb->osdep;
831 
832 	if ((cb->ccb_flags & CCB_SCSIIO) != 0)
833 	{
834 		cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
835 		cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
836 		cb->ccb_scp.scp_data = ccb->csio.data_ptr;
837 		cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
838 		if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
839 			cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
840 		else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
841 			cb->ccb_scp.scp_direction = SCSI_LOW_READ;
842 		cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
843 	}
844 	else
845 	{
846 		scsi_low_unit_ready_cmd(cb);
847 	}
848 	return SCSI_LOW_START_QTAG;
849 }
850 
851 static int
scsi_low_done_cam(slp,cb)852 scsi_low_done_cam(slp, cb)
853 	struct scsi_low_softc *slp;
854 	struct slccb *cb;
855 {
856 	union ccb *ccb;
857 
858 	ccb = (union ccb *) cb->osdep;
859 	if (cb->ccb_error == 0)
860 	{
861 		ccb->ccb_h.status = CAM_REQ_CMP;
862 		ccb->csio.resid = 0;
863 	}
864 	else
865 	{
866 	        if (cb->ccb_rcnt >= slp->sl_max_retry)
867 			cb->ccb_error |= ABORTIO;
868 
869 		if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
870 		    (cb->ccb_error & ABORTIO) == 0)
871 			return EJUSTRETURN;
872 
873 		if ((cb->ccb_error & SENSEIO) != 0)
874 		{
875 			memcpy(&ccb->csio.sense_data,
876 			       &cb->ccb_sense,
877 			       sizeof(ccb->csio.sense_data));
878 		}
879 
880 		ccb->ccb_h.status = scsi_low_translate_error_code(cb,
881 					&scsi_low_error_code_cam[0]);
882 
883 #ifdef	SCSI_LOW_DIAGNOSTIC
884 		if ((cb->ccb_flags & CCB_SILENT) == 0 &&
885 		    cb->ccb_scp.scp_cmdlen > 0 &&
886 		    (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
887 		     SCSI_LOW_CMD_ABORT_WARNING) != 0)
888 		{
889 			device_printf(slp->sl_dev,
890 			    "WARNING: scsi_low IO abort\n");
891 			scsi_low_print(slp, NULL);
892 		}
893 #endif	/* SCSI_LOW_DIAGNOSTIC */
894 	}
895 
896 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
897 		ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
898 
899 	if (cb->ccb_scp.scp_status == ST_UNKNOWN)
900 		ccb->csio.scsi_status = 0;	/* XXX */
901 	else
902 		ccb->csio.scsi_status = cb->ccb_scp.scp_status;
903 
904 	if ((cb->ccb_flags & CCB_NOSDONE) == 0)
905 		xpt_done(ccb);
906 	return 0;
907 }
908 
909 static void
scsi_low_timeout_cam(slp,ch,action)910 scsi_low_timeout_cam(slp, ch, action)
911 	struct scsi_low_softc *slp;
912 	int ch;
913 	int action;
914 {
915 
916 	switch (ch)
917 	{
918 	case SCSI_LOW_TIMEOUT_CH_IO:
919 		switch (action)
920 		{
921 		case SCSI_LOW_TIMEOUT_START:
922 			slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
923 				hz / SCSI_LOW_TIMEOUT_HZ);
924 			break;
925 		case SCSI_LOW_TIMEOUT_STOP:
926 			untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
927 			break;
928 		}
929 		break;
930 
931 	case SCSI_LOW_TIMEOUT_CH_ENGAGE:
932 		switch (action)
933 		{
934 		case SCSI_LOW_TIMEOUT_START:
935 			slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
936 			break;
937 		case SCSI_LOW_TIMEOUT_STOP:
938 			untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
939 			break;
940 		}
941 		break;
942 	case SCSI_LOW_TIMEOUT_CH_RECOVER:
943 		break;
944 	}
945 }
946 
947 /*=============================================================
948  * END OF OS switch  (All OS depend fucntions should be above)
949  =============================================================*/
950 
951 /**************************************************************
952  * scsi low deactivate and activate
953  **************************************************************/
954 int
scsi_low_is_busy(slp)955 scsi_low_is_busy(slp)
956 	struct scsi_low_softc *slp;
957 {
958 
959 	if (slp->sl_nio > 0)
960 		return EBUSY;
961 	return 0;
962 }
963 
964 int
scsi_low_deactivate(slp)965 scsi_low_deactivate(slp)
966 	struct scsi_low_softc *slp;
967 {
968 	int s;
969 
970 	s = splcam();
971 	slp->sl_flags |= HW_INACTIVE;
972 	(*slp->sl_osdep_fp->scsi_low_osdep_timeout)
973 		(slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
974 	(*slp->sl_osdep_fp->scsi_low_osdep_timeout)
975 		(slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
976 	splx(s);
977 	return 0;
978 }
979 
980 int
scsi_low_activate(slp)981 scsi_low_activate(slp)
982 	struct scsi_low_softc *slp;
983 {
984 	int error, s;
985 
986 	s = splcam();
987 	slp->sl_flags &= ~HW_INACTIVE;
988 	if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
989 	{
990 		slp->sl_flags |= HW_INACTIVE;
991 		splx(s);
992 		return error;
993 	}
994 
995 	slp->sl_timeout_count = 0;
996 	(*slp->sl_osdep_fp->scsi_low_osdep_timeout)
997 		(slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
998 	splx(s);
999 	return 0;
1000 }
1001 
1002 /**************************************************************
1003  * scsi low log
1004  **************************************************************/
1005 #ifdef	SCSI_LOW_DIAGNOSTIC
1006 static void scsi_low_msg_log_init(struct scsi_low_msg_log *);
1007 static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int);
1008 static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int);
1009 
1010 static void
scsi_low_msg_log_init(slmlp)1011 scsi_low_msg_log_init(slmlp)
1012 	struct scsi_low_msg_log *slmlp;
1013 {
1014 
1015 	slmlp->slml_ptr = 0;
1016 }
1017 
1018 static void
scsi_low_msg_log_write(slmlp,datap,len)1019 scsi_low_msg_log_write(slmlp, datap, len)
1020 	struct scsi_low_msg_log *slmlp;
1021 	u_int8_t *datap;
1022 	int len;
1023 {
1024 	int ptr, ind;
1025 
1026 	if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1027 		return;
1028 
1029 	ptr = slmlp->slml_ptr ++;
1030 	for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1031 		slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1032 	for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1033 		slmlp->slml_msg[ptr].msg[ind] = 0;
1034 }
1035 
1036 static void
scsi_low_msg_log_show(slmlp,s,len)1037 scsi_low_msg_log_show(slmlp, s, len)
1038 	struct scsi_low_msg_log *slmlp;
1039 	char *s;
1040 	int len;
1041 {
1042 	int ptr, ind;
1043 
1044 	printf("%s: (%d) ", s, slmlp->slml_ptr);
1045 	for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1046 	{
1047 		for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1048 		     ind ++)
1049 		{
1050 			printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1051 		}
1052 		printf(">");
1053 	}
1054 	printf("\n");
1055 }
1056 #endif	/* SCSI_LOW_DIAGNOSTIC */
1057 
1058 /**************************************************************
1059  * power control
1060  **************************************************************/
1061 static void
scsi_low_engage(arg)1062 scsi_low_engage(arg)
1063 	void *arg;
1064 {
1065 	struct scsi_low_softc *slp = arg;
1066 	int s = splcam();
1067 
1068 	switch (slp->sl_rstep)
1069 	{
1070 	case 0:
1071 		slp->sl_rstep ++;
1072 		(*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1073 		(*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1074 			SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1075 		break;
1076 
1077 	case 1:
1078 		slp->sl_rstep ++;
1079 		slp->sl_flags &= ~HW_RESUME;
1080 		scsi_low_start(slp);
1081 		break;
1082 
1083 	case 2:
1084 		break;
1085 	}
1086 	splx(s);
1087 }
1088 
1089 static int
scsi_low_init(slp,flags)1090 scsi_low_init(slp, flags)
1091 	struct scsi_low_softc *slp;
1092 	u_int flags;
1093 {
1094 	int rv = 0;
1095 
1096 	slp->sl_flags |= HW_INITIALIZING;
1097 
1098 	/* clear power control timeout */
1099 	if ((slp->sl_flags & HW_POWERCTRL) != 0)
1100 	{
1101 		(*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1102 			SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1103 		slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1104 		slp->sl_active = 1;
1105 		slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1106 	}
1107 
1108 	/* reset current nexus */
1109 	scsi_low_reset_nexus(slp, flags);
1110 	if ((slp->sl_flags & HW_INACTIVE) != 0)
1111 	{
1112 		rv = EBUSY;
1113 		goto out;
1114 	}
1115 
1116 	if (flags != SCSI_LOW_RESTART_SOFT)
1117 	{
1118 		rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1119 	}
1120 
1121 out:
1122 	slp->sl_flags &= ~HW_INITIALIZING;
1123 	return rv;
1124 }
1125 
1126 /**************************************************************
1127  * allocate lun_info
1128  **************************************************************/
1129 static struct lun_info *
scsi_low_alloc_li(ti,lun,alloc)1130 scsi_low_alloc_li(ti, lun, alloc)
1131 	struct targ_info *ti;
1132 	int lun;
1133 	int alloc;
1134 {
1135 	struct scsi_low_softc *slp = ti->ti_sc;
1136 	struct lun_info *li;
1137 
1138 	li = LIST_FIRST(&ti->ti_litab);
1139 	if (li != NULL)
1140 	{
1141 		if (li->li_lun == lun)
1142 			return li;
1143 
1144 		while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1145 		{
1146 			if (li->li_lun == lun)
1147 			{
1148 				LIST_REMOVE(li, lun_chain);
1149 				LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1150 				return li;
1151 			}
1152 		}
1153 	}
1154 
1155 	if (alloc == 0)
1156 		return li;
1157 
1158 	li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1159 	if (li == NULL)
1160 		panic("no lun info mem");
1161 
1162 	bzero(li, ti->ti_lunsize);
1163 	li->li_lun = lun;
1164 	li->li_ti = ti;
1165 
1166 	li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1167 			  SCSI_LOW_QTAG;
1168 	li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1169 	li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1170 #ifdef	SCSI_LOW_FLAGS_QUIRKS_OK
1171 	li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1172 #endif	/* SCSI_LOW_FLAGS_QUIRKS_OK */
1173 
1174 	li->li_qtagbits = (u_int) -1;
1175 
1176 	TAILQ_INIT(&li->li_discq);
1177 	LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1178 
1179 	/* host specific structure initialization per lun */
1180 	if (slp->sl_funcs->scsi_low_lun_init != NULL)
1181 		(*slp->sl_funcs->scsi_low_lun_init)
1182 			(slp, ti, li, SCSI_LOW_INFO_ALLOC);
1183 	scsi_low_calcf_lun(li);
1184 	return li;
1185 }
1186 
1187 /**************************************************************
1188  * allocate targ_info
1189  **************************************************************/
1190 static struct targ_info *
scsi_low_alloc_ti(slp,targ)1191 scsi_low_alloc_ti(slp, targ)
1192 	struct scsi_low_softc *slp;
1193 	int targ;
1194 {
1195 	struct targ_info *ti;
1196 
1197 	if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1198 		TAILQ_INIT(&slp->sl_titab);
1199 
1200 	ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1201 	if (ti == NULL)
1202 		panic("%s short of memory", device_get_nameunit(slp->sl_dev));
1203 
1204 	bzero(ti, slp->sl_targsize);
1205 	ti->ti_id = targ;
1206 	ti->ti_sc = slp;
1207 
1208 	slp->sl_ti[targ] = ti;
1209 	TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1210 	LIST_INIT(&ti->ti_litab);
1211 
1212 	ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1213 	ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1214 	ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1215 #ifdef	SCSI_LOW_FLAGS_QUIRKS_OK
1216 	ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1217 #endif	/* SCSI_LOW_FLAGS_QUIRKS_OK */
1218 
1219 	if (slp->sl_funcs->scsi_low_targ_init != NULL)
1220 	{
1221 		(*slp->sl_funcs->scsi_low_targ_init)
1222 			(slp, ti, SCSI_LOW_INFO_ALLOC);
1223 	}
1224 	scsi_low_calcf_target(ti);
1225 	return ti;
1226 }
1227 
1228 static void
scsi_low_free_ti(slp)1229 scsi_low_free_ti(slp)
1230 	struct scsi_low_softc *slp;
1231 {
1232 	struct targ_info *ti, *tib;
1233 	struct lun_info *li, *nli;
1234 
1235 	for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1236 	{
1237 		for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1238 		{
1239 			if (slp->sl_funcs->scsi_low_lun_init != NULL)
1240 			{
1241 				(*slp->sl_funcs->scsi_low_lun_init)
1242 					(slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1243 			}
1244 			nli = LIST_NEXT(li, lun_chain);
1245 			SCSI_LOW_FREE(li);
1246 		}
1247 
1248 		if (slp->sl_funcs->scsi_low_targ_init != NULL)
1249 		{
1250 			(*slp->sl_funcs->scsi_low_targ_init)
1251 				(slp, ti, SCSI_LOW_INFO_DEALLOC);
1252 		}
1253 		tib = TAILQ_NEXT(ti, ti_chain);
1254 		SCSI_LOW_FREE(ti);
1255 	}
1256 }
1257 
1258 /**************************************************************
1259  * timeout
1260  **************************************************************/
1261 void
scsi_low_bus_idle(slp)1262 scsi_low_bus_idle(slp)
1263 	struct scsi_low_softc *slp;
1264 {
1265 
1266 	slp->sl_retry_sel = 0;
1267 	if (slp->sl_Tnexus == NULL)
1268 		scsi_low_start(slp);
1269 }
1270 
1271 static void
scsi_low_timeout(arg)1272 scsi_low_timeout(arg)
1273 	void *arg;
1274 {
1275 	struct scsi_low_softc *slp = arg;
1276 	int s;
1277 
1278 	s = splcam();
1279 	(void) scsi_low_timeout_check(slp);
1280 	(*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1281 		(slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1282 	splx(s);
1283 }
1284 
1285 static int
scsi_low_timeout_check(slp)1286 scsi_low_timeout_check(slp)
1287 	struct scsi_low_softc *slp;
1288 {
1289 	struct targ_info *ti;
1290 	struct lun_info *li;
1291 	struct slccb *cb = NULL;		/* XXX */
1292 
1293 	/* selection restart */
1294 	if (slp->sl_retry_sel != 0)
1295 	{
1296 		slp->sl_retry_sel = 0;
1297 		if (slp->sl_Tnexus != NULL)
1298 			goto step1;
1299 
1300 		cb = TAILQ_FIRST(&slp->sl_start);
1301 		if (cb == NULL)
1302 			goto step1;
1303 
1304 		if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1305 		{
1306 			cb->ccb_flags |= CCB_NORETRY;
1307 			cb->ccb_error |= SELTIMEOUTIO;
1308 			if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1309 				panic("%s: ccb not finished",
1310 				    device_get_nameunit(slp->sl_dev));
1311 		}
1312 
1313 		if (slp->sl_Tnexus == NULL)
1314 			scsi_low_start(slp);
1315 	}
1316 
1317 	/* call hardware timeout */
1318 step1:
1319 	if (slp->sl_funcs->scsi_low_timeout != NULL)
1320 	{
1321 		(*slp->sl_funcs->scsi_low_timeout) (slp);
1322 	}
1323 
1324 	if (slp->sl_timeout_count ++ <
1325 	    SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1326 		return 0;
1327 
1328 	slp->sl_timeout_count = 0;
1329 	if (slp->sl_nio > 0)
1330 	{
1331 		if ((cb = slp->sl_Qnexus) != NULL)
1332 		{
1333 			cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1334 			if (cb->ccb_tc < 0)
1335 				goto bus_reset;
1336 		}
1337 		else if (slp->sl_disc == 0)
1338 		{
1339 		        if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1340 				return 0;
1341 
1342 			cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1343 			if (cb->ccb_tc < 0)
1344 				goto bus_reset;
1345 		}
1346 		else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1347 		          ti = TAILQ_NEXT(ti, ti_chain))
1348 		{
1349 			if (ti->ti_disc == 0)
1350 				continue;
1351 
1352 			for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1353 			     li = LIST_NEXT(li, lun_chain))
1354 			{
1355 				for (cb = TAILQ_FIRST(&li->li_discq);
1356 				     cb != NULL;
1357 				     cb = TAILQ_NEXT(cb, ccb_chain))
1358 				{
1359 					cb->ccb_tc -=
1360 						SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1361 					if (cb->ccb_tc < 0)
1362 						goto bus_reset;
1363 				}
1364 			}
1365 		}
1366 
1367 	}
1368 	else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1369 	{
1370 		if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1371 			return 0;
1372 
1373 		if (slp->sl_active != 0)
1374 		{
1375 			slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1376 			slp->sl_active = 0;
1377 			return 0;
1378 		}
1379 
1380 		slp->sl_powc --;
1381 		if (slp->sl_powc < 0)
1382 		{
1383 			slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1384 			slp->sl_flags |= HW_POWDOWN;
1385 			(*slp->sl_funcs->scsi_low_power)
1386 					(slp, SCSI_LOW_POWDOWN);
1387 		}
1388 	}
1389 	return 0;
1390 
1391 bus_reset:
1392 	cb->ccb_error |= TIMEOUTIO;
1393 	device_printf(slp->sl_dev, "slccb (0x%lx) timeout!\n", (u_long) cb);
1394 	scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1395 	scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1396 	scsi_low_start(slp);
1397 	return ERESTART;
1398 }
1399 
1400 
1401 static int
scsi_low_abort_ccb(slp,cb)1402 scsi_low_abort_ccb(slp, cb)
1403 	struct scsi_low_softc *slp;
1404 	struct slccb *cb;
1405 {
1406 	struct targ_info *ti;
1407 	struct lun_info *li;
1408 	u_int msg;
1409 
1410 	if (cb == NULL)
1411 		return EINVAL;
1412 	if ((cb->ccb_omsgoutflag &
1413 	     (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1414 		return EBUSY;
1415 
1416 	ti = cb->ti;
1417 	li = cb->li;
1418 	if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1419 		msg = SCSI_LOW_MSG_ABORT;
1420 	else
1421 		msg = SCSI_LOW_MSG_ABORT_QTAG;
1422 
1423 	cb->ccb_error |= ABORTIO;
1424 	cb->ccb_flags |= CCB_NORETRY;
1425 	scsi_low_ccb_message_assert(cb, msg);
1426 
1427 	if (cb == slp->sl_Qnexus)
1428 	{
1429 		scsi_low_assert_msg(slp, ti, msg, 1);
1430 	}
1431 	else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1432 	{
1433 		if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1434 			panic("%s: revoked ccb done",
1435 			    device_get_nameunit(slp->sl_dev));
1436 
1437 		cb->ccb_flags |= CCB_STARTQ;
1438 		TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1439 
1440 		if (slp->sl_Tnexus == NULL)
1441 			scsi_low_start(slp);
1442 	}
1443 	else
1444 	{
1445 		if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1446 			panic("%s: revoked ccb retried",
1447 			    device_get_nameunit(slp->sl_dev));
1448 	}
1449 	return 0;
1450 }
1451 
1452 /**************************************************************
1453  * Generic SCSI INTERFACE
1454  **************************************************************/
1455 int
scsi_low_attach(slp,openings,ntargs,nluns,targsize,lunsize)1456 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
1457 	struct scsi_low_softc *slp;
1458 	int openings, ntargs, nluns, targsize, lunsize;
1459 {
1460 	struct targ_info *ti;
1461 	struct lun_info *li;
1462 	int s, i, nccb, rv;
1463 
1464 	slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
1465 
1466 	if (slp->sl_osdep_fp == NULL)
1467 		panic("scsi_low: interface not spcified");
1468 
1469 	if (ntargs > SCSI_LOW_NTARGETS)
1470 	{
1471 		printf("scsi_low: %d targets are too large\n", ntargs);
1472 		printf("change kernel options SCSI_LOW_NTARGETS");
1473 		return EINVAL;
1474 	}
1475 
1476 	if (openings <= 0)
1477 		slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1478 	else
1479 		slp->sl_openings = openings;
1480 	slp->sl_ntargs = ntargs;
1481 	slp->sl_nluns = nluns;
1482 	slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1483 
1484 	if (lunsize < sizeof(struct lun_info))
1485 		lunsize = sizeof(struct lun_info);
1486 
1487 	if (targsize < sizeof(struct targ_info))
1488 		targsize = sizeof(struct targ_info);
1489 
1490 	slp->sl_targsize = targsize;
1491 	for (i = 0; i < ntargs; i ++)
1492 	{
1493 		ti = scsi_low_alloc_ti(slp, i);
1494 		ti->ti_lunsize = lunsize;
1495 		li = scsi_low_alloc_li(ti, 0, 1);
1496 	}
1497 
1498 	/* initialize queue */
1499 	nccb = openings * ntargs;
1500 	if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1501 		nccb = SCSI_LOW_NCCB;
1502 	scsi_low_init_ccbque(nccb);
1503 	TAILQ_INIT(&slp->sl_start);
1504 
1505 	/* call os depend attach */
1506 	s = splcam();
1507 	rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
1508 	if (rv != 0)
1509 	{
1510 		splx(s);
1511 		device_printf(slp->sl_dev,
1512 		    "scsi_low_attach: osdep attach failed\n");
1513 		return EINVAL;
1514 	}
1515 
1516 	/* check hardware */
1517 	DELAY(1000);	/* wait for 1ms */
1518 	if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1519 	{
1520 		splx(s);
1521 		device_printf(slp->sl_dev,
1522 		    "scsi_low_attach: initialization failed\n");
1523 		return EINVAL;
1524 	}
1525 
1526 	/* start watch dog */
1527 	slp->sl_timeout_count = 0;
1528 	(*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1529 		 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1530 	LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1531 
1532 	/* fake call */
1533 	scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1534 
1535 #ifdef	SCSI_LOW_START_UP_CHECK
1536 	/* probing devices */
1537 	scsi_low_start_up(slp);
1538 #endif	/* SCSI_LOW_START_UP_CHECK */
1539 
1540 	/* call os depend attach done*/
1541 	(*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
1542 	splx(s);
1543 	return 0;
1544 }
1545 
1546 int
scsi_low_dettach(slp)1547 scsi_low_dettach(slp)
1548 	struct scsi_low_softc *slp;
1549 {
1550 	int s, rv;
1551 
1552 	s = splcam();
1553 	if (scsi_low_is_busy(slp) != 0)
1554 	{
1555 		splx(s);
1556 		return EBUSY;
1557 	}
1558 
1559 	scsi_low_deactivate(slp);
1560 
1561 	rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
1562 	if (rv != 0)
1563 	{
1564 		splx(s);
1565 		return EBUSY;
1566 	}
1567 
1568 	scsi_low_free_ti(slp);
1569 	LIST_REMOVE(slp, sl_chain);
1570 	splx(s);
1571 	return 0;
1572 }
1573 
1574 /**************************************************************
1575  * Generic enqueue
1576  **************************************************************/
1577 static int
scsi_low_enqueue(slp,ti,li,cb,flags,msg)1578 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
1579 	struct scsi_low_softc *slp;
1580 	struct targ_info *ti;
1581 	struct lun_info *li;
1582 	struct slccb *cb;
1583 	u_int flags, msg;
1584 {
1585 
1586 	cb->ti = ti;
1587 	cb->li = li;
1588 
1589 	scsi_low_ccb_message_assert(cb, msg);
1590 
1591 	cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1592 	scsi_low_alloc_qtag(cb);
1593 
1594 	cb->ccb_flags = flags | CCB_STARTQ;
1595 	cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1596 	cb->ccb_error |= PENDINGIO;
1597 
1598 	if ((flags & CCB_URGENT) != 0)
1599 	{
1600 		TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1601 	}
1602 	else
1603 	{
1604 		TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1605 	}
1606 
1607 	slp->sl_nio ++;
1608 
1609 	if (slp->sl_Tnexus == NULL)
1610 		scsi_low_start(slp);
1611 	return 0;
1612 }
1613 
1614 static int
scsi_low_message_enqueue(slp,ti,li,flags)1615 scsi_low_message_enqueue(slp, ti, li, flags)
1616 	struct scsi_low_softc *slp;
1617 	struct targ_info *ti;
1618 	struct lun_info *li;
1619 	u_int flags;
1620 {
1621 	struct slccb *cb;
1622 	u_int tmsgflags;
1623 
1624 	tmsgflags = ti->ti_setup_msg;
1625 	ti->ti_setup_msg = 0;
1626 
1627 	flags |= CCB_NORETRY;
1628 	if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1629 		return ENOMEM;
1630 
1631 	cb->osdep = NULL;
1632 	cb->bp = NULL;
1633 	scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1634 	return 0;
1635 }
1636 
1637 /**************************************************************
1638  * Generic Start & Done
1639  **************************************************************/
1640 #define	SLSC_MODE_SENSE_SHORT   0x1a
1641 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1642 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1643 			      sizeof(struct scsi_low_mode_sense_data), 0};
1644 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1645 			      sizeof(struct scsi_low_inq_data), 0};
1646 static u_int8_t unit_ready_cmd[6];
1647 static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1648 static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1649 static int scsi_low_resume(struct scsi_low_softc *);
1650 
1651 static void
scsi_low_unit_ready_cmd(cb)1652 scsi_low_unit_ready_cmd(cb)
1653 	struct slccb *cb;
1654 {
1655 
1656 	cb->ccb_scp.scp_cmd = unit_ready_cmd;
1657 	cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1658 	cb->ccb_scp.scp_datalen = 0;
1659 	cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1660 	cb->ccb_tcmax = 15;
1661 }
1662 
1663 static int
scsi_low_sense_abort_start(slp,ti,li,cb)1664 scsi_low_sense_abort_start(slp, ti, li, cb)
1665 	struct scsi_low_softc *slp;
1666 	struct targ_info *ti;
1667 	struct lun_info *li;
1668 	struct slccb *cb;
1669 {
1670 
1671 	cb->ccb_scp.scp_cmdlen = 6;
1672 	bzero(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1673 	cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1674 	cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1675 	cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1676 	cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1677 	cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1678 	cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1679 	cb->ccb_tcmax = 15;
1680 	scsi_low_ccb_message_clear(cb);
1681 	if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1682 	{
1683 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1684 	}
1685 	else
1686 	{
1687 		bzero(&cb->ccb_sense, sizeof(cb->ccb_sense));
1688 #ifdef	SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1689 		scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1690 #endif	/* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1691 	}
1692 
1693 	return SCSI_LOW_START_NO_QTAG;
1694 }
1695 
1696 static int
scsi_low_setup_start(slp,ti,li,cb)1697 scsi_low_setup_start(slp, ti, li, cb)
1698 	struct scsi_low_softc *slp;
1699 	struct targ_info *ti;
1700 	struct lun_info *li;
1701 	struct slccb *cb;
1702 {
1703 
1704 	switch(li->li_state)
1705 	{
1706 	case SCSI_LOW_LUN_SLEEP:
1707 		scsi_low_unit_ready_cmd(cb);
1708 		break;
1709 
1710 	case SCSI_LOW_LUN_START:
1711 		cb->ccb_scp.scp_cmd = ss_cmd;
1712 		cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1713 		cb->ccb_scp.scp_datalen = 0;
1714 		cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1715 		cb->ccb_tcmax = 30;
1716 		break;
1717 
1718 	case SCSI_LOW_LUN_INQ:
1719 		cb->ccb_scp.scp_cmd = inq_cmd;
1720 		cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1721 		cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1722 		cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1723 		cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1724 		cb->ccb_tcmax = 15;
1725 		break;
1726 
1727 	case SCSI_LOW_LUN_MODEQ:
1728 		cb->ccb_scp.scp_cmd = sms_cmd;
1729 		cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1730 		cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1731 		cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1732 		cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1733 		cb->ccb_tcmax = 15;
1734 		return SCSI_LOW_START_QTAG;
1735 
1736 	default:
1737 		panic("%s: no setup phase", device_get_nameunit(slp->sl_dev));
1738 	}
1739 
1740 	return SCSI_LOW_START_NO_QTAG;
1741 }
1742 
1743 static int
scsi_low_resume(slp)1744 scsi_low_resume(slp)
1745 	struct scsi_low_softc *slp;
1746 {
1747 
1748 	if (slp->sl_flags & HW_RESUME)
1749 		return EJUSTRETURN;
1750 	slp->sl_flags &= ~HW_POWDOWN;
1751 	if (slp->sl_funcs->scsi_low_power != NULL)
1752 	{
1753 		slp->sl_flags |= HW_RESUME;
1754 		slp->sl_rstep = 0;
1755 		(*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1756 		(*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1757 					(slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
1758 				         SCSI_LOW_TIMEOUT_START);
1759 		return EJUSTRETURN;
1760 	}
1761 	return 0;
1762 }
1763 
1764 static void
scsi_low_start(slp)1765 scsi_low_start(slp)
1766 	struct scsi_low_softc *slp;
1767 {
1768 	struct targ_info *ti;
1769 	struct lun_info *li;
1770 	struct slccb *cb;
1771 	int rv;
1772 
1773 	/* check hardware exists or under initializations ? */
1774 	if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1775 		return;
1776 
1777 	/* check hardware power up ? */
1778 	if ((slp->sl_flags & HW_POWERCTRL) != 0)
1779 	{
1780 		slp->sl_active ++;
1781 		if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1782 		{
1783 			if (scsi_low_resume(slp) == EJUSTRETURN)
1784 				return;
1785 		}
1786 	}
1787 
1788 	/* setup nexus */
1789 #ifdef	SCSI_LOW_DIAGNOSTIC
1790 	if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1791 	{
1792 		scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
1793 		panic("%s: inconsistent", device_get_nameunit(slp->sl_dev));
1794 	}
1795 #endif	/* SCSI_LOW_DIAGNOSTIC */
1796 
1797 	for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
1798 	     cb = TAILQ_NEXT(cb, ccb_chain))
1799 	{
1800 		li = cb->li;
1801 
1802 		if (li->li_disc == 0)
1803 		{
1804 			goto scsi_low_cmd_start;
1805 		}
1806 		else if (li->li_nqio > 0)
1807 		{
1808 			if (li->li_nqio < li->li_maxnqio ||
1809 		            (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1810 				goto scsi_low_cmd_start;
1811 		}
1812 	}
1813 	return;
1814 
1815 scsi_low_cmd_start:
1816 	cb->ccb_flags &= ~CCB_STARTQ;
1817 	TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1818 	ti = cb->ti;
1819 
1820 	/* clear all error flag bits (for restart) */
1821 	cb->ccb_error = 0;
1822 	cb->ccb_datalen = -1;
1823 	cb->ccb_scp.scp_status = ST_UNKNOWN;
1824 
1825 	/* setup nexus pointer */
1826 	slp->sl_Qnexus = cb;
1827 	slp->sl_Lnexus = li;
1828 	slp->sl_Tnexus = ti;
1829 
1830 	/* initialize msgsys */
1831 	scsi_low_init_msgsys(slp, ti);
1832 
1833 	/* exec cmd */
1834 	if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1835 	{
1836 		/* CA state or forced abort */
1837 		rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1838 	}
1839 	else if (li->li_state >= SCSI_LOW_LUN_OK)
1840 	{
1841 		cb->ccb_flags &= ~CCB_INTERNAL;
1842 		rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
1843 		if (cb->ccb_msgoutflag != 0)
1844 		{
1845 			scsi_low_ccb_message_exec(slp, cb);
1846 		}
1847 	}
1848 	else
1849 	{
1850 		cb->ccb_flags |= CCB_INTERNAL;
1851 		rv = scsi_low_setup_start(slp, ti, li, cb);
1852 	}
1853 
1854 	/* allocate qtag */
1855 #define	SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1856 
1857 	if (rv == SCSI_LOW_START_QTAG &&
1858 	    (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1859 	    li->li_maxnqio > 0)
1860 	{
1861 		u_int qmsg;
1862 
1863 		scsi_low_activate_qtag(cb);
1864 		if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1865 		     SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1866 			qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1867 		else if ((cb->ccb_flags & CCB_URGENT) != 0)
1868 			qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1869 		else
1870 			qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1871 		scsi_low_assert_msg(slp, ti, qmsg, 0);
1872 	}
1873 
1874 	/* timeout */
1875 	if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1876 		cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1877 	cb->ccb_tc = cb->ccb_tcmax;
1878 
1879 	/* setup saved scsi data pointer */
1880 	cb->ccb_sscp = cb->ccb_scp;
1881 
1882 	/* setup current scsi pointer */
1883 	slp->sl_scp = cb->ccb_sscp;
1884 	slp->sl_error = cb->ccb_error;
1885 
1886 	/* assert always an identify msg */
1887 	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1888 
1889 	/* debug section */
1890 #ifdef	SCSI_LOW_DIAGNOSTIC
1891 	scsi_low_msg_log_init(&ti->ti_log_msgin);
1892 	scsi_low_msg_log_init(&ti->ti_log_msgout);
1893 #endif	/* SCSI_LOW_DIAGNOSTIC */
1894 
1895 	/* selection start */
1896 	slp->sl_selid = cb;
1897 	rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1898 	if (rv == SCSI_LOW_START_OK)
1899 	{
1900 #ifdef	SCSI_LOW_STATICS
1901 		scsi_low_statics.nexus_win ++;
1902 #endif	/* SCSI_LOW_STATICS */
1903 		return;
1904 	}
1905 
1906 	scsi_low_arbit_fail(slp, cb);
1907 #ifdef	SCSI_LOW_STATICS
1908 	scsi_low_statics.nexus_fail ++;
1909 #endif	/* SCSI_LOW_STATICS */
1910 }
1911 
1912 void
scsi_low_arbit_fail(slp,cb)1913 scsi_low_arbit_fail(slp, cb)
1914 	struct scsi_low_softc *slp;
1915 	struct slccb *cb;
1916 {
1917 	struct targ_info *ti = cb->ti;
1918 
1919 	scsi_low_deactivate_qtag(cb);
1920 	scsi_low_ccb_message_retry(cb);
1921 	cb->ccb_flags |= CCB_STARTQ;
1922 	TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1923 
1924 	scsi_low_bus_release(slp, ti);
1925 
1926 	cb->ccb_selrcnt ++;
1927 	if (slp->sl_disc == 0)
1928 	{
1929 #ifdef	SCSI_LOW_DIAGNOSTIC
1930 		device_printf(slp->sl_dev, "try selection again\n");
1931 #endif	/* SCSI_LOW_DIAGNOSTIC */
1932 		slp->sl_retry_sel = 1;
1933 	}
1934 }
1935 
1936 static void
scsi_low_bus_release(slp,ti)1937 scsi_low_bus_release(slp, ti)
1938 	struct scsi_low_softc *slp;
1939 	struct targ_info *ti;
1940 {
1941 
1942 	if (ti->ti_disc > 0)
1943 	{
1944 		SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
1945 	}
1946 	else
1947 	{
1948 		SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1949 	}
1950 
1951 	/* clear all nexus pointer */
1952 	slp->sl_Qnexus = NULL;
1953 	slp->sl_Lnexus = NULL;
1954 	slp->sl_Tnexus = NULL;
1955 
1956 	/* clear selection assert */
1957 	slp->sl_selid = NULL;
1958 
1959 	/* clear nexus data */
1960 	slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
1961 
1962 	/* clear phase change counter */
1963 	slp->sl_ph_count = 0;
1964 }
1965 
1966 static int
scsi_low_setup_done(slp,cb)1967 scsi_low_setup_done(slp, cb)
1968 	struct scsi_low_softc *slp;
1969 	struct slccb *cb;
1970 {
1971 	struct targ_info *ti;
1972 	struct lun_info *li;
1973 
1974 	ti = cb->ti;
1975 	li = cb->li;
1976 
1977 	if (cb->ccb_rcnt >= slp->sl_max_retry)
1978 	{
1979 		cb->ccb_error |= ABORTIO;
1980 		return SCSI_LOW_DONE_COMPLETE;
1981 	}
1982 
1983 	/* XXX: special huck for selection timeout */
1984 	if (li->li_state == SCSI_LOW_LUN_SLEEP &&
1985 	    (cb->ccb_error & SELTIMEOUTIO) != 0)
1986 	{
1987 		cb->ccb_error |= ABORTIO;
1988 		return SCSI_LOW_DONE_COMPLETE;
1989 	}
1990 
1991 	switch(li->li_state)
1992 	{
1993 	case SCSI_LOW_LUN_INQ:
1994 		if (cb->ccb_error != 0)
1995 		{
1996 			li->li_diskflags &=
1997 				~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
1998 			if (li->li_lun > 0)
1999 				goto resume;
2000 			ti->ti_diskflags &=
2001 				~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2002 		}
2003 		else if ((li->li_inq.sd_version & 7) >= 2 ||
2004 		         (li->li_inq.sd_len >= 4))
2005 		{
2006 			if ((li->li_inq.sd_support & 0x2) == 0)
2007 				li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2008 			if ((li->li_inq.sd_support & 0x8) == 0)
2009 				li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2010 			if (li->li_lun > 0)
2011 				goto resume;
2012 			if ((li->li_inq.sd_support & 0x10) == 0)
2013 				ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2014 			if ((li->li_inq.sd_support & 0x20) == 0)
2015 				ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2016 			if ((li->li_inq.sd_support & 0x40) == 0)
2017 				ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2018 		}
2019 		else
2020 		{
2021 			li->li_diskflags &=
2022 				~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2023 			if (li->li_lun > 0)
2024 				goto resume;
2025 			ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2026 		}
2027 		ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2028 resume:
2029 		scsi_low_calcf_target(ti);
2030 		scsi_low_calcf_lun(li);
2031 		break;
2032 
2033 	case SCSI_LOW_LUN_MODEQ:
2034 		if (cb->ccb_error != 0)
2035 		{
2036 			if (cb->ccb_error & SENSEIO)
2037 			{
2038 #ifdef	SCSI_LOW_DEBUG
2039 				if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2040 				{
2041 					int error_code, sense_key, asc, ascq;
2042 
2043 					scsi_extract_sense(&cb->ccb_sense,
2044 							   &error_code,
2045 							   &sense_key,
2046 							   &asc,
2047 							   &ascq);
2048 					printf("SENSE: [%x][%x][%x][%x]\n",
2049 					       error_code, sense_key, asc,
2050 					       ascq);
2051 				}
2052 #endif	/* SCSI_LOW_DEBUG */
2053 			}
2054 			else
2055 			{
2056 				li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2057 			}
2058 		}
2059 		else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2060 		{
2061 			if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2062 				li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2063 			else
2064 				li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2065 			if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2066 				li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2067 		}
2068 		li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2069 		scsi_low_calcf_lun(li);
2070 		break;
2071 
2072 	default:
2073 		break;
2074 	}
2075 
2076 	li->li_state ++;
2077 	if (li->li_state == SCSI_LOW_LUN_OK)
2078 	{
2079 		scsi_low_calcf_target(ti);
2080 		scsi_low_calcf_lun(li);
2081 		if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2082 	            (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2083 		{
2084 			scsi_low_calcf_show(li);
2085 		}
2086 	}
2087 
2088 	cb->ccb_rcnt --;
2089 	return SCSI_LOW_DONE_RETRY;
2090 }
2091 
2092 static int
scsi_low_done(slp,cb)2093 scsi_low_done(slp, cb)
2094 	struct scsi_low_softc *slp;
2095 	struct slccb *cb;
2096 {
2097 	int rv;
2098 
2099 	if (cb->ccb_error == 0)
2100 	{
2101 		if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2102 		{
2103 #ifdef	SCSI_LOW_QCLEAR_AFTER_CA
2104 			/* XXX:
2105 			 * SCSI-2 draft suggests
2106 			 * page 0x0a QErr bit determins if
2107 			 * the target aborts or continues
2108 			 * the queueing io's after CA state resolved.
2109 			 * However many targets seem not to support
2110 			 * the page 0x0a. Thus we should manually clear the
2111 			 * queuing io's after CA state.
2112 			 */
2113 			if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2114 			{
2115 				cb->ccb_rcnt --;
2116 				cb->ccb_flags |= CCB_CLEARQ;
2117 				goto retry;
2118 			}
2119 #endif	/* SCSI_LOW_QCLEAR_AFTER_CA */
2120 
2121 			if ((cb->ccb_flags & CCB_SENSE) != 0)
2122 				cb->ccb_error |= (SENSEIO | ABORTIO);
2123 			cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2124 		}
2125 		else switch (cb->ccb_sscp.scp_status)
2126 		{
2127 		case ST_GOOD:
2128 		case ST_MET:
2129 		case ST_INTERGOOD:
2130 		case ST_INTERMET:
2131 			if (cb->ccb_datalen == 0 ||
2132 			    cb->ccb_scp.scp_datalen == 0)
2133 				break;
2134 
2135 			if (cb->ccb_scp.scp_cmdlen > 0 &&
2136 			    (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2137 			     SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2138 				break;
2139 
2140 			cb->ccb_error |= PDMAERR;
2141 			break;
2142 
2143 		case ST_BUSY:
2144 		case ST_QUEFULL:
2145 			cb->ccb_error |= (BUSYERR | STATERR);
2146 			break;
2147 
2148 		case ST_CONFLICT:
2149 			cb->ccb_error |= (STATERR | ABORTIO);
2150 			break;
2151 
2152 		case ST_CHKCOND:
2153 		case ST_CMDTERM:
2154 			if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2155 			{
2156 				cb->ccb_rcnt --;
2157 				cb->ccb_flags |= CCB_SENSE;
2158 				goto retry;
2159 			}
2160 			cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2161 			break;
2162 
2163 		case ST_UNKNOWN:
2164 		default:
2165 			cb->ccb_error |= FATALIO;
2166 			break;
2167 		}
2168 	}
2169 	else
2170 	{
2171 		if (cb->ccb_flags & CCB_SENSE)
2172 		{
2173 			cb->ccb_error |= (SENSEERR | ABORTIO);
2174 		}
2175 		cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2176 	}
2177 
2178 	/* internal ccb */
2179 	if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2180 	{
2181 		if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2182 			goto retry;
2183 	}
2184 
2185 	/* check a ccb msgout flag */
2186 	if (cb->ccb_omsgoutflag != 0)
2187 	{
2188 #define	SCSI_LOW_MSG_ABORT_OK	(SCSI_LOW_MSG_ABORT | \
2189 				 SCSI_LOW_MSG_ABORT_QTAG | \
2190 				 SCSI_LOW_MSG_CLEAR_QTAG | \
2191 				 SCSI_LOW_MSG_TERMIO)
2192 
2193 		if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2194 		{
2195 			cb->ccb_error |= ABORTIO;
2196 		}
2197 	}
2198 
2199 	/* call OS depend done */
2200 	if (cb->osdep != NULL)
2201 	{
2202 		rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2203 		if (rv == EJUSTRETURN)
2204 			goto retry;
2205 	}
2206 	else if (cb->ccb_error != 0)
2207 	{
2208 	        if (cb->ccb_rcnt >= slp->sl_max_retry)
2209 			cb->ccb_error |= ABORTIO;
2210 
2211 		if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2212 		    (cb->ccb_error & ABORTIO) == 0)
2213 			goto retry;
2214 	}
2215 
2216 	/* free our target */
2217 #ifdef	SCSI_LOW_DEBUG
2218 	if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2219 	{
2220 		printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2221 		scsi_low_print(slp, NULL);
2222 	}
2223 #endif	/* SCSI_LOW_DEBUG */
2224 
2225 	scsi_low_deactivate_qtag(cb);
2226 	scsi_low_dealloc_qtag(cb);
2227 	scsi_low_free_ccb(cb);
2228 	slp->sl_nio --;
2229 	return SCSI_LOW_DONE_COMPLETE;
2230 
2231 retry:
2232 #ifdef	SCSI_LOW_DEBUG
2233 	if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2234 	{
2235 		printf("** SCSI_LOW_DONE_RETRY ===============\n");
2236 		scsi_low_print(slp, NULL);
2237 	}
2238 #endif	/* SCSI_LOW_DEBUG */
2239 
2240 	cb->ccb_rcnt ++;
2241 	scsi_low_deactivate_qtag(cb);
2242 	scsi_low_ccb_message_retry(cb);
2243 	return SCSI_LOW_DONE_RETRY;
2244 }
2245 
2246 /**************************************************************
2247  * Reset
2248  **************************************************************/
2249 static void
scsi_low_reset_nexus_target(slp,ti,fdone)2250 scsi_low_reset_nexus_target(slp, ti, fdone)
2251 	struct scsi_low_softc *slp;
2252 	struct targ_info *ti;
2253 	int fdone;
2254 {
2255 	struct lun_info *li;
2256 
2257 	for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2258 	     li = LIST_NEXT(li, lun_chain))
2259 	{
2260 		scsi_low_reset_nexus_lun(slp, li, fdone);
2261 		li->li_state = SCSI_LOW_LUN_SLEEP;
2262 		li->li_maxnqio = 0;
2263 	}
2264 
2265 	ti->ti_disc = 0;
2266 	ti->ti_setup_msg = 0;
2267 	ti->ti_setup_msg_done = 0;
2268 
2269 	ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2270 	ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2271 
2272 	ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2273 	ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2274 
2275 	if (slp->sl_funcs->scsi_low_targ_init != NULL)
2276 	{
2277 		((*slp->sl_funcs->scsi_low_targ_init)
2278 			(slp, ti, SCSI_LOW_INFO_REVOKE));
2279 	}
2280 	scsi_low_calcf_target(ti);
2281 
2282 	for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2283 	     li = LIST_NEXT(li, lun_chain))
2284 	{
2285 		li->li_flags = 0;
2286 
2287 		li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2288 		li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2289 
2290 		if (slp->sl_funcs->scsi_low_lun_init != NULL)
2291 		{
2292 			((*slp->sl_funcs->scsi_low_lun_init)
2293 				(slp, ti, li, SCSI_LOW_INFO_REVOKE));
2294 		}
2295 		scsi_low_calcf_lun(li);
2296 	}
2297 }
2298 
2299 static void
scsi_low_reset_nexus(slp,fdone)2300 scsi_low_reset_nexus(slp, fdone)
2301 	struct scsi_low_softc *slp;
2302 	int fdone;
2303 {
2304 	struct targ_info *ti;
2305 	struct slccb *cb, *topcb;
2306 
2307 	if ((cb = slp->sl_Qnexus) != NULL)
2308 	{
2309 		topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2310 	}
2311 	else
2312 	{
2313 		topcb = NULL;
2314 	}
2315 
2316 	for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2317 	     ti = TAILQ_NEXT(ti, ti_chain))
2318 	{
2319 		scsi_low_reset_nexus_target(slp, ti, fdone);
2320 		scsi_low_bus_release(slp, ti);
2321 		scsi_low_init_msgsys(slp, ti);
2322 	}
2323 
2324 	if (topcb != NULL)
2325 	{
2326 		topcb->ccb_flags |= CCB_STARTQ;
2327 		TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2328 	}
2329 
2330 	slp->sl_disc = 0;
2331 	slp->sl_retry_sel = 0;
2332 	slp->sl_flags &= ~HW_PDMASTART;
2333 }
2334 
2335 /* misc */
2336 static int tw_pos;
2337 static char tw_chars[] = "|/-\\";
2338 #define	TWIDDLEWAIT		10000
2339 
2340 static void
scsi_low_twiddle_wait(void)2341 scsi_low_twiddle_wait(void)
2342 {
2343 
2344 	cnputc('\b');
2345 	cnputc(tw_chars[tw_pos++]);
2346 	tw_pos %= (sizeof(tw_chars) - 1);
2347 	DELAY(TWIDDLEWAIT);
2348 }
2349 
2350 void
scsi_low_bus_reset(slp)2351 scsi_low_bus_reset(slp)
2352 	struct scsi_low_softc *slp;
2353 {
2354 	int i;
2355 
2356 	(*slp->sl_funcs->scsi_low_bus_reset) (slp);
2357 
2358 	device_printf(slp->sl_dev, "try to reset scsi bus  ");
2359 	for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2360 		scsi_low_twiddle_wait();
2361 	cnputc('\b');
2362 	printf("\n");
2363 }
2364 
2365 int
scsi_low_restart(slp,flags,s)2366 scsi_low_restart(slp, flags, s)
2367 	struct scsi_low_softc *slp;
2368 	int flags;
2369 	u_char *s;
2370 {
2371 	int error;
2372 
2373 	if (s != NULL)
2374 		device_printf(slp->sl_dev, "scsi bus restart. reason: %s\n", s);
2375 
2376 	if ((error = scsi_low_init(slp, flags)) != 0)
2377 		return error;
2378 
2379 	scsi_low_start(slp);
2380 	return 0;
2381 }
2382 
2383 /**************************************************************
2384  * disconnect and reselect
2385  **************************************************************/
2386 #define	MSGCMD_LUN(msg)	(msg & 0x07)
2387 
2388 static struct slccb *
scsi_low_establish_ccb(ti,li,tag)2389 scsi_low_establish_ccb(ti, li, tag)
2390 	struct targ_info *ti;
2391 	struct lun_info *li;
2392 	scsi_low_tag_t tag;
2393 {
2394 	struct scsi_low_softc *slp = ti->ti_sc;
2395 	struct slccb *cb;
2396 
2397 	if (li == NULL)
2398 		return NULL;
2399 
2400 	cb = TAILQ_FIRST(&li->li_discq);
2401 	for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
2402 		if (cb->ccb_tag == tag)
2403 			goto found;
2404 	return cb;
2405 
2406 	/*
2407 	 * establish our ccb nexus
2408 	 */
2409 found:
2410 #ifdef	SCSI_LOW_DEBUG
2411 	if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2412 	{
2413 		device_printf(slp->sl_dev, "nexus(0x%lx) abort check start\n",
2414 		    (u_long) cb);
2415 		cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2416 		scsi_low_revoke_ccb(slp, cb, 1);
2417 		return NULL;
2418 	}
2419 
2420 	if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2421 	{
2422 		if (cb->ccb_omsgoutflag == 0)
2423 			scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2424 	}
2425 #endif	/* SCSI_LOW_DEBUG */
2426 
2427 	TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2428 	cb->ccb_flags &= ~CCB_DISCQ;
2429 	slp->sl_Qnexus = cb;
2430 
2431 	slp->sl_scp = cb->ccb_sscp;
2432 	slp->sl_error |= cb->ccb_error;
2433 
2434 	slp->sl_disc --;
2435 	ti->ti_disc --;
2436 	li->li_disc --;
2437 
2438 	/* inform "ccb nexus established" to the host driver */
2439 	(*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2440 
2441 	/* check msg */
2442 	if (cb->ccb_msgoutflag != 0)
2443 	{
2444 		scsi_low_ccb_message_exec(slp, cb);
2445 	}
2446 
2447 	return cb;
2448 }
2449 
2450 struct targ_info *
scsi_low_reselected(slp,targ)2451 scsi_low_reselected(slp, targ)
2452 	struct scsi_low_softc *slp;
2453 	u_int targ;
2454 {
2455 	struct targ_info *ti;
2456 	struct slccb *cb;
2457 	u_char *s;
2458 
2459 	/*
2460 	 * Check select vs reselected collision.
2461 	 */
2462 
2463 	if ((cb = slp->sl_selid) != NULL)
2464 	{
2465 		scsi_low_arbit_fail(slp, cb);
2466 #ifdef	SCSI_LOW_STATICS
2467 		scsi_low_statics.nexus_conflict ++;
2468 #endif	/* SCSI_LOW_STATICS */
2469 	}
2470 
2471 	/*
2472 	 * Check if no current active nexus.
2473 	 */
2474 	if (slp->sl_Tnexus != NULL)
2475 	{
2476 		s = "host busy";
2477 		goto world_restart;
2478 	}
2479 
2480 	/*
2481 	 * Check a valid target id asserted ?
2482 	 */
2483 	if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2484 	{
2485 		s = "scsi id illegal";
2486 		goto world_restart;
2487 	}
2488 
2489 	/*
2490 	 * Check the target scsi status.
2491 	 */
2492 	ti = slp->sl_ti[targ];
2493 	if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2494 	{
2495 		s = "phase mismatch";
2496 		goto world_restart;
2497 	}
2498 
2499 	/*
2500 	 * Setup init msgsys
2501 	 */
2502 	slp->sl_error = 0;
2503 	scsi_low_init_msgsys(slp, ti);
2504 
2505 	/*
2506 	 * Establish our target nexus
2507 	 */
2508 	SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2509 	slp->sl_Tnexus = ti;
2510 #ifdef	SCSI_LOW_STATICS
2511 	scsi_low_statics.nexus_reselected ++;
2512 #endif	/* SCSI_LOW_STATICS */
2513 	return ti;
2514 
2515 world_restart:
2516 	device_printf(slp->sl_dev, "reselect(%x:unknown) %s\n", targ, s);
2517 	scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
2518 		         "reselect: scsi world confused");
2519 	return NULL;
2520 }
2521 
2522 /**************************************************************
2523  * cmd out pointer setup
2524  **************************************************************/
2525 int
scsi_low_cmd(slp,ti)2526 scsi_low_cmd(slp, ti)
2527 	struct scsi_low_softc *slp;
2528 	struct targ_info *ti;
2529 {
2530 	struct slccb *cb = slp->sl_Qnexus;
2531 
2532 	slp->sl_ph_count ++;
2533 	if (cb == NULL)
2534 	{
2535 		/*
2536 		 * no ccb, abort!
2537 		 */
2538 		slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2539 		slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2540 		slp->sl_scp.scp_datalen = 0;
2541 		slp->sl_scp.scp_direction = SCSI_LOW_READ;
2542 		slp->sl_error |= FATALIO;
2543 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2544 		SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2545 		return EINVAL;
2546 	}
2547 	else
2548 	{
2549 #ifdef	SCSI_LOW_DEBUG
2550 		if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2551 		{
2552 			scsi_low_test_cmdlnk(slp, cb);
2553 		}
2554 #endif	/* SCSI_LOW_DEBUG */
2555 	}
2556 	return 0;
2557 }
2558 
2559 /**************************************************************
2560  * data out pointer setup
2561  **************************************************************/
2562 int
scsi_low_data(slp,ti,bp,direction)2563 scsi_low_data(slp, ti, bp, direction)
2564 	struct scsi_low_softc *slp;
2565 	struct targ_info *ti;
2566 	struct buf **bp;
2567 	int direction;
2568 {
2569 	struct slccb *cb = slp->sl_Qnexus;
2570 
2571 	if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2572 	{
2573 		*bp = cb->bp;
2574 		return 0;
2575 	}
2576 
2577 	slp->sl_error |= (FATALIO | PDMAERR);
2578 	slp->sl_scp.scp_datalen = 0;
2579 	slp->sl_scp.scp_direction = direction;
2580 	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2581 	if (ti->ti_ophase != ti->ti_phase)
2582 	{
2583 		char *s;
2584 
2585 		if (cb == NULL)
2586 			s = "DATA PHASE: ccb nexus not found";
2587 		else
2588 			s = "DATA PHASE: xfer direction mismatch";
2589 		SCSI_LOW_INFO(slp, ti, s);
2590 	}
2591 
2592 	*bp = NULL;
2593 	return EINVAL;
2594 }
2595 
2596 /**************************************************************
2597  * MSG_SYS
2598  **************************************************************/
2599 #define	MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2600 #define	MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2601 #define	MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2602 #define	MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2603 #define	MSGIN_DATA_LAST	0x30
2604 
2605 static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int);
2606 static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int);
2607 static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int);
2608 static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int);
2609 
2610 static int scsi_low_msgfunc_synch(struct scsi_low_softc *);
2611 static int scsi_low_msgfunc_wide(struct scsi_low_softc *);
2612 static int scsi_low_msgfunc_identify(struct scsi_low_softc *);
2613 static int scsi_low_msgfunc_abort(struct scsi_low_softc *);
2614 static int scsi_low_msgfunc_qabort(struct scsi_low_softc *);
2615 static int scsi_low_msgfunc_qtag(struct scsi_low_softc *);
2616 static int scsi_low_msgfunc_reset(struct scsi_low_softc *);
2617 
2618 struct scsi_low_msgout_data {
2619 	u_int	md_flags;
2620 	u_int8_t md_msg;
2621 	int (*md_msgfunc)(struct scsi_low_softc *);
2622 	int (*md_errfunc)(struct scsi_low_softc *, u_int);
2623 #define	MSG_RELEASE_ATN	0x0001
2624 	u_int md_condition;
2625 };
2626 
2627 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2628 /* 0 */	{SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2629 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2630 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2631 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2632 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2633 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2634 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2635 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG,  MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2636 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2637 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG,  MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2638 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL,  MSG_RELEASE_ATN},
2639 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2640 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2641 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2642 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2643 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2644 };
2645 
2646 static int scsi_low_msginfunc_ext(struct scsi_low_softc *);
2647 static int scsi_low_synch(struct scsi_low_softc *);
2648 static int scsi_low_wide(struct scsi_low_softc *);
2649 static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *);
2650 static int scsi_low_msginfunc_rejop(struct scsi_low_softc *);
2651 static int scsi_low_msginfunc_rp(struct scsi_low_softc *);
2652 static int scsi_low_msginfunc_sdp(struct scsi_low_softc *);
2653 static int scsi_low_msginfunc_disc(struct scsi_low_softc *);
2654 static int scsi_low_msginfunc_cc(struct scsi_low_softc *);
2655 static int scsi_low_msginfunc_lcc(struct scsi_low_softc *);
2656 static int scsi_low_msginfunc_parity(struct scsi_low_softc *);
2657 static int scsi_low_msginfunc_noop(struct scsi_low_softc *);
2658 static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *);
2659 static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *);
2660 
2661 struct scsi_low_msgin_data {
2662 	u_int md_len;
2663 	int (*md_msgfunc)(struct scsi_low_softc *);
2664 };
2665 
2666 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2667 /* 0 */	{1,	scsi_low_msginfunc_cc},
2668 /* 1 */ {2,	scsi_low_msginfunc_ext},
2669 /* 2 */ {1,	scsi_low_msginfunc_sdp},
2670 /* 3 */ {1,	scsi_low_msginfunc_rp},
2671 /* 4 */ {1,	scsi_low_msginfunc_disc},
2672 /* 5 */ {1,	scsi_low_msginfunc_rejop},
2673 /* 6 */ {1,	scsi_low_msginfunc_rejop},
2674 /* 7 */ {1,	scsi_low_msginfunc_msg_reject},
2675 /* 8 */ {1,	scsi_low_msginfunc_noop},
2676 /* 9 */ {1,	scsi_low_msginfunc_parity},
2677 /* a */ {1,	scsi_low_msginfunc_lcc},
2678 /* b */ {1,	scsi_low_msginfunc_lcc},
2679 /* c */ {1,	scsi_low_msginfunc_rejop},
2680 /* d */ {2,	scsi_low_msginfunc_rejop},
2681 /* e */ {1,	scsi_low_msginfunc_rejop},
2682 /* f */ {1,	scsi_low_msginfunc_rejop},
2683 /* 0x10 */ {1,	scsi_low_msginfunc_rejop},
2684 /* 0x11 */ {1,	scsi_low_msginfunc_rejop},
2685 /* 0x12 */ {1,	scsi_low_msginfunc_rejop},
2686 /* 0x13 */ {1,	scsi_low_msginfunc_rejop},
2687 /* 0x14 */ {1,	scsi_low_msginfunc_rejop},
2688 /* 0x15 */ {1,	scsi_low_msginfunc_rejop},
2689 /* 0x16 */ {1,	scsi_low_msginfunc_rejop},
2690 /* 0x17 */ {1,	scsi_low_msginfunc_rejop},
2691 /* 0x18 */ {1,	scsi_low_msginfunc_rejop},
2692 /* 0x19 */ {1,	scsi_low_msginfunc_rejop},
2693 /* 0x1a */ {1,	scsi_low_msginfunc_rejop},
2694 /* 0x1b */ {1,	scsi_low_msginfunc_rejop},
2695 /* 0x1c */ {1,	scsi_low_msginfunc_rejop},
2696 /* 0x1d */ {1,	scsi_low_msginfunc_rejop},
2697 /* 0x1e */ {1,	scsi_low_msginfunc_rejop},
2698 /* 0x1f */ {1,	scsi_low_msginfunc_rejop},
2699 /* 0x20 */ {2,	scsi_low_msginfunc_simple_qtag},
2700 /* 0x21 */ {2,	scsi_low_msginfunc_rejop},
2701 /* 0x22 */ {2,	scsi_low_msginfunc_rejop},
2702 /* 0x23 */ {2,	scsi_low_msginfunc_i_wide_residue},
2703 /* 0x24 */ {2,	scsi_low_msginfunc_rejop},
2704 /* 0x25 */ {2,	scsi_low_msginfunc_rejop},
2705 /* 0x26 */ {2,	scsi_low_msginfunc_rejop},
2706 /* 0x27 */ {2,	scsi_low_msginfunc_rejop},
2707 /* 0x28 */ {2,	scsi_low_msginfunc_rejop},
2708 /* 0x29 */ {2,	scsi_low_msginfunc_rejop},
2709 /* 0x2a */ {2,	scsi_low_msginfunc_rejop},
2710 /* 0x2b */ {2,	scsi_low_msginfunc_rejop},
2711 /* 0x2c */ {2,	scsi_low_msginfunc_rejop},
2712 /* 0x2d */ {2,	scsi_low_msginfunc_rejop},
2713 /* 0x2e */ {2,	scsi_low_msginfunc_rejop},
2714 /* 0x2f */ {2,	scsi_low_msginfunc_rejop},
2715 /* 0x30 */ {1,	scsi_low_msginfunc_rejop}	/* default rej op */
2716 };
2717 
2718 /**************************************************************
2719  * msgout
2720  **************************************************************/
2721 static int
scsi_low_msgfunc_synch(slp)2722 scsi_low_msgfunc_synch(slp)
2723 	struct scsi_low_softc *slp;
2724 {
2725 	struct targ_info *ti = slp->sl_Tnexus;
2726 	int ptr = ti->ti_msgoutlen;
2727 
2728 	ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2729 	ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2730 	ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2731 	ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2732 	return MSG_EXTEND_SYNCHLEN + 2;
2733 }
2734 
2735 static int
scsi_low_msgfunc_wide(slp)2736 scsi_low_msgfunc_wide(slp)
2737 	struct scsi_low_softc *slp;
2738 {
2739 	struct targ_info *ti = slp->sl_Tnexus;
2740 	int ptr = ti->ti_msgoutlen;
2741 
2742 	ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2743 	ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2744 	ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2745 	return MSG_EXTEND_WIDELEN + 2;
2746 }
2747 
2748 static int
scsi_low_msgfunc_identify(slp)2749 scsi_low_msgfunc_identify(slp)
2750 	struct scsi_low_softc *slp;
2751 {
2752 	struct targ_info *ti = slp->sl_Tnexus;
2753 	struct lun_info *li = slp->sl_Lnexus;
2754 	struct slccb *cb = slp->sl_Qnexus;
2755 	int ptr = ti->ti_msgoutlen;
2756 	u_int8_t msg;
2757 
2758 	msg = MSG_IDENTIFY;
2759 	if (cb == NULL)
2760 	{
2761 		slp->sl_error |= FATALIO;
2762 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2763 		SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2764 	}
2765 	else
2766 	{
2767 		if (scsi_low_is_disconnect_ok(cb) != 0)
2768 			msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2769 		else
2770 			msg |= li->li_lun;
2771 
2772 		if (ti->ti_phase == PH_MSGOUT)
2773 		{
2774 			(*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2775 			if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2776 			{
2777 				(*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2778 			}
2779 		}
2780 	}
2781 	ti->ti_msgoutstr[ptr + 0] = msg;
2782 	return 1;
2783 }
2784 
2785 static int
scsi_low_msgfunc_abort(slp)2786 scsi_low_msgfunc_abort(slp)
2787 	struct scsi_low_softc *slp;
2788 {
2789 
2790 	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2791 	return 1;
2792 }
2793 
2794 static int
scsi_low_msgfunc_qabort(slp)2795 scsi_low_msgfunc_qabort(slp)
2796 	struct scsi_low_softc *slp;
2797 {
2798 
2799 	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2800 	return 1;
2801 }
2802 
2803 static int
scsi_low_msgfunc_reset(slp)2804 scsi_low_msgfunc_reset(slp)
2805 	struct scsi_low_softc *slp;
2806 {
2807 
2808 	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2809 	return 1;
2810 }
2811 
2812 static int
scsi_low_msgfunc_qtag(slp)2813 scsi_low_msgfunc_qtag(slp)
2814 	struct scsi_low_softc *slp;
2815 {
2816 	struct targ_info *ti = slp->sl_Tnexus;
2817 	struct slccb *cb = slp->sl_Qnexus;
2818 	int ptr = ti->ti_msgoutlen;
2819 
2820 	if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2821 	{
2822 		ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2823 		return 1;
2824 	}
2825 	else
2826 	{
2827 		ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2828 		if (ti->ti_phase == PH_MSGOUT)
2829 		{
2830 			(*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2831 		}
2832 	}
2833 	return 2;
2834 }
2835 
2836 /*
2837  * The following functions are called when targets give unexpected
2838  * responces in msgin (after msgout).
2839  */
2840 static int
scsi_low_errfunc_identify(slp,msgflags)2841 scsi_low_errfunc_identify(slp, msgflags)
2842 	struct scsi_low_softc *slp;
2843 	u_int msgflags;
2844 {
2845 
2846 	if (slp->sl_Lnexus != NULL)
2847 	{
2848 	        slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2849 		scsi_low_calcf_lun(slp->sl_Lnexus);
2850 	}
2851 	return 0;
2852 }
2853 
2854 static int
scsi_low_errfunc_synch(slp,msgflags)2855 scsi_low_errfunc_synch(slp, msgflags)
2856 	struct scsi_low_softc *slp;
2857 	u_int msgflags;
2858 {
2859 	struct targ_info *ti = slp->sl_Tnexus;
2860 
2861 	MSGIN_PERIOD(ti) = 0;
2862 	MSGIN_OFFSET(ti) = 0;
2863 	scsi_low_synch(slp);
2864 	return 0;
2865 }
2866 
2867 static int
scsi_low_errfunc_wide(slp,msgflags)2868 scsi_low_errfunc_wide(slp, msgflags)
2869 	struct scsi_low_softc *slp;
2870 	u_int msgflags;
2871 {
2872 	struct targ_info *ti = slp->sl_Tnexus;
2873 
2874 	MSGIN_WIDTHP(ti) = 0;
2875 	scsi_low_wide(slp);
2876 	return 0;
2877 }
2878 
2879 static int
scsi_low_errfunc_qtag(slp,msgflags)2880 scsi_low_errfunc_qtag(slp, msgflags)
2881 	struct scsi_low_softc *slp;
2882 	u_int msgflags;
2883 {
2884 
2885 	if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2886 	{
2887 		if (slp->sl_Qnexus != NULL)
2888 		{
2889 			scsi_low_deactivate_qtag(slp->sl_Qnexus);
2890 		}
2891 		if (slp->sl_Lnexus != NULL)
2892 		{
2893 			slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2894 			scsi_low_calcf_lun(slp->sl_Lnexus);
2895 		}
2896 		device_printf(slp->sl_dev, "scsi_low: qtag msg rejected\n");
2897 	}
2898 	return 0;
2899 }
2900 
2901 
2902 int
scsi_low_msgout(slp,ti,fl)2903 scsi_low_msgout(slp, ti, fl)
2904 	struct scsi_low_softc *slp;
2905 	struct targ_info *ti;
2906 	u_int fl;
2907 {
2908 	struct scsi_low_msgout_data *mdp;
2909 	int len = 0;
2910 
2911 #ifdef	SCSI_LOW_DIAGNOSTIC
2912 	if (ti != slp->sl_Tnexus)
2913 	{
2914 		scsi_low_print(slp, NULL);
2915 		panic("scsi_low_msgout: Target nexus inconsistent");
2916 	}
2917 #endif	/* SCSI_LOW_DIAGNOSTIC */
2918 
2919 	slp->sl_ph_count ++;
2920 	if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
2921 	{
2922 		device_printf(slp->sl_dev, "too many phase changes\n");
2923 		slp->sl_error |= FATALIO;
2924 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2925 	}
2926 
2927 	/* STEP I.
2928 	 * Scsi phase changes.
2929 	 * Previously msgs asserted are accepted by our target or
2930 	 * processed by scsi_low_msgin.
2931 	 * Thus clear all saved informations.
2932 	 */
2933 	if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
2934 	{
2935 		ti->ti_omsgflags = 0;
2936 		ti->ti_emsgflags = 0;
2937 	}
2938 	else if (slp->sl_atten == 0)
2939 	{
2940 	/* STEP II.
2941 	 * We did not assert attention, however still our target required
2942 	 * msgs. Resend previous msgs.
2943 	 */
2944 		ti->ti_msgflags |= ti->ti_omsgflags;
2945 		ti->ti_omsgflags = 0;
2946 #ifdef	SCSI_LOW_DIAGNOSTIC
2947 		device_printf(slp->sl_dev, "scsi_low_msgout: retry msgout\n");
2948 #endif	/* SCSI_LOW_DIAGNOSTIC */
2949 	}
2950 
2951 	/* STEP III.
2952 	 * We have no msgs. send MSG_NOOP (OK?)
2953 	 */
2954 	if (scsi_low_is_msgout_continue(ti, 0) == 0)
2955 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
2956 
2957 	/* STEP IV.
2958 	 * Process all msgs
2959 	 */
2960 	ti->ti_msgoutlen = 0;
2961 	slp->sl_clear_atten = 0;
2962 	mdp = &scsi_low_msgout_data[0];
2963 	for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
2964 	{
2965 		if ((ti->ti_msgflags & mdp->md_flags) != 0)
2966 		{
2967 			ti->ti_omsgflags |= mdp->md_flags;
2968 			ti->ti_msgflags &= ~mdp->md_flags;
2969 			ti->ti_emsgflags = mdp->md_flags;
2970 
2971 			ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
2972 			if (mdp->md_msgfunc != NULL)
2973 				len = (*mdp->md_msgfunc) (slp);
2974 			else
2975 				len = 1;
2976 
2977 #ifdef	SCSI_LOW_DIAGNOSTIC
2978 			scsi_low_msg_log_write(&ti->ti_log_msgout,
2979 			       &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
2980 #endif	/* SCSI_LOW_DIAGNOSTIC */
2981 
2982 			ti->ti_msgoutlen += len;
2983 			if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
2984 			{
2985 				slp->sl_clear_atten = 1;
2986 				break;
2987 			}
2988 
2989 			if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
2990 			    ti->ti_msgflags == 0)
2991 				break;
2992 
2993 			if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
2994 				break;
2995 		}
2996 	}
2997 
2998 	if (scsi_low_is_msgout_continue(ti, 0) == 0)
2999 		slp->sl_clear_atten = 1;
3000 
3001 	return ti->ti_msgoutlen;
3002 }
3003 
3004 /**************************************************************
3005  * msgin
3006  **************************************************************/
3007 static int
scsi_low_msginfunc_noop(slp)3008 scsi_low_msginfunc_noop(slp)
3009 	struct scsi_low_softc *slp;
3010 {
3011 
3012 	return 0;
3013 }
3014 
3015 static int
scsi_low_msginfunc_rejop(slp)3016 scsi_low_msginfunc_rejop(slp)
3017 	struct scsi_low_softc *slp;
3018 {
3019 	struct targ_info *ti = slp->sl_Tnexus;
3020 	u_int8_t msg = ti->ti_msgin[0];
3021 
3022 	device_printf(slp->sl_dev, "MSGIN: msg 0x%x rejected\n", (u_int) msg);
3023 	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3024 	return 0;
3025 }
3026 
3027 static int
scsi_low_msginfunc_cc(slp)3028 scsi_low_msginfunc_cc(slp)
3029 	struct scsi_low_softc *slp;
3030 {
3031 	struct lun_info *li;
3032 
3033 	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3034 
3035 	/* validate status */
3036 	if (slp->sl_Qnexus == NULL)
3037 		return ENOENT;
3038 
3039 	slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3040  	li = slp->sl_Lnexus;
3041 	switch (slp->sl_scp.scp_status)
3042 	{
3043 	case ST_GOOD:
3044 		li->li_maxnqio = li->li_maxnexus;
3045 		break;
3046 
3047 	case ST_CHKCOND:
3048 		li->li_maxnqio = 0;
3049 		if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3050 			scsi_low_reset_nexus_lun(slp, li, 0);
3051 		break;
3052 
3053 	case ST_BUSY:
3054 		li->li_maxnqio = 0;
3055 		break;
3056 
3057 	case ST_QUEFULL:
3058 		if (li->li_maxnexus >= li->li_nqio)
3059 			li->li_maxnexus = li->li_nqio - 1;
3060 		li->li_maxnqio = li->li_maxnexus;
3061 		break;
3062 
3063 	case ST_INTERGOOD:
3064 	case ST_INTERMET:
3065 		slp->sl_error |= MSGERR;
3066 		break;
3067 
3068 	default:
3069 		break;
3070 	}
3071 	return 0;
3072 }
3073 
3074 static int
scsi_low_msginfunc_lcc(slp)3075 scsi_low_msginfunc_lcc(slp)
3076 	struct scsi_low_softc *slp;
3077 {
3078 	struct targ_info *ti;
3079 	struct lun_info *li;
3080 	struct slccb *ncb, *cb;
3081 
3082 	ti = slp->sl_Tnexus;
3083  	li = slp->sl_Lnexus;
3084 	if ((cb = slp->sl_Qnexus) == NULL)
3085 		goto bad;
3086 
3087 	cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3088 	switch (slp->sl_scp.scp_status)
3089 	{
3090 	case ST_INTERGOOD:
3091 	case ST_INTERMET:
3092 		li->li_maxnqio = li->li_maxnexus;
3093 		break;
3094 
3095 	default:
3096 		slp->sl_error |= MSGERR;
3097 		break;
3098 	}
3099 
3100 	if ((li->li_flags & SCSI_LOW_LINK) == 0)
3101 		goto bad;
3102 
3103 	cb->ccb_error |= slp->sl_error;
3104 	if (cb->ccb_error != 0)
3105 		goto bad;
3106 
3107 	for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3108 	     ncb = TAILQ_NEXT(ncb, ccb_chain))
3109 	{
3110 		if (ncb->li == li)
3111 			goto cmd_link_start;
3112 	}
3113 
3114 
3115 bad:
3116 	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3117 	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3118 	return EIO;
3119 
3120 cmd_link_start:
3121 	ncb->ccb_flags &= ~CCB_STARTQ;
3122 	TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3123 
3124 	scsi_low_dealloc_qtag(ncb);
3125 	ncb->ccb_tag = cb->ccb_tag;
3126 	ncb->ccb_otag = cb->ccb_otag;
3127 	cb->ccb_tag = SCSI_LOW_UNKTAG;
3128 	cb->ccb_otag = SCSI_LOW_UNKTAG;
3129 	if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3130 		panic("%s: linked ccb retried",
3131 		    device_get_nameunit(slp->sl_dev));
3132 
3133 	slp->sl_Qnexus = ncb;
3134 	slp->sl_ph_count = 0;
3135 
3136 	ncb->ccb_error = 0;
3137 	ncb->ccb_datalen = -1;
3138 	ncb->ccb_scp.scp_status = ST_UNKNOWN;
3139 	ncb->ccb_flags &= ~CCB_INTERNAL;
3140 
3141 	scsi_low_init_msgsys(slp, ti);
3142 
3143 	(*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3144 
3145 	if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3146 		ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3147 	ncb->ccb_tc = ncb->ccb_tcmax;
3148 
3149 	/* setup saved scsi data pointer */
3150 	ncb->ccb_sscp = ncb->ccb_scp;
3151 	slp->sl_scp = ncb->ccb_sscp;
3152 	slp->sl_error = ncb->ccb_error;
3153 
3154 #ifdef	SCSI_LOW_DIAGNOSTIC
3155 	scsi_low_msg_log_init(&ti->ti_log_msgin);
3156 	scsi_low_msg_log_init(&ti->ti_log_msgout);
3157 #endif	/* SCSI_LOW_DIAGNOSTIC */
3158 	return EJUSTRETURN;
3159 }
3160 
3161 static int
scsi_low_msginfunc_disc(slp)3162 scsi_low_msginfunc_disc(slp)
3163 	struct scsi_low_softc *slp;
3164 {
3165 
3166 	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3167 	return 0;
3168 }
3169 
3170 static int
scsi_low_msginfunc_sdp(slp)3171 scsi_low_msginfunc_sdp(slp)
3172 	struct scsi_low_softc *slp;
3173 {
3174 	struct slccb *cb = slp->sl_Qnexus;
3175 
3176 	if (cb != NULL)
3177 	{
3178 		cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3179 		cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3180 	}
3181 	else
3182 		scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3183 	return 0;
3184 }
3185 
3186 static int
scsi_low_msginfunc_rp(slp)3187 scsi_low_msginfunc_rp(slp)
3188 	struct scsi_low_softc *slp;
3189 {
3190 
3191 	if (slp->sl_Qnexus != NULL)
3192 		slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3193 	else
3194 		scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3195 	return 0;
3196 }
3197 
3198 static int
scsi_low_synch(slp)3199 scsi_low_synch(slp)
3200 	struct scsi_low_softc *slp;
3201 {
3202 	struct targ_info *ti = slp->sl_Tnexus;
3203 	u_int period = 0, offset = 0, speed;
3204 	u_char *s;
3205 	int error;
3206 
3207 	if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3208 	     MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3209 	     MSGIN_OFFSET(ti) == 0)
3210 	{
3211 		if ((offset = MSGIN_OFFSET(ti)) != 0)
3212 			period = MSGIN_PERIOD(ti);
3213 		s = offset ? "synchronous" : "async";
3214 	}
3215 	else
3216 	{
3217 		/* XXX:
3218 		 * Target seems to be brain damaged.
3219 		 * Force async transfer.
3220 		 */
3221 		ti->ti_maxsynch.period = 0;
3222 		ti->ti_maxsynch.offset = 0;
3223 		device_printf(slp->sl_dev,
3224 		    "target brain damaged. async transfer\n");
3225 		return EINVAL;
3226 	}
3227 
3228 	ti->ti_maxsynch.period = period;
3229 	ti->ti_maxsynch.offset = offset;
3230 
3231 	error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3232 	if (error != 0)
3233 	{
3234 		/* XXX:
3235 		 * Current period and offset are not acceptable
3236 		 * for our adapter.
3237 		 * The adapter changes max synch and max offset.
3238 		 */
3239 		device_printf(slp->sl_dev,
3240 		    "synch neg failed. retry synch msg neg ...\n");
3241 		return error;
3242 	}
3243 
3244 	ti->ti_osynch = ti->ti_maxsynch;
3245 	if (offset > 0)
3246 	{
3247 		ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3248 	}
3249 
3250 	/* inform data */
3251 	if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3252 	{
3253 #ifdef	SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3254 		struct slccb *cb = slp->sl_Qnexus;
3255 
3256 		if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3257 			return 0;
3258 #endif	/* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3259 
3260 		device_printf(slp->sl_dev,
3261 		    "(%d:*): <%s> offset %d period %dns ",
3262 		    ti->ti_id, s, offset, period * 4);
3263 
3264 		if (period != 0)
3265 		{
3266 			speed = 1000 * 10 / (period * 4);
3267 			printf("%d.%d M/s", speed / 10, speed % 10);
3268 		}
3269 		printf("\n");
3270 	}
3271 	return 0;
3272 }
3273 
3274 static int
scsi_low_wide(slp)3275 scsi_low_wide(slp)
3276 	struct scsi_low_softc *slp;
3277 {
3278 	struct targ_info *ti = slp->sl_Tnexus;
3279 	int error;
3280 
3281 	ti->ti_width = MSGIN_WIDTHP(ti);
3282 	error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3283 	if (error != 0)
3284 	{
3285 		/* XXX:
3286 		 * Current width is not acceptable for our adapter.
3287 		 * The adapter changes max width.
3288 		 */
3289 		device_printf(slp->sl_dev,
3290 		    "wide neg failed. retry wide msg neg ...\n");
3291 		return error;
3292 	}
3293 
3294 	ti->ti_owidth = ti->ti_width;
3295 	if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3296 	{
3297 		ti->ti_setup_msg_done |=
3298 			(SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3299 	}
3300 
3301 	/* inform data */
3302 	if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3303 	{
3304 #ifdef	SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3305 		struct slccb *cb = slp->sl_Qnexus;
3306 
3307 		if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3308 			return 0;
3309 #endif	/* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3310 
3311 		device_printf(slp->sl_dev, "(%d:*): transfer width %d bits\n",
3312 		    ti->ti_id, 1 << (3 + ti->ti_width));
3313 	}
3314 	return 0;
3315 }
3316 
3317 static int
scsi_low_msginfunc_simple_qtag(slp)3318 scsi_low_msginfunc_simple_qtag(slp)
3319 	struct scsi_low_softc *slp;
3320 {
3321 	struct targ_info *ti = slp->sl_Tnexus;
3322 	scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3323 
3324 	if (slp->sl_Qnexus != NULL)
3325 	{
3326 		if (slp->sl_Qnexus->ccb_tag != etag)
3327 		{
3328 			slp->sl_error |= FATALIO;
3329 			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3330 			SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3331 		}
3332 	}
3333 	else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3334 	{
3335 #ifdef	SCSI_LOW_DEBUG
3336 		if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3337 			return 0;
3338 #endif	/* SCSI_LOW_DEBUG */
3339 
3340 		slp->sl_error |= FATALIO;
3341 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3342 		SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3343 	}
3344 	return 0;
3345 }
3346 
3347 static int
scsi_low_msginfunc_i_wide_residue(slp)3348 scsi_low_msginfunc_i_wide_residue(slp)
3349 	struct scsi_low_softc *slp;
3350 {
3351 	struct targ_info *ti = slp->sl_Tnexus;
3352 	struct slccb *cb = slp->sl_Qnexus;
3353 	int res = (int) ti->ti_msgin[1];
3354 
3355 	if (cb == NULL || res <= 0 ||
3356 	    (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3357 	    (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3358 		return EINVAL;
3359 
3360 	if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3361 		return EINVAL;
3362 
3363 	slp->sl_scp.scp_datalen += res;
3364 	slp->sl_scp.scp_data -= res;
3365 	scsi_low_data_finish(slp);
3366 	return 0;
3367 }
3368 
3369 static int
scsi_low_msginfunc_ext(slp)3370 scsi_low_msginfunc_ext(slp)
3371 	struct scsi_low_softc *slp;
3372 {
3373 	struct slccb *cb = slp->sl_Qnexus;
3374 	struct lun_info *li = slp->sl_Lnexus;
3375 	struct targ_info *ti = slp->sl_Tnexus;
3376 	int count, retry;
3377 	u_int32_t *ptr;
3378 
3379 	if (ti->ti_msginptr == 2)
3380 	{
3381 		ti->ti_msginlen = ti->ti_msgin[1] + 2;
3382 		return 0;
3383 	}
3384 
3385 	switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3386 	{
3387 	case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3388 		if (cb == NULL)
3389 			break;
3390 
3391 		ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3392 		count = (int) htonl((long) (*ptr));
3393 		if(slp->sl_scp.scp_datalen - count < 0 ||
3394 		   slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3395 			break;
3396 
3397 		slp->sl_scp.scp_datalen -= count;
3398 		slp->sl_scp.scp_data += count;
3399 		return 0;
3400 
3401 	case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3402 		if (li == NULL)
3403 			break;
3404 
3405 		retry = scsi_low_synch(slp);
3406 		if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3407 			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3408 
3409 #ifdef	SCSI_LOW_DEBUG
3410 		if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3411 		{
3412 			scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3413 		}
3414 #endif	/* SCSI_LOW_DEBUG */
3415 		return 0;
3416 
3417 	case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3418 		if (li == NULL)
3419 			break;
3420 
3421 		retry = scsi_low_wide(slp);
3422 		if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3423 			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3424 
3425 		return 0;
3426 
3427 	default:
3428 		break;
3429 	}
3430 
3431 	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3432 	return EINVAL;
3433 }
3434 
3435 static int
scsi_low_msginfunc_parity(slp)3436 scsi_low_msginfunc_parity(slp)
3437 	struct scsi_low_softc *slp;
3438 {
3439 	struct targ_info *ti = slp->sl_Tnexus;
3440 
3441 	/* only I -> T, invalid! */
3442 	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3443 	return 0;
3444 }
3445 
3446 static int
scsi_low_msginfunc_msg_reject(slp)3447 scsi_low_msginfunc_msg_reject(slp)
3448 	struct scsi_low_softc *slp;
3449 {
3450 	struct targ_info *ti = slp->sl_Tnexus;
3451 	struct scsi_low_msgout_data *mdp;
3452 	u_int msgflags;
3453 
3454 	if (ti->ti_emsgflags != 0)
3455 	{
3456 		device_printf(slp->sl_dev, "msg flags [0x%x] rejected\n",
3457 		    ti->ti_emsgflags);
3458 		msgflags = SCSI_LOW_MSG_REJECT;
3459 		mdp = &scsi_low_msgout_data[0];
3460 		for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3461 		{
3462 			if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3463 			{
3464 				ti->ti_emsgflags &= ~mdp->md_flags;
3465 				if (mdp->md_errfunc != NULL)
3466 					(*mdp->md_errfunc) (slp, msgflags);
3467 				break;
3468 			}
3469 		}
3470 		return 0;
3471 	}
3472 	else
3473 	{
3474 		SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3475 		slp->sl_error |= MSGERR;
3476 	}
3477 	return EINVAL;
3478 }
3479 
3480 int
scsi_low_msgin(slp,ti,c)3481 scsi_low_msgin(slp, ti, c)
3482 	struct scsi_low_softc *slp;
3483 	struct targ_info *ti;
3484 	u_int c;
3485 {
3486 	struct scsi_low_msgin_data *sdp;
3487 	struct lun_info *li;
3488 	u_int8_t msg;
3489 
3490 #ifdef	SCSI_LOW_DIAGNOSTIC
3491 	if (ti != slp->sl_Tnexus)
3492 	{
3493 		scsi_low_print(slp, NULL);
3494 		panic("scsi_low_msgin: Target nexus inconsistent");
3495 	}
3496 #endif	/* SCSI_LOW_DIAGNOSTIC */
3497 
3498 	/*
3499 	 * Phase changes, clear the pointer.
3500 	 */
3501 	if (ti->ti_ophase != ti->ti_phase)
3502 	{
3503 		MSGINPTR_CLR(ti);
3504 		ti->ti_msgin_parity_error = 0;
3505 
3506 		slp->sl_ph_count ++;
3507 		if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3508 		{
3509 			device_printf(slp->sl_dev, "too many phase changes\n");
3510 			slp->sl_error |= FATALIO;
3511 			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3512 		}
3513 	}
3514 
3515 	/*
3516 	 * Store a current messages byte into buffer and
3517 	 * wait for the completion of the current msg.
3518 	 */
3519 	ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3520 	if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3521 	{
3522 		ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3523 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3524 	}
3525 
3526 	/*
3527 	 * Check parity errors.
3528 	 */
3529 	if ((c & SCSI_LOW_DATA_PE) != 0)
3530 	{
3531 		ti->ti_msgin_parity_error ++;
3532 		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3533 		goto out;
3534 	}
3535 
3536 	if (ti->ti_msgin_parity_error != 0)
3537 		goto out;
3538 
3539 	/*
3540 	 * Calculate messages length.
3541 	 */
3542 	msg = ti->ti_msgin[0];
3543 	if (msg < MSGIN_DATA_LAST)
3544 		sdp = &scsi_low_msgin_data[msg];
3545 	else
3546 		sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3547 
3548 	if (ti->ti_msginlen == 0)
3549 	{
3550 		ti->ti_msginlen = sdp->md_len;
3551 	}
3552 
3553 	/*
3554 	 * Check comletion.
3555 	 */
3556 	if (ti->ti_msginptr < ti->ti_msginlen)
3557 		return EJUSTRETURN;
3558 
3559 	/*
3560 	 * Do process.
3561 	 */
3562 	if ((msg & MSG_IDENTIFY) == 0)
3563 	{
3564 		if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3565 			return EJUSTRETURN;
3566 	}
3567 	else
3568 	{
3569 		li = slp->sl_Lnexus;
3570 		if (li == NULL)
3571 		{
3572 			li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3573 			if (li == NULL)
3574 				goto badlun;
3575 			slp->sl_Lnexus = li;
3576 			(*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3577 		}
3578 		else
3579 		{
3580 			if (MSGCMD_LUN(msg) != li->li_lun)
3581 				goto badlun;
3582 		}
3583 
3584 		if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3585 		{
3586 			if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3587 			{
3588 #ifdef	SCSI_LOW_DEBUG
3589 				if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3590 				{
3591 					goto out;
3592 				}
3593 #endif	/* SCSI_LOW_DEBUG */
3594 				goto badlun;
3595 			}
3596 		}
3597 	}
3598 	goto out;
3599 
3600 	/*
3601 	 * Msg process completed, reset msgin pointer and assert ATN if desired.
3602 	 */
3603 badlun:
3604 	slp->sl_error |= FATALIO;
3605 	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3606 	SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3607 
3608 out:
3609 	if (ti->ti_msginptr < ti->ti_msginlen)
3610 		return EJUSTRETURN;
3611 
3612 #ifdef	SCSI_LOW_DIAGNOSTIC
3613 	scsi_low_msg_log_write(&ti->ti_log_msgin,
3614 			       &ti->ti_msgin[0], ti->ti_msginlen);
3615 #endif	/* SCSI_LOW_DIAGNOSTIC */
3616 
3617 	MSGINPTR_CLR(ti);
3618 	return 0;
3619 }
3620 
3621 /**********************************************************
3622  * disconnect
3623  **********************************************************/
3624 int
scsi_low_disconnected(slp,ti)3625 scsi_low_disconnected(slp, ti)
3626 	struct scsi_low_softc *slp;
3627 	struct targ_info *ti;
3628 {
3629 	struct slccb *cb = slp->sl_Qnexus;
3630 
3631 	/* check phase completion */
3632 	switch (slp->sl_msgphase)
3633 	{
3634 	case MSGPH_RESET:
3635 		scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3636 		scsi_low_msginfunc_cc(slp);
3637 		scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3638 		goto io_resume;
3639 
3640 	case MSGPH_ABORT:
3641 		scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3642 		scsi_low_msginfunc_cc(slp);
3643 		scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3644 		goto io_resume;
3645 
3646 	case MSGPH_TERM:
3647 		scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3648 		scsi_low_msginfunc_cc(slp);
3649 		goto io_resume;
3650 
3651 	case MSGPH_DISC:
3652 		if (cb != NULL)
3653 		{
3654 			struct lun_info *li;
3655 
3656 			li = cb->li;
3657 			TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3658 			cb->ccb_flags |= CCB_DISCQ;
3659 			cb->ccb_error |= slp->sl_error;
3660 			li->li_disc ++;
3661 			ti->ti_disc ++;
3662 			slp->sl_disc ++;
3663 		}
3664 
3665 #ifdef	SCSI_LOW_STATICS
3666 		scsi_low_statics.nexus_disconnected ++;
3667 #endif	/* SCSI_LOW_STATICS */
3668 
3669 #ifdef	SCSI_LOW_DEBUG
3670 		if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3671 		{
3672 			printf("## SCSI_LOW_DISCONNECTED ===============\n");
3673 			scsi_low_print(slp, NULL);
3674 		}
3675 #endif	/* SCSI_LOW_DEBUG */
3676 		break;
3677 
3678 	case MSGPH_NULL:
3679 		slp->sl_error |= FATALIO;
3680 		if (ti->ti_phase == PH_SELSTART)
3681 			slp->sl_error |= SELTIMEOUTIO;
3682 		else
3683 			slp->sl_error |= UBFERR;
3684 		/* fall through */
3685 
3686 	case MSGPH_LCTERM:
3687 	case MSGPH_CMDC:
3688 io_resume:
3689 		if (cb == NULL)
3690 			break;
3691 
3692 #ifdef	SCSI_LOW_DEBUG
3693 		if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3694 		{
3695 			if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3696 			    (cb->ccb_msgoutflag != 0 ||
3697 			     (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3698 			{
3699 				scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3700 			}
3701 		}
3702 #endif	/* SCSI_LOW_DEBUG */
3703 
3704 		cb->ccb_error |= slp->sl_error;
3705 		if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3706 		{
3707 			cb->ccb_flags |= CCB_STARTQ;
3708 			TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3709 		}
3710 		break;
3711 	}
3712 
3713 	scsi_low_bus_release(slp, ti);
3714 	scsi_low_start(slp);
3715 	return 1;
3716 }
3717 
3718 /**********************************************************
3719  * TAG operations
3720  **********************************************************/
3721 static int
scsi_low_alloc_qtag(cb)3722 scsi_low_alloc_qtag(cb)
3723 	struct slccb *cb;
3724 {
3725 	struct lun_info *li = cb->li;
3726 	scsi_low_tag_t etag;
3727 
3728 	if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3729 		return 0;
3730 
3731 #ifndef	SCSI_LOW_ALT_QTAG_ALLOCATE
3732 	etag = ffs(li->li_qtagbits);
3733 	if (etag == 0)
3734 		return ENOSPC;
3735 
3736 	li->li_qtagbits &= ~(1 << (etag - 1));
3737 	cb->ccb_otag = etag;
3738 	return 0;
3739 
3740 #else	/* SCSI_LOW_ALT_QTAG_ALLOCATE */
3741 	for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3742 		if (li->li_qtagarray[li->li_qd] == 0)
3743 			goto found;
3744 
3745 	for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3746 		if (li->li_qtagarray[li->li_qd] == 0)
3747 			goto found;
3748 
3749 	return ENOSPC;
3750 
3751 found:
3752 	li->li_qtagarray[li->li_qd] ++;
3753 	cb->ccb_otag = (li->li_qd ++);
3754 	return 0;
3755 #endif	/* SCSI_LOW_ALT_QTAG_ALLOCATE */
3756 }
3757 
3758 static int
scsi_low_dealloc_qtag(cb)3759 scsi_low_dealloc_qtag(cb)
3760 	struct slccb *cb;
3761 {
3762 	struct lun_info *li = cb->li;
3763 	scsi_low_tag_t etag;
3764 
3765 	if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3766 		return 0;
3767 
3768 #ifndef	SCSI_LOW_ALT_QTAG_ALLOCATE
3769 	etag = cb->ccb_otag - 1;
3770 #ifdef	SCSI_LOW_DIAGNOSTIC
3771 	if (etag >= sizeof(li->li_qtagbits) * NBBY)
3772 		panic("scsi_low_dealloc_tag: illegal tag");
3773 #endif	/* SCSI_LOW_DIAGNOSTIC */
3774 	li->li_qtagbits |= (1 << etag);
3775 
3776 #else	/* SCSI_LOW_ALT_QTAG_ALLOCATE */
3777 	etag = cb->ccb_otag;
3778 #ifdef	SCSI_LOW_DIAGNOSTIC
3779 	if (etag >= SCSI_LOW_MAXNEXUS)
3780 		panic("scsi_low_dealloc_tag: illegal tag");
3781 #endif	/* SCSI_LOW_DIAGNOSTIC */
3782 	li->li_qtagarray[etag] --;
3783 #endif	/* SCSI_LOW_ALT_QTAG_ALLOCATE */
3784 
3785 	cb->ccb_otag = SCSI_LOW_UNKTAG;
3786 	return 0;
3787 }
3788 
3789 static struct slccb *
scsi_low_revoke_ccb(slp,cb,fdone)3790 scsi_low_revoke_ccb(slp, cb, fdone)
3791 	struct scsi_low_softc *slp;
3792 	struct slccb *cb;
3793 	int fdone;
3794 {
3795 	struct targ_info *ti = cb->ti;
3796 	struct lun_info *li = cb->li;
3797 
3798 #ifdef	SCSI_LOW_DIAGNOSTIC
3799 	if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
3800 	    (CCB_STARTQ | CCB_DISCQ))
3801 	{
3802 		panic("%s: ccb in both queue",
3803 		    device_get_nameunit(slp->sl_dev));
3804 	}
3805 #endif	/* SCSI_LOW_DIAGNOSTIC */
3806 
3807 	if ((cb->ccb_flags & CCB_STARTQ) != 0)
3808 	{
3809 		TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3810 	}
3811 
3812 	if ((cb->ccb_flags & CCB_DISCQ) != 0)
3813 	{
3814 		TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3815 		li->li_disc --;
3816 		ti->ti_disc --;
3817 		slp->sl_disc --;
3818 	}
3819 
3820 	cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
3821 			   CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3822 
3823 	if (fdone != 0 &&
3824 	    (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
3825 	     (cb->ccb_flags & CCB_NORETRY) != 0))
3826 	{
3827 		cb->ccb_error |= FATALIO;
3828 		cb->ccb_flags &= ~CCB_AUTOSENSE;
3829 		if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3830 			panic("%s: done ccb retried",
3831 			    device_get_nameunit(slp->sl_dev));
3832 		return NULL;
3833 	}
3834 	else
3835 	{
3836 		cb->ccb_error |= PENDINGIO;
3837 		scsi_low_deactivate_qtag(cb);
3838 		scsi_low_ccb_message_retry(cb);
3839 		cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3840 		return cb;
3841 	}
3842 }
3843 
3844 static void
scsi_low_reset_nexus_lun(slp,li,fdone)3845 scsi_low_reset_nexus_lun(slp, li, fdone)
3846 	struct scsi_low_softc *slp;
3847 	struct lun_info *li;
3848 	int fdone;
3849 {
3850 	struct slccb *cb, *ncb, *ecb;
3851 
3852 	if (li == NULL)
3853 		return;
3854 
3855 	ecb = NULL;
3856 	for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3857 	{
3858 		ncb = TAILQ_NEXT(cb, ccb_chain);
3859 		cb = scsi_low_revoke_ccb(slp, cb, fdone);
3860 		if (cb != NULL)
3861 		{
3862 			/*
3863 			 * presumely keep ordering of io
3864 			 */
3865 			cb->ccb_flags |= CCB_STARTQ;
3866 			if (ecb == NULL)
3867 			{
3868 				TAILQ_INSERT_HEAD(&slp->sl_start,\
3869 						  cb, ccb_chain);
3870 			}
3871 			else
3872 			{
3873 				TAILQ_INSERT_AFTER(&slp->sl_start,\
3874 						   ecb, cb, ccb_chain);
3875 			}
3876 			ecb = cb;
3877 		}
3878 	}
3879 }
3880 
3881 /**************************************************************
3882  * Qurik setup
3883  **************************************************************/
3884 static void
scsi_low_calcf_lun(li)3885 scsi_low_calcf_lun(li)
3886 	struct lun_info *li;
3887 {
3888 	struct targ_info *ti = li->li_ti;
3889 	struct scsi_low_softc *slp = ti->ti_sc;
3890 	u_int cfgflags, diskflags;
3891 
3892 	if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3893 		cfgflags = li->li_cfgflags;
3894 	else
3895 		cfgflags = 0;
3896 
3897 	diskflags = li->li_diskflags & li->li_quirks;
3898 
3899 	/* disconnect */
3900 	li->li_flags &= ~SCSI_LOW_DISC;
3901 	if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3902 	    (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3903 	    (cfgflags & SCSI_LOW_DISC) != 0)
3904 		li->li_flags |= SCSI_LOW_DISC;
3905 
3906 	/* parity */
3907 	li->li_flags |= SCSI_LOW_NOPARITY;
3908 	if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3909 	    (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3910 	    (cfgflags & SCSI_LOW_NOPARITY) == 0)
3911 		li->li_flags &= ~SCSI_LOW_NOPARITY;
3912 
3913 	/* qtag */
3914 	if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
3915 	    (cfgflags & SCSI_LOW_QTAG) != 0 &&
3916 	    (diskflags & SCSI_LOW_DISK_QTAG) != 0)
3917 	{
3918 		li->li_flags |= SCSI_LOW_QTAG;
3919 		li->li_maxnexus = SCSI_LOW_MAXNEXUS;
3920 		li->li_maxnqio = li->li_maxnexus;
3921 	}
3922 	else
3923 	{
3924 		li->li_flags &= ~SCSI_LOW_QTAG;
3925 		li->li_maxnexus = 0;
3926 		li->li_maxnqio = li->li_maxnexus;
3927 	}
3928 
3929 	/* cmd link */
3930 	li->li_flags &= ~SCSI_LOW_LINK;
3931 	if ((cfgflags & SCSI_LOW_LINK) != 0 &&
3932 	    (diskflags & SCSI_LOW_DISK_LINK) != 0)
3933 		li->li_flags |= SCSI_LOW_LINK;
3934 
3935 	/* compatible flags */
3936 	li->li_flags &= ~SCSI_LOW_SYNC;
3937 	if (ti->ti_maxsynch.offset > 0)
3938 		li->li_flags |= SCSI_LOW_SYNC;
3939 
3940 #ifdef	SCSI_LOW_DEBUG
3941 	if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3942 	{
3943 		scsi_low_calcf_show(li);
3944 	}
3945 #endif	/* SCSI_LOW_DEBUG */
3946 }
3947 
3948 static void
scsi_low_calcf_target(ti)3949 scsi_low_calcf_target(ti)
3950 	struct targ_info *ti;
3951 {
3952 	struct scsi_low_softc *slp = ti->ti_sc;
3953 	u_int offset, period, diskflags;
3954 
3955 	diskflags = ti->ti_diskflags & ti->ti_quirks;
3956 
3957 	/* synch */
3958 	if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
3959 	    (diskflags & SCSI_LOW_DISK_SYNC) != 0)
3960 	{
3961 		offset = ti->ti_maxsynch.offset;
3962 		period = ti->ti_maxsynch.period;
3963 		if (offset == 0 || period == 0)
3964 			offset = period = 0;
3965 	}
3966 	else
3967 	{
3968 		offset = period = 0;
3969 	}
3970 
3971 	ti->ti_maxsynch.offset = offset;
3972 	ti->ti_maxsynch.period = period;
3973 
3974 	/* wide */
3975 	if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
3976 	     ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
3977 		ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
3978 
3979 	if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
3980 	    ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3981 		ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
3982 
3983 	if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
3984 	{
3985 		if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
3986 		    ti->ti_maxsynch.period != ti->ti_osynch.period)
3987 			ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
3988 		if (ti->ti_width != ti->ti_owidth)
3989 			ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
3990 
3991 		ti->ti_osynch = ti->ti_maxsynch;
3992 		ti->ti_owidth = ti->ti_width;
3993 	}
3994 
3995 #ifdef	SCSI_LOW_DEBUG
3996 	if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3997 	{
3998 		device_printf(slp->sl_dev,
3999 			"(%d:*): max period(%dns) offset(%d) width(%d)\n",
4000 			ti->ti_id,
4001 			ti->ti_maxsynch.period * 4,
4002 			ti->ti_maxsynch.offset,
4003 			ti->ti_width);
4004 	}
4005 #endif	/* SCSI_LOW_DEBUG */
4006 }
4007 
4008 static void
scsi_low_calcf_show(li)4009 scsi_low_calcf_show(li)
4010 	struct lun_info *li;
4011 {
4012 	struct targ_info *ti = li->li_ti;
4013 	struct scsi_low_softc *slp = ti->ti_sc;
4014 
4015 	device_printf(slp->sl_dev,
4016 		"(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4017 		ti->ti_id, li->li_lun,
4018 		ti->ti_maxsynch.period * 4,
4019 		ti->ti_maxsynch.offset,
4020 		ti->ti_width,
4021 		li->li_flags, SCSI_LOW_BITS);
4022 }
4023 
4024 #ifdef	SCSI_LOW_START_UP_CHECK
4025 /**************************************************************
4026  * scsi world start up
4027  **************************************************************/
4028 static int scsi_low_poll(struct scsi_low_softc *, struct slccb *);
4029 
4030 static int
scsi_low_start_up(slp)4031 scsi_low_start_up(slp)
4032 	struct scsi_low_softc *slp;
4033 {
4034 	struct targ_info *ti;
4035 	struct lun_info *li;
4036 	struct slccb *cb;
4037 	int target, lun;
4038 
4039 	device_printf(slp->sl_dev, "scsi_low: probing all devices ....\n");
4040 
4041 	for (target = 0; target < slp->sl_ntargs; target ++)
4042 	{
4043 		if (target == slp->sl_hostid)
4044 		{
4045 			if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4046 			{
4047 				device_printf(slp->sl_dev,
4048 				    "scsi_low: target %d (host card)\n",
4049 				    target);
4050 			}
4051 			continue;
4052 		}
4053 
4054 		if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4055 		{
4056 			device_printf(slp->sl_dev, "scsi_low: target %d lun ",
4057 			    target);
4058 		}
4059 
4060 		ti = slp->sl_ti[target];
4061 		for (lun = 0; lun < slp->sl_nluns; lun ++)
4062 		{
4063 			if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4064 				break;
4065 
4066 			cb->osdep = NULL;
4067 			cb->bp = NULL;
4068 
4069 			li = scsi_low_alloc_li(ti, lun, 1);
4070 
4071 			scsi_low_enqueue(slp, ti, li, cb,
4072 					 CCB_AUTOSENSE | CCB_POLLED, 0);
4073 
4074 			scsi_low_poll(slp, cb);
4075 
4076 			if (li->li_state != SCSI_LOW_LUN_OK)
4077 				break;
4078 
4079 			if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4080 			{
4081 				printf("%d ", lun);
4082 			}
4083 		}
4084 
4085 		if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4086 		{
4087 			printf("\n");
4088 		}
4089 	}
4090 	return 0;
4091 }
4092 
4093 static int
scsi_low_poll(slp,cb)4094 scsi_low_poll(slp, cb)
4095 	struct scsi_low_softc *slp;
4096 	struct slccb *cb;
4097 {
4098 	int tcount;
4099 
4100 	tcount = 0;
4101 	while (slp->sl_nio > 0)
4102 	{
4103 		DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4104 
4105 		(*slp->sl_funcs->scsi_low_poll) (slp);
4106 		if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4107 			continue;
4108 
4109 		tcount = 0;
4110 		scsi_low_timeout_check(slp);
4111 	}
4112 
4113 	return 0;
4114 }
4115 #endif	/* SCSI_LOW_START_UP_CHECK */
4116 
4117 /**********************************************************
4118  * DEBUG SECTION
4119  **********************************************************/
4120 #ifdef	SCSI_LOW_DEBUG
4121 static void
scsi_low_test_abort(slp,ti,li)4122 scsi_low_test_abort(slp, ti, li)
4123 	struct scsi_low_softc *slp;
4124 	struct targ_info *ti;
4125 	struct lun_info *li;
4126 {
4127 	struct slccb *acb;
4128 
4129 	if (li->li_disc > 1)
4130 	{
4131 		acb = TAILQ_FIRST(&li->li_discq);
4132 		if (scsi_low_abort_ccb(slp, acb) == 0)
4133 		{
4134 			device_printf(slp->sl_dev,
4135 			    "aborting ccb(0x%lx) start\n", (u_long) acb);
4136 		}
4137 	}
4138 }
4139 
4140 static void
scsi_low_test_atten(slp,ti,msg)4141 scsi_low_test_atten(slp, ti, msg)
4142 	struct scsi_low_softc *slp;
4143 	struct targ_info *ti;
4144 	u_int msg;
4145 {
4146 
4147 	if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4148 		scsi_low_assert_msg(slp, ti, msg, 0);
4149 	else
4150 		device_printf(slp->sl_dev, "atten check OK\n");
4151 }
4152 
4153 static void
scsi_low_test_cmdlnk(slp,cb)4154 scsi_low_test_cmdlnk(slp, cb)
4155 	struct scsi_low_softc *slp;
4156 	struct slccb *cb;
4157 {
4158 #define	SCSI_LOW_CMDLNK_NOK	(CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4159 
4160 	if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4161 		return;
4162 
4163 	memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4164 	       slp->sl_scp.scp_cmdlen);
4165 	cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4166 	slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4167 }
4168 #endif	/* SCSI_LOW_DEBUG */
4169 
4170 /* static */ void
scsi_low_info(slp,ti,s)4171 scsi_low_info(slp, ti, s)
4172 	struct scsi_low_softc *slp;
4173 	struct targ_info *ti;
4174 	u_char *s;
4175 {
4176 
4177 	if (slp == NULL)
4178 		slp = LIST_FIRST(&sl_tab);
4179 	if (s == NULL)
4180 		s = "no message";
4181 
4182 	printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4183 	if (ti == NULL)
4184 	{
4185 		TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
4186 		{
4187 			scsi_low_print(slp, ti);
4188 		}
4189 	}
4190 	else
4191 	{
4192 		scsi_low_print(slp, ti);
4193 	}
4194 }
4195 
4196 static u_char *phase[] =
4197 {
4198 	"FREE", "ARBSTART", "SELSTART", "SELECTED",
4199 	"CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4200 };
4201 
4202 void
scsi_low_print(slp,ti)4203 scsi_low_print(slp, ti)
4204 	struct scsi_low_softc *slp;
4205 	struct targ_info *ti;
4206 {
4207 	struct lun_info *li;
4208 	struct slccb *cb;
4209 	struct sc_p *sp;
4210 
4211 	if (ti == NULL || ti == slp->sl_Tnexus)
4212 	{
4213 		ti = slp->sl_Tnexus;
4214 		li = slp->sl_Lnexus;
4215 		cb = slp->sl_Qnexus;
4216 	}
4217 	else
4218 	{
4219 		li = LIST_FIRST(&ti->ti_litab);
4220 		cb = TAILQ_FIRST(&li->li_discq);
4221 	}
4222  	sp = &slp->sl_scp;
4223 
4224 	device_printf(slp->sl_dev,
4225 	    "=== NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4226 	    (u_long) ti, (u_long) li, (u_long) cb, slp->sl_nio);
4227 
4228 	/* target stat */
4229 	if (ti != NULL)
4230 	{
4231 		u_int flags = 0, maxnqio = 0, nqio = 0;
4232 		int lun = CAM_LUN_WILDCARD;
4233 
4234 		if (li != NULL)
4235 		{
4236 			lun = li->li_lun;
4237 			flags = li->li_flags;
4238 			maxnqio = li->li_maxnqio;
4239 			nqio = li->li_nqio;
4240 		}
4241 
4242 		device_printf(slp->sl_dev,
4243 		       "(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4244 		       ti->ti_id, lun, phase[(int) ti->ti_ophase],
4245 		       phase[(int) ti->ti_phase], ti->ti_disc,
4246 		       nqio, maxnqio);
4247 
4248 		if (cb != NULL)
4249 		{
4250 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4251 		       (u_int) cb->ccb_scp.scp_cmd[0],
4252 		       cb->ccb_scp.scp_cmdlen,
4253 		       cb->ccb_datalen,
4254 		       cb->ccb_scp.scp_datalen,
4255 		       (u_int) cb->ccb_sscp.scp_status,
4256 		       cb->ccb_error, SCSI_LOW_ERRORBITS);
4257 		}
4258 
4259 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4260 	       (u_int) (ti->ti_msginptr),
4261 	       (u_int) (ti->ti_msgin[0]),
4262 	       (u_int) (ti->ti_msgin[1]),
4263 	       (u_int) (ti->ti_msgin[2]),
4264 	       (u_int) (ti->ti_msgin[3]),
4265 	       (u_int) (ti->ti_msgin[4]),
4266 	       slp->sl_atten);
4267 
4268 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4269 		(u_int) ti->ti_msgflags,
4270 		(u_int) (ti->ti_msgoutstr[0]),
4271 		(u_int) (ti->ti_msgoutstr[1]),
4272 		(u_int) (ti->ti_msgoutstr[2]),
4273 		(u_int) (ti->ti_msgoutstr[3]),
4274 		(u_int) (ti->ti_msgoutstr[4]),
4275 		ti->ti_msgoutlen,
4276 		flags, SCSI_LOW_BITS);
4277 
4278 #ifdef	SCSI_LOW_DIAGNOSTIC
4279 		scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4280 		scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4281 #endif	/* SCSI_LOW_DIAGNOSTIC */
4282 
4283 	}
4284 
4285 	printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4286 	       (u_long) sp->scp_data,
4287 	       sp->scp_datalen,
4288 	       (u_int) sp->scp_status,
4289 	       slp->sl_error, SCSI_LOW_ERRORBITS);
4290 }
4291