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