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