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