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