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