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