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