scsi_low.c revision 288693
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 288693 2015-10-05 06:56:22Z 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
112static 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 *);
118static void scsi_low_engage(void *);
119static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t);
120static int scsi_low_done(struct scsi_low_softc *, struct slccb *);
121static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *);
122static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *);
123static void scsi_low_twiddle_wait(void);
124static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int);
125static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int);
126static void scsi_low_calcf_lun(struct lun_info *);
127static void scsi_low_calcf_target(struct targ_info *);
128static void scsi_low_calcf_show(struct lun_info *);
129static void scsi_low_reset_nexus(struct scsi_low_softc *, int);
130static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int);
131static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int);
132static int scsi_low_init(struct scsi_low_softc *, u_int);
133static void scsi_low_start(struct scsi_low_softc *);
134static void scsi_low_free_ti(struct scsi_low_softc *);
135
136static int scsi_low_alloc_qtag(struct slccb *);
137static int scsi_low_dealloc_qtag(struct slccb *);
138static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
139static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
140static void scsi_low_unit_ready_cmd(struct slccb *);
141static void scsi_low_timeout(void *);
142static int scsi_low_timeout_check(struct scsi_low_softc *);
143#ifdef	SCSI_LOW_START_UP_CHECK
144static int scsi_low_start_up(struct scsi_low_softc *);
145#endif	/* SCSI_LOW_START_UP_CHECK */
146static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *);
147static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int);
148
149int scsi_low_version_major = 2;
150int scsi_low_version_minor = 17;
151
152static 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
164static 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
179int 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
186int scsi_low_test = 0;
187int scsi_low_test_id = 0;
188
189static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *);
190static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *);
191static 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 **************************************************************/
201GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
202GENERIC_CCB(scsi_low, slccb, ccb_chain)
203
204/**************************************************************
205 * Inline functions
206 **************************************************************/
207#define	SCSI_LOW_INLINE	static __inline
208SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *);
209SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *);
210SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int);
211SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *);
212SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *);
213SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *);
214SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *);
215
216SCSI_LOW_INLINE void
217scsi_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
229SCSI_LOW_INLINE void
230scsi_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
242SCSI_LOW_INLINE void
243scsi_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
252SCSI_LOW_INLINE void
253scsi_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
261SCSI_LOW_INLINE void
262scsi_low_ccb_message_retry(cb)
263	struct slccb *cb;
264{
265	cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
266}
267
268SCSI_LOW_INLINE void
269scsi_low_ccb_message_clear(cb)
270	struct slccb *cb;
271{
272	cb->ccb_msgoutflag = 0;
273}
274
275SCSI_LOW_INLINE void
276scsi_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
295static 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
303struct scsi_low_error_code {
304	int error_bits;
305	int error_code;
306};
307
308static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *);
309static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *);
310
311static struct slccb *
312scsi_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
343static int
344scsi_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
364static void scsi_low_poll_cam(struct cam_sim *);
365void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *);
366
367static int scsi_low_attach_cam(struct scsi_low_softc *);
368static int scsi_low_world_start_cam(struct scsi_low_softc *);
369static int scsi_low_dettach_cam(struct scsi_low_softc *);
370static int scsi_low_ccb_setup_cam(struct scsi_low_softc *, struct slccb *);
371static int scsi_low_done_cam(struct scsi_low_softc *, struct slccb *);
372static void scsi_low_timeout_cam(struct scsi_low_softc *, int, int);
373
374struct 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
383struct 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
406static void
407scsi_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
422void
423scsi_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;
660settings_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		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
745		strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
746		strncpy(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
762static int
763scsi_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
805static int
806scsi_low_world_start_cam(slp)
807	struct scsi_low_softc *slp;
808{
809
810	return 0;
811}
812
813static int
814scsi_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
825static int
826scsi_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
851static int
852scsi_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
909static void
910scsi_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 **************************************************************/
954int
955scsi_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
964int
965scsi_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
980int
981scsi_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
1006static void scsi_low_msg_log_init(struct scsi_low_msg_log *);
1007static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int);
1008static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int);
1009
1010static void
1011scsi_low_msg_log_init(slmlp)
1012	struct scsi_low_msg_log *slmlp;
1013{
1014
1015	slmlp->slml_ptr = 0;
1016}
1017
1018static void
1019scsi_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
1036static void
1037scsi_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 **************************************************************/
1061static void
1062scsi_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
1089static int
1090scsi_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
1121out:
1122	slp->sl_flags &= ~HW_INITIALIZING;
1123	return rv;
1124}
1125
1126/**************************************************************
1127 * allocate lun_info
1128 **************************************************************/
1129static struct lun_info *
1130scsi_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 **************************************************************/
1190static struct targ_info *
1191scsi_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
1228static void
1229scsi_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 **************************************************************/
1261void
1262scsi_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
1271static void
1272scsi_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
1285static int
1286scsi_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 */
1318step1:
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
1391bus_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
1401static int
1402scsi_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 **************************************************************/
1455int
1456scsi_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
1546int
1547scsi_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 **************************************************************/
1577static int
1578scsi_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
1614static int
1615scsi_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
1641static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1642static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1643			      sizeof(struct scsi_low_mode_sense_data), 0};
1644static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1645			      sizeof(struct scsi_low_inq_data), 0};
1646static u_int8_t unit_ready_cmd[6];
1647static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1648static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1649static int scsi_low_resume(struct scsi_low_softc *);
1650
1651static void
1652scsi_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
1663static int
1664scsi_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
1696static int
1697scsi_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
1743static int
1744scsi_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
1764static void
1765scsi_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
1815scsi_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
1912void
1913scsi_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
1936static void
1937scsi_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
1966static int
1967scsi_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;
2028resume:
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
2092static int
2093scsi_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
2231retry:
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 **************************************************************/
2249static void
2250scsi_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
2299static void
2300scsi_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 */
2336static int tw_pos;
2337static char tw_chars[] = "|/-\\";
2338#define	TWIDDLEWAIT		10000
2339
2340static void
2341scsi_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
2350void
2351scsi_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
2365int
2366scsi_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
2388static struct slccb *
2389scsi_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	 */
2409found:
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
2450struct targ_info *
2451scsi_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
2515world_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 **************************************************************/
2525int
2526scsi_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 **************************************************************/
2562int
2563scsi_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
2605static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int);
2606static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int);
2607static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int);
2608static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int);
2609
2610static int scsi_low_msgfunc_synch(struct scsi_low_softc *);
2611static int scsi_low_msgfunc_wide(struct scsi_low_softc *);
2612static int scsi_low_msgfunc_identify(struct scsi_low_softc *);
2613static int scsi_low_msgfunc_abort(struct scsi_low_softc *);
2614static int scsi_low_msgfunc_qabort(struct scsi_low_softc *);
2615static int scsi_low_msgfunc_qtag(struct scsi_low_softc *);
2616static int scsi_low_msgfunc_reset(struct scsi_low_softc *);
2617
2618struct 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
2627struct 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
2646static int scsi_low_msginfunc_ext(struct scsi_low_softc *);
2647static int scsi_low_synch(struct scsi_low_softc *);
2648static int scsi_low_wide(struct scsi_low_softc *);
2649static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *);
2650static int scsi_low_msginfunc_rejop(struct scsi_low_softc *);
2651static int scsi_low_msginfunc_rp(struct scsi_low_softc *);
2652static int scsi_low_msginfunc_sdp(struct scsi_low_softc *);
2653static int scsi_low_msginfunc_disc(struct scsi_low_softc *);
2654static int scsi_low_msginfunc_cc(struct scsi_low_softc *);
2655static int scsi_low_msginfunc_lcc(struct scsi_low_softc *);
2656static int scsi_low_msginfunc_parity(struct scsi_low_softc *);
2657static int scsi_low_msginfunc_noop(struct scsi_low_softc *);
2658static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *);
2659static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *);
2660
2661struct scsi_low_msgin_data {
2662	u_int md_len;
2663	int (*md_msgfunc)(struct scsi_low_softc *);
2664};
2665
2666struct 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 **************************************************************/
2721static int
2722scsi_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
2735static int
2736scsi_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
2748static int
2749scsi_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
2785static int
2786scsi_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
2794static int
2795scsi_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
2803static int
2804scsi_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
2812static int
2813scsi_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 */
2840static int
2841scsi_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
2854static int
2855scsi_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
2867static int
2868scsi_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
2879static int
2880scsi_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
2902int
2903scsi_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 **************************************************************/
3007static int
3008scsi_low_msginfunc_noop(slp)
3009	struct scsi_low_softc *slp;
3010{
3011
3012	return 0;
3013}
3014
3015static int
3016scsi_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
3027static int
3028scsi_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
3074static int
3075scsi_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
3115bad:
3116	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3117	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3118	return EIO;
3119
3120cmd_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
3161static int
3162scsi_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
3170static int
3171scsi_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
3186static int
3187scsi_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
3198static int
3199scsi_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
3274static int
3275scsi_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
3317static int
3318scsi_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
3347static int
3348scsi_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
3369static int
3370scsi_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
3435static int
3436scsi_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
3446static int
3447scsi_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
3480int
3481scsi_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	 */
3603badlun:
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
3608out:
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 **********************************************************/
3624int
3625scsi_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:
3688io_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 **********************************************************/
3721static int
3722scsi_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
3751found:
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
3758static int
3759scsi_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
3789static struct slccb *
3790scsi_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
3844static void
3845scsi_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 **************************************************************/
3884static void
3885scsi_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
3948static void
3949scsi_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
4008static void
4009scsi_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 **************************************************************/
4028static int scsi_low_poll(struct scsi_low_softc *, struct slccb *);
4029
4030static int
4031scsi_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
4093static int
4094scsi_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
4121static void
4122scsi_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
4140static void
4141scsi_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
4153static void
4154scsi_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
4171scsi_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
4196static u_char *phase[] =
4197{
4198	"FREE", "ARBSTART", "SELSTART", "SELECTED",
4199	"CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4200};
4201
4202void
4203scsi_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		{
4250printf("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
4259printf("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
4268printf("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