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