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