scsi_low.c revision 71508
1/*	$FreeBSD: head/sys/cam/scsi/scsi_low.c 71508 2001-01-24 01:46:57Z jhb $	*/
2/*	$NecBSD: scsi_low.c,v 1.24 1999/07/26 06:27:01 honda Exp $	*/
3/*	$NetBSD$	*/
4
5#define	SCSI_LOW_STATICS
6#define SCSI_LOW_WARNINGS
7#ifdef __NetBSD__
8#define	SCSI_LOW_TARGET_OPEN
9#define SCSI_LOW_INFORM
10#endif
11#ifdef __FreeBSD__
12#define CAM
13#endif
14
15/*
16 * [NetBSD for NEC PC-98 series]
17 *  Copyright (c) 1995, 1996, 1997, 1998, 1999
18 *	NetBSD/pc98 porting staff. All rights reserved.
19 *  Copyright (c) 1995, 1996, 1997, 1998, 1999
20 *	Naofumi HONDA. All rights reserved.
21 *
22 *  Redistribution and use in source and binary forms, with or without
23 *  modification, are permitted provided that the following conditions
24 *  are met:
25 *  1. Redistributions of source code must retain the above copyright
26 *     notice, this list of conditions and the following disclaimer.
27 *  2. Redistributions in binary form must reproduce the above copyright
28 *     notice, this list of conditions and the following disclaimer in the
29 *     documentation and/or other materials provided with the distribution.
30 *  3. The name of the author may not be used to endorse or promote products
31 *     derived from this software without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
34 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
37 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
42 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGE.
44 */
45
46/* <On the nexus establishment>
47 * When our host is reselected,
48 * nexus establish processes are little complicated.
49 * Normal steps are followings:
50 * 1) Our host selected by target => target nexus (slp->sl_nexus)
51 * 2) Identify msgin => lun nexus (ti->ti_li)
52 * 3) Qtag msg => slccb nexus (ti->ti_nexus)
53 */
54#include "opt_ddb.h"
55
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/kernel.h>
59#ifdef __NetBSD__
60#include <sys/disklabel.h>
61#endif
62#if defined(__FreeBSD__) && __FreeBSD_version >= 500001
63#include <sys/bio.h>
64#include <sys/devicestat.h>
65#endif
66#include <sys/buf.h>
67#include <sys/queue.h>
68#include <sys/malloc.h>
69#include <sys/device_port.h>
70#include <sys/errno.h>
71
72#ifdef __NetBSD__
73#include <vm/vm.h>
74
75#include <machine/bus.h>
76#include <machine/intr.h>
77#include <machine/dvcfg.h>
78
79#include <dev/cons.h>
80
81#include <dev/scsipi/scsipi_all.h>
82#include <dev/scsipi/scsipiconf.h>
83#include <dev/scsipi/scsipi_disk.h>
84#include <dev/scsipi/scsi_all.h>
85#include <dev/scsipi/scsiconf.h>
86
87#include <i386/Cbus/dev/scsi_low.h>
88#endif
89#ifdef __FreeBSD__
90#include <cam/cam.h>
91#include <cam/cam_ccb.h>
92#include <cam/cam_sim.h>
93#include <cam/cam_debug.h>
94#include <cam/cam_periph.h>
95
96#include <cam/scsi/scsi_all.h>
97
98#include <cam/scsi/scsi_low.h>
99
100#if !defined(__FreeBSD__) || __FreeBSD_version < 400001
101#include <i386/i386/cons.h>
102#else
103#include <sys/cons.h>
104#endif
105#define delay(time) DELAY(time)
106
107/* from sys/dev/usb/usb_port.h
108  XXX Change this when FreeBSD has memset
109 */
110#define memset(d, v, s)	\
111		do{			\
112		if ((v) == 0)		\
113			bzero((d), (s));	\
114		else			\
115			panic("Non zero filler for memset, cannot handle!"); \
116		} while (0)
117#endif
118
119#define	SCSI_LOW_DONE_COMPLETE	0
120#define	SCSI_LOW_DONE_RETRY	1
121
122static void scsi_low_engage __P((void *));
123static void scsi_low_info __P((struct scsi_low_softc *, struct targ_info *, u_char *));
124static void scsi_low_init_msgsys __P((struct scsi_low_softc *, struct targ_info *));
125static struct slccb *scsi_low_establish_ccb __P((struct targ_info *, struct lun_info *, scsi_low_tag_t));
126static int scsi_low_done __P((struct scsi_low_softc *, struct slccb *));
127static void scsi_low_twiddle_wait __P((void));
128static struct lun_info *scsi_low_alloc_li __P((struct targ_info *, int, int));
129static struct targ_info *scsi_low_alloc_ti __P((struct scsi_low_softc *, int));
130static void scsi_low_calcf __P((struct targ_info *, struct lun_info *));
131static struct lun_info *scsi_low_establish_lun __P((struct targ_info *, int));
132#ifndef CAM
133static void scsi_low_scsi_minphys __P((struct buf *));
134#endif
135#ifdef	SCSI_LOW_TARGET_OPEN
136static int scsi_low_target_open __P((struct scsipi_link *, struct cfdata *));
137#endif	/* SCSI_LOW_TARGET_OPEN */
138#ifdef CAM
139void scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb);
140static void scsi_low_poll (struct cam_sim *sim);
141#else
142static int scsi_low_scsi_cmd __P((struct scsipi_xfer *));
143#endif
144static void scsi_low_reset_nexus __P((struct scsi_low_softc *, int));
145static int scsi_low_init __P((struct scsi_low_softc *, u_int));
146static void scsi_low_start __P((struct scsi_low_softc *));
147static void scsi_low_free_ti __P((struct scsi_low_softc *));
148static void scsi_low_clear_ccb __P((struct slccb *));
149
150#ifdef	SCSI_LOW_STATICS
151struct scsi_low_statics {
152	int nexus_win;
153	int nexus_fail;
154	int nexus_disconnected;
155	int nexus_reselected;
156	int nexus_conflict;
157} scsi_low_statics;
158#endif	/* SCSI_LOW_STATICS */
159/**************************************************************
160 * power control
161 **************************************************************/
162static void
163scsi_low_engage(arg)
164	void *arg;
165{
166	struct scsi_low_softc *slp = arg;
167	int s = splbio();
168
169	switch (slp->sl_rstep)
170	{
171	case 0:
172		slp->sl_rstep ++;
173		(*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
174#ifdef __FreeBSD__
175		slp->engage_ch =
176#endif
177		timeout(scsi_low_engage, slp, 1);
178		break;
179
180	case 1:
181		slp->sl_rstep ++;
182		slp->sl_flags &= ~HW_RESUME;
183		scsi_low_start(slp);
184		break;
185
186	case 2:
187		break;
188	}
189	splx(s);
190}
191
192static int
193scsi_low_init(slp, flags)
194	struct scsi_low_softc *slp;
195	u_int flags;
196{
197
198	if ((slp->sl_flags & HW_POWERCTRL) != 0)
199	{
200#ifdef __FreeBSD__
201		untimeout(scsi_low_engage, slp, slp->engage_ch);
202#else /* NetBSD */
203		untimeout(scsi_low_engage, slp);
204#endif
205		slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
206		slp->sl_active = 1;
207		slp->sl_powc = SCSI_LOW_POWDOWN_TC;
208	}
209
210	/* reset current nexus */
211	scsi_low_reset_nexus(slp, flags);
212	if ((slp->sl_flags & HW_INACTIVE) != 0)
213		return EBUSY;
214
215	if (flags == SCSI_LOW_RESTART_SOFT)
216		return 0;
217
218	return ((*slp->sl_funcs->scsi_low_init) (slp, flags));
219}
220
221/**************************************************************
222 * allocate lun_info
223 **************************************************************/
224static struct lun_info *
225scsi_low_alloc_li(ti, lun, alloc)
226	struct targ_info *ti;
227	int lun;
228	int alloc;
229{
230	struct scsi_low_softc *slp = ti->ti_sc;
231	struct lun_info *li;
232
233	li = LIST_FIRST(&ti->ti_litab);
234	if (li != NULL)
235	{
236		if (li->li_lun == lun)
237			return li;
238
239		while ((li = LIST_NEXT(li, lun_chain)) != NULL)
240		{
241			if (li->li_lun == lun)
242			{
243				LIST_REMOVE(li, lun_chain);
244				LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
245				return li;
246			}
247		}
248	}
249
250	if (alloc == 0)
251		return li;
252
253	li = malloc(ti->ti_lunsize, M_DEVBUF, M_NOWAIT);
254	if (li == NULL)
255		panic("no lun info mem\n");
256
257	memset(li, 0, ti->ti_lunsize);
258	li->li_lun = lun;
259	li->li_ti = ti;
260#if	defined(SDEV_NOPARITY) && defined(SDEV_NODISC)
261	li->li_quirks = SDEV_NOPARITY | SDEV_NODISC;
262#endif	/* SDEV_NOPARITY && SDEV_NODISC */
263	li->li_cfgflags = 0xffff0000 | SCSI_LOW_SYNC;
264
265	LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
266
267	/* host specific structure initialization per lun */
268	(void) ((*slp->sl_funcs->scsi_low_lun_init) (slp, ti, li));
269
270	return li;
271}
272
273/**************************************************************
274 * allocate targ_info
275 **************************************************************/
276static struct targ_info *
277scsi_low_alloc_ti(slp, targ)
278	struct scsi_low_softc *slp;
279	int targ;
280{
281	struct targ_info *ti;
282
283	if (slp->sl_titab.tqh_first == NULL)
284		TAILQ_INIT(&slp->sl_titab);
285
286	ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_NOWAIT);
287	if (ti == NULL)
288		panic("%s short of memory\n", slp->sl_xname);
289
290	memset(ti, 0, sizeof(struct targ_info));
291	ti->ti_id = targ;
292	ti->ti_sc = slp;
293
294	slp->sl_ti[targ] = ti;
295	TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
296	TAILQ_INIT(&ti->ti_discq);
297	LIST_INIT(&ti->ti_litab);
298
299	return ti;
300}
301
302static void
303scsi_low_free_ti(slp)
304	struct scsi_low_softc *slp;
305{
306	struct targ_info *ti, *tib;
307	struct lun_info *li, *nli;
308
309	for (ti = slp->sl_titab.tqh_first; ti; ti = tib)
310	{
311		tib = ti->ti_chain.tqe_next;
312		for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
313		{
314			nli = LIST_NEXT(li, lun_chain);
315			free(li, M_DEVBUF);
316		}
317		free(ti, M_DEVBUF);
318	}
319}
320
321/**************************************************************
322 * timeout
323 **************************************************************/
324void
325scsi_low_timeout(arg)
326	void *arg;
327{
328	struct scsi_low_softc *slp = arg;
329	struct targ_info *ti;
330	struct slccb *cb = NULL;		/* XXX */
331	int s = splbio();
332
333	/* check */
334	if ((ti = slp->sl_nexus) != NULL && (cb = ti->ti_nexus) != NULL)
335	{
336		cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
337		if (cb->ccb_tc < 0)
338			goto bus_reset;
339	}
340	else if (slp->sl_disc > 0)
341	{
342		struct targ_info *ti;
343
344		for (ti = slp->sl_titab.tqh_first; ti != NULL;
345		     ti = ti->ti_chain.tqe_next)
346		{
347			for (cb = ti->ti_discq.tqh_first; cb != NULL;
348			     cb = cb->ccb_chain.tqe_next)
349			{
350				cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
351				if (cb->ccb_tc < 0)
352					goto bus_reset;
353			}
354		}
355	}
356	else
357	{
358		cb = slp->sl_start.tqh_first;
359		if (cb != NULL)
360		{
361			cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
362			if (cb->ccb_tc < 0)
363				goto bus_reset;
364		}
365		else if ((slp->sl_flags & HW_POWERCTRL) != 0)
366		{
367			if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
368				goto out;
369
370			if (slp->sl_active != 0)
371			{
372				slp->sl_powc = SCSI_LOW_POWDOWN_TC;
373				slp->sl_active = 0;
374				goto out;
375			}
376
377			slp->sl_powc --;
378			if (slp->sl_powc < 0)
379			{
380				slp->sl_powc = SCSI_LOW_POWDOWN_TC;
381				slp->sl_flags |= HW_POWDOWN;
382				(*slp->sl_funcs->scsi_low_power)
383						(slp, SCSI_LOW_POWDOWN);
384			}
385		}
386	}
387
388out:
389#ifdef __FreeBSD__
390	slp->timeout_ch =
391#endif
392	timeout(scsi_low_timeout, slp, SCSI_LOW_TIMEOUT_CHECK_INTERVAL * hz);
393
394	splx(s);
395	return;
396
397bus_reset:
398	cb->ccb_error |= TIMEOUTIO;
399	scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
400	scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
401	scsi_low_start(slp);
402#ifdef __FreeBSD__
403	slp->timeout_ch =
404#endif
405	timeout(scsi_low_timeout, slp, SCSI_LOW_TIMEOUT_CHECK_INTERVAL * hz);
406
407	splx(s);
408}
409
410/**************************************************************
411 * CCB
412 **************************************************************/
413GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
414GENERIC_CCB(scsi_low, slccb, ccb_chain)
415
416/**************************************************************
417 * SCSI INTERFACE (XS)
418 **************************************************************/
419#define	SCSI_LOW_MINPHYS	0x10000
420
421#ifdef __NetBSD__
422struct scsipi_device scsi_low_dev = {
423	NULL,	/* Use default error handler */
424	NULL,	/* have a queue, served by this */
425	NULL,	/* have no async handler */
426	NULL,	/* Use default 'done' routine */
427};
428#endif
429
430#ifdef CAM
431static void
432scsi_low_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
433{
434	xpt_free_path(ccb->ccb_h.path);
435	free(ccb, M_DEVBUF);
436#if defined(__FreeBSD__) && __FreeBSD_version < 400001
437	free(periph, M_DEVBUF);
438#endif
439}
440
441static void
442scsi_low_rescan_bus(struct scsi_low_softc *slp)
443{
444  	struct cam_path *path;
445	union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK);
446#if defined(__FreeBSD__) && __FreeBSD_version < 400001
447	struct cam_periph *xpt_periph = malloc(sizeof(struct cam_periph),
448					       M_DEVBUF, M_WAITOK);
449#endif
450	cam_status status;
451
452	bzero(ccb, sizeof(union ccb));
453
454	status = xpt_create_path(&path, xpt_periph,
455				 cam_sim_path(slp->sim), -1, 0);
456	if (status != CAM_REQ_CMP)
457		return;
458
459	xpt_setup_ccb(&ccb->ccb_h, path, 5);
460	ccb->ccb_h.func_code = XPT_SCAN_BUS;
461	ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
462	ccb->crcn.flags = CAM_FLAG_NONE;
463	xpt_action(ccb);
464}
465#endif
466
467int
468scsi_low_attach(slp, openings, ntargs, nluns, lunsize)
469	struct scsi_low_softc *slp;
470	int openings, ntargs, nluns, lunsize;
471{
472	struct targ_info *ti;
473	struct lun_info *li;
474#ifdef CAM
475	struct cam_devq *devq;
476#else
477	struct scsipi_adapter *sap;
478#endif
479	int i, nccb;
480
481#ifdef CAM
482	OS_DEPEND(sprintf(slp->sl_xname, "%s%d",
483			  DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev)));
484#else
485	OS_DEPEND(strncpy(slp->sl_xname, DEVPORT_DEVNAME(slp->sl_dev), 16));
486#endif
487	if (ntargs > SCSI_LOW_NTARGETS)
488	{
489		printf("scsi_low: %d targets are too large\n", ntargs);
490		printf("change kernel options SCSI_LOW_NTARGETS");
491	}
492
493	if (lunsize < sizeof(struct lun_info))
494		lunsize = sizeof(struct lun_info);
495
496	for (i = 0; i < ntargs; i ++)
497	{
498		ti = scsi_low_alloc_ti(slp, i);
499		ti->ti_lunsize = lunsize;
500		li = scsi_low_alloc_li(ti, 0, 1);
501	}
502
503#ifndef CAM
504	sap = malloc(sizeof(*sap), M_DEVBUF, M_NOWAIT);
505	if (sap == NULL)
506		return ENOMEM;
507
508	memset(sap, 0, sizeof(*sap));
509	sap->scsipi_cmd = scsi_low_scsi_cmd;
510	sap->scsipi_minphys = scsi_low_scsi_minphys;
511#ifdef	SCSI_LOW_TARGET_OPEN
512	sap->open_target_lu = scsi_low_target_open;
513#endif	/* SCSI_LOW_TARGET_OPEN */
514#endif
515
516	if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
517		return EINVAL;
518
519	/* initialize queue */
520	nccb = openings * (ntargs - 1);
521	if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
522		nccb = SCSI_LOW_NCCB;
523	scsi_low_init_ccbque(nccb);
524	TAILQ_INIT(&slp->sl_start);
525
526	slp->sl_openings = openings;
527	slp->sl_ntargs = ntargs;
528	slp->sl_nluns = nluns;
529
530#ifdef CAM
531	/*
532	 * Prepare the scsibus_data area for the upperlevel
533	 * scsi code.
534	 */
535	devq = cam_simq_alloc(256/*MAX_START*/);
536	if (devq == NULL)
537		return (0);
538	/*	scbus->adapter_link = &slp->sc_link; */
539	/*
540	 * ask the adapter what subunits are present
541	 */
542
543	slp->sim = cam_sim_alloc(scsi_low_scsi_action, scsi_low_poll,
544				 DEVPORT_DEVNAME(slp->sl_dev), slp,
545				 DEVPORT_DEVUNIT(slp->sl_dev), 1, 32/*MAX_TAGS*/, devq);
546       if (slp->sim == NULL) {
547	 cam_simq_free(devq);
548	 return 0;
549       }
550
551       if (xpt_bus_register(slp->sim, 0) != CAM_SUCCESS) {
552	 free(slp->sim, M_DEVBUF);
553	 return 0;
554       }
555
556       if (xpt_create_path(&slp->path, /*periph*/NULL,
557                           cam_sim_path(slp->sim), CAM_TARGET_WILDCARD,
558			   CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
559	 xpt_bus_deregister(cam_sim_path(slp->sim));
560	 cam_sim_free(slp->sim, /*free_simq*/TRUE);
561	 free(slp->sim, M_DEVBUF);
562	 return 0;
563       }
564#else /* !CAM */
565	slp->sl_link.adapter_softc = slp;
566	slp->sl_link.scsipi_scsi.adapter_target = slp->sl_hostid;
567	slp->sl_link.scsipi_scsi.max_target = ntargs - 1;
568	slp->sl_link.scsipi_scsi.max_lun = nluns - 1;
569	slp->sl_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
570	slp->sl_link.openings = openings;
571	slp->sl_link.type = BUS_SCSI;
572	slp->sl_link.adapter_softc = slp;
573	slp->sl_link.adapter = sap;
574	slp->sl_link.device = &scsi_low_dev;
575#endif
576
577	/* start watch dog */
578	slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
579#ifdef __FreeBSD__
580	slp->timeout_ch =
581#endif
582	timeout(scsi_low_timeout, slp, SCSI_LOW_TIMEOUT_CHECK_INTERVAL * hz);
583#ifdef CAM
584	if (!cold)
585		scsi_low_rescan_bus(slp);
586#endif
587
588	return 0;
589}
590
591#ifndef CAM
592static void
593scsi_low_scsi_minphys(bp)
594	struct buf *bp;
595{
596
597	if (bp->b_bcount > SCSI_LOW_MINPHYS)
598		bp->b_bcount = SCSI_LOW_MINPHYS;
599	minphys(bp);
600}
601#endif
602
603int
604scsi_low_dettach(slp)
605	struct scsi_low_softc *slp;
606{
607
608	if (slp->sl_disc > 0 || slp->sl_start.tqh_first != NULL)
609		return EBUSY;
610
611	/*
612	 * scsipi does not have dettach bus fucntion.
613	 *
614	scsipi_dettach_scsibus(&slp->sl_link);
615	*/
616
617#ifdef CAM
618	xpt_async(AC_LOST_DEVICE, slp->path, NULL);
619	xpt_free_path(slp->path);
620	xpt_bus_deregister(cam_sim_path(slp->sim));
621	cam_sim_free(slp->sim, /* free_devq */ TRUE);
622#endif
623
624	scsi_low_free_ti(slp);
625	return 0;
626}
627
628#ifdef CAM
629static void
630scsi_low_poll(struct cam_sim *sim)
631{
632	struct scsi_low_softc *slp = (struct scsi_low_softc *) cam_sim_softc(sim);
633	(*slp->sl_funcs->scsi_low_poll) (slp);
634}
635
636void
637scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb)
638{
639	struct scsi_low_softc *slp = (struct scsi_low_softc *) cam_sim_softc(sim);
640	int s, target = (u_int) (ccb->ccb_h.target_id);
641	struct targ_info *ti;
642	struct lun_info *li;
643	struct slccb *cb;
644
645#if 0
646	printf("scsi_low_scsi_action() func code %d Target: %d, LUN: %d\n",
647	       ccb->ccb_h.func_code, target, ccb->ccb_h.target_lun);
648#endif
649	switch (ccb->ccb_h.func_code) {
650	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
651		if (((cb = scsi_low_get_ccb()) == NULL)) {
652			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
653			xpt_done(ccb);
654			return;
655		}
656
657		cb->ccb = ccb;
658		cb->ccb_tag = SCSI_LOW_UNKTAG;
659		cb->bp = (struct buf *)NULL;
660		cb->ti = ti = slp->sl_ti[target];
661		cb->li = scsi_low_alloc_li(ti, ccb->ccb_h.target_lun, 1);
662		cb->ccb_flags = 0;
663		cb->ccb_rcnt = 0;
664
665		s = splcam();
666
667		TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
668
669		if (slp->sl_nexus == NULL) {
670			scsi_low_start(slp);
671		}
672
673		splx(s);
674		break;
675	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
676	case XPT_EN_LUN:		/* Enable LUN as a target */
677	case XPT_TARGET_IO:		/* Execute target I/O request */
678	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
679	case XPT_CONT_TARGET_IO:	/* Continue Host Target I/O Connection*/
680	case XPT_ABORT:			/* Abort the specified CCB */
681		/* XXX Implement */
682		ccb->ccb_h.status = CAM_REQ_INVALID;
683		xpt_done(ccb);
684		break;
685	case XPT_SET_TRAN_SETTINGS:
686		/* XXX Implement */
687		ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
688		xpt_done(ccb);
689		break;
690	case XPT_GET_TRAN_SETTINGS: {
691		struct ccb_trans_settings *cts;
692		struct targ_info *ti;
693		int lun = ccb->ccb_h.target_lun;
694		/*int s;*/
695
696		cts = &ccb->cts;
697		ti = slp->sl_ti[ccb->ccb_h.target_id];
698		li = LIST_FIRST(&ti->ti_litab);
699		if (li != NULL && li->li_lun != lun)
700			while ((li = LIST_NEXT(li, lun_chain)) != NULL)
701				if (li->li_lun == lun)
702					break;
703		s = splcam();
704		if (li != NULL && (cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
705			if (li->li_cfgflags & SCSI_LOW_DISC)
706				cts->flags = CCB_TRANS_DISC_ENB;
707			else
708				cts->flags = 0;
709			if (li->li_cfgflags & SCSI_LOW_QTAG)
710				cts->flags |= CCB_TRANS_TAG_ENB;
711
712			cts->bus_width = 0;/*HN2*/
713
714			cts->valid = CCB_TRANS_SYNC_RATE_VALID
715				   | CCB_TRANS_SYNC_OFFSET_VALID
716				   | CCB_TRANS_BUS_WIDTH_VALID
717				   | CCB_TRANS_DISC_VALID
718				   | CCB_TRANS_TQ_VALID;
719			ccb->ccb_h.status = CAM_REQ_CMP;
720		} else
721			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
722
723		splx(s);
724		xpt_done(ccb);
725		break;
726	}
727	case XPT_CALC_GEOMETRY: { /* not yet HN2 */
728		struct	  ccb_calc_geometry *ccg;
729		u_int32_t size_mb;
730		u_int32_t secs_per_cylinder;
731		int       extended;
732
733		extended = 1;
734		ccg = &ccb->ccg;
735		size_mb = ccg->volume_size
736			/ ((1024L * 1024L) / ccg->block_size);
737
738		if (size_mb > 1024 && extended) {
739		        ccg->heads = 255;
740		        ccg->secs_per_track = 63;
741		} else {
742		        ccg->heads = 64;
743		        ccg->secs_per_track = 32;
744		}
745		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
746		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
747		ccb->ccb_h.status = CAM_REQ_CMP;
748		xpt_done(ccb);
749		break;
750	}
751	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
752#if 0
753	  	scsi_low_bus_reset(slp);
754#endif
755		ccb->ccb_h.status = CAM_REQ_CMP;
756		xpt_done(ccb);
757		break;
758	case XPT_TERM_IO:		/* Terminate the I/O process */
759		/* XXX Implement */
760		ccb->ccb_h.status = CAM_REQ_INVALID;
761		xpt_done(ccb);
762		break;
763	case XPT_PATH_INQ: {		/* Path routing inquiry */
764		struct ccb_pathinq *cpi = &ccb->cpi;
765
766		cpi->version_num = 1; /* XXX??? */
767		cpi->hba_inquiry = PI_SDTR_ABLE;
768		cpi->target_sprt = 0;
769		cpi->hba_misc = 0;
770		cpi->hba_eng_cnt = 0;
771		cpi->max_target = SCSI_LOW_NTARGETS - 1;
772		cpi->max_lun = 7;
773		cpi->initiator_id = 7; /* HOST_SCSI_ID */
774		cpi->bus_id = cam_sim_bus(sim);
775		cpi->base_transfer_speed = 3300;
776		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
777		strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
778		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
779		cpi->unit_number = cam_sim_unit(sim);
780		cpi->ccb_h.status = CAM_REQ_CMP;
781		xpt_done(ccb);
782		break;
783	}
784	default:
785	        printf("scsi_low: non support func_code = %d ", ccb->ccb_h.func_code);
786		ccb->ccb_h.status = CAM_REQ_INVALID;
787		xpt_done(ccb);
788		break;
789	}
790}
791#else /* !CAM */
792static int
793scsi_low_scsi_cmd(xs)
794	struct scsipi_xfer *xs;
795{
796	struct scsi_low_softc *slp = xs->sc_link->adapter_softc;
797	struct targ_info *ti;
798	struct slccb *cb;
799	int s, lun, timeo;
800
801	if (slp->sl_cfgflags & CFG_NOATTEN)
802	{
803		if (xs->sc_link->scsipi_scsi.lun > 0)
804		{
805			xs->error = XS_DRIVER_STUFFUP;
806			return COMPLETE;
807		}
808	}
809
810	if ((cb = scsi_low_get_ccb(xs->flags & SCSI_NOSLEEP)) == NULL)
811		return TRY_AGAIN_LATER;
812
813	lun = xs->sc_link->scsipi_scsi.lun;
814	cb->xs = xs;
815	cb->ccb_tag = SCSI_LOW_UNKTAG;
816	cb->ti = ti = slp->sl_ti[xs->sc_link->scsipi_scsi.target];
817	cb->li = scsi_low_alloc_li(ti, lun, 1);
818	cb->ccb_flags = 0;
819	cb->ccb_rcnt = 0;
820
821	s = splbio();
822
823	TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
824	if (slp->sl_nexus == NULL)
825		scsi_low_start(slp);
826
827	if ((xs->flags & SCSI_POLL) == 0)
828	{
829		splx(s);
830		return SUCCESSFULLY_QUEUED;
831	}
832
833#define	SCSI_LOW_POLL_INTERVAL	1000		/* 1 ms */
834	timeo = xs->timeout * (1000 / SCSI_LOW_POLL_INTERVAL);
835
836	while ((xs->flags & ITSDONE) == 0 && timeo -- > 0)
837	{
838		delay(SCSI_LOW_POLL_INTERVAL);
839		(*slp->sl_funcs->scsi_low_poll) (slp);
840	}
841
842	if ((xs->flags & ITSDONE) == 0)
843	{
844		cb->ccb_error |= (TIMEOUTIO | ABORTIO);
845		SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
846		scsi_low_disconnected(slp, ti);
847		scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
848	}
849
850	scsipi_done(xs);
851	splx(s);
852	return COMPLETE;
853}
854#endif
855
856/**************************************************************
857 * Start & Done
858 **************************************************************/
859#ifdef __NetBSD__
860static struct scsipi_start_stop ss_cmd = { START_STOP, 0, {0,0,}, SSS_START, };
861static struct scsipi_test_unit_ready unit_ready_cmd;
862#endif
863#ifdef __FreeBSD__
864static struct scsi_start_stop_unit ss_cmd = { START_STOP, 0, {0,0,}, SSS_START, };
865static struct scsi_test_unit_ready unit_ready_cmd;
866#endif
867static void scsi_low_unit_ready_cmd __P((struct slccb *));
868
869static void
870scsi_low_unit_ready_cmd(cb)
871	struct slccb *cb;
872{
873
874	cb->ccb_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
875	cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
876	cb->ccb_scp.scp_datalen = 0;
877	cb->ccb_scp.scp_direction = SCSI_LOW_READ;
878	cb->ccb_tcmax = 15;
879}
880
881static void
882scsi_low_start(slp)
883	struct scsi_low_softc *slp;
884{
885#ifdef CAM
886        union ccb *ccb;
887#else
888	struct scsipi_xfer *xs;
889#endif
890	struct targ_info *ti;
891	struct lun_info *li;
892	struct slccb *cb;
893	int rv;
894
895	/* check hardware exists ? */
896	if ((slp->sl_flags & HW_INACTIVE) != 0)
897		return;
898
899	/* check hardware power up ? */
900	if ((slp->sl_flags & HW_POWERCTRL) != 0)
901	{
902		slp->sl_active ++;
903		if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
904		{
905			if (slp->sl_flags & HW_RESUME)
906				return;
907			slp->sl_flags &= ~HW_POWDOWN;
908			if (slp->sl_funcs->scsi_low_power != NULL)
909			{
910				slp->sl_flags |= HW_RESUME;
911				slp->sl_rstep = 0;
912				(*slp->sl_funcs->scsi_low_power)
913					(slp, SCSI_LOW_ENGAGE);
914#ifdef __FreeBSD__
915				slp->engage_ch =
916#endif
917				timeout(scsi_low_engage, slp, 1);
918				return;
919			}
920		}
921	}
922
923	/* setup nexus */
924#ifdef	SCSI_LOW_DIAGNOSTIC
925	ti = slp->sl_nexus;
926	if (ti != NULL)
927	{
928		scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
929		panic("%s: inconsistent(target)\n", slp->sl_xname);
930	}
931#endif	/* SCSI_LOW_DIAGNOSTIC */
932
933	for (cb = slp->sl_start.tqh_first; cb != NULL;
934	     cb = cb->ccb_chain.tqe_next)
935	{
936		ti = cb->ti;
937		li = cb->li;
938		if (ti->ti_phase == PH_NULL)
939			goto scsi_low_cmd_start;
940		if (ti->ti_phase == PH_DISC && li->li_disc < li->li_maxnexus)
941			goto scsi_low_cmd_start;
942	}
943	return;
944
945scsi_low_cmd_start:
946#ifdef CAM
947	ccb = cb->ccb;
948#else
949	xs = cb->xs;
950#endif
951#ifdef	SCSI_LOW_DIAGNOSTIC
952	if (ti->ti_nexus != NULL || ti->ti_li != NULL)
953	{
954		scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
955		panic("%s: inconsistent(lun or ccb)\n", slp->sl_xname);
956	}
957#endif	/* SCSI_LOW_DIAGNOSTIC */
958
959	/* clear all error flag bits (for restart) */
960	cb->ccb_error = 0;
961
962	/* setup nexus pointer */
963	ti->ti_nexus = cb;
964	ti->ti_li = li;
965	slp->sl_nexus = ti;
966
967	/* initialize msgsys */
968	scsi_low_init_msgsys(slp, ti);
969
970	/* target lun state check */
971#ifdef CAM
972		li->li_maxstate = UNIT_OK;
973#else
974	if ((xs->flags & SCSI_POLL) != 0)
975		li->li_maxstate = UNIT_NEGSTART;
976	else
977		li->li_maxstate = UNIT_OK;
978#endif
979
980	/* exec cmds */
981scsi_low_cmd_exec:
982	if ((cb->ccb_flags & CCB_SENSE) != 0)
983	{
984		memset(&cb->ccb_sense, 0, sizeof(cb->ccb_sense));
985#ifdef CAM
986#else
987		cb->ccb_sense_cmd.opcode = REQUEST_SENSE;
988		cb->ccb_sense_cmd.byte2 = (li->li_lun << 5);
989		cb->ccb_sense_cmd.length = sizeof(cb->ccb_sense);
990#endif
991		cb->ccb_scp.scp_cmd = (u_int8_t *) &cb->ccb_sense_cmd;
992		cb->ccb_scp.scp_cmdlen = sizeof(cb->ccb_sense_cmd);
993		cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
994		cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
995		cb->ccb_scp.scp_direction = SCSI_LOW_READ;
996		cb->ccb_tcmax = 15;
997	}
998	else if (li->li_state >= li->li_maxstate)
999	{
1000#ifdef CAM
1001		cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1002		cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1003		cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1004		cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1005		if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1006			cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1007		else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1008			cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1009		cb->ccb_tcmax = (ccb->ccb_h.timeout >> 10);
1010#else
1011		cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
1012		cb->ccb_scp.scp_cmdlen = xs->cmdlen;
1013		cb->ccb_scp.scp_data = xs->data;
1014		cb->ccb_scp.scp_datalen = xs->datalen;
1015		cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
1016				SCSI_LOW_WRITE : SCSI_LOW_READ;
1017		cb->ccb_tcmax = (xs->timeout >> 10);
1018#endif
1019
1020	}
1021	else switch(li->li_state)
1022	{
1023	case UNIT_SLEEP:
1024		scsi_low_unit_ready_cmd(cb);
1025		break;
1026
1027	case UNIT_START:
1028		cb->ccb_scp.scp_cmd = (u_int8_t *) &ss_cmd;
1029		cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1030		cb->ccb_scp.scp_datalen = 0;
1031		cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1032		cb->ccb_tcmax = 30;
1033		break;
1034
1035	case UNIT_SYNCH:
1036		if (li->li_maxsynch.offset > 0)
1037		{
1038			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
1039			scsi_low_unit_ready_cmd(cb);
1040			break;
1041		}
1042		li->li_state = UNIT_WIDE;
1043
1044	case UNIT_WIDE:
1045#ifdef	SCSI_LOW_SUPPORT_WIDE
1046		if (li->li_width > 0)
1047		{
1048			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
1049			scsi_low_unit_ready_cmd(cb);
1050			break;
1051		}
1052#endif	/* SCSI_LOW_SUPPORT_WIDE */
1053		li->li_state = UNIT_OK;
1054
1055	case UNIT_OK:
1056		goto scsi_low_cmd_exec;
1057	}
1058
1059	/* timeout */
1060	if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1061		cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1062	cb->ccb_tc = cb->ccb_tcmax;
1063
1064	/* setup saved scsi data pointer */
1065	cb->ccb_sscp = cb->ccb_scp;
1066
1067	/* setup current scsi pointer */
1068	slp->sl_scp = cb->ccb_sscp;
1069	slp->sl_error = cb->ccb_error;
1070
1071	/* selection start */
1072	slp->sl_selid = ti;
1073	rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1074	if (rv == SCSI_LOW_START_OK)
1075	{
1076#ifdef	SCSI_LOW_STATICS
1077		scsi_low_statics.nexus_win ++;
1078#endif	/* SCSI_LOW_STATICS */
1079		return;
1080	}
1081
1082#ifdef	SCSI_LOW_STATICS
1083	scsi_low_statics.nexus_fail ++;
1084#endif	/* SCSI_LOW_STATICS */
1085	SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1086	scsi_low_clear_nexus(slp, ti);
1087}
1088
1089void
1090scsi_low_clear_nexus(slp, ti)
1091	struct scsi_low_softc *slp;
1092	struct targ_info *ti;
1093{
1094
1095	/* clear all nexus pointer */
1096	ti->ti_nexus = NULL;
1097	ti->ti_li = NULL;
1098	slp->sl_nexus = NULL;
1099
1100	/* clear selection assert */
1101	slp->sl_selid = NULL;
1102
1103	/* clear nexus data */
1104	slp->sl_nexus_call = 0;
1105	slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
1106}
1107
1108static int
1109scsi_low_done(slp, cb)
1110	struct scsi_low_softc *slp;
1111	struct slccb *cb;
1112{
1113#ifdef CAM
1114	union ccb *ccb;
1115#else
1116	struct scsipi_xfer *xs;
1117#endif
1118	struct targ_info *ti;
1119	struct lun_info *li;
1120
1121	ti = cb->ti;
1122	li = cb->li;
1123#ifdef CAM
1124	ccb = cb->ccb;
1125#else
1126	xs = cb->xs;
1127#endif
1128	if (cb->ccb_error == 0)
1129	{
1130		if ((cb->ccb_flags & CCB_SENSE) != 0)
1131		{
1132			cb->ccb_flags &= ~CCB_SENSE;
1133#ifdef CAM
1134			ccb->csio.sense_data = cb->ccb_sense;
1135			/* ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; */
1136			ccb->ccb_h.status = CAM_REQ_CMP;
1137			/* ccb->ccb_h.status = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR; */
1138#else
1139			xs->sense.scsi_sense = cb->ccb_sense;
1140			xs->error = XS_SENSE;
1141#endif
1142		}
1143		else switch (ti->ti_status)
1144		{
1145		case ST_GOOD:
1146			if (slp->sl_scp.scp_datalen == 0)
1147			{
1148#ifdef CAM
1149				ccb->ccb_h.status = CAM_REQ_CMP;
1150#else
1151				xs->error = XS_NOERROR;
1152#endif
1153				break;
1154			}
1155
1156#define	SCSIPI_SCSI_CD_COMPLETELY_BUGGY	"YES"
1157#ifdef	SCSIPI_SCSI_CD_COMPLETELY_BUGGY
1158#ifdef CAM
1159			if (/* cb->bp == NULL &&  */
1160			    slp->sl_scp.scp_datalen < cb->ccb_scp.scp_datalen)
1161#else
1162			if (xs->bp == NULL &&
1163			    slp->sl_scp.scp_datalen < cb->ccb_scp.scp_datalen)
1164#endif
1165			{
1166#ifdef CAM
1167				ccb->ccb_h.status = CAM_REQ_CMP;
1168#else
1169				xs->error = XS_NOERROR;
1170#endif
1171				break;
1172			}
1173#endif	/* SCSIPI_SCSI_CD_COMPLETELY_BUGGY */
1174
1175			cb->ccb_error |= PDMAERR;
1176#ifdef CAM
1177			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1178#else
1179			xs->error = XS_DRIVER_STUFFUP;
1180#endif
1181			break;
1182
1183		case ST_CHKCOND:
1184		case ST_MET:
1185			cb->ccb_flags |= CCB_SENSE;
1186#ifdef CAM
1187			ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
1188#else
1189			xs->error = XS_SENSE;
1190#endif
1191			goto retry;
1192
1193		case ST_BUSY:
1194			cb->ccb_error |= BUSYERR;
1195#ifdef CAM
1196			ccb->ccb_h.status = CAM_BUSY; /* SCSI_STATUS_ERROR; */
1197#else
1198			xs->error = XS_BUSY;
1199#endif
1200			break;
1201
1202		default:
1203			cb->ccb_error |= FATALIO;
1204#ifdef CAM
1205			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1206#else
1207			xs->error = XS_DRIVER_STUFFUP;
1208#endif
1209			break;
1210		}
1211	}
1212	else
1213	{
1214		cb->ccb_flags &= ~CCB_SENSE;
1215		if (ti->ti_phase == PH_SELSTART)
1216		{
1217#ifdef CAM
1218			ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1219#else
1220			xs->error = XS_TIMEOUT;
1221#endif
1222			slp->sl_error |= SELTIMEOUTIO;
1223			if (li->li_state == UNIT_SLEEP)
1224				cb->ccb_error |= ABORTIO;
1225		}
1226		else
1227		{
1228#ifdef CAM
1229			ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1230#else
1231			xs->error = XS_DRIVER_STUFFUP;
1232#endif
1233		}
1234
1235		if ((cb->ccb_error & ABORTIO) != 0)
1236		{
1237			cb->ccb_rcnt = slp->sl_max_retry;
1238#ifdef CAM
1239			ccb->ccb_h.status = CAM_REQ_ABORTED;
1240#endif
1241		}
1242	}
1243
1244	/* target state check */
1245	if (li->li_state < li->li_maxstate)
1246	{
1247		if (cb->ccb_rcnt < slp->sl_max_retry)
1248		{
1249			li->li_state ++;
1250			cb->ccb_rcnt = 0;
1251			goto retry;
1252		}
1253	}
1254
1255	/* internal retry check */
1256#ifdef CAM
1257	if (ccb->ccb_h.status == CAM_REQ_CMP)
1258	{
1259		ccb->csio.resid = 0;
1260	}
1261	else
1262	{
1263#if 0
1264		if (ccb->ccb_h.status != CAM_AUTOSENSE_FAIL &&
1265		    cb->ccb_rcnt < slp->sl_max_retry)
1266			goto retry;
1267#endif
1268#else
1269	if (xs->error == XS_NOERROR)
1270	{
1271		xs->resid = 0;
1272	}
1273	else
1274	{
1275		if (xs->error != XS_SENSE &&
1276		    cb->ccb_rcnt < slp->sl_max_retry)
1277			goto retry;
1278#endif
1279
1280#ifndef CAM
1281#ifdef SCSI_LOW_WARNINGS
1282		if (xs->bp != NULL)
1283		{
1284			scsi_low_print(slp, ti);
1285			printf("%s: WARNING: File system IO abort\n",
1286				slp->sl_xname);
1287		}
1288#endif	/* SCSI_LOW_WARNINGS */
1289#endif
1290	}
1291
1292#ifdef CAM
1293	ccb->csio.scsi_status = ti->ti_status;
1294	xpt_done(ccb);
1295#else
1296	xs->flags |= ITSDONE;
1297	if ((xs->flags & SCSI_POLL) == 0)
1298		scsipi_done(xs);
1299#endif
1300
1301	/* free our target */
1302	TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1303	scsi_low_free_ccb(cb);
1304	return SCSI_LOW_DONE_COMPLETE;
1305
1306retry:
1307	cb->ccb_rcnt ++;
1308	if (slp->sl_start.tqh_first != cb)
1309	{
1310		TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1311		TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1312	}
1313	return SCSI_LOW_DONE_RETRY;
1314}
1315
1316/**************************************************************
1317 * Reset
1318 **************************************************************/
1319static void
1320scsi_low_clear_ccb(cb)
1321	struct slccb *cb;
1322{
1323
1324	cb->ccb_flags &= ~CCB_SENSE;
1325	cb->ccb_tag = SCSI_LOW_UNKTAG;
1326}
1327
1328static void
1329scsi_low_reset_nexus(slp, fdone)
1330	struct scsi_low_softc *slp;
1331	int fdone;
1332{
1333	struct targ_info *ti;
1334	struct lun_info *li;
1335	struct slccb *cb, *ncb;
1336
1337	/* current nexus */
1338	ti = slp->sl_nexus;
1339	if (ti != NULL && (cb = ti->ti_nexus) != NULL)
1340	{
1341		scsi_low_clear_ccb(cb);
1342		if (fdone != 0 && cb->ccb_rcnt ++ >= slp->sl_max_retry)
1343		{
1344			cb->ccb_error |= FATALIO;
1345			scsi_low_done(slp, cb);
1346		}
1347	}
1348
1349	/* disconnected nexus */
1350	for (ti = slp->sl_titab.tqh_first; ti != NULL;
1351	     ti = ti->ti_chain.tqe_next)
1352	{
1353		for (cb = ti->ti_discq.tqh_first; cb != NULL; cb = ncb)
1354		{
1355		     	ncb = cb->ccb_chain.tqe_next;
1356			TAILQ_REMOVE(&ti->ti_discq, cb, ccb_chain);
1357			TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1358			scsi_low_clear_ccb(cb);
1359			if (fdone != 0 && cb->ccb_rcnt ++ >= slp->sl_max_retry)
1360			{
1361				cb->ccb_error |= FATALIO;
1362				scsi_low_done(slp, cb);
1363			}
1364		}
1365
1366		for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1367		     li = LIST_NEXT(li, lun_chain))
1368		{
1369			li->li_state = UNIT_SLEEP;
1370			li->li_disc = 0;
1371			((*slp->sl_funcs->scsi_low_lun_init) (slp, ti, li));
1372			scsi_low_calcf(ti, li);
1373		}
1374
1375		scsi_low_init_msgsys(slp, ti);
1376		scsi_low_clear_nexus(slp, ti);
1377		SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1378	}
1379
1380	slp->sl_flags &= ~HW_PDMASTART;
1381	slp->sl_disc = 0;
1382}
1383
1384/* misc */
1385static int tw_pos;
1386static char tw_chars[] = "|/-\\";
1387
1388static void
1389scsi_low_twiddle_wait(void)
1390{
1391
1392	cnputc('\b');
1393	cnputc(tw_chars[tw_pos++]);
1394	tw_pos %= (sizeof(tw_chars) - 1);
1395	delay(TWIDDLEWAIT);
1396}
1397
1398void
1399scsi_low_bus_reset(slp)
1400	struct scsi_low_softc *slp;
1401{
1402	int i;
1403
1404	(*slp->sl_funcs->scsi_low_bus_reset) (slp);
1405
1406	printf("%s: try to reset scsi bus  ", slp->sl_xname);
1407	for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
1408		scsi_low_twiddle_wait();
1409	cnputc('\b');
1410	printf("\n");
1411}
1412
1413int
1414scsi_low_restart(slp, flags, s)
1415	struct scsi_low_softc *slp;
1416	int flags;
1417	u_char *s;
1418{
1419	int error;
1420
1421	if (s != NULL)
1422		printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
1423
1424	if ((error = scsi_low_init(slp, flags)) != 0)
1425		return error;
1426
1427	scsi_low_start(slp);
1428	return 0;
1429}
1430
1431/**************************************************************
1432 * disconnect and reselect
1433 **************************************************************/
1434#define	MSGCMD_LUN(msg)	(msg & 0x07)
1435
1436static struct lun_info *
1437scsi_low_establish_lun(ti, lun)
1438	struct targ_info *ti;
1439	int lun;
1440{
1441	struct lun_info *li;
1442
1443	li = scsi_low_alloc_li(ti, lun, 0);
1444	if (li == NULL)
1445		return li;
1446
1447	ti->ti_li = li;
1448	return li;
1449}
1450
1451static struct slccb *
1452scsi_low_establish_ccb(ti, li, tag)
1453	struct targ_info *ti;
1454	struct lun_info *li;
1455	scsi_low_tag_t tag;
1456{
1457	struct scsi_low_softc *slp = ti->ti_sc;
1458	struct slccb *cb;
1459
1460	/*
1461	 * Search ccb matching with lun and tag.
1462	 */
1463	cb = ti->ti_discq.tqh_first;
1464	for ( ; cb != NULL; cb = cb->ccb_chain.tqe_next)
1465		if (cb->li == li && cb->ccb_tag == tag)
1466			goto found;
1467	return cb;
1468
1469	/*
1470	 * establish our ccb nexus
1471	 */
1472found:
1473	TAILQ_REMOVE(&ti->ti_discq, cb, ccb_chain);
1474	TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1475	ti->ti_nexus = cb;
1476
1477	slp->sl_scp = cb->ccb_sscp;
1478	slp->sl_error |= cb->ccb_error;
1479
1480	slp->sl_disc --;
1481	li->li_disc --;
1482
1483	/* inform "ccb nexus established" to the host driver */
1484	slp->sl_nexus_call = 1;
1485	(*slp->sl_funcs->scsi_low_establish_nexus) (slp, ti);
1486	return cb;
1487}
1488
1489struct targ_info *
1490scsi_low_reselected(slp, targ)
1491	struct scsi_low_softc *slp;
1492	u_int targ;
1493{
1494	struct targ_info *ti;
1495	u_char *s;
1496
1497	/*
1498	 * Check select vs reselected collision.
1499	 */
1500
1501	if ((ti = slp->sl_selid) != NULL)
1502	{
1503		scsi_low_clear_nexus(slp, ti);
1504		SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1505#ifdef	SCSI_LOW_STATICS
1506		scsi_low_statics.nexus_conflict ++;
1507#endif	/* SCSI_LOW_STATICS */
1508	}
1509	else if (slp->sl_nexus != NULL)
1510	{
1511		s = "host busy";
1512		goto world_restart;
1513	}
1514
1515	/*
1516	 * Check a valid target id asserted ?
1517	 */
1518	if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
1519	{
1520		s = "scsi id illegal";
1521		goto world_restart;
1522	}
1523
1524	/*
1525	 * Check the target scsi status.
1526	 */
1527	ti = slp->sl_ti[targ];
1528	if (ti->ti_phase != PH_DISC)
1529	{
1530		s = "phase mismatch";
1531		goto world_restart;
1532	}
1533
1534	/*
1535	 * Setup lun and init msgsys
1536	 */
1537	slp->sl_error = 0;
1538	scsi_low_init_msgsys(slp, ti);
1539
1540	/*
1541	 * Establish our target nexus
1542	 * Remark: ccb and scsi pointer not yet restored
1543	 * 	   if lun != SCSI_LOW_UNKLUN.
1544	 */
1545	SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
1546	slp->sl_nexus = ti;
1547#ifdef	SCSI_LOW_STATICS
1548	scsi_low_statics.nexus_reselected ++;
1549#endif	/* SCSI_LOW_STATICS */
1550	return ti;
1551
1552world_restart:
1553	printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
1554	scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
1555		         "reselect: scsi world confused");
1556	return NULL;
1557}
1558
1559int
1560scsi_low_disconnected(slp, ti)
1561	struct scsi_low_softc *slp;
1562	struct targ_info *ti;
1563{
1564	struct slccb *cb = ti->ti_nexus;
1565
1566	/* check phase completion */
1567	switch (slp->sl_msgphase)
1568	{
1569	case MSGPH_DISC:
1570		if (cb != NULL)
1571		{
1572			TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1573			TAILQ_INSERT_TAIL(&ti->ti_discq, cb, ccb_chain);
1574			cb->ccb_error |= slp->sl_error;
1575			cb->li->li_disc ++;
1576			slp->sl_disc ++;
1577		}
1578		SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
1579#ifdef	SCSI_LOW_STATICS
1580		scsi_low_statics.nexus_disconnected ++;
1581#endif	/* SCSI_LOW_STATICS */
1582		break;
1583
1584	case MSGPH_NULL:
1585		slp->sl_error |= FATALIO;
1586
1587	case MSGPH_CMDC:
1588		if (cb != NULL)
1589		{
1590			cb->ccb_error |= slp->sl_error;
1591			scsi_low_done(slp, cb);
1592		}
1593		SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1594		break;
1595	}
1596
1597	scsi_low_clear_nexus(slp, ti);
1598	scsi_low_start(slp);
1599	return 1;
1600}
1601
1602/**************************************************************
1603 * cmd out pointer setup
1604 **************************************************************/
1605int
1606scsi_low_cmd(slp, ti)
1607	struct scsi_low_softc *slp;
1608	struct targ_info *ti;
1609{
1610	struct slccb *cb = ti->ti_nexus;
1611
1612	if (cb == NULL)
1613	{
1614		/*
1615		 * no slccb, abort!
1616		 */
1617		slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
1618		slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1619		slp->sl_scp.scp_datalen = 0;
1620		slp->sl_scp.scp_direction = SCSI_LOW_READ;
1621		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1);
1622		scsi_low_info(slp, ti, "CMDOUT: slccb nexus not found");
1623	}
1624	else if (slp->sl_nexus_call == 0)
1625	{
1626		slp->sl_nexus_call = 1;
1627		(*slp->sl_funcs->scsi_low_establish_nexus) (slp, ti);
1628	}
1629	return 0;
1630}
1631
1632/**************************************************************
1633 * data out pointer setup
1634 **************************************************************/
1635int
1636scsi_low_data(slp, ti, bp, direction)
1637	struct scsi_low_softc *slp;
1638	struct targ_info *ti;
1639	struct buf **bp;
1640	int direction;
1641{
1642	struct slccb *cb = ti->ti_nexus;
1643
1644	if (cb == NULL)
1645	{
1646		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1);
1647		scsi_low_info(slp, ti, "DATA PHASE: slccb nexus not found");
1648		return EINVAL;
1649	}
1650
1651	if (direction != cb->ccb_scp.scp_direction)
1652	{
1653		scsi_low_info(slp, ti, "DATA PHASE: xfer direction mismatch");
1654		return EINVAL;
1655	}
1656
1657#ifdef CAM
1658	*bp = NULL; /* (cb->ccb == NULL) ? NULL : cb->bp; */
1659#else
1660	*bp = (cb->xs == NULL) ? NULL : cb->xs->bp;
1661#endif
1662	return 0;
1663}
1664
1665/**************************************************************
1666 * MSG_SYS
1667 **************************************************************/
1668#define	MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
1669#define	MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
1670#define	MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
1671#define	MSGIN_DATA_LAST	0x30
1672
1673static int scsi_low_errfunc_synch __P((struct targ_info *, u_int));
1674static int scsi_low_errfunc_wide __P((struct targ_info *, u_int));
1675static int scsi_low_errfunc_identify __P((struct targ_info *, u_int));
1676
1677static int scsi_low_msgfunc_synch __P((struct targ_info *));
1678static int scsi_low_msgfunc_wide __P((struct targ_info *));
1679static int scsi_low_msgfunc_identify __P((struct targ_info *));
1680static int scsi_low_msgfunc_user __P((struct targ_info *));
1681static int scsi_low_msgfunc_abort __P((struct targ_info *));
1682
1683struct scsi_low_msgout_data {
1684	u_int	md_flags;
1685	u_int8_t md_msg;
1686	int (*md_msgfunc) __P((struct targ_info *));
1687	int (*md_errfunc) __P((struct targ_info *, u_int));
1688};
1689
1690struct scsi_low_msgout_data scsi_low_msgout_data[] = {
1691/* 0 */	{SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_abort, NULL},
1692/* 1 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL},
1693/* 2 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL},
1694/* 3 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL},
1695/* 4 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL},
1696/* 5 */ {SCSI_LOW_MSG_IDENTIFY, 0, scsi_low_msgfunc_identify, scsi_low_errfunc_identify},
1697/* 6 */ {SCSI_LOW_MSG_SYNCH, 0, scsi_low_msgfunc_synch, scsi_low_errfunc_synch},
1698/* 7 */ {SCSI_LOW_MSG_WIDE, 0, scsi_low_msgfunc_wide, scsi_low_errfunc_wide},
1699/* 8 */ {SCSI_LOW_MSG_USER, 0, scsi_low_msgfunc_user, NULL},
1700/* 9 */ {SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL},
1701/* 10 */ {SCSI_LOW_MSG_ALL, 0},
1702};
1703
1704static int scsi_low_msginfunc_ext __P((struct targ_info *));
1705static int scsi_low_synch __P((struct targ_info *));
1706static int scsi_low_msginfunc_msg_reject __P((struct targ_info *));
1707static int scsi_low_msginfunc_rejop __P((struct targ_info *));
1708static int scsi_low_msginfunc_rdp __P((struct targ_info *));
1709static int scsi_low_msginfunc_sdp __P((struct targ_info *));
1710static int scsi_low_msginfunc_disc __P((struct targ_info *));
1711static int scsi_low_msginfunc_cc __P((struct targ_info *));
1712static int scsi_low_msginfunc_parity __P((struct targ_info *));
1713static int scsi_low_msginfunc_noop __P((struct targ_info *));
1714static void scsi_low_retry_phase __P((struct targ_info *));
1715
1716struct scsi_low_msgin_data {
1717	u_int md_len;
1718	int (*md_msgfunc) __P((struct targ_info *));
1719};
1720
1721struct scsi_low_msgin_data scsi_low_msgin_data[] = {
1722/* 0 */	{1,	scsi_low_msginfunc_cc},
1723/* 1 */ {2,	scsi_low_msginfunc_ext},
1724/* 2 */ {1,	scsi_low_msginfunc_sdp},
1725/* 3 */ {1,	scsi_low_msginfunc_rdp},
1726/* 4 */ {1,	scsi_low_msginfunc_disc},
1727/* 5 */ {1,	scsi_low_msginfunc_rejop},
1728/* 6 */ {1,	scsi_low_msginfunc_rejop},
1729/* 7 */ {1,	scsi_low_msginfunc_msg_reject},
1730/* 8 */ {1,	scsi_low_msginfunc_noop},
1731/* 9 */ {1,	scsi_low_msginfunc_parity},
1732/* a */ {1,	scsi_low_msginfunc_rejop},
1733/* b */ {1,	scsi_low_msginfunc_rejop},
1734/* c */ {1,	scsi_low_msginfunc_rejop},
1735/* d */ {2,	scsi_low_msginfunc_rejop},
1736/* e */ {1,	scsi_low_msginfunc_rejop},
1737/* f */ {1,	scsi_low_msginfunc_rejop},
1738/* 0x10 */ {1,	scsi_low_msginfunc_rejop},
1739/* 0x11 */ {1,	scsi_low_msginfunc_rejop},
1740/* 0x12 */ {1,	scsi_low_msginfunc_rejop},
1741/* 0x13 */ {1,	scsi_low_msginfunc_rejop},
1742/* 0x14 */ {1,	scsi_low_msginfunc_rejop},
1743/* 0x15 */ {1,	scsi_low_msginfunc_rejop},
1744/* 0x16 */ {1,	scsi_low_msginfunc_rejop},
1745/* 0x17 */ {1,	scsi_low_msginfunc_rejop},
1746/* 0x18 */ {1,	scsi_low_msginfunc_rejop},
1747/* 0x19 */ {1,	scsi_low_msginfunc_rejop},
1748/* 0x1a */ {1,	scsi_low_msginfunc_rejop},
1749/* 0x1b */ {1,	scsi_low_msginfunc_rejop},
1750/* 0x1c */ {1,	scsi_low_msginfunc_rejop},
1751/* 0x1d */ {1,	scsi_low_msginfunc_rejop},
1752/* 0x1e */ {1,	scsi_low_msginfunc_rejop},
1753/* 0x1f */ {1,	scsi_low_msginfunc_rejop},
1754/* 0x20 */ {2,	scsi_low_msginfunc_rejop},
1755/* 0x21 */ {2,	scsi_low_msginfunc_rejop},
1756/* 0x22 */ {2,	scsi_low_msginfunc_rejop},
1757/* 0x23 */ {2,	scsi_low_msginfunc_rejop},
1758/* 0x24 */ {2,	scsi_low_msginfunc_rejop},
1759/* 0x25 */ {2,	scsi_low_msginfunc_rejop},
1760/* 0x26 */ {2,	scsi_low_msginfunc_rejop},
1761/* 0x27 */ {2,	scsi_low_msginfunc_rejop},
1762/* 0x28 */ {2,	scsi_low_msginfunc_rejop},
1763/* 0x29 */ {2,	scsi_low_msginfunc_rejop},
1764/* 0x2a */ {2,	scsi_low_msginfunc_rejop},
1765/* 0x2b */ {2,	scsi_low_msginfunc_rejop},
1766/* 0x2c */ {2,	scsi_low_msginfunc_rejop},
1767/* 0x2d */ {2,	scsi_low_msginfunc_rejop},
1768/* 0x2e */ {2,	scsi_low_msginfunc_rejop},
1769/* 0x2f */ {2,	scsi_low_msginfunc_rejop},
1770/* 0x30 */ {1,	scsi_low_msginfunc_rejop}	/* default rej op */
1771};
1772
1773static void
1774scsi_low_init_msgsys(slp, ti)
1775	struct scsi_low_softc *slp;
1776	struct targ_info *ti;
1777{
1778
1779	ti->ti_msginptr = 0;
1780	ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
1781	ti->ti_tflags &= ~TARG_ASSERT_ATN;
1782	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
1783}
1784
1785/**************************************************************
1786 * msgout
1787 **************************************************************/
1788static int
1789scsi_low_msgfunc_synch(ti)
1790	struct targ_info *ti;
1791{
1792	struct lun_info *li = ti->ti_li;
1793	int ptr = ti->ti_msgoutlen;
1794
1795	if (li == NULL)
1796	{
1797		scsi_low_assert_msg(ti->ti_sc, ti, SCSI_LOW_MSG_ABORT, 0);
1798		return EINVAL;
1799	}
1800
1801	ti->ti_msgoutstr[ptr + 0] = MSG_EXTEND;
1802	ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
1803	ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
1804	ti->ti_msgoutstr[ptr + 3] = li->li_maxsynch.period;
1805	ti->ti_msgoutstr[ptr + 4] = li->li_maxsynch.offset;
1806	return MSG_EXTEND_SYNCHLEN + 2;
1807}
1808
1809static int
1810scsi_low_msgfunc_wide(ti)
1811	struct targ_info *ti;
1812{
1813	struct lun_info *li = ti->ti_li;
1814	int ptr = ti->ti_msgoutlen;
1815
1816	if (li == NULL)
1817	{
1818		scsi_low_assert_msg(ti->ti_sc, ti, SCSI_LOW_MSG_ABORT, 0);
1819		return EINVAL;
1820	}
1821
1822	ti->ti_msgoutstr[ptr + 0] = MSG_EXTEND;
1823	ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
1824	ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
1825	ti->ti_msgoutstr[ptr + 3] = li->li_width;
1826	return MSG_EXTEND_WIDELEN + 2;
1827}
1828
1829static int
1830scsi_low_msgfunc_identify(ti)
1831	struct targ_info *ti;
1832{
1833	int ptr = ti->ti_msgoutlen;;
1834
1835	if (ti->ti_li == NULL)
1836	{
1837		ti->ti_msgoutstr[ptr + 0] = 0x80;
1838		scsi_low_info(ti->ti_sc, ti, "MSGOUT: lun unknown");
1839		scsi_low_assert_msg(ti->ti_sc, ti, SCSI_LOW_MSG_ABORT, 0);
1840	}
1841	else
1842	{
1843		ti->ti_msgoutstr[ptr + 0] = ID_MSG_SETUP(ti);
1844	}
1845	return 1;
1846}
1847
1848static int
1849scsi_low_msgfunc_user(ti)
1850	struct targ_info *ti;
1851{
1852#ifdef	SCSI_LOW_SUPPORT_USER_MSGOUT
1853	struct slccb *cb = ti->ti_nexus;
1854	int ptr = ti->ti_msgoutlen;;
1855
1856	if (ti->ti_nexus == NULL)
1857	{
1858		ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
1859		return 1;
1860	}
1861	else
1862	{
1863		bcopy(cb->msgout, ti->ti_msgoutstr + ptr, SCSI_LOW_MAX_MSGLEN);
1864		return cb->msgoutlen;
1865	}
1866#else	/* !SCSI_LOW_SUPPORT_USER_MSGOUT */
1867	return 0;
1868#endif	/* !SCSI_LOW_SUPPORT_USER_MSGOUT */
1869}
1870
1871static int
1872scsi_low_msgfunc_abort(ti)
1873	struct targ_info *ti;
1874{
1875	struct scsi_low_softc *slp = ti->ti_sc;
1876
1877	/* The target should releases bus */
1878	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
1879	slp->sl_error |= /* ABORTIO */ FATALIO;
1880	return 1;
1881}
1882
1883/*
1884 * The following functions are called when targets give unexpected
1885 * responces in msgin (after msgout).
1886 */
1887static int
1888scsi_low_errfunc_identify(ti, msgflags)
1889	struct targ_info *ti;
1890	u_int msgflags;
1891{
1892	struct lun_info *li = ti->ti_li;
1893
1894	li->li_flags &= ~SCSI_LOW_DISC;
1895	return 0;
1896}
1897
1898static int
1899scsi_low_errfunc_synch(ti, msgflags)
1900	struct targ_info *ti;
1901	u_int msgflags;
1902{
1903
1904	/* XXX:
1905	 * illegal behavior, however
1906	 * there are buggy devices!
1907	 */
1908	MSGIN_PERIOD(ti) = 0;
1909	MSGIN_OFFSET(ti) = 0;
1910	scsi_low_synch(ti);
1911	return 0;
1912}
1913
1914static int
1915scsi_low_errfunc_wide(ti, msgflags)
1916	struct targ_info *ti;
1917	u_int msgflags;
1918{
1919	struct lun_info *li = ti->ti_li;
1920
1921	li->li_width = 0;
1922	return 0;
1923}
1924
1925int
1926scsi_low_msgout(slp, ti)
1927	struct scsi_low_softc *slp;
1928	struct targ_info *ti;
1929{
1930	struct scsi_low_msgout_data *mdp;
1931	int len = 0;
1932
1933	/* STEP I.
1934	 * Scsi phase changes.
1935	 * Previously msgs asserted are accepted by our target or
1936	 * processed by scsi_low_msgin.
1937	 * Thus clear all saved informations.
1938	 */
1939	if (ti->ti_ophase != ti->ti_phase)
1940	{
1941		ti->ti_omsgflags = 0;
1942		ti->ti_emsgflags = 0;
1943	}
1944
1945	/* STEP II.
1946	 * We did not assert attention, however still our target required
1947	 * msgs. Resend previous msgs.
1948	 */
1949	if (ti->ti_ophase == PH_MSGOUT && !(ti->ti_tflags & TARG_ASSERT_ATN))
1950	{
1951		ti->ti_msgflags |= ti->ti_omsgflags;
1952#ifdef	SCSI_LOW_DIAGNOSTIC
1953		printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
1954#endif	/* SCSI_LOW_DIAGNOSTIC */
1955	}
1956
1957	/*
1958	 * OK. clear flags.
1959	 */
1960	ti->ti_tflags &= ~TARG_ASSERT_ATN;
1961
1962	/* STEP III.
1963	 * We have no msgs. send MSG_LOOP (OK?)
1964	 */
1965	if (scsi_low_is_msgout_continue(ti) == 0)
1966		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
1967
1968	/* STEP IV.
1969	 * Process all msgs
1970	 */
1971	ti->ti_msgoutlen = 0;
1972	mdp = &scsi_low_msgout_data[0];
1973	for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
1974	{
1975		if ((ti->ti_msgflags & mdp->md_flags) != 0)
1976		{
1977			ti->ti_omsgflags |= mdp->md_flags;
1978			ti->ti_msgflags &= ~mdp->md_flags;
1979			ti->ti_emsgflags = mdp->md_flags;
1980
1981			ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
1982			if (mdp->md_msgfunc != NULL)
1983				len = (*mdp->md_msgfunc) (ti);
1984			else
1985				len = 1;
1986
1987			ti->ti_msgoutlen += len;
1988			if ((slp->sl_cfgflags & CFG_MSGUNIFY) == 0 ||
1989			    ti->ti_msgflags == 0)
1990				break;
1991			if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
1992				break;
1993		}
1994	}
1995
1996	if (scsi_low_is_msgout_continue(ti) != 0)
1997	{
1998#ifdef	SCSI_LOW_DIAGNOSTIC
1999		printf("SCSI_LOW_ATTENTION(msgout): 0x%x\n", ti->ti_msgflags);
2000#endif	/* SCSI_LOW_DIAGNOSTIC */
2001		scsi_low_attention(slp, ti);
2002	}
2003
2004	/*
2005	 * OK. advance old phase.
2006	 */
2007	ti->ti_ophase = ti->ti_phase;
2008	return ti->ti_msgoutlen;
2009}
2010
2011/**************************************************************
2012 * msgin
2013 **************************************************************/
2014static int
2015scsi_low_msginfunc_noop(ti)
2016	struct targ_info *ti;
2017{
2018
2019	return 0;
2020}
2021
2022static int
2023scsi_low_msginfunc_rejop(ti)
2024	struct targ_info *ti;
2025{
2026	struct scsi_low_softc *slp = ti->ti_sc;
2027	u_int8_t msg = ti->ti_msgin[0];
2028
2029	printf("%s: MSGIN: msg 0x%x reject\n", slp->sl_xname, (u_int) msg);
2030	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2031	return 0;
2032}
2033
2034static int
2035scsi_low_msginfunc_cc(ti)
2036	struct targ_info *ti;
2037{
2038	struct scsi_low_softc *slp = ti->ti_sc;
2039
2040	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
2041	return 0;
2042}
2043
2044static int
2045scsi_low_msginfunc_disc(ti)
2046	struct targ_info *ti;
2047{
2048	struct scsi_low_softc *slp = ti->ti_sc;
2049
2050	SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
2051	return 0;
2052}
2053
2054static int
2055scsi_low_msginfunc_sdp(ti)
2056	struct targ_info *ti;
2057{
2058	struct scsi_low_softc *slp = ti->ti_sc;
2059
2060	if (ti->ti_nexus != NULL)
2061		ti->ti_nexus->ccb_sscp = slp->sl_scp;
2062	else
2063		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2064	return 0;
2065}
2066
2067static int
2068scsi_low_msginfunc_rdp(ti)
2069	struct targ_info *ti;
2070{
2071	struct scsi_low_softc *slp = ti->ti_sc;
2072
2073	if (ti->ti_nexus != NULL)
2074		slp->sl_scp = ti->ti_nexus->ccb_sscp;
2075	else
2076		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2077	return 0;
2078}
2079
2080static int
2081scsi_low_synch(ti)
2082	struct targ_info *ti;
2083{
2084	struct scsi_low_softc *slp = ti->ti_sc;
2085	struct lun_info *li = ti->ti_li;
2086	u_int period = 0, offset = 0;
2087#ifdef SCSI_LOW_INFORM
2088	u_int speed;
2089#endif
2090	u_char *s;
2091	int error;
2092
2093	if (MSGIN_PERIOD(ti) >= li->li_maxsynch.period &&
2094	    MSGIN_OFFSET(ti) <= li->li_maxsynch.offset)
2095	{
2096		if ((offset = MSGIN_OFFSET(ti)) != 0)
2097			period = MSGIN_PERIOD(ti);
2098		s = offset ? "synchronous" : "async";
2099	}
2100	else
2101	{
2102		/* XXX:
2103		 * Target seems to be brain damaged.
2104		 * Force async transfer.
2105		 */
2106		li->li_maxsynch.period = 0;
2107		li->li_maxsynch.offset = 0;
2108		printf("%s: target brain damaged. async transfer\n",
2109			slp->sl_xname);
2110		return EINVAL;
2111	}
2112
2113	li->li_maxsynch.period = period;
2114	li->li_maxsynch.offset = offset;
2115
2116	error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
2117	if (error != 0)
2118	{
2119		/* XXX:
2120		 * Current period and offset are not acceptable
2121		 * for our adapter.
2122		 * The adapter changes max synch and max offset.
2123		 */
2124		printf("%s: synch neg failed. retry synch msg neg ...\n",
2125			slp->sl_xname);
2126		return error;
2127	}
2128
2129#ifdef SCSI_LOW_INFORM
2130	/* inform data */
2131	printf("%s(%d:%d): <%s> offset %d period %dns ",
2132		slp->sl_xname, ti->ti_id, li->li_lun, s, offset, period * 4);
2133	if (period != 0)
2134	{
2135		speed = 1000 * 10 / (period * 4);
2136		printf("%d.%d M/s", speed / 10, speed % 10);
2137	}
2138	printf("\n");
2139#endif
2140
2141	return 0;
2142}
2143
2144static int
2145scsi_low_msginfunc_ext(ti)
2146	struct targ_info *ti;
2147{
2148	struct scsi_low_softc *slp = ti->ti_sc;
2149	struct slccb *cb = ti->ti_nexus;
2150	struct lun_info *li = ti->ti_li;
2151	int count, retry;
2152	u_int32_t *ptr;
2153
2154	if (ti->ti_msginptr == 2)
2155	{
2156		ti->ti_msginlen = ti->ti_msgin[1] + 2;
2157		return 0;
2158	}
2159
2160	switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
2161	{
2162	case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
2163		if (cb == NULL)
2164			break;
2165
2166		ptr = (u_int32_t *)(&ti->ti_msgin[3]);
2167		count = (int) htonl((long) (*ptr));
2168		if(slp->sl_scp.scp_datalen - count < 0 ||
2169		   slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
2170			break;
2171
2172		slp->sl_scp.scp_datalen -= count;
2173		slp->sl_scp.scp_data += count;
2174		return 0;
2175
2176	case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
2177		if (li == NULL)
2178			break;
2179
2180		retry = scsi_low_synch(ti);
2181		if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
2182			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
2183		return 0;
2184
2185	case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
2186		if (li == NULL)
2187			break;
2188
2189		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
2190		return 0;
2191
2192	default:
2193		break;
2194	}
2195
2196	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2197	return EINVAL;
2198}
2199
2200static void
2201scsi_low_retry_phase(ti)
2202	struct targ_info *ti;
2203{
2204
2205	switch (ti->ti_sphase)
2206	{
2207	case PH_MSGOUT:
2208		ti->ti_msgflags |= ti->ti_omsgflags;
2209		break;
2210
2211	default:
2212		break;
2213	}
2214}
2215
2216static int
2217scsi_low_msginfunc_parity(ti)
2218	struct targ_info *ti;
2219{
2220	struct scsi_low_softc *slp = ti->ti_sc;
2221
2222	if (ti->ti_sphase != PH_MSGOUT)
2223		slp->sl_error |= PARITYERR;
2224	scsi_low_retry_phase(ti);
2225	return 0;
2226}
2227
2228static int
2229scsi_low_msginfunc_msg_reject(ti)
2230	struct targ_info *ti;
2231{
2232	struct scsi_low_softc *slp = ti->ti_sc;
2233	struct lun_info *li = ti->ti_li;
2234	struct scsi_low_msgout_data *mdp;
2235	u_int msgflags;
2236
2237	if (li == NULL)
2238	{
2239		/* not yet lun nexus established! */
2240		goto out;
2241	}
2242
2243	switch (ti->ti_sphase)
2244	{
2245	case PH_CMD:
2246		slp->sl_error |= CMDREJECT;
2247		break;
2248
2249	case PH_MSGOUT:
2250		if (ti->ti_emsgflags == 0)
2251			break;
2252
2253		msgflags = SCSI_LOW_MSG_REJECT;
2254		mdp = &scsi_low_msgout_data[0];
2255		for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
2256		{
2257			if ((ti->ti_emsgflags & mdp->md_flags) != 0)
2258			{
2259				ti->ti_emsgflags &= ~mdp->md_flags;
2260				if (mdp->md_errfunc != NULL)
2261					(*mdp->md_errfunc) (ti, msgflags);
2262				break;
2263			}
2264		}
2265		break;
2266
2267	default:
2268		break;
2269	}
2270
2271out:
2272	scsi_low_info(slp, ti, "msg rejected");
2273	slp->sl_error |= MSGERR;
2274	return 0;
2275}
2276
2277void
2278scsi_low_msgin(slp, ti, c)
2279	struct scsi_low_softc *slp;
2280	struct targ_info *ti;
2281	u_int8_t c;
2282{
2283	struct scsi_low_msgin_data *sdp;
2284	struct lun_info *li;
2285	u_int8_t msg;
2286
2287	/*
2288	 * Phase changes, clear the pointer.
2289	 */
2290	if (ti->ti_ophase != ti->ti_phase)
2291	{
2292		ti->ti_sphase = ti->ti_ophase;
2293		ti->ti_ophase = ti->ti_phase;
2294		MSGINPTR_CLR(ti);
2295#ifdef	SCSI_LOW_DIAGNOSTIC
2296		ti->ti_msgin_hist_pointer = 0;
2297#endif	/* SCSI_LOW_DIAGNOSTIC */
2298	}
2299
2300	/*
2301	 * Store a current messages byte into buffer and
2302	 * wait for the completion of the current msg.
2303	 */
2304	ti->ti_msgin[ti->ti_msginptr ++] = c;
2305	if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
2306	{
2307		ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
2308		scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2309	}
2310
2311	/*
2312	 * Calculate messages length.
2313	 */
2314	msg = ti->ti_msgin[0];
2315	if (msg < MSGIN_DATA_LAST)
2316		sdp = &scsi_low_msgin_data[msg];
2317	else
2318		sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
2319
2320	if (ti->ti_msginlen == 0)
2321	{
2322		ti->ti_msginlen = sdp->md_len;
2323#ifdef	SCSI_LOW_DIAGNOSTIC
2324	    	if (ti->ti_msgin_hist_pointer < MSGIN_HISTORY_LEN)
2325		{
2326			ti->ti_msgin_history[ti->ti_msgin_hist_pointer] = msg;
2327			ti->ti_msgin_hist_pointer ++;
2328		}
2329#endif	/* SCSI_LOW_DIAGNOSTIC */
2330	}
2331
2332	/*
2333	 * Check comletion.
2334	 */
2335	if (ti->ti_msginptr < ti->ti_msginlen)
2336		return;
2337
2338	/*
2339	 * Do process.
2340	 */
2341	if ((msg & MSG_IDENTIFY) == 0)
2342	{
2343		(void) ((*sdp->md_msgfunc) (ti));
2344	}
2345	else
2346	{
2347		li = ti->ti_li;
2348		if (li == NULL)
2349		{
2350			li = scsi_low_establish_lun(ti, MSGCMD_LUN(msg));
2351			if (li == NULL)
2352				goto badlun;
2353		}
2354
2355		if (ti->ti_nexus == NULL)
2356		{
2357			/* XXX:
2358		 	 * move the following functions to
2359			 * tag queue msg process in the future.
2360			 */
2361			if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
2362				goto badlun;
2363		}
2364
2365		if (MSGCMD_LUN(msg) != li->li_lun)
2366			goto badlun;
2367	}
2368
2369	/*
2370	 * Msg process completed, reset msin pointer and assert ATN if desired.
2371	 */
2372	if (ti->ti_msginptr >= ti->ti_msginlen)
2373	{
2374		ti->ti_sphase = ti->ti_phase;
2375		MSGINPTR_CLR(ti);
2376
2377		if (scsi_low_is_msgout_continue(ti) != 0)
2378		{
2379#ifdef	SCSI_LOW_DIAGNOSTIC
2380			printf("SCSI_LOW_ATTETION(msgin): 0x%x\n",
2381				ti->ti_msgflags);
2382#endif	/* SCSI_LOW_DIAGNOSTIC */
2383			scsi_low_attention(slp, ti);
2384		}
2385	}
2386	return;
2387
2388badlun:
2389	scsi_low_info(slp, ti, "MSGIN: identify lun mismatch");
2390	scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2391}
2392
2393/**************************************************************
2394 * Qurik setup
2395 **************************************************************/
2396#define	MAXOFFSET	0x10
2397
2398static void
2399scsi_low_calcf(ti, li)
2400	struct targ_info *ti;
2401	struct lun_info *li;
2402{
2403	u_int period;
2404	u_int8_t offset;
2405	struct scsi_low_softc *slp = ti->ti_sc;
2406
2407	li->li_flags &= ~SCSI_LOW_DISC;
2408	if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
2409#ifdef	SDEV_NODISC
2410	    (li->li_quirks & SDEV_NODISC) == 0 &&
2411#endif	/* SDEV_NODISC */
2412	    (li->li_cfgflags & SCSI_LOW_DISC) != 0)
2413		li->li_flags |= SCSI_LOW_DISC;
2414
2415	li->li_flags |= SCSI_LOW_NOPARITY;
2416	if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
2417#ifdef	SDEV_NOPARITY
2418	    (li->li_quirks & SDEV_NOPARITY) == 0 &&
2419#endif	/* SDEV_NOPARITY */
2420	    (li->li_cfgflags & SCSI_LOW_NOPARITY) == 0)
2421		li->li_flags &= ~SCSI_LOW_NOPARITY;
2422
2423	li->li_flags &= ~SCSI_LOW_SYNC;
2424	if ((li->li_cfgflags & SCSI_LOW_SYNC) &&
2425	    (slp->sl_cfgflags & CFG_ASYNC) == 0)
2426	{
2427		offset = SCSI_LOW_OFFSET(li->li_cfgflags);
2428		if (offset > li->li_maxsynch.offset)
2429			offset = li->li_maxsynch.offset;
2430		li->li_flags |= SCSI_LOW_SYNC;
2431	}
2432	else
2433		offset = 0;
2434
2435	if (offset > 0)
2436	{
2437		period = SCSI_LOW_PERIOD(li->li_cfgflags);
2438		if (period > SCSI_LOW_MAX_SYNCH_SPEED)
2439			period = SCSI_LOW_MAX_SYNCH_SPEED;
2440		if (period != 0)
2441			period = 1000 * 10 / (period * 4);
2442		if (period < li->li_maxsynch.period)
2443			period = li->li_maxsynch.period;
2444	}
2445	else
2446		period = 0;
2447
2448	li->li_maxsynch.offset = offset;
2449	li->li_maxsynch.period = period;
2450}
2451
2452#ifdef	SCSI_LOW_TARGET_OPEN
2453static int
2454scsi_low_target_open(link, cf)
2455	struct scsipi_link *link;
2456	struct cfdata *cf;
2457{
2458	u_int target = link->scsipi_scsi.target;
2459	u_int lun = link->scsipi_scsi.lun;
2460	struct scsi_low_softc *slp;
2461	struct targ_info *ti;
2462	struct lun_info *li;
2463
2464	slp = (struct scsi_low_softc *) link->adapter_softc;
2465	ti = slp->sl_ti[target];
2466	li = scsi_low_alloc_li(ti, lun, 0);
2467	if (li == NULL)
2468		return 0;
2469
2470	li->li_quirks = (u_int) link->quirks;
2471	li->li_cfgflags = cf->cf_flags;
2472	if (li->li_state > UNIT_SYNCH)
2473		li->li_state = UNIT_SYNCH;
2474
2475	scsi_low_calcf(ti, li);
2476
2477	printf("%s(%d:%d): max period(%dns) max offset(%d) flags 0x%b\n",
2478		slp->sl_xname, target, lun,
2479		li->li_maxsynch.period * 4,
2480		li->li_maxsynch.offset,
2481		li->li_flags, SCSI_LOW_BITS);
2482	return 0;
2483}
2484#endif	/* SCSI_LOW_TARGET_OPEN */
2485
2486/**********************************************************
2487 * DEBUG SECTION
2488 **********************************************************/
2489static void
2490scsi_low_info(slp, ti, s)
2491	struct scsi_low_softc *slp;
2492	struct targ_info *ti;
2493	u_char *s;
2494{
2495
2496	printf("%s: SCSI_LOW: %s\n", slp->sl_xname, s);
2497	if (ti == NULL)
2498	{
2499		for (ti = slp->sl_titab.tqh_first; ti != NULL;
2500		     ti = ti->ti_chain.tqe_next)
2501			scsi_low_print(slp, ti);
2502	}
2503	else
2504		scsi_low_print(slp, ti);
2505
2506}
2507
2508static u_char *phase[] =
2509{
2510	"FREE", "ARBSTART", "SELSTART", "SELECTED",
2511	"CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
2512};
2513
2514void
2515scsi_low_print(slp, ti)
2516	struct scsi_low_softc *slp;
2517	struct targ_info *ti;
2518{
2519	struct slccb *cb = NULL;
2520
2521	if (ti == NULL)
2522		ti = slp->sl_nexus;
2523	if (ti != NULL)
2524		cb = ti->ti_nexus;
2525
2526	printf("%s: TARGET(0x%lx) T_NEXUS(0x%lx) C_NEXUS(0x%lx) NDISCS(%d)\n",
2527	       slp->sl_xname, (u_long) ti, (u_long) slp->sl_nexus,
2528	       (u_long) cb, slp->sl_disc);
2529
2530	/* target stat */
2531	if (ti != NULL)
2532	{
2533		struct sc_p *sp = &slp->sl_scp;
2534		struct lun_info *li = ti->ti_li;
2535		u_int flags = 0;
2536		int lun = -1;
2537
2538		if (li != NULL)
2539		{
2540			lun = li->li_lun;
2541			flags = li->li_flags;
2542		}
2543
2544		printf("%s(%d:%d) ph<%s> => ph<%s>\n", slp->sl_xname,
2545		       ti->ti_id, lun, phase[(int) ti->ti_ophase],
2546		       phase[(int) ti->ti_phase]);
2547
2548printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] STATUSIN: 0x%x T_FLAGS: 0x%x\n",
2549		       (u_int) (ti->ti_msginptr),
2550		       (u_int) (ti->ti_msgin[0]),
2551		       (u_int) (ti->ti_msgin[1]),
2552		       (u_int) (ti->ti_msgin[2]),
2553		       (u_int) (ti->ti_msgin[3]),
2554		       (u_int) (ti->ti_msgin[4]),
2555		       ti->ti_status, ti->ti_tflags);
2556#ifdef	SCSI_LOW_DIAGNOSTIC
2557printf("MSGIN HISTORY: (%d) [0x%x] => [0x%x] => [0x%x] => [0x%x] => [0x%x]\n",
2558			ti->ti_msgin_hist_pointer,
2559			(u_int) (ti->ti_msgin_history[0]),
2560			(u_int) (ti->ti_msgin_history[1]),
2561			(u_int) (ti->ti_msgin_history[2]),
2562			(u_int) (ti->ti_msgin_history[3]),
2563			(u_int) (ti->ti_msgin_history[4]));
2564#endif	/* SCSI_LOW_DIAGNOSTIC */
2565
2566printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
2567			(u_int) ti->ti_msgflags,
2568			(u_int) (ti->ti_msgoutstr[0]),
2569			(u_int) (ti->ti_msgoutstr[1]),
2570			(u_int) (ti->ti_msgoutstr[2]),
2571			(u_int) (ti->ti_msgoutstr[3]),
2572			(u_int) (ti->ti_msgoutstr[4]),
2573		        ti->ti_msgoutlen,
2574			flags, SCSI_LOW_BITS);
2575
2576printf("SCP: datalen 0x%x dataaddr 0x%lx ",
2577			sp->scp_datalen,
2578			(u_long) sp->scp_data);
2579
2580		if (cb != NULL)
2581		{
2582printf("CCB: cmdlen %x cmdaddr %lx cmd[0] %x datalen %x",
2583		       cb->ccb_scp.scp_cmdlen,
2584		       (u_long) cb->ccb_scp.scp_cmd,
2585		       (u_int) cb->ccb_scp.scp_cmd[0],
2586		       cb->ccb_scp.scp_datalen);
2587		}
2588		printf("\n");
2589	}
2590	printf("error flags %b\n", slp->sl_error, SCSI_LOW_ERRORBITS);
2591}
2592