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