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